react-bkoi-gl 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1420 -176
- package/dist/index.cjs +1181 -174
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +548 -48
- package/dist/index.d.ts +548 -48
- package/dist/index.js +1189 -203
- package/dist/index.js.map +1 -1
- package/dist/styles/react-bkoi-gl.css +95 -1
- package/package.json +28 -8
package/dist/index.cjs
CHANGED
|
@@ -30,13 +30,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
32
|
AttributionControl: () => AttributionControl,
|
|
33
|
+
CanvasSource: () => CanvasSource,
|
|
34
|
+
DrawControl: () => DrawControl,
|
|
33
35
|
FullscreenControl: () => FullscreenControl,
|
|
34
36
|
GeolocateControl: () => GeolocateControl,
|
|
37
|
+
GlobeControl: () => GlobeControl,
|
|
35
38
|
Layer: () => Layer,
|
|
36
39
|
LogoControl: () => LogoControl,
|
|
37
40
|
Map: () => Map,
|
|
38
41
|
MapProvider: () => MapProvider,
|
|
39
42
|
Marker: () => Marker,
|
|
43
|
+
Minimap: () => Minimap,
|
|
44
|
+
MinimapControl: () => MinimapControl,
|
|
40
45
|
NavigationControl: () => NavigationControl,
|
|
41
46
|
Popup: () => Popup,
|
|
42
47
|
ScaleControl: () => ScaleControl,
|
|
@@ -95,7 +100,8 @@ function useMap() {
|
|
|
95
100
|
const maps = (0, import_react.useContext)(MountedMapsContext)?.maps;
|
|
96
101
|
const currentMap = (0, import_react.useContext)(MapContext);
|
|
97
102
|
const mapsWithCurrent = (0, import_react.useMemo)(() => {
|
|
98
|
-
|
|
103
|
+
const current = currentMap?.map || (maps ? Object.values(maps)[0] : void 0);
|
|
104
|
+
return { ...maps, current };
|
|
99
105
|
}, [maps, currentMap]);
|
|
100
106
|
return mapsWithCurrent;
|
|
101
107
|
}
|
|
@@ -181,15 +187,7 @@ function applyViewStateToTransform(tr, props) {
|
|
|
181
187
|
}
|
|
182
188
|
|
|
183
189
|
// src/utils/style-utils.ts
|
|
184
|
-
var refProps = [
|
|
185
|
-
"type",
|
|
186
|
-
"source",
|
|
187
|
-
"source-layer",
|
|
188
|
-
"minzoom",
|
|
189
|
-
"maxzoom",
|
|
190
|
-
"filter",
|
|
191
|
-
"layout"
|
|
192
|
-
];
|
|
190
|
+
var refProps = ["type", "source", "source-layer", "minzoom", "maxzoom", "filter", "layout"];
|
|
193
191
|
function normalizeStyle(style) {
|
|
194
192
|
if (!style) {
|
|
195
193
|
return null;
|
|
@@ -208,14 +206,15 @@ function normalizeStyle(style) {
|
|
|
208
206
|
layerIndex[layer.id] = layer;
|
|
209
207
|
}
|
|
210
208
|
const layers = style.layers.map((layer) => {
|
|
209
|
+
const legacyLayer = layer;
|
|
211
210
|
let normalizedLayer = null;
|
|
212
|
-
if ("interactive" in
|
|
213
|
-
normalizedLayer = Object.assign({},
|
|
211
|
+
if ("interactive" in legacyLayer) {
|
|
212
|
+
normalizedLayer = Object.assign({}, legacyLayer);
|
|
214
213
|
delete normalizedLayer.interactive;
|
|
215
214
|
}
|
|
216
|
-
const layerRef = layerIndex[
|
|
215
|
+
const layerRef = layerIndex[legacyLayer.ref];
|
|
217
216
|
if (layerRef) {
|
|
218
|
-
normalizedLayer = normalizedLayer || Object.assign({},
|
|
217
|
+
normalizedLayer = normalizedLayer || Object.assign({}, legacyLayer);
|
|
219
218
|
delete normalizedLayer.ref;
|
|
220
219
|
for (const propName of refProps) {
|
|
221
220
|
if (propName in layerRef) {
|
|
@@ -311,7 +310,8 @@ var Maplibre = class _Maplibre {
|
|
|
311
310
|
this._propsedCameraUpdate = null;
|
|
312
311
|
this._styleComponents = {};
|
|
313
312
|
this._onEvent = (e) => {
|
|
314
|
-
const
|
|
313
|
+
const handlerName = otherEvents[e.type];
|
|
314
|
+
const cb = this.props[handlerName];
|
|
315
315
|
if (cb) {
|
|
316
316
|
cb(e);
|
|
317
317
|
} else if (e.type === "error") {
|
|
@@ -323,7 +323,8 @@ var Maplibre = class _Maplibre {
|
|
|
323
323
|
return;
|
|
324
324
|
}
|
|
325
325
|
e.viewState = this._propsedCameraUpdate || transformToViewState(this._map.transform);
|
|
326
|
-
const
|
|
326
|
+
const handlerName = cameraEvents[e.type];
|
|
327
|
+
const cb = this.props[handlerName];
|
|
327
328
|
if (cb) {
|
|
328
329
|
cb(e);
|
|
329
330
|
}
|
|
@@ -339,7 +340,8 @@ var Maplibre = class _Maplibre {
|
|
|
339
340
|
if (e.type === "mousemove" || e.type === "mouseout") {
|
|
340
341
|
this._updateHover(e);
|
|
341
342
|
}
|
|
342
|
-
const
|
|
343
|
+
const handlerName = pointerEvents[e.type];
|
|
344
|
+
const cb = this.props[handlerName];
|
|
343
345
|
if (cb) {
|
|
344
346
|
if (this.props.interactiveLayerIds && e.type !== "mouseover" && e.type !== "mouseout") {
|
|
345
347
|
e.features = this._hoveredFeatures || this._queryRenderedFeatures(e.point);
|
|
@@ -353,7 +355,6 @@ var Maplibre = class _Maplibre {
|
|
|
353
355
|
this._initialize(container);
|
|
354
356
|
}
|
|
355
357
|
static {
|
|
356
|
-
// eslint-disable-next-line no-use-before-define
|
|
357
358
|
this.savedMaps = [];
|
|
358
359
|
}
|
|
359
360
|
get map() {
|
|
@@ -383,8 +384,9 @@ var Maplibre = class _Maplibre {
|
|
|
383
384
|
while (oldContainer.childNodes.length > 0) {
|
|
384
385
|
container.appendChild(oldContainer.childNodes[0]);
|
|
385
386
|
}
|
|
386
|
-
|
|
387
|
-
|
|
387
|
+
const mapInternal = map;
|
|
388
|
+
mapInternal._container = container;
|
|
389
|
+
const resizeObserver = mapInternal._resizeObserver;
|
|
388
390
|
if (resizeObserver) {
|
|
389
391
|
resizeObserver.disconnect();
|
|
390
392
|
resizeObserver.observe(container);
|
|
@@ -407,10 +409,10 @@ var Maplibre = class _Maplibre {
|
|
|
407
409
|
} else {
|
|
408
410
|
map.once("style.load", () => map.fire("load"));
|
|
409
411
|
}
|
|
410
|
-
map
|
|
412
|
+
const mapInternalForUpdate = map;
|
|
413
|
+
mapInternalForUpdate._update();
|
|
411
414
|
return that;
|
|
412
415
|
}
|
|
413
|
-
/* eslint-disable complexity,max-statements */
|
|
414
416
|
_initialize(container) {
|
|
415
417
|
const { props } = this;
|
|
416
418
|
const { mapStyle = DEFAULT_STYLE } = props;
|
|
@@ -443,11 +445,11 @@ var Maplibre = class _Maplibre {
|
|
|
443
445
|
}
|
|
444
446
|
map.transformCameraUpdate = this._onCameraUpdate;
|
|
445
447
|
map.on("style.load", () => {
|
|
448
|
+
const mapWithProjection = map;
|
|
446
449
|
this._styleComponents = {
|
|
447
450
|
light: map.getLight(),
|
|
448
451
|
sky: map.getSky(),
|
|
449
|
-
|
|
450
|
-
projection: map.getProjection?.(),
|
|
452
|
+
projection: mapWithProjection.getProjection?.(),
|
|
451
453
|
terrain: map.getTerrain()
|
|
452
454
|
};
|
|
453
455
|
this._updateStyleComponents(this.props);
|
|
@@ -466,7 +468,6 @@ var Maplibre = class _Maplibre {
|
|
|
466
468
|
}
|
|
467
469
|
this._map = map;
|
|
468
470
|
}
|
|
469
|
-
/* eslint-enable complexity,max-statements */
|
|
470
471
|
recycle() {
|
|
471
472
|
const container = this.map.getContainer();
|
|
472
473
|
const children = container.querySelector("[mapboxgl-children]");
|
|
@@ -563,14 +564,10 @@ var Maplibre = class _Maplibre {
|
|
|
563
564
|
* 1. They can not be applied right away. Certain conditions (style loaded, source loaded, etc.) must be met
|
|
564
565
|
* 2. They can be overwritten by mapStyle
|
|
565
566
|
*/
|
|
566
|
-
_updateStyleComponents({
|
|
567
|
-
light,
|
|
568
|
-
projection,
|
|
569
|
-
sky,
|
|
570
|
-
terrain
|
|
571
|
-
}) {
|
|
567
|
+
_updateStyleComponents({ light, projection, sky, terrain }) {
|
|
572
568
|
const map = this._map;
|
|
573
569
|
const currProps = this._styleComponents;
|
|
570
|
+
const mapWithProjection = map;
|
|
574
571
|
if (map.style._loaded) {
|
|
575
572
|
if (light && !deepEqual(light, currProps.light)) {
|
|
576
573
|
currProps.light = light;
|
|
@@ -578,7 +575,7 @@ var Maplibre = class _Maplibre {
|
|
|
578
575
|
}
|
|
579
576
|
if (projection && !deepEqual(projection, currProps.projection) && projection !== currProps.projection?.type) {
|
|
580
577
|
currProps.projection = typeof projection === "string" ? { type: projection } : projection;
|
|
581
|
-
|
|
578
|
+
mapWithProjection.setProjection?.(currProps.projection);
|
|
582
579
|
}
|
|
583
580
|
if (sky && !deepEqual(sky, currProps.sky)) {
|
|
584
581
|
currProps.sky = sky;
|
|
@@ -700,19 +697,34 @@ var useIsomorphicLayoutEffect = typeof document !== "undefined" ? import_react2.
|
|
|
700
697
|
var use_isomorphic_layout_effect_default = useIsomorphicLayoutEffect;
|
|
701
698
|
|
|
702
699
|
// src/utils/set-globals.ts
|
|
700
|
+
var validateUrl = (url, settingName) => {
|
|
701
|
+
try {
|
|
702
|
+
const parsed = new URL(url);
|
|
703
|
+
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
704
|
+
console.warn(`${settingName}: Only http/https protocols are allowed, got: ${parsed.protocol}`);
|
|
705
|
+
return false;
|
|
706
|
+
}
|
|
707
|
+
return true;
|
|
708
|
+
} catch {
|
|
709
|
+
console.warn(`${settingName}: Invalid URL format: ${url}`);
|
|
710
|
+
return false;
|
|
711
|
+
}
|
|
712
|
+
};
|
|
703
713
|
function setGlobals(mapLib, props) {
|
|
704
714
|
const { RTLTextPlugin, maxParallelImageRequests, workerCount, workerUrl } = props;
|
|
705
715
|
if (RTLTextPlugin && mapLib.getRTLTextPluginStatus && mapLib.getRTLTextPluginStatus() === "unavailable") {
|
|
706
716
|
const { pluginUrl, lazy = true } = typeof RTLTextPlugin === "string" ? { pluginUrl: RTLTextPlugin } : RTLTextPlugin;
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
717
|
+
if (validateUrl(pluginUrl, "RTLTextPlugin")) {
|
|
718
|
+
mapLib.setRTLTextPlugin(
|
|
719
|
+
pluginUrl,
|
|
720
|
+
(error) => {
|
|
721
|
+
if (error) {
|
|
722
|
+
console.error(error);
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
lazy
|
|
726
|
+
);
|
|
727
|
+
}
|
|
716
728
|
}
|
|
717
729
|
if (maxParallelImageRequests !== void 0) {
|
|
718
730
|
mapLib.setMaxParallelImageRequests(maxParallelImageRequests);
|
|
@@ -721,7 +733,9 @@ function setGlobals(mapLib, props) {
|
|
|
721
733
|
mapLib.setWorkerCount(workerCount);
|
|
722
734
|
}
|
|
723
735
|
if (workerUrl !== void 0) {
|
|
724
|
-
|
|
736
|
+
if (validateUrl(workerUrl, "workerUrl")) {
|
|
737
|
+
mapLib.setWorkerUrl(workerUrl);
|
|
738
|
+
}
|
|
725
739
|
}
|
|
726
740
|
}
|
|
727
741
|
|
|
@@ -749,14 +763,18 @@ function applyReactStyle(element, styles) {
|
|
|
749
763
|
var import_react3 = require("react");
|
|
750
764
|
function useControl(onCreate, arg1, arg2, arg3) {
|
|
751
765
|
const context = (0, import_react3.useContext)(MapContext);
|
|
766
|
+
if (!context) {
|
|
767
|
+
throw new Error("useControl must be used within a Map component");
|
|
768
|
+
}
|
|
752
769
|
const ctrl = (0, import_react3.useMemo)(() => onCreate(context), []);
|
|
753
770
|
(0, import_react3.useEffect)(() => {
|
|
754
771
|
const opts = arg3 || arg2 || arg1;
|
|
755
772
|
const onAdd = typeof arg1 === "function" && typeof arg2 === "function" ? arg1 : null;
|
|
756
773
|
const onRemove = typeof arg2 === "function" ? arg2 : typeof arg1 === "function" ? arg1 : null;
|
|
757
774
|
const { map } = context;
|
|
758
|
-
|
|
759
|
-
|
|
775
|
+
const ctrlAsIControl = ctrl;
|
|
776
|
+
if (!map.hasControl(ctrlAsIControl)) {
|
|
777
|
+
map.addControl(ctrlAsIControl, opts?.position);
|
|
760
778
|
if (onAdd) {
|
|
761
779
|
onAdd(context);
|
|
762
780
|
}
|
|
@@ -765,8 +783,8 @@ function useControl(onCreate, arg1, arg2, arg3) {
|
|
|
765
783
|
if (onRemove) {
|
|
766
784
|
onRemove(context);
|
|
767
785
|
}
|
|
768
|
-
if (map.hasControl(
|
|
769
|
-
map.removeControl(
|
|
786
|
+
if (map.hasControl(ctrlAsIControl)) {
|
|
787
|
+
map.removeControl(ctrlAsIControl);
|
|
770
788
|
}
|
|
771
789
|
};
|
|
772
790
|
}, []);
|
|
@@ -826,11 +844,24 @@ function _AttributionControl(props) {
|
|
|
826
844
|
if (!ctrl._container || !map) return;
|
|
827
845
|
const onLoad = () => {
|
|
828
846
|
setTimeout(() => {
|
|
829
|
-
const inner = ctrl._container.querySelector(
|
|
830
|
-
".maplibregl-ctrl-attrib-inner"
|
|
831
|
-
);
|
|
847
|
+
const inner = ctrl._container.querySelector(".maplibregl-ctrl-attrib-inner");
|
|
832
848
|
if (inner) {
|
|
833
|
-
inner.
|
|
849
|
+
inner.textContent = "";
|
|
850
|
+
const createLink = (text, href) => {
|
|
851
|
+
const a = document.createElement("a");
|
|
852
|
+
a.href = href;
|
|
853
|
+
a.target = "_blank";
|
|
854
|
+
a.rel = "noopener noreferrer";
|
|
855
|
+
a.textContent = text;
|
|
856
|
+
return a;
|
|
857
|
+
};
|
|
858
|
+
inner.appendChild(createLink("Barikoi", "https://barikoi.com"));
|
|
859
|
+
inner.appendChild(document.createTextNode(" \xA9 "));
|
|
860
|
+
inner.appendChild(createLink("OpenMapTiles", "https://openmaptiles.org"));
|
|
861
|
+
inner.appendChild(document.createTextNode(" \xA9 "));
|
|
862
|
+
inner.appendChild(
|
|
863
|
+
createLink("OpenStreetMap contributors", "https://www.openstreetmap.org/copyright")
|
|
864
|
+
);
|
|
834
865
|
}
|
|
835
866
|
}, 0);
|
|
836
867
|
};
|
|
@@ -860,7 +891,7 @@ function _Map(props, ref) {
|
|
|
860
891
|
(0, import_react6.useEffect)(() => {
|
|
861
892
|
const mapLib = props.mapLib;
|
|
862
893
|
let isMounted = true;
|
|
863
|
-
let maplibre;
|
|
894
|
+
let maplibre = null;
|
|
864
895
|
Promise.resolve(mapLib || import("maplibre-gl")).then((module2) => {
|
|
865
896
|
if (!isMounted) {
|
|
866
897
|
return;
|
|
@@ -881,15 +912,16 @@ function _Map(props, ref) {
|
|
|
881
912
|
mapboxgl.Map,
|
|
882
913
|
{
|
|
883
914
|
...props,
|
|
884
|
-
// @ts-ignore - attributionControl is not in the type definition but is supported by maplibre-gl
|
|
885
915
|
attributionControl: false
|
|
886
916
|
},
|
|
887
917
|
containerRef.current
|
|
888
918
|
);
|
|
889
919
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
920
|
+
if (maplibre) {
|
|
921
|
+
contextValue.map = createRef(maplibre);
|
|
922
|
+
contextValue.mapLib = mapboxgl;
|
|
923
|
+
setMapInstance(maplibre);
|
|
924
|
+
}
|
|
893
925
|
mountedMapsContext?.onMapMount(contextValue.map, props.id);
|
|
894
926
|
}).catch((error) => {
|
|
895
927
|
const { onError } = props;
|
|
@@ -934,7 +966,7 @@ function _Map(props, ref) {
|
|
|
934
966
|
const CHILD_CONTAINER_STYLE = {
|
|
935
967
|
height: "100%"
|
|
936
968
|
};
|
|
937
|
-
return /* @__PURE__ */ React2.createElement("div", { id: props.id, ref: containerRef, style }, mapInstance && /* @__PURE__ */ React2.createElement(MapContext.Provider, { value: contextValue }, /* @__PURE__ */ React2.createElement("div", {
|
|
969
|
+
return /* @__PURE__ */ React2.createElement("div", { id: props.id, ref: containerRef, style }, mapInstance && /* @__PURE__ */ React2.createElement(MapContext.Provider, { value: contextValue }, /* @__PURE__ */ React2.createElement("div", { style: CHILD_CONTAINER_STYLE }, /* @__PURE__ */ React2.createElement(LogoControl, { position: "bottom-left" }), /* @__PURE__ */ React2.createElement(AttributionControl, { position: "bottom-right" }), props.children)));
|
|
938
970
|
}
|
|
939
971
|
var Map = React2.forwardRef(_Map);
|
|
940
972
|
|
|
@@ -971,7 +1003,7 @@ function getClassList(className) {
|
|
|
971
1003
|
var Marker = (0, import_react7.memo)(
|
|
972
1004
|
(0, import_react7.forwardRef)((props, ref) => {
|
|
973
1005
|
const { map, mapLib } = (0, import_react7.useContext)(MapContext);
|
|
974
|
-
const
|
|
1006
|
+
const callbackRef = (0, import_react7.useRef)({});
|
|
975
1007
|
const marker = (0, import_react7.useMemo)(() => {
|
|
976
1008
|
let hasChildren = false;
|
|
977
1009
|
React3.Children.forEach(props.children, (el) => {
|
|
@@ -985,33 +1017,46 @@ var Marker = (0, import_react7.memo)(
|
|
|
985
1017
|
};
|
|
986
1018
|
const mk = new mapLib.Marker(options);
|
|
987
1019
|
mk.setLngLat([props.longitude, props.latitude]);
|
|
988
|
-
mk.getElement().addEventListener("click", (e) => {
|
|
989
|
-
thisRef.current.props.onClick?.({
|
|
990
|
-
type: "click",
|
|
991
|
-
target: mk,
|
|
992
|
-
originalEvent: e
|
|
993
|
-
});
|
|
994
|
-
});
|
|
995
|
-
mk.on("dragstart", (e) => {
|
|
996
|
-
const evt = e;
|
|
997
|
-
evt.lngLat = marker.getLngLat();
|
|
998
|
-
thisRef.current.props.onDragStart?.(evt);
|
|
999
|
-
});
|
|
1000
|
-
mk.on("drag", (e) => {
|
|
1001
|
-
const evt = e;
|
|
1002
|
-
evt.lngLat = marker.getLngLat();
|
|
1003
|
-
thisRef.current.props.onDrag?.(evt);
|
|
1004
|
-
});
|
|
1005
|
-
mk.on("dragend", (e) => {
|
|
1006
|
-
const evt = e;
|
|
1007
|
-
evt.lngLat = marker.getLngLat();
|
|
1008
|
-
thisRef.current.props.onDragEnd?.(evt);
|
|
1009
|
-
});
|
|
1010
1020
|
return mk;
|
|
1011
1021
|
}, []);
|
|
1012
1022
|
(0, import_react7.useEffect)(() => {
|
|
1023
|
+
callbackRef.current = {
|
|
1024
|
+
onClick: props.onClick,
|
|
1025
|
+
onDragStart: props.onDragStart,
|
|
1026
|
+
onDrag: props.onDrag,
|
|
1027
|
+
onDragEnd: props.onDragEnd
|
|
1028
|
+
};
|
|
1029
|
+
});
|
|
1030
|
+
(0, import_react7.useEffect)(() => {
|
|
1031
|
+
const clickHandler = (e) => {
|
|
1032
|
+
callbackRef.current.onClick?.({
|
|
1033
|
+
type: "click",
|
|
1034
|
+
target: marker,
|
|
1035
|
+
originalEvent: e
|
|
1036
|
+
});
|
|
1037
|
+
};
|
|
1038
|
+
marker.getElement().addEventListener("click", clickHandler);
|
|
1039
|
+
const dragStartHandler = (e) => {
|
|
1040
|
+
e.lngLat = marker.getLngLat();
|
|
1041
|
+
callbackRef.current.onDragStart?.(e);
|
|
1042
|
+
};
|
|
1043
|
+
const dragHandler = (e) => {
|
|
1044
|
+
e.lngLat = marker.getLngLat();
|
|
1045
|
+
callbackRef.current.onDrag?.(e);
|
|
1046
|
+
};
|
|
1047
|
+
const dragEndHandler = (e) => {
|
|
1048
|
+
e.lngLat = marker.getLngLat();
|
|
1049
|
+
callbackRef.current.onDragEnd?.(e);
|
|
1050
|
+
};
|
|
1051
|
+
marker.on("dragstart", dragStartHandler);
|
|
1052
|
+
marker.on("drag", dragHandler);
|
|
1053
|
+
marker.on("dragend", dragEndHandler);
|
|
1013
1054
|
marker.addTo(map.getMap());
|
|
1014
1055
|
return () => {
|
|
1056
|
+
marker.getElement().removeEventListener("click", clickHandler);
|
|
1057
|
+
marker.off("dragstart", dragStartHandler);
|
|
1058
|
+
marker.off("drag", dragHandler);
|
|
1059
|
+
marker.off("dragend", dragEndHandler);
|
|
1015
1060
|
marker.remove();
|
|
1016
1061
|
};
|
|
1017
1062
|
}, []);
|
|
@@ -1024,44 +1069,44 @@ var Marker = (0, import_react7.memo)(
|
|
|
1024
1069
|
popup = null,
|
|
1025
1070
|
rotation = 0,
|
|
1026
1071
|
rotationAlignment = "auto",
|
|
1027
|
-
pitchAlignment = "auto"
|
|
1072
|
+
pitchAlignment = "auto",
|
|
1073
|
+
className
|
|
1028
1074
|
} = props;
|
|
1029
1075
|
(0, import_react7.useEffect)(() => {
|
|
1030
1076
|
applyReactStyle(marker.getElement(), style);
|
|
1031
1077
|
}, [style]);
|
|
1032
1078
|
(0, import_react7.useImperativeHandle)(ref, () => marker, []);
|
|
1033
|
-
const
|
|
1034
|
-
|
|
1035
|
-
marker.
|
|
1036
|
-
|
|
1037
|
-
if (offset && !arePointsEqual(marker.getOffset(), offset)) {
|
|
1038
|
-
marker.setOffset(offset);
|
|
1039
|
-
}
|
|
1040
|
-
if (marker.isDraggable() !== draggable) {
|
|
1041
|
-
marker.setDraggable(draggable);
|
|
1042
|
-
}
|
|
1043
|
-
if (marker.getRotation() !== rotation) {
|
|
1044
|
-
marker.setRotation(rotation);
|
|
1045
|
-
}
|
|
1046
|
-
if (marker.getRotationAlignment() !== rotationAlignment) {
|
|
1047
|
-
marker.setRotationAlignment(rotationAlignment);
|
|
1048
|
-
}
|
|
1049
|
-
if (marker.getPitchAlignment() !== pitchAlignment) {
|
|
1050
|
-
marker.setPitchAlignment(pitchAlignment);
|
|
1051
|
-
}
|
|
1052
|
-
if (marker.getPopup() !== popup) {
|
|
1053
|
-
marker.setPopup(popup);
|
|
1054
|
-
}
|
|
1055
|
-
const classNameDiff = compareClassNames(
|
|
1056
|
-
oldProps.className,
|
|
1057
|
-
props.className
|
|
1058
|
-
);
|
|
1059
|
-
if (classNameDiff) {
|
|
1060
|
-
for (const c of classNameDiff) {
|
|
1061
|
-
marker.toggleClassName(c);
|
|
1079
|
+
const prevClassNameRef = (0, import_react7.useRef)(className);
|
|
1080
|
+
(0, import_react7.useEffect)(() => {
|
|
1081
|
+
if (marker.getLngLat().lng !== longitude || marker.getLngLat().lat !== latitude) {
|
|
1082
|
+
marker.setLngLat([longitude, latitude]);
|
|
1062
1083
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1084
|
+
if (offset && !arePointsEqual(marker.getOffset(), offset)) {
|
|
1085
|
+
marker.setOffset(offset);
|
|
1086
|
+
}
|
|
1087
|
+
if (marker.isDraggable() !== draggable) {
|
|
1088
|
+
marker.setDraggable(draggable);
|
|
1089
|
+
}
|
|
1090
|
+
if (marker.getRotation() !== rotation) {
|
|
1091
|
+
marker.setRotation(rotation);
|
|
1092
|
+
}
|
|
1093
|
+
if (marker.getRotationAlignment() !== rotationAlignment) {
|
|
1094
|
+
marker.setRotationAlignment(rotationAlignment);
|
|
1095
|
+
}
|
|
1096
|
+
if (marker.getPitchAlignment() !== pitchAlignment) {
|
|
1097
|
+
marker.setPitchAlignment(pitchAlignment);
|
|
1098
|
+
}
|
|
1099
|
+
if (marker.getPopup() !== popup) {
|
|
1100
|
+
marker.setPopup(popup);
|
|
1101
|
+
}
|
|
1102
|
+
const classNameDiff = compareClassNames(prevClassNameRef.current, className);
|
|
1103
|
+
if (classNameDiff) {
|
|
1104
|
+
for (const c of classNameDiff) {
|
|
1105
|
+
marker.toggleClassName(c);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
prevClassNameRef.current = className;
|
|
1109
|
+
});
|
|
1065
1110
|
return (0, import_react_dom.createPortal)(props.children, marker.getElement());
|
|
1066
1111
|
})
|
|
1067
1112
|
);
|
|
@@ -1075,23 +1120,25 @@ var Popup = (0, import_react8.memo)(
|
|
|
1075
1120
|
const container = (0, import_react8.useMemo)(() => {
|
|
1076
1121
|
return document.createElement("div");
|
|
1077
1122
|
}, []);
|
|
1078
|
-
const thisRef = (0, import_react8.useRef)({ props });
|
|
1079
1123
|
const popup = (0, import_react8.useMemo)(() => {
|
|
1080
1124
|
const options = { ...props };
|
|
1081
1125
|
const pp = new mapLib.Popup(options);
|
|
1082
1126
|
pp.setLngLat([props.longitude, props.latitude]);
|
|
1083
|
-
pp.once("open", (e) => {
|
|
1084
|
-
thisRef.current.props.onOpen?.(e);
|
|
1085
|
-
});
|
|
1086
1127
|
return pp;
|
|
1087
1128
|
}, []);
|
|
1129
|
+
(0, import_react8.useImperativeHandle)(ref, () => popup, []);
|
|
1088
1130
|
(0, import_react8.useEffect)(() => {
|
|
1131
|
+
const onOpen = (e) => {
|
|
1132
|
+
props.onOpen?.(e);
|
|
1133
|
+
};
|
|
1089
1134
|
const onClose = (e) => {
|
|
1090
|
-
|
|
1135
|
+
props.onClose?.(e);
|
|
1091
1136
|
};
|
|
1137
|
+
popup.on("open", onOpen);
|
|
1092
1138
|
popup.on("close", onClose);
|
|
1093
1139
|
popup.setDOMContent(container).addTo(map.getMap());
|
|
1094
1140
|
return () => {
|
|
1141
|
+
popup.off("open", onOpen);
|
|
1095
1142
|
popup.off("close", onClose);
|
|
1096
1143
|
if (popup.isOpen()) {
|
|
1097
1144
|
popup.remove();
|
|
@@ -1101,30 +1148,34 @@ var Popup = (0, import_react8.memo)(
|
|
|
1101
1148
|
(0, import_react8.useEffect)(() => {
|
|
1102
1149
|
applyReactStyle(popup.getElement(), props.style);
|
|
1103
1150
|
}, [props.style]);
|
|
1104
|
-
(0, import_react8.
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1151
|
+
(0, import_react8.useEffect)(() => {
|
|
1152
|
+
if (popup.isOpen()) {
|
|
1153
|
+
if (popup.getLngLat().lng !== props.longitude || popup.getLngLat().lat !== props.latitude) {
|
|
1154
|
+
popup.setLngLat([props.longitude, props.latitude]);
|
|
1155
|
+
}
|
|
1109
1156
|
}
|
|
1110
|
-
|
|
1157
|
+
}, [props.longitude, props.latitude]);
|
|
1158
|
+
(0, import_react8.useEffect)(() => {
|
|
1159
|
+
if (popup.isOpen() && props.offset) {
|
|
1111
1160
|
popup.setOffset(props.offset);
|
|
1112
1161
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1162
|
+
}, [props.offset]);
|
|
1163
|
+
(0, import_react8.useEffect)(() => {
|
|
1164
|
+
if (popup.isOpen() && props.maxWidth !== void 0) {
|
|
1115
1165
|
popup.setMaxWidth(props.maxWidth);
|
|
1116
1166
|
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1167
|
+
}, [props.maxWidth]);
|
|
1168
|
+
(0, import_react8.useEffect)(() => {
|
|
1169
|
+
if (popup.isOpen() && props.className) {
|
|
1170
|
+
const currentClassName = popup.options.className || "";
|
|
1171
|
+
const classNameDiff = compareClassNames(currentClassName, props.className);
|
|
1172
|
+
if (classNameDiff) {
|
|
1173
|
+
for (const c of classNameDiff) {
|
|
1174
|
+
popup.toggleClassName(c);
|
|
1175
|
+
}
|
|
1124
1176
|
}
|
|
1125
1177
|
}
|
|
1126
|
-
|
|
1127
|
-
}
|
|
1178
|
+
}, [props.className]);
|
|
1128
1179
|
return (0, import_react_dom2.createPortal)(props.children, container);
|
|
1129
1180
|
})
|
|
1130
1181
|
);
|
|
@@ -1184,9 +1235,7 @@ function _GeolocateControl(props, ref) {
|
|
|
1184
1235
|
}, [props.style]);
|
|
1185
1236
|
return null;
|
|
1186
1237
|
}
|
|
1187
|
-
var GeolocateControl = (0, import_react10.memo)(
|
|
1188
|
-
(0, import_react10.forwardRef)(_GeolocateControl)
|
|
1189
|
-
);
|
|
1238
|
+
var GeolocateControl = (0, import_react10.memo)((0, import_react10.forwardRef)(_GeolocateControl));
|
|
1190
1239
|
|
|
1191
1240
|
// src/components/navigation-control.ts
|
|
1192
1241
|
var import_react11 = require("react");
|
|
@@ -1210,16 +1259,18 @@ function _ScaleControl(props) {
|
|
|
1210
1259
|
const propsRef = (0, import_react12.useRef)(props);
|
|
1211
1260
|
const prevProps = propsRef.current;
|
|
1212
1261
|
propsRef.current = props;
|
|
1213
|
-
const { style } = props;
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1262
|
+
const { style, maxWidth, unit } = props;
|
|
1263
|
+
(0, import_react12.useEffect)(() => {
|
|
1264
|
+
if (maxWidth !== void 0 && maxWidth !== prevProps.maxWidth) {
|
|
1265
|
+
ctrl.options.maxWidth = maxWidth;
|
|
1266
|
+
}
|
|
1267
|
+
if (unit !== void 0 && unit !== prevProps.unit) {
|
|
1268
|
+
ctrl.setUnit(unit);
|
|
1269
|
+
}
|
|
1270
|
+
}, [ctrl, maxWidth, unit, prevProps.maxWidth, prevProps.unit]);
|
|
1220
1271
|
(0, import_react12.useEffect)(() => {
|
|
1221
1272
|
applyReactStyle(ctrl._container, style);
|
|
1222
|
-
}, [style]);
|
|
1273
|
+
}, [ctrl, style]);
|
|
1223
1274
|
return null;
|
|
1224
1275
|
}
|
|
1225
1276
|
var ScaleControl = (0, import_react12.memo)(_ScaleControl);
|
|
@@ -1249,9 +1300,9 @@ function assert(condition, message) {
|
|
|
1249
1300
|
}
|
|
1250
1301
|
|
|
1251
1302
|
// src/components/source.ts
|
|
1252
|
-
var sourceCounter = 0;
|
|
1253
1303
|
function createSource(map, id, props) {
|
|
1254
|
-
|
|
1304
|
+
const mapInternal = map;
|
|
1305
|
+
if (mapInternal.style && mapInternal.style._loaded) {
|
|
1255
1306
|
const options = { ...props };
|
|
1256
1307
|
delete options.id;
|
|
1257
1308
|
delete options.children;
|
|
@@ -1276,33 +1327,43 @@ function updateSource(source, props, prevProps) {
|
|
|
1276
1327
|
}
|
|
1277
1328
|
const type = props.type;
|
|
1278
1329
|
if (type === "geojson") {
|
|
1330
|
+
;
|
|
1279
1331
|
source.setData(props.data);
|
|
1280
1332
|
} else if (type === "image") {
|
|
1333
|
+
;
|
|
1281
1334
|
source.updateImage({
|
|
1282
1335
|
url: props.url,
|
|
1283
1336
|
coordinates: props.coordinates
|
|
1284
1337
|
});
|
|
1285
1338
|
} else {
|
|
1339
|
+
const sourceWithMethods = source;
|
|
1340
|
+
const propsWithOptional = props;
|
|
1286
1341
|
switch (changedKey) {
|
|
1287
1342
|
case "coordinates":
|
|
1288
|
-
|
|
1343
|
+
sourceWithMethods.setCoordinates?.(propsWithOptional.coordinates);
|
|
1289
1344
|
break;
|
|
1290
1345
|
case "url":
|
|
1291
|
-
|
|
1346
|
+
sourceWithMethods.setUrl?.(propsWithOptional.url);
|
|
1292
1347
|
break;
|
|
1293
1348
|
case "tiles":
|
|
1294
|
-
|
|
1349
|
+
sourceWithMethods.setTiles?.(propsWithOptional.tiles);
|
|
1295
1350
|
break;
|
|
1296
1351
|
default:
|
|
1297
1352
|
console.warn(`Unable to update <Source> prop: ${changedKey}`);
|
|
1298
1353
|
}
|
|
1299
1354
|
}
|
|
1300
1355
|
}
|
|
1301
|
-
function
|
|
1356
|
+
function _Source(props, ref) {
|
|
1302
1357
|
const map = (0, import_react14.useContext)(MapContext).map.getMap();
|
|
1303
1358
|
const propsRef = (0, import_react14.useRef)(props);
|
|
1359
|
+
const sourceRef = (0, import_react14.useRef)(null);
|
|
1304
1360
|
const [, setStyleLoaded] = (0, import_react14.useState)(0);
|
|
1305
|
-
const
|
|
1361
|
+
const generatedId = (0, import_react14.useId)();
|
|
1362
|
+
const id = (0, import_react14.useMemo)(
|
|
1363
|
+
() => props.id || `jsx-source-${generatedId.replace(/:/g, "-")}`,
|
|
1364
|
+
// Empty deps - id is set once on mount and should not change
|
|
1365
|
+
[]
|
|
1366
|
+
);
|
|
1306
1367
|
(0, import_react14.useEffect)(() => {
|
|
1307
1368
|
if (map) {
|
|
1308
1369
|
const forceUpdate = () => setTimeout(() => setStyleLoaded((version) => version + 1), 0);
|
|
@@ -1310,11 +1371,13 @@ function Source(props) {
|
|
|
1310
1371
|
forceUpdate();
|
|
1311
1372
|
return () => {
|
|
1312
1373
|
map.off("styledata", forceUpdate);
|
|
1313
|
-
|
|
1374
|
+
const mapInternal2 = map;
|
|
1375
|
+
if (mapInternal2.style && mapInternal2.style._loaded && map.getSource(id)) {
|
|
1314
1376
|
const allLayers = map.getStyle()?.layers;
|
|
1315
1377
|
if (allLayers) {
|
|
1316
1378
|
for (const layer of allLayers) {
|
|
1317
|
-
|
|
1379
|
+
const layerWithSource = layer;
|
|
1380
|
+
if (layerWithSource.source === id) {
|
|
1318
1381
|
map.removeLayer(layer.id);
|
|
1319
1382
|
}
|
|
1320
1383
|
}
|
|
@@ -1325,13 +1388,16 @@ function Source(props) {
|
|
|
1325
1388
|
}
|
|
1326
1389
|
return void 0;
|
|
1327
1390
|
}, [map]);
|
|
1328
|
-
|
|
1391
|
+
const mapInternal = map;
|
|
1392
|
+
let source = map && mapInternal.style && map.getSource(id);
|
|
1329
1393
|
if (source) {
|
|
1330
1394
|
updateSource(source, props, propsRef.current);
|
|
1331
1395
|
} else {
|
|
1332
1396
|
source = createSource(map, id, props);
|
|
1333
1397
|
}
|
|
1398
|
+
sourceRef.current = source;
|
|
1334
1399
|
propsRef.current = props;
|
|
1400
|
+
(0, import_react14.useImperativeHandle)(ref, () => sourceRef.current, [source]);
|
|
1335
1401
|
return source && React4.Children.map(
|
|
1336
1402
|
props.children,
|
|
1337
1403
|
(child) => child && (0, import_react14.cloneElement)(child, {
|
|
@@ -1339,21 +1405,103 @@ function Source(props) {
|
|
|
1339
1405
|
})
|
|
1340
1406
|
) || null;
|
|
1341
1407
|
}
|
|
1408
|
+
var Source = (0, import_react14.memo)(React4.forwardRef(_Source));
|
|
1342
1409
|
|
|
1343
|
-
// src/components/
|
|
1410
|
+
// src/components/canvas-source.ts
|
|
1411
|
+
var React5 = __toESM(require("react"), 1);
|
|
1344
1412
|
var import_react15 = require("react");
|
|
1413
|
+
function _CanvasSource(props) {
|
|
1414
|
+
const map = (0, import_react15.useContext)(MapContext).map.getMap();
|
|
1415
|
+
const propsRef = (0, import_react15.useRef)(props);
|
|
1416
|
+
const id = (0, import_react15.useMemo)(() => props.id || `canvas-source-${Date.now()}`, [props.id]);
|
|
1417
|
+
(0, import_react15.useEffect)(() => {
|
|
1418
|
+
if (!map) return void 0;
|
|
1419
|
+
const mapInternal2 = map;
|
|
1420
|
+
let source = null;
|
|
1421
|
+
const addSource = () => {
|
|
1422
|
+
if (!mapInternal2.style || !mapInternal2.style._loaded) return;
|
|
1423
|
+
if (map.getSource(id)) return;
|
|
1424
|
+
const { coordinates, canvas, animate } = props;
|
|
1425
|
+
map.addSource(id, {
|
|
1426
|
+
type: "canvas",
|
|
1427
|
+
coordinates,
|
|
1428
|
+
canvas,
|
|
1429
|
+
animate: animate || false
|
|
1430
|
+
});
|
|
1431
|
+
source = map.getSource(id);
|
|
1432
|
+
};
|
|
1433
|
+
const updateSource2 = () => {
|
|
1434
|
+
if (!source) return;
|
|
1435
|
+
const { coordinates, canvas } = props;
|
|
1436
|
+
const prevProps = propsRef.current;
|
|
1437
|
+
if (JSON.stringify(coordinates) !== JSON.stringify(prevProps.coordinates)) {
|
|
1438
|
+
const sourceWithMethods = source;
|
|
1439
|
+
sourceWithMethods.setCoordinates?.(coordinates);
|
|
1440
|
+
}
|
|
1441
|
+
};
|
|
1442
|
+
if (mapInternal2.style && mapInternal2.style._loaded) {
|
|
1443
|
+
addSource();
|
|
1444
|
+
} else {
|
|
1445
|
+
map.once("styledata", addSource);
|
|
1446
|
+
}
|
|
1447
|
+
return () => {
|
|
1448
|
+
map.off("styledata", addSource);
|
|
1449
|
+
const mapInternalForCleanup = map;
|
|
1450
|
+
if (mapInternalForCleanup.style && mapInternalForCleanup.style._loaded && map.getSource(id)) {
|
|
1451
|
+
const allLayers = map.getStyle()?.layers;
|
|
1452
|
+
if (allLayers) {
|
|
1453
|
+
for (const layer of allLayers) {
|
|
1454
|
+
if (layer.source === id) {
|
|
1455
|
+
map.removeLayer(layer.id);
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
map.removeSource(id);
|
|
1460
|
+
}
|
|
1461
|
+
};
|
|
1462
|
+
}, [map, id]);
|
|
1463
|
+
(0, import_react15.useEffect)(() => {
|
|
1464
|
+
if (!map) return;
|
|
1465
|
+
const source = map.getSource(id);
|
|
1466
|
+
if (!source) return;
|
|
1467
|
+
const { coordinates } = props;
|
|
1468
|
+
const prevProps = propsRef.current;
|
|
1469
|
+
if (JSON.stringify(coordinates) !== JSON.stringify(prevProps.coordinates)) {
|
|
1470
|
+
const sourceWithMethods = source;
|
|
1471
|
+
sourceWithMethods.setCoordinates?.(coordinates);
|
|
1472
|
+
}
|
|
1473
|
+
propsRef.current = props;
|
|
1474
|
+
}, [map, id, props.coordinates, props.canvas]);
|
|
1475
|
+
if (!map) return null;
|
|
1476
|
+
const mapInternal = map;
|
|
1477
|
+
if (!mapInternal.style || !mapInternal.style._loaded || !map.getSource(id)) {
|
|
1478
|
+
return null;
|
|
1479
|
+
}
|
|
1480
|
+
return props.children && React5.Children.map(
|
|
1481
|
+
props.children,
|
|
1482
|
+
(child) => child && React5.cloneElement(child, {
|
|
1483
|
+
source: id
|
|
1484
|
+
})
|
|
1485
|
+
) || null;
|
|
1486
|
+
}
|
|
1487
|
+
var CanvasSource = (0, import_react15.memo)(_CanvasSource);
|
|
1488
|
+
|
|
1489
|
+
// src/components/layer.ts
|
|
1490
|
+
var import_react16 = require("react");
|
|
1345
1491
|
function updateLayer(map, id, props, prevProps) {
|
|
1346
1492
|
assert(props.id === prevProps.id, "layer id changed");
|
|
1347
1493
|
assert(props.type === prevProps.type, "layer type changed");
|
|
1348
1494
|
if (props.type === "custom" || prevProps.type === "custom") {
|
|
1349
1495
|
return;
|
|
1350
1496
|
}
|
|
1351
|
-
const
|
|
1352
|
-
|
|
1497
|
+
const propsWithFilter = props;
|
|
1498
|
+
const prevPropsWithFilter = prevProps;
|
|
1499
|
+
const { layout = {}, paint = {}, filter, minzoom, maxzoom, beforeId } = propsWithFilter;
|
|
1500
|
+
if (beforeId !== prevPropsWithFilter.beforeId) {
|
|
1353
1501
|
map.moveLayer(id, beforeId);
|
|
1354
1502
|
}
|
|
1355
|
-
if (layout !==
|
|
1356
|
-
const prevLayout =
|
|
1503
|
+
if (layout !== prevPropsWithFilter.layout) {
|
|
1504
|
+
const prevLayout = prevPropsWithFilter.layout || {};
|
|
1357
1505
|
for (const key in layout) {
|
|
1358
1506
|
if (!deepEqual(layout[key], prevLayout[key])) {
|
|
1359
1507
|
map.setLayoutProperty(id, key, layout[key]);
|
|
@@ -1365,8 +1513,8 @@ function updateLayer(map, id, props, prevProps) {
|
|
|
1365
1513
|
}
|
|
1366
1514
|
}
|
|
1367
1515
|
}
|
|
1368
|
-
if (paint !==
|
|
1369
|
-
const prevPaint =
|
|
1516
|
+
if (paint !== prevPropsWithFilter.paint) {
|
|
1517
|
+
const prevPaint = prevPropsWithFilter.paint || {};
|
|
1370
1518
|
for (const key in paint) {
|
|
1371
1519
|
if (!deepEqual(paint[key], prevPaint[key])) {
|
|
1372
1520
|
map.setPaintProperty(id, key, paint[key]);
|
|
@@ -1378,41 +1526,151 @@ function updateLayer(map, id, props, prevProps) {
|
|
|
1378
1526
|
}
|
|
1379
1527
|
}
|
|
1380
1528
|
}
|
|
1381
|
-
if (!deepEqual(filter,
|
|
1382
|
-
map.setFilter(id, filter);
|
|
1529
|
+
if (!deepEqual(filter, prevPropsWithFilter.filter)) {
|
|
1530
|
+
map.setFilter(id, filter ?? null);
|
|
1383
1531
|
}
|
|
1384
|
-
if (minzoom !==
|
|
1532
|
+
if (minzoom !== prevPropsWithFilter.minzoom || maxzoom !== prevPropsWithFilter.maxzoom) {
|
|
1385
1533
|
map.setLayerZoomRange(id, minzoom, maxzoom);
|
|
1386
1534
|
}
|
|
1387
1535
|
}
|
|
1388
1536
|
function createLayer(map, id, props) {
|
|
1389
|
-
|
|
1537
|
+
const mapInternal = map;
|
|
1538
|
+
if (mapInternal.style && mapInternal.style._loaded && (!("source" in props) || map.getSource(props.source))) {
|
|
1390
1539
|
const options = { ...props, id };
|
|
1391
1540
|
delete options.beforeId;
|
|
1392
1541
|
map.addLayer(options, props.beforeId);
|
|
1393
1542
|
}
|
|
1394
1543
|
}
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
const
|
|
1398
|
-
const
|
|
1399
|
-
const
|
|
1400
|
-
const id = (0,
|
|
1401
|
-
|
|
1544
|
+
function _Layer(props) {
|
|
1545
|
+
const map = (0, import_react16.useContext)(MapContext).map.getMap();
|
|
1546
|
+
const propsRef = (0, import_react16.useRef)(props);
|
|
1547
|
+
const [, setStyleLoaded] = (0, import_react16.useState)(0);
|
|
1548
|
+
const generatedId = (0, import_react16.useId)();
|
|
1549
|
+
const id = (0, import_react16.useMemo)(
|
|
1550
|
+
() => props.id || `jsx-layer-${generatedId.replace(/:/g, "-")}`,
|
|
1551
|
+
// Empty deps - id is set once on mount and should not change
|
|
1552
|
+
[]
|
|
1553
|
+
);
|
|
1554
|
+
const {
|
|
1555
|
+
onClick,
|
|
1556
|
+
onMouseEnter,
|
|
1557
|
+
onMouseLeave,
|
|
1558
|
+
onMouseMove,
|
|
1559
|
+
onMouseDown,
|
|
1560
|
+
onMouseUp,
|
|
1561
|
+
onContextMenu,
|
|
1562
|
+
onDoubleClick
|
|
1563
|
+
} = props;
|
|
1564
|
+
const callbacksRef = (0, import_react16.useRef)({
|
|
1565
|
+
onClick,
|
|
1566
|
+
onMouseEnter,
|
|
1567
|
+
onMouseLeave,
|
|
1568
|
+
onMouseMove,
|
|
1569
|
+
onMouseDown,
|
|
1570
|
+
onMouseUp,
|
|
1571
|
+
onContextMenu,
|
|
1572
|
+
onDoubleClick
|
|
1573
|
+
});
|
|
1574
|
+
(0, import_react16.useEffect)(() => {
|
|
1575
|
+
callbacksRef.current = {
|
|
1576
|
+
onClick,
|
|
1577
|
+
onMouseEnter,
|
|
1578
|
+
onMouseLeave,
|
|
1579
|
+
onMouseMove,
|
|
1580
|
+
onMouseDown,
|
|
1581
|
+
onMouseUp,
|
|
1582
|
+
onContextMenu,
|
|
1583
|
+
onDoubleClick
|
|
1584
|
+
};
|
|
1585
|
+
}, [
|
|
1586
|
+
onClick,
|
|
1587
|
+
onMouseEnter,
|
|
1588
|
+
onMouseLeave,
|
|
1589
|
+
onMouseMove,
|
|
1590
|
+
onMouseDown,
|
|
1591
|
+
onMouseUp,
|
|
1592
|
+
onContextMenu,
|
|
1593
|
+
onDoubleClick
|
|
1594
|
+
]);
|
|
1595
|
+
(0, import_react16.useEffect)(() => {
|
|
1402
1596
|
if (map) {
|
|
1403
1597
|
const forceUpdate = () => setStyleLoaded((version) => version + 1);
|
|
1404
1598
|
map.on("styledata", forceUpdate);
|
|
1405
1599
|
forceUpdate();
|
|
1406
1600
|
return () => {
|
|
1407
1601
|
map.off("styledata", forceUpdate);
|
|
1408
|
-
|
|
1602
|
+
const mapInternal2 = map;
|
|
1603
|
+
if (mapInternal2.style && mapInternal2.style._loaded && map.getLayer(id)) {
|
|
1409
1604
|
map.removeLayer(id);
|
|
1410
1605
|
}
|
|
1411
1606
|
};
|
|
1412
1607
|
}
|
|
1413
1608
|
return void 0;
|
|
1414
1609
|
}, [map]);
|
|
1415
|
-
|
|
1610
|
+
(0, import_react16.useEffect)(() => {
|
|
1611
|
+
if (!map) return void 0;
|
|
1612
|
+
const hasEventHandler = onClick || onMouseEnter || onMouseLeave || onMouseMove || onMouseDown || onMouseUp || onContextMenu || onDoubleClick;
|
|
1613
|
+
if (!hasEventHandler) return void 0;
|
|
1614
|
+
const handleClick = (e) => {
|
|
1615
|
+
callbacksRef.current.onClick?.(e);
|
|
1616
|
+
};
|
|
1617
|
+
const handleMouseEnter = (e) => {
|
|
1618
|
+
callbacksRef.current.onMouseEnter?.(e);
|
|
1619
|
+
if (callbacksRef.current.onClick) {
|
|
1620
|
+
map.getCanvas().style.cursor = "pointer";
|
|
1621
|
+
}
|
|
1622
|
+
};
|
|
1623
|
+
const handleMouseLeave = () => {
|
|
1624
|
+
callbacksRef.current.onMouseLeave?.();
|
|
1625
|
+
map.getCanvas().style.cursor = "";
|
|
1626
|
+
};
|
|
1627
|
+
const handleMouseMove = (e) => {
|
|
1628
|
+
callbacksRef.current.onMouseMove?.(e);
|
|
1629
|
+
};
|
|
1630
|
+
const handleMouseDown = (e) => {
|
|
1631
|
+
callbacksRef.current.onMouseDown?.(e);
|
|
1632
|
+
};
|
|
1633
|
+
const handleMouseUp = (e) => {
|
|
1634
|
+
callbacksRef.current.onMouseUp?.(e);
|
|
1635
|
+
};
|
|
1636
|
+
const handleContextMenu = (e) => {
|
|
1637
|
+
callbacksRef.current.onContextMenu?.(e);
|
|
1638
|
+
};
|
|
1639
|
+
const handleDoubleClick = (e) => {
|
|
1640
|
+
callbacksRef.current.onDoubleClick?.(e);
|
|
1641
|
+
};
|
|
1642
|
+
if (onClick) map.on("click", id, handleClick);
|
|
1643
|
+
if (onMouseEnter) map.on("mouseenter", id, handleMouseEnter);
|
|
1644
|
+
if (onMouseLeave) map.on("mouseleave", id, handleMouseLeave);
|
|
1645
|
+
if (onMouseMove) map.on("mousemove", id, handleMouseMove);
|
|
1646
|
+
if (onMouseDown) map.on("mousedown", id, handleMouseDown);
|
|
1647
|
+
if (onMouseUp) map.on("mouseup", id, handleMouseUp);
|
|
1648
|
+
if (onContextMenu) map.on("contextmenu", id, handleContextMenu);
|
|
1649
|
+
if (onDoubleClick) map.on("dblclick", id, handleDoubleClick);
|
|
1650
|
+
return () => {
|
|
1651
|
+
if (onClick) map.off("click", id, handleClick);
|
|
1652
|
+
if (onMouseEnter) map.off("mouseenter", id, handleMouseEnter);
|
|
1653
|
+
if (onMouseLeave) map.off("mouseleave", id, handleMouseLeave);
|
|
1654
|
+
if (onMouseMove) map.off("mousemove", id, handleMouseMove);
|
|
1655
|
+
if (onMouseDown) map.off("mousedown", id, handleMouseDown);
|
|
1656
|
+
if (onMouseUp) map.off("mouseup", id, handleMouseUp);
|
|
1657
|
+
if (onContextMenu) map.off("contextmenu", id, handleContextMenu);
|
|
1658
|
+
if (onDoubleClick) map.off("dblclick", id, handleDoubleClick);
|
|
1659
|
+
};
|
|
1660
|
+
}, [
|
|
1661
|
+
map,
|
|
1662
|
+
id,
|
|
1663
|
+
onClick,
|
|
1664
|
+
onMouseEnter,
|
|
1665
|
+
onMouseLeave,
|
|
1666
|
+
onMouseMove,
|
|
1667
|
+
onMouseDown,
|
|
1668
|
+
onMouseUp,
|
|
1669
|
+
onContextMenu,
|
|
1670
|
+
onDoubleClick
|
|
1671
|
+
]);
|
|
1672
|
+
const mapInternal = map;
|
|
1673
|
+
const layer = map && mapInternal.style && map.getLayer(id);
|
|
1416
1674
|
if (layer) {
|
|
1417
1675
|
try {
|
|
1418
1676
|
updateLayer(map, id, props, propsRef.current);
|
|
@@ -1425,19 +1683,768 @@ function Layer(props) {
|
|
|
1425
1683
|
propsRef.current = props;
|
|
1426
1684
|
return null;
|
|
1427
1685
|
}
|
|
1686
|
+
var Layer = (0, import_react16.memo)(_Layer);
|
|
1687
|
+
|
|
1688
|
+
// src/components/draw-control.ts
|
|
1689
|
+
var import_react17 = require("react");
|
|
1690
|
+
var import_maplibre_gl_draw = __toESM(require("maplibre-gl-draw"), 1);
|
|
1691
|
+
var defaultDrawOptions = {
|
|
1692
|
+
displayControlsDefault: false,
|
|
1693
|
+
controls: {
|
|
1694
|
+
polygon: true,
|
|
1695
|
+
trash: true
|
|
1696
|
+
}
|
|
1697
|
+
};
|
|
1698
|
+
function _DrawControl(props) {
|
|
1699
|
+
const {
|
|
1700
|
+
position,
|
|
1701
|
+
style,
|
|
1702
|
+
onDrawCreate,
|
|
1703
|
+
onDrawDelete,
|
|
1704
|
+
onDrawUpdate,
|
|
1705
|
+
onDrawSelectionChange,
|
|
1706
|
+
onDrawModeChange,
|
|
1707
|
+
onDrawCombine,
|
|
1708
|
+
onDrawUncombine,
|
|
1709
|
+
onDrawRender,
|
|
1710
|
+
...drawOptions
|
|
1711
|
+
} = props;
|
|
1712
|
+
const context = (0, import_react17.useContext)(MapContext);
|
|
1713
|
+
if (!context) {
|
|
1714
|
+
throw new Error("DrawControl must be used within a Map component");
|
|
1715
|
+
}
|
|
1716
|
+
const options = (0, import_react17.useMemo)(
|
|
1717
|
+
() => ({
|
|
1718
|
+
...defaultDrawOptions,
|
|
1719
|
+
...drawOptions,
|
|
1720
|
+
controls: {
|
|
1721
|
+
...defaultDrawOptions.controls,
|
|
1722
|
+
...drawOptions.controls
|
|
1723
|
+
}
|
|
1724
|
+
}),
|
|
1725
|
+
[
|
|
1726
|
+
drawOptions.displayControlsDefault,
|
|
1727
|
+
drawOptions.controls,
|
|
1728
|
+
drawOptions.styles,
|
|
1729
|
+
drawOptions.modes,
|
|
1730
|
+
drawOptions.defaultMode
|
|
1731
|
+
]
|
|
1732
|
+
);
|
|
1733
|
+
const optionsKey = (0, import_react17.useMemo)(() => JSON.stringify(options), [options]);
|
|
1734
|
+
const callbacksRef = (0, import_react17.useRef)({
|
|
1735
|
+
onDrawCreate,
|
|
1736
|
+
onDrawDelete,
|
|
1737
|
+
onDrawUpdate,
|
|
1738
|
+
onDrawSelectionChange,
|
|
1739
|
+
onDrawModeChange,
|
|
1740
|
+
onDrawCombine,
|
|
1741
|
+
onDrawUncombine,
|
|
1742
|
+
onDrawRender
|
|
1743
|
+
});
|
|
1744
|
+
(0, import_react17.useEffect)(() => {
|
|
1745
|
+
callbacksRef.current = {
|
|
1746
|
+
onDrawCreate,
|
|
1747
|
+
onDrawDelete,
|
|
1748
|
+
onDrawUpdate,
|
|
1749
|
+
onDrawSelectionChange,
|
|
1750
|
+
onDrawModeChange,
|
|
1751
|
+
onDrawCombine,
|
|
1752
|
+
onDrawUncombine,
|
|
1753
|
+
onDrawRender
|
|
1754
|
+
};
|
|
1755
|
+
}, [
|
|
1756
|
+
onDrawCreate,
|
|
1757
|
+
onDrawDelete,
|
|
1758
|
+
onDrawUpdate,
|
|
1759
|
+
onDrawSelectionChange,
|
|
1760
|
+
onDrawModeChange,
|
|
1761
|
+
onDrawCombine,
|
|
1762
|
+
onDrawUncombine,
|
|
1763
|
+
onDrawRender
|
|
1764
|
+
]);
|
|
1765
|
+
const ctrlRef = (0, import_react17.useRef)(null);
|
|
1766
|
+
const listenersRef = (0, import_react17.useRef)({});
|
|
1767
|
+
(0, import_react17.useEffect)(() => {
|
|
1768
|
+
const { map } = context;
|
|
1769
|
+
if (!map) return;
|
|
1770
|
+
const mapInstance = map.getMap();
|
|
1771
|
+
if (!mapInstance) return;
|
|
1772
|
+
const DrawClass = import_maplibre_gl_draw.default;
|
|
1773
|
+
const resetCursorIfNeeded = () => {
|
|
1774
|
+
if (ctrlRef.current) {
|
|
1775
|
+
const currentMode = ctrlRef.current.getMode();
|
|
1776
|
+
if (currentMode === "simple_select") {
|
|
1777
|
+
mapInstance.getCanvas().style.cursor = "";
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
};
|
|
1781
|
+
const handleCreate = (e) => {
|
|
1782
|
+
resetCursorIfNeeded();
|
|
1783
|
+
callbacksRef.current.onDrawCreate?.(e);
|
|
1784
|
+
};
|
|
1785
|
+
const handleUpdate = (e) => {
|
|
1786
|
+
resetCursorIfNeeded();
|
|
1787
|
+
callbacksRef.current.onDrawUpdate?.(e);
|
|
1788
|
+
};
|
|
1789
|
+
const handleDelete = (e) => {
|
|
1790
|
+
resetCursorIfNeeded();
|
|
1791
|
+
callbacksRef.current.onDrawDelete?.(e);
|
|
1792
|
+
};
|
|
1793
|
+
const handleSelectionChange = (e) => {
|
|
1794
|
+
resetCursorIfNeeded();
|
|
1795
|
+
callbacksRef.current.onDrawSelectionChange?.(e);
|
|
1796
|
+
};
|
|
1797
|
+
const handleModeChange = (e) => {
|
|
1798
|
+
resetCursorIfNeeded();
|
|
1799
|
+
callbacksRef.current.onDrawModeChange?.(e);
|
|
1800
|
+
};
|
|
1801
|
+
const handleCombine = (e) => {
|
|
1802
|
+
callbacksRef.current.onDrawCombine?.(e);
|
|
1803
|
+
};
|
|
1804
|
+
const handleUncombine = (e) => {
|
|
1805
|
+
callbacksRef.current.onDrawUncombine?.(e);
|
|
1806
|
+
};
|
|
1807
|
+
const handleRender = (e) => {
|
|
1808
|
+
callbacksRef.current.onDrawRender?.(e);
|
|
1809
|
+
};
|
|
1810
|
+
const ctrl = new DrawClass(options);
|
|
1811
|
+
ctrlRef.current = ctrl;
|
|
1812
|
+
map.addControl(ctrl, position);
|
|
1813
|
+
listenersRef.current = {
|
|
1814
|
+
handleCreate,
|
|
1815
|
+
handleUpdate,
|
|
1816
|
+
handleDelete,
|
|
1817
|
+
handleSelectionChange,
|
|
1818
|
+
handleModeChange,
|
|
1819
|
+
handleCombine,
|
|
1820
|
+
handleUncombine,
|
|
1821
|
+
handleRender
|
|
1822
|
+
};
|
|
1823
|
+
mapInstance.on("draw.create", handleCreate);
|
|
1824
|
+
mapInstance.on("draw.update", handleUpdate);
|
|
1825
|
+
mapInstance.on("draw.delete", handleDelete);
|
|
1826
|
+
mapInstance.on("draw.selectionchange", handleSelectionChange);
|
|
1827
|
+
mapInstance.on("draw.modechange", handleModeChange);
|
|
1828
|
+
mapInstance.on("draw.combine", handleCombine);
|
|
1829
|
+
mapInstance.on("draw.uncombine", handleUncombine);
|
|
1830
|
+
mapInstance.on("draw.render", handleRender);
|
|
1831
|
+
return () => {
|
|
1832
|
+
if (listenersRef.current.handleCreate) {
|
|
1833
|
+
mapInstance.off("draw.create", listenersRef.current.handleCreate);
|
|
1834
|
+
}
|
|
1835
|
+
if (listenersRef.current.handleUpdate) {
|
|
1836
|
+
mapInstance.off("draw.update", listenersRef.current.handleUpdate);
|
|
1837
|
+
}
|
|
1838
|
+
if (listenersRef.current.handleDelete) {
|
|
1839
|
+
mapInstance.off("draw.delete", listenersRef.current.handleDelete);
|
|
1840
|
+
}
|
|
1841
|
+
if (listenersRef.current.handleSelectionChange) {
|
|
1842
|
+
mapInstance.off("draw.selectionchange", listenersRef.current.handleSelectionChange);
|
|
1843
|
+
}
|
|
1844
|
+
if (listenersRef.current.handleModeChange) {
|
|
1845
|
+
mapInstance.off("draw.modechange", listenersRef.current.handleModeChange);
|
|
1846
|
+
}
|
|
1847
|
+
if (listenersRef.current.handleCombine) {
|
|
1848
|
+
mapInstance.off("draw.combine", listenersRef.current.handleCombine);
|
|
1849
|
+
}
|
|
1850
|
+
if (listenersRef.current.handleUncombine) {
|
|
1851
|
+
mapInstance.off("draw.uncombine", listenersRef.current.handleUncombine);
|
|
1852
|
+
}
|
|
1853
|
+
if (listenersRef.current.handleRender) {
|
|
1854
|
+
mapInstance.off("draw.render", listenersRef.current.handleRender);
|
|
1855
|
+
}
|
|
1856
|
+
if (ctrlRef.current && map.hasControl(ctrlRef.current)) {
|
|
1857
|
+
map.removeControl(ctrlRef.current);
|
|
1858
|
+
}
|
|
1859
|
+
ctrlRef.current = null;
|
|
1860
|
+
};
|
|
1861
|
+
}, [context, optionsKey, position]);
|
|
1862
|
+
return null;
|
|
1863
|
+
}
|
|
1864
|
+
var DrawControl = (0, import_react17.memo)(_DrawControl);
|
|
1865
|
+
|
|
1866
|
+
// src/components/globe-control.ts
|
|
1867
|
+
var import_react18 = require("react");
|
|
1868
|
+
var GLOBE_SVG = `<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2">
|
|
1869
|
+
<circle cx="12" cy="12" r="9" fill="none"/>
|
|
1870
|
+
<path d="M12 21a9 9-9 0 0-9 9-9 0 0 9h0c2.2a8.2 2.3 5.1 5.8-5.5c-.4-.4-.5-.9-.5-1.5v-1.3c0-2.3 1.8-4.2 4-4.5V5.5c-1.8.5-3.5 2-4.5 2.8 0 5.2 2.3 5.2 5 0z"/>
|
|
1871
|
+
<path d="M12 3c-2.8 0-5.2 2.3-5.2 5h2c0-1.5.1-1.1.5-1.5L5.8 9 2.3 5.1 8.2 2c.4 0 .9-.5 1.5-.5h1.3c2.3 0 4.2-1.8 4.5-4h-2c0 1.5-1.8 3.5-4 4.5V21c2.8 0 5.2-2.3 5.2-5h-2c0 1.5-.1 1.1-.5 1.5L18.2 15 14.8l2.7-5.1c-.4 0-.9.5-1.5.5h-1.3c-2.3 0-4.2 1.8-4.5 4h2c0-1.5 1.8-3.5 4-4.5V3z"/>
|
|
1872
|
+
</svg>`;
|
|
1873
|
+
var MAP_SVG = `<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2">
|
|
1874
|
+
<rect x="3" y="3" width="18" height="18" rx="2" fill="none"/>
|
|
1875
|
+
<path d="M3 9h18M3 15h18M9 3v18M15 3v18"/>
|
|
1876
|
+
</svg>`;
|
|
1877
|
+
var GlobeControlImpl = class {
|
|
1878
|
+
constructor(options, callbacks) {
|
|
1879
|
+
this._map = null;
|
|
1880
|
+
this._isGlobe = false;
|
|
1881
|
+
this._options = options;
|
|
1882
|
+
this._onProjectionChange = callbacks.onProjectionChange;
|
|
1883
|
+
this._container = document.createElement("div");
|
|
1884
|
+
this._container.className = "maplibregl-ctrl maplibregl-ctrl-group";
|
|
1885
|
+
this._button = this._createButton();
|
|
1886
|
+
this._container.appendChild(this._button);
|
|
1887
|
+
}
|
|
1888
|
+
_createButton() {
|
|
1889
|
+
const button = this._options.buttonElement || document.createElement("button");
|
|
1890
|
+
if (!this._options.buttonElement) {
|
|
1891
|
+
button.className = this._options.buttonClassName || "maplibregl-ctrl-globe";
|
|
1892
|
+
button.type = "button";
|
|
1893
|
+
button.title = this._options.buttonTitle || "Toggle Globe View";
|
|
1894
|
+
button.setAttribute("aria-label", "Toggle Globe View");
|
|
1895
|
+
button.innerHTML = this._isGlobe ? MAP_SVG : GLOBE_SVG;
|
|
1896
|
+
Object.assign(button.style, {
|
|
1897
|
+
padding: "5px",
|
|
1898
|
+
border: "none",
|
|
1899
|
+
background: "white",
|
|
1900
|
+
cursor: "pointer",
|
|
1901
|
+
borderRadius: "4px",
|
|
1902
|
+
display: "flex",
|
|
1903
|
+
alignItems: "center",
|
|
1904
|
+
justifyContent: "center",
|
|
1905
|
+
...this._options.buttonStyle
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
button.addEventListener("click", () => this._toggleGlobe());
|
|
1909
|
+
return button;
|
|
1910
|
+
}
|
|
1911
|
+
_toggleGlobe() {
|
|
1912
|
+
if (!this._map) return;
|
|
1913
|
+
this._isGlobe = !this._isGlobe;
|
|
1914
|
+
this._button.innerHTML = this._isGlobe ? MAP_SVG : GLOBE_SVG;
|
|
1915
|
+
this._button.title = this._isGlobe ? "Switch to Map View" : "Switch to Globe View";
|
|
1916
|
+
try {
|
|
1917
|
+
const projection = this._isGlobe ? { type: "globe" } : { type: "mercator" };
|
|
1918
|
+
this._map.setProjection(projection);
|
|
1919
|
+
this._onProjectionChange?.(this._isGlobe);
|
|
1920
|
+
} catch (error) {
|
|
1921
|
+
console.warn("GlobeControl: setProjection not available", error);
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
onAdd(map) {
|
|
1925
|
+
this._map = map;
|
|
1926
|
+
try {
|
|
1927
|
+
const currentProjection = map.getProjection?.();
|
|
1928
|
+
this._isGlobe = currentProjection?.type === "globe";
|
|
1929
|
+
this._button.innerHTML = this._isGlobe ? MAP_SVG : GLOBE_SVG;
|
|
1930
|
+
} catch {
|
|
1931
|
+
this._isGlobe = false;
|
|
1932
|
+
}
|
|
1933
|
+
return this._container;
|
|
1934
|
+
}
|
|
1935
|
+
onRemove() {
|
|
1936
|
+
this._container.parentNode?.removeChild(this._container);
|
|
1937
|
+
this._map = null;
|
|
1938
|
+
}
|
|
1939
|
+
/**
|
|
1940
|
+
* Check if currently in globe view
|
|
1941
|
+
*/
|
|
1942
|
+
isGlobe() {
|
|
1943
|
+
return this._isGlobe;
|
|
1944
|
+
}
|
|
1945
|
+
/**
|
|
1946
|
+
* Set the projection programmatically
|
|
1947
|
+
*/
|
|
1948
|
+
setGlobe(isGlobe) {
|
|
1949
|
+
if (this._isGlobe !== isGlobe) {
|
|
1950
|
+
this._toggleGlobe();
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1954
|
+
function _GlobeControl(props) {
|
|
1955
|
+
const { position, onProjectionChange, ...options } = props;
|
|
1956
|
+
const callbacksRef = (0, import_react18.useRef)({ onProjectionChange });
|
|
1957
|
+
(0, import_react18.useEffect)(() => {
|
|
1958
|
+
callbacksRef.current = { onProjectionChange };
|
|
1959
|
+
}, [onProjectionChange]);
|
|
1960
|
+
useControl(
|
|
1961
|
+
() => {
|
|
1962
|
+
return new GlobeControlImpl(options, {
|
|
1963
|
+
onProjectionChange: (isGlobe) => callbacksRef.current.onProjectionChange?.(isGlobe)
|
|
1964
|
+
});
|
|
1965
|
+
},
|
|
1966
|
+
{ position }
|
|
1967
|
+
);
|
|
1968
|
+
return null;
|
|
1969
|
+
}
|
|
1970
|
+
var GlobeControl = (0, import_react18.memo)(_GlobeControl);
|
|
1971
|
+
|
|
1972
|
+
// src/components/minimap-control.ts
|
|
1973
|
+
var import_react19 = require("react");
|
|
1974
|
+
var import_maplibre_gl = require("maplibre-gl");
|
|
1975
|
+
var DEFAULT_ZOOM_ADJUST = -4;
|
|
1976
|
+
var DEFAULT_COLLAPSED_SIZE = "29px";
|
|
1977
|
+
var DEFAULT_BORDER_RADIUS = "3px";
|
|
1978
|
+
var TRANSITION_DURATION_MS = 600;
|
|
1979
|
+
var RESIZE_DEBOUNCE_MS = 100;
|
|
1980
|
+
var DEFAULT_WIDTH = "400px";
|
|
1981
|
+
var DEFAULT_HEIGHT = "300px";
|
|
1982
|
+
var defaultInteractions = {
|
|
1983
|
+
dragPan: true,
|
|
1984
|
+
scrollZoom: false,
|
|
1985
|
+
boxZoom: false,
|
|
1986
|
+
dragRotate: false,
|
|
1987
|
+
keyboard: false,
|
|
1988
|
+
doubleClickZoom: false,
|
|
1989
|
+
touchZoomRotate: false
|
|
1990
|
+
};
|
|
1991
|
+
var DEFAULT_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.6 18L8 8.4V17H6V5h12v2H9.4l9.6 9.6l-1.4 1.4Z" /></svg>`;
|
|
1992
|
+
function getRandomUUID() {
|
|
1993
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
1994
|
+
return crypto.randomUUID();
|
|
1995
|
+
}
|
|
1996
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
1997
|
+
const array = new Uint8Array(1);
|
|
1998
|
+
crypto.getRandomValues(array);
|
|
1999
|
+
const r = array[0] % 16;
|
|
2000
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
2001
|
+
return v.toString(16);
|
|
2002
|
+
});
|
|
2003
|
+
}
|
|
2004
|
+
function sanitizeSVG(svgString) {
|
|
2005
|
+
const svgPattern = /^<svg[^>]*>[\s\S]*<\/svg>$/i;
|
|
2006
|
+
if (!svgPattern.test(svgString)) {
|
|
2007
|
+
console.warn("Invalid SVG format, using default icon");
|
|
2008
|
+
return DEFAULT_ICON;
|
|
2009
|
+
}
|
|
2010
|
+
return svgString.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, "").replace(/javascript:/gi, "");
|
|
2011
|
+
}
|
|
2012
|
+
var Minimap = class {
|
|
2013
|
+
constructor(options = {}) {
|
|
2014
|
+
this.differentStyle = false;
|
|
2015
|
+
this.isMinimized = false;
|
|
2016
|
+
this.id = `minimap-${getRandomUUID()}`;
|
|
2017
|
+
if (options.style !== void 0) {
|
|
2018
|
+
this.differentStyle = true;
|
|
2019
|
+
}
|
|
2020
|
+
const interactions = { ...defaultInteractions, ...options.interactions ?? {} };
|
|
2021
|
+
const containerStyle = this.validateContainerStyle(options.containerStyle);
|
|
2022
|
+
this.options = {
|
|
2023
|
+
zoomAdjust: DEFAULT_ZOOM_ADJUST,
|
|
2024
|
+
position: "top-right",
|
|
2025
|
+
pitchAdjust: false,
|
|
2026
|
+
attributionControl: false,
|
|
2027
|
+
logoPosition: "bottom-left",
|
|
2028
|
+
toggleable: true,
|
|
2029
|
+
initialMinimized: false,
|
|
2030
|
+
collapsedWidth: DEFAULT_COLLAPSED_SIZE,
|
|
2031
|
+
collapsedHeight: DEFAULT_COLLAPSED_SIZE,
|
|
2032
|
+
borderRadius: DEFAULT_BORDER_RADIUS,
|
|
2033
|
+
hideText: "Hide minimap",
|
|
2034
|
+
showText: "Show minimap",
|
|
2035
|
+
responsive: true,
|
|
2036
|
+
responsiveWidth: "20vw",
|
|
2037
|
+
responsiveHeight: "20vh",
|
|
2038
|
+
minWidth: "200px",
|
|
2039
|
+
minHeight: "150px",
|
|
2040
|
+
maxWidth: DEFAULT_WIDTH,
|
|
2041
|
+
maxHeight: DEFAULT_HEIGHT,
|
|
2042
|
+
interactions,
|
|
2043
|
+
...options,
|
|
2044
|
+
containerStyle
|
|
2045
|
+
};
|
|
2046
|
+
if (options.lockZoom !== void 0) {
|
|
2047
|
+
this.options.minZoom = options.lockZoom;
|
|
2048
|
+
this.options.maxZoom = options.lockZoom;
|
|
2049
|
+
}
|
|
2050
|
+
this.isMinimized = this.options.initialMinimized ?? false;
|
|
2051
|
+
}
|
|
2052
|
+
onAdd(parentMap) {
|
|
2053
|
+
this.parentMap = parentMap;
|
|
2054
|
+
this.container = this.createContainer();
|
|
2055
|
+
this.options.container = this.container;
|
|
2056
|
+
this.options.zoom = parentMap.getZoom() + (this.options.zoomAdjust ?? DEFAULT_ZOOM_ADJUST);
|
|
2057
|
+
this.options.center ??= parentMap.getCenter().toArray();
|
|
2058
|
+
this.options.bearing = parentMap.getBearing();
|
|
2059
|
+
this.options.pitch = this.options.pitchAdjust ? parentMap.getPitch() : 0;
|
|
2060
|
+
if (!this.differentStyle) {
|
|
2061
|
+
this.options.style = parentMap.getStyle();
|
|
2062
|
+
}
|
|
2063
|
+
this.map = new import_maplibre_gl.Map(this.options);
|
|
2064
|
+
this.map.once("style.load", () => {
|
|
2065
|
+
this.map.resize();
|
|
2066
|
+
});
|
|
2067
|
+
this.map.once("load", () => {
|
|
2068
|
+
this.configureInteractions();
|
|
2069
|
+
this.addParentRect(this.options.parentRect);
|
|
2070
|
+
this.desync = this.syncMaps();
|
|
2071
|
+
this.setupToggleButton();
|
|
2072
|
+
this.setupResponsiveSizing();
|
|
2073
|
+
});
|
|
2074
|
+
return this.container;
|
|
2075
|
+
}
|
|
2076
|
+
onRemove() {
|
|
2077
|
+
if (this.resizeHandler) {
|
|
2078
|
+
window.removeEventListener("resize", this.resizeHandler);
|
|
2079
|
+
this.resizeHandler = void 0;
|
|
2080
|
+
}
|
|
2081
|
+
this.toggleButtonCleanup?.();
|
|
2082
|
+
this.desync?.();
|
|
2083
|
+
this.container.remove();
|
|
2084
|
+
}
|
|
2085
|
+
createContainer() {
|
|
2086
|
+
const container = document.createElement("div");
|
|
2087
|
+
container.id = this.id;
|
|
2088
|
+
container.className = "maplibregl-ctrl maplibregl-ctrl-group maplibregl-ctrl-minimap custom-ctrl-minimap";
|
|
2089
|
+
if (this.isMinimized) {
|
|
2090
|
+
container.classList.add("minimized");
|
|
2091
|
+
}
|
|
2092
|
+
const styleEl = document.createElement("style");
|
|
2093
|
+
styleEl.innerHTML = this.getContainerStyles();
|
|
2094
|
+
container.appendChild(styleEl);
|
|
2095
|
+
if (this.options.containerStyle) {
|
|
2096
|
+
for (const [key, value] of Object.entries(this.options.containerStyle)) {
|
|
2097
|
+
container.style.setProperty(key, value);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
if (this.isMinimized) {
|
|
2101
|
+
container.style.width = this.options.collapsedWidth || DEFAULT_COLLAPSED_SIZE;
|
|
2102
|
+
container.style.height = this.options.collapsedHeight || DEFAULT_COLLAPSED_SIZE;
|
|
2103
|
+
}
|
|
2104
|
+
const preventDefault = (e) => e.preventDefault();
|
|
2105
|
+
container.addEventListener("contextmenu", preventDefault);
|
|
2106
|
+
return container;
|
|
2107
|
+
}
|
|
2108
|
+
getContainerStyles() {
|
|
2109
|
+
const width = this.options.containerStyle?.width || DEFAULT_WIDTH;
|
|
2110
|
+
const height = this.options.containerStyle?.height || DEFAULT_HEIGHT;
|
|
2111
|
+
const collapsedWidth = this.options.collapsedWidth || DEFAULT_COLLAPSED_SIZE;
|
|
2112
|
+
const collapsedHeight = this.options.collapsedHeight || DEFAULT_COLLAPSED_SIZE;
|
|
2113
|
+
const borderRadius = this.options.borderRadius || DEFAULT_BORDER_RADIUS;
|
|
2114
|
+
return `
|
|
2115
|
+
#${this.id}.custom-ctrl-minimap {
|
|
2116
|
+
cursor: default !important;
|
|
2117
|
+
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);
|
|
2118
|
+
transition: width 0.6s ease-in, height 0.6s ease-in, border-color 0s ease-in;
|
|
2119
|
+
border-style: solid;
|
|
2120
|
+
border-radius: ${borderRadius};
|
|
2121
|
+
border-width: 4px;
|
|
2122
|
+
border-color: white;
|
|
2123
|
+
width: ${width};
|
|
2124
|
+
height: ${height};
|
|
2125
|
+
overflow: hidden;
|
|
2126
|
+
background: #fff;
|
|
2127
|
+
position: relative;
|
|
2128
|
+
}
|
|
2129
|
+
#${this.id}.minimized {
|
|
2130
|
+
border-radius: 3px !important;
|
|
2131
|
+
width: ${collapsedWidth};
|
|
2132
|
+
height: ${collapsedHeight};
|
|
2133
|
+
}
|
|
2134
|
+
#${this.id} canvas {
|
|
2135
|
+
width: 100% !important;
|
|
2136
|
+
height: 100% !important;
|
|
2137
|
+
display: block;
|
|
2138
|
+
}
|
|
2139
|
+
@media (prefers-color-scheme: dark) {
|
|
2140
|
+
#${this.id}.custom-ctrl-minimap {
|
|
2141
|
+
border-color: hsl(0, 0%, 15.2%);
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
`;
|
|
2145
|
+
}
|
|
2146
|
+
validateContainerStyle(style) {
|
|
2147
|
+
const defaults = { border: "1px solid #000", width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT };
|
|
2148
|
+
if (!style) return defaults;
|
|
2149
|
+
const validated = {};
|
|
2150
|
+
if (style.width) {
|
|
2151
|
+
validated.width = CSS.supports("width", style.width) ? style.width : defaults.width;
|
|
2152
|
+
} else {
|
|
2153
|
+
validated.width = defaults.width;
|
|
2154
|
+
}
|
|
2155
|
+
if (style.height) {
|
|
2156
|
+
validated.height = CSS.supports("height", style.height) ? style.height : defaults.height;
|
|
2157
|
+
} else {
|
|
2158
|
+
validated.height = defaults.height;
|
|
2159
|
+
}
|
|
2160
|
+
for (const [key, value] of Object.entries(style)) {
|
|
2161
|
+
if (key !== "width" && key !== "height") {
|
|
2162
|
+
validated[key] = value;
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
return validated;
|
|
2166
|
+
}
|
|
2167
|
+
configureInteractions() {
|
|
2168
|
+
const interactions = this.options.interactions || defaultInteractions;
|
|
2169
|
+
for (const [interaction, enabled] of Object.entries(interactions)) {
|
|
2170
|
+
if (!enabled) {
|
|
2171
|
+
const interactionMethod = interaction;
|
|
2172
|
+
const interactionObj = this.map[interactionMethod];
|
|
2173
|
+
interactionObj?.disable();
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
setupToggleButton() {
|
|
2178
|
+
if (!this.options.toggleable) return;
|
|
2179
|
+
const el = document.createElement("button");
|
|
2180
|
+
const elId = "btn-" + getRandomUUID();
|
|
2181
|
+
el.innerHTML = sanitizeSVG(this.options.toggleButton?.icon || DEFAULT_ICON);
|
|
2182
|
+
el.setAttribute("id", elId);
|
|
2183
|
+
el.setAttribute("type", "button");
|
|
2184
|
+
el.setAttribute("aria-label", this.options.hideText || "Hide minimap");
|
|
2185
|
+
el.setAttribute("title", this.options.hideText || "Hide minimap");
|
|
2186
|
+
if (this.options.toggleButton?.className) {
|
|
2187
|
+
const classes = this.options.toggleButton.className.split(" ");
|
|
2188
|
+
classes.forEach((cls) => el.classList.add(cls));
|
|
2189
|
+
}
|
|
2190
|
+
const iconBackgroundColor = this.options.toggleButton?.iconBackgroundColor || "black";
|
|
2191
|
+
const hoverColor = this.options.toggleButton?.hoverColor || "#e5e7e3";
|
|
2192
|
+
const styleEl = document.createElement("style");
|
|
2193
|
+
styleEl.innerHTML = `
|
|
2194
|
+
button#${elId} {
|
|
2195
|
+
border-radius: 0 !important;
|
|
2196
|
+
color: black;
|
|
2197
|
+
background-color: ${iconBackgroundColor};
|
|
2198
|
+
border: none;
|
|
2199
|
+
display: flex;
|
|
2200
|
+
align-items: center;
|
|
2201
|
+
justify-content: center;
|
|
2202
|
+
cursor: pointer;
|
|
2203
|
+
transition: all 0.2s ease-in;
|
|
2204
|
+
position: absolute;
|
|
2205
|
+
width: 24px;
|
|
2206
|
+
height: 24px;
|
|
2207
|
+
z-index: 2;
|
|
2208
|
+
padding: 0;
|
|
2209
|
+
left: 0;
|
|
2210
|
+
top: 0;
|
|
2211
|
+
}
|
|
2212
|
+
button#${elId}:hover {
|
|
2213
|
+
background-color: ${hoverColor} !important;
|
|
2214
|
+
}
|
|
2215
|
+
button#${elId} svg {
|
|
2216
|
+
fill: white;
|
|
2217
|
+
width: 16px;
|
|
2218
|
+
height: 16px;
|
|
2219
|
+
}
|
|
2220
|
+
.minimized > button#${elId} > * {
|
|
2221
|
+
transform: rotate(-180deg);
|
|
2222
|
+
}
|
|
2223
|
+
`;
|
|
2224
|
+
const clickHandler = () => {
|
|
2225
|
+
this.toggle();
|
|
2226
|
+
const minimized = this.container.classList.contains("minimized");
|
|
2227
|
+
const text = minimized ? this.options.showText || "Show minimap" : this.options.hideText || "Hide minimap";
|
|
2228
|
+
el.setAttribute("aria-label", text);
|
|
2229
|
+
el.setAttribute("title", text);
|
|
2230
|
+
};
|
|
2231
|
+
el.addEventListener("click", clickHandler);
|
|
2232
|
+
document.head.appendChild(styleEl);
|
|
2233
|
+
this.container.appendChild(el);
|
|
2234
|
+
this.toggleButtonCleanup = () => {
|
|
2235
|
+
el.removeEventListener("click", clickHandler);
|
|
2236
|
+
styleEl.remove();
|
|
2237
|
+
this.container.removeChild(el);
|
|
2238
|
+
};
|
|
2239
|
+
}
|
|
2240
|
+
setupResponsiveSizing() {
|
|
2241
|
+
if (!this.options.responsive) return;
|
|
2242
|
+
const updateSize = () => {
|
|
2243
|
+
if (this.isMinimized) return;
|
|
2244
|
+
const vw = window.innerWidth / 100;
|
|
2245
|
+
const vh = window.innerHeight / 100;
|
|
2246
|
+
const responsiveWidth = this.options.responsiveWidth || "20vw";
|
|
2247
|
+
const responsiveHeight = this.options.responsiveHeight || "20vh";
|
|
2248
|
+
let width;
|
|
2249
|
+
let height;
|
|
2250
|
+
if (responsiveWidth.endsWith("vw")) {
|
|
2251
|
+
width = parseFloat(responsiveWidth) * vw;
|
|
2252
|
+
} else if (responsiveWidth.endsWith("%")) {
|
|
2253
|
+
width = parseFloat(responsiveWidth) / 100 * window.innerWidth;
|
|
2254
|
+
} else {
|
|
2255
|
+
width = parseFloat(responsiveWidth);
|
|
2256
|
+
}
|
|
2257
|
+
if (responsiveHeight.endsWith("vh")) {
|
|
2258
|
+
height = parseFloat(responsiveHeight) * vh;
|
|
2259
|
+
} else if (responsiveHeight.endsWith("%")) {
|
|
2260
|
+
height = parseFloat(responsiveHeight) / 100 * window.innerHeight;
|
|
2261
|
+
} else {
|
|
2262
|
+
height = parseFloat(responsiveHeight);
|
|
2263
|
+
}
|
|
2264
|
+
const minW = parseFloat(this.options.minWidth || "200px");
|
|
2265
|
+
const minH = parseFloat(this.options.minHeight || "150px");
|
|
2266
|
+
const maxW = parseFloat(this.options.maxWidth || DEFAULT_WIDTH);
|
|
2267
|
+
const maxH = parseFloat(this.options.maxHeight || DEFAULT_HEIGHT);
|
|
2268
|
+
width = Math.max(minW, Math.min(maxW, width));
|
|
2269
|
+
height = Math.max(minH, Math.min(maxH, height));
|
|
2270
|
+
this.container.style.width = `${width}px`;
|
|
2271
|
+
this.container.style.height = `${height}px`;
|
|
2272
|
+
this.map.resize();
|
|
2273
|
+
this.setParentBounds();
|
|
2274
|
+
};
|
|
2275
|
+
updateSize();
|
|
2276
|
+
let resizeTimeout;
|
|
2277
|
+
this.resizeHandler = () => {
|
|
2278
|
+
clearTimeout(resizeTimeout);
|
|
2279
|
+
resizeTimeout = setTimeout(updateSize, RESIZE_DEBOUNCE_MS);
|
|
2280
|
+
};
|
|
2281
|
+
window.addEventListener("resize", this.resizeHandler);
|
|
2282
|
+
}
|
|
2283
|
+
toggle() {
|
|
2284
|
+
this.isMinimized = !this.isMinimized;
|
|
2285
|
+
const collapsedWidth = this.options.collapsedWidth || DEFAULT_COLLAPSED_SIZE;
|
|
2286
|
+
const collapsedHeight = this.options.collapsedHeight || DEFAULT_COLLAPSED_SIZE;
|
|
2287
|
+
if (this.isMinimized) {
|
|
2288
|
+
this.container.classList.add("minimized");
|
|
2289
|
+
this.container.style.width = collapsedWidth;
|
|
2290
|
+
this.container.style.height = collapsedHeight;
|
|
2291
|
+
} else {
|
|
2292
|
+
this.container.classList.remove("minimized");
|
|
2293
|
+
if (this.options.responsive && this.resizeHandler) {
|
|
2294
|
+
this.resizeHandler();
|
|
2295
|
+
} else {
|
|
2296
|
+
const expandedWidth = this.options.containerStyle?.width || DEFAULT_WIDTH;
|
|
2297
|
+
const expandedHeight = this.options.containerStyle?.height || DEFAULT_HEIGHT;
|
|
2298
|
+
this.container.style.width = expandedWidth;
|
|
2299
|
+
this.container.style.height = expandedHeight;
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
this.options.onToggle?.(this.isMinimized);
|
|
2303
|
+
setTimeout(() => {
|
|
2304
|
+
this.map.resize();
|
|
2305
|
+
this.setParentBounds();
|
|
2306
|
+
}, TRANSITION_DURATION_MS);
|
|
2307
|
+
}
|
|
2308
|
+
isMinimizedState() {
|
|
2309
|
+
return this.isMinimized;
|
|
2310
|
+
}
|
|
2311
|
+
addParentRect(rect) {
|
|
2312
|
+
if (rect === void 0 || rect.linePaint === void 0 && rect.fillPaint === void 0) {
|
|
2313
|
+
return;
|
|
2314
|
+
}
|
|
2315
|
+
this.parentRect = {
|
|
2316
|
+
type: "Feature",
|
|
2317
|
+
properties: { name: "parentRect" },
|
|
2318
|
+
geometry: {
|
|
2319
|
+
type: "Polygon",
|
|
2320
|
+
coordinates: [[[], [], [], [], []]]
|
|
2321
|
+
}
|
|
2322
|
+
};
|
|
2323
|
+
this.map.addSource("parentRect", {
|
|
2324
|
+
type: "geojson",
|
|
2325
|
+
data: this.parentRect
|
|
2326
|
+
});
|
|
2327
|
+
if (rect.lineLayout !== void 0 || rect.linePaint !== void 0) {
|
|
2328
|
+
this.map.addLayer({
|
|
2329
|
+
id: "parentRectOutline",
|
|
2330
|
+
type: "line",
|
|
2331
|
+
source: "parentRect",
|
|
2332
|
+
layout: { ...rect.lineLayout || {} },
|
|
2333
|
+
paint: {
|
|
2334
|
+
"line-color": "#FFF",
|
|
2335
|
+
"line-width": 1,
|
|
2336
|
+
"line-opacity": 0.85,
|
|
2337
|
+
...rect.linePaint || {}
|
|
2338
|
+
}
|
|
2339
|
+
});
|
|
2340
|
+
}
|
|
2341
|
+
if (rect.fillPaint !== void 0) {
|
|
2342
|
+
this.map.addLayer({
|
|
2343
|
+
id: "parentRectFill",
|
|
2344
|
+
type: "fill",
|
|
2345
|
+
source: "parentRect",
|
|
2346
|
+
layout: {},
|
|
2347
|
+
paint: {
|
|
2348
|
+
"fill-color": "#08F",
|
|
2349
|
+
"fill-opacity": 0.135,
|
|
2350
|
+
...rect.fillPaint || {}
|
|
2351
|
+
}
|
|
2352
|
+
});
|
|
2353
|
+
}
|
|
2354
|
+
this.setParentBounds();
|
|
2355
|
+
}
|
|
2356
|
+
setParentBounds() {
|
|
2357
|
+
if (this.parentRect === void 0 || this.isMinimized) return;
|
|
2358
|
+
const { devicePixelRatio } = window;
|
|
2359
|
+
const canvas = this.parentMap.getCanvas();
|
|
2360
|
+
const width = canvas.width / devicePixelRatio;
|
|
2361
|
+
const height = canvas.height / devicePixelRatio;
|
|
2362
|
+
const unproject = this.parentMap.unproject.bind(this.parentMap);
|
|
2363
|
+
const northWest = unproject([0, 0]);
|
|
2364
|
+
const northEast = unproject([width, 0]);
|
|
2365
|
+
const southWest = unproject([0, height]);
|
|
2366
|
+
const southEast = unproject([width, height]);
|
|
2367
|
+
this.parentRect.geometry.coordinates = [
|
|
2368
|
+
[
|
|
2369
|
+
southWest.toArray(),
|
|
2370
|
+
southEast.toArray(),
|
|
2371
|
+
northEast.toArray(),
|
|
2372
|
+
northWest.toArray(),
|
|
2373
|
+
southWest.toArray()
|
|
2374
|
+
]
|
|
2375
|
+
];
|
|
2376
|
+
const source = this.map.getSource("parentRect");
|
|
2377
|
+
if (source !== void 0) {
|
|
2378
|
+
source.setData(this.parentRect);
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
syncMaps() {
|
|
2382
|
+
const { pitchAdjust } = this.options;
|
|
2383
|
+
const parentCallback = () => {
|
|
2384
|
+
if (!this.isMinimized) {
|
|
2385
|
+
sync("parent");
|
|
2386
|
+
}
|
|
2387
|
+
};
|
|
2388
|
+
const minimapCallback = () => {
|
|
2389
|
+
if (!this.isMinimized) {
|
|
2390
|
+
sync("minimap");
|
|
2391
|
+
}
|
|
2392
|
+
};
|
|
2393
|
+
const on = () => {
|
|
2394
|
+
this.parentMap.on("move", parentCallback);
|
|
2395
|
+
this.map.on("move", minimapCallback);
|
|
2396
|
+
};
|
|
2397
|
+
const off = () => {
|
|
2398
|
+
this.parentMap.off("move", parentCallback);
|
|
2399
|
+
this.map.off("move", minimapCallback);
|
|
2400
|
+
};
|
|
2401
|
+
const sync = (which) => {
|
|
2402
|
+
off();
|
|
2403
|
+
const from = which === "parent" ? this.parentMap : this.map;
|
|
2404
|
+
const to = which === "parent" ? this.map : this.parentMap;
|
|
2405
|
+
const center = from.getCenter();
|
|
2406
|
+
const zoom = from.getZoom() + (this.options.zoomAdjust ?? DEFAULT_ZOOM_ADJUST) * (which === "parent" ? 1 : -1);
|
|
2407
|
+
const bearing = from.getBearing();
|
|
2408
|
+
const pitch = from.getPitch();
|
|
2409
|
+
to.jumpTo({
|
|
2410
|
+
center,
|
|
2411
|
+
zoom,
|
|
2412
|
+
bearing,
|
|
2413
|
+
pitch: pitchAdjust ? pitch : 0
|
|
2414
|
+
});
|
|
2415
|
+
this.setParentBounds();
|
|
2416
|
+
on();
|
|
2417
|
+
};
|
|
2418
|
+
on();
|
|
2419
|
+
return () => {
|
|
2420
|
+
off();
|
|
2421
|
+
};
|
|
2422
|
+
}
|
|
2423
|
+
};
|
|
2424
|
+
function _MinimapControl(props) {
|
|
2425
|
+
const { position, ...options } = props;
|
|
2426
|
+
useControl(() => new Minimap(options), { position });
|
|
2427
|
+
return null;
|
|
2428
|
+
}
|
|
2429
|
+
var MinimapControl = (0, import_react19.memo)(_MinimapControl);
|
|
1428
2430
|
|
|
1429
2431
|
// src/exports-maplibre-gl.ts
|
|
1430
2432
|
var exports_maplibre_gl_default = Map;
|
|
1431
2433
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1432
2434
|
0 && (module.exports = {
|
|
1433
2435
|
AttributionControl,
|
|
2436
|
+
CanvasSource,
|
|
2437
|
+
DrawControl,
|
|
1434
2438
|
FullscreenControl,
|
|
1435
2439
|
GeolocateControl,
|
|
2440
|
+
GlobeControl,
|
|
1436
2441
|
Layer,
|
|
1437
2442
|
LogoControl,
|
|
1438
2443
|
Map,
|
|
1439
2444
|
MapProvider,
|
|
1440
2445
|
Marker,
|
|
2446
|
+
Minimap,
|
|
2447
|
+
MinimapControl,
|
|
1441
2448
|
NavigationControl,
|
|
1442
2449
|
Popup,
|
|
1443
2450
|
ScaleControl,
|