UNPKG

terra-draw-maplibre-gl-adapter

Version:
1 lines 22.6 kB
{"version":3,"file":"terra-draw-maplibre-gl-adapter.cjs","sources":["../src/terra-draw-maplibre-gl-adapter.ts"],"sourcesContent":["/**\n * @module terra-draw-maplibre-gl-adapter\n */\nimport {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawExtend,\n\tGeoJSONStoreGeometries,\n} from \"terra-draw\";\nimport {\n\tCircleLayerSpecification,\n\tFillLayerSpecification,\n\tGeoJSONSource,\n\tLineLayerSpecification,\n\tMap,\n\tPointLike,\n} from \"maplibre-gl\";\nimport { Feature, LineString, Point, Polygon } from \"geojson\";\n\nexport class TerraDrawMapLibreGLAdapter<\n\tMapType,\n> extends TerraDrawExtend.TerraDrawBaseAdapter {\n\tconstructor(\n\t\tconfig: {\n\t\t\tmap: MapType;\n\t\t\trenderBelowLayerId?: string;\n\t\t\tprefixId?: string;\n\t\t} & TerraDrawExtend.BaseAdapterConfig,\n\t) {\n\t\tsuper(config);\n\n\t\tthis._map = config.map as Map;\n\t\tthis._container = this._map.getContainer();\n\n\t\t// We want to respect the initial map settings\n\t\tthis._initialDragRotate = this._map.dragRotate.isEnabled();\n\t\tthis._initialDragPan = this._map.dragPan.isEnabled();\n\t\tthis._renderBeforeLayerId = config.renderBelowLayerId;\n\t\tthis._prefixId = config.prefixId || \"td\";\n\t}\n\n\tprivate _renderBeforeLayerId: string | undefined;\n\tprivate _prefixId: string;\n\tprivate _initialDragPan: boolean;\n\tprivate _initialDragRotate: boolean;\n\tprivate _nextRender: number | undefined;\n\tprivate _map: Map;\n\tprivate _container: HTMLElement;\n\n\tprivate _addGeoJSONSource(id: string, features: Feature[]) {\n\t\tthis._map.addSource(id, {\n\t\t\ttype: \"geojson\",\n\t\t\tdata: {\n\t\t\t\ttype: \"FeatureCollection\",\n\t\t\t\tfeatures: features,\n\t\t\t},\n\t\t\ttolerance: 0,\n\t\t});\n\t}\n\n\tprivate _addFillLayer(id: string) {\n\t\treturn this._map.addLayer({\n\t\t\tid,\n\t\t\tsource: id,\n\t\t\ttype: \"fill\",\n\t\t\tlayout: {\n\t\t\t\t\"fill-sort-key\": [\"get\", \"zIndex\"],\n\t\t\t},\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"fill-color\": [\"get\", \"polygonFillColor\"],\n\t\t\t\t\"fill-opacity\": [\"get\", \"polygonFillOpacity\"],\n\t\t\t},\n\t\t} as FillLayerSpecification);\n\t}\n\n\tprivate _addFillOutlineLayer(id: string) {\n\t\tconst layer = this._map.addLayer({\n\t\t\tid: id + \"-outline\",\n\t\t\tsource: id,\n\t\t\ttype: \"line\",\n\t\t\tlayout: {\n\t\t\t\t\"line-sort-key\": [\"get\", \"zIndex\"],\n\t\t\t},\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"line-width\": [\"get\", \"polygonOutlineWidth\"],\n\t\t\t\t\"line-color\": [\"get\", \"polygonOutlineColor\"],\n\t\t\t},\n\t\t} as LineLayerSpecification);\n\n\t\treturn layer;\n\t}\n\n\tprivate _addLineLayer(id: string) {\n\t\tconst layer = this._map.addLayer({\n\t\t\tid,\n\t\t\tsource: id,\n\t\t\ttype: \"line\",\n\t\t\tlayout: {\n\t\t\t\t\"line-sort-key\": [\"get\", \"zIndex\"],\n\t\t\t},\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"line-width\": [\"get\", \"lineStringWidth\"],\n\t\t\t\t\"line-color\": [\"get\", \"lineStringColor\"],\n\t\t\t},\n\t\t} as LineLayerSpecification);\n\n\t\treturn layer;\n\t}\n\n\tprivate _addPointLayer(id: string) {\n\t\tconst layer = this._map.addLayer({\n\t\t\tid,\n\t\t\tsource: id,\n\t\t\ttype: \"circle\",\n\t\t\tlayout: {\n\t\t\t\t\"circle-sort-key\": [\"get\", \"zIndex\"],\n\t\t\t},\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"circle-stroke-color\": [\"get\", \"pointOutlineColor\"],\n\t\t\t\t\"circle-stroke-width\": [\"get\", \"pointOutlineWidth\"],\n\t\t\t\t\"circle-radius\": [\"get\", \"pointWidth\"],\n\t\t\t\t\"circle-color\": [\"get\", \"pointColor\"],\n\t\t\t},\n\t\t} as CircleLayerSpecification);\n\n\t\treturn layer;\n\t}\n\n\tprivate _addLayer(\n\t\tid: string,\n\t\tfeatureType: \"Point\" | \"LineString\" | \"Polygon\",\n\t) {\n\t\tif (featureType === \"Point\") {\n\t\t\tthis._addPointLayer(id);\n\t\t}\n\t\tif (featureType === \"LineString\") {\n\t\t\tthis._addLineLayer(id);\n\t\t}\n\t\tif (featureType === \"Polygon\") {\n\t\t\tthis._addFillLayer(id);\n\t\t\tthis._addFillOutlineLayer(id);\n\t\t}\n\t}\n\n\tprivate _addGeoJSONLayer<T extends GeoJSONStoreGeometries>(\n\t\tfeatureType: Feature<T>[\"geometry\"][\"type\"],\n\t\tfeatures: Feature<T>[],\n\t) {\n\t\tconst id = `${this._prefixId}-${featureType.toLowerCase()}`;\n\t\tthis._addGeoJSONSource(id, features);\n\t\tthis._addLayer(id, featureType);\n\n\t\treturn id;\n\t}\n\n\tprivate _setGeoJSONLayerData<T extends GeoJSONStoreGeometries>(\n\t\tfeatureType: Feature<T>[\"geometry\"][\"type\"],\n\t\tfeatures: Feature<T>[],\n\t) {\n\t\tconst id = `${this._prefixId}-${featureType.toLowerCase()}`;\n\t\t(this._map.getSource(id) as GeoJSONSource).setData({\n\t\t\ttype: \"FeatureCollection\",\n\t\t\tfeatures: features,\n\t\t});\n\t\treturn id;\n\t}\n\n\tprivate changedIds: {\n\t\tdeletion: boolean;\n\t\tpoints: boolean;\n\t\tlinestrings: boolean;\n\t\tpolygons: boolean;\n\t\tstyling: boolean;\n\t} = {\n\t\tdeletion: false,\n\t\tpoints: false,\n\t\tlinestrings: false,\n\t\tpolygons: false,\n\t\tstyling: false,\n\t};\n\n\tprivate updateChangedIds(changes: TerraDrawChanges) {\n\t\t[...changes.updated, ...changes.created].forEach((feature) => {\n\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\tthis.changedIds.points = true;\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tthis.changedIds.linestrings = true;\n\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\tthis.changedIds.polygons = true;\n\t\t\t}\n\t\t});\n\n\t\tif (changes.deletedIds.length > 0) {\n\t\t\tthis.changedIds.deletion = true;\n\t\t}\n\n\t\tif (\n\t\t\tchanges.created.length === 0 &&\n\t\t\tchanges.updated.length === 0 &&\n\t\t\tchanges.deletedIds.length === 0\n\t\t) {\n\t\t\tthis.changedIds.styling = true;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tconst { left, top } = this._container.getBoundingClientRect();\n\t\tconst x = event.clientX - left;\n\t\tconst y = event.clientY - top;\n\n\t\treturn this.unproject(x, y);\n\t}\n\n\t/**\n\t *Retrieves the HTML element of the MapLibre element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\treturn this._map.getCanvas();\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\t// MapLibre GL has both drag rotation and drag panning interactions\n\t\t\t// hence having to enable/disable both\n\t\t\tif (this._initialDragRotate) {\n\t\t\t\tthis._map.dragRotate.enable();\n\t\t\t}\n\t\t\tif (this._initialDragPan) {\n\t\t\t\tthis._map.dragPan.enable();\n\t\t\t}\n\t\t} else {\n\t\t\tif (this._initialDragRotate) {\n\t\t\t\tthis._map.dragRotate.disable();\n\t\t\t}\n\t\t\tif (this._initialDragPan) {\n\t\t\t\tthis._map.dragPan.disable();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\tconst { x, y } = this._map.project({ lng, lat });\n\t\treturn { x, y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\tconst { lng, lat } = this._map.unproject({ x, y } as PointLike);\n\t\treturn { lng, lat };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tconst canvas = this._map.getCanvas();\n\t\tif (cursor === \"unset\") {\n\t\t\tcanvas.style.removeProperty(\"cursor\");\n\t\t} else {\n\t\t\tcanvas.style.cursor = cursor;\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis._map.doubleClickZoom.enable();\n\t\t} else {\n\t\t\tthis._map.doubleClickZoom.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tthis.updateChangedIds(changes);\n\n\t\tif (this._nextRender) {\n\t\t\tcancelAnimationFrame(this._nextRender);\n\t\t}\n\n\t\t// Because Maplibre GL makes us pass in a full re-render of all the features\n\t\t// we can do debounce rendering to only render the last render in a given\n\t\t// frame bucket (16ms)\n\t\tthis._nextRender = requestAnimationFrame(() => {\n\t\t\t// Because unregister may be called synchronously, and the rAF can occur after\n\t\t\t// it lets ensure the adapter is actually registered\n\t\t\tif (!this._currentModeCallbacks) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get a map of the changed feature IDs by geometry type\n\t\t\t// We use this to determine which MB layers need to be updated\n\n\t\t\tconst features = [\n\t\t\t\t...changes.created,\n\t\t\t\t...changes.updated,\n\t\t\t\t...changes.unchanged,\n\t\t\t];\n\n\t\t\tconst points = [];\n\t\t\tconst linestrings = [];\n\t\t\tconst polygons = [];\n\n\t\t\tfor (let i = 0; i < features.length; i++) {\n\t\t\t\tconst feature = features[i];\n\t\t\t\tconst { properties } = feature;\n\t\t\t\tconst mode = properties.mode as string;\n\t\t\t\tconst styles = styling[mode](feature);\n\n\t\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\t\tproperties.pointColor = styles.pointColor;\n\t\t\t\t\tproperties.pointOutlineColor = styles.pointOutlineColor;\n\t\t\t\t\tproperties.pointOutlineWidth = styles.pointOutlineWidth;\n\t\t\t\t\tproperties.pointWidth = styles.pointWidth;\n\t\t\t\t\tproperties.zIndex = styles.zIndex;\n\t\t\t\t\tpoints.push(feature);\n\t\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\t\tproperties.lineStringColor = styles.lineStringColor;\n\t\t\t\t\tproperties.lineStringWidth = styles.lineStringWidth;\n\t\t\t\t\tlinestrings.push(feature);\n\t\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\t\tproperties.polygonFillColor = styles.polygonFillColor;\n\t\t\t\t\tproperties.polygonFillOpacity = styles.polygonFillOpacity;\n\t\t\t\t\tproperties.polygonOutlineColor = styles.polygonOutlineColor;\n\t\t\t\t\tproperties.polygonOutlineWidth = styles.polygonOutlineWidth;\n\t\t\t\t\tpolygons.push(feature);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If deletion occurred we always have to update all layers\n\t\t\t// as we don't know the type (TODO: perhaps we could pass that back?)\n\t\t\tconst deletionOccurred = this.changedIds.deletion;\n\t\t\tconst styleUpdatedOccurred = this.changedIds.styling;\n\t\t\tconst forceUpdate = deletionOccurred || styleUpdatedOccurred;\n\n\t\t\t// Determine if we need to update each layer by geometry type\n\t\t\tconst updatePoints = forceUpdate || this.changedIds.points;\n\t\t\tconst updateLineStrings = forceUpdate || this.changedIds.linestrings;\n\t\t\tconst updatedPolygon = forceUpdate || this.changedIds.polygons;\n\n\t\t\tif (updatePoints) {\n\t\t\t\tthis._setGeoJSONLayerData<Point>(\"Point\", points as Feature<Point>[]);\n\t\t\t}\n\n\t\t\tif (updateLineStrings) {\n\t\t\t\tthis._setGeoJSONLayerData<LineString>(\n\t\t\t\t\t\"LineString\",\n\t\t\t\t\tlinestrings as Feature<LineString>[],\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (updatedPolygon) {\n\t\t\t\tthis._setGeoJSONLayerData<Polygon>(\n\t\t\t\t\t\"Polygon\",\n\t\t\t\t\tpolygons as Feature<Polygon>[],\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Reset changed ids\n\t\t\tthis.changedIds = {\n\t\t\t\tpoints: false,\n\t\t\t\tlinestrings: false,\n\t\t\t\tpolygons: false,\n\t\t\t\tdeletion: false,\n\t\t\t\tstyling: false,\n\t\t\t};\n\t\t});\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\t// If we are not registered, do nothing\n\t\tif (!this._currentModeCallbacks) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clear up state first\n\t\tthis._currentModeCallbacks.onClear();\n\n\t\t// TODO: This is necessary to prevent render artifacts, perhaps there is a nicer solution?\n\t\tif (this._nextRender) {\n\t\t\tcancelAnimationFrame(this._nextRender);\n\t\t\tthis._nextRender = undefined;\n\t\t}\n\n\t\tthis._setGeoJSONLayerData<Point>(\"Point\", []);\n\n\t\tthis._setGeoJSONLayerData<LineString>(\"LineString\", []);\n\n\t\tthis._setGeoJSONLayerData<Polygon>(\"Polygon\", []);\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\treturn super.getCoordinatePrecision();\n\t}\n\n\tpublic unregister(): void {\n\t\tsuper.unregister();\n\n\t\tthis.changedIds = {\n\t\t\tpoints: false,\n\t\t\tlinestrings: false,\n\t\t\tpolygons: false,\n\t\t\tdeletion: false,\n\t\t\tstyling: false,\n\t\t};\n\n\t\tthis._map.removeLayer(`${this._prefixId}-point`);\n\t\tthis._map.removeSource(`${this._prefixId}-point`);\n\t\tthis._map.removeLayer(`${this._prefixId}-linestring`);\n\t\tthis._map.removeSource(`${this._prefixId}-linestring`);\n\t\tthis._map.removeLayer(`${this._prefixId}-polygon`);\n\t\tthis._map.removeLayer(`${this._prefixId}-polygon-outline`);\n\t\tthis._map.removeSource(`${this._prefixId}-polygon`);\n\t}\n\n\tpublic register(callbacks: TerraDrawExtend.TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\n\t\tconst polygonStringId = this._addGeoJSONLayer<Polygon>(\n\t\t\t\"Polygon\",\n\t\t\t[] as Feature<Polygon>[],\n\t\t);\n\n\t\tconst lineStringId = this._addGeoJSONLayer<LineString>(\n\t\t\t\"LineString\",\n\t\t\t[] as Feature<LineString>[],\n\t\t);\n\n\t\tconst pointId = this._addGeoJSONLayer<Point>(\n\t\t\t\"Point\",\n\t\t\t[] as Feature<Point>[],\n\t\t);\n\n\t\tif (this._renderBeforeLayerId) {\n\t\t\tthis._map.moveLayer(pointId, this._renderBeforeLayerId);\n\t\t\tthis._map.moveLayer(lineStringId, pointId);\n\t\t\tthis._map.moveLayer(polygonStringId + \"-outline\", lineStringId);\n\t\t\tthis._map.moveLayer(polygonStringId, lineStringId);\n\t\t}\n\n\t\tif (this._currentModeCallbacks?.onReady) {\n\t\t\tthis._currentModeCallbacks.onReady();\n\t\t}\n\t}\n}\n"],"names":["_TerraDrawExtend$Terr","TerraDrawMapLibreGLAdapter","config","_this","call","this","_renderBeforeLayerId","_prefixId","_initialDragPan","_initialDragRotate","_nextRender","_map","_container","changedIds","deletion","points","linestrings","polygons","styling","map","getContainer","dragRotate","isEnabled","dragPan","renderBelowLayerId","prefixId","_proto","prototype","_addGeoJSONSource","id","features","addSource","type","data","tolerance","_addFillLayer","addLayer","source","layout","paint","_addFillOutlineLayer","_addLineLayer","_addPointLayer","_addLayer","featureType","_addGeoJSONLayer","toLowerCase","_setGeoJSONLayerData","getSource","setData","updateChangedIds","changes","_this2","concat","updated","created","forEach","feature","geometry","deletedIds","length","getLngLatFromEvent","event","_this$_container$getB","getBoundingClientRect","unproject","clientX","left","clientY","top","getMapEventElement","getCanvas","setDraggability","enabled","enable","disable","project","lng","lat","_this$_map$project","x","y","_this$_map$unproject","setCursor","cursor","canvas","style","removeProperty","setDoubleClickToZoom","doubleClickZoom","render","_this3","cancelAnimationFrame","requestAnimationFrame","_currentModeCallbacks","unchanged","i","properties","styles","mode","pointColor","pointOutlineColor","pointOutlineWidth","pointWidth","zIndex","push","lineStringColor","lineStringWidth","polygonFillColor","polygonFillOpacity","polygonOutlineColor","polygonOutlineWidth","forceUpdate","updateLineStrings","updatedPolygon","clear","onClear","undefined","getCoordinatePrecision","unregister","removeLayer","removeSource","register","callbacks","_this$_currentModeCal","polygonStringId","lineStringId","pointId","moveLayer","onReady","TerraDrawExtend","TerraDrawBaseAdapter"],"mappings":"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"}