hmpps-open-layers-map
Version:
A native Web Component for displaying maps using OpenLayers.
71 lines (70 loc) • 2.41 kB
JavaScript
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import { GeoJSON } from 'ol/format';
import { Fill, Stroke, Style } from 'ol/style';
import { Circle as CircleGeom } from 'ol/geom';
import Feature from 'ol/Feature';
const defaultStyle = new Style({
stroke: new Stroke({
color: 'orange',
width: 2,
}),
fill: new Fill({
color: 'rgba(255, 165, 0, 0.1)',
}),
});
function toOlSource(geoJson, radiusProperty) {
const formatter = new GeoJSON();
const pointFeatures = formatter.readFeatures(geoJson, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857',
});
const circleFeatures = pointFeatures.map(feature => {
const geom = feature.getGeometry();
const coords = geom.getCoordinates();
const radius = feature.get(radiusProperty);
const circle = new CircleGeom(coords, radius);
return new Feature({ geometry: circle });
});
return new VectorSource({ features: circleFeatures });
}
export class CirclesLayer {
id;
options;
olLayer;
constructor(options) {
this.options = options;
this.id = options.id ?? 'circles';
}
getNativeLayer() {
return this.olLayer;
}
attach(adapter) {
if (adapter.mapLibrary !== 'openlayers') {
console.warn(`[CirclesLayer] MapLibre support is not implemented yet (layer "${this.id}")`);
return;
}
const { map } = adapter.openlayers;
const radiusProp = this.options.radiusProperty ?? 'confidence';
const vectorLayer = new VectorLayer({
source: toOlSource(this.options.geoJson, radiusProp),
style: this.options.style ?? defaultStyle,
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;
}
}
}