react-native-maps 2.0.0-beta.10 → 2.0.0-beta.12

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.
@@ -279,26 +279,9 @@ public class MapManager extends ViewGroupManager<MapView> {
279
279
  view.setBoundary(boundary);
280
280
  }
281
281
 
282
- @Override
283
- public void receiveCommand(@NonNull MapView view, String commandId, @Nullable ReadableArray args) {
284
- ReadableMap camera;
285
-
286
- switch (commandId) {
287
- case "setCamera":
288
- if(args == null) {
289
- break;
290
- }
291
- camera = args.getMap(0);
292
- view.animateToCamera(camera, 0);
293
- break;
294
-
295
- case "setIndoorActiveLevelIndex":
296
- if(args == null) {
297
- break;
298
- }
299
- view.setIndoorActiveLevelIndex(args.getInt(0));
300
- break;
301
- }
282
+ @ReactProp(name = "indoorActiveLevelIndex")
283
+ public void setIndoorActiveLevelIndex(MapView view, int index) {
284
+ view.setIndoorActiveLevelIndex(index);
302
285
  }
303
286
 
304
287
  @Override
@@ -886,19 +886,6 @@ public class MapView extends com.google.android.gms.maps.MapView implements Goog
886
886
  return CameraUpdateFactory.newCameraPosition(builder.build());
887
887
  }
888
888
 
889
- public void animateToCamera(ReadableMap camera, int duration) {
890
- if (map == null) return;
891
-
892
- CameraUpdate update = buildCameraUpdate(camera);
893
-
894
- if (duration <= 0) {
895
- map.moveCamera(update);
896
- }
897
- else {
898
- map.animateCamera(update, duration, null);
899
- }
900
- }
901
-
902
889
  public int baseLeftMapPadding;
903
890
  public int baseRightMapPadding;
904
891
  public int baseTopMapPadding;
@@ -434,26 +434,34 @@ public class MapViewModule extends ReactContextBaseJavaModule {
434
434
  promise.reject("RNMMapView.map is not valid");
435
435
  return;
436
436
  }
437
- LatLngBounds.Builder builder = new LatLngBounds.Builder();
438
-
439
437
  boolean addedPosition = false;
440
438
 
439
+ double maxLatitude = -Double.MAX_VALUE;
440
+ double minLatitude = Double.MAX_VALUE;
441
+ double maxLongitude = -Double.MAX_VALUE;
442
+ double minLongitude = Double.MAX_VALUE;
443
+
441
444
  for (MapFeature feature : view.features) {
442
445
  if (feature instanceof MapMarker) {
443
- Marker marker = (Marker) feature.getFeature();
444
- builder.include(marker.getPosition());
446
+ LatLng position = ((Marker) feature.getFeature()).getPosition();
447
+ maxLatitude = Math.max(maxLatitude, position.latitude);
448
+ minLatitude = Math.min(minLatitude, position.latitude);
449
+ maxLongitude = Math.max(maxLongitude, position.longitude);
450
+ minLongitude = Math.min(minLongitude, position.longitude);
445
451
  addedPosition = true;
446
452
  }
447
453
  // TODO(lmr): may want to include shapes / etc.
448
454
  }
449
- if (addedPosition) {
450
- LatLngBounds bounds = builder.build();
451
- CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, view.baseMapPadding);
452
-
453
- if (edgePadding != null) {
454
- view.map.setPadding(edgePadding.getInt("left"), edgePadding.getInt("top"),
455
- edgePadding.getInt("right"), edgePadding.getInt("bottom"));
456
- }
455
+ if(!addedPosition) {
456
+ // nothing to do
457
+ promise.resolve(null);
458
+ } else {
459
+ Map<String, Double> paddedBoundary = padBoundary(view, maxLatitude, minLatitude, maxLongitude, minLongitude, edgePadding);
460
+ LatLngBounds bounds = new LatLngBounds(
461
+ new LatLng(paddedBoundary.get("minLatitude"), paddedBoundary.get("minLongitude")), // southwest
462
+ new LatLng(paddedBoundary.get("maxLatitude"), paddedBoundary.get("maxLongitude")) // northeast
463
+ );
464
+ CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
457
465
 
458
466
  if (duration > 0) {
459
467
  view.map.animateCamera(cu, duration, new GoogleMap.CancelableCallback() {
@@ -491,7 +499,6 @@ public class MapViewModule extends ReactContextBaseJavaModule {
491
499
  promise.reject("RNMMapView.map is not valid");
492
500
  return;
493
501
  }
494
- LatLngBounds.Builder builder = new LatLngBounds.Builder();
495
502
 
496
503
  String[] markerIDs = new String[markersIds.size()];
497
504
  for (int i = 0; i < markersIds.size(); i++) {
@@ -502,25 +509,35 @@ public class MapViewModule extends ReactContextBaseJavaModule {
502
509
 
503
510
  List<String> markerIDList = Arrays.asList(markerIDs);
504
511
 
512
+ double maxLatitude = -Double.MAX_VALUE;
513
+ double minLatitude = Double.MAX_VALUE;
514
+ double maxLongitude = -Double.MAX_VALUE;
515
+ double minLongitude = Double.MAX_VALUE;
516
+
505
517
  for (MapFeature feature : view.features) {
506
518
  if (feature instanceof MapMarker) {
507
519
  String identifier = ((MapMarker) feature).getIdentifier();
508
- Marker marker = (Marker) feature.getFeature();
509
520
  if (markerIDList.contains(identifier)) {
510
- builder.include(marker.getPosition());
521
+ LatLng position = ((Marker) feature.getFeature()).getPosition();
522
+ maxLatitude = Math.max(maxLatitude, position.latitude);
523
+ minLatitude = Math.min(minLatitude, position.latitude);
524
+ maxLongitude = Math.max(maxLongitude, position.longitude);
525
+ minLongitude = Math.min(minLongitude, position.longitude);
511
526
  addedPosition = true;
512
527
  }
513
528
  }
514
529
  }
515
530
 
516
- if (addedPosition) {
517
- LatLngBounds bounds = builder.build();
518
- CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, view.baseMapPadding);
519
-
520
- if (edgePadding != null) {
521
- view.map.setPadding(edgePadding.getInt("left"), edgePadding.getInt("top"),
522
- edgePadding.getInt("right"), edgePadding.getInt("bottom"));
523
- }
531
+ if(!addedPosition) {
532
+ // nothing to do
533
+ promise.resolve(null);
534
+ } else {
535
+ Map<String, Double> paddedBoundary = padBoundary(view, maxLatitude, minLatitude, maxLongitude, minLongitude, edgePadding);
536
+ LatLngBounds bounds = new LatLngBounds(
537
+ new LatLng(paddedBoundary.get("minLatitude"), paddedBoundary.get("minLongitude")), // southwest
538
+ new LatLng(paddedBoundary.get("maxLatitude"), paddedBoundary.get("maxLongitude")) // northeast
539
+ );
540
+ CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
524
541
 
525
542
  if (duration > 0) {
526
543
  view.map.animateCamera(cu, duration, new GoogleMap.CancelableCallback() {
@@ -558,21 +575,28 @@ public class MapViewModule extends ReactContextBaseJavaModule {
558
575
  return;
559
576
  }
560
577
 
561
- LatLngBounds.Builder builder = new LatLngBounds.Builder();
578
+ double maxLatitude = -Double.MAX_VALUE;
579
+ double minLatitude = Double.MAX_VALUE;
580
+ double maxLongitude = -Double.MAX_VALUE;
581
+ double minLongitude = Double.MAX_VALUE;
562
582
 
563
583
  for (int i = 0; i < coordinates.size(); i++) {
564
584
  ReadableMap latLng = coordinates.getMap(i);
565
585
  double lat = latLng.getDouble("latitude");
566
586
  double lng = latLng.getDouble("longitude");
567
- builder.include(new LatLng(lat, lng));
587
+ maxLatitude = Math.max(maxLatitude, lat);
588
+ minLatitude = Math.min(minLatitude, lat);
589
+ maxLongitude = Math.max(maxLongitude, lng);
590
+ minLongitude = Math.min(minLongitude, lng);
568
591
  }
569
592
 
570
- LatLngBounds bounds = builder.build();
571
- CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, view.baseMapPadding);
593
+ Map<String, Double> paddedBoundary = padBoundary(view, maxLatitude, minLatitude, maxLongitude, minLongitude, edgePadding);
594
+ LatLngBounds bounds = new LatLngBounds(
595
+ new LatLng(paddedBoundary.get("minLatitude"), paddedBoundary.get("minLongitude")), // southwest
596
+ new LatLng(paddedBoundary.get("maxLatitude"), paddedBoundary.get("maxLongitude")) // northeast
597
+ );
572
598
 
573
- if (edgePadding != null) {
574
- view.appendMapPadding(edgePadding.getInt("left"), edgePadding.getInt("top"), edgePadding.getInt("right"), edgePadding.getInt("bottom"));
575
- }
599
+ CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
576
600
 
577
601
  if (duration > 0) {
578
602
  view.map.animateCamera(cu, duration, new GoogleMap.CancelableCallback() {
@@ -590,9 +614,29 @@ public class MapViewModule extends ReactContextBaseJavaModule {
590
614
  view.map.moveCamera(cu);
591
615
  promise.resolve(null);
592
616
  }
593
- // Move the google logo to the default base padding value.
594
- view.map.setPadding(view.baseLeftMapPadding, view.baseTopMapPadding, view.baseRightMapPadding, view.baseBottomMapPadding);
595
617
  }
596
618
  });
597
619
  }
620
+
621
+ private Map<String, Double> padBoundary(MapView mapView, double maxLat, double minLat, double maxLng, double minLng, ReadableMap edgePadding) {
622
+ double latitudeDelta = maxLat - minLat;
623
+ double longitudeDelta = maxLng - minLng;
624
+ float displayDensity = context.getResources().getDisplayMetrics().density;
625
+ double mapViewHeight = mapView.getHeight() / displayDensity;
626
+ double mapViewWidth = mapView.getWidth() / displayDensity;
627
+ double latPerHeight = latitudeDelta / mapViewHeight;
628
+ double lngPerWidth = longitudeDelta / mapViewWidth;
629
+ double paddedMaxLatitude = maxLat + latPerHeight * edgePadding.getInt("top");
630
+ double paddedMinLatitude = minLat - latPerHeight * edgePadding.getInt("bottom");
631
+ double paddedMaxLongitude = maxLng + lngPerWidth * edgePadding.getInt("right");
632
+ double paddedMinLongitude = minLng - lngPerWidth * edgePadding.getInt("left");
633
+
634
+ Map<String,Double> paddedBoundary = new HashMap<String,Double>();
635
+ paddedBoundary.put("maxLatitude", paddedMaxLatitude);
636
+ paddedBoundary.put("minLatitude", paddedMinLatitude);
637
+ paddedBoundary.put("maxLongitude", paddedMaxLongitude);
638
+ paddedBoundary.put("minLongitude", paddedMinLongitude);
639
+
640
+ return paddedBoundary;
641
+ }
598
642
  }
@@ -309,6 +309,15 @@ id regionAsJSON(MKCoordinateRegion region) {
309
309
  self.cameraTargetBounds = boundary;
310
310
  }
311
311
 
312
+ - (void)setIndoorActiveLevelIndex:(NSInteger)index {
313
+ if (!self.indoorDisplay) {
314
+ return;
315
+ }
316
+ if ( index < [self.indoorDisplay.activeBuilding.levels count]) {
317
+ self.indoorDisplay.activeLevel = self.indoorDisplay.activeBuilding.levels[index];
318
+ }
319
+ }
320
+
312
321
  - (void)didPrepareMap {
313
322
  UIView* mapView = [self valueForKey:@"mapView"]; //GMSVectorMapView
314
323
  [self overrideGestureRecognizersForView:mapView];
@@ -67,6 +67,7 @@ RCT_EXPORT_MODULE(RNMGoogleMap)
67
67
 
68
68
  RCT_EXPORT_VIEW_PROPERTY(boundary, GMSCoordinateBounds*)
69
69
  RCT_EXPORT_VIEW_PROPERTY(customMapStyleString, NSString)
70
+ RCT_EXPORT_VIEW_PROPERTY(indoorActiveLevelIndex, NSInteger)
70
71
  RCT_EXPORT_VIEW_PROPERTY(initialCamera, GMSCameraPosition)
71
72
  RCT_EXPORT_VIEW_PROPERTY(initialRegion, MKCoordinateRegion)
72
73
  RCT_EXPORT_VIEW_PROPERTY(isAccessibilityElement, BOOL)
@@ -107,40 +108,6 @@ RCT_REMAP_VIEW_PROPERTY(camera, cameraProp, GMSCameraPosition)
107
108
  RCT_REMAP_VIEW_PROPERTY(paddingAdjustmentBehavior, paddingAdjustmentBehaviorString, NSString)
108
109
  RCT_REMAP_VIEW_PROPERTY(testID, accessibilityIdentifier, NSString)
109
110
 
110
- RCT_EXPORT_METHOD(setCamera:(nonnull NSNumber *)reactTag
111
- camera:(id)json)
112
- {
113
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
114
- id view = viewRegistry[reactTag];
115
- if (![view isKindOfClass:[RNMGoogleMap class]]) {
116
- RCTLogError(@"Invalid view returned from registry, expecting RNMGoogleMap, got: %@", view);
117
- } else {
118
- RNMGoogleMap *mapView = (RNMGoogleMap *)view;
119
- GMSCameraPosition *camera = [RCTConvert GMSCameraPositionWithDefaults:json existingCamera:[mapView camera]];
120
- [mapView setCamera:camera];
121
- }
122
- }];
123
- }
124
-
125
- RCT_EXPORT_METHOD(setIndoorActiveLevelIndex:(nonnull NSNumber *)reactTag
126
- levelIndex:(NSInteger) levelIndex)
127
- {
128
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
129
- id view = viewRegistry[reactTag];
130
- if (![view isKindOfClass:[RNMGoogleMap class]]) {
131
- RCTLogError(@"Invalid view returned from registry, expecting RNMGoogleMap, got: %@", view);
132
- } else {
133
- RNMGoogleMap *mapView = (RNMGoogleMap *)view;
134
- if (!mapView.indoorDisplay) {
135
- return;
136
- }
137
- if ( levelIndex < [mapView.indoorDisplay.activeBuilding.levels count]) {
138
- mapView.indoorDisplay.activeLevel = mapView.indoorDisplay.activeBuilding.levels[levelIndex];
139
- }
140
- }
141
- }];
142
- }
143
-
144
111
  + (BOOL)requiresMainQueueSetup {
145
112
  return YES;
146
113
  }
@@ -224,13 +224,18 @@ RCT_EXPORT_METHOD(animateCamera:(nonnull NSNumber *)reactTag
224
224
  RNMGoogleMap *mapView = (RNMGoogleMap *)view;
225
225
  GMSCameraPosition *camera = [RCTConvert GMSCameraPositionWithDefaults:json existingCamera:[mapView camera]];
226
226
 
227
- [CATransaction begin];
228
- [CATransaction setCompletionBlock:^{
229
- resolve(nil);
230
- }];
231
- [CATransaction setAnimationDuration:duration/1000];
232
- [mapView animateToCameraPosition:camera];
233
- [CATransaction commit];
227
+ if(duration > 0.0f) {
228
+ [CATransaction begin];
229
+ [CATransaction setCompletionBlock:^{
230
+ resolve(nil);
231
+ }];
232
+ [CATransaction setAnimationDuration:duration/1000];
233
+ [mapView animateToCameraPosition:camera];
234
+ [CATransaction commit];
235
+ } else {
236
+ [mapView moveCamera:camera];
237
+ resolve(nil);
238
+ }
234
239
  }
235
240
  }];
236
241
  }
@@ -256,17 +261,13 @@ RCT_EXPORT_METHOD(fitToElements:(nonnull NSNumber *)reactTag
256
261
 
257
262
  GMSCameraUpdate* cameraUpdate;
258
263
 
259
- if ([edgePadding count] != 0) {
260
- // Set Map viewport
261
- CGFloat top = [RCTConvert CGFloat:edgePadding[@"top"]];
262
- CGFloat right = [RCTConvert CGFloat:edgePadding[@"right"]];
263
- CGFloat bottom = [RCTConvert CGFloat:edgePadding[@"bottom"]];
264
- CGFloat left = [RCTConvert CGFloat:edgePadding[@"left"]];
264
+ // Set Map viewport
265
+ CGFloat top = [RCTConvert CGFloat:edgePadding[@"top"]];
266
+ CGFloat right = [RCTConvert CGFloat:edgePadding[@"right"]];
267
+ CGFloat bottom = [RCTConvert CGFloat:edgePadding[@"bottom"]];
268
+ CGFloat left = [RCTConvert CGFloat:edgePadding[@"left"]];
265
269
 
266
- cameraUpdate = [GMSCameraUpdate fitBounds:bounds withEdgeInsets:UIEdgeInsetsMake(top, left, bottom, right)];
267
- } else {
268
- cameraUpdate = [GMSCameraUpdate fitBounds:bounds withPadding:55.0f];
269
- }
270
+ cameraUpdate = [GMSCameraUpdate fitBounds:bounds withEdgeInsets:UIEdgeInsetsMake(top, left, bottom, right)];
270
271
  if (duration > 0.0f) {
271
272
  [CATransaction begin];
272
273
  [CATransaction setCompletionBlock:^{
@@ -170,30 +170,6 @@ RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RNMMap)
170
170
  view.ignoreRegionChanges = originalIgnore;
171
171
  }
172
172
 
173
- #pragma mark exported MapView methods
174
-
175
- RCT_EXPORT_METHOD(setCamera:(nonnull NSNumber *)reactTag
176
- camera:(id)json)
177
- {
178
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
179
- id view = viewRegistry[reactTag];
180
- if (![view isKindOfClass:[RNMMap class]]) {
181
- RCTLogError(@"Invalid view returned from registry, expecting RNMMap, got: %@", view);
182
- } else {
183
- RNMMap *mapView = (RNMMap *)view;
184
-
185
- // Merge the changes given with the current camera
186
- MKMapCamera *camera = [RCTConvert MKMapCameraWithDefaults:json existingCamera:[mapView camera]];
187
-
188
- // don't emit region change events when we are setting the camera
189
- BOOL originalIgnore = mapView.ignoreRegionChanges;
190
- mapView.ignoreRegionChanges = YES;
191
- [mapView setCamera:camera animated:NO];
192
- mapView.ignoreRegionChanges = originalIgnore;
193
- }
194
- }];
195
- }
196
-
197
173
  #pragma mark Gesture Recognizer Handlers
198
174
 
199
175
  #define MAX_DISTANCE_PX 10.0f
@@ -259,12 +259,18 @@ RCT_EXPORT_METHOD(animateCamera:(nonnull NSNumber *)reactTag
259
259
  // don't emit region change events when we are setting the camera
260
260
  BOOL originalIgnore = mapView.ignoreRegionChanges;
261
261
  mapView.ignoreRegionChanges = YES;
262
- [RNMMap animateWithDuration:duration/1000 animations:^{
263
- [mapView setCamera:camera animated:YES];
264
- } completion:^(BOOL finished){
262
+ if(duration > 0.0f) {
263
+ [RNMMap animateWithDuration:duration/1000 animations:^{
264
+ [mapView setCamera:camera animated:YES];
265
+ } completion:^(BOOL finished){
266
+ mapView.ignoreRegionChanges = originalIgnore;
267
+ resolve(nil);
268
+ }];
269
+ } else {
270
+ [mapView setCamera:camera animated:NO];
265
271
  mapView.ignoreRegionChanges = originalIgnore;
266
272
  resolve(nil);
267
- }];
273
+ }
268
274
  }
269
275
  }];
270
276
  }
@@ -281,21 +287,62 @@ RCT_EXPORT_METHOD(fitToElements:(nonnull NSNumber *)reactTag
281
287
  RCTLogError(@"Invalid view returned from registry, expecting RNMMap, got: %@", view);
282
288
  } else {
283
289
  RNMMap *mapView = (RNMMap *)view;
290
+
291
+ if(mapView.annotations.count < 1) {
292
+ resolve(nil);
293
+ } else {
294
+ CLLocationDegrees minLatitude = DBL_MAX;
295
+ CLLocationDegrees maxLatitude = -DBL_MAX;
296
+ CLLocationDegrees minLongitude = DBL_MAX;
297
+ CLLocationDegrees maxLongitude = -DBL_MAX;
298
+
299
+ for(id<MKAnnotation> annotation in mapView.annotations) {
300
+ double annotationLat = annotation.coordinate.latitude;
301
+ double annotationLong = annotation.coordinate.longitude;
302
+ minLatitude = fmin(annotationLat, minLatitude);
303
+ maxLatitude = fmax(annotationLat, maxLatitude);
304
+ minLongitude = fmin(annotationLong, minLongitude);
305
+ maxLongitude = fmax(annotationLong, maxLongitude);
306
+ }
307
+
308
+ double latitudeDelta = maxLatitude - minLatitude;
309
+ double longitudeDelta = maxLongitude - minLongitude;
310
+
311
+ double mapViewHeight = mapView.bounds.size.height;
312
+ double mapViewWidth = mapView.bounds.size.width;
313
+
314
+ double latPerHeight = latitudeDelta / mapViewHeight;
315
+ double lngPerWidth = longitudeDelta / mapViewWidth;
316
+
317
+ CGFloat topPadding = [RCTConvert CGFloat:edgePadding[@"top"]];
318
+ CGFloat rightPadding = [RCTConvert CGFloat:edgePadding[@"right"]];
319
+ CGFloat bottomPadding = [RCTConvert CGFloat:edgePadding[@"bottom"]];
320
+ CGFloat leftPadding = [RCTConvert CGFloat:edgePadding[@"left"]];
321
+
322
+ maxLatitude = maxLatitude + topPadding * latPerHeight;
323
+ minLatitude = minLatitude - bottomPadding * latPerHeight;
324
+ maxLongitude = maxLongitude + rightPadding * lngPerWidth;
325
+ minLongitude = minLongitude - leftPadding * lngPerWidth;
326
+
327
+ MKCoordinateRegion region;
328
+ region.center.latitude = (minLatitude + maxLatitude) / 2;
329
+ region.center.longitude = (minLongitude + maxLongitude) / 2;
330
+ // if fitting a single marker or if all markers are aligned, the delta will be zero (infinite zoom)
331
+ // this will cause mapkit not to zoom at all. Picking an arbitrary small number to circumvent
332
+ region.span.latitudeDelta = fmax(maxLatitude - minLatitude, 0.000001);
333
+ region.span.longitudeDelta = fmax(maxLongitude - minLongitude, 0.000001);
284
334
 
285
- // TODO(lmr): we potentially want to include overlays here... and could concat the two arrays together.
286
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
287
335
  if(duration > 0.0f) {
288
336
  [RNMMap animateWithDuration:duration/1000 animations:^{
289
- [mapView showAnnotations:mapView.annotations animated:YES];
337
+ [mapView setRegion:region animated:YES];
290
338
  } completion:^(BOOL finished){
291
339
  resolve(nil);
292
340
  }];
293
341
  } else {
294
- [mapView showAnnotations:mapView.annotations animated:NO];
342
+ [mapView setRegion:region animated:NO];
295
343
  resolve(nil);
296
344
  }
297
-
298
- });
345
+ }
299
346
  }
300
347
  }];
301
348
  }
@@ -322,17 +369,62 @@ RCT_EXPORT_METHOD(fitToSuppliedMarkers:(nonnull NSNumber *)reactTag
322
369
  }];
323
370
 
324
371
  NSArray *filteredMarkers = [mapView.annotations filteredArrayUsingPredicate:filterMarkers];
372
+
373
+ if(filteredMarkers.count < 1) {
374
+ resolve(nil);
375
+ } else {
376
+ CLLocationDegrees minLatitude = DBL_MAX;
377
+ CLLocationDegrees maxLatitude = -DBL_MAX;
378
+ CLLocationDegrees minLongitude = DBL_MAX;
379
+ CLLocationDegrees maxLongitude = -DBL_MAX;
380
+
381
+ for(id<MKAnnotation> annotation in filteredMarkers) {
382
+ double annotationLat = annotation.coordinate.latitude;
383
+ double annotationLong = annotation.coordinate.longitude;
384
+ minLatitude = fmin(annotationLat, minLatitude);
385
+ maxLatitude = fmax(annotationLat, maxLatitude);
386
+ minLongitude = fmin(annotationLong, minLongitude);
387
+ maxLongitude = fmax(annotationLong, maxLongitude);
388
+ }
389
+
390
+ double latitudeDelta = maxLatitude - minLatitude;
391
+ double longitudeDelta = maxLongitude - minLongitude;
392
+
393
+ double mapViewHeight = mapView.bounds.size.height;
394
+ double mapViewWidth = mapView.bounds.size.width;
395
+
396
+ double latPerHeight = latitudeDelta / mapViewHeight;
397
+ double lngPerWidth = longitudeDelta / mapViewWidth;
398
+
399
+ CGFloat topPadding = [RCTConvert CGFloat:edgePadding[@"top"]];
400
+ CGFloat rightPadding = [RCTConvert CGFloat:edgePadding[@"right"]];
401
+ CGFloat bottomPadding = [RCTConvert CGFloat:edgePadding[@"bottom"]];
402
+ CGFloat leftPadding = [RCTConvert CGFloat:edgePadding[@"left"]];
403
+
404
+ maxLatitude = maxLatitude + topPadding * latPerHeight;
405
+ minLatitude = minLatitude - bottomPadding * latPerHeight;
406
+ maxLongitude = maxLongitude + rightPadding * lngPerWidth;
407
+ minLongitude = minLongitude - leftPadding * lngPerWidth;
408
+
409
+ MKCoordinateRegion region;
410
+ region.center.latitude = (minLatitude + maxLatitude) / 2;
411
+ region.center.longitude = (minLongitude + maxLongitude) / 2;
412
+ // if fitting a single marker or if all markers are aligned, the delta will be zero (infinite zoom)
413
+ // this will cause mapkit not to zoom at all. Picking an arbitrary small number to circumvent
414
+ region.span.latitudeDelta = fmax(maxLatitude - minLatitude, 0.000001);
415
+ region.span.longitudeDelta = fmax(maxLongitude - minLongitude, 0.000001);
325
416
 
326
- if(duration > 0.0f) {
327
- [RNMMap animateWithDuration:duration/1000 animations:^{
328
- [mapView showAnnotations:filteredMarkers animated:YES];
329
- } completion:^(BOOL finished){
330
- resolve(nil);
331
- }];
417
+ if(duration > 0.0f) {
418
+ [RNMMap animateWithDuration:duration/1000 animations:^{
419
+ [mapView setRegion:region animated:YES];
420
+ } completion:^(BOOL finished){
421
+ resolve(nil);
422
+ }];
332
423
  } else {
333
- [mapView showAnnotations:filteredMarkers animated:NO];
424
+ [mapView setRegion:region animated:NO];
334
425
  resolve(nil);
335
426
  }
427
+ }
336
428
  }
337
429
  }];
338
430
  }
package/lib/MapView.d.ts CHANGED
@@ -53,6 +53,13 @@ export type MapViewProps = ViewProps & {
53
53
  * @platform Android: Not supported
54
54
  */
55
55
  followsUserLocation?: boolean;
56
+ /**
57
+ * Set to control what indoor building level to display.
58
+ *
59
+ * @platform iOS: Google Maps only
60
+ * @platform Android: Supported
61
+ */
62
+ indoorActiveLevelIndex?: number;
56
63
  /**
57
64
  * The initial camera view the map should use. Use this prop instead of `camera`
58
65
  * only if you don't want to control the camera of the map besides the initial view.
@@ -586,7 +593,6 @@ declare class MapView extends React.Component<MapViewProps, State> {
586
593
  private _onMapReady;
587
594
  private _onChange;
588
595
  getCamera(): Promise<Camera>;
589
- setCamera(camera: Partial<Camera>): void;
590
596
  animateCamera(camera: Partial<Camera>, duration?: number): Promise<void>;
591
597
  animateToRegion(region: Region, duration?: number): Promise<void>;
592
598
  fitToElements(options?: FitToOptions): Promise<void>;
@@ -598,7 +604,6 @@ declare class MapView extends React.Component<MapViewProps, State> {
598
604
  * @return Promise Promise with the bounding box ({ northEast: <LatLng>, southWest: <LatLng> })
599
605
  */
600
606
  getMapBoundaries(): Promise<BoundingBox>;
601
- setIndoorActiveLevelIndex(activeLevelIndex: number): void;
602
607
  /**
603
608
  * Takes a snapshot of the map and saves it to a picture
604
609
  * file or returns the image as a base64 encoded string.
package/lib/MapView.js CHANGED
@@ -31,7 +31,6 @@ const React = __importStar(require("react"));
31
31
  const react_native_1 = require("react-native");
32
32
  const decorateMapComponent_1 = require("./decorateMapComponent");
33
33
  const ProviderConstants = __importStar(require("./ProviderConstants"));
34
- const MapViewNativeComponent_1 = require("./MapViewNativeComponent");
35
34
  const NativeMapViewModule_1 = __importDefault(require("./NativeMapViewModule"));
36
35
  const NativeGoogleMapViewModule_1 = __importDefault(require("./NativeGoogleMapViewModule"));
37
36
  exports.MAP_TYPES = {
@@ -89,11 +88,6 @@ class MapView extends React.Component {
89
88
  }
90
89
  return mapViewModuleMethod('getCamera')(this._getHandle());
91
90
  }
92
- setCamera(camera) {
93
- if (this.map.current) {
94
- MapViewNativeComponent_1.Commands.setCamera(this.map.current, camera);
95
- }
96
- }
97
91
  animateCamera(camera, duration = 500) {
98
92
  if (this._gogleMapsOniOS()) {
99
93
  return googleMapViewModuleMethod('animateCamera')(this._getHandle(), camera, duration);
@@ -138,11 +132,6 @@ class MapView extends React.Component {
138
132
  }
139
133
  return mapViewModuleMethod('getMapBoundaries')(this._getHandle());
140
134
  }
141
- setIndoorActiveLevelIndex(activeLevelIndex) {
142
- if (this.map.current) {
143
- MapViewNativeComponent_1.Commands.setIndoorActiveLevelIndex(this.map.current, activeLevelIndex);
144
- }
145
- }
146
135
  /**
147
136
  * Takes a snapshot of the map and saves it to a picture
148
137
  * file or returns the image as a base64 encoded string.
@@ -1,11 +1,3 @@
1
- /// <reference types="react" />
2
1
  import type { HostComponent } from 'react-native';
3
2
  import { NativeProps } from './MapView';
4
- import { Camera } from './MapView.types';
5
3
  export type MapViewNativeComponentType = HostComponent<NativeProps>;
6
- interface NativeCommands {
7
- setCamera: (viewRef: NonNullable<React.RefObject<MapViewNativeComponentType>['current']>, camera: Partial<Camera>) => void;
8
- setIndoorActiveLevelIndex: (viewRef: NonNullable<React.RefObject<MapViewNativeComponentType>['current']>, activeLevelIndex: number) => void;
9
- }
10
- export declare const Commands: NativeCommands;
11
- export {};
@@ -1,10 +1,2 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Commands = void 0;
7
- const codegenNativeCommands_1 = __importDefault(require("react-native/Libraries/Utilities/codegenNativeCommands"));
8
- exports.Commands = (0, codegenNativeCommands_1.default)({
9
- supportedCommands: ['setCamera', 'setIndoorActiveLevelIndex'],
10
- });
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "main": "lib/index.js",
6
6
  "author": "Leland Richardson <leland.m.richardson@gmail.com>",
7
7
  "homepage": "https://github.com/react-native-maps/react-native-maps#readme",
8
- "version": "2.0.0-beta.10",
8
+ "version": "2.0.0-beta.12",
9
9
  "license": "MIT",
10
10
  "scripts": {
11
11
  "lint": "eslint . --max-warnings 0",