@orioro/react-maplibre-util 0.8.1 → 0.9.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/CHANGELOG.md +12 -0
- package/dist/LayeredMap/index.d.ts +1 -1
- package/dist/LayeredMap/layeredMapMouseEventHandler.d.ts +24 -0
- package/dist/LayeredMap/parseMapViews.d.ts +1 -0
- package/dist/Source/Source.d.ts +14 -0
- package/dist/Source/index.d.ts +1 -0
- package/dist/StorybookUtil/DebugMap.d.ts +9 -0
- package/dist/StorybookUtil/DebugPanel.d.ts +11 -0
- package/dist/StorybookUtil/index.d.ts +2 -0
- package/dist/h3/hexRegistry.d.ts +21 -0
- package/dist/h3/index.d.ts +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +372 -264
- package/dist/tmp_h3/H3HexSource/H3HexSource.d.ts +90 -0
- package/dist/tmp_h3/H3HexSource/H3HexSource.stories_.d.ts +11 -0
- package/dist/types.d.ts +1 -0
- package/dist/useFeatureState/index.d.ts +1 -0
- package/dist/useFeatureState/useFeatureState.d.ts +17 -0
- package/dist/useHover/index.d.ts +0 -1
- package/dist/util/getLayerRemountKey.d.ts +16 -0
- package/dist/util/getSourceRemountKey.d.ts +5 -0
- package/dist/util/index.d.ts +2 -0
- package/package.json +3 -1
- package/dist/LayeredMap/layeredMapOnClickHandler.d.ts +0 -17
- package/dist/useHover/withHover.d.ts +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @orioro/react-maplibre-util
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 793bce0: add support for non-reactive <Source /> and <Layer /> props through force-remount via `key` prop
|
|
8
|
+
- d8d6b68: implement feature-state handling on <Source /> component and expose memoizee options on makeMemoFetch
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies [d8d6b68]
|
|
13
|
+
- @orioro/vector-tile-util@0.4.0
|
|
14
|
+
|
|
3
15
|
## 0.8.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { MapGeoJSONFeature, MapMouseEvent } from 'maplibre-gl';
|
|
2
|
+
import { Merge } from 'type-fest';
|
|
3
|
+
type MouseEventHandlerFn = (feature: MapGeoJSONFeature, event: AugmentedMouseEvent, context: Record<string, any>) => any;
|
|
4
|
+
type LayeredMouseInteractiveFeature = Merge<MapGeoJSONFeature, {
|
|
5
|
+
layer: {
|
|
6
|
+
id: string;
|
|
7
|
+
onClick: MouseEventHandlerFn;
|
|
8
|
+
onMouseMove: MouseEventHandlerFn;
|
|
9
|
+
};
|
|
10
|
+
}>;
|
|
11
|
+
type AugmentedMouseEvent = Merge<MapMouseEvent, {
|
|
12
|
+
features: LayeredMouseInteractiveFeature[];
|
|
13
|
+
}>;
|
|
14
|
+
type LayeredMapMouseEventHandlerName = 'onClick' | 'onMouseMove';
|
|
15
|
+
type LayeredMapMouseEventHandlerProps = {
|
|
16
|
+
resolveTargetFeature?: (features: AugmentedMouseEvent['features'], event: AugmentedMouseEvent) => LayeredMouseInteractiveFeature | Promise<LayeredMouseInteractiveFeature>;
|
|
17
|
+
context?: Record<string, any>;
|
|
18
|
+
};
|
|
19
|
+
type LayeredMapEventHandler = (e: AugmentedMouseEvent) => any;
|
|
20
|
+
type LayeredMapEventHandlerList = Record<LayeredMapMouseEventHandlerName, LayeredMapEventHandler>;
|
|
21
|
+
export declare function layeredMapMouseEventHandler(handlerName: LayeredMapMouseEventHandlerName, props?: LayeredMapMouseEventHandlerProps): LayeredMapEventHandler;
|
|
22
|
+
export declare function layeredMapMouseEventHandler(handlerName: LayeredMapMouseEventHandlerName[], props?: LayeredMapMouseEventHandlerProps): LayeredMapEventHandlerList;
|
|
23
|
+
export declare function layeredMapOnClickHandler(props?: LayeredMapMouseEventHandlerProps): LayeredMapEventHandler;
|
|
24
|
+
export {};
|
|
@@ -9,6 +9,7 @@ type ParsedLayer = MapViewLayer & {
|
|
|
9
9
|
id: string;
|
|
10
10
|
viewId: string;
|
|
11
11
|
onClick?: (feature: GeoJSON.Feature, event: MapMouseEvent) => any;
|
|
12
|
+
onMouseMove?: (feature: GeoJSON.Feature, event: MapMouseEvent) => any;
|
|
12
13
|
};
|
|
13
14
|
export type MapViewsParseResult = {
|
|
14
15
|
srcMapViews: MapView[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React, { type ComponentProps } from 'react';
|
|
2
|
+
import { Source as MapGlSource } from 'react-map-gl/maplibre';
|
|
3
|
+
import { FeatureState } from '../useFeatureState';
|
|
4
|
+
type MapGlSourceProps = ComponentProps<typeof MapGlSource>;
|
|
5
|
+
export type SourceProps = MapGlSourceProps & {
|
|
6
|
+
id: string;
|
|
7
|
+
featureState: FeatureState;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Drop-in replacement for react-map-gl's <Source /> that also declaratively
|
|
11
|
+
* syncs MapLibre feature-state from props.
|
|
12
|
+
*/
|
|
13
|
+
export declare function Source({ id, featureState, ...sourceProps }: SourceProps): React.JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Source';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MapProps, SourceProps } from 'react-map-gl/maplibre';
|
|
3
|
+
export declare const DEBUG_MAP_PROPS: MapProps;
|
|
4
|
+
export declare function DebugMap({ children, panel, ...props }: MapProps): React.JSX.Element;
|
|
5
|
+
export declare function sourceGeoJsonBr({ id, intrarregiao, ...props }?: {
|
|
6
|
+
id?: string;
|
|
7
|
+
intrarregiao?: 'municipio' | 'uf' | 'regiao' | null;
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
}): SourceProps;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type PanelPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
3
|
+
export declare const Panel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
4
|
+
$position: PanelPosition;
|
|
5
|
+
}>> & string;
|
|
6
|
+
export declare function DebugPanel({ data, children, position, ...props }: {
|
|
7
|
+
data: any;
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
position?: PanelPosition;
|
|
10
|
+
}): React.JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global interning table for H3 cell ids.
|
|
3
|
+
*
|
|
4
|
+
* Problem: every row of every API response carries full 15-char hex H3 ids.
|
|
5
|
+
* Parsing each into a BigInt (`h3ToBigInt`) allocates a heap object per row,
|
|
6
|
+
* and using bigint as a Map key is slow + heavy. But the *set* of distinct
|
|
7
|
+
* hexes in play (a city, at a fixed resolution) is small and highly
|
|
8
|
+
* recurring across mousemoves/tiles — so we intern each hex string to a
|
|
9
|
+
* small uint32 index exactly once, and every downstream structure
|
|
10
|
+
* (TileData, feature-state ids, caches) works with that index instead.
|
|
11
|
+
*
|
|
12
|
+
* This module is a singleton by design: it must persist for the lifetime
|
|
13
|
+
* of the app so the same hex always maps to the same index, and so the
|
|
14
|
+
* dedup benefit compounds across requests instead of resetting per fetch.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hexRegistry(): {
|
|
17
|
+
registerHex: (hex: string) => number;
|
|
18
|
+
hexFromIdx: (idx: number) => string;
|
|
19
|
+
idxFromHex: (hex: string) => number | undefined;
|
|
20
|
+
registrySize: () => number;
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './hexRegistry';
|
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import { __assign,
|
|
2
|
-
import React, { forwardRef, useContext, createContext,
|
|
3
|
-
import {
|
|
1
|
+
import { __assign, __rest, __spreadArray, __awaiter, __generator, __makeTemplateObject } from 'tslib';
|
|
2
|
+
import React, { useRef, useEffect, forwardRef, useContext, createContext, useMemo, useImperativeHandle, useState, useCallback, useLayoutEffect, createRef } from 'react';
|
|
3
|
+
import { useMap, Source as Source$1, Map as Map$1, Layer, useControl } from 'react-map-gl/maplibre';
|
|
4
|
+
import { bbox } from '@turf/turf';
|
|
4
5
|
import { isPlainObject, uniq, uniqBy, isEqual, pick, omit } from 'lodash-es';
|
|
5
6
|
import { Flex, useRefByKey, useLocalState, DropdownMenu } from '@orioro/react-ui-core';
|
|
6
7
|
import styled from 'styled-components';
|
|
7
8
|
import { usePrevious } from 'react-use';
|
|
8
9
|
import { mergeRefs } from 'react-merge-refs';
|
|
9
|
-
import { jsxs } from 'react/jsx-runtime';
|
|
10
10
|
import { mdiCloseCircleOutline, mdiCheck, mdiTerrain, mdiVideo3d } from '@mdi/js';
|
|
11
11
|
import { interpolate, strExpr } from '@orioro/util';
|
|
12
12
|
import { ckmeans } from 'simple-statistics';
|
|
13
13
|
import { schemeYlOrRd } from 'd3-scale-chromatic';
|
|
14
14
|
import { maxIndex, range, variance, sum } from 'd3';
|
|
15
|
-
import { bbox } from '@turf/turf';
|
|
16
15
|
import { createPortal } from 'react-dom';
|
|
17
16
|
import { Icon } from '@mdi/react';
|
|
18
17
|
import { Tooltip } from '@radix-ui/themes';
|
|
@@ -20,6 +19,244 @@ import maplibregl from 'maplibre-gl';
|
|
|
20
19
|
import mlcontour from 'maplibre-contour';
|
|
21
20
|
import MaplibreInspect from '@maplibre/maplibre-gl-inspect';
|
|
22
21
|
|
|
22
|
+
function _resolveState(map, sourceId, _a) {
|
|
23
|
+
var sourceLayer = _a.sourceLayer,
|
|
24
|
+
stateById = _a.stateById,
|
|
25
|
+
stateByQuery = _a.stateByQuery;
|
|
26
|
+
var result = {};
|
|
27
|
+
for (var _i = 0, _b = stateByQuery !== null && stateByQuery !== void 0 ? stateByQuery : []; _i < _b.length; _i++) {
|
|
28
|
+
var spec = _b[_i];
|
|
29
|
+
var features = map.querySourceFeatures(sourceId, {
|
|
30
|
+
sourceLayer: sourceLayer,
|
|
31
|
+
filter: spec.filter
|
|
32
|
+
});
|
|
33
|
+
for (var _c = 0, features_1 = features; _c < features_1.length; _c++) {
|
|
34
|
+
var f = features_1[_c];
|
|
35
|
+
if (f.id === undefined) continue;
|
|
36
|
+
// result[f.id] may be undefined here — spreading undefined is a no-op
|
|
37
|
+
// ({ ...undefined, ...x } === { ...x }), so this is safe as-is.
|
|
38
|
+
result[f.id] = __assign(__assign({}, result[f.id]), spec.state);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
for (var id in stateById) {
|
|
42
|
+
result[id] = __assign(__assign({}, result[id]), stateById[id]);
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
function useFeatureState(featureStateBySourceId) {
|
|
47
|
+
var _a;
|
|
48
|
+
if (featureStateBySourceId === void 0) {
|
|
49
|
+
featureStateBySourceId = {};
|
|
50
|
+
}
|
|
51
|
+
var mapRef = useMap();
|
|
52
|
+
var map = (_a = mapRef.current) === null || _a === void 0 ? void 0 : _a.getMap();
|
|
53
|
+
var prevAppliedStateBySourceId = useRef({});
|
|
54
|
+
useEffect(function () {
|
|
55
|
+
if (!map) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
var appliedOnceBySourceId = {};
|
|
59
|
+
function _applySourceFeatureState(sourceId) {
|
|
60
|
+
var _a;
|
|
61
|
+
var featureState = featureStateBySourceId[sourceId];
|
|
62
|
+
var _map = map;
|
|
63
|
+
if (!_map.getSource(sourceId)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
var _nextSourceAppliedState = _resolveState(_map, sourceId, featureState);
|
|
67
|
+
var _prevSourceAppliedState = prevAppliedStateBySourceId.current[sourceId] || {};
|
|
68
|
+
//
|
|
69
|
+
// TODO: maybe add batching + requestAnimationFrame
|
|
70
|
+
//
|
|
71
|
+
for (var id in _nextSourceAppliedState) {
|
|
72
|
+
_map.setFeatureState({
|
|
73
|
+
source: sourceId,
|
|
74
|
+
sourceLayer: featureState.sourceLayer,
|
|
75
|
+
id: id
|
|
76
|
+
}, _nextSourceAppliedState[id]);
|
|
77
|
+
}
|
|
78
|
+
for (var id in _prevSourceAppliedState) {
|
|
79
|
+
if (!(id in _nextSourceAppliedState)) {
|
|
80
|
+
_map.removeFeatureState({
|
|
81
|
+
source: sourceId,
|
|
82
|
+
sourceLayer: featureState.sourceLayer,
|
|
83
|
+
id: id
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
prevAppliedStateBySourceId.current = __assign(__assign({}, prevAppliedStateBySourceId.current), (_a = {}, _a[sourceId] = _nextSourceAppliedState, _a));
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
appliedOnceBySourceId = Object.fromEntries(Object.keys(featureStateBySourceId).map(function (sourceId) {
|
|
91
|
+
return [sourceId, _applySourceFeatureState(sourceId)];
|
|
92
|
+
}));
|
|
93
|
+
// Re-apply on sourcedata for two distinct reasons:
|
|
94
|
+
// 1. Initial retry: if the source wasn't registered yet on mount (async
|
|
95
|
+
// relative to this effect), keep trying until it succeeds — this
|
|
96
|
+
// matters even for stateById-only usage, not just stateByQuery.
|
|
97
|
+
// 2. Ongoing re-resolution: stateByQuery results only reflect currently
|
|
98
|
+
// loaded tiles, so once applied at least once, keep re-resolving as
|
|
99
|
+
// more tiles load — this part only matters when queries are in use.
|
|
100
|
+
function onSourceData(e) {
|
|
101
|
+
var _a;
|
|
102
|
+
var _b;
|
|
103
|
+
if (!(e.sourceId in featureStateBySourceId)) {
|
|
104
|
+
//
|
|
105
|
+
// No feature state specified for the given source
|
|
106
|
+
//
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!appliedOnceBySourceId[e.sourceId]) {
|
|
110
|
+
appliedOnceBySourceId = __assign(__assign({}, appliedOnceBySourceId), (_a = {}, _a[e.sourceId] = _applySourceFeatureState(e.sourceId), _a));
|
|
111
|
+
} else if ((_b = featureStateBySourceId[e.sourceId].stateByQuery) === null || _b === void 0 ? void 0 : _b.length) {
|
|
112
|
+
_applySourceFeatureState(e.sourceId);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
map.on('sourcedata', onSourceData);
|
|
116
|
+
return function () {
|
|
117
|
+
map.off('sourcedata', onSourceData);
|
|
118
|
+
};
|
|
119
|
+
}, [map, featureStateBySourceId]);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
var DEFAULT_OPTIONS = {
|
|
123
|
+
padding: {
|
|
124
|
+
top: 60,
|
|
125
|
+
bottom: 60,
|
|
126
|
+
left: 60,
|
|
127
|
+
right: 60
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
function fitGeometry(map, geo, options) {
|
|
131
|
+
if (options === void 0) {
|
|
132
|
+
options = DEFAULT_OPTIONS;
|
|
133
|
+
}
|
|
134
|
+
var bounds = bbox(geo);
|
|
135
|
+
return map.fitBounds([[bounds[0], bounds[1]], [bounds[2], bounds[3]]], __assign(__assign({}, DEFAULT_OPTIONS), options));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//
|
|
139
|
+
// Taken from react-map-gl/maplibre
|
|
140
|
+
// https://github.com/visgl/react-map-gl/blob/c7112cf50d6985e8427d6b187d23a4d957791bb7/modules/react-maplibre/src/utils/apply-react-style.ts
|
|
141
|
+
//
|
|
142
|
+
// This is a simplified version of
|
|
143
|
+
// https://github.com/facebook/react/blob/4131af3e4bf52f3a003537ec95a1655147c81270/src/renderers/dom/shared/CSSPropertyOperations.js#L62
|
|
144
|
+
var unitlessNumber = /box|flex|grid|column|lineHeight|fontWeight|opacity|order|tabSize|zIndex/;
|
|
145
|
+
function applyReactStyle(element, styles) {
|
|
146
|
+
if (!element || !styles) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
var style = element.style;
|
|
150
|
+
for (var key in styles) {
|
|
151
|
+
var value = styles[key];
|
|
152
|
+
if (Number.isFinite(value) && !unitlessNumber.test(key)) {
|
|
153
|
+
style[key] = "".concat(value, "px");
|
|
154
|
+
} else {
|
|
155
|
+
style[key] = value;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function ensureAddLayer(map, layerId, layer) {
|
|
161
|
+
if (!map.getLayer(layerId)) {
|
|
162
|
+
map.addLayer(__assign(__assign({}, layer), {
|
|
163
|
+
id: layerId
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function ensureRemoveLayer(map, layerId) {
|
|
168
|
+
if (map.getLayer(layerId)) {
|
|
169
|
+
map.removeLayer(layerId);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function ensureAddSource(map, sourceId, sourceSpec) {
|
|
173
|
+
if (!map.getSource(sourceId)) {
|
|
174
|
+
map.addSource(sourceId, sourceSpec);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function ensureRemoveSource(map, sourceId) {
|
|
178
|
+
if (map.getSource(sourceId)) {
|
|
179
|
+
map.removeSource(sourceId);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Props react-map-gl's updateSource() cannot push to the underlying
|
|
184
|
+
// MapLibre/Mapbox source after creation, per source type.
|
|
185
|
+
// Keep this in sync with react-map-gl's source.ts — as it gains
|
|
186
|
+
// reactive support for more props (e.g. tiles/url did in 7.1.8),
|
|
187
|
+
// trim the corresponding entries here.
|
|
188
|
+
//
|
|
189
|
+
// See location of <Source /> component src code:
|
|
190
|
+
// https://github.com/visgl/react-map-gl/blob/4b649aaf926adacb3ffba4b7c5d8edebaca90f8a/modules/react-maplibre/src/components/source.ts#L79
|
|
191
|
+
//
|
|
192
|
+
var NON_REACTIVE_PROPS_BY_TYPE = {
|
|
193
|
+
vector: ['bounds', 'scheme', 'minzoom', 'maxzoom', 'attribution', 'promoteId', 'volatile'],
|
|
194
|
+
raster: ['bounds', 'minzoom', 'maxzoom', 'tileSize', 'scheme', 'attribution', 'volatile'],
|
|
195
|
+
'raster-dem': ['bounds', 'tileSize', 'minzoom', 'maxzoom', 'encoding', 'attribution'],
|
|
196
|
+
geojson: ['cluster', 'clusterRadius', 'clusterMaxZoom', 'clusterMinPoints', 'clusterProperties', 'maxzoom', 'attribution', 'buffer', 'tolerance', 'lineMetrics', 'generateId', 'promoteId', 'filter'],
|
|
197
|
+
video: ['urls'],
|
|
198
|
+
canvas: ['canvas', 'animate']
|
|
199
|
+
// image has no non-reactive props — omitted
|
|
200
|
+
};
|
|
201
|
+
function getSourceRemountKey(id, source) {
|
|
202
|
+
var _a, _b;
|
|
203
|
+
var nonReactiveKeys = (_b = NON_REACTIVE_PROPS_BY_TYPE[(_a = source.type) !== null && _a !== void 0 ? _a : '']) !== null && _b !== void 0 ? _b : [];
|
|
204
|
+
if (nonReactiveKeys.length === 0) return id;
|
|
205
|
+
var fingerprint = nonReactiveKeys.map(function (key) {
|
|
206
|
+
return typeof source[key] !== 'undefined' ? "".concat(key, ":").concat(JSON.stringify(source[key])) : null;
|
|
207
|
+
}).filter(Boolean).join('|');
|
|
208
|
+
return "".concat(id, ":").concat(fingerprint);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Derives a React `key` for a <Layer> that changes whenever a
|
|
213
|
+
* non-reactive prop changes, forcing a remount instead of a silently
|
|
214
|
+
* dropped update.
|
|
215
|
+
*
|
|
216
|
+
* react-map-gl only pushes `paint`, `layout`, `filter`,
|
|
217
|
+
* `minzoom`/`maxzoom`, and `beforeId` to the map after mount (via
|
|
218
|
+
* real setters like `setPaintProperty`). `type`, `source`, and
|
|
219
|
+
* `source-layer` have no such setters — changing them is a no-op
|
|
220
|
+
* unless the layer is removed and re-added, i.e. remounted.
|
|
221
|
+
*
|
|
222
|
+
* <Layer key={getLayerRemountKey(id, layer)} id={id} {...layer} />
|
|
223
|
+
*
|
|
224
|
+
* https://github.com/visgl/react-map-gl/blob/4b649aaf926adacb3ffba4b7c5d8edebaca90f8a/modules/react-maplibre/src/components/layer.ts#L20
|
|
225
|
+
*/
|
|
226
|
+
function getLayerRemountKey(id, layer) {
|
|
227
|
+
var _a;
|
|
228
|
+
return "".concat(id, ":").concat(layer.type, ":").concat(layer.source, ":").concat((_a = layer['source-layer']) !== null && _a !== void 0 ? _a : '');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Drop-in replacement for react-map-gl's <Source /> that also declaratively
|
|
233
|
+
* syncs MapLibre feature-state from props.
|
|
234
|
+
*/
|
|
235
|
+
function Source(_a) {
|
|
236
|
+
var _b;
|
|
237
|
+
var id = _a.id,
|
|
238
|
+
featureState = _a.featureState,
|
|
239
|
+
sourceProps = __rest(_a, ["id", "featureState"]);
|
|
240
|
+
useFeatureState(featureState ? (_b = {}, _b[id] = featureState, _b) : {});
|
|
241
|
+
return /*#__PURE__*/React.createElement(Source$1
|
|
242
|
+
//
|
|
243
|
+
// Use `getSourceRemountKey` to ensure that
|
|
244
|
+
// non-reactive props (props that react-map-gl as no
|
|
245
|
+
// way of updating on maplibre) force re-mount
|
|
246
|
+
// of component
|
|
247
|
+
//
|
|
248
|
+
, __assign({
|
|
249
|
+
//
|
|
250
|
+
// Use `getSourceRemountKey` to ensure that
|
|
251
|
+
// non-reactive props (props that react-map-gl as no
|
|
252
|
+
// way of updating on maplibre) force re-mount
|
|
253
|
+
// of component
|
|
254
|
+
//
|
|
255
|
+
key: getSourceRemountKey(id, sourceProps),
|
|
256
|
+
id: id
|
|
257
|
+
}, sourceProps));
|
|
258
|
+
}
|
|
259
|
+
|
|
23
260
|
function _validZIndex(zIndex) {
|
|
24
261
|
return typeof zIndex === 'number' && !Number.isNaN(zIndex);
|
|
25
262
|
}
|
|
@@ -279,7 +516,6 @@ function syncLayerOrder(_a) {
|
|
|
279
516
|
});
|
|
280
517
|
}
|
|
281
518
|
|
|
282
|
-
// import { mergeRefs } from 'react-merge-refs'
|
|
283
519
|
//
|
|
284
520
|
// Augment mouse events with info from original view
|
|
285
521
|
//
|
|
@@ -367,7 +603,7 @@ var LayeredMap = /*#__PURE__*/forwardRef(function LayeredMapInner(_a, layeredMap
|
|
|
367
603
|
clearTimeout(timeoutId);
|
|
368
604
|
};
|
|
369
605
|
}, [parsed === null || parsed === void 0 ? void 0 : parsed.layers]);
|
|
370
|
-
return /*#__PURE__*/React.createElement(Map, __assign({
|
|
606
|
+
return /*#__PURE__*/React.createElement(Map$1, __assign({
|
|
371
607
|
ref: mapRef,
|
|
372
608
|
interactiveLayerIds: __spreadArray(__spreadArray([], interactiveLayerIdsInput, true), parsed.interactiveLayerIds, true)
|
|
373
609
|
}, mapProps, evtHandlers), /*#__PURE__*/React.createElement(LayeredMapContext.Provider, {
|
|
@@ -377,58 +613,85 @@ var LayeredMap = /*#__PURE__*/forwardRef(function LayeredMapInner(_a, layeredMap
|
|
|
377
613
|
_a.viewId;
|
|
378
614
|
var source = __rest(_a, ["id", "viewId"]);
|
|
379
615
|
return /*#__PURE__*/React.createElement(Source, __assign({
|
|
380
|
-
key: id,
|
|
381
616
|
id: id
|
|
382
617
|
}, source));
|
|
383
618
|
}), parsed.layers.map(function (_a) {
|
|
384
619
|
var id = _a.id,
|
|
385
620
|
layer = __rest(_a, ["id"]);
|
|
386
|
-
return /*#__PURE__*/React.createElement(Layer
|
|
387
|
-
|
|
621
|
+
return /*#__PURE__*/React.createElement(Layer
|
|
622
|
+
//
|
|
623
|
+
// Use `getLayerRemountKey` to ensure that
|
|
624
|
+
// non-reactive props (props that react-map-gl as no
|
|
625
|
+
// way of updating on maplibre) force re-mount
|
|
626
|
+
// of component
|
|
627
|
+
//
|
|
628
|
+
, __assign({
|
|
629
|
+
//
|
|
630
|
+
// Use `getLayerRemountKey` to ensure that
|
|
631
|
+
// non-reactive props (props that react-map-gl as no
|
|
632
|
+
// way of updating on maplibre) force re-mount
|
|
633
|
+
// of component
|
|
634
|
+
//
|
|
635
|
+
key: getLayerRemountKey(id, layer),
|
|
388
636
|
id: id
|
|
389
637
|
}, layer));
|
|
390
638
|
})));
|
|
391
639
|
});
|
|
392
640
|
|
|
393
|
-
function
|
|
641
|
+
function selectFirstInteractiveFeature(features) {
|
|
394
642
|
return features[0];
|
|
395
643
|
}
|
|
396
|
-
function
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
644
|
+
function layeredMapMouseEventHandler(handlerName, props) {
|
|
645
|
+
if (props === void 0) {
|
|
646
|
+
props = {};
|
|
647
|
+
}
|
|
648
|
+
if (Array.isArray(handlerName)) {
|
|
649
|
+
return Object.fromEntries(handlerName.map(function (_handlerName) {
|
|
650
|
+
return [_handlerName, layeredMapMouseEventHandler(_handlerName, props)];
|
|
651
|
+
}));
|
|
652
|
+
} else {
|
|
653
|
+
var _a = props.resolveTargetFeature,
|
|
654
|
+
resolveTargetFeature_1 = _a === void 0 ? selectFirstInteractiveFeature : _a,
|
|
655
|
+
_b = props.context,
|
|
656
|
+
context_1 = _b === void 0 ? {} : _b;
|
|
657
|
+
return function layeredMapOnHandleMouseEvent(e) {
|
|
658
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
659
|
+
var features, taregetableFeatures, targetFeature, _a;
|
|
660
|
+
return __generator(this, function (_b) {
|
|
661
|
+
switch (_b.label) {
|
|
662
|
+
case 0:
|
|
663
|
+
features = e.features || [];
|
|
664
|
+
taregetableFeatures = features.filter(function (feature) {
|
|
665
|
+
var _a;
|
|
666
|
+
return typeof ((_a = feature.layer) === null || _a === void 0 ? void 0 : _a[handlerName]) === 'function';
|
|
667
|
+
});
|
|
668
|
+
if (!(taregetableFeatures.length > 0)) return [3 /*break*/, 4];
|
|
669
|
+
if (!(taregetableFeatures.length === 1)) return [3 /*break*/, 1];
|
|
670
|
+
_a = taregetableFeatures[0];
|
|
671
|
+
return [3 /*break*/, 3];
|
|
672
|
+
case 1:
|
|
673
|
+
return [4 /*yield*/, resolveTargetFeature_1(taregetableFeatures, e)];
|
|
674
|
+
case 2:
|
|
675
|
+
_a = _b.sent();
|
|
676
|
+
_b.label = 3;
|
|
677
|
+
case 3:
|
|
678
|
+
targetFeature = _a;
|
|
679
|
+
targetFeature.layer[handlerName](targetFeature, e, context_1);
|
|
680
|
+
_b.label = 4;
|
|
681
|
+
case 4:
|
|
682
|
+
return [2 /*return*/];
|
|
683
|
+
}
|
|
684
|
+
});
|
|
429
685
|
});
|
|
430
|
-
}
|
|
431
|
-
}
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
function layeredMapOnClickHandler(props) {
|
|
690
|
+
if (props === void 0) {
|
|
691
|
+
props = {};
|
|
692
|
+
}
|
|
693
|
+
console.warn('layeredMapOnClickHandler deprecated, prefer layeredMapMouseEventHandler(`onClick`, props)');
|
|
694
|
+
return layeredMapMouseEventHandler('onClick', props);
|
|
432
695
|
}
|
|
433
696
|
|
|
434
697
|
var Container = styled.div(templateObject_1$2 || (templateObject_1$2 = __makeTemplateObject(["\n pointer-events: none;\n position: absolute;\n z-index: 2;\n\n background: rgba(0, 0, 0, 0.5);\n border-radius: 16px;\n box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);\n backdrop-filter: blur(5px);\n -webkit-backdrop-filter: blur(5px);\n border: 1px solid rgba(0, 0, 0, 0.3);\n\n // background-color: black;\n color: white;\n border-radius: 5px;\n font-size: 0.9rem;\n\n max-width: 300px;\n\n hyphens: auto;\n word-break: break-word; /* Avoids overflow */\n overflow-wrap: break-word; /* Ensures long words break */\n white-space: normal;\n"], ["\n pointer-events: none;\n position: absolute;\n z-index: 2;\n\n background: rgba(0, 0, 0, 0.5);\n border-radius: 16px;\n box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);\n backdrop-filter: blur(5px);\n -webkit-backdrop-filter: blur(5px);\n border: 1px solid rgba(0, 0, 0, 0.3);\n\n // background-color: black;\n color: white;\n border-radius: 5px;\n font-size: 0.9rem;\n\n max-width: 300px;\n\n hyphens: auto;\n word-break: break-word; /* Avoids overflow */\n overflow-wrap: break-word; /* Ensures long words break */\n white-space: normal;\n"])));
|
|
@@ -661,7 +924,7 @@ var MapWindow = /*#__PURE__*/forwardRef(function MapWindowInner(_a, externalRef)
|
|
|
661
924
|
externalOnLoad(e);
|
|
662
925
|
}
|
|
663
926
|
}, [setCenterOffsetPixels, setMapReady]);
|
|
664
|
-
return /*#__PURE__*/React.createElement(Map, __assign({
|
|
927
|
+
return /*#__PURE__*/React.createElement(Map$1, __assign({
|
|
665
928
|
attributionControl: false
|
|
666
929
|
}, mapProps, {
|
|
667
930
|
onLoad: _onLoad,
|
|
@@ -767,160 +1030,6 @@ function useHover(props, deps) {
|
|
|
767
1030
|
}, hoverInfo, isDragging];
|
|
768
1031
|
}
|
|
769
1032
|
|
|
770
|
-
function _arrayLikeToArray(r, a) {
|
|
771
|
-
(null == a || a > r.length) && (a = r.length);
|
|
772
|
-
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
773
|
-
return n;
|
|
774
|
-
}
|
|
775
|
-
function _arrayWithHoles(r) {
|
|
776
|
-
if (Array.isArray(r)) return r;
|
|
777
|
-
}
|
|
778
|
-
function _defineProperty(e, r, t) {
|
|
779
|
-
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
780
|
-
value: t,
|
|
781
|
-
enumerable: true,
|
|
782
|
-
configurable: true,
|
|
783
|
-
writable: true
|
|
784
|
-
}) : e[r] = t, e;
|
|
785
|
-
}
|
|
786
|
-
function _iterableToArrayLimit(r, l) {
|
|
787
|
-
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
788
|
-
if (null != t) {
|
|
789
|
-
var e,
|
|
790
|
-
n,
|
|
791
|
-
i,
|
|
792
|
-
u,
|
|
793
|
-
a = [],
|
|
794
|
-
f = true,
|
|
795
|
-
o = false;
|
|
796
|
-
try {
|
|
797
|
-
if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
|
798
|
-
} catch (r) {
|
|
799
|
-
o = true, n = r;
|
|
800
|
-
} finally {
|
|
801
|
-
try {
|
|
802
|
-
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
803
|
-
} finally {
|
|
804
|
-
if (o) throw n;
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
return a;
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
function _nonIterableRest() {
|
|
811
|
-
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
812
|
-
}
|
|
813
|
-
function ownKeys(e, r) {
|
|
814
|
-
var t = Object.keys(e);
|
|
815
|
-
if (Object.getOwnPropertySymbols) {
|
|
816
|
-
var o = Object.getOwnPropertySymbols(e);
|
|
817
|
-
r && (o = o.filter(function (r) {
|
|
818
|
-
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
819
|
-
})), t.push.apply(t, o);
|
|
820
|
-
}
|
|
821
|
-
return t;
|
|
822
|
-
}
|
|
823
|
-
function _objectSpread2(e) {
|
|
824
|
-
for (var r = 1; r < arguments.length; r++) {
|
|
825
|
-
var t = null != arguments[r] ? arguments[r] : {};
|
|
826
|
-
r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
|
|
827
|
-
_defineProperty(e, r, t[r]);
|
|
828
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
829
|
-
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
830
|
-
});
|
|
831
|
-
}
|
|
832
|
-
return e;
|
|
833
|
-
}
|
|
834
|
-
function _objectWithoutProperties(e, t) {
|
|
835
|
-
if (null == e) return {};
|
|
836
|
-
var o,
|
|
837
|
-
r,
|
|
838
|
-
i = _objectWithoutPropertiesLoose(e, t);
|
|
839
|
-
if (Object.getOwnPropertySymbols) {
|
|
840
|
-
var n = Object.getOwnPropertySymbols(e);
|
|
841
|
-
for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
|
|
842
|
-
}
|
|
843
|
-
return i;
|
|
844
|
-
}
|
|
845
|
-
function _objectWithoutPropertiesLoose(r, e) {
|
|
846
|
-
if (null == r) return {};
|
|
847
|
-
var t = {};
|
|
848
|
-
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
849
|
-
if (-1 !== e.indexOf(n)) continue;
|
|
850
|
-
t[n] = r[n];
|
|
851
|
-
}
|
|
852
|
-
return t;
|
|
853
|
-
}
|
|
854
|
-
function _slicedToArray(r, e) {
|
|
855
|
-
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
856
|
-
}
|
|
857
|
-
function _toPrimitive(t, r) {
|
|
858
|
-
if ("object" != typeof t || !t) return t;
|
|
859
|
-
var e = t[Symbol.toPrimitive];
|
|
860
|
-
if (void 0 !== e) {
|
|
861
|
-
var i = e.call(t, r);
|
|
862
|
-
if ("object" != typeof i) return i;
|
|
863
|
-
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
864
|
-
}
|
|
865
|
-
return ("string" === r ? String : Number)(t);
|
|
866
|
-
}
|
|
867
|
-
function _toPropertyKey(t) {
|
|
868
|
-
var i = _toPrimitive(t, "string");
|
|
869
|
-
return "symbol" == typeof i ? i : i + "";
|
|
870
|
-
}
|
|
871
|
-
function _typeof(o) {
|
|
872
|
-
"@babel/helpers - typeof";
|
|
873
|
-
|
|
874
|
-
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
|
|
875
|
-
return typeof o;
|
|
876
|
-
} : function (o) {
|
|
877
|
-
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
878
|
-
}, _typeof(o);
|
|
879
|
-
}
|
|
880
|
-
function _unsupportedIterableToArray(r, a) {
|
|
881
|
-
if (r) {
|
|
882
|
-
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
883
|
-
var t = {}.toString.call(r).slice(8, -1);
|
|
884
|
-
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
var _excluded = ["cursor", "onMouseMove", "onDragStart", "onDragEnd", "children"];
|
|
889
|
-
function useMergedCallback(cbA, cbB) {
|
|
890
|
-
return useCallback(function () {
|
|
891
|
-
if (typeof cbA === 'function') {
|
|
892
|
-
cbA.apply(void 0, arguments);
|
|
893
|
-
}
|
|
894
|
-
if (typeof cbB === 'function') {
|
|
895
|
-
cbB.apply(void 0, arguments);
|
|
896
|
-
}
|
|
897
|
-
}, [cbA, cbB]);
|
|
898
|
-
}
|
|
899
|
-
function withHover(Component, withHoverProps) {
|
|
900
|
-
return /*#__PURE__*/forwardRef(function WithHover(_ref, ref) {
|
|
901
|
-
var cursor = _ref.cursor,
|
|
902
|
-
onMouseMove = _ref.onMouseMove,
|
|
903
|
-
onDragStart = _ref.onDragStart,
|
|
904
|
-
onDragEnd = _ref.onDragEnd,
|
|
905
|
-
children = _ref.children,
|
|
906
|
-
restProps = _objectWithoutProperties(_ref, _excluded);
|
|
907
|
-
//
|
|
908
|
-
// Hover stuff
|
|
909
|
-
//
|
|
910
|
-
var _useHover = useHover(withHoverProps, []),
|
|
911
|
-
_useHover2 = _slicedToArray(_useHover, 1),
|
|
912
|
-
hoverProps = _useHover2[0];
|
|
913
|
-
return /*#__PURE__*/jsxs(Component, _objectSpread2(_objectSpread2({}, restProps), {}, {
|
|
914
|
-
ref: ref,
|
|
915
|
-
cursor: cursor || hoverProps.cursor,
|
|
916
|
-
onMouseMove: useMergedCallback(onMouseMove, hoverProps.onMouseMove),
|
|
917
|
-
onDragStart: useMergedCallback(onDragStart, hoverProps.onDragStart),
|
|
918
|
-
onDragEnd: useMergedCallback(onDragEnd, hoverProps.onDragEnd),
|
|
919
|
-
children: [hoverProps.children, children]
|
|
920
|
-
}));
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
|
|
924
1033
|
function parseHoverInfo(index, event) {
|
|
925
1034
|
return {
|
|
926
1035
|
index: index,
|
|
@@ -1097,7 +1206,7 @@ function makeSyncedMaps(_a) {
|
|
|
1097
1206
|
}
|
|
1098
1207
|
var SyncedMaps = makeSyncedMaps({
|
|
1099
1208
|
components: {
|
|
1100
|
-
Map: Map
|
|
1209
|
+
Map: Map$1
|
|
1101
1210
|
}
|
|
1102
1211
|
});
|
|
1103
1212
|
var templateObject_1;
|
|
@@ -1549,67 +1658,6 @@ var $naturalBreaks = function $naturalBreaks(_a) {
|
|
|
1549
1658
|
return breaks;
|
|
1550
1659
|
};
|
|
1551
1660
|
|
|
1552
|
-
var DEFAULT_OPTIONS = {
|
|
1553
|
-
padding: {
|
|
1554
|
-
top: 60,
|
|
1555
|
-
bottom: 60,
|
|
1556
|
-
left: 60,
|
|
1557
|
-
right: 60
|
|
1558
|
-
}
|
|
1559
|
-
};
|
|
1560
|
-
function fitGeometry(map, geo, options) {
|
|
1561
|
-
if (options === void 0) {
|
|
1562
|
-
options = DEFAULT_OPTIONS;
|
|
1563
|
-
}
|
|
1564
|
-
var bounds = bbox(geo);
|
|
1565
|
-
return map.fitBounds([[bounds[0], bounds[1]], [bounds[2], bounds[3]]], __assign(__assign({}, DEFAULT_OPTIONS), options));
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
//
|
|
1569
|
-
// Taken from react-map-gl/maplibre
|
|
1570
|
-
// https://github.com/visgl/react-map-gl/blob/c7112cf50d6985e8427d6b187d23a4d957791bb7/modules/react-maplibre/src/utils/apply-react-style.ts
|
|
1571
|
-
//
|
|
1572
|
-
// This is a simplified version of
|
|
1573
|
-
// https://github.com/facebook/react/blob/4131af3e4bf52f3a003537ec95a1655147c81270/src/renderers/dom/shared/CSSPropertyOperations.js#L62
|
|
1574
|
-
var unitlessNumber = /box|flex|grid|column|lineHeight|fontWeight|opacity|order|tabSize|zIndex/;
|
|
1575
|
-
function applyReactStyle(element, styles) {
|
|
1576
|
-
if (!element || !styles) {
|
|
1577
|
-
return;
|
|
1578
|
-
}
|
|
1579
|
-
var style = element.style;
|
|
1580
|
-
for (var key in styles) {
|
|
1581
|
-
var value = styles[key];
|
|
1582
|
-
if (Number.isFinite(value) && !unitlessNumber.test(key)) {
|
|
1583
|
-
style[key] = "".concat(value, "px");
|
|
1584
|
-
} else {
|
|
1585
|
-
style[key] = value;
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1589
|
-
|
|
1590
|
-
function ensureAddLayer(map, layerId, layer) {
|
|
1591
|
-
if (!map.getLayer(layerId)) {
|
|
1592
|
-
map.addLayer(__assign(__assign({}, layer), {
|
|
1593
|
-
id: layerId
|
|
1594
|
-
}));
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
function ensureRemoveLayer(map, layerId) {
|
|
1598
|
-
if (map.getLayer(layerId)) {
|
|
1599
|
-
map.removeLayer(layerId);
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
function ensureAddSource(map, sourceId, sourceSpec) {
|
|
1603
|
-
if (!map.getSource(sourceId)) {
|
|
1604
|
-
map.addSource(sourceId, sourceSpec);
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1607
|
-
function ensureRemoveSource(map, sourceId) {
|
|
1608
|
-
if (map.getSource(sourceId)) {
|
|
1609
|
-
map.removeSource(sourceId);
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
|
|
1613
1661
|
function ControlContainer(_a) {
|
|
1614
1662
|
var style = _a.style,
|
|
1615
1663
|
_b = _a.position,
|
|
@@ -1660,6 +1708,16 @@ function ControlContainerWithStyleReset(_a) {
|
|
|
1660
1708
|
}
|
|
1661
1709
|
ControlContainer.Unstyled = ControlContainerWithStyleReset;
|
|
1662
1710
|
|
|
1711
|
+
function _typeof(o) {
|
|
1712
|
+
"@babel/helpers - typeof";
|
|
1713
|
+
|
|
1714
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
|
|
1715
|
+
return typeof o;
|
|
1716
|
+
} : function (o) {
|
|
1717
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
1718
|
+
}, _typeof(o);
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1663
1721
|
var DEFAULT_DEM_SOURCE_ID = 'dem';
|
|
1664
1722
|
var DEFAULT_DEM_SOURCE_SPEC = {
|
|
1665
1723
|
url: 'https://elevation-tiles-prod.s3.amazonaws.com/terrarium/{z}/{x}/{y}.png',
|
|
@@ -1978,4 +2036,54 @@ function InspectControl(props) {
|
|
|
1978
2036
|
return null;
|
|
1979
2037
|
}
|
|
1980
2038
|
|
|
1981
|
-
|
|
2039
|
+
/**
|
|
2040
|
+
* Global interning table for H3 cell ids.
|
|
2041
|
+
*
|
|
2042
|
+
* Problem: every row of every API response carries full 15-char hex H3 ids.
|
|
2043
|
+
* Parsing each into a BigInt (`h3ToBigInt`) allocates a heap object per row,
|
|
2044
|
+
* and using bigint as a Map key is slow + heavy. But the *set* of distinct
|
|
2045
|
+
* hexes in play (a city, at a fixed resolution) is small and highly
|
|
2046
|
+
* recurring across mousemoves/tiles — so we intern each hex string to a
|
|
2047
|
+
* small uint32 index exactly once, and every downstream structure
|
|
2048
|
+
* (TileData, feature-state ids, caches) works with that index instead.
|
|
2049
|
+
*
|
|
2050
|
+
* This module is a singleton by design: it must persist for the lifetime
|
|
2051
|
+
* of the app so the same hex always maps to the same index, and so the
|
|
2052
|
+
* dedup benefit compounds across requests instead of resetting per fetch.
|
|
2053
|
+
*/
|
|
2054
|
+
function hexRegistry() {
|
|
2055
|
+
var hexToIdx = new Map();
|
|
2056
|
+
var idxToHex = [];
|
|
2057
|
+
/** Intern a 15-char H3 hex string, returning a stable uint32 index. */
|
|
2058
|
+
var registerHex = function registerHex(hex) {
|
|
2059
|
+
var idx = hexToIdx.get(hex);
|
|
2060
|
+
if (idx === undefined) {
|
|
2061
|
+
idx = idxToHex.length;
|
|
2062
|
+
hexToIdx.set(hex, idx);
|
|
2063
|
+
idxToHex.push(hex);
|
|
2064
|
+
}
|
|
2065
|
+
return idx;
|
|
2066
|
+
};
|
|
2067
|
+
/** Reverse lookup: index -> original hex string (e.g. for feature ids). */
|
|
2068
|
+
var hexFromIdx = function hexFromIdx(idx) {
|
|
2069
|
+
var hex = idxToHex[idx];
|
|
2070
|
+
if (hex === undefined) {
|
|
2071
|
+
throw new Error("hexRegistry: no hex interned for index ".concat(idx));
|
|
2072
|
+
}
|
|
2073
|
+
return hex;
|
|
2074
|
+
};
|
|
2075
|
+
var idxFromHex = function idxFromHex(hex) {
|
|
2076
|
+
return hexToIdx.get(hex);
|
|
2077
|
+
};
|
|
2078
|
+
var registrySize = function registrySize() {
|
|
2079
|
+
return idxToHex.length;
|
|
2080
|
+
};
|
|
2081
|
+
return {
|
|
2082
|
+
registerHex: registerHex,
|
|
2083
|
+
hexFromIdx: hexFromIdx,
|
|
2084
|
+
idxFromHex: idxFromHex,
|
|
2085
|
+
registrySize: registrySize
|
|
2086
|
+
};
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
export { $naturalBreaks, ControlContainer, DynamicImages, HoverTooltip, InspectControl, LayeredMap, MapWindow, index as SVG_PATTERNS, Source, SyncedMaps, TerrainControl, applyReactStyle, augmentFeature, circles_1, cross_1, diamonds_1, ensureAddLayer, ensureAddSource, ensureRemoveLayer, ensureRemoveSource, fitGeometry, fmtLayerAbsoluteId, getLayerRemountKey, getSourceRemountKey, getSrcLayer, getSrcViewByLayerId, hexRegistry, hoverParseEvent, layeredMapMouseEventHandler, layeredMapOnClickHandler, lines_1, makeSyncedMaps, mapSetFeaturesState, mosaic_1, mosaic_2, naturalBreakBounds, parseMapViews, scaleNaturalBreaks, sortLayers, squares_1, svgIconGenerator, svgImageGenerator, svgImageId, triangles_1, useClientRect, useFeatureState, useHover, useLayeredMap, useMapRegistry, useTilesLoading, waves_1 };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts an array of H3 cell indexes into a GeoJSON FeatureCollection
|
|
3
|
+
* of polygons.
|
|
4
|
+
*/
|
|
5
|
+
export declare function h3CellsToGeoJSON(cells: any, getProperties?: () => {}): {
|
|
6
|
+
type: string;
|
|
7
|
+
features: ({
|
|
8
|
+
type: string;
|
|
9
|
+
id: any;
|
|
10
|
+
properties: {
|
|
11
|
+
h3: any;
|
|
12
|
+
};
|
|
13
|
+
geometry: {
|
|
14
|
+
type: string;
|
|
15
|
+
coordinates: import("h3-js").CoordPair[][];
|
|
16
|
+
};
|
|
17
|
+
} | {
|
|
18
|
+
type: string;
|
|
19
|
+
id: any;
|
|
20
|
+
properties: {
|
|
21
|
+
h3: any;
|
|
22
|
+
};
|
|
23
|
+
geometry: {
|
|
24
|
+
type: string;
|
|
25
|
+
coordinates: number[][][][];
|
|
26
|
+
};
|
|
27
|
+
})[];
|
|
28
|
+
};
|
|
29
|
+
export declare function resolutionForZoom(zoom: any): number;
|
|
30
|
+
/**
|
|
31
|
+
* Bounds -> H3 cell indexes covering that area at the given resolution.
|
|
32
|
+
* `paddingRatio` expands the box so cells don't pop in right at the
|
|
33
|
+
* viewport edge while panning.
|
|
34
|
+
*/
|
|
35
|
+
export declare function boundsToH3Cells(bounds: any, resolution: any, paddingRatio?: number): string[];
|
|
36
|
+
/** Memoized GeoJSON conversion; see usage note on stable `cells` refs. */
|
|
37
|
+
export declare function useH3GeoJSON(cells: any, getProperties: any): {
|
|
38
|
+
type: string;
|
|
39
|
+
features: ({
|
|
40
|
+
type: string;
|
|
41
|
+
id: any;
|
|
42
|
+
properties: {
|
|
43
|
+
h3: any;
|
|
44
|
+
};
|
|
45
|
+
geometry: {
|
|
46
|
+
type: string;
|
|
47
|
+
coordinates: import("h3-js").CoordPair[][];
|
|
48
|
+
};
|
|
49
|
+
} | {
|
|
50
|
+
type: string;
|
|
51
|
+
id: any;
|
|
52
|
+
properties: {
|
|
53
|
+
h3: any;
|
|
54
|
+
};
|
|
55
|
+
geometry: {
|
|
56
|
+
type: string;
|
|
57
|
+
coordinates: number[][][][];
|
|
58
|
+
};
|
|
59
|
+
})[];
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Tracks the map's viewport and returns the H3 cells currently covering
|
|
63
|
+
* it. Recomputes on `moveend` (debounced) rather than every pan frame —
|
|
64
|
+
* `polygonToCells` does real geometric coverage work and isn't cheap
|
|
65
|
+
* enough to run at 60fps during drag.
|
|
66
|
+
*/
|
|
67
|
+
export declare function useViewportH3Cells({ mapId, getResolution, paddingRatio, debounceMs, }?: {
|
|
68
|
+
getResolution?: typeof resolutionForZoom | undefined;
|
|
69
|
+
paddingRatio?: number | undefined;
|
|
70
|
+
debounceMs?: number | undefined;
|
|
71
|
+
}): never[];
|
|
72
|
+
/**
|
|
73
|
+
* Drop-in hex layer. Two modes:
|
|
74
|
+
* - pass `cells` explicitly -> renders exactly that set (old behavior)
|
|
75
|
+
* - omit `cells` -> auto-tracks the viewport and renders whatever's
|
|
76
|
+
* visible, at a resolution derived from zoom
|
|
77
|
+
*/
|
|
78
|
+
export declare function H3HexSource({ id, mapId, cells: cellsProp, getResolution, paddingRatio, getProperties, fillColor, fillOpacity, lineColor, lineWidth, beforeId, }: {
|
|
79
|
+
id?: string | undefined;
|
|
80
|
+
mapId: any;
|
|
81
|
+
cells: any;
|
|
82
|
+
getResolution: any;
|
|
83
|
+
paddingRatio: any;
|
|
84
|
+
getProperties: any;
|
|
85
|
+
fillColor?: string | undefined;
|
|
86
|
+
fillOpacity?: number | undefined;
|
|
87
|
+
lineColor?: string | undefined;
|
|
88
|
+
lineWidth?: number | undefined;
|
|
89
|
+
beforeId: any;
|
|
90
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
3
|
+
import '@radix-ui/themes/styles.css';
|
|
4
|
+
declare const _default: {
|
|
5
|
+
title: string;
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: string;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export default _default;
|
|
11
|
+
export declare const Basic: () => React.JSX.Element;
|
package/dist/types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export type MapViewLayer = Omit<AnyLayer, 'id'> & {
|
|
|
11
11
|
absoluteSourceId?: string;
|
|
12
12
|
zIndex?: number;
|
|
13
13
|
onClick?: (feature: MapGeoJSONFeature, event: MapMouseEvent) => any;
|
|
14
|
+
onMouseMove?: (feature: MapGeoJSONFeature, event: MapMouseEvent) => any;
|
|
14
15
|
};
|
|
15
16
|
type MapViewLegend = {
|
|
16
17
|
type: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useFeatureState';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FilterSpecification } from 'maplibre-gl';
|
|
2
|
+
type SourceId = string;
|
|
3
|
+
type FeatureId = string | number;
|
|
4
|
+
type FeatureStateValue = Record<string, unknown>;
|
|
5
|
+
export type QuerySpec = {
|
|
6
|
+
filter: FilterSpecification;
|
|
7
|
+
state: FeatureStateValue;
|
|
8
|
+
};
|
|
9
|
+
export type FeatureState = {
|
|
10
|
+
sourceLayer?: string;
|
|
11
|
+
featureIdType?: 'string' | 'number';
|
|
12
|
+
stateById?: Record<FeatureId, FeatureStateValue>;
|
|
13
|
+
stateByQuery?: QuerySpec[];
|
|
14
|
+
};
|
|
15
|
+
export type FeatureStateBySourceId = Record<SourceId, FeatureState>;
|
|
16
|
+
export declare function useFeatureState(featureStateBySourceId?: Record<SourceId, FeatureState>): void;
|
|
17
|
+
export {};
|
package/dist/useHover/index.d.ts
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derives a React `key` for a <Layer> that changes whenever a
|
|
3
|
+
* non-reactive prop changes, forcing a remount instead of a silently
|
|
4
|
+
* dropped update.
|
|
5
|
+
*
|
|
6
|
+
* react-map-gl only pushes `paint`, `layout`, `filter`,
|
|
7
|
+
* `minzoom`/`maxzoom`, and `beforeId` to the map after mount (via
|
|
8
|
+
* real setters like `setPaintProperty`). `type`, `source`, and
|
|
9
|
+
* `source-layer` have no such setters — changing them is a no-op
|
|
10
|
+
* unless the layer is removed and re-added, i.e. remounted.
|
|
11
|
+
*
|
|
12
|
+
* <Layer key={getLayerRemountKey(id, layer)} id={id} {...layer} />
|
|
13
|
+
*
|
|
14
|
+
* https://github.com/visgl/react-map-gl/blob/4b649aaf926adacb3ffba4b7c5d8edebaca90f8a/modules/react-maplibre/src/components/layer.ts#L20
|
|
15
|
+
*/
|
|
16
|
+
export declare function getLayerRemountKey(id: string, layer: Record<string, unknown>): string;
|
package/dist/util/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orioro/react-maplibre-util",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"packageManager": "yarn@4.0.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -56,10 +56,12 @@
|
|
|
56
56
|
"@orioro/resolve": "^0.1.12",
|
|
57
57
|
"@orioro/scale-util": "^0.0.12",
|
|
58
58
|
"@orioro/util": "^0.16.0",
|
|
59
|
+
"@orioro/vector-tile-util": "^0.4.0",
|
|
59
60
|
"@turf/turf": "^7.2.0",
|
|
60
61
|
"d3": "^7.9.0",
|
|
61
62
|
"d3-scale-chromatic": "^3.1.0",
|
|
62
63
|
"greenlet": "^1.1.0",
|
|
64
|
+
"h3-js": "^4.5.0",
|
|
63
65
|
"lodash-es": "^4.17.21",
|
|
64
66
|
"maplibre-contour": "^0.1.0",
|
|
65
67
|
"query-string": "^9.1.1",
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { MapGeoJSONFeature, MapMouseEvent } from 'maplibre-gl';
|
|
2
|
-
import { Merge } from 'type-fest';
|
|
3
|
-
type ClickableFeature = Merge<MapGeoJSONFeature, {
|
|
4
|
-
layer: {
|
|
5
|
-
id: string;
|
|
6
|
-
onClick: (feature: MapGeoJSONFeature, event: AugmentedMouseEvent, context: Record<string, any>) => any;
|
|
7
|
-
};
|
|
8
|
-
}>;
|
|
9
|
-
type AugmentedMouseEvent = Merge<MapMouseEvent, {
|
|
10
|
-
features: ClickableFeature[];
|
|
11
|
-
}>;
|
|
12
|
-
type LayeredMapOnClickHandlerProps = {
|
|
13
|
-
resolveTargetFeature?: (features: AugmentedMouseEvent['features'], event: AugmentedMouseEvent) => ClickableFeature | Promise<ClickableFeature>;
|
|
14
|
-
context?: Record<string, any>;
|
|
15
|
-
};
|
|
16
|
-
export declare function layeredMapOnClickHandler({ resolveTargetFeature, context, }?: LayeredMapOnClickHandlerProps): (e: AugmentedMouseEvent) => Promise<void>;
|
|
17
|
-
export {};
|