UNPKG

hmpps-open-layers-map

Version:

A native Web Component for displaying maps using OpenLayers.

74 lines (73 loc) 2.6 kB
import VectorLayer from 'ol/layer/Vector'; import VectorSource from 'ol/source/Vector'; import { GeoJSON } from 'ol/format'; import { Fill, Stroke, Text, Style } from 'ol/style'; // Style function that renders numbers from a feature property function createNumberingStyle(value, options) { return new Style({ text: new Text({ textAlign: 'left', textBaseline: 'middle', font: options.font ?? 'bold 12px "Inter", system-ui, sans-serif', fill: new Fill({ color: options.fillColor ?? 'black' }), stroke: new Stroke({ color: options.strokeColor ?? 'white', width: options.strokeWidth ?? 2, }), text: value, offsetX: options.offsetX ?? 12, offsetY: options.offsetY ?? 1, }), }); } function toOlSource(geoJson) { const formatter = new GeoJSON(); const features = formatter.readFeatures(geoJson, { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857', }); return new VectorSource({ features }); } export class NumberingLayer { id; options; olLayer; constructor(options) { this.options = options; this.id = options.id ?? 'numbering'; } getNativeLayer() { return this.olLayer; } attach(adapter) { if (adapter.mapLibrary !== 'openlayers') { console.warn(`[NumberingLayer] MapLibre support is not implemented yet (layer "${this.id}")`); return; } const { map } = adapter.openlayers; const property = this.options.numberProperty ?? 'sequenceNumber'; const vectorLayer = new VectorLayer({ source: toOlSource(this.options.geoJson), style: feature => { const value = feature.get(property); return value ? createNumberingStyle(String(value), this.options) : undefined; }, properties: { title: this.options.title ?? this.id }, }); const resolvedVisible = this.options.visible ?? false; const resolvedZIndex = this.options.zIndex; vectorLayer.setVisible(resolvedVisible); if (resolvedZIndex !== undefined) vectorLayer.setZIndex(resolvedZIndex); map.addLayer(vectorLayer); this.olLayer = vectorLayer; } detach(adapter) { if (adapter.mapLibrary !== 'openlayers') return; if (this.olLayer) { adapter.openlayers.map.removeLayer(this.olLayer); this.olLayer = undefined; } } }