react-three-map 0.8.1 → 1.0.0-next.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 +19 -0
- package/README.md +41 -24
- package/dist/cjs/main.js +1283 -44
- package/dist/es/main.mjs +2 -1
- package/dist/es/main10.mjs +71 -10
- package/dist/es/main10.mjs.map +1 -1
- package/dist/es/main11.mjs +12 -35
- package/dist/es/main11.mjs.map +1 -1
- package/dist/es/main12.mjs +12 -13
- package/dist/es/main12.mjs.map +1 -1
- package/dist/es/main13.mjs +42 -24
- package/dist/es/main13.mjs.map +1 -1
- package/dist/es/main14.mjs +13 -4
- package/dist/es/main14.mjs.map +1 -1
- package/dist/es/main15.mjs +22 -31
- package/dist/es/main15.mjs.map +1 -1
- package/dist/es/main16.mjs +87 -22
- package/dist/es/main16.mjs.map +1 -1
- package/dist/es/main17.mjs +14 -94
- package/dist/es/main17.mjs.map +1 -1
- package/dist/es/main18.mjs +22 -62
- package/dist/es/main18.mjs.map +1 -1
- package/dist/es/main19.mjs +27 -20
- package/dist/es/main19.mjs.map +1 -1
- package/dist/es/main20.mjs +8 -23
- package/dist/es/main20.mjs.map +1 -1
- package/dist/es/main21.mjs +34 -16
- package/dist/es/main21.mjs.map +1 -1
- package/dist/es/main22.mjs +12 -80
- package/dist/es/main22.mjs.map +1 -1
- package/dist/es/main23.mjs +26 -0
- package/dist/es/main23.mjs.map +1 -0
- package/dist/es/main24.mjs +5 -0
- package/dist/es/main24.mjs.map +1 -0
- package/dist/es/main25.mjs +33 -0
- package/dist/es/main25.mjs.map +1 -0
- package/dist/es/main26.mjs +27 -0
- package/dist/es/main26.mjs.map +1 -0
- package/dist/es/main27.mjs +98 -0
- package/dist/es/main27.mjs.map +1 -0
- package/dist/es/main28.mjs +66 -0
- package/dist/es/main28.mjs.map +1 -0
- package/dist/es/main29.mjs +23 -0
- package/dist/es/main29.mjs.map +1 -0
- package/dist/es/main3.mjs +13 -4
- package/dist/es/main3.mjs.map +1 -1
- package/dist/es/main30.mjs +27 -0
- package/dist/es/main30.mjs.map +1 -0
- package/dist/es/main31.mjs +19 -0
- package/dist/es/main31.mjs.map +1 -0
- package/dist/es/main32.mjs +83 -0
- package/dist/es/main32.mjs.map +1 -0
- package/dist/es/main33.mjs +501 -0
- package/dist/es/main33.mjs.map +1 -0
- package/dist/es/main34.mjs +90 -0
- package/dist/es/main34.mjs.map +1 -0
- package/dist/es/main35.mjs +6 -0
- package/dist/es/main35.mjs.map +1 -0
- package/dist/es/main36.mjs +26 -0
- package/dist/es/main36.mjs.map +1 -0
- package/dist/es/main37.mjs +19 -0
- package/dist/es/main37.mjs.map +1 -0
- package/dist/es/main38.mjs +50 -0
- package/dist/es/main38.mjs.map +1 -0
- package/dist/es/main39.mjs +31 -0
- package/dist/es/main39.mjs.map +1 -0
- package/dist/es/main4.mjs +3 -3
- package/dist/es/main40.mjs +9 -0
- package/dist/es/main40.mjs.map +1 -0
- package/dist/es/main41.mjs +62 -0
- package/dist/es/main41.mjs.map +1 -0
- package/dist/es/main42.mjs +42 -0
- package/dist/es/main42.mjs.map +1 -0
- package/dist/es/main5.mjs +22 -2
- package/dist/es/main5.mjs.map +1 -1
- package/dist/es/main6.mjs +1 -1
- package/dist/es/main7.mjs +1 -1
- package/dist/es/main8.mjs +87 -20
- package/dist/es/main8.mjs.map +1 -1
- package/dist/es/main9.mjs +80 -24
- package/dist/es/main9.mjs.map +1 -1
- package/dist/maplibre/cjs/main.js +30 -9
- package/dist/maplibre/es/main.mjs +2 -1
- package/dist/maplibre/es/main.mjs.map +1 -1
- package/dist/maplibre/es/main14.mjs +1 -1
- package/dist/maplibre/es/main14.mjs.map +1 -1
- package/dist/maplibre/es/main16.mjs +2 -1
- package/dist/maplibre/es/main16.mjs.map +1 -1
- package/dist/maplibre/es/main3.mjs +2 -2
- package/dist/maplibre/es/main3.mjs.map +1 -1
- package/dist/maplibre/es/main5.mjs +21 -1
- package/dist/maplibre/es/main5.mjs.map +1 -1
- package/dist/maplibre/types/api/coords-to-vector-3.d.ts +1 -0
- package/dist/maplibre/types/core/canvas-in-layer/use-canvas-in-layer.d.ts +5 -1
- package/dist/maplibre/types/core/canvas-in-layer/use-render.d.ts +5 -1
- package/dist/maplibre/types/core/earth-radius.d.ts +1 -1
- package/dist/maplibre/types/core/generic-map.d.ts +2 -2
- package/dist/maplibre/types/{mapbox → maplibre}/canvas.d.ts +1 -1
- package/dist/maplibre/types/maplibre.index.d.ts +1 -1
- package/dist/types/api/coords-to-vector-3.d.ts +1 -0
- package/dist/types/core/canvas-in-layer/use-canvas-in-layer.d.ts +5 -1
- package/dist/types/core/canvas-in-layer/use-render.d.ts +5 -1
- package/dist/types/core/earth-radius.d.ts +1 -1
- package/dist/types/core/generic-map.d.ts +2 -2
- package/dist/types/mapbox/canvas.d.ts +1 -1
- package/made-with/studio-carto-urban-project.webp +0 -0
- package/package.json +7 -7
- package/stories/package.json +4 -4
- package/stories/yarn.lock +175 -98
package/dist/cjs/main.js
CHANGED
|
@@ -1,12 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
2
24
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
25
|
const fiber = require("@react-three/fiber");
|
|
4
26
|
const jsxRuntime = require("react/jsx-runtime");
|
|
5
27
|
const mapboxGl = require("mapbox-gl");
|
|
6
|
-
const
|
|
7
|
-
const reactMapGl = require("react-map-gl");
|
|
8
|
-
const THREE = require("three");
|
|
28
|
+
const React = require("react");
|
|
9
29
|
const reactDom = require("react-dom");
|
|
30
|
+
const THREE = require("three");
|
|
10
31
|
function _interopNamespaceDefault(e) {
|
|
11
32
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
12
33
|
if (e) {
|
|
@@ -23,8 +44,9 @@ function _interopNamespaceDefault(e) {
|
|
|
23
44
|
n.default = e;
|
|
24
45
|
return Object.freeze(n);
|
|
25
46
|
}
|
|
47
|
+
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
26
48
|
const THREE__namespace = /* @__PURE__ */ _interopNamespaceDefault(THREE);
|
|
27
|
-
const useMap$
|
|
49
|
+
const useMap$2 = () => fiber.useThree((s) => {
|
|
28
50
|
var _a;
|
|
29
51
|
return (_a = s.r3m) == null ? void 0 : _a.map;
|
|
30
52
|
});
|
|
@@ -79,7 +101,7 @@ function coordsToMatrix({
|
|
|
79
101
|
return m4.compose(pos, quat, scale).toArray();
|
|
80
102
|
}
|
|
81
103
|
function useCoordsToMatrix({ latitude, longitude, altitude, fromLngLat: fromLngLat2 }) {
|
|
82
|
-
const m42 =
|
|
104
|
+
const m42 = React.useMemo(() => coordsToMatrix({
|
|
83
105
|
latitude,
|
|
84
106
|
longitude,
|
|
85
107
|
altitude,
|
|
@@ -93,7 +115,7 @@ function useR3M() {
|
|
|
93
115
|
}
|
|
94
116
|
function useInitR3M(props) {
|
|
95
117
|
const canvas = fiber.useThree((s) => s.gl.domElement);
|
|
96
|
-
|
|
118
|
+
React.useState(() => {
|
|
97
119
|
const store = fiber._roots.get(canvas).store;
|
|
98
120
|
initR3M({ ...props, store });
|
|
99
121
|
});
|
|
@@ -104,13 +126,13 @@ function initR3M({ store, ...props }) {
|
|
|
104
126
|
store.setState({ r3m });
|
|
105
127
|
return r3m;
|
|
106
128
|
}
|
|
107
|
-
const Coordinates =
|
|
129
|
+
const Coordinates = React.memo(({
|
|
108
130
|
latitude,
|
|
109
131
|
longitude,
|
|
110
132
|
altitude = 0,
|
|
111
133
|
children
|
|
112
134
|
}) => {
|
|
113
|
-
const [scene] =
|
|
135
|
+
const [scene] = React.useState(() => new THREE.Scene());
|
|
114
136
|
const r3m = useR3M();
|
|
115
137
|
const origin = useCoordsToMatrix({
|
|
116
138
|
latitude,
|
|
@@ -126,14 +148,14 @@ const Coordinates = react.memo(({
|
|
|
126
148
|
Coordinates.displayName = "Coordinates";
|
|
127
149
|
function RenderAtCoords({ r3m, origin }) {
|
|
128
150
|
const { gl, scene, set } = fiber.useThree();
|
|
129
|
-
const cameraRef =
|
|
151
|
+
const cameraRef = React.useRef(null);
|
|
130
152
|
fiber.useFrame(() => {
|
|
131
153
|
if (!cameraRef.current)
|
|
132
154
|
return;
|
|
133
155
|
syncCamera(cameraRef.current, origin, r3m.viewProjMx);
|
|
134
156
|
gl.render(scene, cameraRef.current);
|
|
135
157
|
});
|
|
136
|
-
|
|
158
|
+
React.useLayoutEffect(() => {
|
|
137
159
|
if (!cameraRef.current)
|
|
138
160
|
return;
|
|
139
161
|
set({
|
|
@@ -147,14 +169,33 @@ function RenderAtCoords({ r3m, origin }) {
|
|
|
147
169
|
}, [set, r3m]);
|
|
148
170
|
return /* @__PURE__ */ jsxRuntime.jsx("perspectiveCamera", { ref: cameraRef });
|
|
149
171
|
}
|
|
150
|
-
const earthRadius =
|
|
172
|
+
const earthRadius = 63710088e-1;
|
|
173
|
+
const mercatorScaleLookup = {};
|
|
174
|
+
function getMercatorScale(lat) {
|
|
175
|
+
const index = Math.round(lat * 1e3);
|
|
176
|
+
if (mercatorScaleLookup[index] === void 0) {
|
|
177
|
+
mercatorScaleLookup[index] = 1 / Math.cos(lat * THREE.MathUtils.DEG2RAD);
|
|
178
|
+
}
|
|
179
|
+
return mercatorScaleLookup[index];
|
|
180
|
+
}
|
|
181
|
+
function averageMercatorScale(originLat, pointLat, steps = 10) {
|
|
182
|
+
let totalScale = 0;
|
|
183
|
+
const latStep = (pointLat - originLat) / steps;
|
|
184
|
+
for (let i = 0; i <= steps; i++) {
|
|
185
|
+
const lat = originLat + latStep * i;
|
|
186
|
+
totalScale += getMercatorScale(lat);
|
|
187
|
+
}
|
|
188
|
+
return totalScale / (steps + 1);
|
|
189
|
+
}
|
|
151
190
|
function coordsToVector3(point, origin) {
|
|
152
191
|
const latitudeDiff = (point.latitude - origin.latitude) * THREE.MathUtils.DEG2RAD;
|
|
153
192
|
const longitudeDiff = (point.longitude - origin.longitude) * THREE.MathUtils.DEG2RAD;
|
|
154
193
|
const altitudeDiff = (point.altitude || 0) - (origin.altitude || 0);
|
|
155
194
|
const x = longitudeDiff * earthRadius * Math.cos(origin.latitude * THREE.MathUtils.DEG2RAD);
|
|
156
195
|
const y = altitudeDiff;
|
|
157
|
-
const
|
|
196
|
+
const steps = Math.ceil(Math.abs(point.latitude - origin.latitude)) * 100 + 1;
|
|
197
|
+
const avgScale = averageMercatorScale(origin.latitude, point.latitude, steps);
|
|
198
|
+
const z = -latitudeDiff * earthRadius / getMercatorScale(origin.latitude) * avgScale;
|
|
158
199
|
return [x, y, z];
|
|
159
200
|
}
|
|
160
201
|
function useCoords() {
|
|
@@ -163,7 +204,7 @@ function useCoords() {
|
|
|
163
204
|
}
|
|
164
205
|
function useSetCoords({ longitude, latitude, altitude }) {
|
|
165
206
|
const canvas = fiber.useThree((s) => s.gl.domElement);
|
|
166
|
-
|
|
207
|
+
React.useMemo(() => {
|
|
167
208
|
const store = fiber._roots.get(canvas).store;
|
|
168
209
|
const coords = { longitude, latitude, altitude };
|
|
169
210
|
setCoords(store, coords);
|
|
@@ -174,16 +215,16 @@ function useSetRootCoords(store, {
|
|
|
174
215
|
latitude,
|
|
175
216
|
altitude
|
|
176
217
|
}) {
|
|
177
|
-
|
|
218
|
+
React.useMemo(() => {
|
|
178
219
|
setCoords(store, { longitude, latitude, altitude });
|
|
179
220
|
}, [longitude, latitude, altitude]);
|
|
180
221
|
}
|
|
181
222
|
function setCoords(store, coords) {
|
|
182
223
|
store.setState({ coords });
|
|
183
224
|
}
|
|
184
|
-
const NearCoordinates =
|
|
225
|
+
const NearCoordinates = React.memo(({ children, ...coords }) => {
|
|
185
226
|
const { latitude, longitude, altitude } = useCoords();
|
|
186
|
-
const pos2 =
|
|
227
|
+
const pos2 = React.useMemo(() => coordsToVector3(coords, { latitude, longitude, altitude }), [
|
|
187
228
|
// eslint-disable-line react-hooks/exhaustive-deps
|
|
188
229
|
latitude,
|
|
189
230
|
longitude,
|
|
@@ -203,10 +244,1206 @@ function vector3ToCoords(position, origin) {
|
|
|
203
244
|
const coords = { latitude, longitude, altitude };
|
|
204
245
|
return coords;
|
|
205
246
|
}
|
|
247
|
+
const MountedMapsContext = React__namespace.createContext(null);
|
|
248
|
+
function useMap$1() {
|
|
249
|
+
var _a;
|
|
250
|
+
const maps = (_a = React.useContext(MountedMapsContext)) == null ? void 0 : _a.maps;
|
|
251
|
+
const currentMap = React.useContext(MapContext);
|
|
252
|
+
const mapsWithCurrent = React.useMemo(() => {
|
|
253
|
+
return { ...maps, current: currentMap == null ? void 0 : currentMap.map };
|
|
254
|
+
}, [maps, currentMap]);
|
|
255
|
+
return mapsWithCurrent;
|
|
256
|
+
}
|
|
257
|
+
function arePointsEqual(a, b) {
|
|
258
|
+
const ax = Array.isArray(a) ? a[0] : a ? a.x : 0;
|
|
259
|
+
const ay = Array.isArray(a) ? a[1] : a ? a.y : 0;
|
|
260
|
+
const bx = Array.isArray(b) ? b[0] : b ? b.x : 0;
|
|
261
|
+
const by = Array.isArray(b) ? b[1] : b ? b.y : 0;
|
|
262
|
+
return ax === bx && ay === by;
|
|
263
|
+
}
|
|
264
|
+
function deepEqual(a, b) {
|
|
265
|
+
if (a === b) {
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
if (!a || !b) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
if (Array.isArray(a)) {
|
|
272
|
+
if (!Array.isArray(b) || a.length !== b.length) {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
for (let i = 0; i < a.length; i++) {
|
|
276
|
+
if (!deepEqual(a[i], b[i])) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return true;
|
|
281
|
+
} else if (Array.isArray(b)) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
285
|
+
const aKeys = Object.keys(a);
|
|
286
|
+
const bKeys = Object.keys(b);
|
|
287
|
+
if (aKeys.length !== bKeys.length) {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
for (const key of aKeys) {
|
|
291
|
+
if (!b.hasOwnProperty(key)) {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
if (!deepEqual(a[key], b[key])) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
function cloneTransform(tr) {
|
|
303
|
+
const newTransform = tr.clone();
|
|
304
|
+
newTransform.pixelsToGLUnits = tr.pixelsToGLUnits;
|
|
305
|
+
return newTransform;
|
|
306
|
+
}
|
|
307
|
+
function syncProjection(src, dest) {
|
|
308
|
+
if (!src.getProjection) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const srcProjection = src.getProjection();
|
|
312
|
+
const destProjection = dest.getProjection();
|
|
313
|
+
if (!deepEqual(srcProjection, destProjection)) {
|
|
314
|
+
dest.setProjection(srcProjection);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function transformToViewState(tr) {
|
|
318
|
+
return {
|
|
319
|
+
longitude: tr.center.lng,
|
|
320
|
+
latitude: tr.center.lat,
|
|
321
|
+
zoom: tr.zoom,
|
|
322
|
+
pitch: tr.pitch,
|
|
323
|
+
bearing: tr.bearing,
|
|
324
|
+
padding: tr.padding
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
function applyViewStateToTransform(tr, props) {
|
|
328
|
+
const v = props.viewState || props;
|
|
329
|
+
let changed = false;
|
|
330
|
+
if ("zoom" in v) {
|
|
331
|
+
const zoom = tr.zoom;
|
|
332
|
+
tr.zoom = v.zoom;
|
|
333
|
+
changed = changed || zoom !== tr.zoom;
|
|
334
|
+
}
|
|
335
|
+
if ("bearing" in v) {
|
|
336
|
+
const bearing = tr.bearing;
|
|
337
|
+
tr.bearing = v.bearing;
|
|
338
|
+
changed = changed || bearing !== tr.bearing;
|
|
339
|
+
}
|
|
340
|
+
if ("pitch" in v) {
|
|
341
|
+
const pitch = tr.pitch;
|
|
342
|
+
tr.pitch = v.pitch;
|
|
343
|
+
changed = changed || pitch !== tr.pitch;
|
|
344
|
+
}
|
|
345
|
+
if (v.padding && !tr.isPaddingEqual(v.padding)) {
|
|
346
|
+
changed = true;
|
|
347
|
+
tr.padding = v.padding;
|
|
348
|
+
}
|
|
349
|
+
if ("longitude" in v && "latitude" in v) {
|
|
350
|
+
const center = tr.center;
|
|
351
|
+
tr.center = new center.constructor(v.longitude, v.latitude);
|
|
352
|
+
changed = changed || center !== tr.center;
|
|
353
|
+
}
|
|
354
|
+
return changed;
|
|
355
|
+
}
|
|
356
|
+
const refProps = ["type", "source", "source-layer", "minzoom", "maxzoom", "filter", "layout"];
|
|
357
|
+
function normalizeStyle(style) {
|
|
358
|
+
if (!style) {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
if (typeof style === "string") {
|
|
362
|
+
return style;
|
|
363
|
+
}
|
|
364
|
+
if ("toJS" in style) {
|
|
365
|
+
style = style.toJS();
|
|
366
|
+
}
|
|
367
|
+
if (!style.layers) {
|
|
368
|
+
return style;
|
|
369
|
+
}
|
|
370
|
+
const layerIndex = {};
|
|
371
|
+
for (const layer of style.layers) {
|
|
372
|
+
layerIndex[layer.id] = layer;
|
|
373
|
+
}
|
|
374
|
+
const layers = style.layers.map((layer) => {
|
|
375
|
+
let normalizedLayer = null;
|
|
376
|
+
if ("interactive" in layer) {
|
|
377
|
+
normalizedLayer = Object.assign({}, layer);
|
|
378
|
+
delete normalizedLayer.interactive;
|
|
379
|
+
}
|
|
380
|
+
const layerRef = layerIndex[layer.ref];
|
|
381
|
+
if (layerRef) {
|
|
382
|
+
normalizedLayer = normalizedLayer || Object.assign({}, layer);
|
|
383
|
+
delete normalizedLayer.ref;
|
|
384
|
+
for (const propName of refProps) {
|
|
385
|
+
if (propName in layerRef) {
|
|
386
|
+
normalizedLayer[propName] = layerRef[propName];
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return normalizedLayer || layer;
|
|
391
|
+
});
|
|
392
|
+
return { ...style, layers };
|
|
393
|
+
}
|
|
394
|
+
const DEFAULT_STYLE = { version: 8, sources: {}, layers: [] };
|
|
395
|
+
const pointerEvents = {
|
|
396
|
+
mousedown: "onMouseDown",
|
|
397
|
+
mouseup: "onMouseUp",
|
|
398
|
+
mouseover: "onMouseOver",
|
|
399
|
+
mousemove: "onMouseMove",
|
|
400
|
+
click: "onClick",
|
|
401
|
+
dblclick: "onDblClick",
|
|
402
|
+
mouseenter: "onMouseEnter",
|
|
403
|
+
mouseleave: "onMouseLeave",
|
|
404
|
+
mouseout: "onMouseOut",
|
|
405
|
+
contextmenu: "onContextMenu",
|
|
406
|
+
touchstart: "onTouchStart",
|
|
407
|
+
touchend: "onTouchEnd",
|
|
408
|
+
touchmove: "onTouchMove",
|
|
409
|
+
touchcancel: "onTouchCancel"
|
|
410
|
+
};
|
|
411
|
+
const cameraEvents = {
|
|
412
|
+
movestart: "onMoveStart",
|
|
413
|
+
move: "onMove",
|
|
414
|
+
moveend: "onMoveEnd",
|
|
415
|
+
dragstart: "onDragStart",
|
|
416
|
+
drag: "onDrag",
|
|
417
|
+
dragend: "onDragEnd",
|
|
418
|
+
zoomstart: "onZoomStart",
|
|
419
|
+
zoom: "onZoom",
|
|
420
|
+
zoomend: "onZoomEnd",
|
|
421
|
+
rotatestart: "onRotateStart",
|
|
422
|
+
rotate: "onRotate",
|
|
423
|
+
rotateend: "onRotateEnd",
|
|
424
|
+
pitchstart: "onPitchStart",
|
|
425
|
+
pitch: "onPitch",
|
|
426
|
+
pitchend: "onPitchEnd"
|
|
427
|
+
};
|
|
428
|
+
const otherEvents = {
|
|
429
|
+
wheel: "onWheel",
|
|
430
|
+
boxzoomstart: "onBoxZoomStart",
|
|
431
|
+
boxzoomend: "onBoxZoomEnd",
|
|
432
|
+
boxzoomcancel: "onBoxZoomCancel",
|
|
433
|
+
resize: "onResize",
|
|
434
|
+
load: "onLoad",
|
|
435
|
+
render: "onRender",
|
|
436
|
+
idle: "onIdle",
|
|
437
|
+
remove: "onRemove",
|
|
438
|
+
data: "onData",
|
|
439
|
+
styledata: "onStyleData",
|
|
440
|
+
sourcedata: "onSourceData",
|
|
441
|
+
error: "onError"
|
|
442
|
+
};
|
|
443
|
+
const settingNames = [
|
|
444
|
+
"minZoom",
|
|
445
|
+
"maxZoom",
|
|
446
|
+
"minPitch",
|
|
447
|
+
"maxPitch",
|
|
448
|
+
"maxBounds",
|
|
449
|
+
"projection",
|
|
450
|
+
"renderWorldCopies"
|
|
451
|
+
];
|
|
452
|
+
const handlerNames = [
|
|
453
|
+
"scrollZoom",
|
|
454
|
+
"boxZoom",
|
|
455
|
+
"dragRotate",
|
|
456
|
+
"dragPan",
|
|
457
|
+
"keyboard",
|
|
458
|
+
"doubleClickZoom",
|
|
459
|
+
"touchZoomRotate",
|
|
460
|
+
"touchPitch"
|
|
461
|
+
];
|
|
462
|
+
class Mapbox {
|
|
463
|
+
constructor(MapClass, props, container) {
|
|
464
|
+
this._map = null;
|
|
465
|
+
this._internalUpdate = false;
|
|
466
|
+
this._inRender = false;
|
|
467
|
+
this._hoveredFeatures = null;
|
|
468
|
+
this._deferredEvents = {
|
|
469
|
+
move: false,
|
|
470
|
+
zoom: false,
|
|
471
|
+
pitch: false,
|
|
472
|
+
rotate: false
|
|
473
|
+
};
|
|
474
|
+
this._onEvent = (e) => {
|
|
475
|
+
const cb = this.props[otherEvents[e.type]];
|
|
476
|
+
if (cb) {
|
|
477
|
+
cb(e);
|
|
478
|
+
} else if (e.type === "error") {
|
|
479
|
+
console.error(e.error);
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
this._onPointerEvent = (e) => {
|
|
483
|
+
if (e.type === "mousemove" || e.type === "mouseout") {
|
|
484
|
+
this._updateHover(e);
|
|
485
|
+
}
|
|
486
|
+
const cb = this.props[pointerEvents[e.type]];
|
|
487
|
+
if (cb) {
|
|
488
|
+
if (this.props.interactiveLayerIds && e.type !== "mouseover" && e.type !== "mouseout") {
|
|
489
|
+
e.features = this._hoveredFeatures || this._queryRenderedFeatures(e.point);
|
|
490
|
+
}
|
|
491
|
+
cb(e);
|
|
492
|
+
delete e.features;
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
this._onCameraEvent = (e) => {
|
|
496
|
+
if (!this._internalUpdate) {
|
|
497
|
+
const cb = this.props[cameraEvents[e.type]];
|
|
498
|
+
if (cb) {
|
|
499
|
+
cb(e);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
if (e.type in this._deferredEvents) {
|
|
503
|
+
this._deferredEvents[e.type] = false;
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
this._MapClass = MapClass;
|
|
507
|
+
this.props = props;
|
|
508
|
+
this._initialize(container);
|
|
509
|
+
}
|
|
510
|
+
get map() {
|
|
511
|
+
return this._map;
|
|
512
|
+
}
|
|
513
|
+
get transform() {
|
|
514
|
+
return this._renderTransform;
|
|
515
|
+
}
|
|
516
|
+
setProps(props) {
|
|
517
|
+
const oldProps = this.props;
|
|
518
|
+
this.props = props;
|
|
519
|
+
const settingsChanged = this._updateSettings(props, oldProps);
|
|
520
|
+
if (settingsChanged) {
|
|
521
|
+
this._createShadowTransform(this._map);
|
|
522
|
+
}
|
|
523
|
+
const sizeChanged = this._updateSize(props);
|
|
524
|
+
const viewStateChanged = this._updateViewState(props, true);
|
|
525
|
+
this._updateStyle(props, oldProps);
|
|
526
|
+
this._updateStyleComponents(props, oldProps);
|
|
527
|
+
this._updateHandlers(props, oldProps);
|
|
528
|
+
if (settingsChanged || sizeChanged || viewStateChanged && !this._map.isMoving()) {
|
|
529
|
+
this.redraw();
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
static reuse(props, container) {
|
|
533
|
+
const that = Mapbox.savedMaps.pop();
|
|
534
|
+
if (!that) {
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
const map = that.map;
|
|
538
|
+
const oldContainer = map.getContainer();
|
|
539
|
+
container.className = oldContainer.className;
|
|
540
|
+
while (oldContainer.childNodes.length > 0) {
|
|
541
|
+
container.appendChild(oldContainer.childNodes[0]);
|
|
542
|
+
}
|
|
543
|
+
map._container = container;
|
|
544
|
+
that.setProps({ ...props, styleDiffing: false });
|
|
545
|
+
map.resize();
|
|
546
|
+
const { initialViewState } = props;
|
|
547
|
+
if (initialViewState) {
|
|
548
|
+
if (initialViewState.bounds) {
|
|
549
|
+
map.fitBounds(initialViewState.bounds, { ...initialViewState.fitBoundsOptions, duration: 0 });
|
|
550
|
+
} else {
|
|
551
|
+
that._updateViewState(initialViewState, false);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (map.isStyleLoaded()) {
|
|
555
|
+
map.fire("load");
|
|
556
|
+
} else {
|
|
557
|
+
map.once("styledata", () => map.fire("load"));
|
|
558
|
+
}
|
|
559
|
+
map._update();
|
|
560
|
+
return that;
|
|
561
|
+
}
|
|
562
|
+
/* eslint-disable complexity,max-statements */
|
|
563
|
+
_initialize(container) {
|
|
564
|
+
const { props } = this;
|
|
565
|
+
const { mapStyle = DEFAULT_STYLE } = props;
|
|
566
|
+
const mapOptions = {
|
|
567
|
+
...props,
|
|
568
|
+
...props.initialViewState,
|
|
569
|
+
accessToken: props.mapboxAccessToken || getAccessTokenFromEnv() || null,
|
|
570
|
+
container,
|
|
571
|
+
style: normalizeStyle(mapStyle)
|
|
572
|
+
};
|
|
573
|
+
const viewState = mapOptions.initialViewState || mapOptions.viewState || mapOptions;
|
|
574
|
+
Object.assign(mapOptions, {
|
|
575
|
+
center: [viewState.longitude || 0, viewState.latitude || 0],
|
|
576
|
+
zoom: viewState.zoom || 0,
|
|
577
|
+
pitch: viewState.pitch || 0,
|
|
578
|
+
bearing: viewState.bearing || 0
|
|
579
|
+
});
|
|
580
|
+
if (props.gl) {
|
|
581
|
+
const getContext = HTMLCanvasElement.prototype.getContext;
|
|
582
|
+
HTMLCanvasElement.prototype.getContext = () => {
|
|
583
|
+
HTMLCanvasElement.prototype.getContext = getContext;
|
|
584
|
+
return props.gl;
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
const map = new this._MapClass(mapOptions);
|
|
588
|
+
if (viewState.padding) {
|
|
589
|
+
map.setPadding(viewState.padding);
|
|
590
|
+
}
|
|
591
|
+
if (props.cursor) {
|
|
592
|
+
map.getCanvas().style.cursor = props.cursor;
|
|
593
|
+
}
|
|
594
|
+
this._createShadowTransform(map);
|
|
595
|
+
const renderMap = map._render;
|
|
596
|
+
map._render = (arg) => {
|
|
597
|
+
this._inRender = true;
|
|
598
|
+
renderMap.call(map, arg);
|
|
599
|
+
this._inRender = false;
|
|
600
|
+
};
|
|
601
|
+
const runRenderTaskQueue = map._renderTaskQueue.run;
|
|
602
|
+
map._renderTaskQueue.run = (arg) => {
|
|
603
|
+
runRenderTaskQueue.call(map._renderTaskQueue, arg);
|
|
604
|
+
this._onBeforeRepaint();
|
|
605
|
+
};
|
|
606
|
+
map.on("render", () => this._onAfterRepaint());
|
|
607
|
+
const fireEvent = map.fire;
|
|
608
|
+
map.fire = this._fireEvent.bind(this, fireEvent);
|
|
609
|
+
map.on("resize", () => {
|
|
610
|
+
this._renderTransform.resize(map.transform.width, map.transform.height);
|
|
611
|
+
});
|
|
612
|
+
map.on("styledata", () => {
|
|
613
|
+
this._updateStyleComponents(this.props, {});
|
|
614
|
+
syncProjection(map.transform, this._renderTransform);
|
|
615
|
+
});
|
|
616
|
+
map.on("sourcedata", () => this._updateStyleComponents(this.props, {}));
|
|
617
|
+
for (const eventName in pointerEvents) {
|
|
618
|
+
map.on(eventName, this._onPointerEvent);
|
|
619
|
+
}
|
|
620
|
+
for (const eventName in cameraEvents) {
|
|
621
|
+
map.on(eventName, this._onCameraEvent);
|
|
622
|
+
}
|
|
623
|
+
for (const eventName in otherEvents) {
|
|
624
|
+
map.on(eventName, this._onEvent);
|
|
625
|
+
}
|
|
626
|
+
this._map = map;
|
|
627
|
+
}
|
|
628
|
+
/* eslint-enable complexity,max-statements */
|
|
629
|
+
recycle() {
|
|
630
|
+
const container = this.map.getContainer();
|
|
631
|
+
const children = container.querySelector("[mapboxgl-children]");
|
|
632
|
+
children == null ? void 0 : children.remove();
|
|
633
|
+
Mapbox.savedMaps.push(this);
|
|
634
|
+
}
|
|
635
|
+
destroy() {
|
|
636
|
+
this._map.remove();
|
|
637
|
+
}
|
|
638
|
+
// Force redraw the map now. Typically resize() and jumpTo() is reflected in the next
|
|
639
|
+
// render cycle, which is managed by Mapbox's animation loop.
|
|
640
|
+
// This removes the synchronization issue caused by requestAnimationFrame.
|
|
641
|
+
redraw() {
|
|
642
|
+
const map = this._map;
|
|
643
|
+
if (!this._inRender && map.style) {
|
|
644
|
+
if (map._frame) {
|
|
645
|
+
map._frame.cancel();
|
|
646
|
+
map._frame = null;
|
|
647
|
+
}
|
|
648
|
+
map._render();
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
_createShadowTransform(map) {
|
|
652
|
+
const renderTransform = cloneTransform(map.transform);
|
|
653
|
+
map.painter.transform = renderTransform;
|
|
654
|
+
this._renderTransform = renderTransform;
|
|
655
|
+
}
|
|
656
|
+
/* Trigger map resize if size is controlled
|
|
657
|
+
@param {object} nextProps
|
|
658
|
+
@returns {bool} true if size has changed
|
|
659
|
+
*/
|
|
660
|
+
_updateSize(nextProps) {
|
|
661
|
+
const { viewState } = nextProps;
|
|
662
|
+
if (viewState) {
|
|
663
|
+
const map = this._map;
|
|
664
|
+
if (viewState.width !== map.transform.width || viewState.height !== map.transform.height) {
|
|
665
|
+
map.resize();
|
|
666
|
+
return true;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
return false;
|
|
670
|
+
}
|
|
671
|
+
// Adapted from map.jumpTo
|
|
672
|
+
/* Update camera to match props
|
|
673
|
+
@param {object} nextProps
|
|
674
|
+
@param {bool} triggerEvents - should fire camera events
|
|
675
|
+
@returns {bool} true if anything is changed
|
|
676
|
+
*/
|
|
677
|
+
_updateViewState(nextProps, triggerEvents) {
|
|
678
|
+
if (this._internalUpdate) {
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
const map = this._map;
|
|
682
|
+
const tr = this._renderTransform;
|
|
683
|
+
const { zoom, pitch, bearing } = tr;
|
|
684
|
+
const isMoving = map.isMoving();
|
|
685
|
+
if (isMoving) {
|
|
686
|
+
tr.cameraElevationReference = "sea";
|
|
687
|
+
}
|
|
688
|
+
const changed = applyViewStateToTransform(tr, {
|
|
689
|
+
...transformToViewState(map.transform),
|
|
690
|
+
...nextProps
|
|
691
|
+
});
|
|
692
|
+
if (isMoving) {
|
|
693
|
+
tr.cameraElevationReference = "ground";
|
|
694
|
+
}
|
|
695
|
+
if (changed && triggerEvents) {
|
|
696
|
+
const deferredEvents = this._deferredEvents;
|
|
697
|
+
deferredEvents.move = true;
|
|
698
|
+
deferredEvents.zoom || (deferredEvents.zoom = zoom !== tr.zoom);
|
|
699
|
+
deferredEvents.rotate || (deferredEvents.rotate = bearing !== tr.bearing);
|
|
700
|
+
deferredEvents.pitch || (deferredEvents.pitch = pitch !== tr.pitch);
|
|
701
|
+
}
|
|
702
|
+
if (!isMoving) {
|
|
703
|
+
applyViewStateToTransform(map.transform, nextProps);
|
|
704
|
+
}
|
|
705
|
+
return changed;
|
|
706
|
+
}
|
|
707
|
+
/* Update camera constraints and projection settings to match props
|
|
708
|
+
@param {object} nextProps
|
|
709
|
+
@param {object} currProps
|
|
710
|
+
@returns {bool} true if anything is changed
|
|
711
|
+
*/
|
|
712
|
+
_updateSettings(nextProps, currProps) {
|
|
713
|
+
const map = this._map;
|
|
714
|
+
let changed = false;
|
|
715
|
+
for (const propName of settingNames) {
|
|
716
|
+
if (propName in nextProps && !deepEqual(nextProps[propName], currProps[propName])) {
|
|
717
|
+
changed = true;
|
|
718
|
+
const setter = map[`set${propName[0].toUpperCase()}${propName.slice(1)}`];
|
|
719
|
+
setter == null ? void 0 : setter.call(map, nextProps[propName]);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
return changed;
|
|
723
|
+
}
|
|
724
|
+
/* Update map style to match props
|
|
725
|
+
@param {object} nextProps
|
|
726
|
+
@param {object} currProps
|
|
727
|
+
@returns {bool} true if style is changed
|
|
728
|
+
*/
|
|
729
|
+
_updateStyle(nextProps, currProps) {
|
|
730
|
+
if (nextProps.cursor !== currProps.cursor) {
|
|
731
|
+
this._map.getCanvas().style.cursor = nextProps.cursor || "";
|
|
732
|
+
}
|
|
733
|
+
if (nextProps.mapStyle !== currProps.mapStyle) {
|
|
734
|
+
const { mapStyle = DEFAULT_STYLE, styleDiffing = true } = nextProps;
|
|
735
|
+
const options = {
|
|
736
|
+
diff: styleDiffing
|
|
737
|
+
};
|
|
738
|
+
if ("localIdeographFontFamily" in nextProps) {
|
|
739
|
+
options.localIdeographFontFamily = nextProps.localIdeographFontFamily;
|
|
740
|
+
}
|
|
741
|
+
this._map.setStyle(normalizeStyle(mapStyle), options);
|
|
742
|
+
return true;
|
|
743
|
+
}
|
|
744
|
+
return false;
|
|
745
|
+
}
|
|
746
|
+
/* Update fog, light and terrain to match props
|
|
747
|
+
@param {object} nextProps
|
|
748
|
+
@param {object} currProps
|
|
749
|
+
@returns {bool} true if anything is changed
|
|
750
|
+
*/
|
|
751
|
+
_updateStyleComponents(nextProps, currProps) {
|
|
752
|
+
const map = this._map;
|
|
753
|
+
let changed = false;
|
|
754
|
+
if (map.isStyleLoaded()) {
|
|
755
|
+
if ("light" in nextProps && map.setLight && !deepEqual(nextProps.light, currProps.light)) {
|
|
756
|
+
changed = true;
|
|
757
|
+
map.setLight(nextProps.light);
|
|
758
|
+
}
|
|
759
|
+
if ("fog" in nextProps && map.setFog && !deepEqual(nextProps.fog, currProps.fog)) {
|
|
760
|
+
changed = true;
|
|
761
|
+
map.setFog(nextProps.fog);
|
|
762
|
+
}
|
|
763
|
+
if ("terrain" in nextProps && map.setTerrain && !deepEqual(nextProps.terrain, currProps.terrain)) {
|
|
764
|
+
if (!nextProps.terrain || map.getSource(nextProps.terrain.source)) {
|
|
765
|
+
changed = true;
|
|
766
|
+
map.setTerrain(nextProps.terrain);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
return changed;
|
|
771
|
+
}
|
|
772
|
+
/* Update interaction handlers to match props
|
|
773
|
+
@param {object} nextProps
|
|
774
|
+
@param {object} currProps
|
|
775
|
+
@returns {bool} true if anything is changed
|
|
776
|
+
*/
|
|
777
|
+
_updateHandlers(nextProps, currProps) {
|
|
778
|
+
const map = this._map;
|
|
779
|
+
let changed = false;
|
|
780
|
+
for (const propName of handlerNames) {
|
|
781
|
+
const newValue = nextProps[propName] ?? true;
|
|
782
|
+
const oldValue = currProps[propName] ?? true;
|
|
783
|
+
if (!deepEqual(newValue, oldValue)) {
|
|
784
|
+
changed = true;
|
|
785
|
+
if (newValue) {
|
|
786
|
+
map[propName].enable(newValue);
|
|
787
|
+
} else {
|
|
788
|
+
map[propName].disable();
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
return changed;
|
|
793
|
+
}
|
|
794
|
+
_queryRenderedFeatures(point) {
|
|
795
|
+
const map = this._map;
|
|
796
|
+
const tr = map.transform;
|
|
797
|
+
const { interactiveLayerIds = [] } = this.props;
|
|
798
|
+
try {
|
|
799
|
+
map.transform = this._renderTransform;
|
|
800
|
+
return map.queryRenderedFeatures(point, {
|
|
801
|
+
layers: interactiveLayerIds.filter(map.getLayer.bind(map))
|
|
802
|
+
});
|
|
803
|
+
} catch {
|
|
804
|
+
return [];
|
|
805
|
+
} finally {
|
|
806
|
+
map.transform = tr;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
_updateHover(e) {
|
|
810
|
+
var _a;
|
|
811
|
+
const { props } = this;
|
|
812
|
+
const shouldTrackHoveredFeatures = props.interactiveLayerIds && (props.onMouseMove || props.onMouseEnter || props.onMouseLeave);
|
|
813
|
+
if (shouldTrackHoveredFeatures) {
|
|
814
|
+
const eventType = e.type;
|
|
815
|
+
const wasHovering = ((_a = this._hoveredFeatures) == null ? void 0 : _a.length) > 0;
|
|
816
|
+
const features = this._queryRenderedFeatures(e.point);
|
|
817
|
+
const isHovering = features.length > 0;
|
|
818
|
+
if (!isHovering && wasHovering) {
|
|
819
|
+
e.type = "mouseleave";
|
|
820
|
+
this._onPointerEvent(e);
|
|
821
|
+
}
|
|
822
|
+
this._hoveredFeatures = features;
|
|
823
|
+
if (isHovering && !wasHovering) {
|
|
824
|
+
e.type = "mouseenter";
|
|
825
|
+
this._onPointerEvent(e);
|
|
826
|
+
}
|
|
827
|
+
e.type = eventType;
|
|
828
|
+
} else {
|
|
829
|
+
this._hoveredFeatures = null;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
_fireEvent(baseFire, event, properties) {
|
|
833
|
+
const map = this._map;
|
|
834
|
+
const tr = map.transform;
|
|
835
|
+
const eventType = typeof event === "string" ? event : event.type;
|
|
836
|
+
if (eventType === "move") {
|
|
837
|
+
this._updateViewState(this.props, false);
|
|
838
|
+
}
|
|
839
|
+
if (eventType in cameraEvents) {
|
|
840
|
+
if (typeof event === "object") {
|
|
841
|
+
event.viewState = transformToViewState(tr);
|
|
842
|
+
}
|
|
843
|
+
if (this._map.isMoving()) {
|
|
844
|
+
map.transform = this._renderTransform;
|
|
845
|
+
baseFire.call(map, event, properties);
|
|
846
|
+
map.transform = tr;
|
|
847
|
+
return map;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
baseFire.call(map, event, properties);
|
|
851
|
+
return map;
|
|
852
|
+
}
|
|
853
|
+
// All camera manipulations are complete, ready to repaint
|
|
854
|
+
_onBeforeRepaint() {
|
|
855
|
+
const map = this._map;
|
|
856
|
+
this._internalUpdate = true;
|
|
857
|
+
for (const eventType in this._deferredEvents) {
|
|
858
|
+
if (this._deferredEvents[eventType]) {
|
|
859
|
+
map.fire(eventType);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
this._internalUpdate = false;
|
|
863
|
+
const tr = this._map.transform;
|
|
864
|
+
map.transform = this._renderTransform;
|
|
865
|
+
this._onAfterRepaint = () => {
|
|
866
|
+
syncProjection(this._renderTransform, tr);
|
|
867
|
+
map.transform = tr;
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
Mapbox.savedMaps = [];
|
|
872
|
+
function getAccessTokenFromEnv() {
|
|
873
|
+
let accessToken = null;
|
|
874
|
+
if (typeof location !== "undefined") {
|
|
875
|
+
const match = /access_token=([^&\/]*)/.exec(location.search);
|
|
876
|
+
accessToken = match && match[1];
|
|
877
|
+
}
|
|
878
|
+
try {
|
|
879
|
+
accessToken = accessToken || process.env.MapboxAccessToken;
|
|
880
|
+
} catch {
|
|
881
|
+
}
|
|
882
|
+
try {
|
|
883
|
+
accessToken = accessToken || process.env.REACT_APP_MAPBOX_ACCESS_TOKEN;
|
|
884
|
+
} catch {
|
|
885
|
+
}
|
|
886
|
+
return accessToken;
|
|
887
|
+
}
|
|
888
|
+
const skipMethods = [
|
|
889
|
+
"setMaxBounds",
|
|
890
|
+
"setMinZoom",
|
|
891
|
+
"setMaxZoom",
|
|
892
|
+
"setMinPitch",
|
|
893
|
+
"setMaxPitch",
|
|
894
|
+
"setRenderWorldCopies",
|
|
895
|
+
"setProjection",
|
|
896
|
+
"setStyle",
|
|
897
|
+
"addSource",
|
|
898
|
+
"removeSource",
|
|
899
|
+
"addLayer",
|
|
900
|
+
"removeLayer",
|
|
901
|
+
"setLayerZoomRange",
|
|
902
|
+
"setFilter",
|
|
903
|
+
"setPaintProperty",
|
|
904
|
+
"setLayoutProperty",
|
|
905
|
+
"setLight",
|
|
906
|
+
"setTerrain",
|
|
907
|
+
"setFog",
|
|
908
|
+
"remove"
|
|
909
|
+
];
|
|
910
|
+
function createRef(mapInstance) {
|
|
911
|
+
if (!mapInstance) {
|
|
912
|
+
return null;
|
|
913
|
+
}
|
|
914
|
+
const map = mapInstance.map;
|
|
915
|
+
const ref = {
|
|
916
|
+
getMap: () => map,
|
|
917
|
+
// Overwrite getters to use our shadow transform
|
|
918
|
+
getCenter: () => mapInstance.transform.center,
|
|
919
|
+
getZoom: () => mapInstance.transform.zoom,
|
|
920
|
+
getBearing: () => mapInstance.transform.bearing,
|
|
921
|
+
getPitch: () => mapInstance.transform.pitch,
|
|
922
|
+
getPadding: () => mapInstance.transform.padding,
|
|
923
|
+
getBounds: () => mapInstance.transform.getBounds(),
|
|
924
|
+
project: (lnglat) => {
|
|
925
|
+
const tr = map.transform;
|
|
926
|
+
map.transform = mapInstance.transform;
|
|
927
|
+
const result = map.project(lnglat);
|
|
928
|
+
map.transform = tr;
|
|
929
|
+
return result;
|
|
930
|
+
},
|
|
931
|
+
unproject: (point) => {
|
|
932
|
+
const tr = map.transform;
|
|
933
|
+
map.transform = mapInstance.transform;
|
|
934
|
+
const result = map.unproject(point);
|
|
935
|
+
map.transform = tr;
|
|
936
|
+
return result;
|
|
937
|
+
},
|
|
938
|
+
// options diverge between mapbox and maplibre
|
|
939
|
+
queryTerrainElevation: (lnglat, options) => {
|
|
940
|
+
const tr = map.transform;
|
|
941
|
+
map.transform = mapInstance.transform;
|
|
942
|
+
const result = map.queryTerrainElevation(lnglat, options);
|
|
943
|
+
map.transform = tr;
|
|
944
|
+
return result;
|
|
945
|
+
},
|
|
946
|
+
queryRenderedFeatures: (geometry, options) => {
|
|
947
|
+
const tr = map.transform;
|
|
948
|
+
map.transform = mapInstance.transform;
|
|
949
|
+
const result = map.queryRenderedFeatures(geometry, options);
|
|
950
|
+
map.transform = tr;
|
|
951
|
+
return result;
|
|
952
|
+
}
|
|
953
|
+
};
|
|
954
|
+
for (const key of getMethodNames(map)) {
|
|
955
|
+
if (!(key in ref) && !skipMethods.includes(key)) {
|
|
956
|
+
ref[key] = map[key].bind(map);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
return ref;
|
|
960
|
+
}
|
|
961
|
+
function getMethodNames(obj) {
|
|
962
|
+
const result = /* @__PURE__ */ new Set();
|
|
963
|
+
let proto = obj;
|
|
964
|
+
while (proto) {
|
|
965
|
+
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
966
|
+
if (key[0] !== "_" && typeof obj[key] === "function" && key !== "fire" && key !== "setEventedParent") {
|
|
967
|
+
result.add(key);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
proto = Object.getPrototypeOf(proto);
|
|
971
|
+
}
|
|
972
|
+
return Array.from(result);
|
|
973
|
+
}
|
|
974
|
+
const useIsomorphicLayoutEffect = typeof document !== "undefined" ? React.useLayoutEffect : React.useEffect;
|
|
975
|
+
const globalSettings = [
|
|
976
|
+
"baseApiUrl",
|
|
977
|
+
"maxParallelImageRequests",
|
|
978
|
+
"workerClass",
|
|
979
|
+
"workerCount",
|
|
980
|
+
"workerUrl"
|
|
981
|
+
];
|
|
982
|
+
function setGlobals(mapLib, props) {
|
|
983
|
+
for (const key of globalSettings) {
|
|
984
|
+
if (key in props) {
|
|
985
|
+
mapLib[key] = props[key];
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
const { RTLTextPlugin = "https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.3/mapbox-gl-rtl-text.js" } = props;
|
|
989
|
+
if (RTLTextPlugin && mapLib.getRTLTextPluginStatus && mapLib.getRTLTextPluginStatus() === "unavailable") {
|
|
990
|
+
mapLib.setRTLTextPlugin(RTLTextPlugin, (error) => {
|
|
991
|
+
if (error) {
|
|
992
|
+
console.error(error);
|
|
993
|
+
}
|
|
994
|
+
}, true);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
const MapContext = React__namespace.createContext(null);
|
|
998
|
+
function _Map(props, ref) {
|
|
999
|
+
const mountedMapsContext = React.useContext(MountedMapsContext);
|
|
1000
|
+
const [mapInstance, setMapInstance] = React.useState(null);
|
|
1001
|
+
const containerRef = React.useRef();
|
|
1002
|
+
const { current: contextValue } = React.useRef({ mapLib: null, map: null });
|
|
1003
|
+
React.useEffect(() => {
|
|
1004
|
+
const mapLib = props.mapLib;
|
|
1005
|
+
let isMounted = true;
|
|
1006
|
+
let mapbox;
|
|
1007
|
+
Promise.resolve(mapLib || import("mapbox-gl")).then((module2) => {
|
|
1008
|
+
if (!isMounted) {
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
if (!module2) {
|
|
1012
|
+
throw new Error("Invalid mapLib");
|
|
1013
|
+
}
|
|
1014
|
+
const mapboxgl = "Map" in module2 ? module2 : module2.default;
|
|
1015
|
+
if (!mapboxgl.Map) {
|
|
1016
|
+
throw new Error("Invalid mapLib");
|
|
1017
|
+
}
|
|
1018
|
+
setGlobals(mapboxgl, props);
|
|
1019
|
+
if (!mapboxgl.supported || mapboxgl.supported(props)) {
|
|
1020
|
+
if (props.reuseMaps) {
|
|
1021
|
+
mapbox = Mapbox.reuse(props, containerRef.current);
|
|
1022
|
+
}
|
|
1023
|
+
if (!mapbox) {
|
|
1024
|
+
mapbox = new Mapbox(mapboxgl.Map, props, containerRef.current);
|
|
1025
|
+
}
|
|
1026
|
+
contextValue.map = createRef(mapbox);
|
|
1027
|
+
contextValue.mapLib = mapboxgl;
|
|
1028
|
+
setMapInstance(mapbox);
|
|
1029
|
+
mountedMapsContext == null ? void 0 : mountedMapsContext.onMapMount(contextValue.map, props.id);
|
|
1030
|
+
} else {
|
|
1031
|
+
throw new Error("Map is not supported by this browser");
|
|
1032
|
+
}
|
|
1033
|
+
}).catch((error) => {
|
|
1034
|
+
const { onError } = props;
|
|
1035
|
+
if (onError) {
|
|
1036
|
+
onError({
|
|
1037
|
+
type: "error",
|
|
1038
|
+
target: null,
|
|
1039
|
+
error
|
|
1040
|
+
});
|
|
1041
|
+
} else {
|
|
1042
|
+
console.error(error);
|
|
1043
|
+
}
|
|
1044
|
+
});
|
|
1045
|
+
return () => {
|
|
1046
|
+
isMounted = false;
|
|
1047
|
+
if (mapbox) {
|
|
1048
|
+
mountedMapsContext == null ? void 0 : mountedMapsContext.onMapUnmount(props.id);
|
|
1049
|
+
if (props.reuseMaps) {
|
|
1050
|
+
mapbox.recycle();
|
|
1051
|
+
} else {
|
|
1052
|
+
mapbox.destroy();
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
}, []);
|
|
1057
|
+
useIsomorphicLayoutEffect(() => {
|
|
1058
|
+
if (mapInstance) {
|
|
1059
|
+
mapInstance.setProps(props);
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
1062
|
+
React.useImperativeHandle(ref, () => contextValue.map, [mapInstance]);
|
|
1063
|
+
const style = React.useMemo(() => ({
|
|
1064
|
+
position: "relative",
|
|
1065
|
+
width: "100%",
|
|
1066
|
+
height: "100%",
|
|
1067
|
+
...props.style
|
|
1068
|
+
}), [props.style]);
|
|
1069
|
+
const CHILD_CONTAINER_STYLE = {
|
|
1070
|
+
height: "100%"
|
|
1071
|
+
};
|
|
1072
|
+
return React__namespace.createElement("div", { id: props.id, ref: containerRef, style }, mapInstance && React__namespace.createElement(
|
|
1073
|
+
MapContext.Provider,
|
|
1074
|
+
{ value: contextValue },
|
|
1075
|
+
React__namespace.createElement("div", { "mapboxgl-children": "", style: CHILD_CONTAINER_STYLE }, props.children)
|
|
1076
|
+
));
|
|
1077
|
+
}
|
|
1078
|
+
React__namespace.forwardRef(_Map);
|
|
1079
|
+
const unitlessNumber = /box|flex|grid|column|lineHeight|fontWeight|opacity|order|tabSize|zIndex/;
|
|
1080
|
+
function applyReactStyle(element, styles) {
|
|
1081
|
+
if (!element || !styles) {
|
|
1082
|
+
return;
|
|
1083
|
+
}
|
|
1084
|
+
const style = element.style;
|
|
1085
|
+
for (const key in styles) {
|
|
1086
|
+
const value = styles[key];
|
|
1087
|
+
if (Number.isFinite(value) && !unitlessNumber.test(key)) {
|
|
1088
|
+
style[key] = `${value}px`;
|
|
1089
|
+
} else {
|
|
1090
|
+
style[key] = value;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
React.memo(React.forwardRef((props, ref) => {
|
|
1095
|
+
const { map, mapLib } = React.useContext(MapContext);
|
|
1096
|
+
const thisRef = React.useRef({ props });
|
|
1097
|
+
thisRef.current.props = props;
|
|
1098
|
+
const marker = React.useMemo(() => {
|
|
1099
|
+
let hasChildren = false;
|
|
1100
|
+
React__namespace.Children.forEach(props.children, (el) => {
|
|
1101
|
+
if (el) {
|
|
1102
|
+
hasChildren = true;
|
|
1103
|
+
}
|
|
1104
|
+
});
|
|
1105
|
+
const options = {
|
|
1106
|
+
...props,
|
|
1107
|
+
element: hasChildren ? document.createElement("div") : null
|
|
1108
|
+
};
|
|
1109
|
+
const mk = new mapLib.Marker(options);
|
|
1110
|
+
mk.setLngLat([props.longitude, props.latitude]);
|
|
1111
|
+
mk.getElement().addEventListener("click", (e) => {
|
|
1112
|
+
var _a, _b;
|
|
1113
|
+
(_b = (_a = thisRef.current.props).onClick) == null ? void 0 : _b.call(_a, {
|
|
1114
|
+
type: "click",
|
|
1115
|
+
target: mk,
|
|
1116
|
+
originalEvent: e
|
|
1117
|
+
});
|
|
1118
|
+
});
|
|
1119
|
+
mk.on("dragstart", (e) => {
|
|
1120
|
+
var _a, _b;
|
|
1121
|
+
const evt = e;
|
|
1122
|
+
evt.lngLat = marker.getLngLat();
|
|
1123
|
+
(_b = (_a = thisRef.current.props).onDragStart) == null ? void 0 : _b.call(_a, evt);
|
|
1124
|
+
});
|
|
1125
|
+
mk.on("drag", (e) => {
|
|
1126
|
+
var _a, _b;
|
|
1127
|
+
const evt = e;
|
|
1128
|
+
evt.lngLat = marker.getLngLat();
|
|
1129
|
+
(_b = (_a = thisRef.current.props).onDrag) == null ? void 0 : _b.call(_a, evt);
|
|
1130
|
+
});
|
|
1131
|
+
mk.on("dragend", (e) => {
|
|
1132
|
+
var _a, _b;
|
|
1133
|
+
const evt = e;
|
|
1134
|
+
evt.lngLat = marker.getLngLat();
|
|
1135
|
+
(_b = (_a = thisRef.current.props).onDragEnd) == null ? void 0 : _b.call(_a, evt);
|
|
1136
|
+
});
|
|
1137
|
+
return mk;
|
|
1138
|
+
}, []);
|
|
1139
|
+
React.useEffect(() => {
|
|
1140
|
+
marker.addTo(map.getMap());
|
|
1141
|
+
return () => {
|
|
1142
|
+
marker.remove();
|
|
1143
|
+
};
|
|
1144
|
+
}, []);
|
|
1145
|
+
const { longitude, latitude, offset, style, draggable = false, popup = null, rotation = 0, rotationAlignment = "auto", pitchAlignment = "auto" } = props;
|
|
1146
|
+
React.useEffect(() => {
|
|
1147
|
+
applyReactStyle(marker.getElement(), style);
|
|
1148
|
+
}, [style]);
|
|
1149
|
+
React.useImperativeHandle(ref, () => marker, []);
|
|
1150
|
+
if (marker.getLngLat().lng !== longitude || marker.getLngLat().lat !== latitude) {
|
|
1151
|
+
marker.setLngLat([longitude, latitude]);
|
|
1152
|
+
}
|
|
1153
|
+
if (offset && !arePointsEqual(marker.getOffset(), offset)) {
|
|
1154
|
+
marker.setOffset(offset);
|
|
1155
|
+
}
|
|
1156
|
+
if (marker.isDraggable() !== draggable) {
|
|
1157
|
+
marker.setDraggable(draggable);
|
|
1158
|
+
}
|
|
1159
|
+
if (marker.getRotation() !== rotation) {
|
|
1160
|
+
marker.setRotation(rotation);
|
|
1161
|
+
}
|
|
1162
|
+
if (marker.getRotationAlignment() !== rotationAlignment) {
|
|
1163
|
+
marker.setRotationAlignment(rotationAlignment);
|
|
1164
|
+
}
|
|
1165
|
+
if (marker.getPitchAlignment() !== pitchAlignment) {
|
|
1166
|
+
marker.setPitchAlignment(pitchAlignment);
|
|
1167
|
+
}
|
|
1168
|
+
if (marker.getPopup() !== popup) {
|
|
1169
|
+
marker.setPopup(popup);
|
|
1170
|
+
}
|
|
1171
|
+
return reactDom.createPortal(props.children, marker.getElement());
|
|
1172
|
+
}));
|
|
1173
|
+
function getClassList(className) {
|
|
1174
|
+
return new Set(className ? className.trim().split(/\s+/) : []);
|
|
1175
|
+
}
|
|
1176
|
+
React.memo(React.forwardRef((props, ref) => {
|
|
1177
|
+
const { map, mapLib } = React.useContext(MapContext);
|
|
1178
|
+
const container = React.useMemo(() => {
|
|
1179
|
+
return document.createElement("div");
|
|
1180
|
+
}, []);
|
|
1181
|
+
const thisRef = React.useRef({ props });
|
|
1182
|
+
thisRef.current.props = props;
|
|
1183
|
+
const popup = React.useMemo(() => {
|
|
1184
|
+
const options = { ...props };
|
|
1185
|
+
const pp = new mapLib.Popup(options);
|
|
1186
|
+
pp.setLngLat([props.longitude, props.latitude]);
|
|
1187
|
+
pp.once("open", (e) => {
|
|
1188
|
+
var _a, _b;
|
|
1189
|
+
(_b = (_a = thisRef.current.props).onOpen) == null ? void 0 : _b.call(_a, e);
|
|
1190
|
+
});
|
|
1191
|
+
return pp;
|
|
1192
|
+
}, []);
|
|
1193
|
+
React.useEffect(() => {
|
|
1194
|
+
const onClose = (e) => {
|
|
1195
|
+
var _a, _b;
|
|
1196
|
+
(_b = (_a = thisRef.current.props).onClose) == null ? void 0 : _b.call(_a, e);
|
|
1197
|
+
};
|
|
1198
|
+
popup.on("close", onClose);
|
|
1199
|
+
popup.setDOMContent(container).addTo(map.getMap());
|
|
1200
|
+
return () => {
|
|
1201
|
+
popup.off("close", onClose);
|
|
1202
|
+
if (popup.isOpen()) {
|
|
1203
|
+
popup.remove();
|
|
1204
|
+
}
|
|
1205
|
+
};
|
|
1206
|
+
}, []);
|
|
1207
|
+
React.useEffect(() => {
|
|
1208
|
+
applyReactStyle(popup.getElement(), props.style);
|
|
1209
|
+
}, [props.style]);
|
|
1210
|
+
React.useImperativeHandle(ref, () => popup, []);
|
|
1211
|
+
if (popup.isOpen()) {
|
|
1212
|
+
if (popup.getLngLat().lng !== props.longitude || popup.getLngLat().lat !== props.latitude) {
|
|
1213
|
+
popup.setLngLat([props.longitude, props.latitude]);
|
|
1214
|
+
}
|
|
1215
|
+
if (props.offset && !deepEqual(popup.options.offset, props.offset)) {
|
|
1216
|
+
popup.setOffset(props.offset);
|
|
1217
|
+
}
|
|
1218
|
+
if (popup.options.anchor !== props.anchor || popup.options.maxWidth !== props.maxWidth) {
|
|
1219
|
+
popup.options.anchor = props.anchor;
|
|
1220
|
+
popup.setMaxWidth(props.maxWidth);
|
|
1221
|
+
}
|
|
1222
|
+
if (popup.options.className !== props.className) {
|
|
1223
|
+
const prevClassList = getClassList(popup.options.className);
|
|
1224
|
+
const nextClassList = getClassList(props.className);
|
|
1225
|
+
for (const c of prevClassList) {
|
|
1226
|
+
if (!nextClassList.has(c)) {
|
|
1227
|
+
popup.removeClassName(c);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
for (const c of nextClassList) {
|
|
1231
|
+
if (!prevClassList.has(c)) {
|
|
1232
|
+
popup.addClassName(c);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
popup.options.className = props.className;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
return reactDom.createPortal(props.children, container);
|
|
1239
|
+
}));
|
|
1240
|
+
function useControl(onCreate, arg1, arg2, arg3) {
|
|
1241
|
+
const context = React.useContext(MapContext);
|
|
1242
|
+
const ctrl = React.useMemo(() => onCreate(context), []);
|
|
1243
|
+
React.useEffect(() => {
|
|
1244
|
+
const opts = arg3 || arg2 || arg1;
|
|
1245
|
+
const onAdd = typeof arg1 === "function" && typeof arg2 === "function" ? arg1 : null;
|
|
1246
|
+
const onRemove = typeof arg2 === "function" ? arg2 : typeof arg1 === "function" ? arg1 : null;
|
|
1247
|
+
const { map } = context;
|
|
1248
|
+
if (!map.hasControl(ctrl)) {
|
|
1249
|
+
map.addControl(ctrl, opts == null ? void 0 : opts.position);
|
|
1250
|
+
if (onAdd) {
|
|
1251
|
+
onAdd(context);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
return () => {
|
|
1255
|
+
if (onRemove) {
|
|
1256
|
+
onRemove(context);
|
|
1257
|
+
}
|
|
1258
|
+
if (map.hasControl(ctrl)) {
|
|
1259
|
+
map.removeControl(ctrl);
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
}, []);
|
|
1263
|
+
return ctrl;
|
|
1264
|
+
}
|
|
1265
|
+
function _AttributionControl(props) {
|
|
1266
|
+
const ctrl = useControl(({ mapLib }) => new mapLib.AttributionControl(props), {
|
|
1267
|
+
position: props.position
|
|
1268
|
+
});
|
|
1269
|
+
React.useEffect(() => {
|
|
1270
|
+
applyReactStyle(ctrl._container, props.style);
|
|
1271
|
+
}, [props.style]);
|
|
1272
|
+
return null;
|
|
1273
|
+
}
|
|
1274
|
+
React.memo(_AttributionControl);
|
|
1275
|
+
function _FullscreenControl(props) {
|
|
1276
|
+
const ctrl = useControl(({ mapLib }) => new mapLib.FullscreenControl({
|
|
1277
|
+
container: props.containerId && document.getElementById(props.containerId)
|
|
1278
|
+
}), { position: props.position });
|
|
1279
|
+
React.useEffect(() => {
|
|
1280
|
+
applyReactStyle(ctrl._controlContainer, props.style);
|
|
1281
|
+
}, [props.style]);
|
|
1282
|
+
return null;
|
|
1283
|
+
}
|
|
1284
|
+
React.memo(_FullscreenControl);
|
|
1285
|
+
function _GeolocateControl(props, ref) {
|
|
1286
|
+
const thisRef = React.useRef({ props });
|
|
1287
|
+
const ctrl = useControl(({ mapLib }) => {
|
|
1288
|
+
const gc = new mapLib.GeolocateControl(props);
|
|
1289
|
+
const setupUI = gc._setupUI.bind(gc);
|
|
1290
|
+
gc._setupUI = (args) => {
|
|
1291
|
+
if (!gc._container.hasChildNodes()) {
|
|
1292
|
+
setupUI(args);
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
gc.on("geolocate", (e) => {
|
|
1296
|
+
var _a, _b;
|
|
1297
|
+
(_b = (_a = thisRef.current.props).onGeolocate) == null ? void 0 : _b.call(_a, e);
|
|
1298
|
+
});
|
|
1299
|
+
gc.on("error", (e) => {
|
|
1300
|
+
var _a, _b;
|
|
1301
|
+
(_b = (_a = thisRef.current.props).onError) == null ? void 0 : _b.call(_a, e);
|
|
1302
|
+
});
|
|
1303
|
+
gc.on("outofmaxbounds", (e) => {
|
|
1304
|
+
var _a, _b;
|
|
1305
|
+
(_b = (_a = thisRef.current.props).onOutOfMaxBounds) == null ? void 0 : _b.call(_a, e);
|
|
1306
|
+
});
|
|
1307
|
+
gc.on("trackuserlocationstart", (e) => {
|
|
1308
|
+
var _a, _b;
|
|
1309
|
+
(_b = (_a = thisRef.current.props).onTrackUserLocationStart) == null ? void 0 : _b.call(_a, e);
|
|
1310
|
+
});
|
|
1311
|
+
gc.on("trackuserlocationend", (e) => {
|
|
1312
|
+
var _a, _b;
|
|
1313
|
+
(_b = (_a = thisRef.current.props).onTrackUserLocationEnd) == null ? void 0 : _b.call(_a, e);
|
|
1314
|
+
});
|
|
1315
|
+
return gc;
|
|
1316
|
+
}, { position: props.position });
|
|
1317
|
+
thisRef.current.props = props;
|
|
1318
|
+
React.useImperativeHandle(ref, () => ctrl, []);
|
|
1319
|
+
React.useEffect(() => {
|
|
1320
|
+
applyReactStyle(ctrl._container, props.style);
|
|
1321
|
+
}, [props.style]);
|
|
1322
|
+
return null;
|
|
1323
|
+
}
|
|
1324
|
+
React.memo(React.forwardRef(_GeolocateControl));
|
|
1325
|
+
function _NavigationControl(props) {
|
|
1326
|
+
const ctrl = useControl(({ mapLib }) => new mapLib.NavigationControl(props), {
|
|
1327
|
+
position: props.position
|
|
1328
|
+
});
|
|
1329
|
+
React.useEffect(() => {
|
|
1330
|
+
applyReactStyle(ctrl._container, props.style);
|
|
1331
|
+
}, [props.style]);
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
React.memo(_NavigationControl);
|
|
1335
|
+
function _ScaleControl(props) {
|
|
1336
|
+
const ctrl = useControl(({ mapLib }) => new mapLib.ScaleControl(props), {
|
|
1337
|
+
position: props.position
|
|
1338
|
+
});
|
|
1339
|
+
const propsRef = React.useRef(props);
|
|
1340
|
+
const prevProps = propsRef.current;
|
|
1341
|
+
propsRef.current = props;
|
|
1342
|
+
const { style } = props;
|
|
1343
|
+
if (props.maxWidth !== void 0 && props.maxWidth !== prevProps.maxWidth) {
|
|
1344
|
+
ctrl.options.maxWidth = props.maxWidth;
|
|
1345
|
+
}
|
|
1346
|
+
if (props.unit !== void 0 && props.unit !== prevProps.unit) {
|
|
1347
|
+
ctrl.setUnit(props.unit);
|
|
1348
|
+
}
|
|
1349
|
+
React.useEffect(() => {
|
|
1350
|
+
applyReactStyle(ctrl._container, style);
|
|
1351
|
+
}, [style]);
|
|
1352
|
+
return null;
|
|
1353
|
+
}
|
|
1354
|
+
React.memo(_ScaleControl);
|
|
1355
|
+
function assert(condition, message) {
|
|
1356
|
+
if (!condition) {
|
|
1357
|
+
throw new Error(message);
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
function updateLayer(map, id, props, prevProps) {
|
|
1361
|
+
assert(props.id === prevProps.id, "layer id changed");
|
|
1362
|
+
assert(props.type === prevProps.type, "layer type changed");
|
|
1363
|
+
if (props.type === "custom" || prevProps.type === "custom") {
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
const { layout = {}, paint = {}, filter, minzoom, maxzoom, beforeId } = props;
|
|
1367
|
+
if (beforeId !== prevProps.beforeId) {
|
|
1368
|
+
map.moveLayer(id, beforeId);
|
|
1369
|
+
}
|
|
1370
|
+
if (layout !== prevProps.layout) {
|
|
1371
|
+
const prevLayout = prevProps.layout || {};
|
|
1372
|
+
for (const key in layout) {
|
|
1373
|
+
if (!deepEqual(layout[key], prevLayout[key])) {
|
|
1374
|
+
map.setLayoutProperty(id, key, layout[key]);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
for (const key in prevLayout) {
|
|
1378
|
+
if (!layout.hasOwnProperty(key)) {
|
|
1379
|
+
map.setLayoutProperty(id, key, void 0);
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
if (paint !== prevProps.paint) {
|
|
1384
|
+
const prevPaint = prevProps.paint || {};
|
|
1385
|
+
for (const key in paint) {
|
|
1386
|
+
if (!deepEqual(paint[key], prevPaint[key])) {
|
|
1387
|
+
map.setPaintProperty(id, key, paint[key]);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
for (const key in prevPaint) {
|
|
1391
|
+
if (!paint.hasOwnProperty(key)) {
|
|
1392
|
+
map.setPaintProperty(id, key, void 0);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
if (!deepEqual(filter, prevProps.filter)) {
|
|
1397
|
+
map.setFilter(id, filter);
|
|
1398
|
+
}
|
|
1399
|
+
if (minzoom !== prevProps.minzoom || maxzoom !== prevProps.maxzoom) {
|
|
1400
|
+
map.setLayerZoomRange(id, minzoom, maxzoom);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
function createLayer(map, id, props) {
|
|
1404
|
+
if (map.style && map.style._loaded && (!("source" in props) || map.getSource(props.source))) {
|
|
1405
|
+
const options = { ...props, id };
|
|
1406
|
+
delete options.beforeId;
|
|
1407
|
+
map.addLayer(options, props.beforeId);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
let layerCounter = 0;
|
|
1411
|
+
function Layer(props) {
|
|
1412
|
+
const map = React.useContext(MapContext).map.getMap();
|
|
1413
|
+
const propsRef = React.useRef(props);
|
|
1414
|
+
const [, setStyleLoaded] = React.useState(0);
|
|
1415
|
+
const id = React.useMemo(() => props.id || `jsx-layer-${layerCounter++}`, []);
|
|
1416
|
+
React.useEffect(() => {
|
|
1417
|
+
if (map) {
|
|
1418
|
+
const forceUpdate = () => setStyleLoaded((version) => version + 1);
|
|
1419
|
+
map.on("styledata", forceUpdate);
|
|
1420
|
+
forceUpdate();
|
|
1421
|
+
return () => {
|
|
1422
|
+
map.off("styledata", forceUpdate);
|
|
1423
|
+
if (map.style && map.style._loaded && map.getLayer(id)) {
|
|
1424
|
+
map.removeLayer(id);
|
|
1425
|
+
}
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
return void 0;
|
|
1429
|
+
}, [map]);
|
|
1430
|
+
const layer = map && map.style && map.getLayer(id);
|
|
1431
|
+
if (layer) {
|
|
1432
|
+
try {
|
|
1433
|
+
updateLayer(map, id, props, propsRef.current);
|
|
1434
|
+
} catch (error) {
|
|
1435
|
+
console.warn(error);
|
|
1436
|
+
}
|
|
1437
|
+
} else {
|
|
1438
|
+
createLayer(map, id, props);
|
|
1439
|
+
}
|
|
1440
|
+
propsRef.current = props;
|
|
1441
|
+
return null;
|
|
1442
|
+
}
|
|
206
1443
|
const useFunction = (callback) => {
|
|
207
|
-
const callbackRef =
|
|
1444
|
+
const callbackRef = React.useRef(callback);
|
|
208
1445
|
callbackRef.current = callback;
|
|
209
|
-
return
|
|
1446
|
+
return React.useCallback((...args) => {
|
|
210
1447
|
return callbackRef.current(...args);
|
|
211
1448
|
}, []);
|
|
212
1449
|
};
|
|
@@ -218,7 +1455,8 @@ function useRender({
|
|
|
218
1455
|
r3m
|
|
219
1456
|
}) {
|
|
220
1457
|
const render = useFunction((_gl, projViewMx) => {
|
|
221
|
-
|
|
1458
|
+
const pVMx = "defaultProjectionData" in projViewMx ? Object.values(projViewMx.defaultProjectionData.mainMatrix) : projViewMx;
|
|
1459
|
+
r3m.viewProjMx.splice(0, 16, ...pVMx);
|
|
222
1460
|
const state = useThree.getState();
|
|
223
1461
|
const camera = state.camera;
|
|
224
1462
|
const { gl, advance } = state;
|
|
@@ -252,7 +1490,7 @@ const events = (store) => {
|
|
|
252
1490
|
};
|
|
253
1491
|
};
|
|
254
1492
|
function useRoot(fromLngLat2, map, { frameloop, longitude, latitude, altitude, ...props }) {
|
|
255
|
-
const [{ root, useThree, canvas, r3m }] =
|
|
1493
|
+
const [{ root, useThree, canvas, r3m }] = React.useState(() => {
|
|
256
1494
|
const canvas2 = map.getCanvas();
|
|
257
1495
|
const gl = canvas2.getContext("webgl2") || canvas2.getContext("webgl");
|
|
258
1496
|
const root2 = fiber.createRoot(canvas2);
|
|
@@ -312,7 +1550,7 @@ function useRoot(fromLngLat2, map, { frameloop, longitude, latitude, altitude, .
|
|
|
312
1550
|
root.unmount();
|
|
313
1551
|
});
|
|
314
1552
|
useSetRootCoords(useThree, { longitude, latitude, altitude });
|
|
315
|
-
|
|
1553
|
+
React.useEffect(() => {
|
|
316
1554
|
if (frameloop !== "demand")
|
|
317
1555
|
return;
|
|
318
1556
|
const setState = useThree.setState;
|
|
@@ -327,13 +1565,13 @@ function useRoot(fromLngLat2, map, { frameloop, longitude, latitude, altitude, .
|
|
|
327
1565
|
setState({ frameloop: "never", invalidate });
|
|
328
1566
|
};
|
|
329
1567
|
}, [frameloop]);
|
|
330
|
-
|
|
1568
|
+
React.useEffect(() => {
|
|
331
1569
|
map.on("resize", onResize);
|
|
332
1570
|
return () => {
|
|
333
1571
|
map.off("resize", onResize);
|
|
334
1572
|
};
|
|
335
1573
|
}, []);
|
|
336
|
-
|
|
1574
|
+
React.useEffect(() => {
|
|
337
1575
|
root.render(/* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: props.children }));
|
|
338
1576
|
}, [props.children]);
|
|
339
1577
|
return { onRemove, useThree, r3m };
|
|
@@ -357,7 +1595,7 @@ function useCanvasInLayer(props, fromLngLat2, map) {
|
|
|
357
1595
|
renderingMode: "3d"
|
|
358
1596
|
};
|
|
359
1597
|
}
|
|
360
|
-
const InitR3M =
|
|
1598
|
+
const InitR3M = React.memo(({
|
|
361
1599
|
longitude,
|
|
362
1600
|
latitude,
|
|
363
1601
|
altitude,
|
|
@@ -368,7 +1606,7 @@ const InitR3M = react.memo(({
|
|
|
368
1606
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
369
1607
|
});
|
|
370
1608
|
InitR3M.displayName = "InitR3M";
|
|
371
|
-
const SyncCameraFC =
|
|
1609
|
+
const SyncCameraFC = React.memo(({
|
|
372
1610
|
latitude,
|
|
373
1611
|
longitude,
|
|
374
1612
|
altitude = 0,
|
|
@@ -379,7 +1617,7 @@ const SyncCameraFC = react.memo(({
|
|
|
379
1617
|
}) => {
|
|
380
1618
|
const mapCanvas = map.getCanvas();
|
|
381
1619
|
const r3m = useR3M();
|
|
382
|
-
const camRef =
|
|
1620
|
+
const camRef = React.useRef(null);
|
|
383
1621
|
const camera = fiber.useThree((s) => s.camera);
|
|
384
1622
|
const gl = fiber.useThree((s) => s.gl);
|
|
385
1623
|
const threeCanvas = fiber.useThree((s) => s.gl.domElement);
|
|
@@ -388,9 +1626,9 @@ const SyncCameraFC = react.memo(({
|
|
|
388
1626
|
const setSize = fiber.useThree((s) => s.setSize);
|
|
389
1627
|
const set = fiber.useThree((s) => s.set);
|
|
390
1628
|
const origin = useCoordsToMatrix({ latitude, longitude, altitude, fromLngLat: r3m.fromLngLat });
|
|
391
|
-
const ready =
|
|
392
|
-
const triggerRepaint =
|
|
393
|
-
const mapPaintRequests =
|
|
1629
|
+
const ready = React.useRef(false);
|
|
1630
|
+
const triggerRepaint = React.useMemo(() => map.triggerRepaint, [map]);
|
|
1631
|
+
const mapPaintRequests = React.useRef(0);
|
|
394
1632
|
const triggerRepaintOff = useFunction(() => {
|
|
395
1633
|
mapPaintRequests.current++;
|
|
396
1634
|
});
|
|
@@ -422,10 +1660,10 @@ const SyncCameraFC = react.memo(({
|
|
|
422
1660
|
}
|
|
423
1661
|
advance(Date.now() * 1e-3, true);
|
|
424
1662
|
});
|
|
425
|
-
|
|
1663
|
+
React.useEffect(() => {
|
|
426
1664
|
setOnRender && setOnRender(() => onRender);
|
|
427
1665
|
}, [setOnRender, onRender]);
|
|
428
|
-
|
|
1666
|
+
React.useLayoutEffect(() => {
|
|
429
1667
|
if (!manualRender)
|
|
430
1668
|
return;
|
|
431
1669
|
set({ camera: camRef.current });
|
|
@@ -440,7 +1678,7 @@ const SyncCameraFC = react.memo(({
|
|
|
440
1678
|
) });
|
|
441
1679
|
});
|
|
442
1680
|
SyncCameraFC.displayName = "SyncCameraFC";
|
|
443
|
-
const CanvasPortal =
|
|
1681
|
+
const CanvasPortal = React.memo(({
|
|
444
1682
|
children,
|
|
445
1683
|
latitude,
|
|
446
1684
|
longitude,
|
|
@@ -452,7 +1690,7 @@ const CanvasPortal = react.memo(({
|
|
|
452
1690
|
}) => {
|
|
453
1691
|
const mapCanvas = map.getCanvas();
|
|
454
1692
|
const eventSource = mapCanvas.parentElement;
|
|
455
|
-
const [ready, setReady] =
|
|
1693
|
+
const [ready, setReady] = React.useState(false);
|
|
456
1694
|
const onReady = useFunction(() => {
|
|
457
1695
|
setReady(true);
|
|
458
1696
|
});
|
|
@@ -495,9 +1733,9 @@ const CanvasPortal = react.memo(({
|
|
|
495
1733
|
);
|
|
496
1734
|
});
|
|
497
1735
|
CanvasPortal.displayName = "CanvasPortal";
|
|
498
|
-
const InitCanvasFC =
|
|
1736
|
+
const InitCanvasFC = React.memo((props) => {
|
|
499
1737
|
const canvas = props.map.getCanvas();
|
|
500
|
-
const [el] =
|
|
1738
|
+
const [el] = React.useState(() => {
|
|
501
1739
|
const el2 = document.createElement("div");
|
|
502
1740
|
el2.style.position = "absolute";
|
|
503
1741
|
el2.style.top = "0";
|
|
@@ -507,7 +1745,7 @@ const InitCanvasFC = react.memo((props) => {
|
|
|
507
1745
|
el2.style.pointerEvents = "none";
|
|
508
1746
|
return el2;
|
|
509
1747
|
});
|
|
510
|
-
|
|
1748
|
+
React.useEffect(() => {
|
|
511
1749
|
const parent = canvas.parentElement;
|
|
512
1750
|
parent.appendChild(el);
|
|
513
1751
|
return () => {
|
|
@@ -519,28 +1757,28 @@ const InitCanvasFC = react.memo((props) => {
|
|
|
519
1757
|
InitCanvasFC.displayName = "InitCanvasFC";
|
|
520
1758
|
fiber.extend(THREE__namespace);
|
|
521
1759
|
const fromLngLat = mapboxGl.MercatorCoordinate.fromLngLat;
|
|
522
|
-
const Canvas =
|
|
523
|
-
const map =
|
|
1760
|
+
const Canvas = React.memo(({ overlay, ...props }) => {
|
|
1761
|
+
const map = useMap$1().current.getMap();
|
|
524
1762
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
525
1763
|
overlay && /* @__PURE__ */ jsxRuntime.jsx(CanvasOverlay, { map, ...props }),
|
|
526
1764
|
!overlay && /* @__PURE__ */ jsxRuntime.jsx(CanvasInLayer, { map, ...props })
|
|
527
1765
|
] });
|
|
528
1766
|
});
|
|
529
1767
|
Canvas.displayName = "Canvas";
|
|
530
|
-
const CanvasInLayer =
|
|
1768
|
+
const CanvasInLayer = React.memo(({ map, ...props }) => {
|
|
531
1769
|
const layerProps = useCanvasInLayer(props, fromLngLat, map);
|
|
532
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1770
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Layer, { ...layerProps });
|
|
533
1771
|
});
|
|
534
1772
|
CanvasInLayer.displayName = "CanvasInLayer";
|
|
535
|
-
const CanvasOverlay =
|
|
536
|
-
const [onRender, setOnRender] =
|
|
1773
|
+
const CanvasOverlay = React.memo(({ map, id, beforeId, ...props }) => {
|
|
1774
|
+
const [onRender, setOnRender] = React.useState();
|
|
537
1775
|
const render = useFunction((_gl, mx) => {
|
|
538
1776
|
if (!onRender)
|
|
539
1777
|
return;
|
|
540
1778
|
onRender(mx);
|
|
541
1779
|
});
|
|
542
1780
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
543
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1781
|
+
/* @__PURE__ */ jsxRuntime.jsx(Layer, { id, beforeId, type: "custom", render }),
|
|
544
1782
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
545
1783
|
InitCanvasFC,
|
|
546
1784
|
{
|
|
@@ -553,10 +1791,11 @@ const CanvasOverlay = react.memo(({ map, id, beforeId, ...props }) => {
|
|
|
553
1791
|
] });
|
|
554
1792
|
});
|
|
555
1793
|
CanvasInLayer.displayName = "CanvasInLayer";
|
|
556
|
-
const useMap = useMap$
|
|
1794
|
+
const useMap = useMap$2;
|
|
557
1795
|
exports.Canvas = Canvas;
|
|
558
1796
|
exports.Coordinates = Coordinates;
|
|
559
1797
|
exports.NearCoordinates = NearCoordinates;
|
|
1798
|
+
exports.averageMercatorScale = averageMercatorScale;
|
|
560
1799
|
exports.coordsToVector3 = coordsToVector3;
|
|
561
1800
|
exports.useMap = useMap;
|
|
562
1801
|
exports.vector3ToCoords = vector3ToCoords;
|