react-naver-maps-kit 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +64 -137
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +66 -139
- package/dist/index.js.map +1 -1
- 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 +1 -0
- package/dist/react/components/NaverMap.d.ts.map +1 -1
- package/package.json +12 -14
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,6 @@ 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 react_dom_client = require("react-dom/client");
|
|
6
5
|
|
|
7
6
|
//#region src/core/loader/loadNaverMapsScript.ts
|
|
8
7
|
const NAVER_MAPS_SCRIPT_BASE_URL = "https://oapi.map.naver.com/openapi/v3/maps.js";
|
|
@@ -876,15 +875,23 @@ function useNaverMapInstance(options = {}) {
|
|
|
876
875
|
//#endregion
|
|
877
876
|
//#region src/overlays/marker-clusterer/ClustererContext.ts
|
|
878
877
|
/**
|
|
879
|
-
* `<MarkerClusterer>`가 제공하는
|
|
878
|
+
* `<MarkerClusterer>`가 제공하는 registry Context.
|
|
879
|
+
* register/unregister/enabled만 포함하며, enabled가 바뀔 때만 갱신됩니다.
|
|
880
880
|
*
|
|
881
|
-
*
|
|
882
|
-
* `null`이면 클러스터러 밖에 있는 것이므로 일반 마커로 동작합니다.
|
|
883
|
-
*
|
|
884
|
-
* @internal 라이브러리 내부 전용. 직접 사용하지 마세요.
|
|
881
|
+
* @internal
|
|
885
882
|
*/
|
|
886
883
|
const ClustererContext = (0, react.createContext)(null);
|
|
887
884
|
ClustererContext.displayName = "ClustererContext";
|
|
885
|
+
/**
|
|
886
|
+
* `<MarkerClusterer>`가 제공하는 visibility Context.
|
|
887
|
+
* 재계산 시마다 갱신되며, 클러스터링 안 된 마커 ID 집합을 담습니다.
|
|
888
|
+
*
|
|
889
|
+
* `<Marker>`는 이 context를 읽어 자신이 보여야 할지 판단합니다.
|
|
890
|
+
*
|
|
891
|
+
* @internal
|
|
892
|
+
*/
|
|
893
|
+
const ClustererVisibilityContext = (0, react.createContext)(/* @__PURE__ */ new Set());
|
|
894
|
+
ClustererVisibilityContext.displayName = "ClustererVisibilityContext";
|
|
888
895
|
|
|
889
896
|
//#endregion
|
|
890
897
|
//#region src/overlays/marker/Marker.tsx
|
|
@@ -1036,11 +1043,15 @@ function toLatLngLiteral(position) {
|
|
|
1036
1043
|
const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
1037
1044
|
const { map: contextMap, sdkStatus } = useNaverMap();
|
|
1038
1045
|
const clustererRegistry = (0, react.useContext)(ClustererContext);
|
|
1046
|
+
const visibleIds = (0, react.useContext)(ClustererVisibilityContext);
|
|
1039
1047
|
const isInsideClusterer = clustererRegistry !== null && clustererRegistry.enabled;
|
|
1048
|
+
const autoId = (0, react.useId)();
|
|
1049
|
+
const effectiveId = props.clustererItemId ?? autoId;
|
|
1050
|
+
const isHiddenByClusterer = isInsideClusterer && !visibleIds.has(effectiveId);
|
|
1040
1051
|
const markerRef = (0, react.useRef)(null);
|
|
1041
1052
|
const markerEventListenersRef = (0, react.useRef)([]);
|
|
1042
1053
|
const onMarkerDestroyRef = (0, react.useRef)(props.onMarkerDestroy);
|
|
1043
|
-
const [markerDiv
|
|
1054
|
+
const [markerDiv] = (0, react.useState)(() => document.createElement("div"));
|
|
1044
1055
|
const [portalReady, setPortalReady] = (0, react.useState)(false);
|
|
1045
1056
|
const hasChildren = props.children !== void 0 && props.children !== null;
|
|
1046
1057
|
const targetMap = props.map ?? contextMap;
|
|
@@ -1050,8 +1061,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1050
1061
|
});
|
|
1051
1062
|
(0, react.useEffect)(() => {
|
|
1052
1063
|
if (!clustererRegistry) return;
|
|
1053
|
-
const id = props.clustererItemId;
|
|
1054
|
-
if (id === void 0 || id === null) return;
|
|
1064
|
+
const id = props.clustererItemId ?? autoId;
|
|
1055
1065
|
const latLng = toLatLngLiteral(props.position);
|
|
1056
1066
|
if (!latLng) return;
|
|
1057
1067
|
clustererRegistry.register({
|
|
@@ -1064,6 +1074,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1064
1074
|
clustererRegistry.unregister(id);
|
|
1065
1075
|
};
|
|
1066
1076
|
}, [
|
|
1077
|
+
autoId,
|
|
1067
1078
|
clustererRegistry,
|
|
1068
1079
|
props.clustererItemId,
|
|
1069
1080
|
props.position,
|
|
@@ -1071,17 +1082,10 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1071
1082
|
props.icon
|
|
1072
1083
|
]);
|
|
1073
1084
|
(0, react.useEffect)(() => {
|
|
1074
|
-
if (isInsideClusterer) return;
|
|
1075
1085
|
onMarkerDestroyRef.current = props.onMarkerDestroy;
|
|
1076
|
-
}, [
|
|
1077
|
-
(0, react.useEffect)(() => {
|
|
1078
|
-
if (isInsideClusterer) return;
|
|
1079
|
-
if (typeof document === "undefined") return;
|
|
1080
|
-
setMarkerDiv(document.createElement("div"));
|
|
1081
|
-
}, [isInsideClusterer]);
|
|
1086
|
+
}, [props.onMarkerDestroy]);
|
|
1082
1087
|
(0, react.useEffect)(() => {
|
|
1083
|
-
if (
|
|
1084
|
-
if (!hasChildren || !markerDiv) {
|
|
1088
|
+
if (!hasChildren) {
|
|
1085
1089
|
setPortalReady(false);
|
|
1086
1090
|
return;
|
|
1087
1091
|
}
|
|
@@ -1097,11 +1101,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1097
1101
|
return () => {
|
|
1098
1102
|
observer.disconnect();
|
|
1099
1103
|
};
|
|
1100
|
-
}, [
|
|
1101
|
-
isInsideClusterer,
|
|
1102
|
-
hasChildren,
|
|
1103
|
-
markerDiv
|
|
1104
|
-
]);
|
|
1104
|
+
}, [hasChildren, markerDiv]);
|
|
1105
1105
|
const invokeMarkerMethod = (0, react.useCallback)((methodName, ...args) => {
|
|
1106
1106
|
const marker = markerRef.current;
|
|
1107
1107
|
if (!marker) return;
|
|
@@ -1157,7 +1157,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1157
1157
|
setZIndex: (...args) => invokeMarkerMethod("setZIndex", ...args)
|
|
1158
1158
|
}), [invokeMarkerMethod]);
|
|
1159
1159
|
(0, react.useEffect)(() => {
|
|
1160
|
-
if (
|
|
1160
|
+
if (isHiddenByClusterer) return;
|
|
1161
1161
|
if (sdkStatus !== "ready" || !targetMap || markerRef.current) return;
|
|
1162
1162
|
if (hasChildren && !portalReady) return;
|
|
1163
1163
|
try {
|
|
@@ -1173,7 +1173,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1173
1173
|
propsRef.current.onMarkerError?.(normalizedError);
|
|
1174
1174
|
}
|
|
1175
1175
|
}, [
|
|
1176
|
-
|
|
1176
|
+
isHiddenByClusterer,
|
|
1177
1177
|
hasChildren,
|
|
1178
1178
|
markerDiv,
|
|
1179
1179
|
portalReady,
|
|
@@ -1181,7 +1181,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1181
1181
|
targetMap
|
|
1182
1182
|
]);
|
|
1183
1183
|
(0, react.useLayoutEffect)(() => {
|
|
1184
|
-
if (
|
|
1184
|
+
if (isHiddenByClusterer) return;
|
|
1185
1185
|
const marker = markerRef.current;
|
|
1186
1186
|
if (!marker || !targetMap) return;
|
|
1187
1187
|
const rafId = requestAnimationFrame(() => {
|
|
@@ -1195,7 +1195,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1195
1195
|
cancelAnimationFrame(rafId);
|
|
1196
1196
|
};
|
|
1197
1197
|
}, [
|
|
1198
|
-
|
|
1198
|
+
isHiddenByClusterer,
|
|
1199
1199
|
hasChildren,
|
|
1200
1200
|
markerDiv,
|
|
1201
1201
|
portalReady,
|
|
@@ -1214,7 +1214,7 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1214
1214
|
props.collisionBoxSize
|
|
1215
1215
|
]);
|
|
1216
1216
|
(0, react.useEffect)(() => {
|
|
1217
|
-
if (
|
|
1217
|
+
if (isHiddenByClusterer) return;
|
|
1218
1218
|
const marker = markerRef.current;
|
|
1219
1219
|
if (!marker) return;
|
|
1220
1220
|
bindMarkerEventListeners(marker, markerEventListenersRef, buildMarkerEventBindings(propsRef));
|
|
@@ -1224,14 +1224,14 @@ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
|
|
|
1224
1224
|
markerEventListenersRef.current = [];
|
|
1225
1225
|
}
|
|
1226
1226
|
};
|
|
1227
|
-
}, [
|
|
1227
|
+
}, [isHiddenByClusterer]);
|
|
1228
1228
|
(0, react.useEffect)(() => {
|
|
1229
|
-
if (
|
|
1229
|
+
if (isHiddenByClusterer) return;
|
|
1230
1230
|
return () => {
|
|
1231
1231
|
teardownMarker();
|
|
1232
1232
|
};
|
|
1233
|
-
}, [
|
|
1234
|
-
if (
|
|
1233
|
+
}, [isHiddenByClusterer, teardownMarker]);
|
|
1234
|
+
if (isHiddenByClusterer) return null;
|
|
1235
1235
|
if (!hasChildren || !markerDiv) return null;
|
|
1236
1236
|
return (0, react_dom.createPortal)(props.children, markerDiv);
|
|
1237
1237
|
});
|
|
@@ -2225,7 +2225,8 @@ function padBounds(bounds, padding) {
|
|
|
2225
2225
|
* 내부 registry에 위치·데이터를 등록합니다.
|
|
2226
2226
|
* 2. `MarkerClusterer`는 지도 이벤트(`idle`, `move`, `zoom`) 발생 시
|
|
2227
2227
|
* 현재 줌·뷰포트 기준으로 클러스터를 재계산합니다.
|
|
2228
|
-
* 3. 클러스터 마커는
|
|
2228
|
+
* 3. 클러스터 마커는 `<Marker>` JSX로 렌더링되며, children으로 클러스터 아이콘이 전달됩니다.
|
|
2229
|
+
* 4. 클러스터에 포함되지 않은 단독 포인트는 원래 `<Marker>` children을 그대로 표시합니다.
|
|
2229
2230
|
*
|
|
2230
2231
|
* ## 기본 사용법
|
|
2231
2232
|
*
|
|
@@ -2241,10 +2242,11 @@ function padBounds(bounds, padding) {
|
|
|
2241
2242
|
* {points.map(p => (
|
|
2242
2243
|
* <Marker
|
|
2243
2244
|
* key={p.id}
|
|
2244
|
-
* clustererItemId={p.id}
|
|
2245
2245
|
* position={p.position}
|
|
2246
2246
|
* item={p}
|
|
2247
|
-
*
|
|
2247
|
+
* >
|
|
2248
|
+
* <CustomPin />
|
|
2249
|
+
* </Marker>
|
|
2248
2250
|
* ))}
|
|
2249
2251
|
* </MarkerClusterer>
|
|
2250
2252
|
* </NaverMap>
|
|
@@ -2252,7 +2254,6 @@ function padBounds(bounds, padding) {
|
|
|
2252
2254
|
*
|
|
2253
2255
|
* ## 주의 사항
|
|
2254
2256
|
*
|
|
2255
|
-
* - `<Marker>`에 반드시 `clustererItemId` prop을 지정해야 합니다.
|
|
2256
2257
|
* - `<MarkerClusterer>`는 반드시 `<NaverMap>` 내부에 위치해야 합니다.
|
|
2257
2258
|
* - `enabled={false}`로 설정하면 클러스터링이 해제되고 각 `<Marker>`가 개별 마커로 렌더링됩니다.
|
|
2258
2259
|
*
|
|
@@ -2291,10 +2292,8 @@ function MarkerClusterer(props) {
|
|
|
2291
2292
|
if (prev && prev !== algorithm) prev.destroy?.();
|
|
2292
2293
|
};
|
|
2293
2294
|
}, [algorithm]);
|
|
2294
|
-
const
|
|
2295
|
-
const
|
|
2296
|
-
const clusterIconRootsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
2297
|
-
const clusterIconContainersRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
2295
|
+
const [clusters, setClusters] = (0, react.useState)([]);
|
|
2296
|
+
const [visibleIds, setVisibleIds] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
2298
2297
|
const helpersRef = (0, react.useRef)({
|
|
2299
2298
|
zoomToCluster: () => {},
|
|
2300
2299
|
fitBounds: () => {}
|
|
@@ -2327,94 +2326,22 @@ function MarkerClusterer(props) {
|
|
|
2327
2326
|
(0, react.useEffect)(() => {
|
|
2328
2327
|
onClusterClickRef.current = onClusterClick;
|
|
2329
2328
|
}, [onClusterClick]);
|
|
2330
|
-
const clusterIconRef = (0, react.useRef)(clusterIcon);
|
|
2331
|
-
(0, react.useEffect)(() => {
|
|
2332
|
-
clusterIconRef.current = clusterIcon;
|
|
2333
|
-
}, [clusterIcon]);
|
|
2334
2329
|
const recompute = (0, react.useCallback)(() => {
|
|
2335
2330
|
if (!map || sdkStatus !== "ready" || !enabled) return;
|
|
2336
2331
|
const zoom = map.getZoom();
|
|
2337
2332
|
const bounds = getMapBounds(map);
|
|
2338
2333
|
const items = Array.from(registryRef.current.values());
|
|
2339
|
-
const { clusters, points } = algorithm.cluster(items, {
|
|
2334
|
+
const { clusters: rawClusters, points } = algorithm.cluster(items, {
|
|
2340
2335
|
zoom,
|
|
2341
2336
|
bounds
|
|
2342
2337
|
});
|
|
2343
2338
|
const maxItems = clusterData?.maxItemsInCluster;
|
|
2344
2339
|
const includeItems = clusterData?.includeItems ?? true;
|
|
2345
|
-
|
|
2340
|
+
setClusters(rawClusters.map((c) => ({
|
|
2346
2341
|
...c,
|
|
2347
2342
|
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
|
-
}
|
|
2343
|
+
})));
|
|
2344
|
+
setVisibleIds(new Set(points.map((p) => p.id)));
|
|
2418
2345
|
}, [
|
|
2419
2346
|
map,
|
|
2420
2347
|
sdkStatus,
|
|
@@ -2455,31 +2382,31 @@ function MarkerClusterer(props) {
|
|
|
2455
2382
|
behavior?.debounceMs,
|
|
2456
2383
|
recompute
|
|
2457
2384
|
]);
|
|
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
2385
|
(0, react.useEffect)(() => {
|
|
2470
2386
|
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();
|
|
2387
|
+
setClusters([]);
|
|
2388
|
+
setVisibleIds(/* @__PURE__ */ new Set());
|
|
2478
2389
|
}, [enabled]);
|
|
2479
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClustererContext.Provider, {
|
|
2390
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClustererContext.Provider, {
|
|
2480
2391
|
value: registry,
|
|
2481
|
-
children
|
|
2482
|
-
|
|
2392
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClustererVisibilityContext.Provider, {
|
|
2393
|
+
value: visibleIds,
|
|
2394
|
+
children
|
|
2395
|
+
})
|
|
2396
|
+
}), enabled && clusters.map((cluster) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Marker, {
|
|
2397
|
+
position: cluster.position,
|
|
2398
|
+
clickable: true,
|
|
2399
|
+
onClick: () => {
|
|
2400
|
+
onClusterClickRef.current?.({
|
|
2401
|
+
cluster,
|
|
2402
|
+
helpers: helpersRef.current
|
|
2403
|
+
});
|
|
2404
|
+
},
|
|
2405
|
+
children: clusterIcon ? clusterIcon({
|
|
2406
|
+
cluster,
|
|
2407
|
+
count: cluster.count
|
|
2408
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultClusterIcon, { count: cluster.count })
|
|
2409
|
+
}, cluster.id))] });
|
|
2483
2410
|
}
|
|
2484
2411
|
MarkerClusterer.displayName = "MarkerClusterer";
|
|
2485
2412
|
|