@maplibre/maplibre-react-native 10.0.0-alpha.5 → 10.0.0-alpha.7
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/.eslintrc.js +3 -1
- package/.yarn/sdks/eslint/bin/eslint.js +8 -1
- package/.yarn/sdks/eslint/lib/api.js +8 -1
- package/.yarn/sdks/eslint/lib/unsupported-api.js +8 -1
- package/.yarn/sdks/prettier/bin/prettier.cjs +8 -1
- package/.yarn/sdks/prettier/index.cjs +8 -1
- package/.yarn/sdks/typescript/bin/tsc +8 -1
- package/.yarn/sdks/typescript/bin/tsserver +8 -1
- package/.yarn/sdks/typescript/lib/tsc.js +8 -1
- package/.yarn/sdks/typescript/lib/tsserver.js +20 -6
- package/.yarn/sdks/typescript/lib/tsserverlibrary.js +20 -6
- package/.yarn/sdks/typescript/lib/typescript.js +8 -1
- package/CHANGELOG.md +57 -48
- package/CONTRIBUTING.md +10 -9
- package/android/rctmln/src/main/java/com/maplibre/rctmln/components/annotation/MarkerViewManager.java +5 -3
- package/android/rctmln/src/main/java/com/maplibre/rctmln/components/mapview/RCTMLNMapView.java +7 -7
- package/docs/Camera.md +3 -3
- package/docs/MapView.md +9 -33
- package/docs/UserLocation.md +10 -2
- package/docs/docs.json +17 -32
- package/docs/offlineManager.md +246 -0
- package/javascript/Maplibre.ts +5 -1
- package/javascript/components/BackgroundLayer.tsx +27 -20
- package/javascript/components/Callout.tsx +40 -40
- package/javascript/components/Camera.tsx +421 -478
- package/javascript/components/CircleLayer.tsx +29 -22
- package/javascript/components/FillExtrusionLayer.tsx +23 -23
- package/javascript/components/FillLayer.tsx +22 -19
- package/javascript/components/HeatmapLayer.tsx +21 -19
- package/javascript/components/ImageSource.tsx +25 -32
- package/javascript/components/Images.tsx +36 -35
- package/javascript/components/Light.tsx +20 -47
- package/javascript/components/LineLayer.tsx +23 -20
- package/javascript/components/MapView.tsx +604 -554
- package/javascript/components/MarkerView.tsx +23 -38
- package/javascript/components/NativeUserLocation.tsx +3 -5
- package/javascript/components/PointAnnotation.tsx +111 -87
- package/javascript/components/RasterLayer.tsx +21 -18
- package/javascript/components/RasterSource.tsx +39 -42
- package/javascript/components/ShapeSource.tsx +287 -239
- package/javascript/components/Style.tsx +1 -1
- package/javascript/components/SymbolLayer.tsx +34 -28
- package/javascript/components/UserLocation.tsx +164 -151
- package/javascript/components/VectorSource.tsx +128 -117
- package/javascript/components/annotations/Annotation.tsx +105 -79
- package/javascript/{components/AbstractLayer.tsx → hooks/useAbstractLayer.ts} +54 -37
- package/javascript/hooks/useAbstractSource.ts +34 -0
- package/javascript/hooks/useNativeBridge.ts +125 -0
- package/javascript/hooks/useNativeRef.ts +13 -0
- package/javascript/hooks/useOnce.ts +12 -0
- package/javascript/utils/Logger.ts +3 -3
- package/package.json +2 -1
- package/javascript/components/AbstractSource.tsx +0 -27
- package/javascript/components/NativeBridgeComponent.tsx +0 -117
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import useNativeBridge from '../hooks/useNativeBridge';
|
|
2
|
+
import useOnce from '../hooks/useOnce';
|
|
1
3
|
import {FilterExpression} from '../utils/MaplibreStyles';
|
|
2
4
|
import {Location} from '../modules/location/locationManager';
|
|
3
5
|
import {isFunction, isAndroid} from '../utils';
|
|
@@ -5,9 +7,18 @@ import {getFilter} from '../utils/filterUtils';
|
|
|
5
7
|
import Logger from '../utils/Logger';
|
|
6
8
|
import BaseProps from '../types/BaseProps';
|
|
7
9
|
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
import React, {
|
|
11
|
+
Component,
|
|
12
|
+
memo,
|
|
13
|
+
ReactElement,
|
|
14
|
+
ReactNode,
|
|
15
|
+
useCallback,
|
|
16
|
+
useEffect,
|
|
17
|
+
useImperativeHandle,
|
|
18
|
+
useMemo,
|
|
19
|
+
useRef,
|
|
20
|
+
useState,
|
|
21
|
+
} from 'react';
|
|
11
22
|
import {
|
|
12
23
|
View,
|
|
13
24
|
StyleSheet,
|
|
@@ -15,7 +26,6 @@ import {
|
|
|
15
26
|
requireNativeComponent,
|
|
16
27
|
ViewProps,
|
|
17
28
|
NativeMethods,
|
|
18
|
-
LayoutChangeEvent,
|
|
19
29
|
NativeSyntheticEvent,
|
|
20
30
|
} from 'react-native';
|
|
21
31
|
import debounce from 'debounce';
|
|
@@ -107,22 +117,10 @@ interface MapViewProps extends BaseProps {
|
|
|
107
117
|
* Adds attribution offset, e.g. `{top: 8, left: 8}` will put attribution button in top-left corner of the map
|
|
108
118
|
*/
|
|
109
119
|
attributionPosition?:
|
|
110
|
-
| {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
| {
|
|
115
|
-
top?: number;
|
|
116
|
-
right?: number;
|
|
117
|
-
}
|
|
118
|
-
| {
|
|
119
|
-
bottom?: number;
|
|
120
|
-
left?: number;
|
|
121
|
-
}
|
|
122
|
-
| {
|
|
123
|
-
bottom?: number;
|
|
124
|
-
right?: number;
|
|
125
|
-
};
|
|
120
|
+
| {top?: number; left?: number}
|
|
121
|
+
| {top?: number; right?: number}
|
|
122
|
+
| {bottom?: number; left?: number}
|
|
123
|
+
| {bottom?: number; right?: number};
|
|
126
124
|
/**
|
|
127
125
|
* MapView's tintColor
|
|
128
126
|
*/
|
|
@@ -135,22 +133,10 @@ interface MapViewProps extends BaseProps {
|
|
|
135
133
|
* Adds logo offset, e.g. `{top: 8, left: 8}` will put the logo in top-left corner of the map
|
|
136
134
|
*/
|
|
137
135
|
logoPosition?:
|
|
138
|
-
| {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
| {
|
|
143
|
-
top?: number;
|
|
144
|
-
right?: number;
|
|
145
|
-
}
|
|
146
|
-
| {
|
|
147
|
-
bottom?: number;
|
|
148
|
-
left?: number;
|
|
149
|
-
}
|
|
150
|
-
| {
|
|
151
|
-
bottom?: number;
|
|
152
|
-
right?: number;
|
|
153
|
-
};
|
|
136
|
+
| {top?: number; left?: number}
|
|
137
|
+
| {top?: number; right?: number}
|
|
138
|
+
| {bottom?: number; left?: number}
|
|
139
|
+
| {bottom?: number; right?: number};
|
|
154
140
|
/**
|
|
155
141
|
* Enable/Disable the compass from appearing on the map
|
|
156
142
|
*/
|
|
@@ -267,552 +253,616 @@ interface NativeProps extends Omit<MapViewProps, 'onPress' | 'onLongPress'> {
|
|
|
267
253
|
onLongPress(event: NativeSyntheticEvent<{payload: GeoJSON.Feature}>): void;
|
|
268
254
|
}
|
|
269
255
|
|
|
270
|
-
export interface
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
256
|
+
export interface MapViewRef {
|
|
257
|
+
getPointInView: (coordinate: GeoJSON.Position) => Promise<GeoJSON.Point>;
|
|
258
|
+
getCoordinateFromView: (point: number[]) => Promise<GeoJSON.Position>;
|
|
259
|
+
getVisibleBounds: () => Promise<VisibleBounds>;
|
|
260
|
+
queryRenderedFeaturesAtPoint: (
|
|
261
|
+
point: [screenPointX: number, screenPointY: number],
|
|
262
|
+
filter: FilterExpression | undefined,
|
|
263
|
+
layerIDs: string[],
|
|
264
|
+
) => Promise<GeoJSON.FeatureCollection>;
|
|
265
|
+
queryRenderedFeaturesInRect: (
|
|
266
|
+
bbox: GeoJSON.BBox,
|
|
267
|
+
filter: FilterExpression | undefined,
|
|
268
|
+
layerIDs: string[],
|
|
269
|
+
) => Promise<GeoJSON.FeatureCollection>;
|
|
270
|
+
setCamera: () => void;
|
|
271
|
+
takeSnap: (writeToDisk?: boolean) => Promise<string>;
|
|
272
|
+
getZoom: () => Promise<number>;
|
|
273
|
+
getCenter: () => Promise<GeoJSON.Position>;
|
|
274
|
+
setSourceVisibility: (
|
|
275
|
+
visible: boolean,
|
|
276
|
+
sourceId: string,
|
|
277
|
+
sourceLayerId?: string | null,
|
|
278
|
+
) => void;
|
|
279
|
+
showAttribution: () => Promise<void>;
|
|
280
|
+
setNativeProps: (props: NativeProps) => void;
|
|
276
281
|
}
|
|
277
282
|
|
|
278
283
|
/**
|
|
279
284
|
* MapView backed by MapLibre GL Native
|
|
280
285
|
*/
|
|
281
|
-
class MapView extends NativeBridgeComponent(
|
|
282
|
-
React.Component<MapViewProps, MapViewState>,
|
|
283
|
-
NATIVE_MODULE_NAME,
|
|
284
|
-
) {
|
|
285
|
-
static defaultProps = {
|
|
286
|
-
localizeLabels: false,
|
|
287
|
-
scrollEnabled: true,
|
|
288
|
-
pitchEnabled: true,
|
|
289
|
-
rotateEnabled: true,
|
|
290
|
-
attributionEnabled: true,
|
|
291
|
-
logoEnabled: false,
|
|
292
|
-
surfaceView: false,
|
|
293
|
-
regionWillChangeDebounceTime: 10,
|
|
294
|
-
regionDidChangeDebounceTime: 500,
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
logger: Logger;
|
|
298
|
-
_nativeRef?: RCTMLNMapViewRefType;
|
|
299
|
-
_onDebouncedRegionWillChange: ReturnType<typeof debounce>;
|
|
300
|
-
_onDebouncedRegionDidChange: ReturnType<typeof debounce>;
|
|
301
|
-
|
|
302
|
-
constructor(props: MapViewProps) {
|
|
303
|
-
super(props);
|
|
304
|
-
|
|
305
|
-
this.logger = Logger.sharedInstance();
|
|
306
|
-
this.logger.start();
|
|
307
|
-
|
|
308
|
-
this.state = {
|
|
309
|
-
isReady: false,
|
|
310
|
-
region: null,
|
|
311
|
-
width: 0,
|
|
312
|
-
height: 0,
|
|
313
|
-
isUserInteraction: false,
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
this._onPress = this._onPress.bind(this);
|
|
317
|
-
this._onLongPress = this._onLongPress.bind(this);
|
|
318
|
-
this._onChange = this._onChange.bind(this);
|
|
319
|
-
this._onLayout = this._onLayout.bind(this);
|
|
320
|
-
|
|
321
|
-
// debounced map change methods
|
|
322
|
-
this._onDebouncedRegionWillChange = debounce(
|
|
323
|
-
this._onRegionWillChange.bind(this),
|
|
324
|
-
props.regionWillChangeDebounceTime,
|
|
325
|
-
true,
|
|
326
|
-
);
|
|
327
|
-
|
|
328
|
-
this._onDebouncedRegionDidChange = debounce(
|
|
329
|
-
this._onRegionDidChange.bind(this),
|
|
330
|
-
props.regionDidChangeDebounceTime,
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
componentDidMount(): void {
|
|
335
|
-
this._setHandledMapChangedEvents(this.props);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
componentWillUnmount(): void {
|
|
339
|
-
this._onDebouncedRegionWillChange.clear();
|
|
340
|
-
this._onDebouncedRegionDidChange.clear();
|
|
341
|
-
this.logger.stop();
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
UNSAFE_componentWillReceiveProps(nextProps: MapViewProps): void {
|
|
345
|
-
this._setHandledMapChangedEvents(nextProps);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
_setHandledMapChangedEvents(props: MapViewProps): void {
|
|
349
|
-
if (isAndroid()) {
|
|
350
|
-
const events = [];
|
|
351
|
-
|
|
352
|
-
if (props.onRegionWillChange) {
|
|
353
|
-
events.push(MapLibreGL.EventTypes.RegionWillChange);
|
|
354
|
-
}
|
|
355
|
-
if (props.onRegionIsChanging) {
|
|
356
|
-
events.push(MapLibreGL.EventTypes.RegionIsChanging);
|
|
357
|
-
}
|
|
358
|
-
if (props.onRegionDidChange) {
|
|
359
|
-
events.push(MapLibreGL.EventTypes.RegionDidChange);
|
|
360
|
-
}
|
|
361
|
-
if (props.onUserLocationUpdate) {
|
|
362
|
-
events.push(MapLibreGL.EventTypes.UserLocationUpdated);
|
|
363
|
-
}
|
|
364
|
-
if (props.onWillStartLoadingMap) {
|
|
365
|
-
events.push(MapLibreGL.EventTypes.WillStartLoadingMap);
|
|
366
|
-
}
|
|
367
|
-
if (props.onDidFinishLoadingMap) {
|
|
368
|
-
events.push(MapLibreGL.EventTypes.DidFinishLoadingMap);
|
|
369
|
-
}
|
|
370
|
-
if (props.onDidFailLoadingMap) {
|
|
371
|
-
events.push(MapLibreGL.EventTypes.DidFailLoadingMap);
|
|
372
|
-
}
|
|
373
|
-
if (props.onWillStartRenderingFrame) {
|
|
374
|
-
events.push(MapLibreGL.EventTypes.WillStartRenderingFrame);
|
|
375
|
-
}
|
|
376
|
-
if (props.onDidFinishRenderingFrame) {
|
|
377
|
-
events.push(MapLibreGL.EventTypes.DidFinishRenderingFrame);
|
|
378
|
-
}
|
|
379
|
-
if (props.onDidFinishRenderingFrameFully) {
|
|
380
|
-
events.push(MapLibreGL.EventTypes.DidFinishRenderingFrameFully);
|
|
381
|
-
}
|
|
382
|
-
if (props.onWillStartRenderingMap) {
|
|
383
|
-
events.push(MapLibreGL.EventTypes.WillStartRenderingMap);
|
|
384
|
-
}
|
|
385
|
-
if (props.onDidFinishRenderingMap) {
|
|
386
|
-
events.push(MapLibreGL.EventTypes.DidFinishRenderingMap);
|
|
387
|
-
}
|
|
388
|
-
if (props.onDidFinishRenderingMapFully) {
|
|
389
|
-
events.push(MapLibreGL.EventTypes.DidFinishRenderingMapFully);
|
|
390
|
-
}
|
|
391
|
-
if (props.onDidFinishLoadingStyle) {
|
|
392
|
-
events.push(MapLibreGL.EventTypes.DidFinishLoadingStyle);
|
|
393
|
-
}
|
|
394
286
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
287
|
+
const MapView = memo(
|
|
288
|
+
React.forwardRef<MapViewRef, MapViewProps>(
|
|
289
|
+
(
|
|
290
|
+
{
|
|
291
|
+
localizeLabels = false,
|
|
292
|
+
scrollEnabled = true,
|
|
293
|
+
pitchEnabled = true,
|
|
294
|
+
rotateEnabled = true,
|
|
295
|
+
attributionEnabled = true,
|
|
296
|
+
logoEnabled = false,
|
|
297
|
+
surfaceView = false,
|
|
298
|
+
regionWillChangeDebounceTime = 10,
|
|
299
|
+
regionDidChangeDebounceTime = 500,
|
|
300
|
+
...props
|
|
301
|
+
}: MapViewProps,
|
|
302
|
+
ref,
|
|
303
|
+
) => {
|
|
304
|
+
// * exposes the methods of the function component so we don't break projects that depend on calling this methods
|
|
305
|
+
useImperativeHandle(
|
|
306
|
+
ref,
|
|
307
|
+
(): MapViewRef => ({
|
|
308
|
+
/**
|
|
309
|
+
* Converts a geographic coordinate to a point in the given view’s coordinate system.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* const pointInView = await this._map.getPointInView([-37.817070, 144.949901]);
|
|
313
|
+
*
|
|
314
|
+
* @param {Array<Number>} coordinate - A point expressed in the map view's coordinate system.
|
|
315
|
+
* @return {Array}
|
|
316
|
+
*/
|
|
317
|
+
getPointInView,
|
|
318
|
+
/**
|
|
319
|
+
* Converts a point in the given view’s coordinate system to a geographic coordinate.
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* const coordinate = await this._map.getCoordinateFromView([100, 100]);
|
|
323
|
+
*
|
|
324
|
+
* @param {Array<Number>} point - A point expressed in the given view’s coordinate system.
|
|
325
|
+
* @return {Array}
|
|
326
|
+
*/
|
|
327
|
+
getCoordinateFromView,
|
|
328
|
+
/**
|
|
329
|
+
* The coordinate bounds(ne, sw) visible in the users’s viewport.
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* const visibleBounds = await this._map.getVisibleBounds();
|
|
333
|
+
*
|
|
334
|
+
* @return {Array}
|
|
335
|
+
*/
|
|
336
|
+
getVisibleBounds,
|
|
337
|
+
/**
|
|
338
|
+
* Returns an array of rendered map features that intersect with a given point.
|
|
339
|
+
*
|
|
340
|
+
* @example
|
|
341
|
+
* this._map.queryRenderedFeaturesAtPoint([30, 40], ['==', 'type', 'Point'], ['id1', 'id2'])
|
|
342
|
+
*
|
|
343
|
+
* @param {Array<Number>} coordinate - A point expressed in the map view’s coordinate system.
|
|
344
|
+
* @param {Array=} filter - A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.
|
|
345
|
+
* @param {Array=} layerIDs - A array of layer id's to filter the features by
|
|
346
|
+
* @return {GeoJSON.FeatureCollection}
|
|
347
|
+
*/
|
|
348
|
+
queryRenderedFeaturesAtPoint,
|
|
349
|
+
/**
|
|
350
|
+
* Returns an array of rendered map features that intersect with the given rectangle,
|
|
351
|
+
* restricted to the given style layers and filtered by the given predicate.
|
|
352
|
+
*
|
|
353
|
+
* @example
|
|
354
|
+
* this._map.queryRenderedFeaturesInRect([30, 40, 20, 10], ['==', 'type', 'Point'], ['id1', 'id2'])
|
|
355
|
+
*
|
|
356
|
+
* @param {Array<Number>} bbox - A rectangle expressed in the map view’s coordinate system.
|
|
357
|
+
* @param {Array=} filter - A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.
|
|
358
|
+
* @param {Array=} layerIDs - A array of layer id's to filter the features by
|
|
359
|
+
* @return {GeoJSON.FeatureCollection}
|
|
360
|
+
*/
|
|
361
|
+
queryRenderedFeaturesInRect,
|
|
362
|
+
/**
|
|
363
|
+
* Map camera will perform updates based on provided config. Deprecated use Camera#setCamera.
|
|
364
|
+
*/
|
|
365
|
+
setCamera,
|
|
366
|
+
/**
|
|
367
|
+
* Takes snapshot of map with current tiles and returns a URI to the image
|
|
368
|
+
* @param {Boolean} writeToDisk If true will create a temp file, otherwise it is in base64
|
|
369
|
+
* @return {String}
|
|
370
|
+
*/
|
|
371
|
+
takeSnap,
|
|
372
|
+
/**
|
|
373
|
+
* Returns the current zoom of the map view.
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* const zoom = await this._map.getZoom();
|
|
377
|
+
*
|
|
378
|
+
* @return {Number}
|
|
379
|
+
*/
|
|
380
|
+
getZoom,
|
|
381
|
+
/**
|
|
382
|
+
* Returns the map's geographical centerpoint
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* const center = await this._map.getCenter();
|
|
386
|
+
*
|
|
387
|
+
* @return {Array<Number>} Coordinates
|
|
388
|
+
*/
|
|
389
|
+
getCenter,
|
|
390
|
+
/**
|
|
391
|
+
* Sets the visibility of all the layers referencing the specified `sourceLayerId` and/or `sourceId`
|
|
392
|
+
*
|
|
393
|
+
* @example
|
|
394
|
+
* await this._map.setSourceVisibility(false, 'composite', 'building')
|
|
395
|
+
*
|
|
396
|
+
* @param {boolean} visible - Visibility of the layers
|
|
397
|
+
* @param {String} sourceId - Identifier of the target source (e.g. 'composite')
|
|
398
|
+
* @param {String=} sourceLayerId - Identifier of the target source-layer (e.g. 'building')
|
|
399
|
+
*/
|
|
400
|
+
setSourceVisibility,
|
|
401
|
+
/**
|
|
402
|
+
* Show the attribution and telemetry action sheet.
|
|
403
|
+
* If you implement a custom attribution button, you should add this action to the button.
|
|
404
|
+
*/
|
|
405
|
+
showAttribution,
|
|
406
|
+
setNativeProps,
|
|
407
|
+
}),
|
|
399
408
|
);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
409
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
410
|
+
const {_runNativeCommand, _runPendingNativeCommands, _onAndroidCallback} =
|
|
411
|
+
useNativeBridge(NATIVE_MODULE_NAME);
|
|
412
|
+
const logger = useRef<Logger>(Logger.sharedInstance());
|
|
413
|
+
// * start the logger before anyuseEffect
|
|
414
|
+
useOnce(() => {
|
|
415
|
+
logger.current.start();
|
|
416
|
+
});
|
|
417
|
+
const _nativeRef = useRef<RCTMLNMapViewRefType>();
|
|
418
|
+
const [isReady, setIsReady] = useState(false);
|
|
419
|
+
|
|
420
|
+
// Cleanups on unmount
|
|
421
|
+
useEffect(() => {
|
|
422
|
+
const currentLogger = logger.current;
|
|
423
|
+
|
|
424
|
+
return (): void => {
|
|
425
|
+
_onDebouncedRegionWillChange.clear();
|
|
426
|
+
_onDebouncedRegionDidChange.clear();
|
|
427
|
+
currentLogger.stop();
|
|
428
|
+
};
|
|
429
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
430
|
+
}, []);
|
|
431
|
+
|
|
432
|
+
// This will run on every render
|
|
433
|
+
// so similar to componentDidMount and UNSAFE_componentWillReceiveProps
|
|
434
|
+
useEffect(() => {
|
|
435
|
+
_setHandledMapChangedEvents(props);
|
|
436
|
+
}, [props]);
|
|
437
|
+
|
|
438
|
+
const _setHandledMapChangedEvents = (props: MapViewProps): void => {
|
|
439
|
+
if (isAndroid()) {
|
|
440
|
+
const events = [];
|
|
441
|
+
|
|
442
|
+
if (props.onRegionWillChange) {
|
|
443
|
+
events.push(MapLibreGL.EventTypes.RegionWillChange);
|
|
444
|
+
}
|
|
445
|
+
if (props.onRegionIsChanging) {
|
|
446
|
+
events.push(MapLibreGL.EventTypes.RegionIsChanging);
|
|
447
|
+
}
|
|
448
|
+
if (props.onRegionDidChange) {
|
|
449
|
+
events.push(MapLibreGL.EventTypes.RegionDidChange);
|
|
450
|
+
}
|
|
451
|
+
if (props.onUserLocationUpdate) {
|
|
452
|
+
events.push(MapLibreGL.EventTypes.UserLocationUpdated);
|
|
453
|
+
}
|
|
454
|
+
if (props.onWillStartLoadingMap) {
|
|
455
|
+
events.push(MapLibreGL.EventTypes.WillStartLoadingMap);
|
|
456
|
+
}
|
|
457
|
+
if (props.onDidFinishLoadingMap) {
|
|
458
|
+
events.push(MapLibreGL.EventTypes.DidFinishLoadingMap);
|
|
459
|
+
}
|
|
460
|
+
if (props.onDidFailLoadingMap) {
|
|
461
|
+
events.push(MapLibreGL.EventTypes.DidFailLoadingMap);
|
|
462
|
+
}
|
|
463
|
+
if (props.onWillStartRenderingFrame) {
|
|
464
|
+
events.push(MapLibreGL.EventTypes.WillStartRenderingFrame);
|
|
465
|
+
}
|
|
466
|
+
if (props.onDidFinishRenderingFrame) {
|
|
467
|
+
events.push(MapLibreGL.EventTypes.DidFinishRenderingFrame);
|
|
468
|
+
}
|
|
469
|
+
if (props.onDidFinishRenderingFrameFully) {
|
|
470
|
+
events.push(MapLibreGL.EventTypes.DidFinishRenderingFrameFully);
|
|
471
|
+
}
|
|
472
|
+
if (props.onWillStartRenderingMap) {
|
|
473
|
+
events.push(MapLibreGL.EventTypes.WillStartRenderingMap);
|
|
474
|
+
}
|
|
475
|
+
if (props.onDidFinishRenderingMap) {
|
|
476
|
+
events.push(MapLibreGL.EventTypes.DidFinishRenderingMap);
|
|
477
|
+
}
|
|
478
|
+
if (props.onDidFinishRenderingMapFully) {
|
|
479
|
+
events.push(MapLibreGL.EventTypes.DidFinishRenderingMapFully);
|
|
480
|
+
}
|
|
481
|
+
if (props.onDidFinishLoadingStyle) {
|
|
482
|
+
events.push(MapLibreGL.EventTypes.DidFinishLoadingStyle);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
_runNativeCommand(
|
|
486
|
+
'setHandledMapChangedEvents',
|
|
487
|
+
_nativeRef.current,
|
|
488
|
+
events,
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
};
|
|
420
492
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const res: {coordinateFromView: GeoJSON.Position} =
|
|
432
|
-
await this._runNativeCommand('getCoordinateFromView', this._nativeRef, [
|
|
433
|
-
point,
|
|
434
|
-
]);
|
|
435
|
-
return res.coordinateFromView;
|
|
436
|
-
}
|
|
493
|
+
const getPointInView = async (
|
|
494
|
+
coordinate: GeoJSON.Position,
|
|
495
|
+
): Promise<GeoJSON.Point> => {
|
|
496
|
+
const res: {pointInView: GeoJSON.Point} = await _runNativeCommand(
|
|
497
|
+
'getPointInView',
|
|
498
|
+
_nativeRef.current,
|
|
499
|
+
[coordinate],
|
|
500
|
+
);
|
|
501
|
+
return res.pointInView;
|
|
502
|
+
};
|
|
437
503
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
const res: {visibleBounds: VisibleBounds} = await this._runNativeCommand(
|
|
448
|
-
'getVisibleBounds',
|
|
449
|
-
this._nativeRef,
|
|
450
|
-
);
|
|
451
|
-
return res.visibleBounds;
|
|
452
|
-
}
|
|
504
|
+
const getCoordinateFromView = async (
|
|
505
|
+
point: number[],
|
|
506
|
+
): Promise<GeoJSON.Position> => {
|
|
507
|
+
const res: {coordinateFromView: GeoJSON.Position} =
|
|
508
|
+
await _runNativeCommand('getCoordinateFromView', _nativeRef.current, [
|
|
509
|
+
point,
|
|
510
|
+
]);
|
|
511
|
+
return res.coordinateFromView;
|
|
512
|
+
};
|
|
453
513
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
* @typedef {number} ScreenPointY
|
|
462
|
-
* @param {[ScreenPointX, ScreenPointY]} point - A point expressed in the map view’s coordinate system.
|
|
463
|
-
* @param {Array=} filter - A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array.
|
|
464
|
-
* @param {Array=} layerIDs - A array of layer id's to filter the features by
|
|
465
|
-
* @return {GeoJSON.FeatureCollection}
|
|
466
|
-
*/
|
|
467
|
-
async queryRenderedFeaturesAtPoint(
|
|
468
|
-
point: [screenPointX: number, screenPointY: number],
|
|
469
|
-
filter?: FilterExpression,
|
|
470
|
-
layerIDs = [],
|
|
471
|
-
): Promise<GeoJSON.FeatureCollection> {
|
|
472
|
-
if (!point || point.length < 2) {
|
|
473
|
-
throw new Error(
|
|
474
|
-
"Must pass in valid point in the map view's cooridnate system[x, y]",
|
|
475
|
-
);
|
|
476
|
-
}
|
|
514
|
+
const getVisibleBounds = async (): Promise<VisibleBounds> => {
|
|
515
|
+
const res: {visibleBounds: VisibleBounds} = await _runNativeCommand(
|
|
516
|
+
'getVisibleBounds',
|
|
517
|
+
_nativeRef.current,
|
|
518
|
+
);
|
|
519
|
+
return res.visibleBounds;
|
|
520
|
+
};
|
|
477
521
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
522
|
+
const queryRenderedFeaturesAtPoint = async (
|
|
523
|
+
point: [screenPointX: number, screenPointY: number],
|
|
524
|
+
filter?: FilterExpression,
|
|
525
|
+
layerIDs: string[] = [],
|
|
526
|
+
): Promise<GeoJSON.FeatureCollection> => {
|
|
527
|
+
if (!point || point.length < 2) {
|
|
528
|
+
throw new Error(
|
|
529
|
+
"Must pass in valid point in the map view's cooridnate system[x, y]",
|
|
530
|
+
);
|
|
531
|
+
}
|
|
484
532
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
533
|
+
const res: {data: string | GeoJSON.FeatureCollection} =
|
|
534
|
+
await _runNativeCommand(
|
|
535
|
+
'queryRenderedFeaturesAtPoint',
|
|
536
|
+
_nativeRef.current,
|
|
537
|
+
[point, getFilter(filter), layerIDs],
|
|
538
|
+
);
|
|
488
539
|
|
|
489
|
-
|
|
490
|
-
|
|
540
|
+
if (isAndroid()) {
|
|
541
|
+
return JSON.parse(res.data as string);
|
|
542
|
+
}
|
|
491
543
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
544
|
+
return res.data as GeoJSON.FeatureCollection;
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
const queryRenderedFeaturesInRect = async (
|
|
548
|
+
bbox: GeoJSON.BBox,
|
|
549
|
+
filter?: FilterExpression,
|
|
550
|
+
layerIDs: string[] = [],
|
|
551
|
+
): Promise<GeoJSON.FeatureCollection> => {
|
|
552
|
+
if (!bbox || bbox.length !== 4) {
|
|
553
|
+
throw new Error(
|
|
554
|
+
'Must pass in a valid bounding box[top, right, bottom, left]',
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
const res: {data: string | GeoJSON.FeatureCollection} =
|
|
558
|
+
await _runNativeCommand(
|
|
559
|
+
'queryRenderedFeaturesInRect',
|
|
560
|
+
_nativeRef.current,
|
|
561
|
+
[bbox, getFilter(filter), layerIDs],
|
|
562
|
+
);
|
|
563
|
+
|
|
564
|
+
if (isAndroid()) {
|
|
565
|
+
return JSON.parse(res.data as string);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
return res.data as GeoJSON.FeatureCollection;
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
const setCamera = (): void => {
|
|
572
|
+
console.warn(
|
|
573
|
+
'MapView.setCamera is deprecated - please use Camera#setCamera',
|
|
574
|
+
);
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
const takeSnap = async (writeToDisk = false): Promise<string> => {
|
|
578
|
+
const res: {uri: string} = await _runNativeCommand(
|
|
579
|
+
'takeSnap',
|
|
580
|
+
_nativeRef.current,
|
|
581
|
+
[writeToDisk],
|
|
582
|
+
);
|
|
583
|
+
return res.uri;
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
const getZoom = async (): Promise<number> => {
|
|
587
|
+
const res: {zoom: number} = await _runNativeCommand(
|
|
588
|
+
'getZoom',
|
|
589
|
+
_nativeRef.current,
|
|
590
|
+
);
|
|
591
|
+
return res.zoom;
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
const getCenter = async (): Promise<GeoJSON.Position> => {
|
|
595
|
+
const res: {center: GeoJSON.Position} = await _runNativeCommand(
|
|
596
|
+
'getCenter',
|
|
597
|
+
_nativeRef.current,
|
|
598
|
+
);
|
|
599
|
+
return res.center;
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
const setSourceVisibility = (
|
|
603
|
+
visible: boolean,
|
|
604
|
+
sourceId: string,
|
|
605
|
+
sourceLayerId: string | null = null,
|
|
606
|
+
): void => {
|
|
607
|
+
_runNativeCommand('setSourceVisibility', _nativeRef.current, [
|
|
608
|
+
visible,
|
|
609
|
+
sourceId,
|
|
610
|
+
sourceLayerId,
|
|
611
|
+
]);
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
const showAttribution = async (): Promise<void> => {
|
|
615
|
+
_runNativeCommand('showAttribution', _nativeRef.current);
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
const _onPress = (
|
|
619
|
+
e: NativeSyntheticEvent<{payload: GeoJSON.Feature}>,
|
|
620
|
+
): void => {
|
|
621
|
+
if (isFunction(props.onPress)) {
|
|
622
|
+
props.onPress(e.nativeEvent.payload);
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
const _onLongPress = (
|
|
627
|
+
e: NativeSyntheticEvent<{payload: GeoJSON.Feature}>,
|
|
628
|
+
): void => {
|
|
629
|
+
if (isFunction(props.onLongPress)) {
|
|
630
|
+
props.onLongPress(e.nativeEvent.payload);
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
const _onRegionWillChange = (
|
|
635
|
+
payload: GeoJSON.Feature<GeoJSON.Point, RegionPayload>,
|
|
636
|
+
): void => {
|
|
637
|
+
if (isFunction(props.onRegionWillChange)) {
|
|
638
|
+
props.onRegionWillChange(payload);
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
const _onRegionDidChange = (
|
|
643
|
+
payload: GeoJSON.Feature<GeoJSON.Point, RegionPayload>,
|
|
644
|
+
): void => {
|
|
645
|
+
if (isFunction(props.onRegionDidChange)) {
|
|
646
|
+
props.onRegionDidChange(payload);
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
const _onDebouncedRegionWillChange = useCallback(
|
|
651
|
+
debounce(_onRegionWillChange, regionWillChangeDebounceTime, {
|
|
652
|
+
immediate: true,
|
|
653
|
+
}),
|
|
654
|
+
[_onRegionWillChange],
|
|
512
655
|
);
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
this._nativeRef,
|
|
518
|
-
[bbox, getFilter(filter), layerIDs],
|
|
656
|
+
|
|
657
|
+
const _onDebouncedRegionDidChange = useCallback(
|
|
658
|
+
debounce(_onRegionDidChange, regionDidChangeDebounceTime),
|
|
659
|
+
[_onRegionDidChange],
|
|
519
660
|
);
|
|
520
661
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
662
|
+
const _onChange = (
|
|
663
|
+
e: NativeSyntheticEvent<{
|
|
664
|
+
type: string;
|
|
665
|
+
payload?: GeoJSON.Feature | Location;
|
|
666
|
+
}>,
|
|
667
|
+
): void => {
|
|
668
|
+
const {type, payload} = e.nativeEvent;
|
|
669
|
+
let propName: CallableProps | undefined;
|
|
670
|
+
|
|
671
|
+
switch (type) {
|
|
672
|
+
case MapLibreGL.EventTypes.RegionWillChange:
|
|
673
|
+
if (
|
|
674
|
+
regionWillChangeDebounceTime &&
|
|
675
|
+
regionWillChangeDebounceTime > 0
|
|
676
|
+
) {
|
|
677
|
+
if (payload) {
|
|
678
|
+
_onDebouncedRegionWillChange(
|
|
679
|
+
payload as GeoJSON.Feature<GeoJSON.Point, RegionPayload>,
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
} else {
|
|
683
|
+
propName = 'onRegionWillChange';
|
|
684
|
+
}
|
|
685
|
+
break;
|
|
686
|
+
case MapLibreGL.EventTypes.RegionIsChanging:
|
|
687
|
+
propName = 'onRegionIsChanging';
|
|
688
|
+
break;
|
|
689
|
+
case MapLibreGL.EventTypes.RegionDidChange:
|
|
690
|
+
if (
|
|
691
|
+
regionDidChangeDebounceTime &&
|
|
692
|
+
regionDidChangeDebounceTime > 0
|
|
693
|
+
) {
|
|
694
|
+
if (payload) {
|
|
695
|
+
_onDebouncedRegionDidChange(
|
|
696
|
+
payload as GeoJSON.Feature<GeoJSON.Point, RegionPayload>,
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
} else {
|
|
700
|
+
propName = 'onRegionDidChange';
|
|
701
|
+
}
|
|
702
|
+
break;
|
|
703
|
+
case MapLibreGL.EventTypes.UserLocationUpdated:
|
|
704
|
+
propName = 'onUserLocationUpdate';
|
|
705
|
+
break;
|
|
706
|
+
case MapLibreGL.EventTypes.WillStartLoadingMap:
|
|
707
|
+
propName = 'onWillStartLoadingMap';
|
|
708
|
+
break;
|
|
709
|
+
case MapLibreGL.EventTypes.DidFinishLoadingMap:
|
|
710
|
+
propName = 'onDidFinishLoadingMap';
|
|
711
|
+
break;
|
|
712
|
+
case MapLibreGL.EventTypes.DidFailLoadingMap:
|
|
713
|
+
propName = 'onDidFailLoadingMap';
|
|
714
|
+
break;
|
|
715
|
+
case MapLibreGL.EventTypes.WillStartRenderingFrame:
|
|
716
|
+
propName = 'onWillStartRenderingFrame';
|
|
717
|
+
break;
|
|
718
|
+
case MapLibreGL.EventTypes.DidFinishRenderingFrame:
|
|
719
|
+
propName = 'onDidFinishRenderingFrame';
|
|
720
|
+
break;
|
|
721
|
+
case MapLibreGL.EventTypes.DidFinishRenderingFrameFully:
|
|
722
|
+
propName = 'onDidFinishRenderingFrameFully';
|
|
723
|
+
break;
|
|
724
|
+
case MapLibreGL.EventTypes.WillStartRenderingMap:
|
|
725
|
+
propName = 'onWillStartRenderingMap';
|
|
726
|
+
break;
|
|
727
|
+
case MapLibreGL.EventTypes.DidFinishRenderingMap:
|
|
728
|
+
propName = 'onDidFinishRenderingMap';
|
|
729
|
+
break;
|
|
730
|
+
case MapLibreGL.EventTypes.DidFinishRenderingMapFully:
|
|
731
|
+
propName = 'onDidFinishRenderingMapFully';
|
|
732
|
+
break;
|
|
733
|
+
case MapLibreGL.EventTypes.DidFinishLoadingStyle:
|
|
734
|
+
propName = 'onDidFinishLoadingStyle';
|
|
735
|
+
break;
|
|
736
|
+
default:
|
|
737
|
+
console.warn('Unhandled event callback type', type);
|
|
738
|
+
}
|
|
524
739
|
|
|
525
|
-
|
|
526
|
-
|
|
740
|
+
if (propName) {
|
|
741
|
+
_handleOnChange(propName, payload);
|
|
742
|
+
}
|
|
743
|
+
};
|
|
527
744
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
setCamera(): void {
|
|
532
|
-
console.warn(
|
|
533
|
-
'MapView.setCamera is deprecated - please use Camera#setCamera',
|
|
534
|
-
);
|
|
535
|
-
}
|
|
745
|
+
const _onLayout = (): void => {
|
|
746
|
+
setIsReady(true);
|
|
747
|
+
};
|
|
536
748
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
[writeToDisk],
|
|
547
|
-
);
|
|
548
|
-
return res.uri;
|
|
549
|
-
}
|
|
749
|
+
const _handleOnChange = <T extends CallableProps>(
|
|
750
|
+
propName: T,
|
|
751
|
+
payload?: object,
|
|
752
|
+
): void => {
|
|
753
|
+
const callable = props[propName] as (payload?: object) => void;
|
|
754
|
+
if (callable && isFunction(callable)) {
|
|
755
|
+
callable(payload);
|
|
756
|
+
}
|
|
757
|
+
};
|
|
550
758
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
* const zoom = await this._map.getZoom();
|
|
556
|
-
*
|
|
557
|
-
* @return {Number}
|
|
558
|
-
*/
|
|
759
|
+
const contentInsetValue = useMemo(() => {
|
|
760
|
+
if (!props.contentInset) {
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
559
763
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
this._nativeRef,
|
|
564
|
-
);
|
|
565
|
-
return res.zoom;
|
|
566
|
-
}
|
|
764
|
+
if (!Array.isArray(props.contentInset)) {
|
|
765
|
+
return [props.contentInset];
|
|
766
|
+
}
|
|
567
767
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
*
|
|
571
|
-
* @example
|
|
572
|
-
* const center = await this._map.getCenter();
|
|
573
|
-
*
|
|
574
|
-
* @return {Array<Number>} Coordinates
|
|
575
|
-
*/
|
|
576
|
-
async getCenter(): Promise<GeoJSON.Position> {
|
|
577
|
-
const res: {center: GeoJSON.Position} = await this._runNativeCommand(
|
|
578
|
-
'getCenter',
|
|
579
|
-
this._nativeRef,
|
|
580
|
-
);
|
|
581
|
-
return res.center;
|
|
582
|
-
}
|
|
768
|
+
return props.contentInset;
|
|
769
|
+
}, [props.contentInset]);
|
|
583
770
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
* @param {String=} sourceLayerId - Identifier of the target source-layer (e.g. 'building')
|
|
593
|
-
*/
|
|
594
|
-
setSourceVisibility(
|
|
595
|
-
visible: boolean,
|
|
596
|
-
sourceId: string,
|
|
597
|
-
sourceLayerId: string | null = null,
|
|
598
|
-
): void {
|
|
599
|
-
this._runNativeCommand('setSourceVisibility', this._nativeRef, [
|
|
600
|
-
visible,
|
|
601
|
-
sourceId,
|
|
602
|
-
sourceLayerId,
|
|
603
|
-
]);
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
/**
|
|
607
|
-
* Show the attribution and telemetry action sheet.
|
|
608
|
-
* If you implement a custom attribution button, you should add this action to the button.
|
|
609
|
-
*/
|
|
610
|
-
async showAttribution(): Promise<void> {
|
|
611
|
-
this._runNativeCommand('showAttribution', this._nativeRef);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
_onPress(e: NativeSyntheticEvent<{payload: GeoJSON.Feature}>): void {
|
|
615
|
-
if (isFunction(this.props.onPress)) {
|
|
616
|
-
this.props.onPress(e.nativeEvent.payload);
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
_onLongPress(e: NativeSyntheticEvent<{payload: GeoJSON.Feature}>): void {
|
|
621
|
-
if (isFunction(this.props.onLongPress)) {
|
|
622
|
-
this.props.onLongPress(e.nativeEvent.payload);
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
_onRegionWillChange(
|
|
627
|
-
payload: GeoJSON.Feature<GeoJSON.Point, RegionPayload>,
|
|
628
|
-
): void {
|
|
629
|
-
if (isFunction(this.props.onRegionWillChange)) {
|
|
630
|
-
this.props.onRegionWillChange(payload);
|
|
631
|
-
}
|
|
632
|
-
this.setState({isUserInteraction: payload.properties.isUserInteraction});
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
_onRegionDidChange(
|
|
636
|
-
payload: GeoJSON.Feature<GeoJSON.Point, RegionPayload>,
|
|
637
|
-
): void {
|
|
638
|
-
if (isFunction(this.props.onRegionDidChange)) {
|
|
639
|
-
this.props.onRegionDidChange(payload);
|
|
640
|
-
}
|
|
641
|
-
this.setState({region: payload});
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
_onChange(
|
|
645
|
-
e: NativeSyntheticEvent<{
|
|
646
|
-
type: string;
|
|
647
|
-
payload?: GeoJSON.Feature | Location;
|
|
648
|
-
}>,
|
|
649
|
-
): void {
|
|
650
|
-
const {regionWillChangeDebounceTime, regionDidChangeDebounceTime} =
|
|
651
|
-
this.props;
|
|
652
|
-
const {type, payload} = e.nativeEvent;
|
|
653
|
-
let propName: CallableProps | undefined;
|
|
654
|
-
|
|
655
|
-
switch (type) {
|
|
656
|
-
case MapLibreGL.EventTypes.RegionWillChange:
|
|
657
|
-
if (regionWillChangeDebounceTime && regionWillChangeDebounceTime > 0) {
|
|
658
|
-
this._onDebouncedRegionWillChange(payload);
|
|
659
|
-
} else {
|
|
660
|
-
propName = 'onRegionWillChange';
|
|
771
|
+
const _setNativeRef = (nativeRef: RCTMLNMapViewRefType): void => {
|
|
772
|
+
_nativeRef.current = nativeRef;
|
|
773
|
+
_runPendingNativeCommands(nativeRef);
|
|
774
|
+
};
|
|
775
|
+
|
|
776
|
+
const setNativeProps = (props: NativeProps): void => {
|
|
777
|
+
if (_nativeRef.current) {
|
|
778
|
+
_nativeRef.current.setNativeProps(props);
|
|
661
779
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
this._onDebouncedRegionDidChange(payload);
|
|
669
|
-
} else {
|
|
670
|
-
propName = 'onRegionDidChange';
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
const _setStyleURL = (props: MapViewProps): void => {
|
|
783
|
+
// user set a styleURL, no need to alter props
|
|
784
|
+
if (props.styleURL) {
|
|
785
|
+
return;
|
|
671
786
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
super._runPendingNativeCommands(nativeRef);
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
setNativeProps(props: NativeProps): void {
|
|
751
|
-
if (this._nativeRef) {
|
|
752
|
-
this._nativeRef.setNativeProps(props);
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
_setStyleURL(props: MapViewProps): void {
|
|
757
|
-
// user set a styleURL, no need to alter props
|
|
758
|
-
if (props.styleURL) {
|
|
759
|
-
return;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// user set styleJSON pass it to styleURL
|
|
763
|
-
if (props.styleJSON && !props.styleURL) {
|
|
764
|
-
props.styleURL = props.styleJSON;
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
// user neither set styleJSON nor styleURL
|
|
768
|
-
// set defaultStyleUrl
|
|
769
|
-
if (!props.styleJSON || !props.styleURL) {
|
|
770
|
-
props.styleURL = defaultStyleURL;
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
render(): ReactElement {
|
|
775
|
-
const props = {
|
|
776
|
-
...this.props,
|
|
777
|
-
contentInset: this._getContentInset(),
|
|
778
|
-
style: styles.matchParent,
|
|
779
|
-
};
|
|
780
|
-
|
|
781
|
-
this._setStyleURL(props);
|
|
782
|
-
|
|
783
|
-
const callbacks = {
|
|
784
|
-
ref: (ref: RCTMLNMapViewRefType) => this._setNativeRef(ref),
|
|
785
|
-
onPress: this._onPress,
|
|
786
|
-
onLongPress: this._onLongPress,
|
|
787
|
-
onMapChange: this._onChange,
|
|
788
|
-
onAndroidCallback: isAndroid() ? this._onAndroidCallback : undefined,
|
|
789
|
-
};
|
|
790
|
-
|
|
791
|
-
let mapView: ReactElement | null = null;
|
|
792
|
-
if (isAndroid() && !this.props.surfaceView && this.state.isReady) {
|
|
793
|
-
mapView = (
|
|
794
|
-
<RCTMLNAndroidTextureMapView {...props} {...callbacks}>
|
|
795
|
-
{this.props.children}
|
|
796
|
-
</RCTMLNAndroidTextureMapView>
|
|
797
|
-
);
|
|
798
|
-
} else if (this.state.isReady) {
|
|
799
|
-
mapView = (
|
|
800
|
-
<RCTMLNMapView {...props} {...callbacks}>
|
|
801
|
-
{this.props.children}
|
|
802
|
-
</RCTMLNMapView>
|
|
787
|
+
|
|
788
|
+
// user set styleJSON pass it to styleURL
|
|
789
|
+
if (props.styleJSON && !props.styleURL) {
|
|
790
|
+
props.styleURL = props.styleJSON;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// user neither set styleJSON nor styleURL
|
|
794
|
+
// set defaultStyleUrl
|
|
795
|
+
if (!props.styleJSON || !props.styleURL) {
|
|
796
|
+
props.styleURL = defaultStyleURL;
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
const nativeProps = useMemo(() => {
|
|
801
|
+
return {
|
|
802
|
+
...props,
|
|
803
|
+
localizeLabels,
|
|
804
|
+
scrollEnabled,
|
|
805
|
+
pitchEnabled,
|
|
806
|
+
rotateEnabled,
|
|
807
|
+
attributionEnabled,
|
|
808
|
+
logoEnabled,
|
|
809
|
+
surfaceView,
|
|
810
|
+
regionWillChangeDebounceTime,
|
|
811
|
+
regionDidChangeDebounceTime,
|
|
812
|
+
contentInsetValue,
|
|
813
|
+
style: styles.matchParent,
|
|
814
|
+
};
|
|
815
|
+
}, [
|
|
816
|
+
localizeLabels,
|
|
817
|
+
scrollEnabled,
|
|
818
|
+
pitchEnabled,
|
|
819
|
+
rotateEnabled,
|
|
820
|
+
attributionEnabled,
|
|
821
|
+
logoEnabled,
|
|
822
|
+
surfaceView,
|
|
823
|
+
regionWillChangeDebounceTime,
|
|
824
|
+
regionDidChangeDebounceTime,
|
|
825
|
+
contentInsetValue,
|
|
826
|
+
props,
|
|
827
|
+
contentInsetValue,
|
|
828
|
+
]);
|
|
829
|
+
|
|
830
|
+
_setStyleURL(nativeProps);
|
|
831
|
+
|
|
832
|
+
const callbacks = {
|
|
833
|
+
ref: (ref: RCTMLNMapViewRefType): void => _setNativeRef(ref),
|
|
834
|
+
onPress: _onPress,
|
|
835
|
+
onLongPress: _onLongPress,
|
|
836
|
+
onMapChange: _onChange,
|
|
837
|
+
onAndroidCallback: isAndroid() ? _onAndroidCallback : undefined,
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
let mapView: ReactElement | null = null;
|
|
841
|
+
if (isAndroid() && !surfaceView && isReady) {
|
|
842
|
+
mapView = (
|
|
843
|
+
<RCTMLNAndroidTextureMapView {...nativeProps} {...callbacks}>
|
|
844
|
+
{props.children}
|
|
845
|
+
</RCTMLNAndroidTextureMapView>
|
|
846
|
+
);
|
|
847
|
+
} else if (isReady) {
|
|
848
|
+
mapView = (
|
|
849
|
+
<RCTMLNMapView {...nativeProps} {...callbacks}>
|
|
850
|
+
{props.children}
|
|
851
|
+
</RCTMLNMapView>
|
|
852
|
+
);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
return (
|
|
856
|
+
<View
|
|
857
|
+
onLayout={_onLayout}
|
|
858
|
+
style={props.style}
|
|
859
|
+
testID={mapView ? undefined : props.testID}>
|
|
860
|
+
{mapView}
|
|
861
|
+
</View>
|
|
803
862
|
);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
<View
|
|
808
|
-
onLayout={this._onLayout}
|
|
809
|
-
style={this.props.style}
|
|
810
|
-
testID={mapView ? undefined : this.props.testID}>
|
|
811
|
-
{mapView}
|
|
812
|
-
</View>
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
863
|
+
},
|
|
864
|
+
),
|
|
865
|
+
);
|
|
816
866
|
|
|
817
867
|
type RCTMLNMapViewRefType = Component<NativeProps> & Readonly<NativeMethods>;
|
|
818
868
|
const RCTMLNMapView = requireNativeComponent<NativeProps>(NATIVE_MODULE_NAME);
|