@element-editor/adapter-maplibre 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +119 -0
- package/LICENSE +21 -0
- package/README.md +82 -2
- package/basemaps/sprite.json +1 -0
- package/basemaps/sprite.png +0 -0
- package/basemaps/sprite@2x.json +1 -0
- package/basemaps/sprite@2x.png +0 -0
- package/basemaps/thumbs/dark.webp +0 -0
- package/basemaps/thumbs/light.webp +0 -0
- package/basemaps/thumbs/osm.webp +0 -0
- package/basemaps/thumbs/streets.webp +0 -0
- package/basemaps/thumbs/terrain.webp +0 -0
- package/dist/adapter-maplibre.css +1 -0
- package/dist/basemapIds-2GdXIJS1.cjs +1 -0
- package/dist/basemapIds-CVTxeXkr.js +11 -0
- package/dist/basemaps.cjs +1 -0
- package/dist/basemaps.d.cts +2 -0
- package/dist/basemaps.d.ts +2 -0
- package/dist/basemaps.es.js +10 -0
- package/dist/catalog-Cnqi23GZ.cjs +1 -0
- package/dist/catalog-gI-xABuu.js +10 -0
- package/dist/dark-C5d5FijX.cjs +1 -0
- package/dist/dark-CcJT_yHE.js +13 -0
- package/dist/index.cjs +26 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.es.js +3792 -0
- package/dist/light-Cf5tUOoP.js +13 -0
- package/dist/light-DCtd1z4V.cjs +1 -0
- package/dist/src/BasemapControl.d.cts +47 -0
- package/dist/src/BasemapControl.d.ts +47 -0
- package/dist/src/ElementEditorControls.d.cts +113 -0
- package/dist/src/ElementEditorControls.d.ts +113 -0
- package/dist/src/basemapIds.d.cts +10 -0
- package/dist/src/basemapIds.d.ts +10 -0
- package/dist/src/basemaps/catalog.d.cts +7 -0
- package/dist/src/basemaps/catalog.d.ts +7 -0
- package/dist/src/basemaps/index.d.cts +3 -0
- package/dist/src/basemaps/index.d.ts +3 -0
- package/dist/src/basemaps/style.d.cts +61 -0
- package/dist/src/basemaps/style.d.ts +61 -0
- package/dist/src/components/BoundaryLayer.d.cts +11 -0
- package/dist/src/components/BoundaryLayer.d.ts +11 -0
- package/dist/src/components/BoxSelectHandler.d.cts +13 -0
- package/dist/src/components/BoxSelectHandler.d.ts +13 -0
- package/dist/src/components/DrawingLayer.d.cts +8 -0
- package/dist/src/components/DrawingLayer.d.ts +8 -0
- package/dist/src/components/DrawingPreviewLayer.d.cts +8 -0
- package/dist/src/components/DrawingPreviewLayer.d.ts +8 -0
- package/dist/src/components/FeatureInteractionLayer.d.cts +8 -0
- package/dist/src/components/FeatureInteractionLayer.d.ts +8 -0
- package/dist/src/components/FeatureLayer.d.cts +15 -0
- package/dist/src/components/FeatureLayer.d.ts +15 -0
- package/dist/src/components/GeometryProcessingPreview.d.cts +8 -0
- package/dist/src/components/GeometryProcessingPreview.d.ts +8 -0
- package/dist/src/components/MeasurePreviewLayer.d.cts +9 -0
- package/dist/src/components/MeasurePreviewLayer.d.ts +9 -0
- package/dist/src/components/MeasurementTooltip.d.cts +6 -0
- package/dist/src/components/MeasurementTooltip.d.ts +6 -0
- package/dist/src/components/OsmTraceHandler.d.cts +8 -0
- package/dist/src/components/OsmTraceHandler.d.ts +8 -0
- package/dist/src/components/PreciseCoordsOverlay.d.cts +10 -0
- package/dist/src/components/PreciseCoordsOverlay.d.ts +10 -0
- package/dist/src/components/SnapController.d.cts +9 -0
- package/dist/src/components/SnapController.d.ts +9 -0
- package/dist/src/components/TextEditOverlay.d.cts +9 -0
- package/dist/src/components/TextEditOverlay.d.ts +9 -0
- package/dist/src/components/TransformControls.d.cts +8 -0
- package/dist/src/components/TransformControls.d.ts +8 -0
- package/dist/src/components/VertexEditor.d.cts +15 -0
- package/dist/src/components/VertexEditor.d.ts +15 -0
- package/dist/src/contexts/FeatureStyleContext.d.cts +9 -0
- package/dist/src/contexts/FeatureStyleContext.d.ts +9 -0
- package/dist/src/contexts/MapControllerContext.d.cts +2 -0
- package/dist/src/contexts/MapControllerContext.d.ts +2 -0
- package/dist/src/contexts/StyleEpochContext.d.cts +7 -0
- package/dist/src/contexts/StyleEpochContext.d.ts +7 -0
- package/dist/src/elementLayers.d.cts +17 -0
- package/dist/src/elementLayers.d.ts +17 -0
- package/dist/src/hooks/lastPointer.d.cts +18 -0
- package/dist/src/hooks/lastPointer.d.ts +18 -0
- package/dist/src/hooks/useCursorWhileMode.d.cts +20 -0
- package/dist/src/hooks/useCursorWhileMode.d.ts +20 -0
- package/dist/src/hooks/useModifierDragCursor.d.cts +8 -0
- package/dist/src/hooks/useModifierDragCursor.d.ts +8 -0
- package/dist/src/index.d.cts +30 -0
- package/dist/src/index.d.ts +30 -0
- package/dist/src/store/StoreContext.d.cts +1 -0
- package/dist/src/store/StoreContext.d.ts +1 -0
- package/dist/src/utils/accentPaint.d.cts +13 -0
- package/dist/src/utils/accentPaint.d.ts +13 -0
- package/dist/src/utils/boxSelect.d.cts +4 -0
- package/dist/src/utils/boxSelect.d.ts +4 -0
- package/dist/src/utils/darkStyle.d.cts +8 -0
- package/dist/src/utils/darkStyle.d.ts +8 -0
- package/dist/src/utils/featureTooltip.d.cts +16 -0
- package/dist/src/utils/featureTooltip.d.ts +16 -0
- package/dist/src/utils/findPartAtPoint.d.cts +2 -0
- package/dist/src/utils/findPartAtPoint.d.ts +2 -0
- package/dist/src/utils/freehandCommitFlag.d.cts +2 -0
- package/dist/src/utils/freehandCommitFlag.d.ts +2 -0
- package/dist/src/utils/freshFeature.d.cts +3 -0
- package/dist/src/utils/freshFeature.d.ts +3 -0
- package/dist/src/utils/geojson.d.cts +10 -0
- package/dist/src/utils/geojson.d.ts +10 -0
- package/dist/src/utils/liveFeatureSource.d.cts +6 -0
- package/dist/src/utils/liveFeatureSource.d.ts +6 -0
- package/dist/src/utils/measureClickFlag.d.cts +2 -0
- package/dist/src/utils/measureClickFlag.d.ts +2 -0
- package/dist/src/utils/modifierDragFlag.d.cts +2 -0
- package/dist/src/utils/modifierDragFlag.d.ts +2 -0
- package/dist/src/utils/rafThrottle.d.cts +11 -0
- package/dist/src/utils/rafThrottle.d.ts +11 -0
- package/dist/src/utils/snapping.d.cts +25 -0
- package/dist/src/utils/snapping.d.ts +25 -0
- package/dist/src/utils/toolCursor.d.cts +3 -0
- package/dist/src/utils/toolCursor.d.ts +3 -0
- package/dist/streets-Bakdn2nG.cjs +1 -0
- package/dist/streets-D0l2l7xn.js +13 -0
- package/dist/style-873tzaoH.cjs +1 -0
- package/dist/style-mSgM9UsZ.js +75 -0
- package/dist/terrain-CUJe0pn4.cjs +1 -0
- package/dist/terrain-CZOhjFPd.js +13 -0
- package/package.json +124 -3
package/AGENTS.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# @element-editor/adapter-maplibre: guide for coding agents
|
|
2
|
+
|
|
3
|
+
Adds the Element editing layer (drawing, selection, vertex editing, transform, snapping) to a `maplibregl.Map` you already create. It renders no buttons: toolbars and panels come from `@element-editor/ui`. It also ships the built-in basemap catalog (`@element-editor/adapter-maplibre/basemaps`) and the `BasemapControl` picker.
|
|
4
|
+
|
|
5
|
+
Use it when the app already owns a MapLibre GL map (or a MapTiler SDK map, which extends it; Mapbox GL JS works with a `map as unknown as maplibregl.Map` cast). Keep `maplibre-gl` installed in every case: the adapter imports it at runtime (markers, handles), and it is an optional peer, so nothing installs it for you. With no existing map, use the drop-in `@element-editor/react` instead: it builds the map and the whole UI. The decision table, ref API, events and error codes are in `node_modules/@element-editor/react/AGENTS.md` (when that package is installed) and at https://elementeditor.dev/docs.
|
|
6
|
+
|
|
7
|
+
## Install and CSS
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @element-editor/adapter-maplibre @element-editor/ui maplibre-gl
|
|
11
|
+
# types/helpers (FeatureCollection, getFeatureCollectionBBox): pnpm add @element-editor/core
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Peers: `react`, `react-dom` `^19.2.0`; `maplibre-gl` `^5.5.0`. Keep all `@element-editor/*` packages on one version and list every one you import from in your `package.json`.
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import 'maplibre-gl/dist/maplibre-gl.css' // not included in Element's stylesheet
|
|
18
|
+
import '@element-editor/adapter-maplibre/style.css'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Example: your map, Element's toolbars
|
|
22
|
+
|
|
23
|
+
The `@element-editor/ui` components go in `ElementEditorControls`' `children`. `FloatingToolbar`, `LayersPanel` and `DataTablePanel` position themselves against the positioned `data-elm-theme` wrapper; `EditingToolbar` and `ActiveDrawingToolbar` render in place, so give them an absolutely positioned wrapper of your own (adding `--elm-table-offset` keeps them above the open table).
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { Suspense, useEffect, useRef, useState } from 'react'
|
|
27
|
+
import maplibregl from 'maplibre-gl'
|
|
28
|
+
import 'maplibre-gl/dist/maplibre-gl.css'
|
|
29
|
+
import {
|
|
30
|
+
ElementEditorUIProvider, GeoStoreProvider, ElementEditorControls, type ElementEditorControlsRef,
|
|
31
|
+
} from '@element-editor/adapter-maplibre'
|
|
32
|
+
import { getFeatureCollectionBBox, type FeatureCollection } from '@element-editor/core'
|
|
33
|
+
import { ThemeContext, FloatingToolbar, EditingToolbar, ActiveDrawingToolbar, LayersPanel, DataTablePanel } from '@element-editor/ui'
|
|
34
|
+
import '@element-editor/adapter-maplibre/style.css'
|
|
35
|
+
|
|
36
|
+
export default function MyMap({ data }: { data: FeatureCollection | null }) {
|
|
37
|
+
const containerRef = useRef<HTMLDivElement>(null)
|
|
38
|
+
const editorRef = useRef<ElementEditorControlsRef>(null)
|
|
39
|
+
const [map, setMap] = useState<maplibregl.Map | null>(null)
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (!containerRef.current) return
|
|
43
|
+
const m = new maplibregl.Map({
|
|
44
|
+
container: containerRef.current,
|
|
45
|
+
style: 'https://demotiles.maplibre.org/style.json',
|
|
46
|
+
center: [2.35, 48.86], // [lng, lat]
|
|
47
|
+
zoom: 5,
|
|
48
|
+
})
|
|
49
|
+
m.on('load', () => setMap(m))
|
|
50
|
+
return () => { setMap(null); m.remove() }
|
|
51
|
+
}, [])
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<ElementEditorUIProvider config={{ persistKey: 'my-map' }}>
|
|
55
|
+
<GeoStoreProvider>
|
|
56
|
+
<ThemeContext.Provider value="light">
|
|
57
|
+
<div data-elm-theme="light" style={{ position: 'relative', width: '100%', height: 600, overflow: 'hidden' }}>
|
|
58
|
+
<div ref={containerRef} style={{ width: '100%', height: '100%' }} />
|
|
59
|
+
{map && (
|
|
60
|
+
<ElementEditorControls
|
|
61
|
+
ref={editorRef}
|
|
62
|
+
map={map}
|
|
63
|
+
initialData={data}
|
|
64
|
+
onChange={(fc) => console.log(fc)}
|
|
65
|
+
onReady={(m) => {
|
|
66
|
+
const bbox = data && getFeatureCollectionBBox(data) // the adapter never moves the map itself
|
|
67
|
+
if (bbox) m.fitBounds(bbox, { padding: 40, maxZoom: 16 })
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
<FloatingToolbar />
|
|
71
|
+
{/* Not self-positioned: place them yourself (bottom centre here) */}
|
|
72
|
+
<div style={{ position: 'absolute', bottom: 'calc(var(--elm-table-offset, 0px) + 16px)', left: '50%', transform: 'translateX(-50%)', zIndex: 400, display: 'flex', gap: 8 }}>
|
|
73
|
+
<EditingToolbar />
|
|
74
|
+
<ActiveDrawingToolbar />
|
|
75
|
+
</div>
|
|
76
|
+
<LayersPanel />
|
|
77
|
+
<Suspense fallback={null}><DataTablePanel /></Suspense>
|
|
78
|
+
</ElementEditorControls>
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
81
|
+
</ThemeContext.Provider>
|
|
82
|
+
</GeoStoreProvider>
|
|
83
|
+
</ElementEditorUIProvider>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`editorRef.current` is an `ElementEditorControlsRef`: the same methods as the drop-in's `ElementEditorRef` (`getFeatureCollection`, `setFeatureCollection`, `addFeature`, `select`, `setTool`, `fitBounds`, `submit`, `undo`, …) without `getBasemap`/`setBasemap`. `getMap()` returns the `maplibregl.Map`.
|
|
89
|
+
|
|
90
|
+
## `ElementEditorControls` props
|
|
91
|
+
|
|
92
|
+
`map` (required), `initialData` (the starting data: applied at mount, or once when it first arrives while the editor is empty and unedited; later changes are ignored, use `setFeatureCollection`; the adapter never moves the map), `schema`, `tools`, `maxFeatures`, `readonly`, `layout` (`'panel' | 'minimal' | 'split'`), `maxBounds` (`[w, s, e, n]` or `[[w, s], [e, n]]`, `null` clears), `getFeatureStyle`, `onReady(map)`, `children`, and the callbacks `onChange`, `onSubmit`, `onValidationError`, `onFeatureAdd`, `onFeatureUpdate`, `onFeatureDelete`, `onSelectionChange`, `onFeatureSelect`, `onZoomChange`, `onToolChange`, `onEvent`, `onError`. `routingApiKey` is deprecated (`config.network.routing.apiKey`).
|
|
93
|
+
|
|
94
|
+
Names differ from the drop-in: `maxBounds` (not `bounds`), `onReady` (not `onMapReady`), no `initialView`, `theme`, `basemap` or `config` props. Theme, accent, `config` (network, layout, units, `persistKey`), `onEvent` and `onError` go on `ElementEditorUIProvider`.
|
|
95
|
+
|
|
96
|
+
## Basemaps
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import { BasemapControl } from '@element-editor/adapter-maplibre' // picker, inside ElementEditorControls' children
|
|
100
|
+
import { setBasemap, loadBasemapStyle, BASEMAPS } from '@element-editor/adapter-maplibre/basemaps'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- `setBasemap(map, input, { theme?, network? })` switches style and keeps Element's layers and your own sources/layers. `input` is `'streets' | 'terrain' | 'light' | 'dark' | 'osm' | 'auto'`, `{ style, id? }` or a raster `{ url, attribution, id? }`.
|
|
104
|
+
- `loadBasemapStyle(input, { theme?, network? })` returns a style for `new maplibregl.Map({ style })`.
|
|
105
|
+
- `BasemapControl` leaves your style alone until the user picks, unless you pass `value` or `defaultValue`.
|
|
106
|
+
|
|
107
|
+
## Gotchas
|
|
108
|
+
|
|
109
|
+
- `ElementEditorUIProvider` is required (`ElementEditorControls` throws without it). One `GeoStoreProvider` per editor. All editor UI and the map must sit inside a `data-elm-theme="light" | "dark"` element, or the UI renders unstyled and shortcuts don't reach it. For dark mode set `ThemeContext` to the same value (portaled menus and modals read it).
|
|
110
|
+
- Render `ElementEditorControls` after the map exists; waiting for `load` (as above) is the safe pattern. A `useRef` holding the map does not re-render, so keep the map in state.
|
|
111
|
+
- The adapter never fits the map on mount. Fit yourself (`map.fitBounds` in `onReady`, or `ref.fitBounds(getFeatureCollectionBBox(fc))`).
|
|
112
|
+
- Your own `map.setStyle()` removes your layers; Element re-adds its own `elm-*` sources/layers. Re-add yours from a `style.load` listener registered in `onReady` (it runs after Element's repair). `setBasemap` / `BasemapControl` keep your layers. Images from `map.addImage` are never carried over: re-add them on `style.load`.
|
|
113
|
+
- Add your own layers in `onReady`; pass an `elm-*` layer id as `beforeId` to put them under Element's.
|
|
114
|
+
- `DataTablePanel`, `SchemaModal`, `GeoJSONModal`, `SettingsModal`, `ShortcutsModal` and `BooleanOperations` are lazy: give each its own `<Suspense>`.
|
|
115
|
+
- Keep `getFeatureStyle` stable (module level or `useCallback`).
|
|
116
|
+
- Coordinates in Element's API are `[lng, lat]` (same as MapLibre).
|
|
117
|
+
- Next.js: load the component that creates the map with `next/dynamic` and `ssr: false`.
|
|
118
|
+
|
|
119
|
+
Docs: https://elementeditor.dev/docs/quickstart/adapter-maplibre, https://elementeditor.dev/docs/reference/adapter-maplibre, https://elementeditor.dev/docs/guides/custom-ui-with-adapters, https://elementeditor.dev/docs/guides/basemaps. Markdown: append `.md`; everything at once: https://elementeditor.dev/llms-full.txt.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michal Acler and Element Editor contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,83 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @element-editor/adapter-maplibre
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Plug Element drawing and editing tools (vertex editing, snapping, a data table, a GeoJSON inspector, undo/redo) into an existing MapLibre GL map. You keep the map; Element adds the editing layer. MapTiler SDK and Mapbox GL JS maps work too.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @element-editor/adapter-maplibre @element-editor/ui maplibre-gl
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Peer dependencies: `react` and `react-dom` `^19.2` (React 18 is not supported), `maplibre-gl` `^5.5`. `@element-editor/ui` (the toolbars and panels) comes with the adapter; list it yourself when you import from it, because strict package managers (pnpm) only resolve packages you declare. Keep all `@element-editor/*` packages on the same version.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { useEffect, useRef, useState } from 'react'
|
|
17
|
+
import maplibregl from 'maplibre-gl'
|
|
18
|
+
import 'maplibre-gl/dist/maplibre-gl.css'
|
|
19
|
+
import { ElementEditorUIProvider, GeoStoreProvider, ElementEditorControls } from '@element-editor/adapter-maplibre'
|
|
20
|
+
import '@element-editor/adapter-maplibre/style.css'
|
|
21
|
+
|
|
22
|
+
export default function MyMap() {
|
|
23
|
+
const container = useRef<HTMLDivElement>(null)
|
|
24
|
+
const [map, setMap] = useState<maplibregl.Map | null>(null)
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const m = new maplibregl.Map({
|
|
28
|
+
container: container.current!,
|
|
29
|
+
style: 'https://demotiles.maplibre.org/style.json',
|
|
30
|
+
center: [2.35, 48.86], zoom: 12,
|
|
31
|
+
})
|
|
32
|
+
setMap(m)
|
|
33
|
+
return () => { m.remove(); setMap(null) }
|
|
34
|
+
}, [])
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<ElementEditorUIProvider>
|
|
38
|
+
<GeoStoreProvider>
|
|
39
|
+
<div data-elm-theme="light" style={{ position: 'relative', height: 600 }}>
|
|
40
|
+
<div ref={container} style={{ width: '100%', height: '100%' }} />
|
|
41
|
+
{map && <ElementEditorControls map={map} onChange={(data) => console.log(data)} />}
|
|
42
|
+
</div>
|
|
43
|
+
</GeoStoreProvider>
|
|
44
|
+
</ElementEditorUIProvider>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`ElementEditorUIProvider` supplies the contexts the editor needs (and renders its own toast `<Toaster>`); `ElementEditorControls` throws without it. The `data-elm-theme` element scopes the editor's styles (the stylesheet doesn't reset your page) and its keyboard shortcuts. `ElementEditorControls` waits for the style to accept sources, so it can mount as soon as the map exists.
|
|
50
|
+
|
|
51
|
+
## Built-in basemaps
|
|
52
|
+
|
|
53
|
+
`BasemapControl` (main entry) plus the catalog in `@element-editor/adapter-maplibre/basemaps` (`BASEMAPS`, `setBasemap`, `loadBasemapStyle`, `resolveBasemap`): Streets, Terrain, Light and Dark on OpenFreeMap tiles, OpenStreetMap raster, and `'auto'` (follows the editor theme). Switching styles keeps Element's layers, and after your own `map.setStyle()` Element restores them by itself. See [the basemaps guide](https://github.com/spatibase/element/blob/main/docs/guides/basemaps.md); the default sprite loads from jsDelivr, and every host can be replaced with `config.network` ([third-party services](https://github.com/spatibase/element/blob/main/docs/guides/third-party-services.md)).
|
|
54
|
+
|
|
55
|
+
## Works with MapTiler SDK and Mapbox GL JS
|
|
56
|
+
|
|
57
|
+
The adapter only uses APIs shared between MapLibre GL, MapTiler SDK, and Mapbox GL JS (`flyTo`, `fitBounds`, `project`/`unproject`, GeoJSON sources/layers, pointer events, `queryRenderedFeatures`, etc.). Pass your map instance directly. Keep `maplibre-gl` installed either way: the adapter imports it at runtime for its map markers, and as an optional peer it isn't installed for you.
|
|
58
|
+
|
|
59
|
+
```tsx check=false
|
|
60
|
+
// MapTiler SDK — drop-in, no cast needed (their Map extends MapLibre's).
|
|
61
|
+
import * as maptilersdk from '@maptiler/sdk'
|
|
62
|
+
const map = new maptilersdk.Map({ ... })
|
|
63
|
+
<ElementEditorControls map={map} />
|
|
64
|
+
|
|
65
|
+
// Mapbox GL JS — runtime-compatible, one TypeScript cast required because
|
|
66
|
+
// @types/mapbox-gl and maplibre-gl declare separate (but structurally similar)
|
|
67
|
+
// Map types.
|
|
68
|
+
import mapboxgl from 'mapbox-gl'
|
|
69
|
+
import type { Map as MapLibreMap } from 'maplibre-gl'
|
|
70
|
+
const map = new mapboxgl.Map({ ... })
|
|
71
|
+
<ElementEditorControls map={map as unknown as MapLibreMap} />
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If you hit a runtime error specific to Mapbox or MapTiler (not a TypeScript complaint), please [file an issue](https://github.com/spatibase/element/issues) — the adapter is designed to stay on the shared subset.
|
|
75
|
+
|
|
76
|
+
## Documentation
|
|
77
|
+
|
|
78
|
+
- [Quick start](https://elementeditor.dev/docs/quickstart/adapter-maplibre)
|
|
79
|
+
- [Adapter API reference](https://elementeditor.dev/docs/reference/adapter-maplibre)
|
|
80
|
+
- [Custom UI with adapters](https://elementeditor.dev/docs/guides/custom-ui-with-adapters) · [Next.js](https://elementeditor.dev/docs/guides/nextjs)
|
|
81
|
+
- [All docs](https://elementeditor.dev/docs) · [Changelog](https://github.com/spatibase/element/blob/main/CHANGELOG.md) · [Issues](https://github.com/spatibase/element/issues)
|
|
82
|
+
|
|
83
|
+
MIT licence.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"shop":{"x":150,"y":200,"width":21,"height":21,"pixelRatio":1,"sdf":true},"shop-badge":{"x":0,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"office":{"x":172,"y":200,"width":21,"height":21,"pixelRatio":1,"sdf":true},"office-badge":{"x":25,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"town_hall":{"x":194,"y":200,"width":21,"height":21,"pixelRatio":1,"sdf":true},"town_hall-badge":{"x":50,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"golf":{"x":216,"y":200,"width":21,"height":21,"pixelRatio":1,"sdf":true},"golf-badge":{"x":75,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"fast_food":{"x":0,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"fast_food-badge":{"x":100,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"park":{"x":22,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"park-badge":{"x":125,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"bus":{"x":44,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"bus-badge":{"x":150,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"railway":{"x":66,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"railway-badge":{"x":175,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"aerialway":{"x":88,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"aerialway-badge":{"x":200,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"entrance":{"x":110,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"entrance-badge":{"x":225,"y":0,"width":24,"height":24,"pixelRatio":1,"sdf":true},"campsite":{"x":132,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"campsite-badge":{"x":0,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"laundry":{"x":154,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"laundry-badge":{"x":25,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"grocery":{"x":176,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"grocery-badge":{"x":50,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"library":{"x":198,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"library-badge":{"x":75,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"college":{"x":220,"y":225,"width":21,"height":21,"pixelRatio":1,"sdf":true},"college-badge":{"x":100,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"lodging":{"x":0,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"lodging-badge":{"x":125,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"ice_cream":{"x":22,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"ice_cream-badge":{"x":150,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"post":{"x":44,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"post-badge":{"x":175,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"cafe":{"x":66,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"cafe-badge":{"x":200,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"school":{"x":88,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"school-badge":{"x":225,"y":25,"width":24,"height":24,"pixelRatio":1,"sdf":true},"alcohol_shop":{"x":110,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"alcohol_shop-badge":{"x":0,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"bar":{"x":132,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"bar-badge":{"x":25,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"harbor":{"x":154,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"harbor-badge":{"x":50,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"car":{"x":176,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"car-badge":{"x":75,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"hospital":{"x":198,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"hospital-badge":{"x":100,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"cemetery":{"x":220,"y":247,"width":21,"height":21,"pixelRatio":1,"sdf":true},"cemetery-badge":{"x":125,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"attraction":{"x":0,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"attraction-badge":{"x":150,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"beer":{"x":22,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"beer-badge":{"x":175,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"music":{"x":44,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"music-badge":{"x":200,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"stadium":{"x":66,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"stadium-badge":{"x":225,"y":50,"width":24,"height":24,"pixelRatio":1,"sdf":true},"art_gallery":{"x":88,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"art_gallery-badge":{"x":0,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"clothing_store":{"x":110,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"clothing_store-badge":{"x":25,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"swimming":{"x":132,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"swimming-badge":{"x":50,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"castle":{"x":154,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"castle-badge":{"x":75,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"atm":{"x":176,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"atm-badge":{"x":100,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"fuel":{"x":198,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"fuel-badge":{"x":125,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"zoo":{"x":220,"y":269,"width":21,"height":21,"pixelRatio":1,"sdf":true},"zoo-badge":{"x":150,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"restaurant":{"x":0,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"restaurant-badge":{"x":175,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"cinema":{"x":22,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"cinema-badge":{"x":200,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"theatre":{"x":44,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"theatre-badge":{"x":225,"y":75,"width":24,"height":24,"pixelRatio":1,"sdf":true},"place_of_worship":{"x":66,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"place_of_worship-badge":{"x":0,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"religious_christian":{"x":88,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"religious_christian-badge":{"x":25,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"religious_jewish":{"x":110,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"religious_jewish-badge":{"x":50,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"religious_muslim":{"x":132,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"religious_muslim-badge":{"x":75,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"police":{"x":154,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"police-badge":{"x":100,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"pharmacy":{"x":176,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"pharmacy-badge":{"x":125,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"dentist":{"x":198,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"dentist-badge":{"x":150,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"doctors":{"x":220,"y":291,"width":21,"height":21,"pixelRatio":1,"sdf":true},"doctors-badge":{"x":175,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"veterinary":{"x":0,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"veterinary-badge":{"x":200,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"bank":{"x":22,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"bank-badge":{"x":225,"y":100,"width":24,"height":24,"pixelRatio":1,"sdf":true},"toilets":{"x":44,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"toilets-badge":{"x":0,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"playground":{"x":66,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"playground-badge":{"x":25,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"information":{"x":88,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"information-badge":{"x":50,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"monument":{"x":110,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"monument-badge":{"x":75,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"museum":{"x":132,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"museum-badge":{"x":100,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"parking":{"x":154,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"parking-badge":{"x":125,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"motorcycle_parking":{"x":176,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"motorcycle_parking-badge":{"x":150,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"bicycle":{"x":198,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"bicycle-badge":{"x":175,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"bicycle_rental":{"x":220,"y":313,"width":21,"height":21,"pixelRatio":1,"sdf":true},"bicycle_rental-badge":{"x":200,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"bicycle_parking":{"x":0,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"bicycle_parking-badge":{"x":225,"y":125,"width":24,"height":24,"pixelRatio":1,"sdf":true},"drinking_water":{"x":22,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"drinking_water-badge":{"x":0,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"fire_station":{"x":44,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"fire_station-badge":{"x":25,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"ferry_terminal":{"x":66,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"ferry_terminal-badge":{"x":50,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"prison":{"x":88,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"prison-badge":{"x":75,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"recycling":{"x":110,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"recycling-badge":{"x":100,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"shelter":{"x":132,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"shelter-badge":{"x":125,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"swimming_pool":{"x":154,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"swimming_pool-badge":{"x":150,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"telephone":{"x":176,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"telephone-badge":{"x":175,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"waste_basket":{"x":198,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"waste_basket-badge":{"x":200,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"dog_park":{"x":220,"y":335,"width":21,"height":21,"pixelRatio":1,"sdf":true},"dog_park-badge":{"x":225,"y":150,"width":24,"height":24,"pixelRatio":1,"sdf":true},"garden":{"x":0,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"garden-badge":{"x":0,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"ice_rink":{"x":22,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"ice_rink-badge":{"x":25,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"pitch":{"x":44,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"pitch-badge":{"x":50,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"sports_centre":{"x":66,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"sports_centre-badge":{"x":75,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"water_park":{"x":88,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"water_park-badge":{"x":100,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"aquarium":{"x":110,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"aquarium-badge":{"x":125,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"picnic_site":{"x":132,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"picnic_site-badge":{"x":150,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"theme_park":{"x":154,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"theme_park-badge":{"x":175,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"bakery":{"x":176,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"bakery-badge":{"x":200,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"butcher":{"x":198,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"butcher-badge":{"x":225,"y":175,"width":24,"height":24,"pixelRatio":1,"sdf":true},"hairdresser":{"x":220,"y":357,"width":21,"height":21,"pixelRatio":1,"sdf":true},"hairdresser-badge":{"x":0,"y":200,"width":24,"height":24,"pixelRatio":1,"sdf":true},"winter_sports":{"x":0,"y":379,"width":21,"height":21,"pixelRatio":1,"sdf":true},"winter_sports-badge":{"x":25,"y":200,"width":24,"height":24,"pixelRatio":1,"sdf":true},"airport":{"x":22,"y":379,"width":21,"height":21,"pixelRatio":1,"sdf":true},"airport-badge":{"x":50,"y":200,"width":24,"height":24,"pixelRatio":1,"sdf":true},"rail":{"x":44,"y":379,"width":21,"height":21,"pixelRatio":1,"sdf":true},"rail-badge":{"x":75,"y":200,"width":24,"height":24,"pixelRatio":1,"sdf":true},"ferry":{"x":66,"y":379,"width":21,"height":21,"pixelRatio":1,"sdf":true},"ferry-badge":{"x":100,"y":200,"width":24,"height":24,"pixelRatio":1,"sdf":true},"dot":{"x":149,"y":379,"width":12,"height":12,"pixelRatio":1,"sdf":true},"mountain":{"x":88,"y":379,"width":21,"height":21,"pixelRatio":1,"sdf":true},"oneway":{"x":131,"y":379,"width":17,"height":17,"pixelRatio":1,"sdf":true},"capital":{"x":110,"y":379,"width":20,"height":20,"pixelRatio":1,"sdf":true},"shield":{"x":125,"y":200,"width":24,"height":22,"pixelRatio":1,"sdf":true,"stretchX":[[6,18]],"stretchY":[[6,16]],"content":[6,5,18,17]}}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"shop":{"x":300,"y":400,"width":42,"height":42,"pixelRatio":2,"sdf":true},"shop-badge":{"x":0,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"office":{"x":344,"y":400,"width":42,"height":42,"pixelRatio":2,"sdf":true},"office-badge":{"x":50,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"town_hall":{"x":388,"y":400,"width":42,"height":42,"pixelRatio":2,"sdf":true},"town_hall-badge":{"x":100,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"golf":{"x":432,"y":400,"width":42,"height":42,"pixelRatio":2,"sdf":true},"golf-badge":{"x":150,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"fast_food":{"x":0,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"fast_food-badge":{"x":200,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"park":{"x":44,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"park-badge":{"x":250,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"bus":{"x":88,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"bus-badge":{"x":300,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"railway":{"x":132,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"railway-badge":{"x":350,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"aerialway":{"x":176,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"aerialway-badge":{"x":400,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"entrance":{"x":220,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"entrance-badge":{"x":450,"y":0,"width":48,"height":48,"pixelRatio":2,"sdf":true},"campsite":{"x":264,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"campsite-badge":{"x":0,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"laundry":{"x":308,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"laundry-badge":{"x":50,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"grocery":{"x":352,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"grocery-badge":{"x":100,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"library":{"x":396,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"library-badge":{"x":150,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"college":{"x":440,"y":450,"width":42,"height":42,"pixelRatio":2,"sdf":true},"college-badge":{"x":200,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"lodging":{"x":0,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"lodging-badge":{"x":250,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"ice_cream":{"x":44,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"ice_cream-badge":{"x":300,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"post":{"x":88,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"post-badge":{"x":350,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"cafe":{"x":132,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"cafe-badge":{"x":400,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"school":{"x":176,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"school-badge":{"x":450,"y":50,"width":48,"height":48,"pixelRatio":2,"sdf":true},"alcohol_shop":{"x":220,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"alcohol_shop-badge":{"x":0,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"bar":{"x":264,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"bar-badge":{"x":50,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"harbor":{"x":308,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"harbor-badge":{"x":100,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"car":{"x":352,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"car-badge":{"x":150,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"hospital":{"x":396,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"hospital-badge":{"x":200,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"cemetery":{"x":440,"y":494,"width":42,"height":42,"pixelRatio":2,"sdf":true},"cemetery-badge":{"x":250,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"attraction":{"x":0,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"attraction-badge":{"x":300,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"beer":{"x":44,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"beer-badge":{"x":350,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"music":{"x":88,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"music-badge":{"x":400,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"stadium":{"x":132,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"stadium-badge":{"x":450,"y":100,"width":48,"height":48,"pixelRatio":2,"sdf":true},"art_gallery":{"x":176,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"art_gallery-badge":{"x":0,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"clothing_store":{"x":220,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"clothing_store-badge":{"x":50,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"swimming":{"x":264,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"swimming-badge":{"x":100,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"castle":{"x":308,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"castle-badge":{"x":150,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"atm":{"x":352,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"atm-badge":{"x":200,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"fuel":{"x":396,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"fuel-badge":{"x":250,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"zoo":{"x":440,"y":538,"width":42,"height":42,"pixelRatio":2,"sdf":true},"zoo-badge":{"x":300,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"restaurant":{"x":0,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"restaurant-badge":{"x":350,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"cinema":{"x":44,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"cinema-badge":{"x":400,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"theatre":{"x":88,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"theatre-badge":{"x":450,"y":150,"width":48,"height":48,"pixelRatio":2,"sdf":true},"place_of_worship":{"x":132,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"place_of_worship-badge":{"x":0,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"religious_christian":{"x":176,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"religious_christian-badge":{"x":50,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"religious_jewish":{"x":220,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"religious_jewish-badge":{"x":100,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"religious_muslim":{"x":264,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"religious_muslim-badge":{"x":150,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"police":{"x":308,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"police-badge":{"x":200,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"pharmacy":{"x":352,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"pharmacy-badge":{"x":250,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"dentist":{"x":396,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"dentist-badge":{"x":300,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"doctors":{"x":440,"y":582,"width":42,"height":42,"pixelRatio":2,"sdf":true},"doctors-badge":{"x":350,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"veterinary":{"x":0,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"veterinary-badge":{"x":400,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"bank":{"x":44,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"bank-badge":{"x":450,"y":200,"width":48,"height":48,"pixelRatio":2,"sdf":true},"toilets":{"x":88,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"toilets-badge":{"x":0,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"playground":{"x":132,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"playground-badge":{"x":50,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"information":{"x":176,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"information-badge":{"x":100,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"monument":{"x":220,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"monument-badge":{"x":150,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"museum":{"x":264,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"museum-badge":{"x":200,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"parking":{"x":308,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"parking-badge":{"x":250,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"motorcycle_parking":{"x":352,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"motorcycle_parking-badge":{"x":300,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"bicycle":{"x":396,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"bicycle-badge":{"x":350,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"bicycle_rental":{"x":440,"y":626,"width":42,"height":42,"pixelRatio":2,"sdf":true},"bicycle_rental-badge":{"x":400,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"bicycle_parking":{"x":0,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"bicycle_parking-badge":{"x":450,"y":250,"width":48,"height":48,"pixelRatio":2,"sdf":true},"drinking_water":{"x":44,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"drinking_water-badge":{"x":0,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"fire_station":{"x":88,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"fire_station-badge":{"x":50,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"ferry_terminal":{"x":132,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"ferry_terminal-badge":{"x":100,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"prison":{"x":176,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"prison-badge":{"x":150,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"recycling":{"x":220,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"recycling-badge":{"x":200,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"shelter":{"x":264,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"shelter-badge":{"x":250,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"swimming_pool":{"x":308,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"swimming_pool-badge":{"x":300,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"telephone":{"x":352,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"telephone-badge":{"x":350,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"waste_basket":{"x":396,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"waste_basket-badge":{"x":400,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"dog_park":{"x":440,"y":670,"width":42,"height":42,"pixelRatio":2,"sdf":true},"dog_park-badge":{"x":450,"y":300,"width":48,"height":48,"pixelRatio":2,"sdf":true},"garden":{"x":0,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"garden-badge":{"x":0,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"ice_rink":{"x":44,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"ice_rink-badge":{"x":50,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"pitch":{"x":88,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"pitch-badge":{"x":100,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"sports_centre":{"x":132,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"sports_centre-badge":{"x":150,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"water_park":{"x":176,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"water_park-badge":{"x":200,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"aquarium":{"x":220,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"aquarium-badge":{"x":250,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"picnic_site":{"x":264,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"picnic_site-badge":{"x":300,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"theme_park":{"x":308,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"theme_park-badge":{"x":350,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"bakery":{"x":352,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"bakery-badge":{"x":400,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"butcher":{"x":396,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"butcher-badge":{"x":450,"y":350,"width":48,"height":48,"pixelRatio":2,"sdf":true},"hairdresser":{"x":440,"y":714,"width":42,"height":42,"pixelRatio":2,"sdf":true},"hairdresser-badge":{"x":0,"y":400,"width":48,"height":48,"pixelRatio":2,"sdf":true},"winter_sports":{"x":0,"y":758,"width":42,"height":42,"pixelRatio":2,"sdf":true},"winter_sports-badge":{"x":50,"y":400,"width":48,"height":48,"pixelRatio":2,"sdf":true},"airport":{"x":44,"y":758,"width":42,"height":42,"pixelRatio":2,"sdf":true},"airport-badge":{"x":100,"y":400,"width":48,"height":48,"pixelRatio":2,"sdf":true},"rail":{"x":88,"y":758,"width":42,"height":42,"pixelRatio":2,"sdf":true},"rail-badge":{"x":150,"y":400,"width":48,"height":48,"pixelRatio":2,"sdf":true},"ferry":{"x":132,"y":758,"width":42,"height":42,"pixelRatio":2,"sdf":true},"ferry-badge":{"x":200,"y":400,"width":48,"height":48,"pixelRatio":2,"sdf":true},"dot":{"x":298,"y":758,"width":24,"height":24,"pixelRatio":2,"sdf":true},"mountain":{"x":176,"y":758,"width":42,"height":42,"pixelRatio":2,"sdf":true},"oneway":{"x":262,"y":758,"width":34,"height":34,"pixelRatio":2,"sdf":true},"capital":{"x":220,"y":758,"width":40,"height":40,"pixelRatio":2,"sdf":true},"shield":{"x":250,"y":400,"width":48,"height":44,"pixelRatio":2,"sdf":true,"stretchX":[[12,36]],"stretchY":[[12,32]],"content":[12,10,36,34]}}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|