UNPKG

@mattilsynet/designsystem-svelte

Version:

Design system for Mattilsynet

92 lines (91 loc) 3.11 kB
import VectorLayer from 'ol/layer/Vector'; import VectorSource from 'ol/source/Vector'; import {} from 'ol/Feature'; import { Circle, Fill, Style, Text } from 'ol/style'; import { Cluster } from 'ol/source'; import { DEFAULT_CLUSTER_DISPLACEMENT, DEFAULT_CLUSTER_OFFSET_X, DEFAULT_CLUSTER_OFFSET_Y, DEFAULT_CLUSTER_RADIUS, DEFAULT_CLUSTER_SIZE_SCALE } from '../../../ts/mapUtils'; import { addMarkersToSource, createMarkerStyle, MARKER } from './marker'; import { markers as svg } from '../../../ts'; export const LAYER_ID = 'layerId'; export const VECTOR_LAYER_ID = 'clusterLayer'; export function createClusterLayer(markers, options, markerOptions) { const source = addMarkersToSource(new VectorSource(), markers, markerOptions); const cluster = createCluster(options.distance, options.minDistance, source); const vectorLayer = new VectorLayer({ source: cluster, visible: true, style: createClusterStyle }); vectorLayer.set(LAYER_ID, VECTOR_LAYER_ID); return vectorLayer; } export function createMarkerLayer(markers, markerOptions) { const source = addMarkersToSource(new VectorSource(), markers, markerOptions); return new VectorLayer({ source, visible: true }); } function createClusterStyle(feature) { const features = feature.get('features'); const size = features.length; if (size <= 1) { return features?.[0]?.style_; } else if (hasSameMarkerStatus(features)) { return [getClusterStyleFromMarkerStatus(features[0]), createClusterSizeStyle(size)]; } else { return [ createMarkerStyle({ src: `data:image/svg+xml;utf8,${encodeURIComponent(svg.cluster.default)}` }), createClusterSizeStyle(size) ]; } } export function getClusterStyleFromMarkerStatus(feature) { const status = feature.get(MARKER).status; return createMarkerStyle({ src: `data:image/svg+xml;utf8,${encodeURIComponent(svg.cluster[status] ?? svg.cluster.default)}` }); } function hasSameMarkerStatus(features) { let prevStatus; for (const feature of features) { // @ts-ignore const currStatus = feature.get(MARKER).status; if (prevStatus && prevStatus !== currStatus) { return false; } prevStatus = currStatus; } return true; } function createClusterSizeStyle(size) { return new Style({ image: new Circle({ radius: DEFAULT_CLUSTER_RADIUS, fill: new Fill({ color: 'white' }), displacement: DEFAULT_CLUSTER_DISPLACEMENT }), text: new Text({ text: size.toString(), fill: new Fill({ color: '#032C30' }), scale: DEFAULT_CLUSTER_SIZE_SCALE, offsetX: DEFAULT_CLUSTER_OFFSET_X, offsetY: DEFAULT_CLUSTER_OFFSET_Y }) }); } function createCluster(distance, minDistance, source) { return new Cluster({ distance, minDistance, source: source }); }