react-naver-maps-kit 1.1.1 → 1.3.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/dist/core/loader/loadNaverMapsScript.d.ts.map +1 -1
- package/dist/index.cjs +1743 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +23 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1695 -32
- package/dist/index.js.map +1 -1
- package/dist/naver-maps-extensions.d.ts +53 -0
- package/dist/overlays/circle/Circle.d.ts.map +1 -1
- package/dist/overlays/data/GeoJson.d.ts +43 -0
- package/dist/overlays/data/GeoJson.d.ts.map +1 -0
- package/dist/overlays/data/Gpx.d.ts +42 -0
- package/dist/overlays/data/Gpx.d.ts.map +1 -0
- package/dist/overlays/data/Kmz.d.ts +42 -0
- package/dist/overlays/data/Kmz.d.ts.map +1 -0
- package/dist/overlays/ellipse/Ellipse.d.ts.map +1 -1
- package/dist/overlays/ground-overlay/GroundOverlay.d.ts +1 -0
- package/dist/overlays/ground-overlay/GroundOverlay.d.ts.map +1 -1
- package/dist/overlays/infowindow/InfoWindow.d.ts.map +1 -1
- package/dist/overlays/marker/Marker.d.ts.map +1 -1
- package/dist/overlays/marker-clusterer/MarkerClusterer.d.ts.map +1 -1
- package/dist/overlays/polygon/Polygon.d.ts.map +1 -1
- package/dist/overlays/polyline/Polyline.d.ts.map +1 -1
- package/dist/overlays/rectangle/Rectangle.d.ts.map +1 -1
- package/dist/react/components/NaverMap.d.ts +1 -1
- package/dist/react/components/NaverMap.d.ts.map +1 -1
- package/dist/react/context/MapInstanceContext.d.ts +11 -0
- package/dist/react/context/MapInstanceContext.d.ts.map +1 -0
- package/dist/react/provider/NaverMapProvider.d.ts +6 -2
- package/dist/react/provider/NaverMapProvider.d.ts.map +1 -1
- package/dist/submodules/drawing/DrawingManager.d.ts +43 -0
- package/dist/submodules/drawing/DrawingManager.d.ts.map +1 -0
- package/dist/submodules/drawing/index.d.ts +3 -0
- package/dist/submodules/drawing/index.d.ts.map +1 -0
- package/dist/submodules/panorama/AroundControl.d.ts +21 -0
- package/dist/submodules/panorama/AroundControl.d.ts.map +1 -0
- package/dist/submodules/panorama/FlightSpot.d.ts +17 -0
- package/dist/submodules/panorama/FlightSpot.d.ts.map +1 -0
- package/dist/submodules/panorama/Panorama.d.ts +75 -0
- package/dist/submodules/panorama/Panorama.d.ts.map +1 -0
- package/dist/submodules/panorama/PanoramaContext.d.ts +10 -0
- package/dist/submodules/panorama/PanoramaContext.d.ts.map +1 -0
- package/dist/submodules/panorama/index.d.ts +9 -0
- package/dist/submodules/panorama/index.d.ts.map +1 -0
- package/dist/submodules/visualization/DotMap.d.ts +25 -0
- package/dist/submodules/visualization/DotMap.d.ts.map +1 -0
- package/dist/submodules/visualization/HeatMap.d.ts +23 -0
- package/dist/submodules/visualization/HeatMap.d.ts.map +1 -0
- package/dist/submodules/visualization/index.d.ts +5 -0
- package/dist/submodules/visualization/index.d.ts.map +1 -0
- package/package.json +17 -14
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, forwardRef, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
1
|
+
import React, { createContext, forwardRef, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
|
|
@@ -31,27 +31,36 @@ function getClientKey(options) {
|
|
|
31
31
|
};
|
|
32
32
|
throw new Error("loadNaverMapsScript requires ncpKeyId. For backward compatibility, ncpClientId, govClientId, or finClientId can be provided.");
|
|
33
33
|
}
|
|
34
|
-
function isNaverMapsReady() {
|
|
34
|
+
function isNaverMapsReady(submodules) {
|
|
35
35
|
if (typeof window === "undefined") return false;
|
|
36
|
-
const
|
|
37
|
-
|
|
36
|
+
const maps = window.naver?.maps;
|
|
37
|
+
if (!maps) return false;
|
|
38
|
+
if (submodules && submodules.length > 0) {
|
|
39
|
+
const submoduleMap = {
|
|
40
|
+
panorama: "Panorama",
|
|
41
|
+
geocoder: "Service",
|
|
42
|
+
drawing: "drawing",
|
|
43
|
+
visualization: "visualization"
|
|
44
|
+
};
|
|
45
|
+
for (const submodule of submodules) if (!maps[submoduleMap[submodule]]) return false;
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
38
48
|
}
|
|
39
49
|
function createScriptUrl(options) {
|
|
40
50
|
const clientKey = getClientKey(options);
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return `${NAVER_MAPS_SCRIPT_BASE_URL}?${params.toString()}`;
|
|
51
|
+
const queryParts = [`${clientKey.param}=${encodeURIComponent(clientKey.value)}`];
|
|
52
|
+
if (options.submodules && options.submodules.length > 0) queryParts.push(`submodules=${options.submodules.join(",")}`);
|
|
53
|
+
return `${NAVER_MAPS_SCRIPT_BASE_URL}?${queryParts.join("&")}`;
|
|
45
54
|
}
|
|
46
|
-
function waitForNaverMapsReady(timeoutMs) {
|
|
55
|
+
function waitForNaverMapsReady(timeoutMs, submodules) {
|
|
47
56
|
return new Promise((resolve, reject) => {
|
|
48
|
-
if (isNaverMapsReady()) {
|
|
57
|
+
if (isNaverMapsReady(submodules)) {
|
|
49
58
|
resolve();
|
|
50
59
|
return;
|
|
51
60
|
}
|
|
52
61
|
const startedAt = Date.now();
|
|
53
62
|
const intervalId = setInterval(() => {
|
|
54
|
-
if (isNaverMapsReady()) {
|
|
63
|
+
if (isNaverMapsReady(submodules)) {
|
|
55
64
|
clearInterval(intervalId);
|
|
56
65
|
resolve();
|
|
57
66
|
return;
|
|
@@ -76,7 +85,7 @@ function attachAuthFailureHandler(reject) {
|
|
|
76
85
|
}
|
|
77
86
|
function loadNaverMapsScript(options) {
|
|
78
87
|
if (typeof window === "undefined" || typeof document === "undefined") return Promise.reject(/* @__PURE__ */ new Error("loadNaverMapsScript can only run in a browser environment."));
|
|
79
|
-
if (isNaverMapsReady()) return Promise.resolve();
|
|
88
|
+
if (isNaverMapsReady(options.submodules)) return Promise.resolve();
|
|
80
89
|
const scriptUrl = createScriptUrl(options);
|
|
81
90
|
if (inFlightLoad && inFlightScriptUrl === scriptUrl) return inFlightLoad;
|
|
82
91
|
const existingScript = document.querySelector(`script[src="${scriptUrl}"]`);
|
|
@@ -94,7 +103,7 @@ function loadNaverMapsScript(options) {
|
|
|
94
103
|
restoreAuthFailure();
|
|
95
104
|
};
|
|
96
105
|
const handleReady = () => {
|
|
97
|
-
waitForNaverMapsReady(timeoutMs).then(() => {
|
|
106
|
+
waitForNaverMapsReady(timeoutMs, options.submodules).then(() => {
|
|
98
107
|
cleanup();
|
|
99
108
|
resolve();
|
|
100
109
|
}).catch((error) => {
|
|
@@ -144,7 +153,7 @@ function loadNaverMapsScript(options) {
|
|
|
144
153
|
};
|
|
145
154
|
const onLoad = () => {
|
|
146
155
|
script.dataset.reactNaverMapsKitLoaded = "true";
|
|
147
|
-
waitForNaverMapsReady(timeoutMs).then(() => {
|
|
156
|
+
waitForNaverMapsReady(timeoutMs, options.submodules).then(() => {
|
|
148
157
|
cleanup();
|
|
149
158
|
resolve();
|
|
150
159
|
}).catch((error) => {
|
|
@@ -267,13 +276,15 @@ function NaverMapProvider({ children, autoLoad = true, onReady, onError, ncpKeyI
|
|
|
267
276
|
setMap,
|
|
268
277
|
reloadSdk,
|
|
269
278
|
retrySdk: reloadSdk,
|
|
270
|
-
clearSdkError
|
|
279
|
+
clearSdkError,
|
|
280
|
+
submodules: submodules ?? []
|
|
271
281
|
}), [
|
|
272
282
|
clearSdkError,
|
|
273
283
|
map,
|
|
274
284
|
reloadSdk,
|
|
275
285
|
sdkError,
|
|
276
|
-
sdkStatus
|
|
286
|
+
sdkStatus,
|
|
287
|
+
submodules
|
|
277
288
|
]);
|
|
278
289
|
return /* @__PURE__ */ jsx(NaverMapContext.Provider, {
|
|
279
290
|
value,
|
|
@@ -281,6 +292,28 @@ function NaverMapProvider({ children, autoLoad = true, onReady, onError, ncpKeyI
|
|
|
281
292
|
});
|
|
282
293
|
}
|
|
283
294
|
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/react/context/MapInstanceContext.tsx
|
|
297
|
+
const MapInstanceContext = createContext(null);
|
|
298
|
+
function useMapInstance() {
|
|
299
|
+
return useContext(MapInstanceContext);
|
|
300
|
+
}
|
|
301
|
+
function useMapInstanceRequired() {
|
|
302
|
+
const context = useContext(MapInstanceContext);
|
|
303
|
+
if (!context) throw new Error("This component must be used inside NaverMap or Panorama. Make sure it is a child of <NaverMap> or <Panorama>.");
|
|
304
|
+
return context;
|
|
305
|
+
}
|
|
306
|
+
function useMap() {
|
|
307
|
+
const context = useContext(MapInstanceContext);
|
|
308
|
+
if (!context || context.type !== "map") return null;
|
|
309
|
+
return context.instance;
|
|
310
|
+
}
|
|
311
|
+
function usePanoramaInstance() {
|
|
312
|
+
const context = useContext(MapInstanceContext);
|
|
313
|
+
if (!context || context.type !== "panorama") return null;
|
|
314
|
+
return context.instance;
|
|
315
|
+
}
|
|
316
|
+
|
|
284
317
|
//#endregion
|
|
285
318
|
//#region src/react/components/NaverMap.tsx
|
|
286
319
|
const MAP_OPTION_KEYS = [
|
|
@@ -645,6 +678,7 @@ const NaverMapBase = forwardRef(function NaverMapInner(props, ref) {
|
|
|
645
678
|
if (!context) throw new Error("NaverMap must be used inside NaverMapProvider.");
|
|
646
679
|
const { sdkStatus, setMap, reloadSdk } = context;
|
|
647
680
|
const [mapReady, setMapReady] = useState(false);
|
|
681
|
+
const [localMapInstance, setLocalMapInstance] = useState(null);
|
|
648
682
|
const propsRef = useRef(props);
|
|
649
683
|
useEffect(() => {
|
|
650
684
|
propsRef.current = props;
|
|
@@ -789,6 +823,7 @@ const NaverMapBase = forwardRef(function NaverMapInner(props, ref) {
|
|
|
789
823
|
mapRef.current = mapInstance;
|
|
790
824
|
appliedOptionsRef.current = initOptions;
|
|
791
825
|
setMap(mapInstance);
|
|
826
|
+
setLocalMapInstance(mapInstance);
|
|
792
827
|
setMapReady(true);
|
|
793
828
|
propsRef.current.onMapReady?.(mapInstance);
|
|
794
829
|
const listeners = MAP_EVENT_BINDINGS.map((binding) => naver.maps.Event.addListener(mapInstance, binding.eventName, (event) => {
|
|
@@ -810,6 +845,7 @@ const NaverMapBase = forwardRef(function NaverMapInner(props, ref) {
|
|
|
810
845
|
mapRef.current = null;
|
|
811
846
|
appliedOptionsRef.current = {};
|
|
812
847
|
setMap(null);
|
|
848
|
+
setLocalMapInstance(null);
|
|
813
849
|
setMapReady(false);
|
|
814
850
|
propsRef.current.onMapDestroy?.();
|
|
815
851
|
};
|
|
@@ -841,15 +877,23 @@ const NaverMapBase = forwardRef(function NaverMapInner(props, ref) {
|
|
|
841
877
|
isControlledCenter,
|
|
842
878
|
isControlledZoom
|
|
843
879
|
]);
|
|
880
|
+
const mapInstanceContextValue = useMemo(() => ({
|
|
881
|
+
instance: localMapInstance,
|
|
882
|
+
setInstance: setLocalMapInstance,
|
|
883
|
+
type: "map"
|
|
884
|
+
}), [localMapInstance]);
|
|
844
885
|
if (sdkStatus === "error") return /* @__PURE__ */ jsx(Fragment, { children: props.fallback ?? /* @__PURE__ */ jsx("div", {
|
|
845
886
|
...divProps,
|
|
846
887
|
children: "지도를 불러올 수 없습니다."
|
|
847
888
|
}) });
|
|
848
889
|
if (sdkStatus === "loading") return /* @__PURE__ */ jsx(Fragment, { children: props.fallback ?? /* @__PURE__ */ jsx("div", { ...divProps }) });
|
|
849
|
-
return /* @__PURE__ */ jsx(
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
890
|
+
return /* @__PURE__ */ jsx(MapInstanceContext.Provider, {
|
|
891
|
+
value: mapInstanceContextValue,
|
|
892
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
893
|
+
ref: containerRef,
|
|
894
|
+
...divProps,
|
|
895
|
+
children: mapReady ? props.children : null
|
|
896
|
+
})
|
|
853
897
|
});
|
|
854
898
|
});
|
|
855
899
|
NaverMapBase.displayName = "NaverMap";
|
|
@@ -1040,7 +1084,8 @@ function toLatLngLiteral(position) {
|
|
|
1040
1084
|
return null;
|
|
1041
1085
|
}
|
|
1042
1086
|
const Marker = forwardRef(function MarkerInner(props, ref) {
|
|
1043
|
-
const {
|
|
1087
|
+
const { sdkStatus } = useNaverMap();
|
|
1088
|
+
const contextMap = useMapInstance()?.instance;
|
|
1044
1089
|
const clustererRegistry = useContext(ClustererContext);
|
|
1045
1090
|
const visibleIds = useContext(ClustererVisibilityContext);
|
|
1046
1091
|
const isInsideClusterer = clustererRegistry !== null && clustererRegistry.enabled;
|
|
@@ -2260,7 +2305,8 @@ function padBounds(bounds, padding) {
|
|
|
2260
2305
|
*/
|
|
2261
2306
|
function MarkerClusterer(props) {
|
|
2262
2307
|
const { algorithm: algorithmProp, clusterIcon, onClusterClick, behavior, clusterData, enabled = true, children } = props;
|
|
2263
|
-
const {
|
|
2308
|
+
const { sdkStatus } = useNaverMap();
|
|
2309
|
+
const map = useMapInstance()?.instance;
|
|
2264
2310
|
const registryRef = useRef(/* @__PURE__ */ new Map());
|
|
2265
2311
|
const [registryVersion, setRegistryVersion] = useState(0);
|
|
2266
2312
|
const registry = useMemo(() => ({
|
|
@@ -2510,7 +2556,8 @@ function setInfoWindowOptionByKey(infoWindow, key, value) {
|
|
|
2510
2556
|
infoWindow.setOptions(key, value);
|
|
2511
2557
|
}
|
|
2512
2558
|
const InfoWindow = forwardRef(function InfoWindowInner(props, ref) {
|
|
2513
|
-
const {
|
|
2559
|
+
const { sdkStatus } = useNaverMap();
|
|
2560
|
+
const map = useMapInstance()?.instance;
|
|
2514
2561
|
const infoWindowRef = useRef(null);
|
|
2515
2562
|
const infoWindowEventListenersRef = useRef([]);
|
|
2516
2563
|
const onInfoWindowDestroyRef = useRef(props.onInfoWindowDestroy);
|
|
@@ -2784,7 +2831,8 @@ function buildCircleEventBindings(props) {
|
|
|
2784
2831
|
];
|
|
2785
2832
|
}
|
|
2786
2833
|
const Circle = forwardRef(function CircleInner(props, ref) {
|
|
2787
|
-
const {
|
|
2834
|
+
const { sdkStatus } = useNaverMap();
|
|
2835
|
+
const contextMap = useMapInstance()?.instance;
|
|
2788
2836
|
const circleRef = useRef(null);
|
|
2789
2837
|
const circleEventListenersRef = useRef([]);
|
|
2790
2838
|
const onCircleDestroyRef = useRef(props.onCircleDestroy);
|
|
@@ -2996,7 +3044,8 @@ function buildEllipseEventBindings(props) {
|
|
|
2996
3044
|
];
|
|
2997
3045
|
}
|
|
2998
3046
|
const Ellipse = forwardRef(function EllipseInner(props, ref) {
|
|
2999
|
-
const {
|
|
3047
|
+
const { sdkStatus } = useNaverMap();
|
|
3048
|
+
const contextMap = useMapInstance()?.instance;
|
|
3000
3049
|
const ellipseRef = useRef(null);
|
|
3001
3050
|
const ellipseEventListenersRef = useRef([]);
|
|
3002
3051
|
const onEllipseDestroyRef = useRef(props.onEllipseDestroy);
|
|
@@ -3160,7 +3209,8 @@ function buildGroundOverlayEventBindings(props) {
|
|
|
3160
3209
|
];
|
|
3161
3210
|
}
|
|
3162
3211
|
const GroundOverlay = forwardRef(function GroundOverlayInner(props, ref) {
|
|
3163
|
-
const {
|
|
3212
|
+
const { sdkStatus } = useNaverMap();
|
|
3213
|
+
const contextMap = useMapInstance()?.instance;
|
|
3164
3214
|
const groundOverlayRef = useRef(null);
|
|
3165
3215
|
const groundOverlayEventListenersRef = useRef([]);
|
|
3166
3216
|
const onGroundOverlayDestroyRef = useRef(props.onGroundOverlayDestroy);
|
|
@@ -3198,7 +3248,12 @@ const GroundOverlay = forwardRef(function GroundOverlayInner(props, ref) {
|
|
|
3198
3248
|
getProjection: (...args) => invokeGroundOverlayMethod("getProjection", ...args),
|
|
3199
3249
|
getUrl: (...args) => invokeGroundOverlayMethod("getUrl", ...args),
|
|
3200
3250
|
setMap: (...args) => invokeGroundOverlayMethod("setMap", ...args),
|
|
3201
|
-
setOpacity: (...args) => invokeGroundOverlayMethod("setOpacity", ...args)
|
|
3251
|
+
setOpacity: (...args) => invokeGroundOverlayMethod("setOpacity", ...args),
|
|
3252
|
+
setUrl: (url) => {
|
|
3253
|
+
const groundOverlay = groundOverlayRef.current;
|
|
3254
|
+
if (!groundOverlay) return void 0;
|
|
3255
|
+
groundOverlay.setUrl?.(url);
|
|
3256
|
+
}
|
|
3202
3257
|
}), [invokeGroundOverlayMethod]);
|
|
3203
3258
|
useEffect(() => {
|
|
3204
3259
|
if (sdkStatus !== "ready" || !targetMap || groundOverlayRef.current) return;
|
|
@@ -3364,7 +3419,8 @@ function buildPolygonEventBindings(props) {
|
|
|
3364
3419
|
];
|
|
3365
3420
|
}
|
|
3366
3421
|
const Polygon = forwardRef(function PolygonInner(props, ref) {
|
|
3367
|
-
const {
|
|
3422
|
+
const { sdkStatus } = useNaverMap();
|
|
3423
|
+
const contextMap = useMapInstance()?.instance;
|
|
3368
3424
|
const polygonRef = useRef(null);
|
|
3369
3425
|
const polygonEventListenersRef = useRef([]);
|
|
3370
3426
|
const onPolygonDestroyRef = useRef(props.onPolygonDestroy);
|
|
@@ -3586,7 +3642,8 @@ function buildPolylineEventBindings(props) {
|
|
|
3586
3642
|
];
|
|
3587
3643
|
}
|
|
3588
3644
|
const Polyline = forwardRef(function PolylineInner(props, ref) {
|
|
3589
|
-
const {
|
|
3645
|
+
const { sdkStatus } = useNaverMap();
|
|
3646
|
+
const contextMap = useMapInstance()?.instance;
|
|
3590
3647
|
const polylineRef = useRef(null);
|
|
3591
3648
|
const polylineEventListenersRef = useRef([]);
|
|
3592
3649
|
const onPolylineDestroyRef = useRef(props.onPolylineDestroy);
|
|
@@ -3796,7 +3853,8 @@ function buildRectangleEventBindings(props) {
|
|
|
3796
3853
|
];
|
|
3797
3854
|
}
|
|
3798
3855
|
const Rectangle = forwardRef(function RectangleInner(props, ref) {
|
|
3799
|
-
const {
|
|
3856
|
+
const { sdkStatus } = useNaverMap();
|
|
3857
|
+
const contextMap = useMapInstance()?.instance;
|
|
3800
3858
|
const rectangleRef = useRef(null);
|
|
3801
3859
|
const rectangleEventListenersRef = useRef([]);
|
|
3802
3860
|
const onRectangleDestroyRef = useRef(props.onRectangleDestroy);
|
|
@@ -3886,10 +3944,1615 @@ const Rectangle = forwardRef(function RectangleInner(props, ref) {
|
|
|
3886
3944
|
});
|
|
3887
3945
|
Rectangle.displayName = "Rectangle";
|
|
3888
3946
|
|
|
3947
|
+
//#endregion
|
|
3948
|
+
//#region src/overlays/data/GeoJson.tsx
|
|
3949
|
+
function buildGeoJsonEventBindings(props) {
|
|
3950
|
+
return [
|
|
3951
|
+
{
|
|
3952
|
+
eventName: "addfeature",
|
|
3953
|
+
invoke: props.onAddFeature ? (event) => props.onAddFeature?.(event) : void 0
|
|
3954
|
+
},
|
|
3955
|
+
{
|
|
3956
|
+
eventName: "removefeature",
|
|
3957
|
+
invoke: props.onRemoveFeature ? (event) => props.onRemoveFeature?.(event) : void 0
|
|
3958
|
+
},
|
|
3959
|
+
{
|
|
3960
|
+
eventName: "property_changed",
|
|
3961
|
+
invoke: props.onPropertyChanged ? (event) => props.onPropertyChanged?.(event) : void 0
|
|
3962
|
+
},
|
|
3963
|
+
{
|
|
3964
|
+
eventName: "click",
|
|
3965
|
+
invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
|
|
3966
|
+
},
|
|
3967
|
+
{
|
|
3968
|
+
eventName: "dblclick",
|
|
3969
|
+
invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
|
|
3970
|
+
},
|
|
3971
|
+
{
|
|
3972
|
+
eventName: "rightclick",
|
|
3973
|
+
invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
|
|
3974
|
+
},
|
|
3975
|
+
{
|
|
3976
|
+
eventName: "mousedown",
|
|
3977
|
+
invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
|
|
3978
|
+
},
|
|
3979
|
+
{
|
|
3980
|
+
eventName: "mouseup",
|
|
3981
|
+
invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
|
|
3982
|
+
},
|
|
3983
|
+
{
|
|
3984
|
+
eventName: "mouseover",
|
|
3985
|
+
invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
|
|
3986
|
+
},
|
|
3987
|
+
{
|
|
3988
|
+
eventName: "mouseout",
|
|
3989
|
+
invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
|
|
3990
|
+
}
|
|
3991
|
+
];
|
|
3992
|
+
}
|
|
3993
|
+
const GeoJson = forwardRef(function GeoJsonInner(props, ref) {
|
|
3994
|
+
const { sdkStatus } = useNaverMap();
|
|
3995
|
+
const contextMap = useMapInstance()?.instance;
|
|
3996
|
+
const dataRef = useRef(null);
|
|
3997
|
+
const dataEventListenersRef = useRef([]);
|
|
3998
|
+
const onDataDestroyRef = useRef(props.onDataDestroy);
|
|
3999
|
+
const prevDataRef = useRef(null);
|
|
4000
|
+
useEffect(() => {
|
|
4001
|
+
onDataDestroyRef.current = props.onDataDestroy;
|
|
4002
|
+
}, [props.onDataDestroy]);
|
|
4003
|
+
const invokeDataMethod = useCallback((methodName, ...args) => {
|
|
4004
|
+
const data = dataRef.current;
|
|
4005
|
+
if (!data) return;
|
|
4006
|
+
const method = data[methodName];
|
|
4007
|
+
if (typeof method !== "function") return;
|
|
4008
|
+
return method.apply(data, args);
|
|
4009
|
+
}, []);
|
|
4010
|
+
const teardownData = useCallback(() => {
|
|
4011
|
+
const data = dataRef.current;
|
|
4012
|
+
if (!data) return;
|
|
4013
|
+
try {
|
|
4014
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4015
|
+
dataEventListenersRef.current = [];
|
|
4016
|
+
naver.maps.Event.clearInstanceListeners(data);
|
|
4017
|
+
} catch (error) {
|
|
4018
|
+
console.error("[react-naver-maps-kit] failed to clear GeoJson data layer listeners", error);
|
|
4019
|
+
}
|
|
4020
|
+
data.setMap(null);
|
|
4021
|
+
dataRef.current = null;
|
|
4022
|
+
prevDataRef.current = null;
|
|
4023
|
+
onDataDestroyRef.current?.();
|
|
4024
|
+
}, []);
|
|
4025
|
+
useImperativeHandle(ref, () => ({
|
|
4026
|
+
getInstance: () => dataRef.current,
|
|
4027
|
+
getAllFeature: (...args) => invokeDataMethod("getAllFeature", ...args),
|
|
4028
|
+
getFeatureById: (...args) => invokeDataMethod("getFeatureById", ...args),
|
|
4029
|
+
getMap: (...args) => invokeDataMethod("getMap", ...args),
|
|
4030
|
+
getStyle: (...args) => invokeDataMethod("getStyle", ...args),
|
|
4031
|
+
overrideStyle: (...args) => invokeDataMethod("overrideStyle", ...args),
|
|
4032
|
+
removeFeature: (...args) => invokeDataMethod("removeFeature", ...args),
|
|
4033
|
+
revertStyle: (...args) => invokeDataMethod("revertStyle", ...args),
|
|
4034
|
+
setStyle: (...args) => invokeDataMethod("setStyle", ...args),
|
|
4035
|
+
toGeoJson: (...args) => invokeDataMethod("toGeoJson", ...args)
|
|
4036
|
+
}), [invokeDataMethod]);
|
|
4037
|
+
useEffect(() => {
|
|
4038
|
+
if (sdkStatus !== "ready" || !contextMap || dataRef.current) return;
|
|
4039
|
+
try {
|
|
4040
|
+
const data = new naver.maps.Data();
|
|
4041
|
+
data.setMap(contextMap);
|
|
4042
|
+
if (props.style) data.setStyle(props.style);
|
|
4043
|
+
const features = data.addGeoJson(props.data, props.autoStyle ?? true);
|
|
4044
|
+
prevDataRef.current = props.data;
|
|
4045
|
+
dataRef.current = data;
|
|
4046
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildGeoJsonEventBindings(props));
|
|
4047
|
+
props.onDataReady?.(data);
|
|
4048
|
+
props.onFeaturesAdded?.(features);
|
|
4049
|
+
} catch (error) {
|
|
4050
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Data instance for GeoJson.");
|
|
4051
|
+
props.onDataError?.(normalizedError);
|
|
4052
|
+
}
|
|
4053
|
+
}, [sdkStatus, contextMap]);
|
|
4054
|
+
useEffect(() => {
|
|
4055
|
+
const data = dataRef.current;
|
|
4056
|
+
if (!data || props.data === prevDataRef.current) return;
|
|
4057
|
+
try {
|
|
4058
|
+
if (prevDataRef.current) data.removeGeoJson(prevDataRef.current);
|
|
4059
|
+
const features = data.addGeoJson(props.data, props.autoStyle ?? true);
|
|
4060
|
+
prevDataRef.current = props.data;
|
|
4061
|
+
props.onFeaturesAdded?.(features);
|
|
4062
|
+
} catch (error) {
|
|
4063
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to update GeoJson data.");
|
|
4064
|
+
props.onDataError?.(normalizedError);
|
|
4065
|
+
}
|
|
4066
|
+
}, [props.data, props.autoStyle]);
|
|
4067
|
+
useEffect(() => {
|
|
4068
|
+
const data = dataRef.current;
|
|
4069
|
+
if (!data) return;
|
|
4070
|
+
if (props.style) data.setStyle(props.style);
|
|
4071
|
+
}, [props.style]);
|
|
4072
|
+
useEffect(() => {
|
|
4073
|
+
const data = dataRef.current;
|
|
4074
|
+
if (!data) return;
|
|
4075
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildGeoJsonEventBindings(props));
|
|
4076
|
+
return () => {
|
|
4077
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4078
|
+
dataEventListenersRef.current = [];
|
|
4079
|
+
};
|
|
4080
|
+
}, [props]);
|
|
4081
|
+
useEffect(() => {
|
|
4082
|
+
return () => {
|
|
4083
|
+
teardownData();
|
|
4084
|
+
};
|
|
4085
|
+
}, [teardownData]);
|
|
4086
|
+
return null;
|
|
4087
|
+
});
|
|
4088
|
+
GeoJson.displayName = "GeoJson";
|
|
4089
|
+
|
|
4090
|
+
//#endregion
|
|
4091
|
+
//#region src/overlays/data/Gpx.tsx
|
|
4092
|
+
function buildGpxEventBindings(props) {
|
|
4093
|
+
return [
|
|
4094
|
+
{
|
|
4095
|
+
eventName: "addfeature",
|
|
4096
|
+
invoke: props.onAddFeature ? (event) => props.onAddFeature?.(event) : void 0
|
|
4097
|
+
},
|
|
4098
|
+
{
|
|
4099
|
+
eventName: "removefeature",
|
|
4100
|
+
invoke: props.onRemoveFeature ? (event) => props.onRemoveFeature?.(event) : void 0
|
|
4101
|
+
},
|
|
4102
|
+
{
|
|
4103
|
+
eventName: "property_changed",
|
|
4104
|
+
invoke: props.onPropertyChanged ? (event) => props.onPropertyChanged?.(event) : void 0
|
|
4105
|
+
},
|
|
4106
|
+
{
|
|
4107
|
+
eventName: "click",
|
|
4108
|
+
invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
|
|
4109
|
+
},
|
|
4110
|
+
{
|
|
4111
|
+
eventName: "dblclick",
|
|
4112
|
+
invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
|
|
4113
|
+
},
|
|
4114
|
+
{
|
|
4115
|
+
eventName: "rightclick",
|
|
4116
|
+
invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
|
|
4117
|
+
},
|
|
4118
|
+
{
|
|
4119
|
+
eventName: "mousedown",
|
|
4120
|
+
invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
|
|
4121
|
+
},
|
|
4122
|
+
{
|
|
4123
|
+
eventName: "mouseup",
|
|
4124
|
+
invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
|
|
4125
|
+
},
|
|
4126
|
+
{
|
|
4127
|
+
eventName: "mouseover",
|
|
4128
|
+
invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
|
|
4129
|
+
},
|
|
4130
|
+
{
|
|
4131
|
+
eventName: "mouseout",
|
|
4132
|
+
invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
|
|
4133
|
+
}
|
|
4134
|
+
];
|
|
4135
|
+
}
|
|
4136
|
+
function parseXml(xmlString) {
|
|
4137
|
+
const doc = new DOMParser().parseFromString(xmlString, "application/xml");
|
|
4138
|
+
const parseError = doc.querySelector("parsererror");
|
|
4139
|
+
if (parseError) throw new Error(`XML parse error: ${parseError.textContent}`);
|
|
4140
|
+
return doc;
|
|
4141
|
+
}
|
|
4142
|
+
const Gpx = forwardRef(function GpxInner(props, ref) {
|
|
4143
|
+
const { sdkStatus } = useNaverMap();
|
|
4144
|
+
const contextMap = useMapInstance()?.instance;
|
|
4145
|
+
const dataRef = useRef(null);
|
|
4146
|
+
const dataEventListenersRef = useRef([]);
|
|
4147
|
+
const onDataDestroyRef = useRef(props.onDataDestroy);
|
|
4148
|
+
const prevUrlRef = useRef(null);
|
|
4149
|
+
const abortRef = useRef(null);
|
|
4150
|
+
useEffect(() => {
|
|
4151
|
+
onDataDestroyRef.current = props.onDataDestroy;
|
|
4152
|
+
}, [props.onDataDestroy]);
|
|
4153
|
+
const invokeDataMethod = useCallback((methodName, ...args) => {
|
|
4154
|
+
const data = dataRef.current;
|
|
4155
|
+
if (!data) return;
|
|
4156
|
+
const method = data[methodName];
|
|
4157
|
+
if (typeof method !== "function") return;
|
|
4158
|
+
return method.apply(data, args);
|
|
4159
|
+
}, []);
|
|
4160
|
+
const teardownData = useCallback(() => {
|
|
4161
|
+
abortRef.current?.abort();
|
|
4162
|
+
abortRef.current = null;
|
|
4163
|
+
const data = dataRef.current;
|
|
4164
|
+
if (!data) return;
|
|
4165
|
+
try {
|
|
4166
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4167
|
+
dataEventListenersRef.current = [];
|
|
4168
|
+
naver.maps.Event.clearInstanceListeners(data);
|
|
4169
|
+
} catch (error) {
|
|
4170
|
+
console.error("[react-naver-maps-kit] failed to clear GPX data layer listeners", error);
|
|
4171
|
+
}
|
|
4172
|
+
data.setMap(null);
|
|
4173
|
+
dataRef.current = null;
|
|
4174
|
+
prevUrlRef.current = null;
|
|
4175
|
+
onDataDestroyRef.current?.();
|
|
4176
|
+
}, []);
|
|
4177
|
+
useImperativeHandle(ref, () => ({
|
|
4178
|
+
getInstance: () => dataRef.current,
|
|
4179
|
+
getAllFeature: (...args) => invokeDataMethod("getAllFeature", ...args),
|
|
4180
|
+
getFeatureById: (...args) => invokeDataMethod("getFeatureById", ...args),
|
|
4181
|
+
getMap: (...args) => invokeDataMethod("getMap", ...args),
|
|
4182
|
+
getStyle: (...args) => invokeDataMethod("getStyle", ...args),
|
|
4183
|
+
overrideStyle: (...args) => invokeDataMethod("overrideStyle", ...args),
|
|
4184
|
+
removeFeature: (...args) => invokeDataMethod("removeFeature", ...args),
|
|
4185
|
+
revertStyle: (...args) => invokeDataMethod("revertStyle", ...args),
|
|
4186
|
+
setStyle: (...args) => invokeDataMethod("setStyle", ...args),
|
|
4187
|
+
toGeoJson: (...args) => invokeDataMethod("toGeoJson", ...args)
|
|
4188
|
+
}), [invokeDataMethod]);
|
|
4189
|
+
const loadAndAddGpx = useCallback(async (data, url, isInitial) => {
|
|
4190
|
+
const controller = new AbortController();
|
|
4191
|
+
abortRef.current = controller;
|
|
4192
|
+
try {
|
|
4193
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
4194
|
+
if (!response.ok) throw new Error(`Failed to fetch GPX: ${response.status} ${response.statusText}`);
|
|
4195
|
+
const xmlDoc = parseXml(await response.text());
|
|
4196
|
+
if (controller.signal.aborted) return;
|
|
4197
|
+
if (!isInitial) data.getAllFeature().forEach((feature) => data.removeFeature(feature));
|
|
4198
|
+
const features = data.addGpx(xmlDoc, props.autoStyle ?? true);
|
|
4199
|
+
prevUrlRef.current = url;
|
|
4200
|
+
props.onFeaturesAdded?.(features);
|
|
4201
|
+
} catch (error) {
|
|
4202
|
+
if (controller.signal.aborted) return;
|
|
4203
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to load GPX data.");
|
|
4204
|
+
props.onDataError?.(normalizedError);
|
|
4205
|
+
}
|
|
4206
|
+
}, [
|
|
4207
|
+
props.autoStyle,
|
|
4208
|
+
props.onFeaturesAdded,
|
|
4209
|
+
props.onDataError
|
|
4210
|
+
]);
|
|
4211
|
+
useEffect(() => {
|
|
4212
|
+
if (sdkStatus !== "ready" || !contextMap || dataRef.current) return;
|
|
4213
|
+
try {
|
|
4214
|
+
const data = new naver.maps.Data();
|
|
4215
|
+
data.setMap(contextMap);
|
|
4216
|
+
if (props.style) data.setStyle(props.style);
|
|
4217
|
+
dataRef.current = data;
|
|
4218
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildGpxEventBindings(props));
|
|
4219
|
+
props.onDataReady?.(data);
|
|
4220
|
+
loadAndAddGpx(data, props.url, true);
|
|
4221
|
+
} catch (error) {
|
|
4222
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Data instance.");
|
|
4223
|
+
props.onDataError?.(normalizedError);
|
|
4224
|
+
}
|
|
4225
|
+
}, [sdkStatus, contextMap]);
|
|
4226
|
+
useEffect(() => {
|
|
4227
|
+
const data = dataRef.current;
|
|
4228
|
+
if (!data || props.url === prevUrlRef.current) return;
|
|
4229
|
+
abortRef.current?.abort();
|
|
4230
|
+
loadAndAddGpx(data, props.url, false);
|
|
4231
|
+
}, [props.url, loadAndAddGpx]);
|
|
4232
|
+
useEffect(() => {
|
|
4233
|
+
const data = dataRef.current;
|
|
4234
|
+
if (!data) return;
|
|
4235
|
+
if (props.style) data.setStyle(props.style);
|
|
4236
|
+
}, [props.style]);
|
|
4237
|
+
useEffect(() => {
|
|
4238
|
+
const data = dataRef.current;
|
|
4239
|
+
if (!data) return;
|
|
4240
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildGpxEventBindings(props));
|
|
4241
|
+
return () => {
|
|
4242
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4243
|
+
dataEventListenersRef.current = [];
|
|
4244
|
+
};
|
|
4245
|
+
}, [props]);
|
|
4246
|
+
useEffect(() => {
|
|
4247
|
+
return () => {
|
|
4248
|
+
teardownData();
|
|
4249
|
+
};
|
|
4250
|
+
}, [teardownData]);
|
|
4251
|
+
return null;
|
|
4252
|
+
});
|
|
4253
|
+
Gpx.displayName = "Gpx";
|
|
4254
|
+
|
|
4255
|
+
//#endregion
|
|
4256
|
+
//#region ../../node_modules/.pnpm/fflate@0.8.2/node_modules/fflate/esm/browser.js
|
|
4257
|
+
var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;
|
|
4258
|
+
var fleb = new u8([
|
|
4259
|
+
0,
|
|
4260
|
+
0,
|
|
4261
|
+
0,
|
|
4262
|
+
0,
|
|
4263
|
+
0,
|
|
4264
|
+
0,
|
|
4265
|
+
0,
|
|
4266
|
+
0,
|
|
4267
|
+
1,
|
|
4268
|
+
1,
|
|
4269
|
+
1,
|
|
4270
|
+
1,
|
|
4271
|
+
2,
|
|
4272
|
+
2,
|
|
4273
|
+
2,
|
|
4274
|
+
2,
|
|
4275
|
+
3,
|
|
4276
|
+
3,
|
|
4277
|
+
3,
|
|
4278
|
+
3,
|
|
4279
|
+
4,
|
|
4280
|
+
4,
|
|
4281
|
+
4,
|
|
4282
|
+
4,
|
|
4283
|
+
5,
|
|
4284
|
+
5,
|
|
4285
|
+
5,
|
|
4286
|
+
5,
|
|
4287
|
+
0,
|
|
4288
|
+
0,
|
|
4289
|
+
0,
|
|
4290
|
+
0
|
|
4291
|
+
]);
|
|
4292
|
+
var fdeb = new u8([
|
|
4293
|
+
0,
|
|
4294
|
+
0,
|
|
4295
|
+
0,
|
|
4296
|
+
0,
|
|
4297
|
+
1,
|
|
4298
|
+
1,
|
|
4299
|
+
2,
|
|
4300
|
+
2,
|
|
4301
|
+
3,
|
|
4302
|
+
3,
|
|
4303
|
+
4,
|
|
4304
|
+
4,
|
|
4305
|
+
5,
|
|
4306
|
+
5,
|
|
4307
|
+
6,
|
|
4308
|
+
6,
|
|
4309
|
+
7,
|
|
4310
|
+
7,
|
|
4311
|
+
8,
|
|
4312
|
+
8,
|
|
4313
|
+
9,
|
|
4314
|
+
9,
|
|
4315
|
+
10,
|
|
4316
|
+
10,
|
|
4317
|
+
11,
|
|
4318
|
+
11,
|
|
4319
|
+
12,
|
|
4320
|
+
12,
|
|
4321
|
+
13,
|
|
4322
|
+
13,
|
|
4323
|
+
0,
|
|
4324
|
+
0
|
|
4325
|
+
]);
|
|
4326
|
+
var clim = new u8([
|
|
4327
|
+
16,
|
|
4328
|
+
17,
|
|
4329
|
+
18,
|
|
4330
|
+
0,
|
|
4331
|
+
8,
|
|
4332
|
+
7,
|
|
4333
|
+
9,
|
|
4334
|
+
6,
|
|
4335
|
+
10,
|
|
4336
|
+
5,
|
|
4337
|
+
11,
|
|
4338
|
+
4,
|
|
4339
|
+
12,
|
|
4340
|
+
3,
|
|
4341
|
+
13,
|
|
4342
|
+
2,
|
|
4343
|
+
14,
|
|
4344
|
+
1,
|
|
4345
|
+
15
|
|
4346
|
+
]);
|
|
4347
|
+
var freb = function(eb, start) {
|
|
4348
|
+
var b = new u16(31);
|
|
4349
|
+
for (var i = 0; i < 31; ++i) b[i] = start += 1 << eb[i - 1];
|
|
4350
|
+
var r = new i32(b[30]);
|
|
4351
|
+
for (var i = 1; i < 30; ++i) for (var j = b[i]; j < b[i + 1]; ++j) r[j] = j - b[i] << 5 | i;
|
|
4352
|
+
return {
|
|
4353
|
+
b,
|
|
4354
|
+
r
|
|
4355
|
+
};
|
|
4356
|
+
};
|
|
4357
|
+
var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;
|
|
4358
|
+
fl[28] = 258, revfl[258] = 28;
|
|
4359
|
+
var _b = freb(fdeb, 0), fd = _b.b, revfd = _b.r;
|
|
4360
|
+
var rev = new u16(32768);
|
|
4361
|
+
for (var i = 0; i < 32768; ++i) {
|
|
4362
|
+
var x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
4363
|
+
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
4364
|
+
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
4365
|
+
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
4366
|
+
}
|
|
4367
|
+
var hMap = (function(cd, mb, r) {
|
|
4368
|
+
var s = cd.length;
|
|
4369
|
+
var i = 0;
|
|
4370
|
+
var l = new u16(mb);
|
|
4371
|
+
for (; i < s; ++i) if (cd[i]) ++l[cd[i] - 1];
|
|
4372
|
+
var le = new u16(mb);
|
|
4373
|
+
for (i = 1; i < mb; ++i) le[i] = le[i - 1] + l[i - 1] << 1;
|
|
4374
|
+
var co;
|
|
4375
|
+
if (r) {
|
|
4376
|
+
co = new u16(1 << mb);
|
|
4377
|
+
var rvb = 15 - mb;
|
|
4378
|
+
for (i = 0; i < s; ++i) if (cd[i]) {
|
|
4379
|
+
var sv = i << 4 | cd[i];
|
|
4380
|
+
var r_1 = mb - cd[i];
|
|
4381
|
+
var v = le[cd[i] - 1]++ << r_1;
|
|
4382
|
+
for (var m = v | (1 << r_1) - 1; v <= m; ++v) co[rev[v] >> rvb] = sv;
|
|
4383
|
+
}
|
|
4384
|
+
} else {
|
|
4385
|
+
co = new u16(s);
|
|
4386
|
+
for (i = 0; i < s; ++i) if (cd[i]) co[i] = rev[le[cd[i] - 1]++] >> 15 - cd[i];
|
|
4387
|
+
}
|
|
4388
|
+
return co;
|
|
4389
|
+
});
|
|
4390
|
+
var flt = new u8(288);
|
|
4391
|
+
for (var i = 0; i < 144; ++i) flt[i] = 8;
|
|
4392
|
+
for (var i = 144; i < 256; ++i) flt[i] = 9;
|
|
4393
|
+
for (var i = 256; i < 280; ++i) flt[i] = 7;
|
|
4394
|
+
for (var i = 280; i < 288; ++i) flt[i] = 8;
|
|
4395
|
+
var fdt = new u8(32);
|
|
4396
|
+
for (var i = 0; i < 32; ++i) fdt[i] = 5;
|
|
4397
|
+
var flm = /* @__PURE__ */ hMap(flt, 9, 0), flrm = /* @__PURE__ */ hMap(flt, 9, 1);
|
|
4398
|
+
var fdm = /* @__PURE__ */ hMap(fdt, 5, 0), fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
|
|
4399
|
+
var max = function(a) {
|
|
4400
|
+
var m = a[0];
|
|
4401
|
+
for (var i = 1; i < a.length; ++i) if (a[i] > m) m = a[i];
|
|
4402
|
+
return m;
|
|
4403
|
+
};
|
|
4404
|
+
var bits = function(d, p, m) {
|
|
4405
|
+
var o = p / 8 | 0;
|
|
4406
|
+
return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
|
|
4407
|
+
};
|
|
4408
|
+
var bits16 = function(d, p) {
|
|
4409
|
+
var o = p / 8 | 0;
|
|
4410
|
+
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
4411
|
+
};
|
|
4412
|
+
var shft = function(p) {
|
|
4413
|
+
return (p + 7) / 8 | 0;
|
|
4414
|
+
};
|
|
4415
|
+
var slc = function(v, s, e) {
|
|
4416
|
+
if (s == null || s < 0) s = 0;
|
|
4417
|
+
if (e == null || e > v.length) e = v.length;
|
|
4418
|
+
return new u8(v.subarray(s, e));
|
|
4419
|
+
};
|
|
4420
|
+
var ec = [
|
|
4421
|
+
"unexpected EOF",
|
|
4422
|
+
"invalid block type",
|
|
4423
|
+
"invalid length/literal",
|
|
4424
|
+
"invalid distance",
|
|
4425
|
+
"stream finished",
|
|
4426
|
+
"no stream handler",
|
|
4427
|
+
,
|
|
4428
|
+
"no callback",
|
|
4429
|
+
"invalid UTF-8 data",
|
|
4430
|
+
"extra field too long",
|
|
4431
|
+
"date not in range 1980-2099",
|
|
4432
|
+
"filename too long",
|
|
4433
|
+
"stream finishing",
|
|
4434
|
+
"invalid zip data"
|
|
4435
|
+
];
|
|
4436
|
+
var err = function(ind, msg, nt) {
|
|
4437
|
+
var e = new Error(msg || ec[ind]);
|
|
4438
|
+
e.code = ind;
|
|
4439
|
+
if (Error.captureStackTrace) Error.captureStackTrace(e, err);
|
|
4440
|
+
if (!nt) throw e;
|
|
4441
|
+
return e;
|
|
4442
|
+
};
|
|
4443
|
+
var inflt = function(dat, st, buf, dict) {
|
|
4444
|
+
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
4445
|
+
if (!sl || st.f && !st.l) return buf || new u8(0);
|
|
4446
|
+
var noBuf = !buf;
|
|
4447
|
+
var resize = noBuf || st.i != 2;
|
|
4448
|
+
var noSt = st.i;
|
|
4449
|
+
if (noBuf) buf = new u8(sl * 3);
|
|
4450
|
+
var cbuf = function(l) {
|
|
4451
|
+
var bl = buf.length;
|
|
4452
|
+
if (l > bl) {
|
|
4453
|
+
var nbuf = new u8(Math.max(bl * 2, l));
|
|
4454
|
+
nbuf.set(buf);
|
|
4455
|
+
buf = nbuf;
|
|
4456
|
+
}
|
|
4457
|
+
};
|
|
4458
|
+
var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
|
|
4459
|
+
var tbts = sl * 8;
|
|
4460
|
+
do {
|
|
4461
|
+
if (!lm) {
|
|
4462
|
+
final = bits(dat, pos, 1);
|
|
4463
|
+
var type = bits(dat, pos + 1, 3);
|
|
4464
|
+
pos += 3;
|
|
4465
|
+
if (!type) {
|
|
4466
|
+
var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
|
|
4467
|
+
if (t > sl) {
|
|
4468
|
+
if (noSt) err(0);
|
|
4469
|
+
break;
|
|
4470
|
+
}
|
|
4471
|
+
if (resize) cbuf(bt + l);
|
|
4472
|
+
buf.set(dat.subarray(s, t), bt);
|
|
4473
|
+
st.b = bt += l, st.p = pos = t * 8, st.f = final;
|
|
4474
|
+
continue;
|
|
4475
|
+
} else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
4476
|
+
else if (type == 2) {
|
|
4477
|
+
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
4478
|
+
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
4479
|
+
pos += 14;
|
|
4480
|
+
var ldt = new u8(tl);
|
|
4481
|
+
var clt = new u8(19);
|
|
4482
|
+
for (var i = 0; i < hcLen; ++i) clt[clim[i]] = bits(dat, pos + i * 3, 7);
|
|
4483
|
+
pos += hcLen * 3;
|
|
4484
|
+
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
4485
|
+
var clm = hMap(clt, clb, 1);
|
|
4486
|
+
for (var i = 0; i < tl;) {
|
|
4487
|
+
var r = clm[bits(dat, pos, clbmsk)];
|
|
4488
|
+
pos += r & 15;
|
|
4489
|
+
var s = r >> 4;
|
|
4490
|
+
if (s < 16) ldt[i++] = s;
|
|
4491
|
+
else {
|
|
4492
|
+
var c = 0, n = 0;
|
|
4493
|
+
if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
|
|
4494
|
+
else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;
|
|
4495
|
+
else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7;
|
|
4496
|
+
while (n--) ldt[i++] = c;
|
|
4497
|
+
}
|
|
4498
|
+
}
|
|
4499
|
+
var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
4500
|
+
lbt = max(lt);
|
|
4501
|
+
dbt = max(dt);
|
|
4502
|
+
lm = hMap(lt, lbt, 1);
|
|
4503
|
+
dm = hMap(dt, dbt, 1);
|
|
4504
|
+
} else err(1);
|
|
4505
|
+
if (pos > tbts) {
|
|
4506
|
+
if (noSt) err(0);
|
|
4507
|
+
break;
|
|
4508
|
+
}
|
|
4509
|
+
}
|
|
4510
|
+
if (resize) cbuf(bt + 131072);
|
|
4511
|
+
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
4512
|
+
var lpos = pos;
|
|
4513
|
+
for (;; lpos = pos) {
|
|
4514
|
+
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
4515
|
+
pos += c & 15;
|
|
4516
|
+
if (pos > tbts) {
|
|
4517
|
+
if (noSt) err(0);
|
|
4518
|
+
break;
|
|
4519
|
+
}
|
|
4520
|
+
if (!c) err(2);
|
|
4521
|
+
if (sym < 256) buf[bt++] = sym;
|
|
4522
|
+
else if (sym == 256) {
|
|
4523
|
+
lpos = pos, lm = null;
|
|
4524
|
+
break;
|
|
4525
|
+
} else {
|
|
4526
|
+
var add = sym - 254;
|
|
4527
|
+
if (sym > 264) {
|
|
4528
|
+
var i = sym - 257, b = fleb[i];
|
|
4529
|
+
add = bits(dat, pos, (1 << b) - 1) + fl[i];
|
|
4530
|
+
pos += b;
|
|
4531
|
+
}
|
|
4532
|
+
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
4533
|
+
if (!d) err(3);
|
|
4534
|
+
pos += d & 15;
|
|
4535
|
+
var dt = fd[dsym];
|
|
4536
|
+
if (dsym > 3) {
|
|
4537
|
+
var b = fdeb[dsym];
|
|
4538
|
+
dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
|
|
4539
|
+
}
|
|
4540
|
+
if (pos > tbts) {
|
|
4541
|
+
if (noSt) err(0);
|
|
4542
|
+
break;
|
|
4543
|
+
}
|
|
4544
|
+
if (resize) cbuf(bt + 131072);
|
|
4545
|
+
var end = bt + add;
|
|
4546
|
+
if (bt < dt) {
|
|
4547
|
+
var shift = dl - dt, dend = Math.min(dt, end);
|
|
4548
|
+
if (shift + bt < 0) err(3);
|
|
4549
|
+
for (; bt < dend; ++bt) buf[bt] = dict[shift + bt];
|
|
4550
|
+
}
|
|
4551
|
+
for (; bt < end; ++bt) buf[bt] = buf[bt - dt];
|
|
4552
|
+
}
|
|
4553
|
+
}
|
|
4554
|
+
st.l = lm, st.p = lpos, st.b = bt, st.f = final;
|
|
4555
|
+
if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
|
4556
|
+
} while (!final);
|
|
4557
|
+
return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
|
|
4558
|
+
};
|
|
4559
|
+
var et = /* @__PURE__ */ new u8(0);
|
|
4560
|
+
var b2 = function(d, b) {
|
|
4561
|
+
return d[b] | d[b + 1] << 8;
|
|
4562
|
+
};
|
|
4563
|
+
var b4 = function(d, b) {
|
|
4564
|
+
return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;
|
|
4565
|
+
};
|
|
4566
|
+
var b8 = function(d, b) {
|
|
4567
|
+
return b4(d, b) + b4(d, b + 4) * 4294967296;
|
|
4568
|
+
};
|
|
4569
|
+
/**
|
|
4570
|
+
* Expands DEFLATE data with no wrapper
|
|
4571
|
+
* @param data The data to decompress
|
|
4572
|
+
* @param opts The decompression options
|
|
4573
|
+
* @returns The decompressed version of the data
|
|
4574
|
+
*/
|
|
4575
|
+
function inflateSync(data, opts) {
|
|
4576
|
+
return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);
|
|
4577
|
+
}
|
|
4578
|
+
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
4579
|
+
var tds = 0;
|
|
4580
|
+
try {
|
|
4581
|
+
td.decode(et, { stream: true });
|
|
4582
|
+
tds = 1;
|
|
4583
|
+
} catch (e) {}
|
|
4584
|
+
var dutf8 = function(d) {
|
|
4585
|
+
for (var r = "", i = 0;;) {
|
|
4586
|
+
var c = d[i++];
|
|
4587
|
+
var eb = (c > 127) + (c > 223) + (c > 239);
|
|
4588
|
+
if (i + eb > d.length) return {
|
|
4589
|
+
s: r,
|
|
4590
|
+
r: slc(d, i - 1)
|
|
4591
|
+
};
|
|
4592
|
+
if (!eb) r += String.fromCharCode(c);
|
|
4593
|
+
else if (eb == 3) c = ((c & 15) << 18 | (d[i++] & 63) << 12 | (d[i++] & 63) << 6 | d[i++] & 63) - 65536, r += String.fromCharCode(55296 | c >> 10, 56320 | c & 1023);
|
|
4594
|
+
else if (eb & 1) r += String.fromCharCode((c & 31) << 6 | d[i++] & 63);
|
|
4595
|
+
else r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | d[i++] & 63);
|
|
4596
|
+
}
|
|
4597
|
+
};
|
|
4598
|
+
/**
|
|
4599
|
+
* Converts a Uint8Array to a string
|
|
4600
|
+
* @param dat The data to decode to string
|
|
4601
|
+
* @param latin1 Whether or not to interpret the data as Latin-1. This should
|
|
4602
|
+
* not need to be true unless encoding to binary string.
|
|
4603
|
+
* @returns The original UTF-8/Latin-1 string
|
|
4604
|
+
*/
|
|
4605
|
+
function strFromU8(dat, latin1) {
|
|
4606
|
+
if (latin1) {
|
|
4607
|
+
var r = "";
|
|
4608
|
+
for (var i = 0; i < dat.length; i += 16384) r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));
|
|
4609
|
+
return r;
|
|
4610
|
+
} else if (td) return td.decode(dat);
|
|
4611
|
+
else {
|
|
4612
|
+
var _a = dutf8(dat), s = _a.s, r = _a.r;
|
|
4613
|
+
if (r.length) err(8);
|
|
4614
|
+
return s;
|
|
4615
|
+
}
|
|
4616
|
+
}
|
|
4617
|
+
var slzh = function(d, b) {
|
|
4618
|
+
return b + 30 + b2(d, b + 26) + b2(d, b + 28);
|
|
4619
|
+
};
|
|
4620
|
+
var zh = function(d, b, z) {
|
|
4621
|
+
var fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl, bs = b4(d, b + 20);
|
|
4622
|
+
var _a = z && bs == 4294967295 ? z64e(d, es) : [
|
|
4623
|
+
bs,
|
|
4624
|
+
b4(d, b + 24),
|
|
4625
|
+
b4(d, b + 42)
|
|
4626
|
+
], sc = _a[0], su = _a[1], off = _a[2];
|
|
4627
|
+
return [
|
|
4628
|
+
b2(d, b + 10),
|
|
4629
|
+
sc,
|
|
4630
|
+
su,
|
|
4631
|
+
fn,
|
|
4632
|
+
es + b2(d, b + 30) + b2(d, b + 32),
|
|
4633
|
+
off
|
|
4634
|
+
];
|
|
4635
|
+
};
|
|
4636
|
+
var z64e = function(d, b) {
|
|
4637
|
+
for (; b2(d, b) != 1; b += 4 + b2(d, b + 2));
|
|
4638
|
+
return [
|
|
4639
|
+
b8(d, b + 12),
|
|
4640
|
+
b8(d, b + 4),
|
|
4641
|
+
b8(d, b + 20)
|
|
4642
|
+
];
|
|
4643
|
+
};
|
|
4644
|
+
/**
|
|
4645
|
+
* Synchronously decompresses a ZIP archive. Prefer using `unzip` for better
|
|
4646
|
+
* performance with more than one file.
|
|
4647
|
+
* @param data The raw compressed ZIP file
|
|
4648
|
+
* @param opts The ZIP extraction options
|
|
4649
|
+
* @returns The decompressed files
|
|
4650
|
+
*/
|
|
4651
|
+
function unzipSync(data, opts) {
|
|
4652
|
+
var files = {};
|
|
4653
|
+
var e = data.length - 22;
|
|
4654
|
+
for (; b4(data, e) != 101010256; --e) if (!e || data.length - e > 65558) err(13);
|
|
4655
|
+
var c = b2(data, e + 8);
|
|
4656
|
+
if (!c) return {};
|
|
4657
|
+
var o = b4(data, e + 16);
|
|
4658
|
+
var z = o == 4294967295 || c == 65535;
|
|
4659
|
+
if (z) {
|
|
4660
|
+
var ze = b4(data, e - 12);
|
|
4661
|
+
z = b4(data, ze) == 101075792;
|
|
4662
|
+
if (z) {
|
|
4663
|
+
c = b4(data, ze + 32);
|
|
4664
|
+
o = b4(data, ze + 48);
|
|
4665
|
+
}
|
|
4666
|
+
}
|
|
4667
|
+
var fltr = opts && opts.filter;
|
|
4668
|
+
for (var i = 0; i < c; ++i) {
|
|
4669
|
+
var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);
|
|
4670
|
+
o = no;
|
|
4671
|
+
if (!fltr || fltr({
|
|
4672
|
+
name: fn,
|
|
4673
|
+
size: sc,
|
|
4674
|
+
originalSize: su,
|
|
4675
|
+
compression: c_2
|
|
4676
|
+
})) if (!c_2) files[fn] = slc(data, b, b + sc);
|
|
4677
|
+
else if (c_2 == 8) files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });
|
|
4678
|
+
else err(14, "unknown compression type " + c_2);
|
|
4679
|
+
}
|
|
4680
|
+
return files;
|
|
4681
|
+
}
|
|
4682
|
+
|
|
4683
|
+
//#endregion
|
|
4684
|
+
//#region src/overlays/data/Kmz.tsx
|
|
4685
|
+
function buildKmzEventBindings(props) {
|
|
4686
|
+
return [
|
|
4687
|
+
{
|
|
4688
|
+
eventName: "addfeature",
|
|
4689
|
+
invoke: props.onAddFeature ? (event) => props.onAddFeature?.(event) : void 0
|
|
4690
|
+
},
|
|
4691
|
+
{
|
|
4692
|
+
eventName: "removefeature",
|
|
4693
|
+
invoke: props.onRemoveFeature ? (event) => props.onRemoveFeature?.(event) : void 0
|
|
4694
|
+
},
|
|
4695
|
+
{
|
|
4696
|
+
eventName: "property_changed",
|
|
4697
|
+
invoke: props.onPropertyChanged ? (event) => props.onPropertyChanged?.(event) : void 0
|
|
4698
|
+
},
|
|
4699
|
+
{
|
|
4700
|
+
eventName: "click",
|
|
4701
|
+
invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
|
|
4702
|
+
},
|
|
4703
|
+
{
|
|
4704
|
+
eventName: "dblclick",
|
|
4705
|
+
invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
|
|
4706
|
+
},
|
|
4707
|
+
{
|
|
4708
|
+
eventName: "rightclick",
|
|
4709
|
+
invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
|
|
4710
|
+
},
|
|
4711
|
+
{
|
|
4712
|
+
eventName: "mousedown",
|
|
4713
|
+
invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
|
|
4714
|
+
},
|
|
4715
|
+
{
|
|
4716
|
+
eventName: "mouseup",
|
|
4717
|
+
invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
|
|
4718
|
+
},
|
|
4719
|
+
{
|
|
4720
|
+
eventName: "mouseover",
|
|
4721
|
+
invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
|
|
4722
|
+
},
|
|
4723
|
+
{
|
|
4724
|
+
eventName: "mouseout",
|
|
4725
|
+
invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
|
|
4726
|
+
}
|
|
4727
|
+
];
|
|
4728
|
+
}
|
|
4729
|
+
function extractKmlFromKmz(arrayBuffer) {
|
|
4730
|
+
const files = unzipSync(new Uint8Array(arrayBuffer));
|
|
4731
|
+
const kmlFileName = Object.keys(files).find((name) => name.endsWith(".kml") || name === "doc.kml");
|
|
4732
|
+
if (!kmlFileName) throw new Error("No KML file found in KMZ archive.");
|
|
4733
|
+
const kmlBytes = files[kmlFileName];
|
|
4734
|
+
const kmlString = new TextDecoder("utf-8").decode(kmlBytes);
|
|
4735
|
+
const doc = new DOMParser().parseFromString(kmlString, "application/xml");
|
|
4736
|
+
const parseError = doc.querySelector("parsererror");
|
|
4737
|
+
if (parseError) throw new Error(`KML parse error: ${parseError.textContent}`);
|
|
4738
|
+
return doc;
|
|
4739
|
+
}
|
|
4740
|
+
const Kmz = forwardRef(function KmzInner(props, ref) {
|
|
4741
|
+
const { sdkStatus } = useNaverMap();
|
|
4742
|
+
const contextMap = useMapInstance()?.instance;
|
|
4743
|
+
const dataRef = useRef(null);
|
|
4744
|
+
const dataEventListenersRef = useRef([]);
|
|
4745
|
+
const onDataDestroyRef = useRef(props.onDataDestroy);
|
|
4746
|
+
const prevUrlRef = useRef(null);
|
|
4747
|
+
const abortRef = useRef(null);
|
|
4748
|
+
useEffect(() => {
|
|
4749
|
+
onDataDestroyRef.current = props.onDataDestroy;
|
|
4750
|
+
}, [props.onDataDestroy]);
|
|
4751
|
+
const invokeDataMethod = useCallback((methodName, ...args) => {
|
|
4752
|
+
const data = dataRef.current;
|
|
4753
|
+
if (!data) return;
|
|
4754
|
+
const method = data[methodName];
|
|
4755
|
+
if (typeof method !== "function") return;
|
|
4756
|
+
return method.apply(data, args);
|
|
4757
|
+
}, []);
|
|
4758
|
+
const teardownData = useCallback(() => {
|
|
4759
|
+
abortRef.current?.abort();
|
|
4760
|
+
abortRef.current = null;
|
|
4761
|
+
const data = dataRef.current;
|
|
4762
|
+
if (!data) return;
|
|
4763
|
+
try {
|
|
4764
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4765
|
+
dataEventListenersRef.current = [];
|
|
4766
|
+
naver.maps.Event.clearInstanceListeners(data);
|
|
4767
|
+
} catch (error) {
|
|
4768
|
+
console.error("[react-naver-maps-kit] failed to clear KMZ data layer listeners", error);
|
|
4769
|
+
}
|
|
4770
|
+
data.setMap(null);
|
|
4771
|
+
dataRef.current = null;
|
|
4772
|
+
prevUrlRef.current = null;
|
|
4773
|
+
onDataDestroyRef.current?.();
|
|
4774
|
+
}, []);
|
|
4775
|
+
useImperativeHandle(ref, () => ({
|
|
4776
|
+
getInstance: () => dataRef.current,
|
|
4777
|
+
getAllFeature: (...args) => invokeDataMethod("getAllFeature", ...args),
|
|
4778
|
+
getFeatureById: (...args) => invokeDataMethod("getFeatureById", ...args),
|
|
4779
|
+
getMap: (...args) => invokeDataMethod("getMap", ...args),
|
|
4780
|
+
getStyle: (...args) => invokeDataMethod("getStyle", ...args),
|
|
4781
|
+
overrideStyle: (...args) => invokeDataMethod("overrideStyle", ...args),
|
|
4782
|
+
removeFeature: (...args) => invokeDataMethod("removeFeature", ...args),
|
|
4783
|
+
revertStyle: (...args) => invokeDataMethod("revertStyle", ...args),
|
|
4784
|
+
setStyle: (...args) => invokeDataMethod("setStyle", ...args),
|
|
4785
|
+
toGeoJson: (...args) => invokeDataMethod("toGeoJson", ...args)
|
|
4786
|
+
}), [invokeDataMethod]);
|
|
4787
|
+
const loadAndAddKmz = useCallback(async (data, url, isInitial) => {
|
|
4788
|
+
const controller = new AbortController();
|
|
4789
|
+
abortRef.current = controller;
|
|
4790
|
+
try {
|
|
4791
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
4792
|
+
if (!response.ok) throw new Error(`Failed to fetch KMZ: ${response.status} ${response.statusText}`);
|
|
4793
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
4794
|
+
if (controller.signal.aborted) return;
|
|
4795
|
+
const kmlDoc = extractKmlFromKmz(arrayBuffer);
|
|
4796
|
+
if (!isInitial) data.getAllFeature().forEach((feature) => data.removeFeature(feature));
|
|
4797
|
+
const features = data.addKml(kmlDoc, props.autoStyle ?? true);
|
|
4798
|
+
prevUrlRef.current = url;
|
|
4799
|
+
props.onFeaturesAdded?.(features);
|
|
4800
|
+
} catch (error) {
|
|
4801
|
+
if (controller.signal.aborted) return;
|
|
4802
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to load KMZ data.");
|
|
4803
|
+
props.onDataError?.(normalizedError);
|
|
4804
|
+
}
|
|
4805
|
+
}, [
|
|
4806
|
+
props.autoStyle,
|
|
4807
|
+
props.onFeaturesAdded,
|
|
4808
|
+
props.onDataError
|
|
4809
|
+
]);
|
|
4810
|
+
useEffect(() => {
|
|
4811
|
+
if (sdkStatus !== "ready" || !contextMap || dataRef.current) return;
|
|
4812
|
+
try {
|
|
4813
|
+
const data = new naver.maps.Data();
|
|
4814
|
+
data.setMap(contextMap);
|
|
4815
|
+
if (props.style) data.setStyle(props.style);
|
|
4816
|
+
dataRef.current = data;
|
|
4817
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildKmzEventBindings(props));
|
|
4818
|
+
props.onDataReady?.(data);
|
|
4819
|
+
loadAndAddKmz(data, props.url, true);
|
|
4820
|
+
} catch (error) {
|
|
4821
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Data instance.");
|
|
4822
|
+
props.onDataError?.(normalizedError);
|
|
4823
|
+
}
|
|
4824
|
+
}, [sdkStatus, contextMap]);
|
|
4825
|
+
useEffect(() => {
|
|
4826
|
+
const data = dataRef.current;
|
|
4827
|
+
if (!data || props.url === prevUrlRef.current) return;
|
|
4828
|
+
abortRef.current?.abort();
|
|
4829
|
+
loadAndAddKmz(data, props.url, false);
|
|
4830
|
+
}, [props.url, loadAndAddKmz]);
|
|
4831
|
+
useEffect(() => {
|
|
4832
|
+
const data = dataRef.current;
|
|
4833
|
+
if (!data) return;
|
|
4834
|
+
if (props.style) data.setStyle(props.style);
|
|
4835
|
+
}, [props.style]);
|
|
4836
|
+
useEffect(() => {
|
|
4837
|
+
const data = dataRef.current;
|
|
4838
|
+
if (!data) return;
|
|
4839
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildKmzEventBindings(props));
|
|
4840
|
+
return () => {
|
|
4841
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4842
|
+
dataEventListenersRef.current = [];
|
|
4843
|
+
};
|
|
4844
|
+
}, [props]);
|
|
4845
|
+
useEffect(() => {
|
|
4846
|
+
return () => {
|
|
4847
|
+
teardownData();
|
|
4848
|
+
};
|
|
4849
|
+
}, [teardownData]);
|
|
4850
|
+
return null;
|
|
4851
|
+
});
|
|
4852
|
+
Kmz.displayName = "Kmz";
|
|
4853
|
+
|
|
4854
|
+
//#endregion
|
|
4855
|
+
//#region src/submodules/panorama/PanoramaContext.ts
|
|
4856
|
+
const PanoramaContext = createContext(null);
|
|
4857
|
+
function usePanorama() {
|
|
4858
|
+
const value = useContext(PanoramaContext);
|
|
4859
|
+
if (!value) throw new Error("usePanorama must be used within a Panorama component. Make sure you wrap your panorama-dependent components with <Panorama>.");
|
|
4860
|
+
return value;
|
|
4861
|
+
}
|
|
4862
|
+
|
|
4863
|
+
//#endregion
|
|
4864
|
+
//#region src/submodules/panorama/Panorama.tsx
|
|
4865
|
+
function toLatLng(position) {
|
|
4866
|
+
if (!position) return position;
|
|
4867
|
+
const pos = position;
|
|
4868
|
+
if (typeof pos.lat === "number" && typeof pos.lng === "number") return new naver.maps.LatLng(pos.lat, pos.lng);
|
|
4869
|
+
return position;
|
|
4870
|
+
}
|
|
4871
|
+
function toPanoramaOptions(props, convertLatLng = false, excludeControlled = false) {
|
|
4872
|
+
const options = {};
|
|
4873
|
+
if (props.size !== void 0) options.size = props.size;
|
|
4874
|
+
if (props.panoId !== void 0) options.panoId = props.panoId;
|
|
4875
|
+
if (!excludeControlled && props.position !== void 0) options.position = convertLatLng ? toLatLng(props.position) : props.position;
|
|
4876
|
+
if (!excludeControlled && props.pov !== void 0) options.pov = props.pov;
|
|
4877
|
+
if (props.visible !== void 0) options.visible = props.visible;
|
|
4878
|
+
if (props.minScale !== void 0) options.minScale = props.minScale;
|
|
4879
|
+
if (props.maxScale !== void 0) options.maxScale = props.maxScale;
|
|
4880
|
+
if (props.minZoom !== void 0) options.minZoom = props.minZoom;
|
|
4881
|
+
if (props.maxZoom !== void 0) options.maxZoom = props.maxZoom;
|
|
4882
|
+
if (props.flightSpot !== void 0) options.flightSpot = props.flightSpot;
|
|
4883
|
+
if (props.logoControl !== void 0) options.logoControl = props.logoControl;
|
|
4884
|
+
if (props.logoControlOptions !== void 0) options.logoControlOptions = props.logoControlOptions;
|
|
4885
|
+
if (props.zoomControl !== void 0) options.zoomControl = props.zoomControl;
|
|
4886
|
+
if (props.zoomControlOptions !== void 0) options.zoomControlOptions = props.zoomControlOptions;
|
|
4887
|
+
if (props.aroundControl !== void 0) options.aroundControl = props.aroundControl;
|
|
4888
|
+
if (props.aroundControlOptions !== void 0) options.aroundControlOptions = props.aroundControlOptions;
|
|
4889
|
+
return options;
|
|
4890
|
+
}
|
|
4891
|
+
function buildPanoramaEventBindings(props) {
|
|
4892
|
+
return [
|
|
4893
|
+
{
|
|
4894
|
+
eventName: "init",
|
|
4895
|
+
invoke: props.onInit ? () => props.onInit?.() : void 0
|
|
4896
|
+
},
|
|
4897
|
+
{
|
|
4898
|
+
eventName: "pano_changed",
|
|
4899
|
+
invoke: props.onPanoChanged ? () => props.onPanoChanged?.() : void 0
|
|
4900
|
+
},
|
|
4901
|
+
{
|
|
4902
|
+
eventName: "pano_status",
|
|
4903
|
+
invoke: props.onPanoStatus ? (event) => props.onPanoStatus?.(event) : void 0
|
|
4904
|
+
},
|
|
4905
|
+
{
|
|
4906
|
+
eventName: "pov_changed",
|
|
4907
|
+
invoke: props.onPovChanged ? () => props.onPovChanged?.() : void 0
|
|
4908
|
+
}
|
|
4909
|
+
];
|
|
4910
|
+
}
|
|
4911
|
+
function bindPanoramaEventListeners(panorama, listenersRef, bindings) {
|
|
4912
|
+
if (listenersRef.current.length > 0) {
|
|
4913
|
+
naver.maps.Event.removeListener(listenersRef.current);
|
|
4914
|
+
listenersRef.current = [];
|
|
4915
|
+
}
|
|
4916
|
+
listenersRef.current = bindings.filter((binding) => typeof binding.invoke === "function").map((binding) => naver.maps.Event.addListener(panorama, binding.eventName, (event) => {
|
|
4917
|
+
binding.invoke?.(event);
|
|
4918
|
+
}));
|
|
4919
|
+
}
|
|
4920
|
+
const Panorama = forwardRef(function PanoramaInner(props, ref) {
|
|
4921
|
+
const naverMapContext = NaverMapContext;
|
|
4922
|
+
const context = React.useContext(naverMapContext);
|
|
4923
|
+
if (!context) throw new Error("Panorama must be used inside NaverMapProvider.");
|
|
4924
|
+
const { sdkStatus, submodules } = context;
|
|
4925
|
+
if (sdkStatus === "ready" && !submodules.includes("panorama")) throw new Error("Panorama component requires \"panorama\" submodule. Add submodules={[\"panorama\"]} to your NaverMapProvider.");
|
|
4926
|
+
const containerRef = useRef(null);
|
|
4927
|
+
const panoramaRef = useRef(null);
|
|
4928
|
+
const eventListenersRef = useRef([]);
|
|
4929
|
+
const onPanoramaDestroyRef = useRef(props.onPanoramaDestroy);
|
|
4930
|
+
const [panoramaInstance, setPanoramaInstance] = useState(null);
|
|
4931
|
+
const [panoramaReady, setPanoramaReady] = useState(false);
|
|
4932
|
+
const propsRef = useRef(props);
|
|
4933
|
+
useEffect(() => {
|
|
4934
|
+
propsRef.current = props;
|
|
4935
|
+
});
|
|
4936
|
+
useEffect(() => {
|
|
4937
|
+
onPanoramaDestroyRef.current = props.onPanoramaDestroy;
|
|
4938
|
+
}, [props.onPanoramaDestroy]);
|
|
4939
|
+
const initialPositionRef = useRef(props.position ?? props.defaultPosition);
|
|
4940
|
+
const initialPovRef = useRef(props.pov ?? props.defaultPov);
|
|
4941
|
+
const isControlledPosition = props.position !== void 0;
|
|
4942
|
+
const isControlledPov = props.pov !== void 0;
|
|
4943
|
+
const optionsSnapshot = useMemo(() => toPanoramaOptions(props, false, true), [
|
|
4944
|
+
props.size,
|
|
4945
|
+
props.panoId,
|
|
4946
|
+
props.visible,
|
|
4947
|
+
props.minScale,
|
|
4948
|
+
props.maxScale,
|
|
4949
|
+
props.minZoom,
|
|
4950
|
+
props.maxZoom,
|
|
4951
|
+
props.flightSpot,
|
|
4952
|
+
props.logoControl,
|
|
4953
|
+
props.logoControlOptions,
|
|
4954
|
+
props.zoomControl,
|
|
4955
|
+
props.zoomControlOptions,
|
|
4956
|
+
props.aroundControl,
|
|
4957
|
+
props.aroundControlOptions
|
|
4958
|
+
]);
|
|
4959
|
+
const invokePanoramaMethod = useCallback((methodName, ...args) => {
|
|
4960
|
+
const panorama = panoramaRef.current;
|
|
4961
|
+
if (!panorama) return void 0;
|
|
4962
|
+
const method = panorama[methodName];
|
|
4963
|
+
if (typeof method !== "function") return void 0;
|
|
4964
|
+
return method.apply(panorama, args);
|
|
4965
|
+
}, []);
|
|
4966
|
+
useImperativeHandle(ref, () => ({
|
|
4967
|
+
getInstance: () => panoramaRef.current,
|
|
4968
|
+
getElement: (...args) => invokePanoramaMethod("getElement", ...args),
|
|
4969
|
+
getLocation: (...args) => invokePanoramaMethod("getLocation", ...args),
|
|
4970
|
+
getMaxScale: (...args) => invokePanoramaMethod("getMaxScale", ...args),
|
|
4971
|
+
getMaxZoom: (...args) => invokePanoramaMethod("getMaxZoom", ...args),
|
|
4972
|
+
getMinScale: (...args) => invokePanoramaMethod("getMinScale", ...args),
|
|
4973
|
+
getMinZoom: (...args) => invokePanoramaMethod("getMinZoom", ...args),
|
|
4974
|
+
getOptions: (...args) => invokePanoramaMethod("getOptions", ...args),
|
|
4975
|
+
getPanoId: (...args) => invokePanoramaMethod("getPanoId", ...args),
|
|
4976
|
+
getPosition: (...args) => invokePanoramaMethod("getPosition", ...args),
|
|
4977
|
+
getPov: (...args) => invokePanoramaMethod("getPov", ...args),
|
|
4978
|
+
getProjection: (...args) => invokePanoramaMethod("getProjection", ...args),
|
|
4979
|
+
getScale: (...args) => invokePanoramaMethod("getScale", ...args),
|
|
4980
|
+
getSize: (...args) => invokePanoramaMethod("getSize", ...args),
|
|
4981
|
+
getVisible: (...args) => invokePanoramaMethod("getVisible", ...args),
|
|
4982
|
+
getZoom: (...args) => invokePanoramaMethod("getZoom", ...args),
|
|
4983
|
+
setOptions: (...args) => invokePanoramaMethod("setOptions", ...args),
|
|
4984
|
+
setPanoId: (...args) => invokePanoramaMethod("setPanoId", ...args),
|
|
4985
|
+
setPanoIdWithPov: (...args) => invokePanoramaMethod("setPanoIdWithPov", ...args),
|
|
4986
|
+
setPosition: (...args) => invokePanoramaMethod("setPosition", ...args),
|
|
4987
|
+
setPov: (...args) => invokePanoramaMethod("setPov", ...args),
|
|
4988
|
+
setScale: (...args) => invokePanoramaMethod("setScale", ...args),
|
|
4989
|
+
setSize: (...args) => invokePanoramaMethod("setSize", ...args),
|
|
4990
|
+
setVisible: (...args) => invokePanoramaMethod("setVisible", ...args),
|
|
4991
|
+
setZoom: (...args) => invokePanoramaMethod("setZoom", ...args),
|
|
4992
|
+
zoomIn: (...args) => invokePanoramaMethod("zoomIn", ...args),
|
|
4993
|
+
zoomOut: (...args) => invokePanoramaMethod("zoomOut", ...args)
|
|
4994
|
+
}), [invokePanoramaMethod]);
|
|
4995
|
+
useEffect(() => {
|
|
4996
|
+
if (sdkStatus !== "ready" || !containerRef.current || panoramaRef.current) return;
|
|
4997
|
+
const container = containerRef.current;
|
|
4998
|
+
try {
|
|
4999
|
+
const initOpts = toPanoramaOptions(propsRef.current, true, true);
|
|
5000
|
+
if (initialPositionRef.current !== void 0) initOpts.position = toLatLng(initialPositionRef.current);
|
|
5001
|
+
if (initialPovRef.current !== void 0) initOpts.pov = initialPovRef.current;
|
|
5002
|
+
const panorama = new naver.maps.Panorama(container, initOpts);
|
|
5003
|
+
panoramaRef.current = panorama;
|
|
5004
|
+
setPanoramaInstance(panorama);
|
|
5005
|
+
setPanoramaReady(true);
|
|
5006
|
+
bindPanoramaEventListeners(panorama, eventListenersRef, buildPanoramaEventBindings(propsRef.current));
|
|
5007
|
+
propsRef.current.onPanoramaReady?.(panorama);
|
|
5008
|
+
} catch (error) {
|
|
5009
|
+
console.error("[Panorama] Failed to create panorama:", error);
|
|
5010
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Panorama instance.");
|
|
5011
|
+
propsRef.current.onPanoramaError?.(normalizedError);
|
|
5012
|
+
}
|
|
5013
|
+
}, [sdkStatus]);
|
|
5014
|
+
useEffect(() => {
|
|
5015
|
+
return () => {
|
|
5016
|
+
const container = containerRef.current;
|
|
5017
|
+
try {
|
|
5018
|
+
if (eventListenersRef.current.length > 0) {
|
|
5019
|
+
naver.maps.Event.removeListener(eventListenersRef.current);
|
|
5020
|
+
eventListenersRef.current = [];
|
|
5021
|
+
}
|
|
5022
|
+
if (panoramaRef.current) naver.maps.Event.clearInstanceListeners(panoramaRef.current);
|
|
5023
|
+
} catch (error) {
|
|
5024
|
+
console.error("[react-naver-maps-kit] failed to clear panorama listeners", error);
|
|
5025
|
+
}
|
|
5026
|
+
if (container) container.innerHTML = "";
|
|
5027
|
+
panoramaRef.current = null;
|
|
5028
|
+
setPanoramaInstance(null);
|
|
5029
|
+
setPanoramaReady(false);
|
|
5030
|
+
onPanoramaDestroyRef.current?.();
|
|
5031
|
+
};
|
|
5032
|
+
}, []);
|
|
5033
|
+
useEffect(() => {
|
|
5034
|
+
const panorama = panoramaRef.current;
|
|
5035
|
+
if (!panorama) return;
|
|
5036
|
+
if (Object.keys(optionsSnapshot).length > 0) panorama.setOptions(optionsSnapshot);
|
|
5037
|
+
}, [optionsSnapshot]);
|
|
5038
|
+
useEffect(() => {
|
|
5039
|
+
const panorama = panoramaRef.current;
|
|
5040
|
+
if (!panorama || !isControlledPosition || props.position === void 0) return;
|
|
5041
|
+
panorama.setPosition(toLatLng(props.position));
|
|
5042
|
+
}, [isControlledPosition, props.position]);
|
|
5043
|
+
useEffect(() => {
|
|
5044
|
+
const panorama = panoramaRef.current;
|
|
5045
|
+
if (!panorama || !isControlledPov || props.pov === void 0) return;
|
|
5046
|
+
panorama.setPov(props.pov);
|
|
5047
|
+
}, [isControlledPov, props.pov]);
|
|
5048
|
+
const panoramaContextValue = useMemo(() => ({
|
|
5049
|
+
panorama: panoramaInstance,
|
|
5050
|
+
setPanorama: setPanoramaInstance,
|
|
5051
|
+
sdkStatus,
|
|
5052
|
+
submodules
|
|
5053
|
+
}), [
|
|
5054
|
+
panoramaInstance,
|
|
5055
|
+
sdkStatus,
|
|
5056
|
+
submodules
|
|
5057
|
+
]);
|
|
5058
|
+
const mapInstanceContextValue = useMemo(() => ({
|
|
5059
|
+
instance: panoramaInstance,
|
|
5060
|
+
setInstance: setPanoramaInstance,
|
|
5061
|
+
type: "panorama"
|
|
5062
|
+
}), [panoramaInstance]);
|
|
5063
|
+
const naverMapContextValue = useMemo(() => ({
|
|
5064
|
+
...context,
|
|
5065
|
+
map: panoramaInstance,
|
|
5066
|
+
setMap: setPanoramaInstance
|
|
5067
|
+
}), [context, panoramaInstance]);
|
|
5068
|
+
return /* @__PURE__ */ jsx(NaverMapContext.Provider, {
|
|
5069
|
+
value: naverMapContextValue,
|
|
5070
|
+
children: /* @__PURE__ */ jsx(MapInstanceContext.Provider, {
|
|
5071
|
+
value: mapInstanceContextValue,
|
|
5072
|
+
children: /* @__PURE__ */ jsx(PanoramaContext.Provider, {
|
|
5073
|
+
value: panoramaContextValue,
|
|
5074
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
5075
|
+
ref: containerRef,
|
|
5076
|
+
style: props.style,
|
|
5077
|
+
className: props.className,
|
|
5078
|
+
children: panoramaReady ? props.children : null
|
|
5079
|
+
})
|
|
5080
|
+
})
|
|
5081
|
+
})
|
|
5082
|
+
});
|
|
5083
|
+
});
|
|
5084
|
+
Panorama.displayName = "Panorama";
|
|
5085
|
+
|
|
5086
|
+
//#endregion
|
|
5087
|
+
//#region src/submodules/panorama/FlightSpot.tsx
|
|
5088
|
+
const FlightSpot = forwardRef(function FlightSpotInner(props, ref) {
|
|
5089
|
+
const { sdkStatus, submodules } = useNaverMap();
|
|
5090
|
+
const contextMap = useMapInstance()?.instance;
|
|
5091
|
+
let panoramaContext = null;
|
|
5092
|
+
try {
|
|
5093
|
+
panoramaContext = usePanorama();
|
|
5094
|
+
} catch {}
|
|
5095
|
+
const flightSpotRef = useRef(null);
|
|
5096
|
+
const eventListenersRef = useRef([]);
|
|
5097
|
+
const onFlightSpotDestroyRef = useRef(props.onFlightSpotDestroy);
|
|
5098
|
+
const targetMap = props.map ?? panoramaContext?.panorama ?? contextMap;
|
|
5099
|
+
const isInPanorama = panoramaContext !== null;
|
|
5100
|
+
const effectiveSubmodules = panoramaContext?.submodules ?? submodules;
|
|
5101
|
+
if (sdkStatus === "ready" && effectiveSubmodules && !effectiveSubmodules.includes("panorama")) throw new Error("FlightSpot component requires \"panorama\" submodule. Add submodules={[\"panorama\"]} to your NaverMapProvider.");
|
|
5102
|
+
const propsRef = useRef(props);
|
|
5103
|
+
useEffect(() => {
|
|
5104
|
+
propsRef.current = props;
|
|
5105
|
+
});
|
|
5106
|
+
useEffect(() => {
|
|
5107
|
+
onFlightSpotDestroyRef.current = props.onFlightSpotDestroy;
|
|
5108
|
+
}, [props.onFlightSpotDestroy]);
|
|
5109
|
+
const invokeFlightSpotMethod = useCallback((methodName, ...args) => {
|
|
5110
|
+
const flightSpot = flightSpotRef.current;
|
|
5111
|
+
if (!flightSpot) return void 0;
|
|
5112
|
+
const method = flightSpot[methodName];
|
|
5113
|
+
if (typeof method !== "function") return void 0;
|
|
5114
|
+
return method.apply(flightSpot, args);
|
|
5115
|
+
}, []);
|
|
5116
|
+
const teardownFlightSpot = useCallback(() => {
|
|
5117
|
+
const flightSpot = flightSpotRef.current;
|
|
5118
|
+
if (!flightSpot) return;
|
|
5119
|
+
try {
|
|
5120
|
+
if (eventListenersRef.current.length > 0) {
|
|
5121
|
+
naver.maps.Event.removeListener(eventListenersRef.current);
|
|
5122
|
+
eventListenersRef.current = [];
|
|
5123
|
+
}
|
|
5124
|
+
naver.maps.Event.clearInstanceListeners(flightSpot);
|
|
5125
|
+
} catch (error) {
|
|
5126
|
+
console.error("[react-naver-maps-kit] failed to clear flightSpot listeners", error);
|
|
5127
|
+
}
|
|
5128
|
+
flightSpot.setMap(null);
|
|
5129
|
+
flightSpotRef.current = null;
|
|
5130
|
+
onFlightSpotDestroyRef.current?.();
|
|
5131
|
+
}, []);
|
|
5132
|
+
useImperativeHandle(ref, () => ({
|
|
5133
|
+
getInstance: () => flightSpotRef.current,
|
|
5134
|
+
getMap: (...args) => invokeFlightSpotMethod("getMap", ...args),
|
|
5135
|
+
setMap: (...args) => invokeFlightSpotMethod("setMap", ...args)
|
|
5136
|
+
}), [invokeFlightSpotMethod]);
|
|
5137
|
+
useEffect(() => {
|
|
5138
|
+
if (sdkStatus !== "ready" || flightSpotRef.current) return;
|
|
5139
|
+
if (isInPanorama && !panoramaContext?.panorama) return;
|
|
5140
|
+
try {
|
|
5141
|
+
const flightSpot = new naver.maps.FlightSpot();
|
|
5142
|
+
flightSpotRef.current = flightSpot;
|
|
5143
|
+
if (propsRef.current.onPoiClicked) {
|
|
5144
|
+
const listener = naver.maps.Event.addListener(flightSpot, "poi_clicked", (panoId) => {
|
|
5145
|
+
propsRef.current.onPoiClicked?.(panoId);
|
|
5146
|
+
});
|
|
5147
|
+
eventListenersRef.current.push(listener);
|
|
5148
|
+
}
|
|
5149
|
+
if (propsRef.current.visible !== false && targetMap) flightSpot.setMap(targetMap);
|
|
5150
|
+
propsRef.current.onFlightSpotReady?.(flightSpot);
|
|
5151
|
+
} catch (error) {
|
|
5152
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.FlightSpot instance.");
|
|
5153
|
+
propsRef.current.onFlightSpotError?.(normalizedError);
|
|
5154
|
+
}
|
|
5155
|
+
}, [
|
|
5156
|
+
sdkStatus,
|
|
5157
|
+
isInPanorama,
|
|
5158
|
+
panoramaContext?.panorama,
|
|
5159
|
+
targetMap
|
|
5160
|
+
]);
|
|
5161
|
+
useEffect(() => {
|
|
5162
|
+
const flightSpot = flightSpotRef.current;
|
|
5163
|
+
if (!flightSpot) return;
|
|
5164
|
+
if (props.visible === false) flightSpot.setMap(null);
|
|
5165
|
+
else if (targetMap) flightSpot.setMap(targetMap);
|
|
5166
|
+
}, [props.visible, targetMap]);
|
|
5167
|
+
useEffect(() => {
|
|
5168
|
+
return () => {
|
|
5169
|
+
teardownFlightSpot();
|
|
5170
|
+
};
|
|
5171
|
+
}, [teardownFlightSpot]);
|
|
5172
|
+
return null;
|
|
5173
|
+
});
|
|
5174
|
+
FlightSpot.displayName = "FlightSpot";
|
|
5175
|
+
|
|
5176
|
+
//#endregion
|
|
5177
|
+
//#region src/submodules/panorama/AroundControl.tsx
|
|
5178
|
+
const AroundControl = forwardRef(function AroundControlInner(props, ref) {
|
|
5179
|
+
const { panorama, sdkStatus, submodules } = usePanorama();
|
|
5180
|
+
if (sdkStatus === "ready" && !submodules.includes("panorama")) throw new Error("AroundControl component requires \"panorama\" submodule. Add submodules={[\"panorama\"]} to your NaverMapProvider.");
|
|
5181
|
+
const aroundControlRef = useRef(null);
|
|
5182
|
+
const onAroundControlDestroyRef = useRef(props.onAroundControlDestroy);
|
|
5183
|
+
const propsRef = useRef(props);
|
|
5184
|
+
useEffect(() => {
|
|
5185
|
+
propsRef.current = props;
|
|
5186
|
+
});
|
|
5187
|
+
useEffect(() => {
|
|
5188
|
+
onAroundControlDestroyRef.current = props.onAroundControlDestroy;
|
|
5189
|
+
}, [props.onAroundControlDestroy]);
|
|
5190
|
+
const invokeAroundControlMethod = useCallback((methodName, ...args) => {
|
|
5191
|
+
const aroundControl = aroundControlRef.current;
|
|
5192
|
+
if (!aroundControl) return void 0;
|
|
5193
|
+
const method = aroundControl[methodName];
|
|
5194
|
+
if (typeof method !== "function") return void 0;
|
|
5195
|
+
return method.apply(aroundControl, args);
|
|
5196
|
+
}, []);
|
|
5197
|
+
const teardownAroundControl = useCallback(() => {
|
|
5198
|
+
const aroundControl = aroundControlRef.current;
|
|
5199
|
+
if (!aroundControl) return;
|
|
5200
|
+
try {
|
|
5201
|
+
naver.maps.Event.clearInstanceListeners(aroundControl);
|
|
5202
|
+
} catch (error) {
|
|
5203
|
+
console.error("[react-naver-maps-kit] failed to clear aroundControl listeners", error);
|
|
5204
|
+
}
|
|
5205
|
+
aroundControl.setMap(null);
|
|
5206
|
+
aroundControlRef.current = null;
|
|
5207
|
+
onAroundControlDestroyRef.current?.();
|
|
5208
|
+
}, []);
|
|
5209
|
+
useImperativeHandle(ref, () => ({
|
|
5210
|
+
getInstance: () => aroundControlRef.current,
|
|
5211
|
+
getElement: (...args) => invokeAroundControlMethod("getElement", ...args),
|
|
5212
|
+
getMap: (...args) => invokeAroundControlMethod("getMap", ...args),
|
|
5213
|
+
getOptions: (...args) => invokeAroundControlMethod("getOptions", ...args),
|
|
5214
|
+
html: (...args) => invokeAroundControlMethod("html", ...args),
|
|
5215
|
+
setMap: (...args) => invokeAroundControlMethod("setMap", ...args),
|
|
5216
|
+
setOptions: (...args) => invokeAroundControlMethod("setOptions", ...args),
|
|
5217
|
+
setPosition: (...args) => invokeAroundControlMethod("setPosition", ...args)
|
|
5218
|
+
}), [invokeAroundControlMethod]);
|
|
5219
|
+
useEffect(() => {
|
|
5220
|
+
if (sdkStatus !== "ready" || !panorama || aroundControlRef.current) return;
|
|
5221
|
+
try {
|
|
5222
|
+
const options = { position: propsRef.current.position ?? naver.maps.Position.TOP_RIGHT };
|
|
5223
|
+
const aroundControl = new naver.maps.AroundControl(options);
|
|
5224
|
+
aroundControlRef.current = aroundControl;
|
|
5225
|
+
if (propsRef.current.visible !== false) aroundControl.setMap(panorama);
|
|
5226
|
+
propsRef.current.onAroundControlReady?.(aroundControl);
|
|
5227
|
+
} catch (error) {
|
|
5228
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.AroundControl instance.");
|
|
5229
|
+
propsRef.current.onAroundControlError?.(normalizedError);
|
|
5230
|
+
}
|
|
5231
|
+
}, [sdkStatus, panorama]);
|
|
5232
|
+
useEffect(() => {
|
|
5233
|
+
const aroundControl = aroundControlRef.current;
|
|
5234
|
+
if (!aroundControl || !panorama) return;
|
|
5235
|
+
const ctrl = aroundControl;
|
|
5236
|
+
if (props.visible === false) ctrl.setMap(null);
|
|
5237
|
+
else {
|
|
5238
|
+
ctrl.setMap(panorama);
|
|
5239
|
+
if (props.position !== void 0) aroundControl.setPosition(props.position);
|
|
5240
|
+
}
|
|
5241
|
+
}, [
|
|
5242
|
+
props.visible,
|
|
5243
|
+
props.position,
|
|
5244
|
+
panorama
|
|
5245
|
+
]);
|
|
5246
|
+
useEffect(() => {
|
|
5247
|
+
return () => {
|
|
5248
|
+
teardownAroundControl();
|
|
5249
|
+
};
|
|
5250
|
+
}, [teardownAroundControl]);
|
|
5251
|
+
return null;
|
|
5252
|
+
});
|
|
5253
|
+
AroundControl.displayName = "AroundControl";
|
|
5254
|
+
|
|
5255
|
+
//#endregion
|
|
5256
|
+
//#region src/submodules/visualization/HeatMap.tsx
|
|
5257
|
+
const HeatMap = forwardRef(function HeatMap({ data, opacity, radius, colorMap, colorMapReverse, onHeatMapReady }, ref) {
|
|
5258
|
+
const map = useMap();
|
|
5259
|
+
const heatMapRef = useRef(null);
|
|
5260
|
+
const onHeatMapReadyRef = useRef(onHeatMapReady);
|
|
5261
|
+
onHeatMapReadyRef.current = onHeatMapReady;
|
|
5262
|
+
const normalizeData = useCallback((inputData) => {
|
|
5263
|
+
if (!inputData || inputData.length === 0) return [];
|
|
5264
|
+
const first = inputData[0];
|
|
5265
|
+
if (first instanceof naver.maps.LatLng) return inputData;
|
|
5266
|
+
if (first instanceof naver.maps.visualization.WeightedLocation) return inputData;
|
|
5267
|
+
if (Array.isArray(first)) return inputData;
|
|
5268
|
+
if (typeof first === "object" && "lat" in first && "lng" in first) {
|
|
5269
|
+
const items = inputData;
|
|
5270
|
+
if (items.some((item) => item.weight !== void 0)) return items.map((item) => new naver.maps.visualization.WeightedLocation(item.lat, item.lng, item.weight ?? 1));
|
|
5271
|
+
return items.map((item) => new naver.maps.LatLng(item.lat, item.lng));
|
|
5272
|
+
}
|
|
5273
|
+
return inputData;
|
|
5274
|
+
}, []);
|
|
5275
|
+
useImperativeHandle(ref, () => ({
|
|
5276
|
+
getInstance: () => heatMapRef.current,
|
|
5277
|
+
getMap: () => heatMapRef.current?.getMap() ?? null,
|
|
5278
|
+
setData: (newData) => {
|
|
5279
|
+
heatMapRef.current?.setData(newData);
|
|
5280
|
+
},
|
|
5281
|
+
addData: (newData) => {
|
|
5282
|
+
heatMapRef.current?.addData(newData);
|
|
5283
|
+
},
|
|
5284
|
+
redraw: () => {
|
|
5285
|
+
heatMapRef.current?.redraw();
|
|
5286
|
+
}
|
|
5287
|
+
}), []);
|
|
5288
|
+
useEffect(() => {
|
|
5289
|
+
if (!map) return;
|
|
5290
|
+
if (typeof naver.maps.visualization?.HeatMap !== "function") {
|
|
5291
|
+
console.warn("[HeatMap] visualization 서브모듈이 로드되지 않았습니다. NaverMapProvider에 submodules={['visualization']}을 추가하세요.");
|
|
5292
|
+
return;
|
|
5293
|
+
}
|
|
5294
|
+
let heatMap = null;
|
|
5295
|
+
let listener = null;
|
|
5296
|
+
const createHeatMap = () => {
|
|
5297
|
+
if (heatMapRef.current) return;
|
|
5298
|
+
const normalizedData = normalizeData(data);
|
|
5299
|
+
heatMap = new naver.maps.visualization.HeatMap({
|
|
5300
|
+
map,
|
|
5301
|
+
data: normalizedData,
|
|
5302
|
+
opacity: opacity ?? .6,
|
|
5303
|
+
radius: radius ?? 20,
|
|
5304
|
+
colorMap,
|
|
5305
|
+
colorMapReverse: colorMapReverse ?? false
|
|
5306
|
+
});
|
|
5307
|
+
heatMapRef.current = heatMap;
|
|
5308
|
+
onHeatMapReadyRef.current?.(heatMap);
|
|
5309
|
+
};
|
|
5310
|
+
if (map.isReady) createHeatMap();
|
|
5311
|
+
else listener = naver.maps.Event.addListener(map, "init", createHeatMap);
|
|
5312
|
+
return () => {
|
|
5313
|
+
if (listener) naver.maps.Event.removeListener(listener);
|
|
5314
|
+
if (heatMap) heatMap.setMap(null);
|
|
5315
|
+
heatMapRef.current = null;
|
|
5316
|
+
};
|
|
5317
|
+
}, [map]);
|
|
5318
|
+
useEffect(() => {
|
|
5319
|
+
if (!heatMapRef.current) return;
|
|
5320
|
+
const normalizedData = normalizeData(data);
|
|
5321
|
+
heatMapRef.current.setData(normalizedData);
|
|
5322
|
+
heatMapRef.current.redraw();
|
|
5323
|
+
}, [data, normalizeData]);
|
|
5324
|
+
useEffect(() => {
|
|
5325
|
+
if (!heatMapRef.current || opacity === void 0) return;
|
|
5326
|
+
heatMapRef.current.setOptions({ opacity });
|
|
5327
|
+
heatMapRef.current.redraw();
|
|
5328
|
+
}, [opacity]);
|
|
5329
|
+
useEffect(() => {
|
|
5330
|
+
if (!heatMapRef.current || radius === void 0) return;
|
|
5331
|
+
heatMapRef.current.setOptions({ radius });
|
|
5332
|
+
heatMapRef.current.redraw();
|
|
5333
|
+
}, [radius]);
|
|
5334
|
+
useEffect(() => {
|
|
5335
|
+
if (!heatMapRef.current || colorMap === void 0) return;
|
|
5336
|
+
heatMapRef.current.setOptions({
|
|
5337
|
+
colorMap,
|
|
5338
|
+
colorMapReverse: colorMapReverse ?? false
|
|
5339
|
+
});
|
|
5340
|
+
heatMapRef.current.redraw();
|
|
5341
|
+
}, [colorMap, colorMapReverse]);
|
|
5342
|
+
return null;
|
|
5343
|
+
});
|
|
5344
|
+
|
|
5345
|
+
//#endregion
|
|
5346
|
+
//#region src/submodules/visualization/DotMap.tsx
|
|
5347
|
+
const DotMap = forwardRef(function DotMap({ data, opacity, radius, strokeWeight, strokeColor, strokeLineCap, strokeLineJoin, fillColor, onDotMapReady }, ref) {
|
|
5348
|
+
const map = useMap();
|
|
5349
|
+
const dotMapRef = useRef(null);
|
|
5350
|
+
const onDotMapReadyRef = useRef(onDotMapReady);
|
|
5351
|
+
onDotMapReadyRef.current = onDotMapReady;
|
|
5352
|
+
const normalizeData = useCallback((inputData) => {
|
|
5353
|
+
if (!inputData || inputData.length === 0) return [];
|
|
5354
|
+
const first = inputData[0];
|
|
5355
|
+
if (first instanceof naver.maps.LatLng) return inputData;
|
|
5356
|
+
if (Array.isArray(first)) return inputData;
|
|
5357
|
+
if (typeof first === "object" && "lat" in first && "lng" in first) return inputData.map((item) => new naver.maps.LatLng(item.lat, item.lng));
|
|
5358
|
+
return inputData;
|
|
5359
|
+
}, []);
|
|
5360
|
+
useImperativeHandle(ref, () => ({
|
|
5361
|
+
getInstance: () => dotMapRef.current,
|
|
5362
|
+
getMap: () => dotMapRef.current?.getMap() ?? null,
|
|
5363
|
+
setData: (newData) => {
|
|
5364
|
+
dotMapRef.current?.setData(newData);
|
|
5365
|
+
},
|
|
5366
|
+
addData: (newData) => {
|
|
5367
|
+
dotMapRef.current?.addData(newData);
|
|
5368
|
+
},
|
|
5369
|
+
redraw: () => {
|
|
5370
|
+
dotMapRef.current?.redraw();
|
|
5371
|
+
}
|
|
5372
|
+
}), []);
|
|
5373
|
+
useEffect(() => {
|
|
5374
|
+
if (!map) return;
|
|
5375
|
+
if (typeof naver.maps.visualization?.DotMap !== "function") {
|
|
5376
|
+
console.warn("[DotMap] visualization 서브모듈이 로드되지 않았습니다. NaverMapProvider에 submodules={['visualization']}을 추가하세요.");
|
|
5377
|
+
return;
|
|
5378
|
+
}
|
|
5379
|
+
let dotMap = null;
|
|
5380
|
+
let listener = null;
|
|
5381
|
+
const createDotMap = () => {
|
|
5382
|
+
if (dotMapRef.current) return;
|
|
5383
|
+
const normalizedData = normalizeData(data);
|
|
5384
|
+
dotMap = new naver.maps.visualization.DotMap({
|
|
5385
|
+
map,
|
|
5386
|
+
data: normalizedData,
|
|
5387
|
+
opacity: opacity ?? .6,
|
|
5388
|
+
radius: radius ?? 5,
|
|
5389
|
+
strokeWeight: strokeWeight ?? 1,
|
|
5390
|
+
strokeColor: strokeColor ?? "#fff",
|
|
5391
|
+
strokeLineCap: strokeLineCap ?? "round",
|
|
5392
|
+
strokeLineJoin: strokeLineJoin ?? "round",
|
|
5393
|
+
fillColor: fillColor ?? "#ff0000"
|
|
5394
|
+
});
|
|
5395
|
+
dotMapRef.current = dotMap;
|
|
5396
|
+
onDotMapReadyRef.current?.(dotMap);
|
|
5397
|
+
};
|
|
5398
|
+
if (map.isReady) createDotMap();
|
|
5399
|
+
else listener = naver.maps.Event.addListener(map, "init", createDotMap);
|
|
5400
|
+
return () => {
|
|
5401
|
+
if (listener) naver.maps.Event.removeListener(listener);
|
|
5402
|
+
if (dotMap) dotMap.setMap(null);
|
|
5403
|
+
dotMapRef.current = null;
|
|
5404
|
+
};
|
|
5405
|
+
}, [map]);
|
|
5406
|
+
useEffect(() => {
|
|
5407
|
+
if (!dotMapRef.current) return;
|
|
5408
|
+
const normalizedData = normalizeData(data);
|
|
5409
|
+
dotMapRef.current.setData(normalizedData);
|
|
5410
|
+
dotMapRef.current.redraw();
|
|
5411
|
+
}, [data, normalizeData]);
|
|
5412
|
+
useEffect(() => {
|
|
5413
|
+
if (!dotMapRef.current || opacity === void 0) return;
|
|
5414
|
+
dotMapRef.current.setOptions({ opacity });
|
|
5415
|
+
dotMapRef.current.redraw();
|
|
5416
|
+
}, [opacity]);
|
|
5417
|
+
useEffect(() => {
|
|
5418
|
+
if (!dotMapRef.current || radius === void 0) return;
|
|
5419
|
+
dotMapRef.current.setOptions({ radius });
|
|
5420
|
+
dotMapRef.current.redraw();
|
|
5421
|
+
}, [radius]);
|
|
5422
|
+
useEffect(() => {
|
|
5423
|
+
if (!dotMapRef.current) return;
|
|
5424
|
+
dotMapRef.current.setOptions({
|
|
5425
|
+
strokeWeight,
|
|
5426
|
+
strokeColor,
|
|
5427
|
+
strokeLineCap,
|
|
5428
|
+
strokeLineJoin,
|
|
5429
|
+
fillColor
|
|
5430
|
+
});
|
|
5431
|
+
dotMapRef.current.redraw();
|
|
5432
|
+
}, [
|
|
5433
|
+
strokeWeight,
|
|
5434
|
+
strokeColor,
|
|
5435
|
+
strokeLineCap,
|
|
5436
|
+
strokeLineJoin,
|
|
5437
|
+
fillColor
|
|
5438
|
+
]);
|
|
5439
|
+
return null;
|
|
5440
|
+
});
|
|
5441
|
+
|
|
5442
|
+
//#endregion
|
|
5443
|
+
//#region src/submodules/drawing/DrawingManager.tsx
|
|
5444
|
+
const DrawingManager = forwardRef(function DrawingManager({ drawingControl, drawingControlOptions, drawingMode, controlPointOptions, rectangleOptions, ellipseOptions, polylineOptions, arrowlineOptions, polygonOptions, markerOptions, onDrawingAdded, onDrawingRemoved, onDrawingSelect, onDrawingStart, onDrawingCanceled, onDrawingManagerReady }, ref) {
|
|
5445
|
+
const map = useMap();
|
|
5446
|
+
const managerRef = useRef(null);
|
|
5447
|
+
const listenersRef = useRef([]);
|
|
5448
|
+
const onDrawingManagerReadyRef = useRef(onDrawingManagerReady);
|
|
5449
|
+
onDrawingManagerReadyRef.current = onDrawingManagerReady;
|
|
5450
|
+
const eventPropsRef = useRef({
|
|
5451
|
+
onDrawingAdded,
|
|
5452
|
+
onDrawingRemoved,
|
|
5453
|
+
onDrawingSelect,
|
|
5454
|
+
onDrawingStart,
|
|
5455
|
+
onDrawingCanceled
|
|
5456
|
+
});
|
|
5457
|
+
eventPropsRef.current = {
|
|
5458
|
+
onDrawingAdded,
|
|
5459
|
+
onDrawingRemoved,
|
|
5460
|
+
onDrawingSelect,
|
|
5461
|
+
onDrawingStart,
|
|
5462
|
+
onDrawingCanceled
|
|
5463
|
+
};
|
|
5464
|
+
useImperativeHandle(ref, () => ({
|
|
5465
|
+
getInstance: () => managerRef.current,
|
|
5466
|
+
getMap: () => managerRef.current?.getMap() ?? null,
|
|
5467
|
+
getDrawings: () => managerRef.current?.getDrawings() ?? {},
|
|
5468
|
+
getDrawing: (id) => managerRef.current?.getDrawing(id),
|
|
5469
|
+
addDrawing: (overlay, mode, id) => {
|
|
5470
|
+
managerRef.current?.addDrawing(overlay, mode, id);
|
|
5471
|
+
},
|
|
5472
|
+
removeDrawing: (overlayOrId) => {
|
|
5473
|
+
managerRef.current?.removeDrawing(overlayOrId);
|
|
5474
|
+
},
|
|
5475
|
+
toGeoJson: () => managerRef.current?.toGeoJson() ?? {},
|
|
5476
|
+
setDrawingMode: (mode) => {
|
|
5477
|
+
managerRef.current?.setOptions({ drawingMode: mode });
|
|
5478
|
+
},
|
|
5479
|
+
getDrawingMode: () => {
|
|
5480
|
+
return managerRef.current?.getOptions("drawingMode");
|
|
5481
|
+
}
|
|
5482
|
+
}), []);
|
|
5483
|
+
useEffect(() => {
|
|
5484
|
+
if (!map) return;
|
|
5485
|
+
if (typeof naver.maps.drawing?.DrawingManager !== "function") {
|
|
5486
|
+
console.warn("[DrawingManager] drawing 서브모듈이 로드되지 않았습니다. NaverMapProvider에 submodules={['drawing']}을 추가하세요.");
|
|
5487
|
+
return;
|
|
5488
|
+
}
|
|
5489
|
+
let manager = null;
|
|
5490
|
+
const createManager = () => {
|
|
5491
|
+
if (managerRef.current) return;
|
|
5492
|
+
const options = { map };
|
|
5493
|
+
if (drawingControl !== void 0) options.drawingControl = drawingControl;
|
|
5494
|
+
if (drawingControlOptions) options.drawingControlOptions = drawingControlOptions;
|
|
5495
|
+
if (drawingMode) options.drawingMode = drawingMode;
|
|
5496
|
+
if (controlPointOptions) options.controlPointOptions = controlPointOptions;
|
|
5497
|
+
if (rectangleOptions) options.rectangleOptions = rectangleOptions;
|
|
5498
|
+
if (ellipseOptions) options.ellipseOptions = ellipseOptions;
|
|
5499
|
+
if (polylineOptions) options.polylineOptions = polylineOptions;
|
|
5500
|
+
if (arrowlineOptions) options.arrowlineOptions = arrowlineOptions;
|
|
5501
|
+
if (polygonOptions) options.polygonOptions = polygonOptions;
|
|
5502
|
+
if (markerOptions) options.markerOptions = markerOptions;
|
|
5503
|
+
manager = new naver.maps.drawing.DrawingManager(options);
|
|
5504
|
+
managerRef.current = manager;
|
|
5505
|
+
const listeners = [];
|
|
5506
|
+
const addedListener = manager.addListener(naver.maps.drawing.DrawingEvents.ADD, (overlay) => {
|
|
5507
|
+
eventPropsRef.current.onDrawingAdded?.(overlay);
|
|
5508
|
+
});
|
|
5509
|
+
listeners.push(addedListener);
|
|
5510
|
+
const removedListener = manager.addListener(naver.maps.drawing.DrawingEvents.REMOVE, (overlay) => {
|
|
5511
|
+
eventPropsRef.current.onDrawingRemoved?.(overlay);
|
|
5512
|
+
});
|
|
5513
|
+
listeners.push(removedListener);
|
|
5514
|
+
const selectListener = manager.addListener(naver.maps.drawing.DrawingEvents.SELECT, (overlay) => {
|
|
5515
|
+
eventPropsRef.current.onDrawingSelect?.(overlay);
|
|
5516
|
+
});
|
|
5517
|
+
listeners.push(selectListener);
|
|
5518
|
+
const startListener = manager.addListener(naver.maps.drawing.DrawingEvents.START, (overlay) => {
|
|
5519
|
+
eventPropsRef.current.onDrawingStart?.(overlay);
|
|
5520
|
+
});
|
|
5521
|
+
listeners.push(startListener);
|
|
5522
|
+
const canceledListener = manager.addListener(naver.maps.drawing.DrawingEvents.CANCLE, (overlay) => {
|
|
5523
|
+
eventPropsRef.current.onDrawingCanceled?.(overlay);
|
|
5524
|
+
});
|
|
5525
|
+
listeners.push(canceledListener);
|
|
5526
|
+
listenersRef.current = listeners;
|
|
5527
|
+
onDrawingManagerReadyRef.current?.(manager);
|
|
5528
|
+
};
|
|
5529
|
+
if (map.isReady) createManager();
|
|
5530
|
+
else {
|
|
5531
|
+
const listener = naver.maps.Event.addListener(map, "init", createManager);
|
|
5532
|
+
return () => {
|
|
5533
|
+
naver.maps.Event.removeListener(listener);
|
|
5534
|
+
listenersRef.current.forEach((l) => naver.maps.Event.removeListener(l));
|
|
5535
|
+
if (manager) manager.destroy();
|
|
5536
|
+
managerRef.current = null;
|
|
5537
|
+
};
|
|
5538
|
+
}
|
|
5539
|
+
return () => {
|
|
5540
|
+
listenersRef.current.forEach((l) => naver.maps.Event.removeListener(l));
|
|
5541
|
+
if (manager) manager.destroy();
|
|
5542
|
+
managerRef.current = null;
|
|
5543
|
+
};
|
|
5544
|
+
}, [map]);
|
|
5545
|
+
useEffect(() => {
|
|
5546
|
+
if (!managerRef.current || drawingMode === void 0) return;
|
|
5547
|
+
managerRef.current.setOptions({ drawingMode });
|
|
5548
|
+
}, [drawingMode]);
|
|
5549
|
+
return null;
|
|
5550
|
+
});
|
|
5551
|
+
|
|
3889
5552
|
//#endregion
|
|
3890
5553
|
//#region src/index.ts
|
|
3891
|
-
const version = "
|
|
5554
|
+
const version = "1.3.0";
|
|
3892
5555
|
|
|
3893
5556
|
//#endregion
|
|
3894
|
-
export { Circle, ClustererContext, Ellipse, GroundOverlay, InfoWindow, Marker, MarkerClusterer, NaverMap, NaverMapContext, NaverMapProvider, Polygon, Polyline, Rectangle, loadNaverMapsScript, useNaverMap, useNaverMapInstance, version };
|
|
5557
|
+
export { AroundControl, Circle, ClustererContext, DotMap, DrawingManager, Ellipse, FlightSpot, GeoJson, Gpx, GroundOverlay, HeatMap, InfoWindow, Kmz, MapInstanceContext, Marker, MarkerClusterer, NaverMap, NaverMapContext, NaverMapProvider, Panorama, PanoramaContext, Polygon, Polyline, Rectangle, loadNaverMapsScript, useMap, useMapInstance, useMapInstanceRequired, useNaverMap, useNaverMapInstance, usePanorama, usePanoramaInstance, version };
|
|
3895
5558
|
//# sourceMappingURL=index.js.map
|