@maplibre/maplibre-react-native 10.0.0-alpha.24 → 10.0.0-alpha.25
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/.husky/pre-commit +1 -1
- package/CHANGELOG.md +6 -0
- package/CONTRIBUTING.md +1 -1
- package/docs/Annotation.md +2 -11
- package/docs/BackgroundLayer.md +2 -1
- package/docs/Callout.md +2 -1
- package/docs/Camera.md +28 -29
- package/docs/CircleLayer.md +2 -1
- package/docs/FillExtrusionLayer.md +2 -1
- package/docs/FillLayer.md +2 -1
- package/docs/HeadingIndicator.md +2 -1
- package/docs/HeatmapLayer.md +2 -1
- package/docs/ImageSource.md +2 -1
- package/docs/Images.md +2 -1
- package/docs/Light.md +2 -1
- package/docs/LineLayer.md +2 -1
- package/docs/MapView.md +5 -4
- package/docs/MarkerView.md +2 -1
- package/docs/NativeUserLocation.md +2 -1
- package/docs/PointAnnotation.md +2 -1
- package/docs/RasterLayer.md +2 -1
- package/docs/RasterSource.md +2 -1
- package/docs/ShapeSource.md +2 -1
- package/docs/Style.md +2 -1
- package/docs/SymbolLayer.md +2 -1
- package/docs/UserLocation.md +2 -1
- package/docs/VectorSource.md +3 -2
- package/docs/coordinates.md +2 -1
- package/docs/docs.json +49 -88
- package/docs/location.md +2 -1
- package/docs/offlineManager.md +3 -2
- package/docs/snapshotManager.md +2 -1
- package/ios/RCTMLN/RCTMLNCamera.h +0 -3
- package/ios/RCTMLN/RCTMLNCamera.m +1 -1
- package/ios/RCTMLN/RCTMLNCameraManager.m +0 -3
- package/javascript/MLNModule.ts +9 -0
- package/javascript/Maplibre.ts +1 -1
- package/javascript/components/{annotations/Annotation.tsx → Annotation.tsx} +5 -5
- package/javascript/components/Camera.tsx +257 -388
- package/javascript/components/UserLocation.tsx +1 -1
- package/javascript/hooks/useNativeRef.ts +2 -1
- package/javascript/types/CameraMode.ts +6 -0
- package/package.json +7 -8
- package/scripts/codegen.ts +341 -0
- package/scripts/templates/MaplibreStyles.ts.ejs +8 -7
- package/scripts/templates/RCTMLNStyle.h.ejs +4 -3
- package/scripts/templates/RCTMLNStyle.m.ejs +11 -10
- package/scripts/templates/RCTMLNStyleFactory.java.ejs +12 -11
- package/scripts/templates/component.md.ejs +14 -12
- package/scripts/templates/index.d.ts.ejs +2 -1
- package/scripts/templates/styleMap.ts.ejs +2 -1
- package/scripts/utils/{DocJSONBuilder.js → DocJSONBuilder.ts} +133 -128
- package/scripts/utils/{JSDocNodeTree.js → JSDocNodeTree.ts} +14 -13
- package/scripts/utils/MarkdownBuilder.ts +44 -0
- package/scripts/utils/{template-globals.js → TemplateHelpers.ts} +65 -94
- package/scripts/utils/getNativeVersion.ts +53 -0
- package/tsconfig.json +2 -3
- package/docs/OfflineManager.md +0 -246
- package/scripts/download-style-spec.sh +0 -15
- package/scripts/generate-docs.js +0 -396
- package/scripts/utils/MarkdownBuilder.js +0 -37
- package/style-spec/v8.json +0 -6645
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import { point } from "@turf/helpers";
|
|
2
|
-
import React, {
|
|
3
|
-
|
|
4
|
-
RefObject,
|
|
5
|
-
useCallback,
|
|
6
|
-
useEffect,
|
|
7
|
-
useImperativeHandle,
|
|
8
|
-
useMemo,
|
|
9
|
-
useRef,
|
|
10
|
-
} from "react";
|
|
11
|
-
import { NativeModules, requireNativeComponent, ViewProps } from "react-native";
|
|
2
|
+
import React, { forwardRef, memo, useImperativeHandle, useMemo } from "react";
|
|
3
|
+
import { requireNativeComponent, ViewProps } from "react-native";
|
|
12
4
|
|
|
5
|
+
import { CameraModes } from "../MLNModule";
|
|
13
6
|
import { useNativeRef } from "../hooks/useNativeRef";
|
|
14
7
|
import { MaplibreGLEvent } from "../types";
|
|
8
|
+
import BaseProps from "../types/BaseProps";
|
|
9
|
+
import { CameraMode } from "../types/CameraMode";
|
|
15
10
|
import { makeNativeBounds } from "../utils/makeNativeBounds";
|
|
16
11
|
|
|
17
|
-
const MapLibreGL = NativeModules.MLNModule;
|
|
18
|
-
|
|
19
12
|
export const NATIVE_MODULE_NAME = "RCTMLNCamera";
|
|
20
13
|
|
|
21
14
|
export enum UserTrackingMode {
|
|
@@ -34,32 +27,91 @@ export type UserTrackingModeChangeCallback = (
|
|
|
34
27
|
>,
|
|
35
28
|
) => void;
|
|
36
29
|
|
|
30
|
+
export function getNativeCameraMode(mode?: CameraAnimationMode): CameraMode {
|
|
31
|
+
switch (mode) {
|
|
32
|
+
case "flyTo":
|
|
33
|
+
return CameraModes.Flight;
|
|
34
|
+
case "moveTo":
|
|
35
|
+
return CameraModes.None;
|
|
36
|
+
case "linearTo":
|
|
37
|
+
return CameraModes.Linear;
|
|
38
|
+
case "easeTo":
|
|
39
|
+
return CameraModes.Ease;
|
|
40
|
+
default:
|
|
41
|
+
return CameraModes.None;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function makeNativeCameraStop(stop?: CameraStop): NativeCameraStop | undefined {
|
|
46
|
+
if (!stop) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const nativeStop: NativeCameraStop = {};
|
|
51
|
+
|
|
52
|
+
if (stop.animationDuration !== undefined) {
|
|
53
|
+
nativeStop.duration = stop.animationDuration;
|
|
54
|
+
}
|
|
55
|
+
if (stop.animationMode !== undefined) {
|
|
56
|
+
nativeStop.mode = getNativeCameraMode(stop.animationMode);
|
|
57
|
+
}
|
|
58
|
+
if (stop.centerCoordinate) {
|
|
59
|
+
nativeStop.centerCoordinate = JSON.stringify(point(stop.centerCoordinate));
|
|
60
|
+
}
|
|
61
|
+
if (stop.heading !== undefined) {
|
|
62
|
+
nativeStop.heading = stop.heading;
|
|
63
|
+
}
|
|
64
|
+
if (stop.pitch !== undefined) {
|
|
65
|
+
nativeStop.pitch = stop.pitch;
|
|
66
|
+
}
|
|
67
|
+
if (stop.zoomLevel !== undefined) {
|
|
68
|
+
nativeStop.zoom = stop.zoomLevel;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (stop.bounds && stop.bounds.ne && stop.bounds.sw) {
|
|
72
|
+
const { ne, sw } = stop.bounds;
|
|
73
|
+
nativeStop.bounds = makeNativeBounds(ne, sw);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const paddingTop = stop.padding?.paddingTop ?? stop.bounds?.paddingTop;
|
|
77
|
+
if (paddingTop !== undefined) {
|
|
78
|
+
nativeStop.paddingTop = paddingTop;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const paddingRight = stop.padding?.paddingRight ?? stop.bounds?.paddingRight;
|
|
82
|
+
if (paddingRight !== undefined) {
|
|
83
|
+
nativeStop.paddingRight = paddingRight;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const paddingBottom =
|
|
87
|
+
stop.padding?.paddingBottom ?? stop.bounds?.paddingBottom;
|
|
88
|
+
if (paddingBottom !== undefined) {
|
|
89
|
+
nativeStop.paddingBottom = paddingBottom;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const paddingLeft = stop.padding?.paddingLeft ?? stop.bounds?.paddingLeft;
|
|
93
|
+
if (paddingLeft !== undefined) {
|
|
94
|
+
nativeStop.paddingLeft = paddingLeft;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return nativeStop;
|
|
98
|
+
}
|
|
99
|
+
|
|
37
100
|
export interface CameraRef {
|
|
38
101
|
setCamera: (config: CameraStop | CameraStops) => void;
|
|
102
|
+
|
|
39
103
|
fitBounds: (
|
|
40
104
|
ne: GeoJSON.Position,
|
|
41
105
|
sw: GeoJSON.Position,
|
|
42
106
|
paddingConfig?: number | number[],
|
|
43
107
|
animationDuration?: number,
|
|
44
108
|
) => void;
|
|
45
|
-
flyTo: (
|
|
46
|
-
centerCoordinate: GeoJSON.Position,
|
|
47
|
-
animationDuration?: number,
|
|
48
|
-
) => void;
|
|
49
|
-
moveTo: (
|
|
50
|
-
centerCoordinate: GeoJSON.Position,
|
|
51
|
-
animationDuration?: number,
|
|
52
|
-
) => void;
|
|
53
|
-
zoomTo: (zoomLevel: number, animationDuration?: number) => void;
|
|
54
109
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
ignoreFollowUserLocation?: boolean,
|
|
61
|
-
) => NativeCameraStop | null;
|
|
62
|
-
_createDefaultCamera: () => NativeCameraStop | null;
|
|
110
|
+
flyTo: (coordinates: GeoJSON.Position, animationDuration?: number) => void;
|
|
111
|
+
|
|
112
|
+
moveTo: (coordinates: GeoJSON.Position, animationDuration?: number) => void;
|
|
113
|
+
|
|
114
|
+
zoomTo: (zoomLevel: number, animationDuration?: number) => void;
|
|
63
115
|
}
|
|
64
116
|
|
|
65
117
|
export interface CameraPadding {
|
|
@@ -96,14 +148,13 @@ interface CameraBoundsWithPadding
|
|
|
96
148
|
extends CameraBounds,
|
|
97
149
|
Partial<CameraPadding> {}
|
|
98
150
|
|
|
99
|
-
type NativeAnimationMode = "flight" | "ease" | "linear" | "none" | "move";
|
|
100
151
|
export type CameraAnimationMode = "flyTo" | "easeTo" | "linearTo" | "moveTo";
|
|
101
152
|
|
|
102
|
-
export interface NativeCameraStop extends
|
|
103
|
-
|
|
153
|
+
export interface NativeCameraStop extends CameraPadding {
|
|
154
|
+
duration?: number;
|
|
155
|
+
mode?: CameraMode;
|
|
104
156
|
pitch?: number;
|
|
105
157
|
heading?: number;
|
|
106
|
-
duration: number;
|
|
107
158
|
zoom?: number;
|
|
108
159
|
centerCoordinate?: string;
|
|
109
160
|
bounds?: string;
|
|
@@ -133,24 +184,19 @@ export type CameraStops = {
|
|
|
133
184
|
stops: CameraStop[];
|
|
134
185
|
};
|
|
135
186
|
|
|
136
|
-
interface CameraProps extends
|
|
137
|
-
/**
|
|
138
|
-
* If false, the camera will not send any props to the native module. Intended to be used to prevent unnecessary tile fetching and improve performance when the map is not visible. Defaults to true.
|
|
139
|
-
*/
|
|
140
|
-
allowUpdates?: boolean;
|
|
141
|
-
|
|
187
|
+
export interface CameraProps extends BaseProps, CameraStop {
|
|
142
188
|
/**
|
|
143
189
|
* Default view settings applied on camera
|
|
144
190
|
*/
|
|
145
191
|
defaultSettings?: CameraStop;
|
|
146
192
|
|
|
147
193
|
/**
|
|
148
|
-
*
|
|
194
|
+
* Minimum zoom level of the map
|
|
149
195
|
*/
|
|
150
196
|
minZoomLevel?: number;
|
|
151
197
|
|
|
152
198
|
/**
|
|
153
|
-
*
|
|
199
|
+
* Maximum zoom level of the map
|
|
154
200
|
*/
|
|
155
201
|
maxZoomLevel?: number;
|
|
156
202
|
|
|
@@ -185,39 +231,161 @@ interface CameraProps extends Omit<ViewProps, "style">, CameraStop {
|
|
|
185
231
|
followHeading?: number;
|
|
186
232
|
|
|
187
233
|
/**
|
|
188
|
-
*
|
|
234
|
+
* Triggered when `followUserLocation` or `followUserMode` changes
|
|
189
235
|
*/
|
|
190
|
-
triggerKey?: string | number;
|
|
191
|
-
|
|
192
|
-
// Triggered when the
|
|
193
236
|
onUserTrackingModeChange?: UserTrackingModeChangeCallback;
|
|
194
237
|
}
|
|
195
238
|
|
|
196
|
-
interface
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
239
|
+
export interface NativeCameraProps
|
|
240
|
+
extends Omit<CameraProps, "maxBounds">,
|
|
241
|
+
ViewProps {
|
|
242
|
+
maxBounds?: string;
|
|
243
|
+
stop?: NativeCameraStop;
|
|
244
|
+
defaultStop?: NativeCameraStop;
|
|
200
245
|
}
|
|
201
246
|
|
|
202
247
|
const Camera = memo(
|
|
203
|
-
|
|
248
|
+
forwardRef<CameraRef, CameraProps>(
|
|
204
249
|
(
|
|
205
250
|
{
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
251
|
+
animationMode,
|
|
252
|
+
animationDuration,
|
|
253
|
+
bounds,
|
|
254
|
+
centerCoordinate,
|
|
255
|
+
defaultSettings,
|
|
256
|
+
followUserLocation,
|
|
257
|
+
followHeading,
|
|
258
|
+
followPitch,
|
|
259
|
+
followUserMode,
|
|
260
|
+
followZoomLevel,
|
|
261
|
+
heading,
|
|
262
|
+
maxBounds,
|
|
263
|
+
maxZoomLevel,
|
|
264
|
+
minZoomLevel,
|
|
265
|
+
onUserTrackingModeChange,
|
|
266
|
+
padding,
|
|
267
|
+
pitch,
|
|
268
|
+
zoomLevel,
|
|
210
269
|
}: CameraProps,
|
|
211
270
|
ref,
|
|
212
271
|
) => {
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
272
|
+
const nativeCamera = useNativeRef<NativeCameraProps>();
|
|
273
|
+
|
|
274
|
+
const nativeStop = useMemo(() => {
|
|
275
|
+
return makeNativeCameraStop({
|
|
276
|
+
animationDuration,
|
|
216
277
|
animationMode,
|
|
278
|
+
bounds,
|
|
279
|
+
centerCoordinate,
|
|
280
|
+
heading,
|
|
281
|
+
padding,
|
|
282
|
+
pitch,
|
|
283
|
+
zoomLevel,
|
|
284
|
+
});
|
|
285
|
+
}, [
|
|
286
|
+
animationDuration,
|
|
287
|
+
animationMode,
|
|
288
|
+
bounds,
|
|
289
|
+
centerCoordinate,
|
|
290
|
+
heading,
|
|
291
|
+
padding,
|
|
292
|
+
pitch,
|
|
293
|
+
zoomLevel,
|
|
294
|
+
]);
|
|
295
|
+
|
|
296
|
+
const nativeDefaultStop = useMemo(() => {
|
|
297
|
+
return makeNativeCameraStop(defaultSettings);
|
|
298
|
+
}, [defaultSettings]);
|
|
299
|
+
|
|
300
|
+
const nativeMaxBounds = useMemo(() => {
|
|
301
|
+
if (!maxBounds?.ne || !maxBounds?.sw) {
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
304
|
+
return makeNativeBounds(maxBounds.ne, maxBounds.sw);
|
|
305
|
+
}, [maxBounds]);
|
|
306
|
+
|
|
307
|
+
const setCamera = (config: CameraStop | CameraStops = {}): void => {
|
|
308
|
+
if ("stops" in config) {
|
|
309
|
+
nativeCamera.current?.setNativeProps({
|
|
310
|
+
stop: {
|
|
311
|
+
stops: config.stops
|
|
312
|
+
.map((stopItem) => makeNativeCameraStop(stopItem))
|
|
313
|
+
.filter((stopItem) => !!stopItem),
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
} else {
|
|
317
|
+
const nativeStop = makeNativeCameraStop(config);
|
|
318
|
+
|
|
319
|
+
if (nativeStop) {
|
|
320
|
+
nativeCamera.current?.setNativeProps({ stop: nativeStop });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const fitBounds = (
|
|
326
|
+
ne: GeoJSON.Position,
|
|
327
|
+
sw: GeoJSON.Position,
|
|
328
|
+
padding?: number | number[],
|
|
329
|
+
animationDuration?: number,
|
|
330
|
+
): void => {
|
|
331
|
+
const _padding: CameraPadding = {};
|
|
332
|
+
|
|
333
|
+
if (Array.isArray(padding)) {
|
|
334
|
+
if (padding.length === 2) {
|
|
335
|
+
_padding.paddingTop = padding[0];
|
|
336
|
+
_padding.paddingBottom = padding[0];
|
|
337
|
+
_padding.paddingLeft = padding[1];
|
|
338
|
+
_padding.paddingRight = padding[1];
|
|
339
|
+
} else if (padding.length === 4) {
|
|
340
|
+
_padding.paddingTop = padding[0];
|
|
341
|
+
_padding.paddingRight = padding[1];
|
|
342
|
+
_padding.paddingBottom = padding[2];
|
|
343
|
+
_padding.paddingLeft = padding[3];
|
|
344
|
+
}
|
|
345
|
+
} else if (typeof padding === "number") {
|
|
346
|
+
_padding.paddingLeft = padding;
|
|
347
|
+
_padding.paddingRight = padding;
|
|
348
|
+
_padding.paddingTop = padding;
|
|
349
|
+
_padding.paddingBottom = padding;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
setCamera({
|
|
353
|
+
bounds: { ne, sw },
|
|
354
|
+
padding: _padding,
|
|
217
355
|
animationDuration,
|
|
218
|
-
|
|
219
|
-
};
|
|
220
|
-
}
|
|
356
|
+
animationMode: "easeTo",
|
|
357
|
+
});
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
const flyTo = (
|
|
361
|
+
coordinates: GeoJSON.Position,
|
|
362
|
+
animationDuration = 2000,
|
|
363
|
+
): void => {
|
|
364
|
+
setCamera({
|
|
365
|
+
centerCoordinate: coordinates,
|
|
366
|
+
animationDuration,
|
|
367
|
+
animationMode: "flyTo",
|
|
368
|
+
});
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const moveTo = (
|
|
372
|
+
coordinates: GeoJSON.Position,
|
|
373
|
+
animationDuration = 0,
|
|
374
|
+
): void => {
|
|
375
|
+
setCamera({
|
|
376
|
+
centerCoordinate: coordinates,
|
|
377
|
+
animationDuration,
|
|
378
|
+
animationMode: "easeTo",
|
|
379
|
+
});
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const zoomTo = (zoomLevel: number, animationDuration = 2000): void => {
|
|
383
|
+
setCamera({
|
|
384
|
+
zoomLevel,
|
|
385
|
+
animationDuration,
|
|
386
|
+
animationMode: "flyTo",
|
|
387
|
+
});
|
|
388
|
+
};
|
|
221
389
|
|
|
222
390
|
useImperativeHandle(
|
|
223
391
|
ref,
|
|
@@ -226,13 +394,13 @@ const Camera = memo(
|
|
|
226
394
|
* Map camera transitions to fit provided bounds
|
|
227
395
|
*
|
|
228
396
|
* @example
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
397
|
+
* cameraRef.current?.fitBounds([lng, lat], [lng, lat])
|
|
398
|
+
* cameraRef.current?.fitBounds([lng, lat], [lng, lat], 20, 1000) // padding for all sides
|
|
399
|
+
* cameraRef.current?.fitBounds([lng, lat], [lng, lat], [verticalPadding, horizontalPadding], 1000)
|
|
400
|
+
* cameraRef.current?.fitBounds([lng, lat], [lng, lat], [top, right, bottom, left], 1000)
|
|
233
401
|
*
|
|
234
|
-
* @param {Array<Number>}
|
|
235
|
-
* @param {Array<Number>}
|
|
402
|
+
* @param {Array<Number>} ne - North east coordinate of bound
|
|
403
|
+
* @param {Array<Number>} sw - South west coordinate of bound
|
|
236
404
|
* @param {Number|Array<Number>|undefined} padding - Padding for the bounds
|
|
237
405
|
* @param {Number=} animationDuration - Duration of camera animation
|
|
238
406
|
* @return {void}
|
|
@@ -242,10 +410,10 @@ const Camera = memo(
|
|
|
242
410
|
* Map camera will fly to new coordinate
|
|
243
411
|
*
|
|
244
412
|
* @example
|
|
245
|
-
*
|
|
246
|
-
*
|
|
413
|
+
* cameraRef.current?.flyTo([lng, lat])
|
|
414
|
+
* cameraRef.current?.flyTo([lng, lat], 12000)
|
|
247
415
|
*
|
|
248
|
-
* @param {Array<Number>} coordinates - Coordinates that map camera will jump
|
|
416
|
+
* @param {Array<Number>} coordinates - Coordinates that map camera will jump to
|
|
249
417
|
* @param {Number=} animationDuration - Duration of camera animation
|
|
250
418
|
* @return {void}
|
|
251
419
|
*/
|
|
@@ -254,8 +422,8 @@ const Camera = memo(
|
|
|
254
422
|
* Map camera will move to new coordinate at the same zoom level
|
|
255
423
|
*
|
|
256
424
|
* @example
|
|
257
|
-
*
|
|
258
|
-
*
|
|
425
|
+
* cameraRef.current?.moveTo([lng, lat], 200) // eases camera to new location based on duration
|
|
426
|
+
* cameraRef.current?.moveTo([lng, lat]) // snaps camera to new location without any easing
|
|
259
427
|
*
|
|
260
428
|
* @param {Array<Number>} coordinates - Coordinates that map camera will move too
|
|
261
429
|
* @param {Number=} animationDuration - Duration of camera animation
|
|
@@ -266,8 +434,8 @@ const Camera = memo(
|
|
|
266
434
|
* Map camera will zoom to specified level
|
|
267
435
|
*
|
|
268
436
|
* @example
|
|
269
|
-
*
|
|
270
|
-
*
|
|
437
|
+
* cameraRef.current?.zoomTo(16)
|
|
438
|
+
* cameraRef.current?.zoomTo(16, 100)
|
|
271
439
|
*
|
|
272
440
|
* @param {Number} zoomLevel - Zoom level that the map camera will animate too
|
|
273
441
|
* @param {Number=} animationDuration - Duration of camera animation
|
|
@@ -278,13 +446,13 @@ const Camera = memo(
|
|
|
278
446
|
* Map camera will perform updates based on provided config. Advanced use only!
|
|
279
447
|
*
|
|
280
448
|
* @example
|
|
281
|
-
*
|
|
449
|
+
* cameraRef.current?.setCamera({
|
|
282
450
|
* centerCoordinate: [lng, lat],
|
|
283
451
|
* zoomLevel: 16,
|
|
284
452
|
* animationDuration: 2000,
|
|
285
453
|
* })
|
|
286
454
|
*
|
|
287
|
-
*
|
|
455
|
+
* cameraRef.current?.setCamera({
|
|
288
456
|
* stops: [
|
|
289
457
|
* { pitch: 45, animationDuration: 200 },
|
|
290
458
|
* { heading: 180, animationDuration: 300 },
|
|
@@ -294,330 +462,31 @@ const Camera = memo(
|
|
|
294
462
|
* @param {Object} config - Camera configuration
|
|
295
463
|
*/
|
|
296
464
|
setCamera,
|
|
297
|
-
_defaultCamera,
|
|
298
|
-
_getMaxBounds,
|
|
299
|
-
_getNativeCameraMode,
|
|
300
|
-
_createStopConfig,
|
|
301
|
-
_createDefaultCamera,
|
|
302
465
|
}),
|
|
303
466
|
);
|
|
304
467
|
|
|
305
|
-
const _defaultCamera = useRef<NativeCameraStop | null>(null);
|
|
306
|
-
|
|
307
|
-
const cameraRef = useNativeRef<NativeProps>();
|
|
308
|
-
|
|
309
|
-
const _createStopConfig = useCallback(
|
|
310
|
-
(
|
|
311
|
-
config: CameraStop = {},
|
|
312
|
-
ignoreFollowUserLocation = false,
|
|
313
|
-
): NativeCameraStop | null => {
|
|
314
|
-
if (props.followUserLocation && !ignoreFollowUserLocation) {
|
|
315
|
-
return null;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
const stopConfig: NativeCameraStop = {
|
|
319
|
-
mode: _getNativeCameraMode(config),
|
|
320
|
-
pitch: config.pitch,
|
|
321
|
-
heading: config.heading,
|
|
322
|
-
duration: config.animationDuration || 0,
|
|
323
|
-
zoom: config.zoomLevel,
|
|
324
|
-
paddingTop:
|
|
325
|
-
config.padding?.paddingTop || config.bounds?.paddingTop || 0,
|
|
326
|
-
paddingRight:
|
|
327
|
-
config.padding?.paddingRight || config.bounds?.paddingRight || 0,
|
|
328
|
-
paddingBottom:
|
|
329
|
-
config.padding?.paddingBottom ||
|
|
330
|
-
config.bounds?.paddingBottom ||
|
|
331
|
-
0,
|
|
332
|
-
paddingLeft:
|
|
333
|
-
config.padding?.paddingLeft || config.bounds?.paddingLeft || 0,
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
if (config.centerCoordinate) {
|
|
337
|
-
stopConfig.centerCoordinate = JSON.stringify(
|
|
338
|
-
point(config.centerCoordinate),
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
if (config.bounds && config.bounds.ne && config.bounds.sw) {
|
|
343
|
-
const { ne, sw } = config.bounds;
|
|
344
|
-
stopConfig.bounds = makeNativeBounds(ne, sw);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return stopConfig;
|
|
348
|
-
},
|
|
349
|
-
[props.followUserLocation],
|
|
350
|
-
);
|
|
351
|
-
|
|
352
|
-
const _setCamera = useCallback(
|
|
353
|
-
(config: CameraStop | CameraStops = {}): void => {
|
|
354
|
-
if ("stops" in config) {
|
|
355
|
-
let nativeStops: NativeCameraStop[] = [];
|
|
356
|
-
|
|
357
|
-
for (const stop of config.stops) {
|
|
358
|
-
const nativeStop = _createStopConfig(stop);
|
|
359
|
-
if (nativeStop) {
|
|
360
|
-
nativeStops = [...nativeStops, nativeStop];
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
cameraRef.current?.setNativeProps({ stop: { stops: nativeStops } });
|
|
364
|
-
} else {
|
|
365
|
-
const nativeStop = _createStopConfig(config);
|
|
366
|
-
|
|
367
|
-
if (nativeStop) {
|
|
368
|
-
cameraRef.current?.setNativeProps({ stop: nativeStop });
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
},
|
|
372
|
-
[cameraRef.current, _createStopConfig],
|
|
373
|
-
);
|
|
374
|
-
|
|
375
|
-
const _getMaxBounds = useCallback((): string | null => {
|
|
376
|
-
const bounds = props.maxBounds;
|
|
377
|
-
if (!bounds || !bounds.ne || !bounds.sw) {
|
|
378
|
-
return null;
|
|
379
|
-
}
|
|
380
|
-
return makeNativeBounds(bounds.ne, bounds.sw);
|
|
381
|
-
}, [props.maxBounds]);
|
|
382
|
-
|
|
383
|
-
useEffect(() => {
|
|
384
|
-
if (!props.allowUpdates) {
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
cameraRef.current?.setNativeProps({
|
|
389
|
-
followUserLocation: props.followUserLocation,
|
|
390
|
-
});
|
|
391
|
-
}, [cameraRef.current, props.followUserLocation]);
|
|
392
|
-
|
|
393
|
-
useEffect(() => {
|
|
394
|
-
if (!props.maxBounds || !props.allowUpdates) {
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
cameraRef.current?.setNativeProps({
|
|
399
|
-
maxBounds: _getMaxBounds(),
|
|
400
|
-
});
|
|
401
|
-
}, [cameraRef.current, props.maxBounds, _getMaxBounds]);
|
|
402
|
-
|
|
403
|
-
useEffect(() => {
|
|
404
|
-
if (!props.minZoomLevel || !props.allowUpdates) {
|
|
405
|
-
return;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
cameraRef.current?.setNativeProps({
|
|
409
|
-
minZoomLevel: props.minZoomLevel,
|
|
410
|
-
});
|
|
411
|
-
}, [cameraRef.current, props.minZoomLevel]);
|
|
412
|
-
|
|
413
|
-
useEffect(() => {
|
|
414
|
-
if (!props.maxZoomLevel || !props.allowUpdates) {
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
cameraRef.current?.setNativeProps({
|
|
419
|
-
maxZoomLevel: props.maxZoomLevel,
|
|
420
|
-
});
|
|
421
|
-
}, [cameraRef.current, props.maxZoomLevel]);
|
|
422
|
-
|
|
423
|
-
useEffect(() => {
|
|
424
|
-
if (!props.allowUpdates) {
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
if (!props.followUserLocation) {
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
cameraRef.current?.setNativeProps({
|
|
433
|
-
followUserMode: props.followUserMode,
|
|
434
|
-
followPitch: props.followPitch || props.pitch,
|
|
435
|
-
followHeading: props.followHeading || props.heading,
|
|
436
|
-
followZoomLevel: props.followZoomLevel || props.zoomLevel,
|
|
437
|
-
});
|
|
438
|
-
}, [
|
|
439
|
-
cameraRef.current,
|
|
440
|
-
props.allowUpdates,
|
|
441
|
-
props.followUserLocation,
|
|
442
|
-
props.followUserMode,
|
|
443
|
-
props.followPitch,
|
|
444
|
-
props.pitch,
|
|
445
|
-
props.followHeading,
|
|
446
|
-
props.heading,
|
|
447
|
-
props.followZoomLevel,
|
|
448
|
-
props.zoomLevel,
|
|
449
|
-
]);
|
|
450
|
-
|
|
451
|
-
const cameraConfig: CameraStop = useMemo(() => {
|
|
452
|
-
return {
|
|
453
|
-
bounds: props.bounds,
|
|
454
|
-
centerCoordinate: props.centerCoordinate,
|
|
455
|
-
padding: props.padding,
|
|
456
|
-
zoomLevel: props.zoomLevel,
|
|
457
|
-
minZoomLevel: props.minZoomLevel,
|
|
458
|
-
maxZoomLevel: props.maxZoomLevel,
|
|
459
|
-
pitch: props.pitch,
|
|
460
|
-
heading: props.heading,
|
|
461
|
-
animationMode: props.animationMode,
|
|
462
|
-
animationDuration: props.animationDuration,
|
|
463
|
-
};
|
|
464
|
-
}, [
|
|
465
|
-
props.bounds,
|
|
466
|
-
props.centerCoordinate,
|
|
467
|
-
props.padding,
|
|
468
|
-
props.zoomLevel,
|
|
469
|
-
props.minZoomLevel,
|
|
470
|
-
props.maxZoomLevel,
|
|
471
|
-
props.pitch,
|
|
472
|
-
props.heading,
|
|
473
|
-
props.animationMode,
|
|
474
|
-
props.animationDuration,
|
|
475
|
-
]);
|
|
476
|
-
|
|
477
|
-
useEffect(() => {
|
|
478
|
-
if (!props.allowUpdates) {
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
_setCamera(cameraConfig);
|
|
483
|
-
}, [_setCamera, cameraConfig]);
|
|
484
|
-
|
|
485
|
-
const fitBounds = (
|
|
486
|
-
northEastCoordinates: GeoJSON.Position,
|
|
487
|
-
southWestCoordinates: GeoJSON.Position,
|
|
488
|
-
padding: number | number[] = 0,
|
|
489
|
-
animationDuration: number = 0.0,
|
|
490
|
-
): void => {
|
|
491
|
-
const pad = {
|
|
492
|
-
paddingLeft: 0,
|
|
493
|
-
paddingRight: 0,
|
|
494
|
-
paddingTop: 0,
|
|
495
|
-
paddingBottom: 0,
|
|
496
|
-
};
|
|
497
|
-
|
|
498
|
-
if (Array.isArray(padding)) {
|
|
499
|
-
if (padding.length === 2) {
|
|
500
|
-
pad.paddingTop = padding[0];
|
|
501
|
-
pad.paddingBottom = padding[0];
|
|
502
|
-
pad.paddingLeft = padding[1];
|
|
503
|
-
pad.paddingRight = padding[1];
|
|
504
|
-
} else if (padding.length === 4) {
|
|
505
|
-
pad.paddingTop = padding[0];
|
|
506
|
-
pad.paddingRight = padding[1];
|
|
507
|
-
pad.paddingBottom = padding[2];
|
|
508
|
-
pad.paddingLeft = padding[3];
|
|
509
|
-
}
|
|
510
|
-
} else {
|
|
511
|
-
pad.paddingLeft = padding;
|
|
512
|
-
pad.paddingRight = padding;
|
|
513
|
-
pad.paddingTop = padding;
|
|
514
|
-
pad.paddingBottom = padding;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
setCamera({
|
|
518
|
-
bounds: {
|
|
519
|
-
ne: northEastCoordinates,
|
|
520
|
-
sw: southWestCoordinates,
|
|
521
|
-
},
|
|
522
|
-
padding: pad,
|
|
523
|
-
animationDuration,
|
|
524
|
-
animationMode: "easeTo",
|
|
525
|
-
});
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
const flyTo = (
|
|
529
|
-
coordinates: GeoJSON.Position,
|
|
530
|
-
animationDuration = 2000,
|
|
531
|
-
): void => {
|
|
532
|
-
setCamera({
|
|
533
|
-
centerCoordinate: coordinates,
|
|
534
|
-
animationDuration,
|
|
535
|
-
animationMode: "flyTo",
|
|
536
|
-
});
|
|
537
|
-
};
|
|
538
|
-
|
|
539
|
-
const moveTo = (
|
|
540
|
-
coordinates: GeoJSON.Position,
|
|
541
|
-
animationDuration = 0,
|
|
542
|
-
): void => {
|
|
543
|
-
setCamera({
|
|
544
|
-
centerCoordinate: coordinates,
|
|
545
|
-
animationDuration,
|
|
546
|
-
});
|
|
547
|
-
};
|
|
548
|
-
|
|
549
|
-
const zoomTo = (zoomLevel: number, animationDuration = 2000): void => {
|
|
550
|
-
setCamera({
|
|
551
|
-
zoomLevel,
|
|
552
|
-
animationDuration,
|
|
553
|
-
animationMode: "flyTo",
|
|
554
|
-
});
|
|
555
|
-
};
|
|
556
|
-
|
|
557
|
-
const setCamera = (config: CameraStop | CameraStops = {}): void => {
|
|
558
|
-
_setCamera(config);
|
|
559
|
-
};
|
|
560
|
-
|
|
561
|
-
const _createDefaultCamera = (): NativeCameraStop | null => {
|
|
562
|
-
if (_defaultCamera.current) {
|
|
563
|
-
return _defaultCamera.current;
|
|
564
|
-
}
|
|
565
|
-
if (!props.defaultSettings) {
|
|
566
|
-
return null;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
_defaultCamera.current = _createStopConfig(
|
|
570
|
-
{
|
|
571
|
-
...props.defaultSettings,
|
|
572
|
-
animationMode: "moveTo",
|
|
573
|
-
},
|
|
574
|
-
true,
|
|
575
|
-
);
|
|
576
|
-
return _defaultCamera.current;
|
|
577
|
-
};
|
|
578
|
-
|
|
579
|
-
const _getNativeCameraMode = (
|
|
580
|
-
config: CameraStop,
|
|
581
|
-
): NativeAnimationMode => {
|
|
582
|
-
switch (config.animationMode) {
|
|
583
|
-
case "flyTo":
|
|
584
|
-
return MapLibreGL.CameraModes.Flight;
|
|
585
|
-
case "moveTo":
|
|
586
|
-
return MapLibreGL.CameraModes.None;
|
|
587
|
-
case "linearTo":
|
|
588
|
-
return MapLibreGL.CameraModes.Linear;
|
|
589
|
-
default:
|
|
590
|
-
return MapLibreGL.CameraModes.Ease;
|
|
591
|
-
}
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
const nativeProps = Object.assign({}, props);
|
|
595
|
-
|
|
596
|
-
const callbacks = {
|
|
597
|
-
onUserTrackingModeChange: nativeProps.onUserTrackingModeChange,
|
|
598
|
-
};
|
|
599
|
-
|
|
600
468
|
return (
|
|
601
469
|
<RCTMLNCamera
|
|
602
470
|
testID="Camera"
|
|
603
|
-
ref={
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
{
|
|
471
|
+
ref={nativeCamera}
|
|
472
|
+
stop={nativeStop}
|
|
473
|
+
defaultStop={nativeDefaultStop}
|
|
474
|
+
maxBounds={nativeMaxBounds}
|
|
475
|
+
followUserLocation={followUserLocation}
|
|
476
|
+
followHeading={followHeading}
|
|
477
|
+
followPitch={followPitch}
|
|
478
|
+
followUserMode={followUserMode}
|
|
479
|
+
followZoomLevel={followZoomLevel}
|
|
480
|
+
maxZoomLevel={maxZoomLevel}
|
|
481
|
+
minZoomLevel={minZoomLevel}
|
|
482
|
+
onUserTrackingModeChange={onUserTrackingModeChange}
|
|
615
483
|
/>
|
|
616
484
|
);
|
|
617
485
|
},
|
|
618
486
|
),
|
|
619
487
|
);
|
|
620
488
|
|
|
621
|
-
const RCTMLNCamera =
|
|
489
|
+
const RCTMLNCamera =
|
|
490
|
+
requireNativeComponent<NativeCameraProps>(NATIVE_MODULE_NAME);
|
|
622
491
|
|
|
623
492
|
export default Camera;
|