mirror of
https://github.com/status-im/react-native-mapbox-gl.git
synced 2026-08-30 20:41:08 +00:00
Send only annotation changes over bridge
This commit is contained in:
+55
-7
@@ -8,6 +8,10 @@ import {
|
||||
findNodeHandle
|
||||
} from 'react-native';
|
||||
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import clone from 'lodash/clone';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
const { MapboxGLManager } = NativeModules;
|
||||
const { mapStyles, userTrackingMode, userLocationVerticalAlignment, unknownResourceCount } = MapboxGLManager;
|
||||
|
||||
@@ -206,9 +210,6 @@ class MapView extends Component {
|
||||
onTap: PropTypes.func,
|
||||
contentInset: PropTypes.array,
|
||||
userLocationVerticalAlignment: PropTypes.number,
|
||||
onOfflineProgressDidChange: PropTypes.func,
|
||||
onOfflineMaxAllowedMapboxTiles: PropTypes.func,
|
||||
onOfflineDidRecieveError: PropTypes.func,
|
||||
onChangeUserTrackingMode: PropTypes.func
|
||||
};
|
||||
|
||||
@@ -231,10 +232,59 @@ class MapView extends Component {
|
||||
compassIsHidden: false
|
||||
};
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
const oldKeys = clone(this._annotations);
|
||||
const itemsToAdd = [];
|
||||
const itemsToRemove = [];
|
||||
|
||||
newProps.annotations.forEach(annotation => {
|
||||
const id = annotation.id;
|
||||
if (!isEqual(this._annotations[id], annotation)) {
|
||||
this._annotations[id] = cloneDeep(annotation);
|
||||
itemsToAdd.push(annotation);
|
||||
}
|
||||
oldKeys[id] = null;
|
||||
});
|
||||
|
||||
for (let key in oldKeys) {
|
||||
if (oldKeys[key]) {
|
||||
delete this._annotations[key];
|
||||
itemsToRemove.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
MapboxGLManager.spliceAnnotations(findNodeHandle(this), false, itemsToRemove, itemsToAdd);
|
||||
}
|
||||
|
||||
_native = null;
|
||||
|
||||
onNativeComponentMount = (ref) => {
|
||||
if (this._native === ref) { return; }
|
||||
this._native = ref;
|
||||
|
||||
MapboxGLManager.spliceAnnotations(findNodeHandle(this), true, [], this.props.annotations);
|
||||
|
||||
let annotations = this.props.annotations.reduce((acc, annotation) => {
|
||||
acc[annotation.id] = cloneDeep(annotation);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
this._annotations = annotations;
|
||||
};
|
||||
|
||||
setNativeProps(nativeProps) {
|
||||
this._native && this._native.setNativeProps(nativeProps);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._native = null;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MapboxGLView
|
||||
{...this.props}
|
||||
ref={this.onNativeComponentMount}
|
||||
onRegionChange={this._onRegionChange}
|
||||
onRegionWillChange={this._onRegionWillChange}
|
||||
onOpenAnnotation={this._onOpenAnnotation}
|
||||
@@ -245,10 +295,8 @@ class MapView extends Component {
|
||||
onFinishLoadingMap={this._onFinishLoadingMap}
|
||||
onStartLoadingMap={this._onStartLoadingMap}
|
||||
onLocateUserFailed={this._onLocateUserFailed}
|
||||
onOfflineProgressDidChange={this._onOfflineProgressDidChange}
|
||||
onOfflineMaxAllowedMapboxTiles={this._onOfflineMaxAllowedMapboxTiles}
|
||||
onOfflineDidRecieveError={this._onOfflineDidRecieveError}
|
||||
onChangeUserTrackingMode={this._onChangeUserTrackingMode} />
|
||||
onChangeUserTrackingMode={this._onChangeUserTrackingMode}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
- (void)selectAnnotation:(NSString*)selectedId animated:(BOOL)animated;
|
||||
|
||||
// Annotation management
|
||||
- (void)addAnnotation:(NSObject *)annotation;
|
||||
- (void)upsertAnnotation:(NSObject *)annotation;
|
||||
- (void)removeAnnotation:(NSString*)selectedIdentifier;
|
||||
- (void)removeAllAnnotations;
|
||||
|
||||
|
||||
@@ -101,7 +101,9 @@
|
||||
_isChangingUserTracking = YES;
|
||||
_map.userTrackingMode = _userTrackingMode;
|
||||
_isChangingUserTracking = NO;
|
||||
[_map addAnnotations:[_annotations allValues]];
|
||||
for (NSString * annotationId in _annotations) {
|
||||
[_map addAnnotation:_annotations[annotationId]];
|
||||
}
|
||||
|
||||
[self addSubview:_map];
|
||||
[self layoutSubviews];
|
||||
@@ -122,14 +124,19 @@
|
||||
|
||||
// Annotation management
|
||||
|
||||
- (void)addAnnotation:(RCTMGLAnnotation *) annotation {
|
||||
- (void)upsertAnnotation:(RCTMGLAnnotation *) annotation {
|
||||
NSString * identifier = [annotation id];
|
||||
if (!identifier || [identifier length] == 0) {
|
||||
RCTLogError(@"field `id` is required on all annotations");
|
||||
return;
|
||||
}
|
||||
|
||||
RCTMGLAnnotation * oldAnnotation = [_annotations objectForKey:identifier];
|
||||
[_annotations setObject:annotation forKey:identifier];
|
||||
[_map addAnnotation:annotation];
|
||||
if (oldAnnotation) {
|
||||
[_map removeAnnotation:oldAnnotation];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeAnnotation:(NSString*)selectedIdentifier
|
||||
|
||||
@@ -73,23 +73,6 @@ RCT_CUSTOM_VIEW_PROPERTY(contentInset, UIEdgeInsetsMake, RCTMapboxGL)
|
||||
view.contentInset = inset;
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(annotations, CLLocationCoordinate2D, RCTMapboxGL)
|
||||
{
|
||||
if ([json isKindOfClass:[NSArray class]]) {
|
||||
[view removeAllAnnotations];
|
||||
|
||||
id annotationObject;
|
||||
NSEnumerator *enumerator = [json objectEnumerator];
|
||||
|
||||
while (annotationObject = [enumerator nextObject]) {
|
||||
CLLocationCoordinate2D coordinate = [RCTConvert CLLocationCoordinate2D:annotationObject];
|
||||
if (CLLocationCoordinate2DIsValid(coordinate)){
|
||||
[view addAnnotation:convertToMGLAnnotation(annotationObject)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Constants
|
||||
|
||||
- (NSDictionary *)constantsToExport
|
||||
@@ -306,6 +289,28 @@ RCT_EXPORT_METHOD(removePack:(NSString*)packName
|
||||
|
||||
// View methods
|
||||
|
||||
RCT_EXPORT_METHOD(spliceAnnotations:(nonnull NSNumber *)reactTag
|
||||
deleteAll:(BOOL)deleteAll
|
||||
toDelete:(nonnull NSArray<NSString *> *)toDelete
|
||||
toAdd:(nonnull NSArray *)toAdd)
|
||||
{
|
||||
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, RCTMapboxGL *> *viewRegistry) {
|
||||
RCTMapboxGL *mapView = viewRegistry[reactTag];
|
||||
|
||||
if (deleteAll) {
|
||||
[mapView removeAllAnnotations];
|
||||
} else {
|
||||
for (NSString * key in toDelete) {
|
||||
[mapView removeAnnotation:key];
|
||||
}
|
||||
}
|
||||
|
||||
for (NSObject * annotationObject in toAdd) {
|
||||
[mapView upsertAnnotation:convertToMGLAnnotation(annotationObject)];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getCenterCoordinateZoomLevel:(nonnull NSNumber *)reactTag
|
||||
callback:(RCTResponseSenderBlock)callback)
|
||||
{
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@
|
||||
"eslint-plugin-react": "^3.11.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-eslint": "^4.1.6"
|
||||
"babel-eslint": "^4.1.6",
|
||||
"lodash": "^4.13.1"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user