react-naver-maps-kit 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +978 -138
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +972 -141
- package/dist/index.js.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/marker/Marker.d.ts.map +1 -1
- package/dist/overlays/marker-clusterer/ClustererContext.d.ts +10 -17
- package/dist/overlays/marker-clusterer/ClustererContext.d.ts.map +1 -1
- package/dist/overlays/marker-clusterer/MarkerClusterer.d.ts +5 -4
- package/dist/overlays/marker-clusterer/MarkerClusterer.d.ts.map +1 -1
- package/dist/react/components/NaverMap.d.ts +2 -1
- package/dist/react/components/NaverMap.d.ts.map +1 -1
- package/package.json +15 -16
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
let react = require("react");
|
|
3
3
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
4
4
|
let react_dom = require("react-dom");
|
|
5
|
-
let
|
|
5
|
+
let module$1 = require("module");
|
|
6
6
|
|
|
7
7
|
//#region src/core/loader/loadNaverMapsScript.ts
|
|
8
8
|
const NAVER_MAPS_SCRIPT_BASE_URL = "https://oapi.map.naver.com/openapi/v3/maps.js";
|
|
@@ -876,15 +876,23 @@ function useNaverMapInstance(options = {}) {
|
|
|
876
876
|
//#endregion
|
|
877
877
|
//#region src/overlays/marker-clusterer/ClustererContext.ts
|
|
878
878
|
/**
|
|
879
|
-
* `<MarkerClusterer>`가 제공하는
|
|
879
|
+
* `<MarkerClusterer>`가 제공하는 registry Context.
|
|
880
|
+
* register/unregister/enabled만 포함하며, enabled가 바뀔 때만 갱신됩니다.
|
|
880
881
|
*
|
|
881
|
-
*
|
|
882
|
-
* `null`이면 클러스터러 밖에 있는 것이므로 일반 마커로 동작합니다.
|
|
883
|
-
*
|
|
884
|
-
* @internal 라이브러리 내부 전용. 직접 사용하지 마세요.
|
|
882
|
+
* @internal
|
|
885
883
|
*/
|
|
886
884
|
const ClustererContext = (0, react.createContext)(null);
|
|
887
885
|
ClustererContext.displayName = "ClustererContext";
|
|
886
|
+
/**
|
|
887
|
+
* `<MarkerClusterer>`가 제공하는 visibility Context.
|
|
888
|
+
* 재계산 시마다 갱신되며, 클러스터링 안 된 마커 ID 집합을 담습니다.
|
|
889
|
+
*
|
|
890
|
+
* `<Marker>`는 이 context를 읽어 자신이 보여야 할지 판단합니다.
|
|
891
|
+
*
|
|
892
|
+
* @internal
|
|
893
|
+
*/
|
|
894
|
+
const ClustererVisibilityContext = (0, react.createContext)(/* @__PURE__ */ new Set());
|
|
895
|
+
ClustererVisibilityContext.displayName = "ClustererVisibilityContext";
|
|
888
896
|
|
|
889
897
|
//#endregion
|
|
890
898
|
//#region src/overlays/marker/Marker.tsx
|
|
@@ -1036,11 +1044,15 @@ function toLatLngLiteral(position) {
|
|
|
1036
1044
|
const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
1037
1045
|
const { map: contextMap, sdkStatus } = useNaverMap();
|
|
1038
1046
|
const clustererRegistry = (0, react.useContext)(ClustererContext);
|
|
1047
|
+
const visibleIds = (0, react.useContext)(ClustererVisibilityContext);
|
|
1039
1048
|
const isInsideClusterer = clustererRegistry !== null && clustererRegistry.enabled;
|
|
1049
|
+
const autoId = (0, react.useId)();
|
|
1050
|
+
const effectiveId = props.clustererItemId ?? autoId;
|
|
1051
|
+
const isHiddenByClusterer = isInsideClusterer && !visibleIds.has(effectiveId);
|
|
1040
1052
|
const markerRef = (0, react.useRef)(null);
|
|
1041
1053
|
const markerEventListenersRef = (0, react.useRef)([]);
|
|
1042
1054
|
const onMarkerDestroyRef = (0, react.useRef)(props.onMarkerDestroy);
|
|
1043
|
-
const [markerDiv
|
|
1055
|
+
const [markerDiv] = (0, react.useState)(() => document.createElement("div"));
|
|
1044
1056
|
const [portalReady, setPortalReady] = (0, react.useState)(false);
|
|
1045
1057
|
const hasChildren = props.children !== void 0 && props.children !== null;
|
|
1046
1058
|
const targetMap = props.map ?? contextMap;
|
|
@@ -1050,8 +1062,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1050
1062
|
});
|
|
1051
1063
|
(0, react.useEffect)(() => {
|
|
1052
1064
|
if (!clustererRegistry) return;
|
|
1053
|
-
const id = props.clustererItemId;
|
|
1054
|
-
if (id === void 0 || id === null) return;
|
|
1065
|
+
const id = props.clustererItemId ?? autoId;
|
|
1055
1066
|
const latLng = toLatLngLiteral(props.position);
|
|
1056
1067
|
if (!latLng) return;
|
|
1057
1068
|
clustererRegistry.register({
|
|
@@ -1064,6 +1075,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1064
1075
|
clustererRegistry.unregister(id);
|
|
1065
1076
|
};
|
|
1066
1077
|
}, [
|
|
1078
|
+
autoId,
|
|
1067
1079
|
clustererRegistry,
|
|
1068
1080
|
props.clustererItemId,
|
|
1069
1081
|
props.position,
|
|
@@ -1071,17 +1083,10 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1071
1083
|
props.icon
|
|
1072
1084
|
]);
|
|
1073
1085
|
(0, react.useEffect)(() => {
|
|
1074
|
-
if (isInsideClusterer) return;
|
|
1075
1086
|
onMarkerDestroyRef.current = props.onMarkerDestroy;
|
|
1076
|
-
}, [
|
|
1087
|
+
}, [props.onMarkerDestroy]);
|
|
1077
1088
|
(0, react.useEffect)(() => {
|
|
1078
|
-
if (
|
|
1079
|
-
if (typeof document === "undefined") return;
|
|
1080
|
-
setMarkerDiv(document.createElement("div"));
|
|
1081
|
-
}, [isInsideClusterer]);
|
|
1082
|
-
(0, react.useEffect)(() => {
|
|
1083
|
-
if (isInsideClusterer) return;
|
|
1084
|
-
if (!hasChildren || !markerDiv) {
|
|
1089
|
+
if (!hasChildren) {
|
|
1085
1090
|
setPortalReady(false);
|
|
1086
1091
|
return;
|
|
1087
1092
|
}
|
|
@@ -1097,11 +1102,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1097
1102
|
return () => {
|
|
1098
1103
|
observer.disconnect();
|
|
1099
1104
|
};
|
|
1100
|
-
}, [
|
|
1101
|
-
isInsideClusterer,
|
|
1102
|
-
hasChildren,
|
|
1103
|
-
markerDiv
|
|
1104
|
-
]);
|
|
1105
|
+
}, [hasChildren, markerDiv]);
|
|
1105
1106
|
const invokeMarkerMethod = (0, react.useCallback)((methodName, ...args) => {
|
|
1106
1107
|
const marker = markerRef.current;
|
|
1107
1108
|
if (!marker) return;
|
|
@@ -1157,7 +1158,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1157
1158
|
setZIndex: (...args) => invokeMarkerMethod("setZIndex", ...args)
|
|
1158
1159
|
}), [invokeMarkerMethod]);
|
|
1159
1160
|
(0, react.useEffect)(() => {
|
|
1160
|
-
if (
|
|
1161
|
+
if (isHiddenByClusterer) return;
|
|
1161
1162
|
if (sdkStatus !== "ready" || !targetMap || markerRef.current) return;
|
|
1162
1163
|
if (hasChildren && !portalReady) return;
|
|
1163
1164
|
try {
|
|
@@ -1173,7 +1174,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1173
1174
|
propsRef.current.onMarkerError?.(normalizedError);
|
|
1174
1175
|
}
|
|
1175
1176
|
}, [
|
|
1176
|
-
|
|
1177
|
+
isHiddenByClusterer,
|
|
1177
1178
|
hasChildren,
|
|
1178
1179
|
markerDiv,
|
|
1179
1180
|
portalReady,
|
|
@@ -1181,7 +1182,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1181
1182
|
targetMap
|
|
1182
1183
|
]);
|
|
1183
1184
|
(0, react.useLayoutEffect)(() => {
|
|
1184
|
-
if (
|
|
1185
|
+
if (isHiddenByClusterer) return;
|
|
1185
1186
|
const marker = markerRef.current;
|
|
1186
1187
|
if (!marker || !targetMap) return;
|
|
1187
1188
|
const rafId = requestAnimationFrame(() => {
|
|
@@ -1195,7 +1196,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1195
1196
|
cancelAnimationFrame(rafId);
|
|
1196
1197
|
};
|
|
1197
1198
|
}, [
|
|
1198
|
-
|
|
1199
|
+
isHiddenByClusterer,
|
|
1199
1200
|
hasChildren,
|
|
1200
1201
|
markerDiv,
|
|
1201
1202
|
portalReady,
|
|
@@ -1214,7 +1215,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1214
1215
|
props.collisionBoxSize
|
|
1215
1216
|
]);
|
|
1216
1217
|
(0, react.useEffect)(() => {
|
|
1217
|
-
if (
|
|
1218
|
+
if (isHiddenByClusterer) return;
|
|
1218
1219
|
const marker = markerRef.current;
|
|
1219
1220
|
if (!marker) return;
|
|
1220
1221
|
bindMarkerEventListeners(marker, markerEventListenersRef, buildMarkerEventBindings(propsRef));
|
|
@@ -1224,14 +1225,14 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1224
1225
|
markerEventListenersRef.current = [];
|
|
1225
1226
|
}
|
|
1226
1227
|
};
|
|
1227
|
-
}, [
|
|
1228
|
+
}, [isHiddenByClusterer]);
|
|
1228
1229
|
(0, react.useEffect)(() => {
|
|
1229
|
-
if (
|
|
1230
|
+
if (isHiddenByClusterer) return;
|
|
1230
1231
|
return () => {
|
|
1231
1232
|
teardownMarker();
|
|
1232
1233
|
};
|
|
1233
|
-
}, [
|
|
1234
|
-
if (
|
|
1234
|
+
}, [isHiddenByClusterer, teardownMarker]);
|
|
1235
|
+
if (isHiddenByClusterer) return null;
|
|
1235
1236
|
if (!hasChildren || !markerDiv) return null;
|
|
1236
1237
|
return (0, react_dom.createPortal)(props.children, markerDiv);
|
|
1237
1238
|
});
|
|
@@ -2225,7 +2226,8 @@ function padBounds(bounds, padding) {
|
|
|
2225
2226
|
* 내부 registry에 위치·데이터를 등록합니다.
|
|
2226
2227
|
* 2. `MarkerClusterer`는 지도 이벤트(`idle`, `move`, `zoom`) 발생 시
|
|
2227
2228
|
* 현재 줌·뷰포트 기준으로 클러스터를 재계산합니다.
|
|
2228
|
-
* 3. 클러스터 마커는
|
|
2229
|
+
* 3. 클러스터 마커는 `<Marker>` JSX로 렌더링되며, children으로 클러스터 아이콘이 전달됩니다.
|
|
2230
|
+
* 4. 클러스터에 포함되지 않은 단독 포인트는 원래 `<Marker>` children을 그대로 표시합니다.
|
|
2229
2231
|
*
|
|
2230
2232
|
* ## 기본 사용법
|
|
2231
2233
|
*
|
|
@@ -2241,10 +2243,11 @@ function padBounds(bounds, padding) {
|
|
|
2241
2243
|
* {points.map(p => (
|
|
2242
2244
|
* <Marker
|
|
2243
2245
|
* key={p.id}
|
|
2244
|
-
* clustererItemId={p.id}
|
|
2245
2246
|
* position={p.position}
|
|
2246
2247
|
* item={p}
|
|
2247
|
-
*
|
|
2248
|
+
* >
|
|
2249
|
+
* <CustomPin />
|
|
2250
|
+
* </Marker>
|
|
2248
2251
|
* ))}
|
|
2249
2252
|
* </MarkerClusterer>
|
|
2250
2253
|
* </NaverMap>
|
|
@@ -2252,7 +2255,6 @@ function padBounds(bounds, padding) {
|
|
|
2252
2255
|
*
|
|
2253
2256
|
* ## 주의 사항
|
|
2254
2257
|
*
|
|
2255
|
-
* - `<Marker>`에 반드시 `clustererItemId` prop을 지정해야 합니다.
|
|
2256
2258
|
* - `<MarkerClusterer>`는 반드시 `<NaverMap>` 내부에 위치해야 합니다.
|
|
2257
2259
|
* - `enabled={false}`로 설정하면 클러스터링이 해제되고 각 `<Marker>`가 개별 마커로 렌더링됩니다.
|
|
2258
2260
|
*
|
|
@@ -2291,10 +2293,8 @@ function MarkerClusterer(props) {
|
|
|
2291
2293
|
if (prev && prev !== algorithm) prev.destroy?.();
|
|
2292
2294
|
};
|
|
2293
2295
|
}, [algorithm]);
|
|
2294
|
-
const
|
|
2295
|
-
const
|
|
2296
|
-
const clusterIconRootsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
2297
|
-
const clusterIconContainersRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
2296
|
+
const [clusters, setClusters] = (0, react.useState)([]);
|
|
2297
|
+
const [visibleIds, setVisibleIds] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
2298
2298
|
const helpersRef = (0, react.useRef)({
|
|
2299
2299
|
zoomToCluster: () => {},
|
|
2300
2300
|
fitBounds: () => {}
|
|
@@ -2327,94 +2327,22 @@ function MarkerClusterer(props) {
|
|
|
2327
2327
|
(0, react.useEffect)(() => {
|
|
2328
2328
|
onClusterClickRef.current = onClusterClick;
|
|
2329
2329
|
}, [onClusterClick]);
|
|
2330
|
-
const clusterIconRef = (0, react.useRef)(clusterIcon);
|
|
2331
|
-
(0, react.useEffect)(() => {
|
|
2332
|
-
clusterIconRef.current = clusterIcon;
|
|
2333
|
-
}, [clusterIcon]);
|
|
2334
2330
|
const recompute = (0, react.useCallback)(() => {
|
|
2335
2331
|
if (!map || sdkStatus !== "ready" || !enabled) return;
|
|
2336
2332
|
const zoom = map.getZoom();
|
|
2337
2333
|
const bounds = getMapBounds(map);
|
|
2338
2334
|
const items = Array.from(registryRef.current.values());
|
|
2339
|
-
const { clusters, points } = algorithm.cluster(items, {
|
|
2335
|
+
const { clusters: rawClusters, points } = algorithm.cluster(items, {
|
|
2340
2336
|
zoom,
|
|
2341
2337
|
bounds
|
|
2342
2338
|
});
|
|
2343
2339
|
const maxItems = clusterData?.maxItemsInCluster;
|
|
2344
2340
|
const includeItems = clusterData?.includeItems ?? true;
|
|
2345
|
-
|
|
2341
|
+
setClusters(rawClusters.map((c) => ({
|
|
2346
2342
|
...c,
|
|
2347
2343
|
items: includeItems ? maxItems !== void 0 ? c.items?.slice(0, maxItems) : c.items : void 0
|
|
2348
|
-
}));
|
|
2349
|
-
|
|
2350
|
-
const prevPointMarkers = pointMarkersRef.current;
|
|
2351
|
-
for (const [id, marker] of prevPointMarkers) if (!nextPointIds.has(id)) {
|
|
2352
|
-
marker.setMap(null);
|
|
2353
|
-
prevPointMarkers.delete(id);
|
|
2354
|
-
}
|
|
2355
|
-
for (const point of points) {
|
|
2356
|
-
const existing = prevPointMarkers.get(point.id);
|
|
2357
|
-
if (existing) {
|
|
2358
|
-
const pos = new naver.maps.LatLng(point.position.lat, point.position.lng);
|
|
2359
|
-
existing.setPosition(pos);
|
|
2360
|
-
if (point.markerOptions) existing.setOptions({ ...point.markerOptions });
|
|
2361
|
-
} else {
|
|
2362
|
-
const opts = {
|
|
2363
|
-
position: new naver.maps.LatLng(point.position.lat, point.position.lng),
|
|
2364
|
-
map
|
|
2365
|
-
};
|
|
2366
|
-
if (point.markerOptions) Object.assign(opts, point.markerOptions);
|
|
2367
|
-
const marker = new naver.maps.Marker(opts);
|
|
2368
|
-
prevPointMarkers.set(point.id, marker);
|
|
2369
|
-
}
|
|
2370
|
-
}
|
|
2371
|
-
const nextClusterIds = new Set(processedClusters.map((c) => c.id));
|
|
2372
|
-
const prevClusterMarkers = clusterMarkersRef.current;
|
|
2373
|
-
const prevRoots = clusterIconRootsRef.current;
|
|
2374
|
-
const prevContainers = clusterIconContainersRef.current;
|
|
2375
|
-
for (const [id, marker] of prevClusterMarkers) if (!nextClusterIds.has(id)) {
|
|
2376
|
-
marker.setMap(null);
|
|
2377
|
-
prevClusterMarkers.delete(id);
|
|
2378
|
-
const root = prevRoots.get(id);
|
|
2379
|
-
if (root) {
|
|
2380
|
-
root.unmount();
|
|
2381
|
-
prevRoots.delete(id);
|
|
2382
|
-
}
|
|
2383
|
-
prevContainers.delete(id);
|
|
2384
|
-
}
|
|
2385
|
-
for (const cluster of processedClusters) {
|
|
2386
|
-
const existingMarker = prevClusterMarkers.get(cluster.id);
|
|
2387
|
-
const renderer = clusterIconRef.current;
|
|
2388
|
-
const iconNode = renderer ? renderer({
|
|
2389
|
-
cluster,
|
|
2390
|
-
count: cluster.count
|
|
2391
|
-
}) : DefaultClusterIcon({ count: cluster.count });
|
|
2392
|
-
if (existingMarker) {
|
|
2393
|
-
existingMarker.setPosition(new naver.maps.LatLng(cluster.position.lat, cluster.position.lng));
|
|
2394
|
-
const root = prevRoots.get(cluster.id);
|
|
2395
|
-
if (root) root.render(iconNode);
|
|
2396
|
-
} else {
|
|
2397
|
-
const container = document.createElement("div");
|
|
2398
|
-
container.style.cursor = "pointer";
|
|
2399
|
-
const root = (0, react_dom_client.createRoot)(container);
|
|
2400
|
-
root.render(iconNode);
|
|
2401
|
-
prevContainers.set(cluster.id, container);
|
|
2402
|
-
prevRoots.set(cluster.id, root);
|
|
2403
|
-
const marker = new naver.maps.Marker({
|
|
2404
|
-
position: new naver.maps.LatLng(cluster.position.lat, cluster.position.lng),
|
|
2405
|
-
map,
|
|
2406
|
-
icon: { content: container },
|
|
2407
|
-
clickable: true
|
|
2408
|
-
});
|
|
2409
|
-
naver.maps.Event.addListener(marker, "click", () => {
|
|
2410
|
-
onClusterClickRef.current?.({
|
|
2411
|
-
cluster,
|
|
2412
|
-
helpers: helpersRef.current
|
|
2413
|
-
});
|
|
2414
|
-
});
|
|
2415
|
-
prevClusterMarkers.set(cluster.id, marker);
|
|
2416
|
-
}
|
|
2417
|
-
}
|
|
2344
|
+
})));
|
|
2345
|
+
setVisibleIds(new Set(points.map((p) => p.id)));
|
|
2418
2346
|
}, [
|
|
2419
2347
|
map,
|
|
2420
2348
|
sdkStatus,
|
|
@@ -2455,31 +2383,31 @@ function MarkerClusterer(props) {
|
|
|
2455
2383
|
behavior?.debounceMs,
|
|
2456
2384
|
recompute
|
|
2457
2385
|
]);
|
|
2458
|
-
(0, react.useEffect)(() => {
|
|
2459
|
-
return () => {
|
|
2460
|
-
for (const marker of pointMarkersRef.current.values()) marker.setMap(null);
|
|
2461
|
-
pointMarkersRef.current.clear();
|
|
2462
|
-
for (const marker of clusterMarkersRef.current.values()) marker.setMap(null);
|
|
2463
|
-
clusterMarkersRef.current.clear();
|
|
2464
|
-
for (const root of clusterIconRootsRef.current.values()) root.unmount();
|
|
2465
|
-
clusterIconRootsRef.current.clear();
|
|
2466
|
-
clusterIconContainersRef.current.clear();
|
|
2467
|
-
};
|
|
2468
|
-
}, []);
|
|
2469
2386
|
(0, react.useEffect)(() => {
|
|
2470
2387
|
if (enabled) return;
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
for (const marker of clusterMarkersRef.current.values()) marker.setMap(null);
|
|
2474
|
-
clusterMarkersRef.current.clear();
|
|
2475
|
-
for (const root of clusterIconRootsRef.current.values()) root.unmount();
|
|
2476
|
-
clusterIconRootsRef.current.clear();
|
|
2477
|
-
clusterIconContainersRef.current.clear();
|
|
2388
|
+
setClusters([]);
|
|
2389
|
+
setVisibleIds(/* @__PURE__ */ new Set());
|
|
2478
2390
|
}, [enabled]);
|
|
2479
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClustererContext.Provider, {
|
|
2391
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClustererContext.Provider, {
|
|
2480
2392
|
value: registry,
|
|
2481
|
-
children
|
|
2482
|
-
|
|
2393
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClustererVisibilityContext.Provider, {
|
|
2394
|
+
value: visibleIds,
|
|
2395
|
+
children
|
|
2396
|
+
})
|
|
2397
|
+
}), enabled && clusters.map((cluster) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Marker, {
|
|
2398
|
+
position: cluster.position,
|
|
2399
|
+
clickable: true,
|
|
2400
|
+
onClick: () => {
|
|
2401
|
+
onClusterClickRef.current?.({
|
|
2402
|
+
cluster,
|
|
2403
|
+
helpers: helpersRef.current
|
|
2404
|
+
});
|
|
2405
|
+
},
|
|
2406
|
+
children: clusterIcon ? clusterIcon({
|
|
2407
|
+
cluster,
|
|
2408
|
+
count: cluster.count
|
|
2409
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultClusterIcon, { count: cluster.count })
|
|
2410
|
+
}, cluster.id))] });
|
|
2483
2411
|
}
|
|
2484
2412
|
MarkerClusterer.displayName = "MarkerClusterer";
|
|
2485
2413
|
|
|
@@ -3960,16 +3888,928 @@ const Rectangle = (0, react.forwardRef)(function RectangleInner(props, ref) {
|
|
|
3960
3888
|
});
|
|
3961
3889
|
Rectangle.displayName = "Rectangle";
|
|
3962
3890
|
|
|
3891
|
+
//#endregion
|
|
3892
|
+
//#region src/overlays/data/GeoJson.tsx
|
|
3893
|
+
function buildGeoJsonEventBindings(props) {
|
|
3894
|
+
return [
|
|
3895
|
+
{
|
|
3896
|
+
eventName: "addfeature",
|
|
3897
|
+
invoke: props.onAddFeature ? (event) => props.onAddFeature?.(event) : void 0
|
|
3898
|
+
},
|
|
3899
|
+
{
|
|
3900
|
+
eventName: "removefeature",
|
|
3901
|
+
invoke: props.onRemoveFeature ? (event) => props.onRemoveFeature?.(event) : void 0
|
|
3902
|
+
},
|
|
3903
|
+
{
|
|
3904
|
+
eventName: "property_changed",
|
|
3905
|
+
invoke: props.onPropertyChanged ? (event) => props.onPropertyChanged?.(event) : void 0
|
|
3906
|
+
},
|
|
3907
|
+
{
|
|
3908
|
+
eventName: "click",
|
|
3909
|
+
invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
|
|
3910
|
+
},
|
|
3911
|
+
{
|
|
3912
|
+
eventName: "dblclick",
|
|
3913
|
+
invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
|
|
3914
|
+
},
|
|
3915
|
+
{
|
|
3916
|
+
eventName: "rightclick",
|
|
3917
|
+
invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
|
|
3918
|
+
},
|
|
3919
|
+
{
|
|
3920
|
+
eventName: "mousedown",
|
|
3921
|
+
invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
|
|
3922
|
+
},
|
|
3923
|
+
{
|
|
3924
|
+
eventName: "mouseup",
|
|
3925
|
+
invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
|
|
3926
|
+
},
|
|
3927
|
+
{
|
|
3928
|
+
eventName: "mouseover",
|
|
3929
|
+
invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
|
|
3930
|
+
},
|
|
3931
|
+
{
|
|
3932
|
+
eventName: "mouseout",
|
|
3933
|
+
invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
|
|
3934
|
+
}
|
|
3935
|
+
];
|
|
3936
|
+
}
|
|
3937
|
+
const GeoJson = (0, react.forwardRef)(function GeoJsonInner(props, ref) {
|
|
3938
|
+
const { map: contextMap, sdkStatus } = useNaverMap();
|
|
3939
|
+
const dataRef = (0, react.useRef)(null);
|
|
3940
|
+
const dataEventListenersRef = (0, react.useRef)([]);
|
|
3941
|
+
const onDataDestroyRef = (0, react.useRef)(props.onDataDestroy);
|
|
3942
|
+
const prevDataRef = (0, react.useRef)(null);
|
|
3943
|
+
(0, react.useEffect)(() => {
|
|
3944
|
+
onDataDestroyRef.current = props.onDataDestroy;
|
|
3945
|
+
}, [props.onDataDestroy]);
|
|
3946
|
+
const invokeDataMethod = (0, react.useCallback)((methodName, ...args) => {
|
|
3947
|
+
const data = dataRef.current;
|
|
3948
|
+
if (!data) return;
|
|
3949
|
+
const method = data[methodName];
|
|
3950
|
+
if (typeof method !== "function") return;
|
|
3951
|
+
return method.apply(data, args);
|
|
3952
|
+
}, []);
|
|
3953
|
+
const teardownData = (0, react.useCallback)(() => {
|
|
3954
|
+
const data = dataRef.current;
|
|
3955
|
+
if (!data) return;
|
|
3956
|
+
try {
|
|
3957
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
3958
|
+
dataEventListenersRef.current = [];
|
|
3959
|
+
naver.maps.Event.clearInstanceListeners(data);
|
|
3960
|
+
} catch (error) {
|
|
3961
|
+
console.error("[react-naver-maps-kit] failed to clear GeoJson data layer listeners", error);
|
|
3962
|
+
}
|
|
3963
|
+
data.setMap(null);
|
|
3964
|
+
dataRef.current = null;
|
|
3965
|
+
prevDataRef.current = null;
|
|
3966
|
+
onDataDestroyRef.current?.();
|
|
3967
|
+
}, []);
|
|
3968
|
+
(0, react.useImperativeHandle)(ref, () => ({
|
|
3969
|
+
getInstance: () => dataRef.current,
|
|
3970
|
+
getAllFeature: (...args) => invokeDataMethod("getAllFeature", ...args),
|
|
3971
|
+
getFeatureById: (...args) => invokeDataMethod("getFeatureById", ...args),
|
|
3972
|
+
getMap: (...args) => invokeDataMethod("getMap", ...args),
|
|
3973
|
+
getStyle: (...args) => invokeDataMethod("getStyle", ...args),
|
|
3974
|
+
overrideStyle: (...args) => invokeDataMethod("overrideStyle", ...args),
|
|
3975
|
+
removeFeature: (...args) => invokeDataMethod("removeFeature", ...args),
|
|
3976
|
+
revertStyle: (...args) => invokeDataMethod("revertStyle", ...args),
|
|
3977
|
+
setStyle: (...args) => invokeDataMethod("setStyle", ...args),
|
|
3978
|
+
toGeoJson: (...args) => invokeDataMethod("toGeoJson", ...args)
|
|
3979
|
+
}), [invokeDataMethod]);
|
|
3980
|
+
(0, react.useEffect)(() => {
|
|
3981
|
+
if (sdkStatus !== "ready" || !contextMap || dataRef.current) return;
|
|
3982
|
+
try {
|
|
3983
|
+
const data = new naver.maps.Data();
|
|
3984
|
+
data.setMap(contextMap);
|
|
3985
|
+
if (props.style) data.setStyle(props.style);
|
|
3986
|
+
const features = data.addGeoJson(props.data, props.autoStyle ?? true);
|
|
3987
|
+
prevDataRef.current = props.data;
|
|
3988
|
+
dataRef.current = data;
|
|
3989
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildGeoJsonEventBindings(props));
|
|
3990
|
+
props.onDataReady?.(data);
|
|
3991
|
+
props.onFeaturesAdded?.(features);
|
|
3992
|
+
} catch (error) {
|
|
3993
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Data instance for GeoJson.");
|
|
3994
|
+
props.onDataError?.(normalizedError);
|
|
3995
|
+
}
|
|
3996
|
+
}, [sdkStatus, contextMap]);
|
|
3997
|
+
(0, react.useEffect)(() => {
|
|
3998
|
+
const data = dataRef.current;
|
|
3999
|
+
if (!data || props.data === prevDataRef.current) return;
|
|
4000
|
+
try {
|
|
4001
|
+
if (prevDataRef.current) data.removeGeoJson(prevDataRef.current);
|
|
4002
|
+
const features = data.addGeoJson(props.data, props.autoStyle ?? true);
|
|
4003
|
+
prevDataRef.current = props.data;
|
|
4004
|
+
props.onFeaturesAdded?.(features);
|
|
4005
|
+
} catch (error) {
|
|
4006
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to update GeoJson data.");
|
|
4007
|
+
props.onDataError?.(normalizedError);
|
|
4008
|
+
}
|
|
4009
|
+
}, [props.data, props.autoStyle]);
|
|
4010
|
+
(0, react.useEffect)(() => {
|
|
4011
|
+
const data = dataRef.current;
|
|
4012
|
+
if (!data) return;
|
|
4013
|
+
if (props.style) data.setStyle(props.style);
|
|
4014
|
+
}, [props.style]);
|
|
4015
|
+
(0, react.useEffect)(() => {
|
|
4016
|
+
const data = dataRef.current;
|
|
4017
|
+
if (!data) return;
|
|
4018
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildGeoJsonEventBindings(props));
|
|
4019
|
+
return () => {
|
|
4020
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4021
|
+
dataEventListenersRef.current = [];
|
|
4022
|
+
};
|
|
4023
|
+
}, [props]);
|
|
4024
|
+
(0, react.useEffect)(() => {
|
|
4025
|
+
return () => {
|
|
4026
|
+
teardownData();
|
|
4027
|
+
};
|
|
4028
|
+
}, [teardownData]);
|
|
4029
|
+
return null;
|
|
4030
|
+
});
|
|
4031
|
+
GeoJson.displayName = "GeoJson";
|
|
4032
|
+
|
|
4033
|
+
//#endregion
|
|
4034
|
+
//#region src/overlays/data/Gpx.tsx
|
|
4035
|
+
function buildGpxEventBindings(props) {
|
|
4036
|
+
return [
|
|
4037
|
+
{
|
|
4038
|
+
eventName: "addfeature",
|
|
4039
|
+
invoke: props.onAddFeature ? (event) => props.onAddFeature?.(event) : void 0
|
|
4040
|
+
},
|
|
4041
|
+
{
|
|
4042
|
+
eventName: "removefeature",
|
|
4043
|
+
invoke: props.onRemoveFeature ? (event) => props.onRemoveFeature?.(event) : void 0
|
|
4044
|
+
},
|
|
4045
|
+
{
|
|
4046
|
+
eventName: "property_changed",
|
|
4047
|
+
invoke: props.onPropertyChanged ? (event) => props.onPropertyChanged?.(event) : void 0
|
|
4048
|
+
},
|
|
4049
|
+
{
|
|
4050
|
+
eventName: "click",
|
|
4051
|
+
invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
|
|
4052
|
+
},
|
|
4053
|
+
{
|
|
4054
|
+
eventName: "dblclick",
|
|
4055
|
+
invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
|
|
4056
|
+
},
|
|
4057
|
+
{
|
|
4058
|
+
eventName: "rightclick",
|
|
4059
|
+
invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
|
|
4060
|
+
},
|
|
4061
|
+
{
|
|
4062
|
+
eventName: "mousedown",
|
|
4063
|
+
invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
|
|
4064
|
+
},
|
|
4065
|
+
{
|
|
4066
|
+
eventName: "mouseup",
|
|
4067
|
+
invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
|
|
4068
|
+
},
|
|
4069
|
+
{
|
|
4070
|
+
eventName: "mouseover",
|
|
4071
|
+
invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
|
|
4072
|
+
},
|
|
4073
|
+
{
|
|
4074
|
+
eventName: "mouseout",
|
|
4075
|
+
invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
|
|
4076
|
+
}
|
|
4077
|
+
];
|
|
4078
|
+
}
|
|
4079
|
+
function parseXml(xmlString) {
|
|
4080
|
+
const doc = new DOMParser().parseFromString(xmlString, "application/xml");
|
|
4081
|
+
const parseError = doc.querySelector("parsererror");
|
|
4082
|
+
if (parseError) throw new Error(`XML parse error: ${parseError.textContent}`);
|
|
4083
|
+
return doc;
|
|
4084
|
+
}
|
|
4085
|
+
const Gpx = (0, react.forwardRef)(function GpxInner(props, ref) {
|
|
4086
|
+
const { map: contextMap, sdkStatus } = useNaverMap();
|
|
4087
|
+
const dataRef = (0, react.useRef)(null);
|
|
4088
|
+
const dataEventListenersRef = (0, react.useRef)([]);
|
|
4089
|
+
const onDataDestroyRef = (0, react.useRef)(props.onDataDestroy);
|
|
4090
|
+
const prevUrlRef = (0, react.useRef)(null);
|
|
4091
|
+
const abortRef = (0, react.useRef)(null);
|
|
4092
|
+
(0, react.useEffect)(() => {
|
|
4093
|
+
onDataDestroyRef.current = props.onDataDestroy;
|
|
4094
|
+
}, [props.onDataDestroy]);
|
|
4095
|
+
const invokeDataMethod = (0, react.useCallback)((methodName, ...args) => {
|
|
4096
|
+
const data = dataRef.current;
|
|
4097
|
+
if (!data) return;
|
|
4098
|
+
const method = data[methodName];
|
|
4099
|
+
if (typeof method !== "function") return;
|
|
4100
|
+
return method.apply(data, args);
|
|
4101
|
+
}, []);
|
|
4102
|
+
const teardownData = (0, react.useCallback)(() => {
|
|
4103
|
+
abortRef.current?.abort();
|
|
4104
|
+
abortRef.current = null;
|
|
4105
|
+
const data = dataRef.current;
|
|
4106
|
+
if (!data) return;
|
|
4107
|
+
try {
|
|
4108
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4109
|
+
dataEventListenersRef.current = [];
|
|
4110
|
+
naver.maps.Event.clearInstanceListeners(data);
|
|
4111
|
+
} catch (error) {
|
|
4112
|
+
console.error("[react-naver-maps-kit] failed to clear GPX data layer listeners", error);
|
|
4113
|
+
}
|
|
4114
|
+
data.setMap(null);
|
|
4115
|
+
dataRef.current = null;
|
|
4116
|
+
prevUrlRef.current = null;
|
|
4117
|
+
onDataDestroyRef.current?.();
|
|
4118
|
+
}, []);
|
|
4119
|
+
(0, react.useImperativeHandle)(ref, () => ({
|
|
4120
|
+
getInstance: () => dataRef.current,
|
|
4121
|
+
getAllFeature: (...args) => invokeDataMethod("getAllFeature", ...args),
|
|
4122
|
+
getFeatureById: (...args) => invokeDataMethod("getFeatureById", ...args),
|
|
4123
|
+
getMap: (...args) => invokeDataMethod("getMap", ...args),
|
|
4124
|
+
getStyle: (...args) => invokeDataMethod("getStyle", ...args),
|
|
4125
|
+
overrideStyle: (...args) => invokeDataMethod("overrideStyle", ...args),
|
|
4126
|
+
removeFeature: (...args) => invokeDataMethod("removeFeature", ...args),
|
|
4127
|
+
revertStyle: (...args) => invokeDataMethod("revertStyle", ...args),
|
|
4128
|
+
setStyle: (...args) => invokeDataMethod("setStyle", ...args),
|
|
4129
|
+
toGeoJson: (...args) => invokeDataMethod("toGeoJson", ...args)
|
|
4130
|
+
}), [invokeDataMethod]);
|
|
4131
|
+
const loadAndAddGpx = (0, react.useCallback)(async (data, url, isInitial) => {
|
|
4132
|
+
const controller = new AbortController();
|
|
4133
|
+
abortRef.current = controller;
|
|
4134
|
+
try {
|
|
4135
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
4136
|
+
if (!response.ok) throw new Error(`Failed to fetch GPX: ${response.status} ${response.statusText}`);
|
|
4137
|
+
const xmlDoc = parseXml(await response.text());
|
|
4138
|
+
if (controller.signal.aborted) return;
|
|
4139
|
+
if (!isInitial) data.getAllFeature().forEach((feature) => data.removeFeature(feature));
|
|
4140
|
+
const features = data.addGpx(xmlDoc, props.autoStyle ?? true);
|
|
4141
|
+
prevUrlRef.current = url;
|
|
4142
|
+
props.onFeaturesAdded?.(features);
|
|
4143
|
+
} catch (error) {
|
|
4144
|
+
if (controller.signal.aborted) return;
|
|
4145
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to load GPX data.");
|
|
4146
|
+
props.onDataError?.(normalizedError);
|
|
4147
|
+
}
|
|
4148
|
+
}, [
|
|
4149
|
+
props.autoStyle,
|
|
4150
|
+
props.onFeaturesAdded,
|
|
4151
|
+
props.onDataError
|
|
4152
|
+
]);
|
|
4153
|
+
(0, react.useEffect)(() => {
|
|
4154
|
+
if (sdkStatus !== "ready" || !contextMap || dataRef.current) return;
|
|
4155
|
+
try {
|
|
4156
|
+
const data = new naver.maps.Data();
|
|
4157
|
+
data.setMap(contextMap);
|
|
4158
|
+
if (props.style) data.setStyle(props.style);
|
|
4159
|
+
dataRef.current = data;
|
|
4160
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildGpxEventBindings(props));
|
|
4161
|
+
props.onDataReady?.(data);
|
|
4162
|
+
loadAndAddGpx(data, props.url, true);
|
|
4163
|
+
} catch (error) {
|
|
4164
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Data instance.");
|
|
4165
|
+
props.onDataError?.(normalizedError);
|
|
4166
|
+
}
|
|
4167
|
+
}, [sdkStatus, contextMap]);
|
|
4168
|
+
(0, react.useEffect)(() => {
|
|
4169
|
+
const data = dataRef.current;
|
|
4170
|
+
if (!data || props.url === prevUrlRef.current) return;
|
|
4171
|
+
abortRef.current?.abort();
|
|
4172
|
+
loadAndAddGpx(data, props.url, false);
|
|
4173
|
+
}, [props.url, loadAndAddGpx]);
|
|
4174
|
+
(0, react.useEffect)(() => {
|
|
4175
|
+
const data = dataRef.current;
|
|
4176
|
+
if (!data) return;
|
|
4177
|
+
if (props.style) data.setStyle(props.style);
|
|
4178
|
+
}, [props.style]);
|
|
4179
|
+
(0, react.useEffect)(() => {
|
|
4180
|
+
const data = dataRef.current;
|
|
4181
|
+
if (!data) return;
|
|
4182
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildGpxEventBindings(props));
|
|
4183
|
+
return () => {
|
|
4184
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4185
|
+
dataEventListenersRef.current = [];
|
|
4186
|
+
};
|
|
4187
|
+
}, [props]);
|
|
4188
|
+
(0, react.useEffect)(() => {
|
|
4189
|
+
return () => {
|
|
4190
|
+
teardownData();
|
|
4191
|
+
};
|
|
4192
|
+
}, [teardownData]);
|
|
4193
|
+
return null;
|
|
4194
|
+
});
|
|
4195
|
+
Gpx.displayName = "Gpx";
|
|
4196
|
+
|
|
4197
|
+
//#endregion
|
|
4198
|
+
//#region ../../node_modules/.pnpm/fflate@0.8.2/node_modules/fflate/esm/index.mjs
|
|
4199
|
+
var require$1 = (0, module$1.createRequire)("/");
|
|
4200
|
+
var Worker;
|
|
4201
|
+
try {
|
|
4202
|
+
Worker = require$1("worker_threads").Worker;
|
|
4203
|
+
} catch (e) {}
|
|
4204
|
+
var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;
|
|
4205
|
+
var fleb = new u8([
|
|
4206
|
+
0,
|
|
4207
|
+
0,
|
|
4208
|
+
0,
|
|
4209
|
+
0,
|
|
4210
|
+
0,
|
|
4211
|
+
0,
|
|
4212
|
+
0,
|
|
4213
|
+
0,
|
|
4214
|
+
1,
|
|
4215
|
+
1,
|
|
4216
|
+
1,
|
|
4217
|
+
1,
|
|
4218
|
+
2,
|
|
4219
|
+
2,
|
|
4220
|
+
2,
|
|
4221
|
+
2,
|
|
4222
|
+
3,
|
|
4223
|
+
3,
|
|
4224
|
+
3,
|
|
4225
|
+
3,
|
|
4226
|
+
4,
|
|
4227
|
+
4,
|
|
4228
|
+
4,
|
|
4229
|
+
4,
|
|
4230
|
+
5,
|
|
4231
|
+
5,
|
|
4232
|
+
5,
|
|
4233
|
+
5,
|
|
4234
|
+
0,
|
|
4235
|
+
0,
|
|
4236
|
+
0,
|
|
4237
|
+
0
|
|
4238
|
+
]);
|
|
4239
|
+
var fdeb = new u8([
|
|
4240
|
+
0,
|
|
4241
|
+
0,
|
|
4242
|
+
0,
|
|
4243
|
+
0,
|
|
4244
|
+
1,
|
|
4245
|
+
1,
|
|
4246
|
+
2,
|
|
4247
|
+
2,
|
|
4248
|
+
3,
|
|
4249
|
+
3,
|
|
4250
|
+
4,
|
|
4251
|
+
4,
|
|
4252
|
+
5,
|
|
4253
|
+
5,
|
|
4254
|
+
6,
|
|
4255
|
+
6,
|
|
4256
|
+
7,
|
|
4257
|
+
7,
|
|
4258
|
+
8,
|
|
4259
|
+
8,
|
|
4260
|
+
9,
|
|
4261
|
+
9,
|
|
4262
|
+
10,
|
|
4263
|
+
10,
|
|
4264
|
+
11,
|
|
4265
|
+
11,
|
|
4266
|
+
12,
|
|
4267
|
+
12,
|
|
4268
|
+
13,
|
|
4269
|
+
13,
|
|
4270
|
+
0,
|
|
4271
|
+
0
|
|
4272
|
+
]);
|
|
4273
|
+
var clim = new u8([
|
|
4274
|
+
16,
|
|
4275
|
+
17,
|
|
4276
|
+
18,
|
|
4277
|
+
0,
|
|
4278
|
+
8,
|
|
4279
|
+
7,
|
|
4280
|
+
9,
|
|
4281
|
+
6,
|
|
4282
|
+
10,
|
|
4283
|
+
5,
|
|
4284
|
+
11,
|
|
4285
|
+
4,
|
|
4286
|
+
12,
|
|
4287
|
+
3,
|
|
4288
|
+
13,
|
|
4289
|
+
2,
|
|
4290
|
+
14,
|
|
4291
|
+
1,
|
|
4292
|
+
15
|
|
4293
|
+
]);
|
|
4294
|
+
var freb = function(eb, start) {
|
|
4295
|
+
var b = new u16(31);
|
|
4296
|
+
for (var i = 0; i < 31; ++i) b[i] = start += 1 << eb[i - 1];
|
|
4297
|
+
var r = new i32(b[30]);
|
|
4298
|
+
for (var i = 1; i < 30; ++i) for (var j = b[i]; j < b[i + 1]; ++j) r[j] = j - b[i] << 5 | i;
|
|
4299
|
+
return {
|
|
4300
|
+
b,
|
|
4301
|
+
r
|
|
4302
|
+
};
|
|
4303
|
+
};
|
|
4304
|
+
var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;
|
|
4305
|
+
fl[28] = 258, revfl[258] = 28;
|
|
4306
|
+
var _b = freb(fdeb, 0), fd = _b.b, revfd = _b.r;
|
|
4307
|
+
var rev = new u16(32768);
|
|
4308
|
+
for (var i = 0; i < 32768; ++i) {
|
|
4309
|
+
var x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
4310
|
+
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
4311
|
+
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
4312
|
+
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
4313
|
+
}
|
|
4314
|
+
var hMap = (function(cd, mb, r) {
|
|
4315
|
+
var s = cd.length;
|
|
4316
|
+
var i = 0;
|
|
4317
|
+
var l = new u16(mb);
|
|
4318
|
+
for (; i < s; ++i) if (cd[i]) ++l[cd[i] - 1];
|
|
4319
|
+
var le = new u16(mb);
|
|
4320
|
+
for (i = 1; i < mb; ++i) le[i] = le[i - 1] + l[i - 1] << 1;
|
|
4321
|
+
var co;
|
|
4322
|
+
if (r) {
|
|
4323
|
+
co = new u16(1 << mb);
|
|
4324
|
+
var rvb = 15 - mb;
|
|
4325
|
+
for (i = 0; i < s; ++i) if (cd[i]) {
|
|
4326
|
+
var sv = i << 4 | cd[i];
|
|
4327
|
+
var r_1 = mb - cd[i];
|
|
4328
|
+
var v = le[cd[i] - 1]++ << r_1;
|
|
4329
|
+
for (var m = v | (1 << r_1) - 1; v <= m; ++v) co[rev[v] >> rvb] = sv;
|
|
4330
|
+
}
|
|
4331
|
+
} else {
|
|
4332
|
+
co = new u16(s);
|
|
4333
|
+
for (i = 0; i < s; ++i) if (cd[i]) co[i] = rev[le[cd[i] - 1]++] >> 15 - cd[i];
|
|
4334
|
+
}
|
|
4335
|
+
return co;
|
|
4336
|
+
});
|
|
4337
|
+
var flt = new u8(288);
|
|
4338
|
+
for (var i = 0; i < 144; ++i) flt[i] = 8;
|
|
4339
|
+
for (var i = 144; i < 256; ++i) flt[i] = 9;
|
|
4340
|
+
for (var i = 256; i < 280; ++i) flt[i] = 7;
|
|
4341
|
+
for (var i = 280; i < 288; ++i) flt[i] = 8;
|
|
4342
|
+
var fdt = new u8(32);
|
|
4343
|
+
for (var i = 0; i < 32; ++i) fdt[i] = 5;
|
|
4344
|
+
var flm = /* @__PURE__ */ hMap(flt, 9, 0), flrm = /* @__PURE__ */ hMap(flt, 9, 1);
|
|
4345
|
+
var fdm = /* @__PURE__ */ hMap(fdt, 5, 0), fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
|
|
4346
|
+
var max = function(a) {
|
|
4347
|
+
var m = a[0];
|
|
4348
|
+
for (var i = 1; i < a.length; ++i) if (a[i] > m) m = a[i];
|
|
4349
|
+
return m;
|
|
4350
|
+
};
|
|
4351
|
+
var bits = function(d, p, m) {
|
|
4352
|
+
var o = p / 8 | 0;
|
|
4353
|
+
return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
|
|
4354
|
+
};
|
|
4355
|
+
var bits16 = function(d, p) {
|
|
4356
|
+
var o = p / 8 | 0;
|
|
4357
|
+
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
4358
|
+
};
|
|
4359
|
+
var shft = function(p) {
|
|
4360
|
+
return (p + 7) / 8 | 0;
|
|
4361
|
+
};
|
|
4362
|
+
var slc = function(v, s, e) {
|
|
4363
|
+
if (s == null || s < 0) s = 0;
|
|
4364
|
+
if (e == null || e > v.length) e = v.length;
|
|
4365
|
+
return new u8(v.subarray(s, e));
|
|
4366
|
+
};
|
|
4367
|
+
var ec = [
|
|
4368
|
+
"unexpected EOF",
|
|
4369
|
+
"invalid block type",
|
|
4370
|
+
"invalid length/literal",
|
|
4371
|
+
"invalid distance",
|
|
4372
|
+
"stream finished",
|
|
4373
|
+
"no stream handler",
|
|
4374
|
+
,
|
|
4375
|
+
"no callback",
|
|
4376
|
+
"invalid UTF-8 data",
|
|
4377
|
+
"extra field too long",
|
|
4378
|
+
"date not in range 1980-2099",
|
|
4379
|
+
"filename too long",
|
|
4380
|
+
"stream finishing",
|
|
4381
|
+
"invalid zip data"
|
|
4382
|
+
];
|
|
4383
|
+
var err = function(ind, msg, nt) {
|
|
4384
|
+
var e = new Error(msg || ec[ind]);
|
|
4385
|
+
e.code = ind;
|
|
4386
|
+
if (Error.captureStackTrace) Error.captureStackTrace(e, err);
|
|
4387
|
+
if (!nt) throw e;
|
|
4388
|
+
return e;
|
|
4389
|
+
};
|
|
4390
|
+
var inflt = function(dat, st, buf, dict) {
|
|
4391
|
+
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
4392
|
+
if (!sl || st.f && !st.l) return buf || new u8(0);
|
|
4393
|
+
var noBuf = !buf;
|
|
4394
|
+
var resize = noBuf || st.i != 2;
|
|
4395
|
+
var noSt = st.i;
|
|
4396
|
+
if (noBuf) buf = new u8(sl * 3);
|
|
4397
|
+
var cbuf = function(l) {
|
|
4398
|
+
var bl = buf.length;
|
|
4399
|
+
if (l > bl) {
|
|
4400
|
+
var nbuf = new u8(Math.max(bl * 2, l));
|
|
4401
|
+
nbuf.set(buf);
|
|
4402
|
+
buf = nbuf;
|
|
4403
|
+
}
|
|
4404
|
+
};
|
|
4405
|
+
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;
|
|
4406
|
+
var tbts = sl * 8;
|
|
4407
|
+
do {
|
|
4408
|
+
if (!lm) {
|
|
4409
|
+
final = bits(dat, pos, 1);
|
|
4410
|
+
var type = bits(dat, pos + 1, 3);
|
|
4411
|
+
pos += 3;
|
|
4412
|
+
if (!type) {
|
|
4413
|
+
var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
|
|
4414
|
+
if (t > sl) {
|
|
4415
|
+
if (noSt) err(0);
|
|
4416
|
+
break;
|
|
4417
|
+
}
|
|
4418
|
+
if (resize) cbuf(bt + l);
|
|
4419
|
+
buf.set(dat.subarray(s, t), bt);
|
|
4420
|
+
st.b = bt += l, st.p = pos = t * 8, st.f = final;
|
|
4421
|
+
continue;
|
|
4422
|
+
} else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
4423
|
+
else if (type == 2) {
|
|
4424
|
+
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
4425
|
+
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
4426
|
+
pos += 14;
|
|
4427
|
+
var ldt = new u8(tl);
|
|
4428
|
+
var clt = new u8(19);
|
|
4429
|
+
for (var i = 0; i < hcLen; ++i) clt[clim[i]] = bits(dat, pos + i * 3, 7);
|
|
4430
|
+
pos += hcLen * 3;
|
|
4431
|
+
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
4432
|
+
var clm = hMap(clt, clb, 1);
|
|
4433
|
+
for (var i = 0; i < tl;) {
|
|
4434
|
+
var r = clm[bits(dat, pos, clbmsk)];
|
|
4435
|
+
pos += r & 15;
|
|
4436
|
+
var s = r >> 4;
|
|
4437
|
+
if (s < 16) ldt[i++] = s;
|
|
4438
|
+
else {
|
|
4439
|
+
var c = 0, n = 0;
|
|
4440
|
+
if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
|
|
4441
|
+
else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;
|
|
4442
|
+
else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7;
|
|
4443
|
+
while (n--) ldt[i++] = c;
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4446
|
+
var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
4447
|
+
lbt = max(lt);
|
|
4448
|
+
dbt = max(dt);
|
|
4449
|
+
lm = hMap(lt, lbt, 1);
|
|
4450
|
+
dm = hMap(dt, dbt, 1);
|
|
4451
|
+
} else err(1);
|
|
4452
|
+
if (pos > tbts) {
|
|
4453
|
+
if (noSt) err(0);
|
|
4454
|
+
break;
|
|
4455
|
+
}
|
|
4456
|
+
}
|
|
4457
|
+
if (resize) cbuf(bt + 131072);
|
|
4458
|
+
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
4459
|
+
var lpos = pos;
|
|
4460
|
+
for (;; lpos = pos) {
|
|
4461
|
+
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
4462
|
+
pos += c & 15;
|
|
4463
|
+
if (pos > tbts) {
|
|
4464
|
+
if (noSt) err(0);
|
|
4465
|
+
break;
|
|
4466
|
+
}
|
|
4467
|
+
if (!c) err(2);
|
|
4468
|
+
if (sym < 256) buf[bt++] = sym;
|
|
4469
|
+
else if (sym == 256) {
|
|
4470
|
+
lpos = pos, lm = null;
|
|
4471
|
+
break;
|
|
4472
|
+
} else {
|
|
4473
|
+
var add = sym - 254;
|
|
4474
|
+
if (sym > 264) {
|
|
4475
|
+
var i = sym - 257, b = fleb[i];
|
|
4476
|
+
add = bits(dat, pos, (1 << b) - 1) + fl[i];
|
|
4477
|
+
pos += b;
|
|
4478
|
+
}
|
|
4479
|
+
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
4480
|
+
if (!d) err(3);
|
|
4481
|
+
pos += d & 15;
|
|
4482
|
+
var dt = fd[dsym];
|
|
4483
|
+
if (dsym > 3) {
|
|
4484
|
+
var b = fdeb[dsym];
|
|
4485
|
+
dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
|
|
4486
|
+
}
|
|
4487
|
+
if (pos > tbts) {
|
|
4488
|
+
if (noSt) err(0);
|
|
4489
|
+
break;
|
|
4490
|
+
}
|
|
4491
|
+
if (resize) cbuf(bt + 131072);
|
|
4492
|
+
var end = bt + add;
|
|
4493
|
+
if (bt < dt) {
|
|
4494
|
+
var shift = dl - dt, dend = Math.min(dt, end);
|
|
4495
|
+
if (shift + bt < 0) err(3);
|
|
4496
|
+
for (; bt < dend; ++bt) buf[bt] = dict[shift + bt];
|
|
4497
|
+
}
|
|
4498
|
+
for (; bt < end; ++bt) buf[bt] = buf[bt - dt];
|
|
4499
|
+
}
|
|
4500
|
+
}
|
|
4501
|
+
st.l = lm, st.p = lpos, st.b = bt, st.f = final;
|
|
4502
|
+
if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
|
4503
|
+
} while (!final);
|
|
4504
|
+
return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
|
|
4505
|
+
};
|
|
4506
|
+
var et = /* @__PURE__ */ new u8(0);
|
|
4507
|
+
var b2 = function(d, b) {
|
|
4508
|
+
return d[b] | d[b + 1] << 8;
|
|
4509
|
+
};
|
|
4510
|
+
var b4 = function(d, b) {
|
|
4511
|
+
return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;
|
|
4512
|
+
};
|
|
4513
|
+
var b8 = function(d, b) {
|
|
4514
|
+
return b4(d, b) + b4(d, b + 4) * 4294967296;
|
|
4515
|
+
};
|
|
4516
|
+
/**
|
|
4517
|
+
* Expands DEFLATE data with no wrapper
|
|
4518
|
+
* @param data The data to decompress
|
|
4519
|
+
* @param opts The decompression options
|
|
4520
|
+
* @returns The decompressed version of the data
|
|
4521
|
+
*/
|
|
4522
|
+
function inflateSync(data, opts) {
|
|
4523
|
+
return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);
|
|
4524
|
+
}
|
|
4525
|
+
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
4526
|
+
var tds = 0;
|
|
4527
|
+
try {
|
|
4528
|
+
td.decode(et, { stream: true });
|
|
4529
|
+
tds = 1;
|
|
4530
|
+
} catch (e) {}
|
|
4531
|
+
var dutf8 = function(d) {
|
|
4532
|
+
for (var r = "", i = 0;;) {
|
|
4533
|
+
var c = d[i++];
|
|
4534
|
+
var eb = (c > 127) + (c > 223) + (c > 239);
|
|
4535
|
+
if (i + eb > d.length) return {
|
|
4536
|
+
s: r,
|
|
4537
|
+
r: slc(d, i - 1)
|
|
4538
|
+
};
|
|
4539
|
+
if (!eb) r += String.fromCharCode(c);
|
|
4540
|
+
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);
|
|
4541
|
+
else if (eb & 1) r += String.fromCharCode((c & 31) << 6 | d[i++] & 63);
|
|
4542
|
+
else r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | d[i++] & 63);
|
|
4543
|
+
}
|
|
4544
|
+
};
|
|
4545
|
+
/**
|
|
4546
|
+
* Converts a Uint8Array to a string
|
|
4547
|
+
* @param dat The data to decode to string
|
|
4548
|
+
* @param latin1 Whether or not to interpret the data as Latin-1. This should
|
|
4549
|
+
* not need to be true unless encoding to binary string.
|
|
4550
|
+
* @returns The original UTF-8/Latin-1 string
|
|
4551
|
+
*/
|
|
4552
|
+
function strFromU8(dat, latin1) {
|
|
4553
|
+
if (latin1) {
|
|
4554
|
+
var r = "";
|
|
4555
|
+
for (var i = 0; i < dat.length; i += 16384) r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));
|
|
4556
|
+
return r;
|
|
4557
|
+
} else if (td) return td.decode(dat);
|
|
4558
|
+
else {
|
|
4559
|
+
var _a = dutf8(dat), s = _a.s, r = _a.r;
|
|
4560
|
+
if (r.length) err(8);
|
|
4561
|
+
return s;
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4564
|
+
var slzh = function(d, b) {
|
|
4565
|
+
return b + 30 + b2(d, b + 26) + b2(d, b + 28);
|
|
4566
|
+
};
|
|
4567
|
+
var zh = function(d, b, z) {
|
|
4568
|
+
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);
|
|
4569
|
+
var _a = z && bs == 4294967295 ? z64e(d, es) : [
|
|
4570
|
+
bs,
|
|
4571
|
+
b4(d, b + 24),
|
|
4572
|
+
b4(d, b + 42)
|
|
4573
|
+
], sc = _a[0], su = _a[1], off = _a[2];
|
|
4574
|
+
return [
|
|
4575
|
+
b2(d, b + 10),
|
|
4576
|
+
sc,
|
|
4577
|
+
su,
|
|
4578
|
+
fn,
|
|
4579
|
+
es + b2(d, b + 30) + b2(d, b + 32),
|
|
4580
|
+
off
|
|
4581
|
+
];
|
|
4582
|
+
};
|
|
4583
|
+
var z64e = function(d, b) {
|
|
4584
|
+
for (; b2(d, b) != 1; b += 4 + b2(d, b + 2));
|
|
4585
|
+
return [
|
|
4586
|
+
b8(d, b + 12),
|
|
4587
|
+
b8(d, b + 4),
|
|
4588
|
+
b8(d, b + 20)
|
|
4589
|
+
];
|
|
4590
|
+
};
|
|
4591
|
+
/**
|
|
4592
|
+
* Synchronously decompresses a ZIP archive. Prefer using `unzip` for better
|
|
4593
|
+
* performance with more than one file.
|
|
4594
|
+
* @param data The raw compressed ZIP file
|
|
4595
|
+
* @param opts The ZIP extraction options
|
|
4596
|
+
* @returns The decompressed files
|
|
4597
|
+
*/
|
|
4598
|
+
function unzipSync(data, opts) {
|
|
4599
|
+
var files = {};
|
|
4600
|
+
var e = data.length - 22;
|
|
4601
|
+
for (; b4(data, e) != 101010256; --e) if (!e || data.length - e > 65558) err(13);
|
|
4602
|
+
var c = b2(data, e + 8);
|
|
4603
|
+
if (!c) return {};
|
|
4604
|
+
var o = b4(data, e + 16);
|
|
4605
|
+
var z = o == 4294967295 || c == 65535;
|
|
4606
|
+
if (z) {
|
|
4607
|
+
var ze = b4(data, e - 12);
|
|
4608
|
+
z = b4(data, ze) == 101075792;
|
|
4609
|
+
if (z) {
|
|
4610
|
+
c = b4(data, ze + 32);
|
|
4611
|
+
o = b4(data, ze + 48);
|
|
4612
|
+
}
|
|
4613
|
+
}
|
|
4614
|
+
var fltr = opts && opts.filter;
|
|
4615
|
+
for (var i = 0; i < c; ++i) {
|
|
4616
|
+
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);
|
|
4617
|
+
o = no;
|
|
4618
|
+
if (!fltr || fltr({
|
|
4619
|
+
name: fn,
|
|
4620
|
+
size: sc,
|
|
4621
|
+
originalSize: su,
|
|
4622
|
+
compression: c_2
|
|
4623
|
+
})) if (!c_2) files[fn] = slc(data, b, b + sc);
|
|
4624
|
+
else if (c_2 == 8) files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });
|
|
4625
|
+
else err(14, "unknown compression type " + c_2);
|
|
4626
|
+
}
|
|
4627
|
+
return files;
|
|
4628
|
+
}
|
|
4629
|
+
|
|
4630
|
+
//#endregion
|
|
4631
|
+
//#region src/overlays/data/Kmz.tsx
|
|
4632
|
+
function buildKmzEventBindings(props) {
|
|
4633
|
+
return [
|
|
4634
|
+
{
|
|
4635
|
+
eventName: "addfeature",
|
|
4636
|
+
invoke: props.onAddFeature ? (event) => props.onAddFeature?.(event) : void 0
|
|
4637
|
+
},
|
|
4638
|
+
{
|
|
4639
|
+
eventName: "removefeature",
|
|
4640
|
+
invoke: props.onRemoveFeature ? (event) => props.onRemoveFeature?.(event) : void 0
|
|
4641
|
+
},
|
|
4642
|
+
{
|
|
4643
|
+
eventName: "property_changed",
|
|
4644
|
+
invoke: props.onPropertyChanged ? (event) => props.onPropertyChanged?.(event) : void 0
|
|
4645
|
+
},
|
|
4646
|
+
{
|
|
4647
|
+
eventName: "click",
|
|
4648
|
+
invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
|
|
4649
|
+
},
|
|
4650
|
+
{
|
|
4651
|
+
eventName: "dblclick",
|
|
4652
|
+
invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
|
|
4653
|
+
},
|
|
4654
|
+
{
|
|
4655
|
+
eventName: "rightclick",
|
|
4656
|
+
invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
|
|
4657
|
+
},
|
|
4658
|
+
{
|
|
4659
|
+
eventName: "mousedown",
|
|
4660
|
+
invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
|
|
4661
|
+
},
|
|
4662
|
+
{
|
|
4663
|
+
eventName: "mouseup",
|
|
4664
|
+
invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
|
|
4665
|
+
},
|
|
4666
|
+
{
|
|
4667
|
+
eventName: "mouseover",
|
|
4668
|
+
invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
|
|
4669
|
+
},
|
|
4670
|
+
{
|
|
4671
|
+
eventName: "mouseout",
|
|
4672
|
+
invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
|
|
4673
|
+
}
|
|
4674
|
+
];
|
|
4675
|
+
}
|
|
4676
|
+
function extractKmlFromKmz(arrayBuffer) {
|
|
4677
|
+
const files = unzipSync(new Uint8Array(arrayBuffer));
|
|
4678
|
+
const kmlFileName = Object.keys(files).find((name) => name.endsWith(".kml") || name === "doc.kml");
|
|
4679
|
+
if (!kmlFileName) throw new Error("No KML file found in KMZ archive.");
|
|
4680
|
+
const kmlBytes = files[kmlFileName];
|
|
4681
|
+
const kmlString = new TextDecoder("utf-8").decode(kmlBytes);
|
|
4682
|
+
const doc = new DOMParser().parseFromString(kmlString, "application/xml");
|
|
4683
|
+
const parseError = doc.querySelector("parsererror");
|
|
4684
|
+
if (parseError) throw new Error(`KML parse error: ${parseError.textContent}`);
|
|
4685
|
+
return doc;
|
|
4686
|
+
}
|
|
4687
|
+
const Kmz = (0, react.forwardRef)(function KmzInner(props, ref) {
|
|
4688
|
+
const { map: contextMap, sdkStatus } = useNaverMap();
|
|
4689
|
+
const dataRef = (0, react.useRef)(null);
|
|
4690
|
+
const dataEventListenersRef = (0, react.useRef)([]);
|
|
4691
|
+
const onDataDestroyRef = (0, react.useRef)(props.onDataDestroy);
|
|
4692
|
+
const prevUrlRef = (0, react.useRef)(null);
|
|
4693
|
+
const abortRef = (0, react.useRef)(null);
|
|
4694
|
+
(0, react.useEffect)(() => {
|
|
4695
|
+
onDataDestroyRef.current = props.onDataDestroy;
|
|
4696
|
+
}, [props.onDataDestroy]);
|
|
4697
|
+
const invokeDataMethod = (0, react.useCallback)((methodName, ...args) => {
|
|
4698
|
+
const data = dataRef.current;
|
|
4699
|
+
if (!data) return;
|
|
4700
|
+
const method = data[methodName];
|
|
4701
|
+
if (typeof method !== "function") return;
|
|
4702
|
+
return method.apply(data, args);
|
|
4703
|
+
}, []);
|
|
4704
|
+
const teardownData = (0, react.useCallback)(() => {
|
|
4705
|
+
abortRef.current?.abort();
|
|
4706
|
+
abortRef.current = null;
|
|
4707
|
+
const data = dataRef.current;
|
|
4708
|
+
if (!data) return;
|
|
4709
|
+
try {
|
|
4710
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4711
|
+
dataEventListenersRef.current = [];
|
|
4712
|
+
naver.maps.Event.clearInstanceListeners(data);
|
|
4713
|
+
} catch (error) {
|
|
4714
|
+
console.error("[react-naver-maps-kit] failed to clear KMZ data layer listeners", error);
|
|
4715
|
+
}
|
|
4716
|
+
data.setMap(null);
|
|
4717
|
+
dataRef.current = null;
|
|
4718
|
+
prevUrlRef.current = null;
|
|
4719
|
+
onDataDestroyRef.current?.();
|
|
4720
|
+
}, []);
|
|
4721
|
+
(0, react.useImperativeHandle)(ref, () => ({
|
|
4722
|
+
getInstance: () => dataRef.current,
|
|
4723
|
+
getAllFeature: (...args) => invokeDataMethod("getAllFeature", ...args),
|
|
4724
|
+
getFeatureById: (...args) => invokeDataMethod("getFeatureById", ...args),
|
|
4725
|
+
getMap: (...args) => invokeDataMethod("getMap", ...args),
|
|
4726
|
+
getStyle: (...args) => invokeDataMethod("getStyle", ...args),
|
|
4727
|
+
overrideStyle: (...args) => invokeDataMethod("overrideStyle", ...args),
|
|
4728
|
+
removeFeature: (...args) => invokeDataMethod("removeFeature", ...args),
|
|
4729
|
+
revertStyle: (...args) => invokeDataMethod("revertStyle", ...args),
|
|
4730
|
+
setStyle: (...args) => invokeDataMethod("setStyle", ...args),
|
|
4731
|
+
toGeoJson: (...args) => invokeDataMethod("toGeoJson", ...args)
|
|
4732
|
+
}), [invokeDataMethod]);
|
|
4733
|
+
const loadAndAddKmz = (0, react.useCallback)(async (data, url, isInitial) => {
|
|
4734
|
+
const controller = new AbortController();
|
|
4735
|
+
abortRef.current = controller;
|
|
4736
|
+
try {
|
|
4737
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
4738
|
+
if (!response.ok) throw new Error(`Failed to fetch KMZ: ${response.status} ${response.statusText}`);
|
|
4739
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
4740
|
+
if (controller.signal.aborted) return;
|
|
4741
|
+
const kmlDoc = extractKmlFromKmz(arrayBuffer);
|
|
4742
|
+
if (!isInitial) data.getAllFeature().forEach((feature) => data.removeFeature(feature));
|
|
4743
|
+
const features = data.addKml(kmlDoc, props.autoStyle ?? true);
|
|
4744
|
+
prevUrlRef.current = url;
|
|
4745
|
+
props.onFeaturesAdded?.(features);
|
|
4746
|
+
} catch (error) {
|
|
4747
|
+
if (controller.signal.aborted) return;
|
|
4748
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to load KMZ data.");
|
|
4749
|
+
props.onDataError?.(normalizedError);
|
|
4750
|
+
}
|
|
4751
|
+
}, [
|
|
4752
|
+
props.autoStyle,
|
|
4753
|
+
props.onFeaturesAdded,
|
|
4754
|
+
props.onDataError
|
|
4755
|
+
]);
|
|
4756
|
+
(0, react.useEffect)(() => {
|
|
4757
|
+
if (sdkStatus !== "ready" || !contextMap || dataRef.current) return;
|
|
4758
|
+
try {
|
|
4759
|
+
const data = new naver.maps.Data();
|
|
4760
|
+
data.setMap(contextMap);
|
|
4761
|
+
if (props.style) data.setStyle(props.style);
|
|
4762
|
+
dataRef.current = data;
|
|
4763
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildKmzEventBindings(props));
|
|
4764
|
+
props.onDataReady?.(data);
|
|
4765
|
+
loadAndAddKmz(data, props.url, true);
|
|
4766
|
+
} catch (error) {
|
|
4767
|
+
const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Data instance.");
|
|
4768
|
+
props.onDataError?.(normalizedError);
|
|
4769
|
+
}
|
|
4770
|
+
}, [sdkStatus, contextMap]);
|
|
4771
|
+
(0, react.useEffect)(() => {
|
|
4772
|
+
const data = dataRef.current;
|
|
4773
|
+
if (!data || props.url === prevUrlRef.current) return;
|
|
4774
|
+
abortRef.current?.abort();
|
|
4775
|
+
loadAndAddKmz(data, props.url, false);
|
|
4776
|
+
}, [props.url, loadAndAddKmz]);
|
|
4777
|
+
(0, react.useEffect)(() => {
|
|
4778
|
+
const data = dataRef.current;
|
|
4779
|
+
if (!data) return;
|
|
4780
|
+
if (props.style) data.setStyle(props.style);
|
|
4781
|
+
}, [props.style]);
|
|
4782
|
+
(0, react.useEffect)(() => {
|
|
4783
|
+
const data = dataRef.current;
|
|
4784
|
+
if (!data) return;
|
|
4785
|
+
bindOverlayEventListeners(data, dataEventListenersRef, buildKmzEventBindings(props));
|
|
4786
|
+
return () => {
|
|
4787
|
+
removeOverlayEventListeners(dataEventListenersRef.current);
|
|
4788
|
+
dataEventListenersRef.current = [];
|
|
4789
|
+
};
|
|
4790
|
+
}, [props]);
|
|
4791
|
+
(0, react.useEffect)(() => {
|
|
4792
|
+
return () => {
|
|
4793
|
+
teardownData();
|
|
4794
|
+
};
|
|
4795
|
+
}, [teardownData]);
|
|
4796
|
+
return null;
|
|
4797
|
+
});
|
|
4798
|
+
Kmz.displayName = "Kmz";
|
|
4799
|
+
|
|
3963
4800
|
//#endregion
|
|
3964
4801
|
//#region src/index.ts
|
|
3965
|
-
const version = "
|
|
4802
|
+
const version = "1.2.0";
|
|
3966
4803
|
|
|
3967
4804
|
//#endregion
|
|
3968
4805
|
exports.Circle = Circle;
|
|
3969
4806
|
exports.ClustererContext = ClustererContext;
|
|
3970
4807
|
exports.Ellipse = Ellipse;
|
|
4808
|
+
exports.GeoJson = GeoJson;
|
|
4809
|
+
exports.Gpx = Gpx;
|
|
3971
4810
|
exports.GroundOverlay = GroundOverlay;
|
|
3972
4811
|
exports.InfoWindow = InfoWindow;
|
|
4812
|
+
exports.Kmz = Kmz;
|
|
3973
4813
|
exports.Marker = Marker;
|
|
3974
4814
|
exports.MarkerClusterer = MarkerClusterer;
|
|
3975
4815
|
exports.NaverMap = NaverMap;
|