react-native-maps 1.10.0 → 1.10.2

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.
@@ -33,6 +33,7 @@ extern const NSInteger AIRMapMaxZoomLevel;
33
33
  @property (nonatomic, assign) BOOL hasStartedRendering;
34
34
  @property (nonatomic, assign) BOOL cacheEnabled;
35
35
  @property (nonatomic, assign) BOOL loadingEnabled;
36
+ @property (nonatomic, assign) BOOL legacyZoomConstraintsEnabled;
36
37
  @property (nonatomic, strong) UIColor *loadingBackgroundColor;
37
38
  @property (nonatomic, strong) UIColor *loadingIndicatorColor;
38
39
  @property (nonatomic, assign) BOOL hasShownInitialLoading;
@@ -64,6 +65,7 @@ extern const NSInteger AIRMapMaxZoomLevel;
64
65
  @property (nonatomic, copy) RCTDirectEventBlock onMarkerDragStart;
65
66
  @property (nonatomic, copy) RCTDirectEventBlock onMarkerDrag;
66
67
  @property (nonatomic, copy) RCTDirectEventBlock onMarkerDragEnd;
68
+
67
69
  @property (nonatomic, copy) RCTDirectEventBlock onCalloutPress;
68
70
  @property (nonatomic, copy) RCTDirectEventBlock onRegionChange;
69
71
  @property (nonatomic, copy) RCTBubblingEventBlock onUserLocationChange;
@@ -71,6 +73,7 @@ extern const NSInteger AIRMapMaxZoomLevel;
71
73
  - (void)cacheViewIfNeeded;
72
74
  - (void)beginLoading;
73
75
  - (void)finishLoading;
76
+ - (double)getZoomLevel;
74
77
  - (NSArray *)getMapBoundaries;
75
78
 
76
79
  - (AIRMapMarker*) markerAtPoint:(CGPoint)point;
@@ -86,6 +86,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
86
86
  self.minZoomLevel = 0;
87
87
  self.maxZoomLevel = AIRMapMaxZoomLevel;
88
88
  self.compassOffset = CGPointMake(0, 0);
89
+ self.legacyZoomConstraintsEnabled = YES;
89
90
  }
90
91
  return self;
91
92
  }
@@ -466,6 +467,43 @@ const NSInteger AIRMapMaxZoomLevel = 20;
466
467
  self.activityIndicatorView.color = loadingIndicatorColor;
467
468
  }
468
469
 
470
+ - (void)setCameraZoomRange:(NSDictionary *)cameraZoomRange {
471
+ if (!@available(iOS 13.0, *)) {
472
+ return;
473
+ }
474
+
475
+ if (cameraZoomRange == nil) {
476
+ cameraZoomRange = @{};
477
+ }
478
+
479
+ NSNumber *minValue = cameraZoomRange[@"minCenterCoordinateDistance"];
480
+ NSNumber *maxValue = cameraZoomRange[@"maxCenterCoordinateDistance"];
481
+
482
+ if (minValue == nil && maxValue == nil) {
483
+ self.legacyZoomConstraintsEnabled = YES;
484
+
485
+ MKMapCameraZoomRange *defaultZoomRange = [[MKMapCameraZoomRange alloc] initWithMinCenterCoordinateDistance:MKMapCameraZoomDefault maxCenterCoordinateDistance:MKMapCameraZoomDefault];
486
+ [super setCameraZoomRange:defaultZoomRange animated:NO];
487
+
488
+ return;
489
+ }
490
+
491
+ MKMapCameraZoomRange *zoomRange = nil;
492
+
493
+ if (minValue != nil && maxValue != nil) {
494
+ zoomRange = [[MKMapCameraZoomRange alloc] initWithMinCenterCoordinateDistance:[minValue doubleValue] maxCenterCoordinateDistance:[maxValue doubleValue]];
495
+ } else if (minValue != nil) {
496
+ zoomRange = [[MKMapCameraZoomRange alloc] initWithMinCenterCoordinateDistance:[minValue doubleValue]];
497
+ } else if (maxValue != nil) {
498
+ zoomRange = [[MKMapCameraZoomRange alloc] initWithMaxCenterCoordinateDistance:[maxValue doubleValue]];
499
+ }
500
+
501
+ BOOL animated = [cameraZoomRange[@"animated"] boolValue];
502
+
503
+ self.legacyZoomConstraintsEnabled = NO;
504
+ [super setCameraZoomRange:zoomRange animated:animated];
505
+ }
506
+
469
507
  // Include properties of MKMapView which are only available on iOS 9+
470
508
  // and check if their selector is available before calling super method.
471
509
 
@@ -675,4 +713,26 @@ const NSInteger AIRMapMaxZoomLevel = 20;
675
713
  }
676
714
  }
677
715
 
716
+ // based on https://medium.com/@dmytrobabych/getting-actual-rotation-and-zoom-level-for-mapkit-mkmapview-e7f03f430aa9
717
+ - (CGFloat)getZoomLevel {
718
+ CGFloat cameraAngle = self.camera.heading;
719
+
720
+ if (cameraAngle > 270) {
721
+ cameraAngle = 360 - cameraAngle;
722
+ } else if (cameraAngle > 90) {
723
+ cameraAngle = fabs(cameraAngle - 180);
724
+ }
725
+
726
+ CGFloat angleRad = M_PI * cameraAngle / 180; // map rotation in radians
727
+ CGFloat width = self.frame.size.width;
728
+ CGFloat height = self.frame.size.height;
729
+ CGFloat heightOffset = 20; // the offset (status bar height) which is taken by MapKit into consideration to calculate visible area height
730
+
731
+ // calculating Longitude span corresponding to normal (non-rotated) width
732
+ CGFloat spanStraight = width * self.region.span.longitudeDelta / (width * cos(angleRad) + (height - heightOffset) * sin(angleRad));
733
+ int normalizingFactor = 512;
734
+
735
+ return log2(360 * ((width / normalizingFactor) / spanStraight));
736
+ }
737
+
678
738
  @end
@@ -110,6 +110,7 @@ RCT_EXPORT_VIEW_PROPERTY(compassOffset, CGPoint)
110
110
  RCT_EXPORT_VIEW_PROPERTY(legalLabelInsets, UIEdgeInsets)
111
111
  RCT_EXPORT_VIEW_PROPERTY(mapPadding, UIEdgeInsets)
112
112
  RCT_EXPORT_VIEW_PROPERTY(mapType, MKMapType)
113
+ RCT_EXPORT_VIEW_PROPERTY(cameraZoomRange, NSDictionary)
113
114
  RCT_EXPORT_VIEW_PROPERTY(onMapReady, RCTBubblingEventBlock)
114
115
  RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
115
116
  RCT_EXPORT_VIEW_PROPERTY(onPanDrag, RCTBubblingEventBlock)
@@ -941,19 +942,14 @@ static int kDragCenterContext;
941
942
 
942
943
  - (void)mapView:(AIRMap *)mapView regionDidChangeAnimated:(__unused BOOL)animated
943
944
  {
944
- CGFloat zoomLevel = [self zoomLevel:mapView];
945
-
946
945
  // Don't send region did change events until map has
947
946
  // started rendering, as these won't represent the final location
948
947
  if(mapView.hasStartedRendering){
949
948
  [self _regionChanged:mapView];
950
949
  }
951
950
 
952
- if (zoomLevel < mapView.minZoomLevel) {
953
- [self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.minZoomLevel animated:TRUE mapView:mapView];
954
- }
955
- else if (zoomLevel > mapView.maxZoomLevel) {
956
- [self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.maxZoomLevel animated:TRUE mapView:mapView];
951
+ if (mapView.legacyZoomConstraintsEnabled == YES) {
952
+ [self applyLegacyZoomConstrains:mapView];
957
953
  }
958
954
 
959
955
  // Don't send region did change events until map has
@@ -1165,6 +1161,22 @@ static int kDragCenterContext;
1165
1161
  [mapView setRegion:region animated:animated];
1166
1162
  }
1167
1163
 
1164
+ -(void)applyLegacyZoomConstrains:(AIRMap *)mapView {
1165
+ // flyover maps don't use mercator projection so we can't calculate their zoom level.
1166
+ if (mapView.mapType == MKMapTypeHybridFlyover || mapView.mapType == MKMapTypeSatelliteFlyover) {
1167
+ return;
1168
+ }
1169
+
1170
+ CGFloat zoomLevel = [mapView getZoomLevel];
1171
+
1172
+ if (zoomLevel < mapView.minZoomLevel) {
1173
+ [self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.minZoomLevel animated:TRUE mapView:mapView];
1174
+ }
1175
+ else if (zoomLevel > mapView.maxZoomLevel) {
1176
+ [self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.maxZoomLevel animated:TRUE mapView:mapView];
1177
+ }
1178
+ }
1179
+
1168
1180
  //KMapView cannot display tiles that cross the pole (as these would involve wrapping the map from top to bottom, something that a Mercator projection just cannot do).
1169
1181
  -(MKCoordinateRegion)coordinateRegionWithMapView:(AIRMap *)mapView
1170
1182
  centerCoordinate:(CLLocationCoordinate2D)centerCoordinate
@@ -1223,21 +1235,6 @@ static int kDragCenterContext;
1223
1235
  return region;
1224
1236
  }
1225
1237
 
1226
- - (double) zoomLevel:(AIRMap *)mapView {
1227
- MKCoordinateRegion region = mapView.region;
1228
-
1229
- double centerPixelX = [AIRMapManager longitudeToPixelSpaceX: region.center.longitude];
1230
- double topLeftPixelX = [AIRMapManager longitudeToPixelSpaceX: region.center.longitude - region.span.longitudeDelta / 2];
1231
-
1232
- double scaledMapWidth = (centerPixelX - topLeftPixelX) * 2;
1233
- CGSize mapSizeInPixels = mapView.bounds.size;
1234
- double zoomScale = scaledMapWidth / mapSizeInPixels.width;
1235
- double zoomExponent = log(zoomScale) / log(2);
1236
- double zoomLevel = AIRMapMaxZoomLevel - zoomExponent;
1237
-
1238
- return zoomLevel;
1239
- }
1240
-
1241
1238
  #pragma mark MKMapViewDelegate - Tracking the User Location
1242
1239
 
1243
1240
  - (void)mapView:(AIRMap *)mapView didFailToLocateUserWithError:(NSError *)error {
package/lib/MapView.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Animated as RNAnimated, Animated, NativeSyntheticEvent, ViewProps } from 'react-native';
3
3
  import { CalloutPressEvent, ClickEvent, Frame, LatLng, MarkerDeselectEvent, MarkerDragEvent, MarkerDragStartEndEvent, MarkerPressEvent, MarkerSelectEvent, Point, Provider, Region } from './sharedTypes';
4
- import { Address, BoundingBox, Camera, ChangeEvent, Details, EdgePadding, FitToOptions, IndoorBuildingEvent, IndoorLevelActivatedEvent, KmlMapEvent, LongPressEvent, MapPressEvent, MapStyleElement, MapType, MapTypes, PanDragEvent, PoiClickEvent, SnapshotOptions, UserLocationChangeEvent } from './MapView.types';
4
+ import { Address, BoundingBox, Camera, CameraZoomRange, ChangeEvent, Details, EdgePadding, FitToOptions, IndoorBuildingEvent, IndoorLevelActivatedEvent, KmlMapEvent, LongPressEvent, MapPressEvent, MapStyleElement, MapType, MapTypes, PanDragEvent, PoiClickEvent, SnapshotOptions, UserLocationChangeEvent } from './MapView.types';
5
5
  import { Modify } from './sharedTypesInternal';
6
6
  import { MapViewNativeComponentType } from './MapViewNativeComponent';
7
7
  export declare const MAP_TYPES: MapTypes;
@@ -135,8 +135,8 @@ export type MapViewProps = ViewProps & {
135
135
  * The map type to be displayed
136
136
  *
137
137
  * @default `standard`
138
- * @platform iOS: hybrid | mutedStandard | sattelite | standard | terrain
139
- * @platform Android: hybrid | none | sattelite | standard | terrain
138
+ * @platform iOS: hybrid | mutedStandard | satellite | standard | terrain | hybridFlyover | satelliteFlyover
139
+ * @platform Android: hybrid | none | satellite | standard | terrain
140
140
  */
141
141
  mapType?: MapType;
142
142
  /**
@@ -152,6 +152,7 @@ export type MapViewProps = ViewProps & {
152
152
  * @default 20
153
153
  * @platform iOS: Supported
154
154
  * @platform Android: Supported
155
+ * @deprecated on Apple Maps, use `cameraZoomRange` instead
155
156
  */
156
157
  maxZoomLevel?: number;
157
158
  /**
@@ -167,6 +168,7 @@ export type MapViewProps = ViewProps & {
167
168
  * @default 0
168
169
  * @platform iOS: Supported
169
170
  * @platform Android: Supported
171
+ * @deprecated on Apple Maps, use `cameraZoomRange` instead
170
172
  */
171
173
  minZoomLevel?: number;
172
174
  /**
@@ -560,6 +562,15 @@ export type MapViewProps = ViewProps & {
560
562
  * @platform Android: Not supported
561
563
  */
562
564
  zoomTapEnabled?: boolean;
565
+ /**
566
+ * Map camera distance limits. `minCenterCoordinateDistance` for minimum distance, `maxCenterCoordinateDistance` for maximum.
567
+ * `animated` for animated zoom changes.
568
+ * Takes precedence if conflicting with `minZoomLevel`, `maxZoomLevel`.
569
+ *
570
+ * @platform iOS: 13.0+
571
+ * @platform Android: Not supported
572
+ */
573
+ cameraZoomRange?: CameraZoomRange;
563
574
  };
564
575
  type ModifiedProps = Modify<MapViewProps, {
565
576
  region?: MapViewProps['region'] | null;
package/lib/MapView.js CHANGED
@@ -36,6 +36,8 @@ exports.MAP_TYPES = {
36
36
  TERRAIN: 'terrain',
37
37
  NONE: 'none',
38
38
  MUTEDSTANDARD: 'mutedStandard',
39
+ SATELLITE_FLYOVER: 'satelliteFlyover',
40
+ HYBRID_FLYOVER: 'hybridFlyover',
39
41
  };
40
42
  const GOOGLE_MAPS_ONLY_TYPES = [exports.MAP_TYPES.TERRAIN, exports.MAP_TYPES.NONE];
41
43
  class MapView extends React.Component {
@@ -19,12 +19,12 @@ export type MapStyleElement = {
19
19
  stylers: object[];
20
20
  };
21
21
  export type EdgePadding = {
22
- top: Number;
23
- right: Number;
24
- bottom: Number;
25
- left: Number;
22
+ top: number;
23
+ right: number;
24
+ bottom: number;
25
+ left: number;
26
26
  };
27
- export type MapType = 'hybrid' | 'mutedStandard' | 'none' | 'satellite' | 'standard' | 'terrain';
27
+ export type MapType = 'hybrid' | 'mutedStandard' | 'none' | 'satellite' | 'standard' | 'terrain' | 'satelliteFlyover' | 'hybridFlyover';
28
28
  export type MapTypes = {
29
29
  STANDARD: 'standard';
30
30
  SATELLITE: 'satellite';
@@ -32,6 +32,8 @@ export type MapTypes = {
32
32
  TERRAIN: 'terrain';
33
33
  NONE: 'none';
34
34
  MUTEDSTANDARD: 'mutedStandard';
35
+ SATELLITE_FLYOVER: 'satelliteFlyover';
36
+ HYBRID_FLYOVER: 'hybridFlyover';
35
37
  };
36
38
  export type IndoorLevel = {
37
39
  index: number;
@@ -151,4 +153,9 @@ export type Address = {
151
153
  thoroughfare: string;
152
154
  subThoroughfare?: string;
153
155
  };
156
+ export type CameraZoomRange = {
157
+ minCenterCoordinateDistance?: number;
158
+ maxCenterCoordinateDistance?: number;
159
+ animated?: boolean;
160
+ };
154
161
  export type NativeCommandName = 'animateCamera' | 'animateToRegion' | 'coordinateForPoint' | 'fitToCoordinates' | 'fitToElements' | 'fitToSuppliedMarkers' | 'getAddressFromCoordinates' | 'getCamera' | 'getMapBoundaries' | 'getMarkersFrames' | 'pointForCoordinate' | 'setCamera' | 'setIndoorActiveLevelIndex' | 'setMapBoundaries' | 'takeSnapshot';
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": "1.10.0",
8
+ "version": "1.10.2",
9
9
  "license": "MIT",
10
10
  "scripts": {
11
11
  "lint": "eslint . --max-warnings 0",