solid-map-gl 1.13.0 → 2.0.1
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/README.md +157 -30
- package/dist/index.d.ts +489 -0
- package/dist/index.js +11 -0
- package/dist/index.jsx +2320 -0
- package/package.json +51 -35
- package/dist/esm/index.js +0 -2
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/styles.css +0 -1
- package/dist/source/components/Atmosphere/index.jsx +0 -13
- package/dist/source/components/Camera/index.jsx +0 -108
- package/dist/source/components/Control/index.jsx +0 -33
- package/dist/source/components/Draw/drawingStyles.jsx +0 -225
- package/dist/source/components/Draw/index.jsx +0 -52
- package/dist/source/components/Draw/modes/line_string.js +0 -43
- package/dist/source/components/Draw/modes/measurements.js +0 -76
- package/dist/source/components/Draw/modes/multi_point.js +0 -37
- package/dist/source/components/Draw/modes/point.js +0 -25
- package/dist/source/components/Draw/modes/polygon.js +0 -25
- package/dist/source/components/Draw/modes/radius.js +0 -138
- package/dist/source/components/Draw/modes/rectangle.js +0 -118
- package/dist/source/components/Draw/modes/rectangle_assisted.js +0 -233
- package/dist/source/components/Image/index.jsx +0 -135
- package/dist/source/components/Layer/index.jsx +0 -125
- package/dist/source/components/Layer3D/index.jsx +0 -330
- package/dist/source/components/Light/index.jsx +0 -10
- package/dist/source/components/MapGL/index.jsx +0 -273
- package/dist/source/components/MapProvider/index.jsx +0 -9
- package/dist/source/components/Marker/index.jsx +0 -57
- package/dist/source/components/Popup/index.jsx +0 -38
- package/dist/source/components/Source/index.jsx +0 -89
- package/dist/source/components/Terrain/index.jsx +0 -30
- package/dist/source/events.js +0 -78
- package/dist/source/index.jsx +0 -14
- package/dist/source/mapStyles.js +0 -116
- package/dist/source/styles.js +0 -62
- package/dist/types/components/Atmosphere/index.d.ts +0 -8
- package/dist/types/components/Camera/index.d.ts +0 -54
- package/dist/types/components/Control/index.d.ts +0 -15
- package/dist/types/components/Draw/drawingStyles.d.ts +0 -20
- package/dist/types/components/Draw/index.d.ts +0 -16
- package/dist/types/components/Draw/modes/line_string.d.ts +0 -2
- package/dist/types/components/Draw/modes/multi_point.d.ts +0 -2
- package/dist/types/components/Draw/modes/point.d.ts +0 -2
- package/dist/types/components/Draw/modes/polygon.d.ts +0 -2
- package/dist/types/components/Draw/modes/radius.d.ts +0 -2
- package/dist/types/components/Draw/modes/rectangle.d.ts +0 -2
- package/dist/types/components/Draw/modes/rectangle_assisted.d.ts +0 -18
- package/dist/types/components/Image/index.d.ts +0 -28
- package/dist/types/components/Layer/index.d.ts +0 -32
- package/dist/types/components/Layer3D/index.d.ts +0 -22
- package/dist/types/components/Light/index.d.ts +0 -8
- package/dist/types/components/MapGL/index.d.ts +0 -96
- package/dist/types/components/MapProvider/index.d.ts +0 -11
- package/dist/types/components/Marker/index.d.ts +0 -28
- package/dist/types/components/Popup/index.d.ts +0 -18
- package/dist/types/components/Source/index.d.ts +0 -13
- package/dist/types/components/Terrain/index.d.ts +0 -7
- package/dist/types/events.d.ts +0 -103
- package/dist/types/index.d.ts +0 -16
- package/dist/types/mapStyles.d.ts +0 -2
- package/dist/types/styles.d.ts +0 -2
package/dist/index.jsx
ADDED
|
@@ -0,0 +1,2320 @@
|
|
|
1
|
+
// src/components/MapGL/index.tsx
|
|
2
|
+
import {
|
|
3
|
+
createSignal,
|
|
4
|
+
createEffect,
|
|
5
|
+
onMount,
|
|
6
|
+
onCleanup,
|
|
7
|
+
on
|
|
8
|
+
} from "solid-js";
|
|
9
|
+
|
|
10
|
+
// src/components/MapProvider/index.tsx
|
|
11
|
+
import { createContext, useContext } from "solid-js";
|
|
12
|
+
import { createStore } from "solid-js/store";
|
|
13
|
+
var defaultState = { map: null, mapLib: null, isMapLibre: false };
|
|
14
|
+
var MapContext = createContext([defaultState]);
|
|
15
|
+
var useMapContext = () => useContext(MapContext);
|
|
16
|
+
var MapProvider = (props) => {
|
|
17
|
+
const [state, setState] = createStore({ ...defaultState });
|
|
18
|
+
props.map && setState("map", props.map);
|
|
19
|
+
props.mapLib && setState("mapLib", props.mapLib);
|
|
20
|
+
setState("isMapLibre", !!props.isMapLibre);
|
|
21
|
+
return <MapContext.Provider value={[state]}>{props.children}</MapContext.Provider>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/events.ts
|
|
25
|
+
var mapEvents = [
|
|
26
|
+
"onMouseDown",
|
|
27
|
+
"onMouseUp",
|
|
28
|
+
"onMouseOver",
|
|
29
|
+
"onMouseOut",
|
|
30
|
+
"onMouseMove",
|
|
31
|
+
"onMouseEnter",
|
|
32
|
+
"onMouseLeave",
|
|
33
|
+
"onPreClick",
|
|
34
|
+
"onClick",
|
|
35
|
+
"onDblClick",
|
|
36
|
+
"onContextMenu",
|
|
37
|
+
"onTouchStart",
|
|
38
|
+
"onTouchEnd",
|
|
39
|
+
"onTouchCancel",
|
|
40
|
+
"onWheel",
|
|
41
|
+
"onResize",
|
|
42
|
+
"onRemove",
|
|
43
|
+
"onTouchMove",
|
|
44
|
+
"onMoveStart",
|
|
45
|
+
"onMove",
|
|
46
|
+
"onMoveEnd",
|
|
47
|
+
"onDragStart",
|
|
48
|
+
"onDrag",
|
|
49
|
+
"onDragEnd",
|
|
50
|
+
"onZoomStart",
|
|
51
|
+
"onZoom",
|
|
52
|
+
"onZoomEnd",
|
|
53
|
+
"onRotateStart",
|
|
54
|
+
"onRotate",
|
|
55
|
+
"onRotatEnd",
|
|
56
|
+
"onPitchStart",
|
|
57
|
+
"onPitch",
|
|
58
|
+
"onPitchEnd",
|
|
59
|
+
"onBoxZoomStart",
|
|
60
|
+
"onBoxZoomEnd",
|
|
61
|
+
"onBoxZoomCancel",
|
|
62
|
+
"onWebglContextLost",
|
|
63
|
+
"onWebglContextRestored",
|
|
64
|
+
"onLoad",
|
|
65
|
+
"onRender",
|
|
66
|
+
"onIdle",
|
|
67
|
+
"onError",
|
|
68
|
+
"onData",
|
|
69
|
+
"onStyleData",
|
|
70
|
+
"onSourceData",
|
|
71
|
+
"onDataLoading",
|
|
72
|
+
"onStyleDataLoading",
|
|
73
|
+
"onSourceDataLoading",
|
|
74
|
+
"onStyleImageMissing"
|
|
75
|
+
];
|
|
76
|
+
var layerEvents = [
|
|
77
|
+
"onMouseDown",
|
|
78
|
+
"onMouseUp",
|
|
79
|
+
"onMouseOver",
|
|
80
|
+
"onMouseOut",
|
|
81
|
+
"onMouseMove",
|
|
82
|
+
"onMouseEnter",
|
|
83
|
+
"onMouseLeave",
|
|
84
|
+
"onClick",
|
|
85
|
+
"onDblClick",
|
|
86
|
+
"onContextMenu",
|
|
87
|
+
"onTouchStart",
|
|
88
|
+
"onTouchEnd",
|
|
89
|
+
"onTouchCancel"
|
|
90
|
+
];
|
|
91
|
+
var drawEvents = [
|
|
92
|
+
"onCreate",
|
|
93
|
+
"onDelete",
|
|
94
|
+
"onCombine",
|
|
95
|
+
"onUncombine",
|
|
96
|
+
"onUpdate",
|
|
97
|
+
"onSelectionchange",
|
|
98
|
+
"onModechange",
|
|
99
|
+
"onRender",
|
|
100
|
+
"onActionable"
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
// src/mapStyles.ts
|
|
104
|
+
var mapBase = "mapbox://styles/mapbox";
|
|
105
|
+
var gitBase = "https://raw.githubusercontent.com/";
|
|
106
|
+
var gishub = "https://raw.githubusercontent.com/GIShub4/map-styles/main/";
|
|
107
|
+
var hereBase = "https://assets.vector.hereapi.com/styles/";
|
|
108
|
+
var vectorStyleList = {
|
|
109
|
+
mb: {
|
|
110
|
+
standard: `${mapBase}/standard`,
|
|
111
|
+
light: `${mapBase}/light-v11`,
|
|
112
|
+
dark: `${mapBase}/dark-v11`,
|
|
113
|
+
street: `${mapBase}/streets-v12`,
|
|
114
|
+
outdoor: `${mapBase}/outdoors-v12`,
|
|
115
|
+
sat: `${mapBase}/satellite-v9`,
|
|
116
|
+
sat_street: `${mapBase}/satellite-streets-v12`,
|
|
117
|
+
nav_base: `${mapBase}/navigation-guidance-day-v4`,
|
|
118
|
+
nav_base_night: `${mapBase}/navigation-guidance-night-v4`,
|
|
119
|
+
nav: `${mapBase}/navigation-day-v1`,
|
|
120
|
+
nav_night: `${mapBase}/navigation-night-v1`,
|
|
121
|
+
basic: `${mapBase}/cjf4m44iw0uza2spb3q0a7s41`,
|
|
122
|
+
monochrome: `${mapBase}/cjv6rzz4j3m4b1fqcchuxclhb`,
|
|
123
|
+
leshine: `${mapBase}/cjcunv5ae262f2sm9tfwg8i0w`,
|
|
124
|
+
icecream: `${mapBase}/cj7t3i5yj0unt2rmt3y4b5e32`,
|
|
125
|
+
cali: `${mapBase}/cjerxnqt3cgvp2rmyuxbeqme7`,
|
|
126
|
+
northstar: `${mapBase}/cj44mfrt20f082snokim4ungi`,
|
|
127
|
+
mineral: `${mapBase}/cjtep62gq54l21frr1whf27ak`,
|
|
128
|
+
moonlight: `${mapBase}/cj3kbeqzo00022smj7akz3o1e`,
|
|
129
|
+
frank: `${mapBase}-map-design/ckshxkppe0gge18nz20i0nrwq`,
|
|
130
|
+
minimo: `${mapBase}-map-design/cksjc2nsq1bg117pnekb655h1`,
|
|
131
|
+
decimal: `${mapBase}-map-design/ck4014y110wt61ctt07egsel6`,
|
|
132
|
+
stand: `${mapBase}-map-design/ckr0svm3922ki18qntevm857n`,
|
|
133
|
+
blueprint: `${mapBase}-map-design/cks97e1e37nsd17nzg7p0308g`,
|
|
134
|
+
bubble: `${mapBase}-map-design/cksysy2nl62zp17quosctdtcc`,
|
|
135
|
+
pencil: `${mapBase}-map-design/cks9iema71es417mlrft4go2k`,
|
|
136
|
+
swiss_ski: `${gitBase}mapbox/mapbox-gl-swiss-ski-style/master/cij1zoclj002y8rkkdjl69psd.json`,
|
|
137
|
+
vintage: `${gitBase}mapbox/mapbox-gl-vintage-style/master/cif5p01n202nisaktvljx9mv3.json`,
|
|
138
|
+
whaam: `${gitBase}mapbox/mapbox-gl-whaam-style/master/cii8323c8004w0nlvtss3dbm2.json`,
|
|
139
|
+
neon: `${gitBase}NatEvatt/awesome-mapbox-gl-styles/master/styles/Neon/style.json`,
|
|
140
|
+
camoflauge: `${gitBase}jingsam/mapbox-gl-styles/master/Camouflage.json`,
|
|
141
|
+
emerald: `${gitBase}jingsam/mapbox-gl-styles/master/Emerald.json`,
|
|
142
|
+
runner: `${gitBase}jingsam/mapbox-gl-styles/master/Runner.json`,
|
|
143
|
+
x_ray: `${gitBase}jingsam/mapbox-gl-styles/master/X-ray.json`
|
|
144
|
+
},
|
|
145
|
+
here: {
|
|
146
|
+
base: `${hereBase}berlin/base/mapbox/tilezen?apikey={apikey}`,
|
|
147
|
+
day: `${hereBase}berlin/day/mapbox/tilezen?apikey={apikey}`,
|
|
148
|
+
night: `${hereBase}berlin/night/mapbox/tilezen?apikey={apikey}`
|
|
149
|
+
},
|
|
150
|
+
esri: {
|
|
151
|
+
blueprint: `${gishub}esri:blueprint.json`,
|
|
152
|
+
charted_territory: `${gishub}esri:charted-territory.json`,
|
|
153
|
+
colored_pencil: `${gishub}esri:colored-pencil.json`,
|
|
154
|
+
community: `${gishub}esri:community.json`,
|
|
155
|
+
mid_century: `${gishub}esri:mid-century.json`,
|
|
156
|
+
modern_antique: `${gishub}esri:modern-antique.json`,
|
|
157
|
+
nat_geo: `${gishub}esri:national-geographic.json`,
|
|
158
|
+
newspaper: `${gishub}esri:newspaper.json`,
|
|
159
|
+
open_street_map: `${gishub}esri:open-street-map.json`,
|
|
160
|
+
light_gray_canvas: `${gishub}esri:light-gray-canvas.json`,
|
|
161
|
+
dark_gray_canvas: `${gishub}esri:dark-gray-canvas.json`,
|
|
162
|
+
human_geo_light: `${gishub}esri:human-geography-light.json`,
|
|
163
|
+
human_geo_dark: `${gishub}esri:human-geography-dark.json`,
|
|
164
|
+
world_navigation: `${gishub}esri:world-navigation.json`,
|
|
165
|
+
world_street: `${gishub}esri:world-street.json`,
|
|
166
|
+
world_street_night: `${gishub}esri:world-street-night.json`,
|
|
167
|
+
world_terrain: `${gishub}esri:world-terrain.json`,
|
|
168
|
+
world_terrain_hybrid: `${gishub}esri:world-terrain-hybrid.json`,
|
|
169
|
+
world_topographic: `${gishub}esri:world-topographic.json`,
|
|
170
|
+
chromium: `${gishub}esri:chromium.json`,
|
|
171
|
+
dreamcatcher: `${gishub}esri:dreamcatcher.json`,
|
|
172
|
+
seahaven: `${gishub}esri:seahaven.json`,
|
|
173
|
+
sangria: `${gishub}esri:sangria.json`,
|
|
174
|
+
mercurial: `${gishub}esri:mercurial.json`,
|
|
175
|
+
imagery: `${gishub}esri:imagery.json`,
|
|
176
|
+
imagery_hybrid: `${gishub}esri:imagery-hybrid.json`,
|
|
177
|
+
firefly: `${gishub}esri:firefly.json`,
|
|
178
|
+
firefly_hybrid: `${gishub}esri:firefly-hybrid.json`,
|
|
179
|
+
oceans: `${gishub}esri:oceans.json`
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
var carto = "https://{s}.basemaps.cartocdn.com/rastertiles/";
|
|
183
|
+
var stamen = "https://stamen-tiles-{s}.a.ssl.fastly.net/";
|
|
184
|
+
var tf = "https://{s}.tile.thunderforest.com/";
|
|
185
|
+
var rasterStyleList = {
|
|
186
|
+
osm: {
|
|
187
|
+
org: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
188
|
+
human: "https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
|
|
189
|
+
cycle: "https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png",
|
|
190
|
+
topo: "https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
191
|
+
_copy: '<a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap</a>'
|
|
192
|
+
},
|
|
193
|
+
carto: {
|
|
194
|
+
voyager: `${carto}voyager_labels_under/{z}/{x}/{y}{r}.png`,
|
|
195
|
+
positron: `${carto}light_all/{z}/{x}/{y}{r}.png`,
|
|
196
|
+
dark: `${carto}dark_all/{z}/{x}/{y}{r}.png`,
|
|
197
|
+
_copy: '<a href="https://carto.com/attribution" target="_blank">© Carto</a>'
|
|
198
|
+
},
|
|
199
|
+
stamen: {
|
|
200
|
+
toner: `${stamen}toner/{z}/{x}/{y}{r}.png`,
|
|
201
|
+
toner_lite: `${stamen}toner-lite/{z}/{x}/{y}{r}.png`,
|
|
202
|
+
watercolor: `${stamen}watercolor/{z}/{x}/{y}.png`,
|
|
203
|
+
terrain: `${stamen}terrain/{z}/{x}/{y}{r}.png`,
|
|
204
|
+
_copy: '<a href="https://stamen.com/privacy-policy" target="_blank">© Stamen Design</a>'
|
|
205
|
+
},
|
|
206
|
+
tf: {
|
|
207
|
+
cycle: `${tf}cycle/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
208
|
+
trans: `${tf}transport/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
209
|
+
trans_dark: `${tf}transport-dark/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
210
|
+
landscape: `${tf}landscape/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
211
|
+
outdoors: `${tf}outdoors/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
212
|
+
neighbourhood: `${tf}neighbourhood/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
213
|
+
spinal: `${tf}spinal-map/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
214
|
+
pioneer: `${tf}pioneer/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
215
|
+
atlas: `${tf}atlas/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
216
|
+
mobile: `${tf}mobile-atlas/{z}/{x}/{y}{r}.png?apikey={apikey}`,
|
|
217
|
+
_copy: '<a href="https://thunderforest.com/privacy" target="_blank">© Thunderforest</a>'
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// src/components/MapGL/index.tsx
|
|
222
|
+
var MapGL = (props) => {
|
|
223
|
+
let map;
|
|
224
|
+
let mapRef;
|
|
225
|
+
let resizeObserver;
|
|
226
|
+
let mutationObserver;
|
|
227
|
+
let mapLib;
|
|
228
|
+
let isMapLibre = false;
|
|
229
|
+
const [mapLoaded, setMapLoaded] = createSignal(null);
|
|
230
|
+
const [darkMode, setDarkMode] = createSignal(
|
|
231
|
+
typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches || typeof document !== "undefined" && document.body.classList.contains("dark")
|
|
232
|
+
);
|
|
233
|
+
let interruptingEase = false;
|
|
234
|
+
let expectingOwnEcho = false;
|
|
235
|
+
const debug = (text, value) => (props.debug || props.debugEvents) && console.debug("%c[MapGL]", "color: #0ea5e9", text, value || "");
|
|
236
|
+
const getStyle = (light, dark) => {
|
|
237
|
+
const style = darkMode() && dark ? dark : light;
|
|
238
|
+
return typeof style === "string" || style instanceof String ? style?.split(":").reduce((p, c) => p && p[c], vectorStyleList)?.replace(
|
|
239
|
+
"{apikey}",
|
|
240
|
+
//@ts-ignore
|
|
241
|
+
props.apikey || import.meta.env?.VITE_VECTOR_API_KEY
|
|
242
|
+
) || style : style;
|
|
243
|
+
};
|
|
244
|
+
onMount(async () => {
|
|
245
|
+
mapLib = props.mapLib || await import("mapbox-gl");
|
|
246
|
+
if (!mapLib.Map) mapLib = window["maplibregl"] || window["mapboxgl"];
|
|
247
|
+
if (typeof mapLib.supported === "function" && !mapLib.supported())
|
|
248
|
+
throw new Error("Mapbox GL not supported");
|
|
249
|
+
isMapLibre = typeof mapLib.Map?.prototype?.setConfigProperty !== "function";
|
|
250
|
+
debug(`Map (v${mapLib.version}) loading...`);
|
|
251
|
+
map = new mapLib.Map({
|
|
252
|
+
accessToken: props.options?.accessToken || //@ts-ignore
|
|
253
|
+
import.meta.env?.VITE_MAPBOX_ACCESS_TOKEN,
|
|
254
|
+
interactive: props.options?.interactive || !!props.onViewportChange,
|
|
255
|
+
...props.options,
|
|
256
|
+
...props.viewport,
|
|
257
|
+
projection: props.options?.projection,
|
|
258
|
+
container: mapRef,
|
|
259
|
+
style: getStyle(props.options?.style, props.darkStyle),
|
|
260
|
+
fitBoundsOptions: { padding: props.viewport?.padding }
|
|
261
|
+
});
|
|
262
|
+
map.debug = props.debug;
|
|
263
|
+
map.debugEvents = props.debugEvents;
|
|
264
|
+
map.sourceIdList = [];
|
|
265
|
+
map.layerIdList = [];
|
|
266
|
+
map.isMapLibre = isMapLibre;
|
|
267
|
+
mapEvents.forEach((item) => {
|
|
268
|
+
const prop = props[item];
|
|
269
|
+
if (prop) {
|
|
270
|
+
const event = item.slice(2).toLowerCase();
|
|
271
|
+
if (typeof prop === "function") {
|
|
272
|
+
map.on(event, (evt) => {
|
|
273
|
+
setTimeout(() => {
|
|
274
|
+
if (evt.clickOnLayer) return;
|
|
275
|
+
prop(evt);
|
|
276
|
+
props.debugEvents && debug(`Map '${event}' event:`, evt);
|
|
277
|
+
}, 0);
|
|
278
|
+
});
|
|
279
|
+
} else {
|
|
280
|
+
Object.keys(prop).forEach((layerId) => {
|
|
281
|
+
map.on(event, layerId, (evt) => {
|
|
282
|
+
setTimeout(() => {
|
|
283
|
+
if (evt.clickOnLayer) return;
|
|
284
|
+
prop[layerId](evt);
|
|
285
|
+
props.debugEvents && debug(`Map '${event}' event on '${layerId}':`, evt);
|
|
286
|
+
}, 0);
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
map.once("load", () => {
|
|
293
|
+
setMapLoaded(map);
|
|
294
|
+
debug("Map loaded");
|
|
295
|
+
["mousedown", "touchstart", "wheel"].forEach(
|
|
296
|
+
(event) => map.on(
|
|
297
|
+
event,
|
|
298
|
+
(evt) => !evt.rotate && props.onUserInteraction?.(true)
|
|
299
|
+
)
|
|
300
|
+
);
|
|
301
|
+
["moveend", "mouseup", "touchend"].forEach(
|
|
302
|
+
(event) => map.on(
|
|
303
|
+
event,
|
|
304
|
+
(evt) => !evt.rotate && props.onUserInteraction?.(false)
|
|
305
|
+
)
|
|
306
|
+
);
|
|
307
|
+
const darkTheme = typeof window !== "undefined" && window?.matchMedia("(prefers-color-scheme: dark)");
|
|
308
|
+
darkTheme?.addEventListener("change", () => {
|
|
309
|
+
setDarkMode(darkTheme.matches);
|
|
310
|
+
debug("Set dark theme to:", darkTheme.matches?.toString());
|
|
311
|
+
});
|
|
312
|
+
mutationObserver = new MutationObserver(() => {
|
|
313
|
+
const darkTheme2 = document.body.classList.contains("dark");
|
|
314
|
+
setDarkMode(darkTheme2);
|
|
315
|
+
debug("Set theme to:", darkTheme2);
|
|
316
|
+
});
|
|
317
|
+
mutationObserver.observe(document.body, { attributes: true });
|
|
318
|
+
if (!props.disableResize) {
|
|
319
|
+
resizeObserver = new ResizeObserver(() => {
|
|
320
|
+
setTimeout(() => {
|
|
321
|
+
map?.resize();
|
|
322
|
+
}, 0);
|
|
323
|
+
debug("Map resized");
|
|
324
|
+
});
|
|
325
|
+
resizeObserver.observe(mapRef);
|
|
326
|
+
}
|
|
327
|
+
map.on("move", (event) => {
|
|
328
|
+
const viewport = {
|
|
329
|
+
...props.viewport,
|
|
330
|
+
id: props.id,
|
|
331
|
+
point: {
|
|
332
|
+
x: event.originalEvent?.x,
|
|
333
|
+
y: event.originalEvent?.y
|
|
334
|
+
},
|
|
335
|
+
center: props.viewport?.center?.lat ? map.getCenter() : [map.getCenter().lng, map.getCenter().lat],
|
|
336
|
+
zoom: map.getZoom(),
|
|
337
|
+
pitch: map.getPitch(),
|
|
338
|
+
bearing: map.getBearing(),
|
|
339
|
+
inTransit: true,
|
|
340
|
+
bounds: null
|
|
341
|
+
// !internal()
|
|
342
|
+
// ? props.viewport?.center?.lat
|
|
343
|
+
// ? map.getBounds()
|
|
344
|
+
// : [
|
|
345
|
+
// [
|
|
346
|
+
// map.getBounds().getNorthEast().lng,
|
|
347
|
+
// map.getBounds().getNorthEast().lat,
|
|
348
|
+
// ],
|
|
349
|
+
// [
|
|
350
|
+
// map.getBounds().getSouthWest().lng,
|
|
351
|
+
// map.getBounds().getSouthWest().lat,
|
|
352
|
+
// ],
|
|
353
|
+
// ]
|
|
354
|
+
// : null,
|
|
355
|
+
};
|
|
356
|
+
if (!event.viewport && props.onViewportChange) {
|
|
357
|
+
expectingOwnEcho = true;
|
|
358
|
+
props.onViewportChange(viewport);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
map.on("moveend", (event) => {
|
|
362
|
+
if (interruptingEase) return;
|
|
363
|
+
if (event.rotate) return;
|
|
364
|
+
if (!props.onViewportChange) return;
|
|
365
|
+
const viewport = { ...props.viewport, inTransit: false };
|
|
366
|
+
expectingOwnEcho = true;
|
|
367
|
+
props.onViewportChange(viewport);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
createEffect(
|
|
372
|
+
on(
|
|
373
|
+
() => props.viewport,
|
|
374
|
+
(vp) => {
|
|
375
|
+
if (props.id !== vp?.id) return;
|
|
376
|
+
if (expectingOwnEcho) {
|
|
377
|
+
expectingOwnEcho = false;
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
const viewport = {
|
|
381
|
+
...vp,
|
|
382
|
+
...vp.bounds ? map.cameraForBounds(vp.bounds, {
|
|
383
|
+
bearing: vp?.bearing,
|
|
384
|
+
pitch: vp?.pitch,
|
|
385
|
+
padding: vp?.padding
|
|
386
|
+
}) : null
|
|
387
|
+
};
|
|
388
|
+
interruptingEase = true;
|
|
389
|
+
map.stop();
|
|
390
|
+
interruptingEase = false;
|
|
391
|
+
map[props.transitionType || "flyTo"](viewport);
|
|
392
|
+
debug(
|
|
393
|
+
`Update Viewport (${props.transitionType || "flyTo"}):`,
|
|
394
|
+
viewport
|
|
395
|
+
);
|
|
396
|
+
},
|
|
397
|
+
{ defer: true }
|
|
398
|
+
)
|
|
399
|
+
);
|
|
400
|
+
createEffect(() => {
|
|
401
|
+
const loadedMap = mapLoaded();
|
|
402
|
+
if (typeof loadedMap?.setConfigProperty !== "function") {
|
|
403
|
+
if (loadedMap && props.config && Object.keys(props.config).length) {
|
|
404
|
+
debug(
|
|
405
|
+
"Config prop is set but this map library has no setConfigProperty (Mapbox Standard Style only) \u2014 skipping"
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
for (const key in props.config) {
|
|
411
|
+
if (!key || key === "id") continue;
|
|
412
|
+
const id = props.config?.id || "basemap";
|
|
413
|
+
const value = props.config[key];
|
|
414
|
+
loadedMap.setConfigProperty(id, key, value);
|
|
415
|
+
debug(`Set Config (${id}:${key}) to:`, value);
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
createEffect(() => {
|
|
419
|
+
const proj = props.options?.projection;
|
|
420
|
+
if (!map || !proj) return;
|
|
421
|
+
map.setProjection(proj);
|
|
422
|
+
debug("Set Projection to:", proj);
|
|
423
|
+
});
|
|
424
|
+
createEffect(() => {
|
|
425
|
+
const cur = props.cursorStyle;
|
|
426
|
+
if (!map || !cur) return;
|
|
427
|
+
map.getCanvas().style.cursor = cur;
|
|
428
|
+
debug("Set Cursor to:", cur);
|
|
429
|
+
});
|
|
430
|
+
const insertLayers = (list, layers) => {
|
|
431
|
+
layers.forEach((layer) => {
|
|
432
|
+
const index = list.findIndex(
|
|
433
|
+
(i) => layer.metadata.smg.beforeType ? i.type === layer.metadata.smg.beforeType : i.id === layer.metadata.smg.beforeId
|
|
434
|
+
);
|
|
435
|
+
list = index === -1 ? [...list, layer] : [...list.slice(0, index), layer, ...list.slice(index)];
|
|
436
|
+
});
|
|
437
|
+
return list;
|
|
438
|
+
};
|
|
439
|
+
createEffect((prev) => {
|
|
440
|
+
const style = getStyle(props.options?.style, props.darkStyle);
|
|
441
|
+
if (map?.isStyleLoaded() && prev !== style) {
|
|
442
|
+
const oldStyle = map.getStyle();
|
|
443
|
+
const oldLayers = oldStyle.layers.filter(
|
|
444
|
+
(l) => map.layerIdList.includes(l.id)
|
|
445
|
+
);
|
|
446
|
+
const oldSources = Object.keys(oldStyle.sources).filter((s) => map.sourceIdList.includes(s)).reduce((obj, key) => ({ ...obj, [key]: oldStyle.sources[key] }), {});
|
|
447
|
+
const diff2 = props.shouldDiffStyle ? props.shouldDiffStyle(prev, style) : true;
|
|
448
|
+
map.setStyle(style, diff2 ? void 0 : { diff: false });
|
|
449
|
+
map.once("styledata", () => {
|
|
450
|
+
if (!oldLayers) return;
|
|
451
|
+
const newStyle = map.getStyle();
|
|
452
|
+
map.setStyle({
|
|
453
|
+
...newStyle,
|
|
454
|
+
sources: { ...newStyle.sources, ...oldSources },
|
|
455
|
+
layers: insertLayers(newStyle.layers, oldLayers),
|
|
456
|
+
fog: oldStyle.fog,
|
|
457
|
+
terrain: oldStyle.terrain,
|
|
458
|
+
light: oldStyle.light
|
|
459
|
+
});
|
|
460
|
+
debug("Set Mapstyle to:", style);
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
return style;
|
|
464
|
+
}, props.options?.style);
|
|
465
|
+
[
|
|
466
|
+
"showTileBoundaries",
|
|
467
|
+
"showTerrainWireframe",
|
|
468
|
+
"showCollisionBoxes",
|
|
469
|
+
"showPadding",
|
|
470
|
+
"showOverdrawInspector"
|
|
471
|
+
].forEach((item) => {
|
|
472
|
+
createEffect(() => {
|
|
473
|
+
const prop = props[item];
|
|
474
|
+
if (!map || !prop) return;
|
|
475
|
+
map[item] = prop;
|
|
476
|
+
debug(`Set ${item} to:`, prop);
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
onCleanup(() => {
|
|
480
|
+
resizeObserver?.disconnect();
|
|
481
|
+
mutationObserver?.disconnect();
|
|
482
|
+
map?.remove();
|
|
483
|
+
debug("Map removed");
|
|
484
|
+
});
|
|
485
|
+
return <div
|
|
486
|
+
ref={mapRef}
|
|
487
|
+
id={props.id}
|
|
488
|
+
class={props?.class}
|
|
489
|
+
classList={props?.classList}
|
|
490
|
+
style={{ width: "100%", height: "100%", ...props.style }}
|
|
491
|
+
>
|
|
492
|
+
{mapLoaded() && <MapProvider map={mapLoaded()} mapLib={mapLib} isMapLibre={isMapLibre}>
|
|
493
|
+
<style>{`.overlay{position:relative;width:100%;height:100%;pointer-events:none}:where(.overlay>*){pointer-events:auto}`}</style>
|
|
494
|
+
<div class="overlay">{props.children}</div>
|
|
495
|
+
</MapProvider>}
|
|
496
|
+
</div>;
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
// src/components/Source/index.tsx
|
|
500
|
+
import {
|
|
501
|
+
onCleanup as onCleanup2,
|
|
502
|
+
createEffect as createEffect2,
|
|
503
|
+
createContext as createContext2,
|
|
504
|
+
useContext as useContext2,
|
|
505
|
+
createUniqueId
|
|
506
|
+
} from "solid-js";
|
|
507
|
+
var SourceContext = createContext2();
|
|
508
|
+
var useSourceId = () => useContext2(SourceContext);
|
|
509
|
+
var Source = (props) => {
|
|
510
|
+
const [ctx] = useMapContext();
|
|
511
|
+
props.id ??= createUniqueId();
|
|
512
|
+
const debug = (text, value) => {
|
|
513
|
+
ctx.map.debug && console.debug("%c[MapGL]", "color: #ec4899", text, value || "");
|
|
514
|
+
};
|
|
515
|
+
const anySource = () => props.source;
|
|
516
|
+
const lookup = (url) => {
|
|
517
|
+
const s = url?.split(":").reduce((p, c) => p && p[c], rasterStyleList);
|
|
518
|
+
const source = s ? {
|
|
519
|
+
...anySource(),
|
|
520
|
+
url: "",
|
|
521
|
+
tiles: [
|
|
522
|
+
s.replace(
|
|
523
|
+
"{apikey}",
|
|
524
|
+
//@ts-ignore
|
|
525
|
+
anySource().apikey || import.meta.env?.VITE_RASTER_API_KEY
|
|
526
|
+
).replace("{r}", window.devicePixelRatio > 1 ? "@2x" : "")
|
|
527
|
+
],
|
|
528
|
+
attribution: rasterStyleList[url.split(":")[0]]._copy
|
|
529
|
+
} : anySource();
|
|
530
|
+
source.tiles && (source.tiles = ["a", "b", "c"].map(
|
|
531
|
+
(i) => source.tiles[0].replace("{s}", i)
|
|
532
|
+
));
|
|
533
|
+
return source;
|
|
534
|
+
};
|
|
535
|
+
ctx.map.addSource(props.id, lookup(anySource().url));
|
|
536
|
+
ctx.map.sourceIdList.push(props.id);
|
|
537
|
+
debug("Add Source:", props.id);
|
|
538
|
+
switch (anySource().type) {
|
|
539
|
+
case "geojson":
|
|
540
|
+
createEffect2(() => {
|
|
541
|
+
const data = anySource().data;
|
|
542
|
+
ctx.map.getSource(props.id).setData(data || {});
|
|
543
|
+
debug("Update GeoJSON Data:", props.id);
|
|
544
|
+
});
|
|
545
|
+
break;
|
|
546
|
+
case "image":
|
|
547
|
+
createEffect2(() => {
|
|
548
|
+
const url = anySource().url;
|
|
549
|
+
const coords = anySource().coordinates;
|
|
550
|
+
ctx.map.getSource(props.id).updateImage(url, coords);
|
|
551
|
+
debug("Update Image Data:", props.id);
|
|
552
|
+
});
|
|
553
|
+
break;
|
|
554
|
+
case "vector":
|
|
555
|
+
createEffect2(() => {
|
|
556
|
+
const url = anySource().url;
|
|
557
|
+
const tiles = anySource().tiles;
|
|
558
|
+
const source = ctx.map.getSource(props.id);
|
|
559
|
+
url ? source.setUrl(url) : source.setTiles(tiles);
|
|
560
|
+
debug("Update Vector Data:", props.id);
|
|
561
|
+
});
|
|
562
|
+
break;
|
|
563
|
+
case "raster":
|
|
564
|
+
createEffect2(() => {
|
|
565
|
+
const src = lookup(anySource().url);
|
|
566
|
+
const source = ctx.map.getSource(props.id);
|
|
567
|
+
src.url ? source.setUrl(src.url) : source.setTiles(src.tiles);
|
|
568
|
+
debug("Update Raster Data:", props.id);
|
|
569
|
+
});
|
|
570
|
+
break;
|
|
571
|
+
}
|
|
572
|
+
onCleanup2(() => {
|
|
573
|
+
ctx.map?.getStyle().layers.forEach(
|
|
574
|
+
(layer) => layer.source === props.id && ctx.map.removeLayer(layer.id)
|
|
575
|
+
);
|
|
576
|
+
ctx.map?.getSource(props.id) && ctx.map?.removeSource(props.id);
|
|
577
|
+
debug("Remove Source:", props.id);
|
|
578
|
+
});
|
|
579
|
+
return <SourceContext.Provider value={props.id}>
|
|
580
|
+
{props.children}
|
|
581
|
+
</SourceContext.Provider>;
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
// src/components/Layer/index.tsx
|
|
585
|
+
import {
|
|
586
|
+
onCleanup as onCleanup3,
|
|
587
|
+
createEffect as createEffect3,
|
|
588
|
+
createMemo,
|
|
589
|
+
createUniqueId as createUniqueId2
|
|
590
|
+
} from "solid-js";
|
|
591
|
+
|
|
592
|
+
// src/styles.ts
|
|
593
|
+
var baseStyle = [
|
|
594
|
+
"id",
|
|
595
|
+
"type",
|
|
596
|
+
"filter",
|
|
597
|
+
"source",
|
|
598
|
+
"source-layer",
|
|
599
|
+
"minzoom",
|
|
600
|
+
"metadata",
|
|
601
|
+
"maxzoom",
|
|
602
|
+
"paint",
|
|
603
|
+
"layout"
|
|
604
|
+
];
|
|
605
|
+
var layoutStyles = [
|
|
606
|
+
"visibility",
|
|
607
|
+
"line-join",
|
|
608
|
+
"line-cap",
|
|
609
|
+
"line-miter-limit",
|
|
610
|
+
"line-round-limit",
|
|
611
|
+
"line-sort-key",
|
|
612
|
+
"circle-sort-key",
|
|
613
|
+
"symbol-avoid-edges",
|
|
614
|
+
"symbol-placement",
|
|
615
|
+
"symbol-sort-key",
|
|
616
|
+
"symbol-spacing",
|
|
617
|
+
"symbol-z-order",
|
|
618
|
+
"icon-allow-overlap",
|
|
619
|
+
"icon-anchor",
|
|
620
|
+
"icon-ignore-placement",
|
|
621
|
+
"icon-image",
|
|
622
|
+
"icon-keep-upright",
|
|
623
|
+
"icon-offset",
|
|
624
|
+
"icon-optional",
|
|
625
|
+
"icon-padding",
|
|
626
|
+
"icon-pitch-alignment",
|
|
627
|
+
"icon-rotate",
|
|
628
|
+
"icon-rotation-alignment",
|
|
629
|
+
"icon-size",
|
|
630
|
+
"icon-text-fit",
|
|
631
|
+
"icon-text-fit-padding",
|
|
632
|
+
"text-allow-overlap",
|
|
633
|
+
"text-anchor",
|
|
634
|
+
"text-field",
|
|
635
|
+
"text-font",
|
|
636
|
+
"text-ignore-placement",
|
|
637
|
+
"text-justify",
|
|
638
|
+
"text-keep-upright",
|
|
639
|
+
"text-letter-spacing",
|
|
640
|
+
"text-line-height",
|
|
641
|
+
"text-max-angle",
|
|
642
|
+
"text-max-width",
|
|
643
|
+
"text-offset",
|
|
644
|
+
"text-optional",
|
|
645
|
+
"text-padding",
|
|
646
|
+
"text-pitch-alignment",
|
|
647
|
+
"text-radial-offset",
|
|
648
|
+
"text-rotate",
|
|
649
|
+
"text-rotation-alignment",
|
|
650
|
+
"text-size",
|
|
651
|
+
"text-transform",
|
|
652
|
+
"text-variable-anchor",
|
|
653
|
+
"text-writing-mode"
|
|
654
|
+
];
|
|
655
|
+
|
|
656
|
+
// src/components/Layer/index.tsx
|
|
657
|
+
var diff = (newProps = {}, prevProps = {}) => {
|
|
658
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(newProps), ...Object.keys(prevProps)]);
|
|
659
|
+
return [...keys].reduce((acc, key) => {
|
|
660
|
+
const value = newProps[key];
|
|
661
|
+
if (value !== prevProps[key]) {
|
|
662
|
+
acc.push([key, value]);
|
|
663
|
+
}
|
|
664
|
+
return acc;
|
|
665
|
+
}, []);
|
|
666
|
+
};
|
|
667
|
+
var newKey = (key, type) => (key.startsWith(type) || key.startsWith("icon") || key.startsWith("text") ? "" : type + "-") + key.replace(/[A-Z]/g, (s) => "-" + s.toLowerCase());
|
|
668
|
+
var updateStyle = (oldStyle) => {
|
|
669
|
+
if (!oldStyle) return;
|
|
670
|
+
let layout = {};
|
|
671
|
+
let paint = {};
|
|
672
|
+
let style = {};
|
|
673
|
+
Object.entries(oldStyle).forEach(([key, value]) => {
|
|
674
|
+
if (baseStyle.includes(key)) style[key] = value;
|
|
675
|
+
else {
|
|
676
|
+
const nk = newKey(key, oldStyle.type);
|
|
677
|
+
layoutStyles.includes(nk) ? layout[nk] = value : paint[nk] = value;
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
if (oldStyle.paint)
|
|
681
|
+
Object.entries(oldStyle.paint).forEach(
|
|
682
|
+
([key, value]) => paint[newKey(key, oldStyle.type)] = value
|
|
683
|
+
);
|
|
684
|
+
if (oldStyle.layout)
|
|
685
|
+
Object.entries(oldStyle.layout).forEach(
|
|
686
|
+
([key, value]) => layout[newKey(key, oldStyle.type)] = value
|
|
687
|
+
);
|
|
688
|
+
return { ...style, paint, layout };
|
|
689
|
+
};
|
|
690
|
+
var Layer = (props) => {
|
|
691
|
+
const [ctx] = useMapContext();
|
|
692
|
+
const sourceId = props.sourceId || props.style?.source || useSourceId();
|
|
693
|
+
const layerId = props.id || props.customLayer?.id || createUniqueId2();
|
|
694
|
+
const debug = (text, value) => {
|
|
695
|
+
(ctx.map.debug || ctx.map.debugEvents) && console.debug("%c[MapGL]", "color: #10b981", text, value || "");
|
|
696
|
+
};
|
|
697
|
+
const getBeforeId = createMemo(
|
|
698
|
+
() => props.beforeType ? ctx.map.getStyle().layers.find((l) => l.type === props.beforeType)?.id : props.beforeId
|
|
699
|
+
);
|
|
700
|
+
ctx.map.addLayer(
|
|
701
|
+
props.customLayer || {
|
|
702
|
+
...updateStyle(props.style),
|
|
703
|
+
id: layerId,
|
|
704
|
+
source: sourceId,
|
|
705
|
+
// `slot` is Mapbox Standard-Style-only — MapLibre has no equivalent (see docs/dev-notes.md)
|
|
706
|
+
...ctx.isMapLibre ? {} : { slot: props.slot || "" },
|
|
707
|
+
metadata: {
|
|
708
|
+
smg: { beforeType: props.beforeType, beforeId: props.beforeId }
|
|
709
|
+
}
|
|
710
|
+
},
|
|
711
|
+
getBeforeId()
|
|
712
|
+
);
|
|
713
|
+
ctx.map.layerIdList.push(layerId);
|
|
714
|
+
if (props.customLayer) ctx.map.fire("load");
|
|
715
|
+
debug("Add Layer:", layerId);
|
|
716
|
+
layerEvents.forEach((item) => {
|
|
717
|
+
if (props[item]) {
|
|
718
|
+
const event = item.slice(2).toLowerCase();
|
|
719
|
+
ctx.map.on(event, layerId, (evt) => {
|
|
720
|
+
evt.clickOnLayer = true;
|
|
721
|
+
props[item](evt);
|
|
722
|
+
ctx.map.debugEvents && debug(`Layer '${event}' event on '${layerId}':`, evt);
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
createEffect3((prev) => {
|
|
727
|
+
const style = updateStyle(props.style);
|
|
728
|
+
if (style === prev) return;
|
|
729
|
+
if (style.layout !== prev?.layout)
|
|
730
|
+
diff(style.layout, prev?.layout).forEach(
|
|
731
|
+
([key, value]) => ctx.map.setLayoutProperty(layerId, key, value, { validate: false })
|
|
732
|
+
);
|
|
733
|
+
if (style.paint !== prev?.paint)
|
|
734
|
+
diff(style.paint, prev?.paint).forEach(
|
|
735
|
+
([key, value]) => ctx.map.setPaintProperty(layerId, key, value, { validate: false })
|
|
736
|
+
);
|
|
737
|
+
if (style.minzoom !== prev?.minzoom || style.maxzoom !== prev?.maxzoom)
|
|
738
|
+
ctx.map.setLayerZoomRange(layerId, style.minzoom, style.maxzoom);
|
|
739
|
+
if (style.filter !== prev?.filter)
|
|
740
|
+
ctx.map.setFilter(layerId, style.filter, { validate: false });
|
|
741
|
+
debug("Update Layer Style:", layerId);
|
|
742
|
+
return style;
|
|
743
|
+
}, updateStyle(props.style));
|
|
744
|
+
createEffect3((prev) => {
|
|
745
|
+
if (props.visible === prev) return;
|
|
746
|
+
ctx.map.setLayoutProperty(
|
|
747
|
+
layerId,
|
|
748
|
+
"visibility",
|
|
749
|
+
props.visible ? "visible" : "none",
|
|
750
|
+
{ validate: false }
|
|
751
|
+
);
|
|
752
|
+
debug(`Update Visibility (${layerId}):`, props.visible.toString());
|
|
753
|
+
return props.visible;
|
|
754
|
+
}, props.visible);
|
|
755
|
+
createEffect3((prev) => {
|
|
756
|
+
if (getBeforeId() === prev) return prev;
|
|
757
|
+
ctx.map.moveLayer(layerId, getBeforeId());
|
|
758
|
+
debug(`Update Layer Z-Index (${layerId}):`, getBeforeId());
|
|
759
|
+
return getBeforeId();
|
|
760
|
+
}, getBeforeId());
|
|
761
|
+
createEffect3(async () => {
|
|
762
|
+
if (!props.filter) return;
|
|
763
|
+
!ctx.map.isStyleLoaded() && await ctx.map.once("styledata");
|
|
764
|
+
ctx.map.setFilter(layerId, props.filter);
|
|
765
|
+
debug(`Update Filter (${layerId}):`, props.filter);
|
|
766
|
+
});
|
|
767
|
+
createEffect3(async () => {
|
|
768
|
+
if (!props.featureState || props.featureState.id === null) return;
|
|
769
|
+
!ctx.map.isStyleLoaded() && await ctx.map.once("styledata");
|
|
770
|
+
ctx.map.removeFeatureState({
|
|
771
|
+
source: sourceId,
|
|
772
|
+
sourceLayer: props.style["source-layer"]
|
|
773
|
+
});
|
|
774
|
+
ctx.map.setFeatureState(
|
|
775
|
+
{
|
|
776
|
+
source: sourceId,
|
|
777
|
+
sourceLayer: props.style["source-layer"],
|
|
778
|
+
id: props.featureState.id
|
|
779
|
+
},
|
|
780
|
+
props.featureState.state
|
|
781
|
+
);
|
|
782
|
+
});
|
|
783
|
+
onCleanup3(() => ctx.map?.getLayer(layerId) && ctx.map?.removeLayer(layerId));
|
|
784
|
+
return props.children;
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
// src/components/Layer3D/index.tsx
|
|
788
|
+
import {
|
|
789
|
+
onCleanup as onCleanup4,
|
|
790
|
+
createUniqueId as createUniqueId3,
|
|
791
|
+
createSignal as createSignal2,
|
|
792
|
+
onMount as onMount2,
|
|
793
|
+
createContext as createContext3,
|
|
794
|
+
useContext as useContext3
|
|
795
|
+
} from "solid-js";
|
|
796
|
+
var LayerContext = createContext3();
|
|
797
|
+
var useScene = () => useContext3(LayerContext);
|
|
798
|
+
var Layer3D = (props) => {
|
|
799
|
+
const [ctx] = useMapContext();
|
|
800
|
+
const [scene, setScene] = createSignal2(null);
|
|
801
|
+
onMount2(async () => {
|
|
802
|
+
props.id = props.id || createUniqueId3();
|
|
803
|
+
const worldOriginMercator = ctx.mapLib.MercatorCoordinate.fromLngLat(
|
|
804
|
+
[props.origin[0] || 0, props.origin[1] || 0],
|
|
805
|
+
props.origin[2] || 0
|
|
806
|
+
);
|
|
807
|
+
const worldScale = worldOriginMercator.meterInMercatorCoordinateUnits();
|
|
808
|
+
const { x, y, z } = worldOriginMercator;
|
|
809
|
+
let worldMatrix = null;
|
|
810
|
+
let BABYLON = null;
|
|
811
|
+
let THREE = null;
|
|
812
|
+
if (props.babylon) {
|
|
813
|
+
BABYLON = await import("@babylonjs/core");
|
|
814
|
+
worldMatrix = BABYLON.Matrix.Compose(
|
|
815
|
+
new BABYLON.Vector3(worldScale, worldScale, worldScale),
|
|
816
|
+
BABYLON.Quaternion.FromEulerAngles(Math.PI / 2, 0, 0),
|
|
817
|
+
new BABYLON.Vector3(x, y, z)
|
|
818
|
+
);
|
|
819
|
+
} else {
|
|
820
|
+
THREE = await import("three");
|
|
821
|
+
worldMatrix = {
|
|
822
|
+
translateX: x,
|
|
823
|
+
translateY: y,
|
|
824
|
+
translateZ: z,
|
|
825
|
+
rotateX: Math.PI / 2,
|
|
826
|
+
rotateY: 0,
|
|
827
|
+
rotateZ: 0,
|
|
828
|
+
scale: worldScale
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
ctx.map.addLayer(
|
|
832
|
+
{
|
|
833
|
+
id: props.id,
|
|
834
|
+
type: "custom",
|
|
835
|
+
renderingMode: "3d",
|
|
836
|
+
onAdd(map, gl) {
|
|
837
|
+
if (props.babylon) {
|
|
838
|
+
const engine = new BABYLON.Engine(
|
|
839
|
+
gl,
|
|
840
|
+
true,
|
|
841
|
+
{
|
|
842
|
+
useHighPrecisionMatrix: true
|
|
843
|
+
},
|
|
844
|
+
true
|
|
845
|
+
);
|
|
846
|
+
this.scene = new BABYLON.Scene(engine);
|
|
847
|
+
this.scene.autoClear = false;
|
|
848
|
+
this.scene.preventDefaultOnPointerDown = false;
|
|
849
|
+
this.scene.preventDefaultOnPointerUp = false;
|
|
850
|
+
const camera = new BABYLON.UniversalCamera(
|
|
851
|
+
"Camera",
|
|
852
|
+
BABYLON.Vector3.Zero()
|
|
853
|
+
);
|
|
854
|
+
camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;
|
|
855
|
+
camera.inertia = 0;
|
|
856
|
+
this.scene.ambientColor = new BABYLON.Color3(1, 1, 1);
|
|
857
|
+
if (props.defaultLight)
|
|
858
|
+
new BABYLON.HemisphericLight(
|
|
859
|
+
"Light",
|
|
860
|
+
new BABYLON.Vector3(100, 10, 0),
|
|
861
|
+
this.scene
|
|
862
|
+
);
|
|
863
|
+
} else {
|
|
864
|
+
this.camera = new THREE.Camera();
|
|
865
|
+
this.scene = new THREE.Scene();
|
|
866
|
+
if (props.defaultLight) {
|
|
867
|
+
this.light = new THREE.DirectionalLight(16777215);
|
|
868
|
+
this.light.position.set(100, 0, 0).normalize();
|
|
869
|
+
this.scene.add(this.light);
|
|
870
|
+
}
|
|
871
|
+
this.renderer = new THREE.WebGLRenderer({
|
|
872
|
+
canvas: map.getCanvas(),
|
|
873
|
+
context: gl,
|
|
874
|
+
antialias: true
|
|
875
|
+
});
|
|
876
|
+
this.renderer.autoClear = false;
|
|
877
|
+
}
|
|
878
|
+
this.map = map;
|
|
879
|
+
props.onAdd && props.onAdd(this.scene, this.map, gl);
|
|
880
|
+
setScene(this.scene);
|
|
881
|
+
},
|
|
882
|
+
render(gl, matrix) {
|
|
883
|
+
if (props.babylon) {
|
|
884
|
+
this.scene.activeCamera.freezeProjectionMatrix(
|
|
885
|
+
// props.disableProjectionMatrix
|
|
886
|
+
// ? BABYLON.Matrix.FromArray(matrix)
|
|
887
|
+
worldMatrix.multiply(BABYLON.Matrix.FromArray(matrix))
|
|
888
|
+
);
|
|
889
|
+
const pitch = this.map.getPitch() * (Math.PI / 180);
|
|
890
|
+
const bearing = this.map.getBearing() * (Math.PI / 180);
|
|
891
|
+
this.scene.render(false);
|
|
892
|
+
} else {
|
|
893
|
+
const rotationX = new THREE.Matrix4().makeRotationAxis(
|
|
894
|
+
new THREE.Vector3(1, 0, 0),
|
|
895
|
+
worldMatrix.rotateX
|
|
896
|
+
);
|
|
897
|
+
const rotationY = new THREE.Matrix4().makeRotationAxis(
|
|
898
|
+
new THREE.Vector3(0, 1, 0),
|
|
899
|
+
worldMatrix.rotateY
|
|
900
|
+
);
|
|
901
|
+
const rotationZ = new THREE.Matrix4().makeRotationAxis(
|
|
902
|
+
new THREE.Vector3(0, 0, 1),
|
|
903
|
+
worldMatrix.rotateZ
|
|
904
|
+
);
|
|
905
|
+
const m = new THREE.Matrix4().fromArray(matrix);
|
|
906
|
+
const l = new THREE.Matrix4().makeTranslation(
|
|
907
|
+
worldMatrix.translateX,
|
|
908
|
+
worldMatrix.translateY,
|
|
909
|
+
worldMatrix.translateZ
|
|
910
|
+
).scale(
|
|
911
|
+
new THREE.Vector3(
|
|
912
|
+
worldMatrix.scale,
|
|
913
|
+
-worldMatrix.scale,
|
|
914
|
+
worldMatrix.scale
|
|
915
|
+
)
|
|
916
|
+
).multiply(rotationX).multiply(rotationY).multiply(rotationZ);
|
|
917
|
+
this.camera.projectionMatrix = m.multiply(l);
|
|
918
|
+
this.renderer.resetState();
|
|
919
|
+
this.renderer.render(this.scene, this.camera);
|
|
920
|
+
}
|
|
921
|
+
props.onRender && props.onRender(gl, matrix);
|
|
922
|
+
ctx.map.triggerRepaint();
|
|
923
|
+
}
|
|
924
|
+
},
|
|
925
|
+
props.beforeId
|
|
926
|
+
);
|
|
927
|
+
});
|
|
928
|
+
onCleanup4(() => {
|
|
929
|
+
ctx.map.getLayer(props.id) && ctx.map.removeLayer(props.id);
|
|
930
|
+
});
|
|
931
|
+
return <LayerContext.Provider value={scene}>
|
|
932
|
+
{scene() && props.children}
|
|
933
|
+
</LayerContext.Provider>;
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
// src/components/Atmosphere/index.tsx
|
|
937
|
+
import { onCleanup as onCleanup5, createEffect as createEffect4 } from "solid-js";
|
|
938
|
+
var Atmosphere = (props) => {
|
|
939
|
+
const [ctx] = useMapContext();
|
|
940
|
+
createEffect4(() => {
|
|
941
|
+
if (ctx.isMapLibre) ctx.map.setSky?.(props.style || {});
|
|
942
|
+
else ctx.map.setFog(props.style || {});
|
|
943
|
+
});
|
|
944
|
+
onCleanup5(() => {
|
|
945
|
+
if (ctx.isMapLibre) {
|
|
946
|
+
ctx.map.getSky?.() && ctx.map.setSky(null);
|
|
947
|
+
} else if (ctx.map.getFog()) {
|
|
948
|
+
ctx.map.setFog(null);
|
|
949
|
+
}
|
|
950
|
+
});
|
|
951
|
+
return null;
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
// src/components/Terrain/index.tsx
|
|
955
|
+
import {
|
|
956
|
+
createEffect as createEffect5,
|
|
957
|
+
createUniqueId as createUniqueId4,
|
|
958
|
+
onCleanup as onCleanup6
|
|
959
|
+
} from "solid-js";
|
|
960
|
+
var Terrain = (props) => {
|
|
961
|
+
const [ctx] = useMapContext();
|
|
962
|
+
let sourceId = useSourceId();
|
|
963
|
+
if (!sourceId && !props?.source) {
|
|
964
|
+
sourceId = createUniqueId4();
|
|
965
|
+
ctx.map.addSource(sourceId, {
|
|
966
|
+
type: "raster-dem",
|
|
967
|
+
url: ctx.isMapLibre ? "https://demotiles.maplibre.org/terrain-tiles/tiles.json" : "mapbox://mapbox.terrain-rgb",
|
|
968
|
+
tileSize: ctx.isMapLibre ? 256 : 512,
|
|
969
|
+
maxzoom: ctx.isMapLibre ? void 0 : 14
|
|
970
|
+
});
|
|
971
|
+
ctx.map.sourceIdList.push(sourceId);
|
|
972
|
+
}
|
|
973
|
+
createEffect5(() => {
|
|
974
|
+
ctx.map.setTerrain({
|
|
975
|
+
exaggeration: props.exaggeration || 1,
|
|
976
|
+
source: props?.source || sourceId
|
|
977
|
+
});
|
|
978
|
+
});
|
|
979
|
+
onCleanup6(() => ctx.map?.setTerrain(null));
|
|
980
|
+
return null;
|
|
981
|
+
};
|
|
982
|
+
|
|
983
|
+
// src/components/Control/index.tsx
|
|
984
|
+
import { createSignal as createSignal3, createEffect as createEffect7, splitProps, untrack } from "solid-js";
|
|
985
|
+
|
|
986
|
+
// src/lib/createMapControl.ts
|
|
987
|
+
import { createEffect as createEffect6, onCleanup as onCleanup7 } from "solid-js";
|
|
988
|
+
var useControlPosition = (control, position) => {
|
|
989
|
+
const [ctx] = useMapContext();
|
|
990
|
+
createEffect6(() => {
|
|
991
|
+
const c = control();
|
|
992
|
+
const pos = position?.();
|
|
993
|
+
if (!c) return;
|
|
994
|
+
ctx.map.hasControl(c) && ctx.map.removeControl(c);
|
|
995
|
+
ctx.map.addControl(c, pos);
|
|
996
|
+
});
|
|
997
|
+
onCleanup7(() => {
|
|
998
|
+
const c = control();
|
|
999
|
+
c && ctx.map.hasControl(c) && ctx.map.removeControl(c);
|
|
1000
|
+
});
|
|
1001
|
+
};
|
|
1002
|
+
|
|
1003
|
+
// src/components/Control/index.tsx
|
|
1004
|
+
var Control = (props) => {
|
|
1005
|
+
const [ctx] = useMapContext();
|
|
1006
|
+
const [update, create] = splitProps(props, ["position"]);
|
|
1007
|
+
const [control, setControl] = createSignal3(null);
|
|
1008
|
+
const controlClasses = /* @__PURE__ */ new Map([
|
|
1009
|
+
["navigation", ctx.mapLib.NavigationControl],
|
|
1010
|
+
["scale", ctx.mapLib.ScaleControl],
|
|
1011
|
+
["attribution", ctx.mapLib.AttributionControl],
|
|
1012
|
+
["geolocate", ctx.mapLib.GeolocateControl],
|
|
1013
|
+
["fullscreen", ctx.mapLib.FullscreenControl],
|
|
1014
|
+
["logo", ctx.mapLib.LogoControl],
|
|
1015
|
+
["terrain", ctx.mapLib.TerrainControl]
|
|
1016
|
+
]);
|
|
1017
|
+
createEffect7(() => {
|
|
1018
|
+
untrack(
|
|
1019
|
+
() => control() && ctx.map.hasControl(control()) && ctx.map.removeControl(control())
|
|
1020
|
+
);
|
|
1021
|
+
setControl(
|
|
1022
|
+
create.custom || new (controlClasses.get(create.type || "navigation"))(create.options)
|
|
1023
|
+
);
|
|
1024
|
+
});
|
|
1025
|
+
useControlPosition(control, () => update.position);
|
|
1026
|
+
return null;
|
|
1027
|
+
};
|
|
1028
|
+
|
|
1029
|
+
// src/components/Marker/index.tsx
|
|
1030
|
+
import { onCleanup as onCleanup8, createEffect as createEffect8, splitProps as splitProps2 } from "solid-js";
|
|
1031
|
+
var Marker = (props) => {
|
|
1032
|
+
if (!props.lngLat) throw new Error("Marker - lngLat is required");
|
|
1033
|
+
const [update, create_popup, create_marker] = splitProps2(
|
|
1034
|
+
props,
|
|
1035
|
+
["lngLat", "children", "showPopup", "draggable"],
|
|
1036
|
+
["popup", "onOpen", "onClose"]
|
|
1037
|
+
);
|
|
1038
|
+
const [ctx] = useMapContext();
|
|
1039
|
+
let marker = null;
|
|
1040
|
+
let popup = null;
|
|
1041
|
+
const LNGLAT = update.lngLat;
|
|
1042
|
+
createEffect8(() => {
|
|
1043
|
+
if (!ctx.map) return;
|
|
1044
|
+
popup?.remove();
|
|
1045
|
+
popup = new ctx.mapLib.Popup({
|
|
1046
|
+
closeOnClick: false,
|
|
1047
|
+
focusAfterOpen: false,
|
|
1048
|
+
...create_popup.popup
|
|
1049
|
+
}).on("open", () => create_popup.onOpen?.()).on("close", () => create_popup.onClose?.());
|
|
1050
|
+
createEffect8(() => {
|
|
1051
|
+
if (update.children === void 0) return;
|
|
1052
|
+
typeof update.children === "string" ? popup?.setHTML(update.children) : popup?.setDOMContent(update.children);
|
|
1053
|
+
marker?.setPopup(popup);
|
|
1054
|
+
});
|
|
1055
|
+
createEffect8(
|
|
1056
|
+
() => update.showPopup !== popup?.isOpen() && marker?.togglePopup()
|
|
1057
|
+
);
|
|
1058
|
+
});
|
|
1059
|
+
createEffect8(() => {
|
|
1060
|
+
if (!ctx.map) return;
|
|
1061
|
+
marker?.remove();
|
|
1062
|
+
marker = new ctx.mapLib.Marker(create_marker.options).on("dragstart", () => create_marker.onDragStart?.()).on("dragend", () => create_marker.onDragEnd?.()).on("drag", () => create_marker.onDrag?.(marker?.getLngLat().toArray())).setPopup(popup).setLngLat(LNGLAT).addTo(ctx.map);
|
|
1063
|
+
createEffect8(
|
|
1064
|
+
() => update.showPopup !== popup?.isOpen() && marker?.togglePopup()
|
|
1065
|
+
);
|
|
1066
|
+
});
|
|
1067
|
+
createEffect8(() => marker?.setLngLat(update.lngLat));
|
|
1068
|
+
createEffect8(() => marker?.setDraggable(update.draggable));
|
|
1069
|
+
onCleanup8(() => marker?.remove());
|
|
1070
|
+
return null;
|
|
1071
|
+
};
|
|
1072
|
+
|
|
1073
|
+
// src/components/Popup/index.tsx
|
|
1074
|
+
import { onCleanup as onCleanup9, createEffect as createEffect9, splitProps as splitProps3 } from "solid-js";
|
|
1075
|
+
var Popup = (props) => {
|
|
1076
|
+
if (!props.trackPointer && !props.lngLat)
|
|
1077
|
+
throw new Error("Popup - lngLat or trackPointer is required");
|
|
1078
|
+
const [update, create] = splitProps3(props, [
|
|
1079
|
+
"lngLat",
|
|
1080
|
+
"children",
|
|
1081
|
+
"trackPointer"
|
|
1082
|
+
]);
|
|
1083
|
+
const [ctx] = useMapContext();
|
|
1084
|
+
let popup;
|
|
1085
|
+
createEffect9(() => {
|
|
1086
|
+
if (!ctx.map) return;
|
|
1087
|
+
popup?.remove();
|
|
1088
|
+
popup = new ctx.mapLib.Popup({
|
|
1089
|
+
closeOnClick: false,
|
|
1090
|
+
focusAfterOpen: false,
|
|
1091
|
+
...create.options
|
|
1092
|
+
}).on("open", () => create.onOpen?.()).on("close", () => create.onClose?.()).addTo(ctx.map);
|
|
1093
|
+
createEffect9(
|
|
1094
|
+
() => update.trackPointer ? popup.trackPointer() : popup.setLngLat(update.lngLat)
|
|
1095
|
+
);
|
|
1096
|
+
createEffect9(
|
|
1097
|
+
() => typeof update.children === "string" ? popup.setHTML(update.children) : popup.setDOMContent(update.children)
|
|
1098
|
+
);
|
|
1099
|
+
});
|
|
1100
|
+
onCleanup9(() => popup?.remove());
|
|
1101
|
+
return null;
|
|
1102
|
+
};
|
|
1103
|
+
|
|
1104
|
+
// src/components/Image/index.tsx
|
|
1105
|
+
import {
|
|
1106
|
+
onCleanup as onCleanup10,
|
|
1107
|
+
createSignal as createSignal4,
|
|
1108
|
+
createEffect as createEffect10,
|
|
1109
|
+
untrack as untrack2
|
|
1110
|
+
} from "solid-js";
|
|
1111
|
+
var PATTERN = {
|
|
1112
|
+
diagonal_l: { size: 20, path: "M20 0 0 20M-10 10 10-10M10 30 30 10" },
|
|
1113
|
+
diagonal_r: { size: 20, path: "M0 0 20 20M30 10 10-10M10 30-10 10" },
|
|
1114
|
+
horizontal: { size: 14, path: "M7 0V20" },
|
|
1115
|
+
vertical: { size: 14, path: "M0 7H20" },
|
|
1116
|
+
cross: { size: 18, path: "M9 0V18M0 9H18" },
|
|
1117
|
+
hash: { size: 30, path: "M15 0 30 15 15 30 0 15Z" },
|
|
1118
|
+
chevron_h: { size: 20, path: "M-5 5 0 10 10 0 20 10 25 5M0 30 10 20 20 30" },
|
|
1119
|
+
chevron_v: { size: 20, path: "M5-5 10 0 0 10 10 20 5 25M25 15 20 10 25 5" },
|
|
1120
|
+
square: { size: 20, path: "M8 8H12V12H8Z", fill: true },
|
|
1121
|
+
hex: { size: 50, path: "M0 0V50L50 25ZM50 0V50L0 25ZM25 0V50" },
|
|
1122
|
+
circle: {
|
|
1123
|
+
size: 25,
|
|
1124
|
+
path: "M8 10A2.5 2.5 0 118.01 10M18 15A2.5 2.5 0 1018.01 15",
|
|
1125
|
+
fill: true
|
|
1126
|
+
}
|
|
1127
|
+
};
|
|
1128
|
+
var patternList = Object.keys(PATTERN);
|
|
1129
|
+
var MGL_Image = (props) => {
|
|
1130
|
+
const [ctx] = useMapContext();
|
|
1131
|
+
const [size, setSize] = createSignal4({ width: 0, height: 0 });
|
|
1132
|
+
const debug = (text, value) => {
|
|
1133
|
+
ctx.map.debug && console.debug("%c[MapGL]", "color: #10b981", text, value || "");
|
|
1134
|
+
};
|
|
1135
|
+
onCleanup10(() => {
|
|
1136
|
+
ctx.map?.hasImage(props.id) && ctx.map?.removeImage(props.id);
|
|
1137
|
+
debug("Remove Image:", props.id);
|
|
1138
|
+
});
|
|
1139
|
+
createEffect10(() => {
|
|
1140
|
+
if (!props.id) throw new Error("Image - ID is required");
|
|
1141
|
+
if (!props.source && !props.pattern)
|
|
1142
|
+
throw new Error("Image - Image or Pattern is required");
|
|
1143
|
+
const ops = props.pattern ? { pixelRatio: 2, ...props.options } : props.options;
|
|
1144
|
+
_loadImage(props.source || _createPattern(props.pattern), (data) => {
|
|
1145
|
+
const { width, height } = data;
|
|
1146
|
+
if (ctx.map && !ctx.map.hasImage(props.id))
|
|
1147
|
+
ctx.map.addImage(props.id, data, ops);
|
|
1148
|
+
if (!props.pattern && untrack2(() => width === size().width && height === size().height)) {
|
|
1149
|
+
ctx.map.updateImage(props.id, data);
|
|
1150
|
+
ctx.map.triggerRepaint();
|
|
1151
|
+
} else {
|
|
1152
|
+
ctx.map.removeImage(props.id);
|
|
1153
|
+
ctx.map.addImage(props.id, data, ops);
|
|
1154
|
+
}
|
|
1155
|
+
setSize({ width, height });
|
|
1156
|
+
debug("Add Image:", props.id);
|
|
1157
|
+
ctx.map.on("style.load", () => {
|
|
1158
|
+
if (ctx.map.hasImage(props.id)) return;
|
|
1159
|
+
ctx.map.addImage(props.id, data, ops);
|
|
1160
|
+
debug("Re-Add Image:", props.id);
|
|
1161
|
+
});
|
|
1162
|
+
});
|
|
1163
|
+
});
|
|
1164
|
+
const _loadImage = (image, callback) => {
|
|
1165
|
+
if (typeof image == "string" && image?.trimStart().startsWith("<svg")) {
|
|
1166
|
+
image = new DOMParser().parseFromString(image, "image/svg+xml").childNodes[0];
|
|
1167
|
+
}
|
|
1168
|
+
if (image instanceof SVGElement) {
|
|
1169
|
+
props.options?.fill && image.setAttribute("fill", props.options.fill);
|
|
1170
|
+
props.options?.stroke && image.setAttribute("stroke", props.options.stroke);
|
|
1171
|
+
image = new XMLSerializer().serializeToString(image);
|
|
1172
|
+
}
|
|
1173
|
+
if (typeof image !== "string") return callback(image);
|
|
1174
|
+
ctx.map.loadImage(image, async (error, imageData) => {
|
|
1175
|
+
if (error) {
|
|
1176
|
+
if (typeof image == "string" && image?.trimEnd().endsWith(".svg")) {
|
|
1177
|
+
image = await (await fetch(image)).text();
|
|
1178
|
+
image = new DOMParser().parseFromString(image, "image/svg+xml").childNodes[0];
|
|
1179
|
+
image.setAttribute("fill", props.options.fill);
|
|
1180
|
+
image.setAttribute("stroke", props.options.stroke);
|
|
1181
|
+
image.setAttribute("transform", props.options.transform);
|
|
1182
|
+
image = new XMLSerializer().serializeToString(image);
|
|
1183
|
+
}
|
|
1184
|
+
const img = new Image();
|
|
1185
|
+
img.crossOrigin = "Anonymous";
|
|
1186
|
+
img.onload = () => {
|
|
1187
|
+
const canvas = document.createElement("canvas");
|
|
1188
|
+
canvas.width = Math.max(img.width, 50);
|
|
1189
|
+
canvas.height = Math.max(img.height, 50);
|
|
1190
|
+
const ctx2 = canvas.getContext("2d");
|
|
1191
|
+
ctx2.imageSmoothingEnabled = true;
|
|
1192
|
+
ctx2.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
1193
|
+
return callback(ctx2.getImageData(0, 0, canvas.width, canvas.height));
|
|
1194
|
+
};
|
|
1195
|
+
img.src = image.trimStart().startsWith("<svg") ? "data:image/svg+xml;charset=utf-8," + image : image;
|
|
1196
|
+
} else {
|
|
1197
|
+
return callback(imageData);
|
|
1198
|
+
}
|
|
1199
|
+
});
|
|
1200
|
+
};
|
|
1201
|
+
const _createPattern = (pattern) => {
|
|
1202
|
+
const p = PATTERN[pattern.type];
|
|
1203
|
+
return {
|
|
1204
|
+
width: p.size,
|
|
1205
|
+
height: p.size,
|
|
1206
|
+
data: new Uint8Array(p.size * p.size * 4),
|
|
1207
|
+
onAdd: function() {
|
|
1208
|
+
let canvas = document.createElement("canvas");
|
|
1209
|
+
canvas.width = canvas.height = p.size;
|
|
1210
|
+
this.ctx = canvas.getContext("2d", { willReadFrequently: true });
|
|
1211
|
+
},
|
|
1212
|
+
render: function() {
|
|
1213
|
+
this.ctx.fillStyle = pattern.background || "transparent";
|
|
1214
|
+
this.ctx.fillRect(0, 0, this.width, this.height);
|
|
1215
|
+
this.ctx.strokeStyle = this.ctx.fillStyle = pattern.color || "black";
|
|
1216
|
+
this.ctx.lineWidth = pattern.lineWith || 1;
|
|
1217
|
+
this.ctx.stroke(new Path2D(p.path));
|
|
1218
|
+
if (p.fill) this.ctx.fill(new Path2D(p.path));
|
|
1219
|
+
this.data = this.ctx.getImageData(0, 0, this.width, this.height).data;
|
|
1220
|
+
return true;
|
|
1221
|
+
}
|
|
1222
|
+
};
|
|
1223
|
+
};
|
|
1224
|
+
return null;
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
// src/components/Camera/index.tsx
|
|
1228
|
+
import { createEffect as createEffect11, onCleanup as onCleanup11, createSignal as createSignal5 } from "solid-js";
|
|
1229
|
+
var lerp = (a, b, t) => a.map((_, idx) => (1 - t) * a[idx] + t * b[idx]);
|
|
1230
|
+
var slerp = (a, b, t) => {
|
|
1231
|
+
const dotProduct = a.map((_, idx) => a[idx] * b[idx]).reduce((m, n) => m + n);
|
|
1232
|
+
const theta = Math.acos(dotProduct);
|
|
1233
|
+
return a.map(
|
|
1234
|
+
(_, idx) => Math.sin((1 - t) * theta) / Math.sin(theta) * a[idx] + Math.sin(t * theta) / Math.sin(theta) * b[idx]
|
|
1235
|
+
);
|
|
1236
|
+
};
|
|
1237
|
+
var easeQuad = {
|
|
1238
|
+
in: (x) => x * x,
|
|
1239
|
+
out: (x) => 1 - (1 - x) * (1 - x),
|
|
1240
|
+
inOut: (x) => x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2
|
|
1241
|
+
};
|
|
1242
|
+
var Camera = (props) => {
|
|
1243
|
+
const [ctx] = useMapContext();
|
|
1244
|
+
let animationTime = 0.1;
|
|
1245
|
+
let isReverse = false;
|
|
1246
|
+
const [userInteraction, setUserInteraction] = createSignal5(false);
|
|
1247
|
+
["mousedown", "touchstart", "wheel"].forEach(
|
|
1248
|
+
(event) => ctx.map.on(event, (evt) => !evt.rotate && setUserInteraction(true))
|
|
1249
|
+
);
|
|
1250
|
+
["moveend", "mouseup", "touchend"].forEach(
|
|
1251
|
+
(event) => ctx.map.on(event, (evt) => !evt.rotate && setUserInteraction(false))
|
|
1252
|
+
);
|
|
1253
|
+
const updateCameraPosition = async ([lng, lat, alt], target) => {
|
|
1254
|
+
const camera = ctx.map.getFreeCameraOptions();
|
|
1255
|
+
camera.position = ctx.mapLib.MercatorCoordinate.fromLngLat(
|
|
1256
|
+
[lng, lat],
|
|
1257
|
+
alt
|
|
1258
|
+
);
|
|
1259
|
+
camera.lookAtPoint(target);
|
|
1260
|
+
ctx.map.setFreeCameraOptions(camera);
|
|
1261
|
+
};
|
|
1262
|
+
const frame = () => {
|
|
1263
|
+
props.translate && window.requestAnimationFrame(frame);
|
|
1264
|
+
const params = [
|
|
1265
|
+
props.translate.start,
|
|
1266
|
+
props.translate.end,
|
|
1267
|
+
props.translate.easing ? easeQuad[props.translate.easing](animationTime) : animationTime
|
|
1268
|
+
];
|
|
1269
|
+
const position = props.translate.type === "line" ? lerp(...params) : slerp(...params);
|
|
1270
|
+
updateCameraPosition(position, props.translate.target);
|
|
1271
|
+
if (!props.translate.loop && (animationTime > 1 || animationTime < 0))
|
|
1272
|
+
isReverse = !isReverse;
|
|
1273
|
+
animationTime = isReverse ? animationTime - 1e-3 : animationTime + 1e-3;
|
|
1274
|
+
};
|
|
1275
|
+
createEffect11(() => {
|
|
1276
|
+
props.translate && window.requestAnimationFrame(frame);
|
|
1277
|
+
});
|
|
1278
|
+
const options = { duration: 1e3, easing: (n) => n };
|
|
1279
|
+
const rotateGlobe = () => {
|
|
1280
|
+
if (userInteraction()) return;
|
|
1281
|
+
const {
|
|
1282
|
+
secPerRev = 120,
|
|
1283
|
+
maxSpinZoom = 5,
|
|
1284
|
+
slowSpinZoom = 3
|
|
1285
|
+
} = props.rotateGlobe;
|
|
1286
|
+
const zoom = ctx.map.getZoom();
|
|
1287
|
+
if (zoom > maxSpinZoom) return;
|
|
1288
|
+
let distancePerSecond = 360 / secPerRev;
|
|
1289
|
+
if (zoom > slowSpinZoom)
|
|
1290
|
+
distancePerSecond *= (maxSpinZoom - zoom) / (maxSpinZoom - slowSpinZoom);
|
|
1291
|
+
const center = ctx.map.getCenter();
|
|
1292
|
+
center.lng = props.reverse ? center.lng + distancePerSecond : center.lng - distancePerSecond;
|
|
1293
|
+
ctx.map.easeTo({ center, ...options }, { rotate: true });
|
|
1294
|
+
};
|
|
1295
|
+
const rotateViewport = () => {
|
|
1296
|
+
if (!props.rotateViewport || userInteraction()) {
|
|
1297
|
+
ctx.map.stop();
|
|
1298
|
+
return;
|
|
1299
|
+
}
|
|
1300
|
+
const rotateViewport2 = props.rotateViewport;
|
|
1301
|
+
const secPerRev = rotateViewport2?.secPerRev || 60;
|
|
1302
|
+
const bearing = props.reverse ? ctx.map.getBearing() + 360 / secPerRev : ctx.map.getBearing() - 360 / secPerRev;
|
|
1303
|
+
const pitch = rotateViewport2?.pitch || 60;
|
|
1304
|
+
const around = rotateViewport2?.around;
|
|
1305
|
+
ctx.map.easeTo({ bearing, pitch, around, ...options }, { rotate: true });
|
|
1306
|
+
};
|
|
1307
|
+
const onEnd = () => props.rotateGlobe ? rotateGlobe() : rotateViewport();
|
|
1308
|
+
ctx.map.on("moveend", onEnd).on("dragend", onEnd);
|
|
1309
|
+
let originalCenter;
|
|
1310
|
+
createEffect11(() => {
|
|
1311
|
+
if (props.rotateGlobe == void 0) return;
|
|
1312
|
+
if (props.rotateGlobe) {
|
|
1313
|
+
originalCenter = ctx.map.getCenter();
|
|
1314
|
+
rotateGlobe();
|
|
1315
|
+
} else {
|
|
1316
|
+
props.resetWhenStopped ? ctx.map.stop().easeTo({ center: originalCenter }) : ctx.map.stop();
|
|
1317
|
+
}
|
|
1318
|
+
});
|
|
1319
|
+
createEffect11(() => {
|
|
1320
|
+
if (props.rotateViewport == void 0) return;
|
|
1321
|
+
props.rotateViewport ? rotateViewport() : props.resetWhenStopped ? ctx.map.stop().resetNorthPitch() : ctx.map.stop();
|
|
1322
|
+
});
|
|
1323
|
+
onCleanup11(() => ctx.map.off("moveend", onEnd).off("dragend", onEnd));
|
|
1324
|
+
return props.children;
|
|
1325
|
+
};
|
|
1326
|
+
|
|
1327
|
+
// src/components/Light/index.tsx
|
|
1328
|
+
import { onCleanup as onCleanup12, createEffect as createEffect12 } from "solid-js";
|
|
1329
|
+
var Light = (props) => {
|
|
1330
|
+
const [ctx] = useMapContext();
|
|
1331
|
+
createEffect12(() => ctx.map.setLight(props.style || {}));
|
|
1332
|
+
onCleanup12(() => ctx.map?.setLight(null));
|
|
1333
|
+
return null;
|
|
1334
|
+
};
|
|
1335
|
+
|
|
1336
|
+
// src/components/Draw/index.tsx
|
|
1337
|
+
import { onCleanup as onCleanup13 } from "solid-js";
|
|
1338
|
+
|
|
1339
|
+
// src/components/Draw/modes/multi_point.ts
|
|
1340
|
+
var MultiPointMode = {};
|
|
1341
|
+
MultiPointMode.onSetup = function(opts) {
|
|
1342
|
+
var state = {};
|
|
1343
|
+
state.count = opts.count || 0;
|
|
1344
|
+
return state;
|
|
1345
|
+
};
|
|
1346
|
+
MultiPointMode.onClick = function(state, e) {
|
|
1347
|
+
var point = this.newFeature({
|
|
1348
|
+
type: "Feature",
|
|
1349
|
+
properties: {
|
|
1350
|
+
count: state.count
|
|
1351
|
+
},
|
|
1352
|
+
geometry: {
|
|
1353
|
+
type: "Point",
|
|
1354
|
+
coordinates: [e.lngLat.lng, e.lngLat.lat]
|
|
1355
|
+
}
|
|
1356
|
+
});
|
|
1357
|
+
this.addFeature(point);
|
|
1358
|
+
};
|
|
1359
|
+
MultiPointMode.onKeyUp = function(state, e) {
|
|
1360
|
+
if (e.keyCode === 27) return this.changeMode("simple_select");
|
|
1361
|
+
};
|
|
1362
|
+
MultiPointMode.toDisplayFeatures = function(state, geojson, display) {
|
|
1363
|
+
display(geojson);
|
|
1364
|
+
};
|
|
1365
|
+
var multi_point_default = MultiPointMode;
|
|
1366
|
+
|
|
1367
|
+
// src/components/Draw/modes/measurements.ts
|
|
1368
|
+
import length from "@turf/length";
|
|
1369
|
+
import area from "@turf/area";
|
|
1370
|
+
import midpoint from "@turf/midpoint";
|
|
1371
|
+
import { centerOfMass } from "@turf/center-of-mass";
|
|
1372
|
+
var getCoords = (coords) => {
|
|
1373
|
+
return new Intl.NumberFormat(void 0, {
|
|
1374
|
+
maximumFractionDigits: 5
|
|
1375
|
+
}).format(coords[0]) + "\xB0 " + new Intl.NumberFormat(void 0, {
|
|
1376
|
+
maximumFractionDigits: 5
|
|
1377
|
+
}).format(coords[1]) + "\xB0";
|
|
1378
|
+
};
|
|
1379
|
+
var getLength = (coordinates, meta) => {
|
|
1380
|
+
const lengthValue = length(
|
|
1381
|
+
{
|
|
1382
|
+
type: "Feature",
|
|
1383
|
+
properties: {},
|
|
1384
|
+
geometry: {
|
|
1385
|
+
type: "LineString",
|
|
1386
|
+
coordinates
|
|
1387
|
+
}
|
|
1388
|
+
},
|
|
1389
|
+
{
|
|
1390
|
+
units: window.navigator.language === "en-US" ? "miles" : "kilometers"
|
|
1391
|
+
}
|
|
1392
|
+
);
|
|
1393
|
+
const label = window.navigator.language === "en-US" ? new Intl.NumberFormat(void 0, {
|
|
1394
|
+
style: "unit",
|
|
1395
|
+
maximumFractionDigits: 2,
|
|
1396
|
+
unit: lengthValue <= 1 ? "foot" : "mile"
|
|
1397
|
+
}).format(lengthValue <= 1 ? lengthValue * 5280 : lengthValue) : new Intl.NumberFormat(void 0, {
|
|
1398
|
+
style: "unit",
|
|
1399
|
+
maximumFractionDigits: 2,
|
|
1400
|
+
unit: lengthValue <= 1 ? "meter" : "kilometer"
|
|
1401
|
+
}).format(lengthValue <= 1 ? lengthValue * 1e3 : lengthValue);
|
|
1402
|
+
return {
|
|
1403
|
+
type: "Feature",
|
|
1404
|
+
properties: {
|
|
1405
|
+
type: "measure",
|
|
1406
|
+
value: label,
|
|
1407
|
+
...meta
|
|
1408
|
+
},
|
|
1409
|
+
geometry: {
|
|
1410
|
+
type: "Point",
|
|
1411
|
+
coordinates: midpoint(coordinates[0], coordinates[1]).geometry.coordinates
|
|
1412
|
+
}
|
|
1413
|
+
};
|
|
1414
|
+
};
|
|
1415
|
+
var getArea = (coordinates, meta) => {
|
|
1416
|
+
const areaValue = area({
|
|
1417
|
+
type: "Feature",
|
|
1418
|
+
properties: {},
|
|
1419
|
+
geometry: {
|
|
1420
|
+
type: "Polygon",
|
|
1421
|
+
coordinates
|
|
1422
|
+
}
|
|
1423
|
+
});
|
|
1424
|
+
const areaLabel = window.navigator.language === "en-US" ? new Intl.NumberFormat(void 0, {
|
|
1425
|
+
style: "unit",
|
|
1426
|
+
maximumFractionDigits: 2,
|
|
1427
|
+
unit: areaValue <= 10.764 ? "foot" : "mile"
|
|
1428
|
+
}).format(
|
|
1429
|
+
areaValue <= 10.764 ? areaValue * 10.764 : areaValue * 1.0000003861
|
|
1430
|
+
) + "\xB2" : new Intl.NumberFormat(void 0, {
|
|
1431
|
+
style: "unit",
|
|
1432
|
+
maximumFractionDigits: 2,
|
|
1433
|
+
unit: areaValue <= 1e6 ? "meter" : "kilometer"
|
|
1434
|
+
}).format(areaValue <= 1e6 ? areaValue : areaValue / 1e6) + "\xB2";
|
|
1435
|
+
return {
|
|
1436
|
+
type: "Feature",
|
|
1437
|
+
properties: {
|
|
1438
|
+
type: "measure",
|
|
1439
|
+
value: areaLabel,
|
|
1440
|
+
...meta
|
|
1441
|
+
},
|
|
1442
|
+
geometry: centerOfMass({
|
|
1443
|
+
type: "Polygon",
|
|
1444
|
+
coordinates
|
|
1445
|
+
}).geometry
|
|
1446
|
+
};
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1449
|
+
// src/components/Draw/modes/line_string.ts
|
|
1450
|
+
var line_string_default = (lib) => {
|
|
1451
|
+
const DrawLineString = lib.modes.draw_line_string;
|
|
1452
|
+
return {
|
|
1453
|
+
...DrawLineString,
|
|
1454
|
+
onSetup: function() {
|
|
1455
|
+
const draw = DrawLineString.onSetup.call(this);
|
|
1456
|
+
const measure = this.newFeature({
|
|
1457
|
+
type: "Feature",
|
|
1458
|
+
properties: {
|
|
1459
|
+
type: "measure",
|
|
1460
|
+
value: "TTT"
|
|
1461
|
+
},
|
|
1462
|
+
geometry: {
|
|
1463
|
+
type: "Point",
|
|
1464
|
+
coordinates: []
|
|
1465
|
+
}
|
|
1466
|
+
});
|
|
1467
|
+
return { ...draw, measure };
|
|
1468
|
+
},
|
|
1469
|
+
onMouseMove: function(state, e) {
|
|
1470
|
+
DrawLineString.onMouseMove.call(this, state, e);
|
|
1471
|
+
if (state.line.coordinates.length >= 2) {
|
|
1472
|
+
const measure = getLength(state.line.coordinates);
|
|
1473
|
+
state.measure.properties.value = measure.properties.value;
|
|
1474
|
+
state.measure.updateCoordinate(
|
|
1475
|
+
"",
|
|
1476
|
+
measure.geometry.coordinates[0],
|
|
1477
|
+
measure.geometry.coordinates[1]
|
|
1478
|
+
);
|
|
1479
|
+
}
|
|
1480
|
+
},
|
|
1481
|
+
toDisplayFeatures: function(state, geojson, display) {
|
|
1482
|
+
DrawLineString.toDisplayFeatures.call(this, state, geojson, display);
|
|
1483
|
+
if (this.drawConfig.userProperties.showLength) {
|
|
1484
|
+
display(state.measure.toGeoJSON());
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
};
|
|
1489
|
+
|
|
1490
|
+
// src/components/Draw/modes/point.ts
|
|
1491
|
+
var point_default = (lib) => {
|
|
1492
|
+
const DrawPoint = lib.modes.draw_point;
|
|
1493
|
+
return {
|
|
1494
|
+
...DrawPoint,
|
|
1495
|
+
onSetup: function() {
|
|
1496
|
+
const draw = DrawPoint.onSetup.call(this);
|
|
1497
|
+
draw.point.properties = {
|
|
1498
|
+
...draw.point.properties,
|
|
1499
|
+
type: "measure",
|
|
1500
|
+
anchor: "bottom"
|
|
1501
|
+
};
|
|
1502
|
+
return draw;
|
|
1503
|
+
},
|
|
1504
|
+
onMouseMove: function(state, { lngLat }) {
|
|
1505
|
+
state.point.properties.value = getCoords([lngLat.lng, lngLat.lat]);
|
|
1506
|
+
state.point.updateCoordinate("", lngLat.lng, lngLat.lat);
|
|
1507
|
+
},
|
|
1508
|
+
toDisplayFeatures: function(state, geojson, display) {
|
|
1509
|
+
const isActivePoint = geojson.properties.id === state.point.id;
|
|
1510
|
+
geojson.properties.active = isActivePoint ? "" : "false";
|
|
1511
|
+
return display(geojson);
|
|
1512
|
+
}
|
|
1513
|
+
};
|
|
1514
|
+
};
|
|
1515
|
+
|
|
1516
|
+
// src/components/Draw/modes/polygon.ts
|
|
1517
|
+
var polygon_default = (lib) => {
|
|
1518
|
+
const DrawPolygon = lib.modes.draw_polygon;
|
|
1519
|
+
return {
|
|
1520
|
+
...DrawPolygon,
|
|
1521
|
+
toDisplayFeatures: function(state, geojson, display) {
|
|
1522
|
+
const displayMeasure = (geojson2) => {
|
|
1523
|
+
display(geojson2);
|
|
1524
|
+
if (this.drawConfig.userProperties.showLength) {
|
|
1525
|
+
const arr = Array.isArray(geojson2.geometry.coordinates[0][0]) ? geojson2.geometry.coordinates[0] : geojson2.geometry.coordinates;
|
|
1526
|
+
arr.forEach((coords, index) => {
|
|
1527
|
+
if (!Array.isArray(coords) || index == 0) return;
|
|
1528
|
+
display(getLength([arr[index - 1], coords]));
|
|
1529
|
+
});
|
|
1530
|
+
}
|
|
1531
|
+
this.drawConfig.userProperties.showArea && geojson2.geometry.coordinates[0].length >= 3 && display(getArea([geojson2.geometry.coordinates[0]]));
|
|
1532
|
+
};
|
|
1533
|
+
DrawPolygon.toDisplayFeatures.call(this, state, geojson, displayMeasure);
|
|
1534
|
+
}
|
|
1535
|
+
};
|
|
1536
|
+
};
|
|
1537
|
+
|
|
1538
|
+
// src/components/Draw/modes/radius.ts
|
|
1539
|
+
import length2 from "@turf/length";
|
|
1540
|
+
function createVertex(parentId, coordinates, path, selected) {
|
|
1541
|
+
return {
|
|
1542
|
+
type: "Feature",
|
|
1543
|
+
properties: {
|
|
1544
|
+
meta: "vertex",
|
|
1545
|
+
parent: parentId,
|
|
1546
|
+
coord_path: path,
|
|
1547
|
+
active: selected ? "true" : "false"
|
|
1548
|
+
},
|
|
1549
|
+
geometry: {
|
|
1550
|
+
type: "Point",
|
|
1551
|
+
coordinates
|
|
1552
|
+
}
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
function createGeoJSONCircle(center, radius, parentId, points = 64) {
|
|
1556
|
+
const ret = [];
|
|
1557
|
+
const distanceX = radius / (111.32 * Math.cos(center[1] * Math.PI / 180));
|
|
1558
|
+
const distanceY = radius / 110.574;
|
|
1559
|
+
for (let i = 0; i < points; i += 1) {
|
|
1560
|
+
let theta = i / points * (2 * Math.PI);
|
|
1561
|
+
let x = distanceX * Math.cos(theta);
|
|
1562
|
+
let y = distanceY * Math.sin(theta);
|
|
1563
|
+
ret.push([center[0] + x, center[1] + y]);
|
|
1564
|
+
}
|
|
1565
|
+
ret.push(ret[0]);
|
|
1566
|
+
return {
|
|
1567
|
+
type: "Feature",
|
|
1568
|
+
geometry: {
|
|
1569
|
+
type: "Polygon",
|
|
1570
|
+
coordinates: [ret]
|
|
1571
|
+
},
|
|
1572
|
+
properties: {
|
|
1573
|
+
parent: parentId,
|
|
1574
|
+
active: "true"
|
|
1575
|
+
}
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
var doubleClickZoom = {
|
|
1579
|
+
enable: (ctx) => {
|
|
1580
|
+
setTimeout(() => {
|
|
1581
|
+
if (!ctx.map || !ctx.map.doubleClickZoom || !ctx._ctx || !ctx._ctx.store || !ctx._ctx.store.getInitialConfigValue)
|
|
1582
|
+
return;
|
|
1583
|
+
if (!ctx._ctx.store.getInitialConfigValue("doubleClickZoom")) return;
|
|
1584
|
+
ctx.map.doubleClickZoom.enable();
|
|
1585
|
+
}, 0);
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1588
|
+
var RadiusMode = (lib) => ({
|
|
1589
|
+
...lib.modes.draw_line_string,
|
|
1590
|
+
clickAnywhere: function(state, e) {
|
|
1591
|
+
if (state.currentVertexPosition === 1) {
|
|
1592
|
+
state.line.addCoordinate(0, e.lngLat.lng, e.lngLat.lat);
|
|
1593
|
+
return this.changeMode("simple_select", { featureIds: [state.line.id] });
|
|
1594
|
+
}
|
|
1595
|
+
this.updateUIClasses({ mouse: "add" });
|
|
1596
|
+
state.line.updateCoordinate(
|
|
1597
|
+
state.currentVertexPosition,
|
|
1598
|
+
e.lngLat.lng,
|
|
1599
|
+
e.lngLat.lat
|
|
1600
|
+
);
|
|
1601
|
+
if (state.direction === "forward") {
|
|
1602
|
+
state.currentVertexPosition += 1;
|
|
1603
|
+
state.line.updateCoordinate(
|
|
1604
|
+
state.currentVertexPosition,
|
|
1605
|
+
e.lngLat.lng,
|
|
1606
|
+
e.lngLat.lat
|
|
1607
|
+
);
|
|
1608
|
+
} else {
|
|
1609
|
+
state.line.addCoordinate(0, e.lngLat.lng, e.lngLat.lat);
|
|
1610
|
+
}
|
|
1611
|
+
return null;
|
|
1612
|
+
},
|
|
1613
|
+
// creates the final geojson point feature with a radius property
|
|
1614
|
+
// triggers draw.create
|
|
1615
|
+
onStop: function(state) {
|
|
1616
|
+
doubleClickZoom.enable(this);
|
|
1617
|
+
this.activateUIButton();
|
|
1618
|
+
if (this.getFeature(state.line.id) === void 0) return;
|
|
1619
|
+
state.line.removeCoordinate("0");
|
|
1620
|
+
if (state.line.isValid()) {
|
|
1621
|
+
const lineGeoJson = state.line.toGeoJSON();
|
|
1622
|
+
const radius = (length2(lineGeoJson) * 1e3).toFixed(1);
|
|
1623
|
+
const center = lineGeoJson.geometry.coordinates[0];
|
|
1624
|
+
this.deleteFeature([state.line.id], { silent: true });
|
|
1625
|
+
const point = this.newFeature({
|
|
1626
|
+
type: "Feature",
|
|
1627
|
+
properties: { radius },
|
|
1628
|
+
geometry: {
|
|
1629
|
+
type: "Point",
|
|
1630
|
+
coordinates: center
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
this.addFeature(point);
|
|
1634
|
+
this.map.fire("draw.create", {
|
|
1635
|
+
features: [point.toGeoJSON()]
|
|
1636
|
+
});
|
|
1637
|
+
this.changeMode("simple_select", { featureIds: [point.id] });
|
|
1638
|
+
} else {
|
|
1639
|
+
this.deleteFeature([state.line.id], { silent: true });
|
|
1640
|
+
this.changeMode("simple_select", {}, { silent: true });
|
|
1641
|
+
}
|
|
1642
|
+
},
|
|
1643
|
+
toDisplayFeatures: function(state, geojson, display) {
|
|
1644
|
+
const isActiveLine = geojson.properties.id === state.line.id;
|
|
1645
|
+
geojson.properties.active = isActiveLine ? "true" : "false";
|
|
1646
|
+
if (!isActiveLine) return display(geojson);
|
|
1647
|
+
if (geojson.geometry.coordinates.length < 2) return null;
|
|
1648
|
+
geojson.properties.meta = "feature";
|
|
1649
|
+
display(
|
|
1650
|
+
createVertex(
|
|
1651
|
+
state.line.id,
|
|
1652
|
+
geojson.geometry.coordinates[state.direction === "forward" ? geojson.geometry.coordinates.length - 2 : 1],
|
|
1653
|
+
`${state.direction === "forward" ? geojson.geometry.coordinates.length - 2 : 1}`,
|
|
1654
|
+
false
|
|
1655
|
+
)
|
|
1656
|
+
);
|
|
1657
|
+
display(geojson);
|
|
1658
|
+
display(getLength(geojson.geometry.coordinates, { parent: state.line.id }));
|
|
1659
|
+
display(
|
|
1660
|
+
createGeoJSONCircle(
|
|
1661
|
+
geojson.geometry.coordinates[0],
|
|
1662
|
+
length2(geojson),
|
|
1663
|
+
state.line.id
|
|
1664
|
+
)
|
|
1665
|
+
);
|
|
1666
|
+
return null;
|
|
1667
|
+
}
|
|
1668
|
+
});
|
|
1669
|
+
var radius_default = RadiusMode;
|
|
1670
|
+
|
|
1671
|
+
// src/components/Draw/modes/rectangle.ts
|
|
1672
|
+
var RectangleMode = (lib) => ({
|
|
1673
|
+
...lib.modes.draw_line_string,
|
|
1674
|
+
// When the mode starts this function will be called.
|
|
1675
|
+
onSetup: function(opts) {
|
|
1676
|
+
const props = lib.modes.draw_line_string.onSetup.call(this, opts);
|
|
1677
|
+
const rectangle = this.newFeature({
|
|
1678
|
+
type: "Feature",
|
|
1679
|
+
properties: {},
|
|
1680
|
+
geometry: {
|
|
1681
|
+
type: "Polygon",
|
|
1682
|
+
coordinates: [[]]
|
|
1683
|
+
}
|
|
1684
|
+
});
|
|
1685
|
+
this.addFeature(rectangle);
|
|
1686
|
+
return { ...props, ...opts, rectangle };
|
|
1687
|
+
},
|
|
1688
|
+
// support mobile taps
|
|
1689
|
+
onTap: function(state, e) {
|
|
1690
|
+
if (state.startPoint) this.onMouseMove(state, e);
|
|
1691
|
+
this.onClick(state, e);
|
|
1692
|
+
},
|
|
1693
|
+
// Whenever a user clicks on the map, Draw will call `onClick`
|
|
1694
|
+
onClick: function(state, e) {
|
|
1695
|
+
if (state.startPoint && state.startPoint[0] !== e.lngLat.lng && state.startPoint[1] !== e.lngLat.lat) {
|
|
1696
|
+
this.updateUIClasses({ mouse: "pointer" });
|
|
1697
|
+
state.endPoint = [e.lngLat.lng, e.lngLat.lat];
|
|
1698
|
+
this.changeMode("simple_select", { featuresId: state.rectangle.id });
|
|
1699
|
+
} else {
|
|
1700
|
+
state.startPoint = [e.lngLat.lng, e.lngLat.lat];
|
|
1701
|
+
}
|
|
1702
|
+
},
|
|
1703
|
+
onMouseMove: function(state, e) {
|
|
1704
|
+
if (state.startPoint) {
|
|
1705
|
+
state.rectangle.updateCoordinate(
|
|
1706
|
+
"0.0",
|
|
1707
|
+
state.startPoint[0],
|
|
1708
|
+
state.startPoint[1]
|
|
1709
|
+
);
|
|
1710
|
+
state.rectangle.updateCoordinate(
|
|
1711
|
+
"0.1",
|
|
1712
|
+
e.lngLat.lng,
|
|
1713
|
+
state.startPoint[1]
|
|
1714
|
+
);
|
|
1715
|
+
state.rectangle.updateCoordinate("0.2", e.lngLat.lng, e.lngLat.lat);
|
|
1716
|
+
state.rectangle.updateCoordinate(
|
|
1717
|
+
"0.3",
|
|
1718
|
+
state.startPoint[0],
|
|
1719
|
+
e.lngLat.lat
|
|
1720
|
+
);
|
|
1721
|
+
state.rectangle.updateCoordinate(
|
|
1722
|
+
"0.4",
|
|
1723
|
+
state.startPoint[0],
|
|
1724
|
+
state.startPoint[1]
|
|
1725
|
+
);
|
|
1726
|
+
}
|
|
1727
|
+
},
|
|
1728
|
+
// Whenever a user clicks on a key while focused on the map, it will be sent here
|
|
1729
|
+
onKeyUp: function(state, e) {
|
|
1730
|
+
if (e.keyCode === 27) return this.changeMode("simple_select");
|
|
1731
|
+
},
|
|
1732
|
+
onStop: function(state) {
|
|
1733
|
+
lib.modes.draw_line_string.onStop.call(this, state);
|
|
1734
|
+
if (this.getFeature(state.rectangle.id) === void 0) return;
|
|
1735
|
+
state.rectangle.removeCoordinate("0.4");
|
|
1736
|
+
if (state.rectangle.isValid()) {
|
|
1737
|
+
this.map.fire("draw.create", {
|
|
1738
|
+
features: [state.rectangle.toGeoJSON()]
|
|
1739
|
+
});
|
|
1740
|
+
} else {
|
|
1741
|
+
this.deleteFeature([state.rectangle.id], { silent: true });
|
|
1742
|
+
this.changeMode("simple_select", {}, { silent: true });
|
|
1743
|
+
}
|
|
1744
|
+
},
|
|
1745
|
+
toDisplayFeatures: function(state, geojson, display) {
|
|
1746
|
+
const isActivePolygon = geojson.properties.id === state.rectangle.id;
|
|
1747
|
+
geojson.properties.active = isActivePolygon ? "true" : "false";
|
|
1748
|
+
if (!isActivePolygon) return display(geojson);
|
|
1749
|
+
if (!state.startPoint) return;
|
|
1750
|
+
display(geojson);
|
|
1751
|
+
if (this.drawConfig.userProperties.showLength) {
|
|
1752
|
+
display(
|
|
1753
|
+
getLength(
|
|
1754
|
+
[geojson.geometry.coordinates[0][0], geojson.geometry.coordinates[0][1]],
|
|
1755
|
+
{ parent: state.rectangle.id, anchor: "bottom" }
|
|
1756
|
+
)
|
|
1757
|
+
);
|
|
1758
|
+
display(
|
|
1759
|
+
getLength(
|
|
1760
|
+
[geojson.geometry.coordinates[0][1], geojson.geometry.coordinates[0][2]],
|
|
1761
|
+
{ parent: state.rectangle.id, anchor: "left" }
|
|
1762
|
+
)
|
|
1763
|
+
);
|
|
1764
|
+
}
|
|
1765
|
+
this.drawConfig.userProperties.showArea && display(getArea(geojson.geometry.coordinates, { parent: state.rectangle.id }));
|
|
1766
|
+
return null;
|
|
1767
|
+
},
|
|
1768
|
+
onTrash: function(state) {
|
|
1769
|
+
this.deleteFeature([state.rectangle.id], { silent: true });
|
|
1770
|
+
this.changeMode("simple_select");
|
|
1771
|
+
}
|
|
1772
|
+
});
|
|
1773
|
+
var rectangle_default = RectangleMode;
|
|
1774
|
+
|
|
1775
|
+
// src/components/Draw/modes/rectangle_assisted.ts
|
|
1776
|
+
var doubleClickZoom2 = {
|
|
1777
|
+
enable: (ctx) => {
|
|
1778
|
+
setTimeout(() => {
|
|
1779
|
+
if (!ctx.map || !ctx.map.doubleClickZoom || !ctx._ctx || !ctx._ctx.store || !ctx._ctx.store.getInitialConfigValue)
|
|
1780
|
+
return;
|
|
1781
|
+
if (!ctx._ctx.store.getInitialConfigValue("doubleClickZoom")) return;
|
|
1782
|
+
ctx.map.doubleClickZoom.enable();
|
|
1783
|
+
}, 0);
|
|
1784
|
+
},
|
|
1785
|
+
disable(ctx) {
|
|
1786
|
+
setTimeout(() => {
|
|
1787
|
+
if (!ctx.map || !ctx.map.doubleClickZoom) return;
|
|
1788
|
+
ctx.map.doubleClickZoom.disable();
|
|
1789
|
+
}, 0);
|
|
1790
|
+
}
|
|
1791
|
+
};
|
|
1792
|
+
var RectangleAssistedMode = {
|
|
1793
|
+
onSetup: function(opts) {
|
|
1794
|
+
const rectangle = this.newFeature({
|
|
1795
|
+
type: "Feature",
|
|
1796
|
+
properties: {},
|
|
1797
|
+
geometry: {
|
|
1798
|
+
type: "Polygon",
|
|
1799
|
+
coordinates: [[]]
|
|
1800
|
+
}
|
|
1801
|
+
});
|
|
1802
|
+
this.addFeature(rectangle);
|
|
1803
|
+
this.clearSelectedFeatures();
|
|
1804
|
+
doubleClickZoom2.disable(this);
|
|
1805
|
+
this.updateUIClasses({
|
|
1806
|
+
mouse: "add"
|
|
1807
|
+
});
|
|
1808
|
+
this.setActionableState({
|
|
1809
|
+
trash: true
|
|
1810
|
+
});
|
|
1811
|
+
return {
|
|
1812
|
+
rectangle,
|
|
1813
|
+
currentVertexPosition: 0
|
|
1814
|
+
};
|
|
1815
|
+
},
|
|
1816
|
+
onTap: function(state, e) {
|
|
1817
|
+
this.onClick(state, e);
|
|
1818
|
+
},
|
|
1819
|
+
onClick: function(state, e) {
|
|
1820
|
+
if (state.currentVertexPosition === 2) {
|
|
1821
|
+
const getpXY3 = this.calculatepXY3(state, e, false);
|
|
1822
|
+
if (getpXY3) {
|
|
1823
|
+
state.rectangle.updateCoordinate(
|
|
1824
|
+
`0.${state.currentVertexPosition + 1}`,
|
|
1825
|
+
getpXY3[0],
|
|
1826
|
+
getpXY3[1]
|
|
1827
|
+
);
|
|
1828
|
+
}
|
|
1829
|
+
this.updateUIClasses({
|
|
1830
|
+
mouse: "pointer"
|
|
1831
|
+
});
|
|
1832
|
+
return this.changeMode("simple_select", {
|
|
1833
|
+
featuresId: state.rectangle.id
|
|
1834
|
+
});
|
|
1835
|
+
} else {
|
|
1836
|
+
state.rectangle.updateCoordinate(
|
|
1837
|
+
`0.${state.currentVertexPosition}`,
|
|
1838
|
+
e.lngLat.lng,
|
|
1839
|
+
e.lngLat.lat
|
|
1840
|
+
);
|
|
1841
|
+
state.currentVertexPosition++;
|
|
1842
|
+
state.rectangle.updateCoordinate(
|
|
1843
|
+
`0.${state.currentVertexPosition}`,
|
|
1844
|
+
e.lngLat.lng,
|
|
1845
|
+
e.lngLat.lat
|
|
1846
|
+
);
|
|
1847
|
+
}
|
|
1848
|
+
},
|
|
1849
|
+
onMouseMove: function(state, e) {
|
|
1850
|
+
state.rectangle.updateCoordinate(
|
|
1851
|
+
"0." + state.currentVertexPosition,
|
|
1852
|
+
e.lngLat.lng,
|
|
1853
|
+
e.lngLat.lat
|
|
1854
|
+
);
|
|
1855
|
+
if (state.currentVertexPosition && state.currentVertexPosition > 0) {
|
|
1856
|
+
this.calculateOrientedAnglePolygon(state);
|
|
1857
|
+
}
|
|
1858
|
+
if (state.currentVertexPosition === 2) {
|
|
1859
|
+
const getpXY3 = this.calculatepXY3(state, e, true);
|
|
1860
|
+
if (getpXY3) {
|
|
1861
|
+
state.rectangle.updateCoordinate(
|
|
1862
|
+
"0." + (state.currentVertexPosition + 1),
|
|
1863
|
+
getpXY3[0],
|
|
1864
|
+
getpXY3[1]
|
|
1865
|
+
);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
},
|
|
1869
|
+
deegrees2meters(px) {
|
|
1870
|
+
const x = px[0] * 2003750834e-2 / 180;
|
|
1871
|
+
let y = Math.log(Math.tan((90 + px[1]) * Math.PI / 360)) / (Math.PI / 180);
|
|
1872
|
+
y = y * 2003750834e-2 / 180;
|
|
1873
|
+
return [x, y];
|
|
1874
|
+
},
|
|
1875
|
+
meters2degress(px) {
|
|
1876
|
+
const lon = px[0] * 180 / 2003750834e-2;
|
|
1877
|
+
const lat = Math.atan(Math.exp(px[1] * Math.PI / 2003750834e-2)) * 360 / Math.PI - 90;
|
|
1878
|
+
return [lon, lat];
|
|
1879
|
+
},
|
|
1880
|
+
calculateOrientedAnglePolygon: function(state) {
|
|
1881
|
+
const pXY0 = state.rectangle.getCoordinate("0.0");
|
|
1882
|
+
const pXY0_3857 = this.deegrees2meters(pXY0);
|
|
1883
|
+
const pXY1 = state.rectangle.getCoordinate("0.1");
|
|
1884
|
+
const pXY1_3857 = this.deegrees2meters(pXY1);
|
|
1885
|
+
const angleStdGraus = Math.atan2(pXY1_3857[1] - pXY0_3857[1], pXY1_3857[0] - pXY0_3857[0]) * 180 / Math.PI;
|
|
1886
|
+
let angleSudGraus = -1 * (angleStdGraus + 90);
|
|
1887
|
+
const angle = angleSudGraus < 0 ? angleSudGraus + 360 : angleSudGraus;
|
|
1888
|
+
state.angle = parseFloat(angle.toFixed(2));
|
|
1889
|
+
},
|
|
1890
|
+
calculatepXY3: function(state, e, tmp) {
|
|
1891
|
+
const pXY0 = state.rectangle.getCoordinate("0.0");
|
|
1892
|
+
const pXY0_3857 = this.deegrees2meters(pXY0);
|
|
1893
|
+
const pXY1 = state.rectangle.getCoordinate("0.1");
|
|
1894
|
+
const pXY1_3857 = this.deegrees2meters(pXY1);
|
|
1895
|
+
let pXY2_3857 = this.deegrees2meters([e.lngLat.lng, e.lngLat.lat]);
|
|
1896
|
+
const mouse_3857 = this.deegrees2meters([e.lngLat.lng, e.lngLat.lat]);
|
|
1897
|
+
if (pXY0_3857[0] === pXY1_3857[0]) {
|
|
1898
|
+
pXY2_3857 = [mouse_3857[0], pXY1_3857[1]];
|
|
1899
|
+
} else if (pXY0_3857[1] === pXY1_3857[1]) {
|
|
1900
|
+
pXY2_3857 = [pXY1_3857[0], mouse_3857[1]];
|
|
1901
|
+
} else {
|
|
1902
|
+
const vector1_3857 = (pXY1_3857[1] - pXY0_3857[1]) / (pXY1_3857[0] - pXY0_3857[0]);
|
|
1903
|
+
const vector2_3857 = -1 / vector1_3857;
|
|
1904
|
+
if (Math.abs(vector2_3857) < 1) {
|
|
1905
|
+
pXY2_3857[1] = vector2_3857 * (mouse_3857[0] - pXY1_3857[0]) + pXY1_3857[1];
|
|
1906
|
+
} else {
|
|
1907
|
+
pXY2_3857[0] = pXY1_3857[0] + (pXY2_3857[1] - pXY1_3857[1]) / vector2_3857;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
const vector_3857 = [
|
|
1911
|
+
pXY1_3857[0] - pXY0_3857[0],
|
|
1912
|
+
pXY1_3857[1] - pXY0_3857[1]
|
|
1913
|
+
];
|
|
1914
|
+
const pXY3_3857 = [
|
|
1915
|
+
pXY2_3857[0] - vector_3857[0],
|
|
1916
|
+
pXY2_3857[1] - vector_3857[1]
|
|
1917
|
+
];
|
|
1918
|
+
const pXY2G = this.meters2degress(pXY2_3857);
|
|
1919
|
+
const pXY3G = this.meters2degress(pXY3_3857);
|
|
1920
|
+
state.rectangle.updateCoordinate("0.2", pXY2G[0], pXY2G[1]);
|
|
1921
|
+
state.rectangle.updateCoordinate("0.3", pXY3G[0], pXY3G[1]);
|
|
1922
|
+
return pXY3G;
|
|
1923
|
+
},
|
|
1924
|
+
onKeyUp: function(state, e) {
|
|
1925
|
+
if (e.keyCode === 27) return this.changeMode("simple_select");
|
|
1926
|
+
},
|
|
1927
|
+
onStop: function(state) {
|
|
1928
|
+
doubleClickZoom2.enable(this);
|
|
1929
|
+
this.updateUIClasses({
|
|
1930
|
+
mouse: "none"
|
|
1931
|
+
});
|
|
1932
|
+
this.activateUIButton();
|
|
1933
|
+
if (this.getFeature(state.rectangle.id) === void 0) return;
|
|
1934
|
+
state.rectangle.removeCoordinate("0.4");
|
|
1935
|
+
if (state.rectangle.isValid()) {
|
|
1936
|
+
this.map.fire("draw.create", {
|
|
1937
|
+
features: [state.rectangle.toGeoJSON()]
|
|
1938
|
+
});
|
|
1939
|
+
} else {
|
|
1940
|
+
this.deleteFeature([state.rectangle.id], {
|
|
1941
|
+
silent: true
|
|
1942
|
+
});
|
|
1943
|
+
this.changeMode(
|
|
1944
|
+
"simple_select",
|
|
1945
|
+
{},
|
|
1946
|
+
{
|
|
1947
|
+
silent: true
|
|
1948
|
+
}
|
|
1949
|
+
);
|
|
1950
|
+
}
|
|
1951
|
+
},
|
|
1952
|
+
toDisplayFeatures: function(state, geojson, display) {
|
|
1953
|
+
const isActivePolygon = geojson.properties.id === state.rectangle.id;
|
|
1954
|
+
geojson.properties.active = isActivePolygon ? "true" : "false";
|
|
1955
|
+
geojson.properties.angle = state.angle;
|
|
1956
|
+
geojson.angle = state.angle;
|
|
1957
|
+
if (!isActivePolygon) return display(geojson);
|
|
1958
|
+
const coordinateCount = geojson.geometry.coordinates[0].length;
|
|
1959
|
+
if (coordinateCount < 3) {
|
|
1960
|
+
const coordinates = geojson.geometry.coordinates[0][0];
|
|
1961
|
+
const vertexPoint = {
|
|
1962
|
+
type: "Feature",
|
|
1963
|
+
properties: geojson.properties,
|
|
1964
|
+
angle: state.angle,
|
|
1965
|
+
geometry: {
|
|
1966
|
+
coordinates: geojson.geometry.coordinates[0][0],
|
|
1967
|
+
type: "Point"
|
|
1968
|
+
}
|
|
1969
|
+
};
|
|
1970
|
+
if (coordinates) {
|
|
1971
|
+
display(vertexPoint);
|
|
1972
|
+
}
|
|
1973
|
+
return;
|
|
1974
|
+
}
|
|
1975
|
+
if (coordinateCount >= 3 && coordinateCount <= 4) {
|
|
1976
|
+
const lineCoordinates = [
|
|
1977
|
+
[
|
|
1978
|
+
geojson.geometry.coordinates[0][0][0],
|
|
1979
|
+
geojson.geometry.coordinates[0][0][1]
|
|
1980
|
+
],
|
|
1981
|
+
[
|
|
1982
|
+
geojson.geometry.coordinates[0][1][0],
|
|
1983
|
+
geojson.geometry.coordinates[0][1][1]
|
|
1984
|
+
]
|
|
1985
|
+
];
|
|
1986
|
+
display({
|
|
1987
|
+
type: "Feature",
|
|
1988
|
+
properties: geojson.properties,
|
|
1989
|
+
angle: state.angle,
|
|
1990
|
+
geometry: {
|
|
1991
|
+
coordinates: lineCoordinates,
|
|
1992
|
+
type: "LineString"
|
|
1993
|
+
}
|
|
1994
|
+
});
|
|
1995
|
+
if (coordinateCount === 3) {
|
|
1996
|
+
return;
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
return display(geojson);
|
|
2000
|
+
},
|
|
2001
|
+
onTrash: function(state) {
|
|
2002
|
+
this.deleteFeature([state.rectangle.id], {
|
|
2003
|
+
silent: true
|
|
2004
|
+
});
|
|
2005
|
+
this.changeMode("simple_select");
|
|
2006
|
+
}
|
|
2007
|
+
};
|
|
2008
|
+
var rectangle_assisted_default = RectangleAssistedMode;
|
|
2009
|
+
|
|
2010
|
+
// src/components/Draw/drawingStyles.jsx
|
|
2011
|
+
var drawingStyles_default = [
|
|
2012
|
+
// point active
|
|
2013
|
+
// {
|
|
2014
|
+
// id: "points-active-halo",
|
|
2015
|
+
// type: "circle",
|
|
2016
|
+
// filter: [
|
|
2017
|
+
// "all",
|
|
2018
|
+
// ["==", "$type", "Point"],
|
|
2019
|
+
// ["==", "meta", "feature"],
|
|
2020
|
+
// ["==", "active", "true"],
|
|
2021
|
+
// ],
|
|
2022
|
+
// paint: {
|
|
2023
|
+
// "circle-radius": 9,
|
|
2024
|
+
// "circle-color": "#f7ad3b",
|
|
2025
|
+
// "circle-opacity": 0.75,
|
|
2026
|
+
// },
|
|
2027
|
+
// },
|
|
2028
|
+
// {
|
|
2029
|
+
// id: "highlight-active-points",
|
|
2030
|
+
// type: "circle",
|
|
2031
|
+
// filter: [
|
|
2032
|
+
// "all",
|
|
2033
|
+
// ["==", "$type", "Point"],
|
|
2034
|
+
// ["==", "meta", "feature"],
|
|
2035
|
+
// ["==", "active", "true"],
|
|
2036
|
+
// ],
|
|
2037
|
+
// paint: {
|
|
2038
|
+
// "circle-radius": 5,
|
|
2039
|
+
// "circle-color": ["get", "user_color"],
|
|
2040
|
+
// },
|
|
2041
|
+
// },
|
|
2042
|
+
// // point inactive
|
|
2043
|
+
// {
|
|
2044
|
+
// id: "points-inactive-halo",
|
|
2045
|
+
// type: "circle",
|
|
2046
|
+
// filter: [
|
|
2047
|
+
// "all",
|
|
2048
|
+
// ["==", "$type", "Point"],
|
|
2049
|
+
// ["==", "meta", "feature"],
|
|
2050
|
+
// ["==", "active", "false"],
|
|
2051
|
+
// ["!has", "user_label"],
|
|
2052
|
+
// ],
|
|
2053
|
+
// paint: {
|
|
2054
|
+
// "circle-radius": 8,
|
|
2055
|
+
// "circle-color": "#FFFFFF",
|
|
2056
|
+
// "circle-opacity": 0.75,
|
|
2057
|
+
// },
|
|
2058
|
+
// },
|
|
2059
|
+
// {
|
|
2060
|
+
// id: "points-inactive",
|
|
2061
|
+
// type: "circle",
|
|
2062
|
+
// filter: [
|
|
2063
|
+
// "all",
|
|
2064
|
+
// ["==", "$type", "Point"],
|
|
2065
|
+
// ["==", "meta", "feature"],
|
|
2066
|
+
// ["==", "active", "false"],
|
|
2067
|
+
// ["!has", "user_label"],
|
|
2068
|
+
// ],
|
|
2069
|
+
// paint: {
|
|
2070
|
+
// "circle-radius": 5,
|
|
2071
|
+
// "circle-color": ["get", "user_color"],
|
|
2072
|
+
// },
|
|
2073
|
+
// },
|
|
2074
|
+
// {
|
|
2075
|
+
// id: "points-inactive-label",
|
|
2076
|
+
// type: "symbol",
|
|
2077
|
+
// filter: [
|
|
2078
|
+
// "all",
|
|
2079
|
+
// ["==", "$type", "Point"],
|
|
2080
|
+
// ["==", "meta", "feature"],
|
|
2081
|
+
// ["==", "active", "false"],
|
|
2082
|
+
// ["has", "user_label"],
|
|
2083
|
+
// ],
|
|
2084
|
+
// layout: {
|
|
2085
|
+
// "text-field": ["get", "user_label"],
|
|
2086
|
+
// "text-font": ["Arial Regular"],
|
|
2087
|
+
// "text-anchor": "bottom",
|
|
2088
|
+
// "text-size": 20,
|
|
2089
|
+
// },
|
|
2090
|
+
// paint: {
|
|
2091
|
+
// "text-halo-color": "rgba(255,255,255,0.75)",
|
|
2092
|
+
// "text-halo-width": 2,
|
|
2093
|
+
// "text-halo-blur": 1,
|
|
2094
|
+
// "text-color": ["get", "user_color"],
|
|
2095
|
+
// },
|
|
2096
|
+
// },
|
|
2097
|
+
// // line avtive (being drawn)
|
|
2098
|
+
// {
|
|
2099
|
+
// id: "gl-draw-line-active",
|
|
2100
|
+
// type: "line",
|
|
2101
|
+
// filter: ["all", ["==", "$type", "LineString"], ["==", "active", "true"]],
|
|
2102
|
+
// layout: {
|
|
2103
|
+
// "line-cap": "round",
|
|
2104
|
+
// "line-join": "round",
|
|
2105
|
+
// },
|
|
2106
|
+
// paint: {
|
|
2107
|
+
// "line-color": "#f7ad3b",
|
|
2108
|
+
// "line-dasharray": [0.2, 2],
|
|
2109
|
+
// "line-width": 3,
|
|
2110
|
+
// },
|
|
2111
|
+
// },
|
|
2112
|
+
// {
|
|
2113
|
+
// id: "gl-draw-line-inactive",
|
|
2114
|
+
// type: "line",
|
|
2115
|
+
// filter: ["all", ["==", "$type", "LineString"], ["==", "active", "false"]],
|
|
2116
|
+
// layout: {
|
|
2117
|
+
// "line-cap": "round",
|
|
2118
|
+
// "line-join": "round",
|
|
2119
|
+
// },
|
|
2120
|
+
// paint: {
|
|
2121
|
+
// "line-color": [
|
|
2122
|
+
// "case",
|
|
2123
|
+
// ["has", "user_color"],
|
|
2124
|
+
// ["get", "user_color"],
|
|
2125
|
+
// "#f7ad3b",
|
|
2126
|
+
// ],
|
|
2127
|
+
// "line-width": 2,
|
|
2128
|
+
// },
|
|
2129
|
+
// },
|
|
2130
|
+
// // vertex point halos
|
|
2131
|
+
// {
|
|
2132
|
+
// id: "gl-draw-polygon-and-line-vertex-halo-active",
|
|
2133
|
+
// type: "circle",
|
|
2134
|
+
// filter: [
|
|
2135
|
+
// "all",
|
|
2136
|
+
// ["==", "meta", "vertex"],
|
|
2137
|
+
// ["==", "$type", "Point"],
|
|
2138
|
+
// ["!=", "mode", "static"],
|
|
2139
|
+
// ],
|
|
2140
|
+
// paint: {
|
|
2141
|
+
// "circle-radius": 5,
|
|
2142
|
+
// "circle-color": "#FFF",
|
|
2143
|
+
// "circle-opacity": 0.75,
|
|
2144
|
+
// },
|
|
2145
|
+
// },
|
|
2146
|
+
// // vertex points
|
|
2147
|
+
// {
|
|
2148
|
+
// id: "gl-draw-polygon-and-line-vertex-active",
|
|
2149
|
+
// type: "circle",
|
|
2150
|
+
// filter: [
|
|
2151
|
+
// "all",
|
|
2152
|
+
// ["==", "meta", "vertex"],
|
|
2153
|
+
// ["==", "$type", "Point"],
|
|
2154
|
+
// ["!=", "mode", "static"],
|
|
2155
|
+
// ],
|
|
2156
|
+
// paint: {
|
|
2157
|
+
// "circle-radius": 3,
|
|
2158
|
+
// "circle-color": "#f7ad3b",
|
|
2159
|
+
// },
|
|
2160
|
+
// },
|
|
2161
|
+
// // polygon fill
|
|
2162
|
+
// {
|
|
2163
|
+
// id: "gl-draw-polygon-fill-inactive",
|
|
2164
|
+
// type: "fill",
|
|
2165
|
+
// filter: ["==", "$type", "Polygon"],
|
|
2166
|
+
// paint: {
|
|
2167
|
+
// "fill-color": [
|
|
2168
|
+
// "case",
|
|
2169
|
+
// ["has", "user_color"],
|
|
2170
|
+
// ["get", "user_color"],
|
|
2171
|
+
// "#f7ad3b",
|
|
2172
|
+
// ],
|
|
2173
|
+
// "fill-opacity": 0.1,
|
|
2174
|
+
// },
|
|
2175
|
+
// },
|
|
2176
|
+
// // polygon outline stroke
|
|
2177
|
+
// // This doesn't style the first edge of the polygon, which uses the line stroke styling instead
|
|
2178
|
+
// {
|
|
2179
|
+
// id: "gl-draw-polygon-stroke-active",
|
|
2180
|
+
// type: "line",
|
|
2181
|
+
// filter: ["all", ["==", "$type", "Polygon"], ["==", "active", "true"]],
|
|
2182
|
+
// layout: {
|
|
2183
|
+
// "line-cap": "round",
|
|
2184
|
+
// "line-join": "round",
|
|
2185
|
+
// },
|
|
2186
|
+
// paint: {
|
|
2187
|
+
// "line-color": "#f7ad3b",
|
|
2188
|
+
// "line-dasharray": [0.5, 2],
|
|
2189
|
+
// "line-width": 2,
|
|
2190
|
+
// },
|
|
2191
|
+
// },
|
|
2192
|
+
// {
|
|
2193
|
+
// id: "gl-draw-polygon-stroke-inactive",
|
|
2194
|
+
// type: "line",
|
|
2195
|
+
// filter: ["all", ["==", "$type", "Polygon"], ["==", "active", "false"]],
|
|
2196
|
+
// layout: {
|
|
2197
|
+
// "line-cap": "round",
|
|
2198
|
+
// "line-join": "round",
|
|
2199
|
+
// },
|
|
2200
|
+
// paint: {
|
|
2201
|
+
// "line-color": [
|
|
2202
|
+
// "case",
|
|
2203
|
+
// ["has", "user_color"],
|
|
2204
|
+
// ["get", "user_color"],
|
|
2205
|
+
// "#f7ad3b",
|
|
2206
|
+
// ],
|
|
2207
|
+
// "line-width": 2,
|
|
2208
|
+
// },
|
|
2209
|
+
// },
|
|
2210
|
+
{
|
|
2211
|
+
id: "measure-label",
|
|
2212
|
+
type: "symbol",
|
|
2213
|
+
filter: ["all", ["==", "$type", "Point"], ["==", "user_type", "measure"]],
|
|
2214
|
+
layout: {
|
|
2215
|
+
"text-field": ["get", "user_value"],
|
|
2216
|
+
"text-anchor": ["get", "user_anchor"],
|
|
2217
|
+
"text-offset": [
|
|
2218
|
+
"match",
|
|
2219
|
+
["get", "user_anchor"],
|
|
2220
|
+
"bottom",
|
|
2221
|
+
[0, -0.5],
|
|
2222
|
+
[0, 0]
|
|
2223
|
+
],
|
|
2224
|
+
"text-size": 12,
|
|
2225
|
+
"text-allow-overlap": true,
|
|
2226
|
+
"text-ignore-placement": true
|
|
2227
|
+
},
|
|
2228
|
+
paint: {
|
|
2229
|
+
"text-halo-color": "rgba(255,255,255,0.75)",
|
|
2230
|
+
"text-halo-width": 2,
|
|
2231
|
+
"text-halo-blur": 1,
|
|
2232
|
+
"text-color": "#000"
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
];
|
|
2236
|
+
|
|
2237
|
+
// src/components/Draw/index.tsx
|
|
2238
|
+
var Draw = (props) => {
|
|
2239
|
+
const [ctx] = useMapContext();
|
|
2240
|
+
if (ctx.isMapLibre && props.lib.constants?.classes) {
|
|
2241
|
+
Object.assign(props.lib.constants.classes, {
|
|
2242
|
+
CANVAS: "maplibregl-canvas",
|
|
2243
|
+
CONTROL_BASE: "maplibregl-ctrl",
|
|
2244
|
+
CONTROL_PREFIX: "maplibregl-ctrl-",
|
|
2245
|
+
CONTROL_GROUP: "maplibregl-ctrl-group",
|
|
2246
|
+
ATTRIBUTION: "maplibregl-ctrl-attrib"
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2249
|
+
const draw = new props.lib({
|
|
2250
|
+
styles: [...props.lib.lib.theme, ...drawingStyles_default],
|
|
2251
|
+
modes: {
|
|
2252
|
+
...props.lib.modes,
|
|
2253
|
+
draw_point: point_default(props.lib),
|
|
2254
|
+
draw_line_string: line_string_default(props.lib),
|
|
2255
|
+
draw_polygon: polygon_default(props.lib),
|
|
2256
|
+
multi_point: multi_point_default,
|
|
2257
|
+
radius: radius_default(props.lib),
|
|
2258
|
+
rectangle: rectangle_default(props.lib),
|
|
2259
|
+
rectangle_assisted: rectangle_assisted_default
|
|
2260
|
+
},
|
|
2261
|
+
userProperties: {
|
|
2262
|
+
showLength: props.showLength || false,
|
|
2263
|
+
showArea: props.showArea || false
|
|
2264
|
+
},
|
|
2265
|
+
...props.options
|
|
2266
|
+
});
|
|
2267
|
+
ctx.map.addControl(draw, props.position || "top-right");
|
|
2268
|
+
props.getInstance && props.getInstance(draw);
|
|
2269
|
+
const eventList = {};
|
|
2270
|
+
drawEvents.forEach((item) => {
|
|
2271
|
+
if (props[item]) {
|
|
2272
|
+
const event = `draw.${item.slice(2).toLowerCase()}`;
|
|
2273
|
+
const fn = (evt) => props[item](evt);
|
|
2274
|
+
eventList[event] = fn;
|
|
2275
|
+
ctx.map.on(event, fn);
|
|
2276
|
+
}
|
|
2277
|
+
});
|
|
2278
|
+
onCleanup13(() => {
|
|
2279
|
+
Object.keys(eventList).forEach(
|
|
2280
|
+
(event) => ctx.map.off(event, eventList[event])
|
|
2281
|
+
);
|
|
2282
|
+
ctx.map?.removeControl(draw);
|
|
2283
|
+
});
|
|
2284
|
+
return null;
|
|
2285
|
+
};
|
|
2286
|
+
|
|
2287
|
+
// src/components/DeckOverlay/index.tsx
|
|
2288
|
+
import { createEffect as createEffect13 } from "solid-js";
|
|
2289
|
+
var DeckOverlay = (props) => {
|
|
2290
|
+
const [ctx] = useMapContext();
|
|
2291
|
+
let overlay;
|
|
2292
|
+
const control = () => {
|
|
2293
|
+
if (!overlay) overlay = new props.overlay(props.props || {});
|
|
2294
|
+
return overlay;
|
|
2295
|
+
};
|
|
2296
|
+
useControlPosition(control);
|
|
2297
|
+
createEffect13(() => overlay?.setProps(props.props || {}));
|
|
2298
|
+
return null;
|
|
2299
|
+
};
|
|
2300
|
+
export {
|
|
2301
|
+
Atmosphere,
|
|
2302
|
+
Camera,
|
|
2303
|
+
Control,
|
|
2304
|
+
DeckOverlay,
|
|
2305
|
+
Draw,
|
|
2306
|
+
MGL_Image as Image,
|
|
2307
|
+
Layer,
|
|
2308
|
+
Layer3D,
|
|
2309
|
+
Light,
|
|
2310
|
+
MapProvider,
|
|
2311
|
+
Marker,
|
|
2312
|
+
Popup,
|
|
2313
|
+
Source,
|
|
2314
|
+
Terrain,
|
|
2315
|
+
MapGL as default,
|
|
2316
|
+
patternList,
|
|
2317
|
+
useMapContext,
|
|
2318
|
+
useScene,
|
|
2319
|
+
useSourceId
|
|
2320
|
+
};
|