react-native-maps 1.21.0-alpha.9 → 1.21.0-alpha.91

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.
Files changed (179) hide show
  1. package/android/build.gradle +45 -14
  2. package/android/generated/RCTAppDependencyProvider.h +25 -0
  3. package/android/generated/RCTAppDependencyProvider.mm +55 -0
  4. package/android/generated/RCTModulesConformingToProtocolsProvider.h +18 -0
  5. package/android/generated/RCTModulesConformingToProtocolsProvider.mm +33 -0
  6. package/android/generated/RCTThirdPartyComponentsProvider.h +16 -0
  7. package/android/generated/RCTThirdPartyComponentsProvider.mm +26 -0
  8. package/android/generated/ReactAppDependencyProvider.podspec +34 -0
  9. package/android/generated/java/com/facebook/fbreact/specs/NativeAirMapsModuleSpec.java +63 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsCalloutManagerDelegate.java +35 -0
  11. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsCalloutManagerInterface.java +18 -0
  12. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsCircleManagerDelegate.java +49 -0
  13. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsCircleManagerInterface.java +24 -0
  14. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsGooglePolygonManagerDelegate.java +49 -0
  15. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsGooglePolygonManagerInterface.java +24 -0
  16. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsMapViewManagerDelegate.java +206 -0
  17. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsMapViewManagerInterface.java +74 -0
  18. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsMarkerManagerDelegate.java +104 -0
  19. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsMarkerManagerInterface.java +40 -0
  20. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsOverlayManagerDelegate.java +46 -0
  21. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsOverlayManagerInterface.java +24 -0
  22. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsPolylineManagerDelegate.java +58 -0
  23. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsPolylineManagerInterface.java +27 -0
  24. package/android/generated/jni/CMakeLists.txt +36 -0
  25. package/android/generated/jni/RNMapsSpecs-generated.cpp +68 -0
  26. package/android/generated/jni/RNMapsSpecs.h +31 -0
  27. package/android/generated/jni/react/renderer/components/RNMapsSpecs/ComponentDescriptors.cpp +29 -0
  28. package/android/generated/jni/react/renderer/components/RNMapsSpecs/ComponentDescriptors.h +31 -0
  29. package/android/generated/jni/react/renderer/components/RNMapsSpecs/EventEmitters.cpp +984 -0
  30. package/android/generated/jni/react/renderer/components/RNMapsSpecs/EventEmitters.h +853 -0
  31. package/android/generated/jni/react/renderer/components/RNMapsSpecs/Props.cpp +193 -0
  32. package/android/generated/jni/react/renderer/components/RNMapsSpecs/Props.h +1223 -0
  33. package/android/generated/jni/react/renderer/components/RNMapsSpecs/RNMapsSpecsJSI-generated.cpp +74 -0
  34. package/android/generated/jni/react/renderer/components/RNMapsSpecs/RNMapsSpecsJSI.h +268 -0
  35. package/android/generated/jni/react/renderer/components/RNMapsSpecs/ShadowNodes.cpp +24 -0
  36. package/android/generated/jni/react/renderer/components/RNMapsSpecs/ShadowNodes.h +109 -0
  37. package/android/generated/jni/react/renderer/components/RNMapsSpecs/States.cpp +16 -0
  38. package/android/generated/jni/react/renderer/components/RNMapsSpecs/States.h +113 -0
  39. package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  40. package/android/gradlew +1 -2
  41. package/android/src/main/java/com/rnmaps/fabric/CalloutManager.java +77 -0
  42. package/android/src/main/java/com/rnmaps/fabric/CircleManager.java +94 -0
  43. package/android/src/main/java/com/rnmaps/fabric/JSONUtil.java +86 -0
  44. package/android/src/main/java/com/rnmaps/fabric/MapViewManager.java +619 -0
  45. package/android/src/main/java/com/rnmaps/fabric/MarkerManager.java +258 -0
  46. package/android/src/main/java/com/rnmaps/fabric/NativeAirMapsModule.java +235 -2
  47. package/android/src/main/java/com/rnmaps/fabric/OverlayManager.java +95 -0
  48. package/android/src/main/java/com/rnmaps/fabric/PolygonManager.java +89 -0
  49. package/android/src/main/java/com/rnmaps/fabric/PolylineManager.java +121 -0
  50. package/android/src/main/java/com/rnmaps/fabric/event/OnCalloutPressEvent.java +25 -0
  51. package/android/src/main/java/com/rnmaps/fabric/event/OnDeselectEvent.java +28 -0
  52. package/android/src/main/java/com/rnmaps/fabric/event/OnDoublePressEvent.java +27 -0
  53. package/android/src/main/java/com/rnmaps/fabric/event/OnDragEndEvent.java +28 -0
  54. package/android/src/main/java/com/rnmaps/fabric/event/OnDragEvent.java +28 -0
  55. package/android/src/main/java/com/rnmaps/fabric/event/OnDragStartEvent.java +28 -0
  56. package/android/src/main/java/com/rnmaps/fabric/event/OnIndoorBuildingFocusedEvent.java +28 -0
  57. package/android/src/main/java/com/rnmaps/fabric/event/OnIndoorLevelActivatedEvent.java +28 -0
  58. package/android/src/main/java/com/rnmaps/fabric/event/OnKmlReadyEvent.java +28 -0
  59. package/android/src/main/java/com/rnmaps/fabric/event/OnLongPressEvent.java +28 -0
  60. package/android/src/main/java/com/rnmaps/fabric/event/OnMapLoadedEvent.java +29 -0
  61. package/android/src/main/java/com/rnmaps/fabric/event/OnMapReadyEvent.java +29 -0
  62. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDeselectEvent.java +28 -0
  63. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDragEndEvent.java +28 -0
  64. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDragEvent.java +28 -0
  65. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDragStartEvent.java +28 -0
  66. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerPressEvent.java +28 -0
  67. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerSelectEvent.java +28 -0
  68. package/android/src/main/java/com/rnmaps/fabric/event/OnPanDragEvent.java +28 -0
  69. package/android/src/main/java/com/rnmaps/fabric/event/OnPoiClickEvent.java +27 -0
  70. package/android/src/main/java/com/rnmaps/fabric/event/OnPressEvent.java +27 -0
  71. package/android/src/main/java/com/rnmaps/fabric/event/OnRegionChangeCompleteEvent.java +30 -0
  72. package/android/src/main/java/com/rnmaps/fabric/event/OnRegionChangeEvent.java +48 -0
  73. package/android/src/main/java/com/rnmaps/fabric/event/OnRegionChangeStartEvent.java +33 -0
  74. package/android/src/main/java/com/rnmaps/fabric/event/OnSelectEvent.java +28 -0
  75. package/android/src/main/java/com/rnmaps/fabric/event/OnUserLocationChangeEvent.java +28 -0
  76. package/android/src/main/java/com/rnmaps/maps/MapAirModulePackage.java +38 -2
  77. package/android/src/main/java/com/rnmaps/maps/MapCallout.java +18 -0
  78. package/android/src/main/java/com/rnmaps/maps/MapCircle.java +24 -0
  79. package/android/src/main/java/com/rnmaps/maps/MapManager.java +14 -14
  80. package/android/src/main/java/com/rnmaps/maps/MapMarker.java +79 -3
  81. package/android/src/main/java/com/rnmaps/maps/MapModule.java +206 -206
  82. package/android/src/main/java/com/rnmaps/maps/MapOverlay.java +267 -151
  83. package/android/src/main/java/com/rnmaps/maps/MapPolygon.java +31 -1
  84. package/android/src/main/java/com/rnmaps/maps/MapPolyline.java +207 -141
  85. package/android/src/main/java/com/rnmaps/maps/MapPolylineManager.java +1 -16
  86. package/android/src/main/java/com/rnmaps/maps/MapView.java +1653 -1337
  87. package/ios/AirGoogleMaps/AIRGoogleMap.h +1 -0
  88. package/ios/AirGoogleMaps/AIRGoogleMap.m +106 -58
  89. package/ios/AirGoogleMaps/AIRGoogleMapCircle.m +23 -11
  90. package/ios/AirGoogleMaps/AIRGoogleMapManager.m +3 -1
  91. package/ios/AirGoogleMaps/AIRGoogleMapMarker.h +2 -0
  92. package/ios/AirGoogleMaps/AIRGoogleMapMarker.m +347 -243
  93. package/ios/AirGoogleMaps/AIRGoogleMapPolygon.h +2 -1
  94. package/ios/AirGoogleMaps/AIRGoogleMapPolygon.m +30 -0
  95. package/ios/AirGoogleMaps/AIRGoogleMapPolyline.h +0 -1
  96. package/ios/AirGoogleMaps/AIRGoogleMapPolyline.m +0 -7
  97. package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.h +1 -1
  98. package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.m +2 -2
  99. package/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m +2 -0
  100. package/ios/AirGoogleMaps/RNMapsGoogleMapView.mm +197 -61
  101. package/ios/AirGoogleMaps/RNMapsGooglePolygonView.h +26 -0
  102. package/ios/AirGoogleMaps/RNMapsGooglePolygonView.mm +215 -0
  103. package/ios/AirGoogleMaps/RNMapsGooglePolygonViewManager.mm +25 -0
  104. package/ios/AirMaps/AIRMap.h +2 -1
  105. package/ios/AirMaps/AIRMap.m +227 -236
  106. package/ios/AirMaps/AIRMapManager.m +6 -0
  107. package/ios/AirMaps/AIRMapMarker.h +1 -0
  108. package/ios/AirMaps/AIRMapMarker.m +165 -103
  109. package/ios/AirMaps/Callout/SMCalloutView.m +1 -1
  110. package/ios/AirMaps/RNMapsAirModule.h +1 -1
  111. package/ios/AirMaps/RNMapsAirModule.mm +4 -3
  112. package/ios/AirMaps/RNMapsAirModuleDelegate.h +24 -0
  113. package/ios/AirMaps/RNMapsHostVewDelegate.h +17 -0
  114. package/ios/AirMaps/RNMapsMapView.mm +336 -307
  115. package/ios/AirMaps/RNMapsMarkerView.h +24 -0
  116. package/ios/AirMaps/RNMapsMarkerView.mm +427 -0
  117. package/ios/AirMaps/RNMapsMarkerViewManager.mm +21 -0
  118. package/ios/AirMaps/UIView +AirMap.m +20 -0
  119. package/ios/AirMaps/UIView+AirMap.h +11 -0
  120. package/ios/AirMaps.xcodeproj/project.pbxproj +60 -0
  121. package/ios/generated/RCTAppDependencyProvider.h +25 -0
  122. package/ios/generated/RCTAppDependencyProvider.mm +55 -0
  123. package/ios/generated/RCTModulesConformingToProtocolsProvider.h +18 -0
  124. package/ios/generated/RCTModulesConformingToProtocolsProvider.mm +33 -0
  125. package/ios/generated/RCTThirdPartyComponentsProvider.h +16 -0
  126. package/ios/generated/RCTThirdPartyComponentsProvider.mm +26 -0
  127. package/ios/generated/RNMapsSpecs/ComponentDescriptors.cpp +29 -0
  128. package/ios/generated/RNMapsSpecs/ComponentDescriptors.h +31 -0
  129. package/ios/generated/RNMapsSpecs/EventEmitters.cpp +984 -0
  130. package/ios/generated/RNMapsSpecs/EventEmitters.h +853 -0
  131. package/ios/generated/RNMapsSpecs/Props.cpp +193 -0
  132. package/ios/generated/RNMapsSpecs/Props.h +1223 -0
  133. package/ios/generated/RNMapsSpecs/RCTComponentViewHelpers.h +603 -0
  134. package/ios/generated/RNMapsSpecs/RNMapsSpecs-generated.mm +92 -0
  135. package/ios/generated/RNMapsSpecs/RNMapsSpecs.h +137 -0
  136. package/ios/generated/RNMapsSpecs/ShadowNodes.cpp +24 -0
  137. package/ios/generated/RNMapsSpecs/ShadowNodes.h +109 -0
  138. package/ios/generated/RNMapsSpecs/States.cpp +16 -0
  139. package/ios/generated/RNMapsSpecs/States.h +113 -0
  140. package/ios/generated/RNMapsSpecsJSI-generated.cpp +74 -0
  141. package/ios/generated/RNMapsSpecsJSI.h +268 -0
  142. package/ios/generated/ReactAppDependencyProvider.podspec +34 -0
  143. package/ios/generated/module.modulemap +4 -0
  144. package/ios/generated/react-native-maps-generated-umbrella.h +14 -0
  145. package/lib/MapCircle.d.ts +1 -1
  146. package/lib/MapHeatmap.d.ts +2 -2
  147. package/lib/MapHeatmap.js +1 -1
  148. package/lib/MapMarker.d.ts +16 -3
  149. package/lib/MapMarker.js +58 -9
  150. package/lib/MapMarkerNativeComponent.js +0 -2
  151. package/lib/MapOverlay.d.ts +1 -0
  152. package/lib/MapOverlay.js +21 -9
  153. package/lib/MapPolygon.d.ts +1 -1
  154. package/lib/MapPolyline.d.ts +7 -7
  155. package/lib/MapView.d.ts +15 -27
  156. package/lib/MapView.js +109 -124
  157. package/lib/MapView.types.d.ts +1 -1
  158. package/lib/createFabricMap.d.ts +1 -0
  159. package/lib/createFabricMap.js +17 -4
  160. package/lib/decorateMapComponent.js +40 -0
  161. package/lib/specs/NativeAirMapsModule.d.ts +2 -2
  162. package/lib/specs/NativeComponentCallout.d.ts +46 -0
  163. package/lib/specs/NativeComponentCallout.js +9 -0
  164. package/lib/specs/NativeComponentCircle.d.ts +74 -0
  165. package/lib/specs/NativeComponentCircle.js +7 -0
  166. package/lib/specs/NativeComponentGoogleMapView.d.ts +15 -15
  167. package/lib/specs/NativeComponentGoogleMapView.js +1 -0
  168. package/lib/specs/NativeComponentGooglePolygon.d.ts +75 -0
  169. package/lib/specs/NativeComponentGooglePolygon.js +7 -0
  170. package/lib/specs/NativeComponentMapView.d.ts +28 -36
  171. package/lib/specs/NativeComponentMapView.js +2 -3
  172. package/lib/specs/NativeComponentMarker.d.ts +258 -0
  173. package/lib/specs/NativeComponentMarker.js +19 -0
  174. package/lib/specs/NativeComponentOverlay.d.ts +67 -0
  175. package/lib/specs/NativeComponentOverlay.js +7 -0
  176. package/lib/specs/NativeComponentPolyline.d.ts +101 -0
  177. package/lib/specs/NativeComponentPolyline.js +7 -0
  178. package/package.json +27 -21
  179. package/react-native-maps.podspec +61 -16
@@ -39,8 +39,6 @@ const NSInteger AIRMapMaxZoomLevel = 20;
39
39
  @property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView;
40
40
  @property (nonatomic, assign) NSNumber *shouldZoomEnabled;
41
41
  @property (nonatomic, assign) NSNumber *shouldScrollEnabled;
42
- @property (nonatomic, strong) MKCompassButton *defaultCompassButton;
43
- @property (nonatomic, strong) MKCompassButton *overlayCompassButton;
44
42
 
45
43
  - (void)updateScrollEnabled;
46
44
  - (void)updateZoomEnabled;
@@ -51,8 +49,12 @@ const NSInteger AIRMapMaxZoomLevel = 20;
51
49
  {
52
50
  UIView *_legalLabel;
53
51
  BOOL _initialRegionSet;
52
+ BOOL _initialRegionProvided;
53
+ BOOL _initialCameraProvided;
54
54
  BOOL _initialCameraSet;
55
-
55
+ BOOL _initialized;
56
+ BOOL _loadingStarted;
57
+
56
58
  // Array to manually track RN subviews
57
59
  //
58
60
  // AIRMap implicitly creates subviews that aren't regular RN children
@@ -70,7 +72,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
70
72
  if ((self = [super init])) {
71
73
  _hasStartedRendering = NO;
72
74
  _reactSubviews = [NSMutableArray new];
73
-
75
+
74
76
  // Find Apple link label
75
77
  for (UIView *subview in self.subviews) {
76
78
  if ([NSStringFromClass(subview.class) isEqualToString:@"MKAttributionLabel"]) {
@@ -80,16 +82,18 @@ const NSInteger AIRMapMaxZoomLevel = 20;
80
82
  break;
81
83
  }
82
84
  }
83
-
85
+
84
86
  // 3rd-party callout view for MapKit that has more options than the built-in. It's painstakingly built to
85
87
  // be identical to the built-in callout view (which has a private API)
86
88
  self.calloutView = [SMCalloutView platformCalloutView];
87
89
  self.calloutView.delegate = self;
88
-
90
+
89
91
  self.minZoom = 0;
90
92
  self.maxZoom = AIRMapMaxZoomLevel;
91
93
  self.compassOffset = CGPointMake(0, 0);
92
94
  self.legacyZoomConstraintsEnabled = YES;
95
+ _initialized = YES;
96
+ [self listenToMemoryWarnings];
93
97
  }
94
98
  return self;
95
99
  }
@@ -202,17 +206,19 @@ const NSInteger AIRMapMaxZoomLevel = 20;
202
206
  }
203
207
  // Create Polyline with coordinates
204
208
  -(void) fitToCoordinates:(NSArray<AIRMapCoordinate*>*) coordinates edgePadding:(UIEdgeInsets) edgeInsets animated:(Boolean) animated {
205
- CLLocationCoordinate2D coords[coordinates.count];
206
- for(int i = 0; i < coordinates.count; i++)
207
- {
208
- coords[i] = coordinates[i].coordinate;
209
- }
210
- MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordinates.count];
209
+ CLLocationCoordinate2D coords[coordinates.count];
210
+ for(int i = 0; i < coordinates.count; i++)
211
+ {
212
+ coords[i] = coordinates[i].coordinate;
213
+ }
214
+ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordinates.count];
211
215
 
212
- // Set Map viewport
216
+ // Set Map viewport
213
217
 
214
- [self setVisibleMapRect:[polyline boundingMapRect] edgePadding:edgeInsets animated:animated];
218
+ [self setVisibleMapRect:[polyline boundingMapRect] edgePadding:edgeInsets animated:animated];
215
219
  }
220
+
221
+
216
222
  - (CGRect) frameForMarker:(AIRMapMarker*) mrkAnn {
217
223
  MKAnnotationView* mrkView = [self viewForAnnotation: mrkAnn];
218
224
  CGRect mrkFrame = mrkView.frame;
@@ -247,16 +253,16 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
247
253
  // Allow touches to be sent to our calloutview.
248
254
  // See this for some discussion of why we need to override this: https://github.com/nfarina/calloutview/pull/9
249
255
  - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
250
-
256
+
251
257
  CGPoint touchPoint = [self.calloutView convertPoint:point fromView:self];
252
258
  UIView *touchedView = [self.calloutView hitTest:touchPoint withEvent:event];
253
-
259
+
254
260
  if (touchedView) {
255
261
  UIWindow* win = [[[UIApplication sharedApplication] windows] firstObject];
256
262
  AIRMapCalloutSubview* calloutSubview = nil;
257
263
  AIRMapCallout* callout = nil;
258
264
  AIRMapMarker* marker = nil;
259
-
265
+
260
266
  UIView* tmp = touchedView;
261
267
  while (tmp && tmp != win && tmp != self.calloutView) {
262
268
  if ([tmp respondsToSelector:@selector(onPress)]) {
@@ -268,7 +274,7 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
268
274
  }
269
275
  tmp = tmp.superview;
270
276
  }
271
-
277
+
272
278
  if (callout) {
273
279
  marker = [self markerForCallout:callout];
274
280
  if (marker) {
@@ -278,36 +284,36 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
278
284
  }
279
285
  }
280
286
  }
281
-
287
+
282
288
  return calloutSubview ? calloutSubview : touchedView;
283
289
  }
284
-
290
+
285
291
  return [super hitTest:point withEvent:event];
286
292
  }
287
293
 
288
294
  #pragma mark SMCalloutViewDelegate
289
295
 
290
296
  - (NSTimeInterval)calloutView:(SMCalloutView *)calloutView delayForRepositionWithSize:(CGSize)offset {
291
-
297
+
292
298
  // When the callout is being asked to present in a way where it or its target will be partially offscreen, it asks us
293
299
  // if we'd like to reposition our surface first so the callout is completely visible. Here we scroll the map into view,
294
300
  // but it takes some math because we have to deal in lon/lat instead of the given offset in pixels.
295
-
301
+
296
302
  CLLocationCoordinate2D coordinate = self.region.center;
297
-
303
+
298
304
  // where's the center coordinate in terms of our view?
299
305
  CGPoint center = [self convertCoordinate:coordinate toPointToView:self];
300
-
306
+
301
307
  // move it by the requested offset
302
308
  center.x -= offset.width;
303
309
  center.y -= offset.height;
304
-
310
+
305
311
  // and translate it back into map coordinates
306
312
  coordinate = [self convertPoint:center toCoordinateFromView:self];
307
-
313
+
308
314
  // move the map!
309
315
  [self setCenterCoordinate:coordinate animated:YES];
310
-
316
+
311
317
  // tell the callout to wait for a while while we scroll (we assume the scroll delay for MKMapView matches UIScrollView)
312
318
  return kSMCalloutViewRepositionDelayForUIScrollView;
313
319
  }
@@ -317,10 +323,10 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
317
323
  - (NSArray *)getMapBoundaries
318
324
  {
319
325
  MKMapRect mapRect = self.visibleMapRect;
320
-
326
+
321
327
  CLLocationCoordinate2D northEast = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMaxX(mapRect), mapRect.origin.y));
322
328
  CLLocationCoordinate2D southWest = MKCoordinateForMapPoint(MKMapPointMake(mapRect.origin.x, MKMapRectGetMaxY(mapRect)));
323
-
329
+
324
330
  return @[
325
331
  @[
326
332
  [NSNumber numberWithDouble:northEast.longitude],
@@ -335,20 +341,20 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
335
341
  - (NSDictionary *) getPointForCoordinates:(CLLocationCoordinate2D) location
336
342
  {
337
343
  CGPoint touchPoint = [self convertCoordinate:location toPointToView:self];
338
-
344
+
339
345
  return @{
340
- @"x": @(touchPoint.x),
341
- @"y": @(touchPoint.y),
346
+ @"x": @(touchPoint.x),
347
+ @"y": @(touchPoint.y),
342
348
  };
343
349
  }
344
350
  - (NSDictionary *) getCoordinatesForPoint:(CGPoint)point
345
351
  {
346
352
  CLLocationCoordinate2D coordinate = [self convertPoint:point toCoordinateFromView:self];
347
353
  return @{
348
- @"latitude": @(coordinate.latitude),
349
- @"longitude": @(coordinate.longitude),
354
+ @"latitude": @(coordinate.latitude),
355
+ @"longitude": @(coordinate.longitude),
350
356
  };
351
-
357
+
352
358
  }
353
359
 
354
360
  - (NSDictionary*) getMarkersFramesWithOnlyVisible:(BOOL)onlyVisible {
@@ -375,123 +381,128 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
375
381
  return markersFrames;
376
382
  }
377
383
 
378
- - (NSDictionary *) getCamera {
384
+ - (NSDictionary *) getCameraDic {
379
385
  MKMapCamera *camera = [self camera];
380
386
  return @{
381
- @"center": @{
382
- @"latitude": @(camera.centerCoordinate.latitude),
383
- @"longitude": @(camera.centerCoordinate.longitude),
384
- },
385
- @"pitch": @(camera.pitch),
386
- @"heading": @(camera.heading),
387
- @"altitude": @(camera.altitude),
387
+ @"center": @{
388
+ @"latitude": @(camera.centerCoordinate.latitude),
389
+ @"longitude": @(camera.centerCoordinate.longitude),
390
+ },
391
+ @"pitch": @(camera.pitch),
392
+ @"heading": @(camera.heading),
393
+ @"altitude": @(camera.altitude),
388
394
  };
389
395
  }
390
396
  - (void)takeSnapshotWithConfig:(NSDictionary *)config
391
- callback:(RCTPromiseResolveBlock) callback
397
+ success:(RCTPromiseResolveBlock)success error:(RCTPromiseRejectBlock)error
392
398
  {
393
-
394
- MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
395
-
396
- options.mapType = self.mapType;
397
- NSNumber *width = config[@"width"];
398
- NSNumber *height = config[@"height"];
399
- NSNumber *quality = config[@"quality"];
400
- NSString*format =config[@"format"];
401
- NSString*result =config[@"result"];
402
- MKCoordinateRegion region = [RCTConvert MKCoordinateRegion:config[@"region"]];
403
-
404
-
405
- options.region = (region.center.latitude && region.center.longitude) ? region : self.region;
406
- options.size = CGSizeMake(
407
- ([width floatValue] == 0) ? self.bounds.size.width : [width floatValue],
408
- ([height floatValue] == 0) ? self.bounds.size.height : [height floatValue]
409
- );
410
-
411
- options.scale = [[UIScreen mainScreen] scale];
412
-
413
-
414
- MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
415
-
416
- [self takeMapSnapshot:snapshotter
417
- format:format
418
- quality:[quality floatValue]
419
- result:result
420
- callback:callback];
399
+
400
+ MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
401
+
402
+ options.mapType = self.mapType;
403
+ NSNumber *width = config[@"width"];
404
+ NSNumber *height = config[@"height"];
405
+ NSNumber *quality = config[@"quality"];
406
+ NSString*format =config[@"format"];
407
+ NSString*result =config[@"result"];
408
+ if (config[@"region"]){
409
+ MKCoordinateRegion region = [RCTConvert MKCoordinateRegion:config[@"region"]];
410
+ options.region = region;
411
+ } else
412
+ {
413
+ options.region = self.region;
414
+ }
415
+ options.size = CGSizeMake(
416
+ ([width floatValue] == 0) ? self.bounds.size.width : [width floatValue],
417
+ ([height floatValue] == 0) ? self.bounds.size.height : [height floatValue]
418
+ );
419
+
420
+ options.scale = [[UIScreen mainScreen] scale];
421
+
422
+
423
+ MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
424
+
425
+ [self takeMapSnapshot:snapshotter
426
+ format:format
427
+ quality:[quality floatValue]
428
+ result:result
429
+ success:success error:error];
421
430
  }
422
431
 
423
432
  #pragma mark Take Snapshot
424
433
  - (void)takeMapSnapshot:(MKMapSnapshotter *) snapshotter
425
- format:(NSString *)format
426
- quality:(CGFloat) quality
427
- result:(NSString *)result
428
- callback:(RCTPromiseResolveBlock) callback {
434
+ format:(NSString *)format
435
+ quality:(CGFloat) quality
436
+ result:(NSString *)result
437
+ success:(RCTPromiseResolveBlock) success
438
+ error:(RCTPromiseRejectBlock) errorCallback {
429
439
  NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
430
440
  NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.%@", timeStamp, format];
431
441
  NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent];
432
442
 
433
443
  [snapshotter startWithQueue:dispatch_get_main_queue()
434
444
  completionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
435
- if (error) {
436
- callback(@[error]);
437
- return;
438
- }
439
- MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:nil];
440
-
441
- UIImage *image = snapshot.image;
442
- UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
443
- {
444
- [image drawAtPoint:CGPointMake(0.0f, 0.0f)];
445
-
446
- CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
447
-
448
- for (id <AIRMapSnapshot> overlay in self.overlays) {
449
- if ([overlay respondsToSelector:@selector(drawToSnapshot:context:)]) {
450
- [overlay drawToSnapshot:snapshot context:UIGraphicsGetCurrentContext()];
451
- }
452
- }
453
-
454
- for (id <MKAnnotation> annotation in self.annotations) {
455
- CGPoint point = [snapshot pointForCoordinate:annotation.coordinate];
456
-
457
- MKAnnotationView* anView = [self viewForAnnotation: annotation];
458
-
459
- if (anView){
460
- pin = anView;
461
- }
462
-
463
- if (CGRectContainsPoint(rect, point)) {
464
- point.x = point.x + pin.centerOffset.x - (pin.bounds.size.width / 2.0f);
465
- point.y = point.y + pin.centerOffset.y - (pin.bounds.size.height / 2.0f);
466
- if (pin.image) {
467
- [pin.image drawAtPoint:point];
468
- } else {
469
- CGRect pinRect = CGRectMake(point.x, point.y, pin.bounds.size.width, pin.bounds.size.height);
470
- [pin drawViewHierarchyInRect:pinRect afterScreenUpdates:NO];
471
- }
472
- }
473
- }
474
-
475
- UIImage *compositeImage = UIGraphicsGetImageFromCurrentImageContext();
476
-
477
- NSData *data;
478
- if ([format isEqualToString:@"png"]) {
479
- data = UIImagePNGRepresentation(compositeImage);
480
- }
481
- else if([format isEqualToString:@"jpg"]) {
482
- data = UIImageJPEGRepresentation(compositeImage, quality);
483
- }
484
-
485
- if ([result isEqualToString:@"file"]) {
486
- [data writeToFile:filePath atomically:YES];
487
- callback(filePath);
488
- }
489
- else if ([result isEqualToString:@"base64"]) {
490
- callback([data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]);
491
- }
492
- }
493
- UIGraphicsEndImageContext();
494
- }];
445
+ if (error) {
446
+ errorCallback(@"snapshotterError", @"failed", error);
447
+ return;
448
+ }
449
+ MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:nil];
450
+
451
+ UIImage *image = snapshot.image;
452
+ UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
453
+ {
454
+ [image drawAtPoint:CGPointMake(0.0f, 0.0f)];
455
+
456
+ CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
457
+
458
+ for (id <AIRMapSnapshot> overlay in self.overlays) {
459
+ if ([overlay respondsToSelector:@selector(drawToSnapshot:context:)]) {
460
+ [overlay drawToSnapshot:snapshot context:UIGraphicsGetCurrentContext()];
461
+ }
462
+ }
463
+
464
+
465
+ for (id <MKAnnotation> annotation in self.annotations) {
466
+ CGPoint point = [snapshot pointForCoordinate:annotation.coordinate];
467
+
468
+ MKAnnotationView* anView = [self viewForAnnotation: annotation];
469
+
470
+ if (anView){
471
+ pin = anView;
472
+ }
473
+
474
+ if (CGRectContainsPoint(rect, point)) {
475
+ point.x = point.x + pin.centerOffset.x - (pin.bounds.size.width / 2.0f);
476
+ point.y = point.y + pin.centerOffset.y - (pin.bounds.size.height / 2.0f);
477
+ if (pin.image) {
478
+ [pin.image drawAtPoint:point];
479
+ } else {
480
+ CGRect pinRect = CGRectMake(point.x, point.y, pin.bounds.size.width, pin.bounds.size.height);
481
+ [pin drawViewHierarchyInRect:pinRect afterScreenUpdates:NO];
482
+ }
483
+ }
484
+ }
485
+
486
+ UIImage *compositeImage = UIGraphicsGetImageFromCurrentImageContext();
487
+
488
+ NSData *data;
489
+ if ([format isEqualToString:@"png"]) {
490
+ data = UIImagePNGRepresentation(compositeImage);
491
+ }
492
+ else if([format isEqualToString:@"jpg"]) {
493
+ data = UIImageJPEGRepresentation(compositeImage, quality);
494
+ }
495
+
496
+ if ([result isEqualToString:@"file"]) {
497
+ [data writeToFile:filePath atomically:YES];
498
+ success(filePath);
499
+ }
500
+ else if ([result isEqualToString:@"base64"]) {
501
+ success([data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]);
502
+ }
503
+ }
504
+ UIGraphicsEndImageContext();
505
+ }];
495
506
  }
496
507
 
497
508
 
@@ -505,7 +516,6 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
505
516
 
506
517
  - (void)setUserInterfaceStyle:(NSString*)userInterfaceStyle
507
518
  {
508
- if (@available(iOS 13.0, *)) {
509
519
  if([userInterfaceStyle isEqualToString:@"light"]) {
510
520
  self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
511
521
  } else if([userInterfaceStyle isEqualToString:@"dark"]) {
@@ -513,9 +523,6 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
513
523
  } else {
514
524
  self.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
515
525
  }
516
- } else {
517
- NSLog(@"UserInterfaceStyle not supported below iOS 13");
518
- }
519
526
  }
520
527
 
521
528
  - (void)setTintColor:(UIColor *)tintColor
@@ -533,13 +540,14 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
533
540
  _userLocationCalloutEnabled = calloutEnabled;
534
541
  }
535
542
 
536
- - (void)setHandlePanDrag:(BOOL)handleMapDrag {
543
+ - (void)setHandlePanDrag:(BOOL)handlePanDrag {
537
544
  for (UIGestureRecognizer *recognizer in [self gestureRecognizers]) {
538
545
  if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
539
- recognizer.enabled = handleMapDrag;
546
+ recognizer.enabled = handlePanDrag;
540
547
  break;
541
548
  }
542
549
  }
550
+ _handlePanDrag = handlePanDrag;
543
551
  }
544
552
 
545
553
  - (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated
@@ -548,7 +556,7 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
548
556
  if (!CLLocationCoordinate2DIsValid(region.center)) {
549
557
  return;
550
558
  }
551
-
559
+
552
560
  // If new span values are nil, use old values instead
553
561
  if (!region.span.latitudeDelta) {
554
562
  region.span.latitudeDelta = self.region.span.latitudeDelta;
@@ -556,13 +564,28 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
556
564
  if (!region.span.longitudeDelta) {
557
565
  region.span.longitudeDelta = self.region.span.longitudeDelta;
558
566
  }
559
-
567
+
560
568
  // Animate/move to new position
561
569
  [super setRegion:region animated:animated];
562
570
  }
571
+ - (void) setRegion:(MKCoordinateRegion)region
572
+ {
573
+ if (!CLLocationCoordinate2DIsValid(region.center)) {
574
+ return;
575
+ }
576
+ if (!CLLocationCoordinate2DIsValid(_initialRegion.center)) {
577
+ [self setInitialRegion:region];
578
+ }
579
+ [self setRegion:region animated:NO];
580
+ }
563
581
 
564
582
  - (void)setInitialRegion:(MKCoordinateRegion)initialRegion {
565
- if (!_initialRegionSet) {
583
+ if (!CLLocationCoordinate2DIsValid(initialRegion.center)) {
584
+ return;
585
+ }
586
+ _initialRegion = initialRegion;
587
+ _initialRegionProvided = YES;
588
+ if (!_initialRegionSet && _loadingStarted) {
566
589
  _initialRegionSet = YES;
567
590
  [self setRegion:initialRegion animated:NO];
568
591
  }
@@ -575,9 +598,13 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
575
598
 
576
599
 
577
600
  - (void)setInitialCamera:(MKMapCamera*)initialCamera {
578
- if (!_initialCameraSet) {
579
- _initialCameraSet = YES;
580
- [self setCamera:initialCamera animated:NO];
601
+ _initialCamera = initialCamera;
602
+ _initialCameraProvided = YES;
603
+ if (initialCamera){
604
+ if (!_initialCameraSet && _loadingStarted) {
605
+ _initialCameraSet = YES;
606
+ [self setCamera:initialCamera animated:NO];
607
+ }
581
608
  }
582
609
  }
583
610
 
@@ -623,26 +650,24 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
623
650
  }
624
651
 
625
652
  - (void)setCameraZoomRange:(NSDictionary *)cameraZoomRange {
626
- if (@available(iOS 13.0, *)) {
627
-
628
653
  if (cameraZoomRange == nil) {
629
654
  cameraZoomRange = @{};
630
655
  }
631
-
656
+
632
657
  NSNumber *minValue = cameraZoomRange[@"minCenterCoordinateDistance"];
633
658
  NSNumber *maxValue = cameraZoomRange[@"maxCenterCoordinateDistance"];
634
-
659
+
635
660
  if (minValue == nil && maxValue == nil) {
636
661
  self.legacyZoomConstraintsEnabled = YES;
637
-
662
+
638
663
  MKMapCameraZoomRange *defaultZoomRange = [[MKMapCameraZoomRange alloc] initWithMinCenterCoordinateDistance:MKMapCameraZoomDefault maxCenterCoordinateDistance:MKMapCameraZoomDefault];
639
664
  [super setCameraZoomRange:defaultZoomRange animated:NO];
640
-
665
+
641
666
  return;
642
667
  }
643
-
668
+
644
669
  MKMapCameraZoomRange *zoomRange = nil;
645
-
670
+
646
671
  if (minValue != nil && maxValue != nil) {
647
672
  zoomRange = [[MKMapCameraZoomRange alloc] initWithMinCenterCoordinateDistance:[minValue doubleValue] maxCenterCoordinateDistance:[maxValue doubleValue]];
648
673
  } else if (minValue != nil) {
@@ -650,61 +675,13 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
650
675
  } else if (maxValue != nil) {
651
676
  zoomRange = [[MKMapCameraZoomRange alloc] initWithMaxCenterCoordinateDistance:[maxValue doubleValue]];
652
677
  }
653
-
678
+
654
679
  BOOL animated = [cameraZoomRange[@"animated"] boolValue];
655
-
680
+
656
681
  self.legacyZoomConstraintsEnabled = NO;
657
682
  [super setCameraZoomRange:zoomRange animated:animated];
658
- }
659
683
  }
660
684
 
661
- // Include properties of MKMapView which are only available on iOS 9+
662
- // and check if their selector is available before calling super method.
663
-
664
- - (void)setShowsCompass:(BOOL)showsCompass {
665
- if (self.overlayCompassButton != nil) {
666
- self.overlayCompassButton.compassVisibility = showsCompass ? MKFeatureVisibilityAdaptive : MKFeatureVisibilityHidden;
667
- }
668
- if ([MKMapView instancesRespondToSelector:@selector(setShowsCompass:)]) {
669
- [super setShowsCompass:showsCompass];
670
- }
671
- }
672
-
673
- - (BOOL)showsCompass {
674
- if ([MKMapView instancesRespondToSelector:@selector(showsCompass)]) {
675
- return [super showsCompass];
676
- } else {
677
- return NO;
678
- }
679
- }
680
-
681
- - (void)setShowsScale:(BOOL)showsScale {
682
- if ([MKMapView instancesRespondToSelector:@selector(setShowsScale:)]) {
683
- [super setShowsScale:showsScale];
684
- }
685
- }
686
-
687
- - (BOOL)showsScale {
688
- if ([MKMapView instancesRespondToSelector:@selector(showsScale)]) {
689
- return [super showsScale];
690
- } else {
691
- return NO;
692
- }
693
- }
694
-
695
- - (void)setShowsTraffic:(BOOL)showsTraffic {
696
- if ([MKMapView instancesRespondToSelector:@selector(setShowsTraffic:)]) {
697
- [super setShowsTraffic:showsTraffic];
698
- }
699
- }
700
-
701
- - (BOOL)showsTraffic {
702
- if ([MKMapView instancesRespondToSelector:@selector(showsTraffic)]) {
703
- return [super showsTraffic];
704
- } else {
705
- return NO;
706
- }
707
- }
708
685
 
709
686
  - (void)setScrollEnabled:(BOOL)scrollEnabled {
710
687
  self.shouldScrollEnabled = [NSNumber numberWithBool:scrollEnabled];
@@ -750,7 +727,7 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
750
727
  else {
751
728
  self.cacheImageView.image = nil;
752
729
  self.cacheImageView.hidden = YES;
753
-
730
+
754
731
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
755
732
  self.cacheImageView.image = nil;
756
733
  self.cacheImageView.hidden = YES;
@@ -758,18 +735,47 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
758
735
  [self.layer renderInContext:UIGraphicsGetCurrentContext()];
759
736
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
760
737
  UIGraphicsEndImageContext();
761
-
738
+
762
739
  self.cacheImageView.image = image;
763
740
  self.cacheImageView.hidden = NO;
764
741
  });
765
742
  }
766
-
743
+
767
744
  [self updateScrollEnabled];
768
745
  [self updateZoomEnabled];
769
746
  [self updateLegalLabelInsets];
770
747
  }
771
748
  }
772
749
 
750
+ - (void) listenToMemoryWarnings
751
+ {
752
+ __weak typeof(self) weakSelf = self;
753
+ static dispatch_once_t onceToken;
754
+ static dispatch_source_t source;
755
+ dispatch_once(&onceToken, ^{
756
+ source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, DISPATCH_MEMORYPRESSURE_WARN|DISPATCH_MEMORYPRESSURE_CRITICAL, dispatch_get_main_queue());
757
+ dispatch_source_set_event_handler(source, ^{
758
+ [weakSelf handleMemoryWarning];
759
+ });
760
+ dispatch_resume(source);
761
+ });
762
+ }
763
+ /*
764
+ hacky way to release all cache
765
+ this is our last chance to release cache before app crash
766
+ */
767
+ - (void) handleMemoryWarning
768
+ {
769
+ NSLog(@"handleMemoryWarning warning");
770
+ MKMapType type = self.mapType;
771
+ if (type == MKMapTypeSatellite){
772
+ self.mapType = MKMapTypeStandard;
773
+ } else {
774
+ self.mapType = MKMapTypeSatellite;
775
+ }
776
+ self.mapType = type;
777
+ }
778
+
773
779
  - (void)updateLegalLabelInsets {
774
780
  if (_legalLabel) {
775
781
  dispatch_async(dispatch_get_main_queue(), ^{
@@ -813,6 +819,14 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
813
819
  self.loadingView.hidden = YES;
814
820
  }
815
821
  }
822
+ _loadingStarted = YES;
823
+ // display initialRegion/Camera
824
+ if (_initialRegionProvided){
825
+ [self setInitialRegion:_initialRegion];
826
+ }
827
+ if (_initialCameraProvided){
828
+ [self setInitialCamera:_initialCamera];
829
+ }
816
830
  }
817
831
 
818
832
  - (void)finishLoading {
@@ -859,50 +873,27 @@ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordina
859
873
  - (void)layoutSubviews {
860
874
  [super layoutSubviews];
861
875
  [self cacheViewIfNeeded];
862
-
863
- if (self.overlayCompassButton == nil) {
864
- for (UIView *subview in self.subviews) {
865
- if (![NSStringFromClass(subview.class) isEqualToString:@"MKPassThroughStackView"]) continue;
866
- self.overlayCompassButton = [MKCompassButton compassButtonWithMapView:self];
867
- [subview addSubview:self.overlayCompassButton];
868
- self.overlayCompassButton.frame = CGRectMake(self.overlayCompassButton.frame.origin.x + _compassOffset.x, self.overlayCompassButton.frame.origin.y + _compassOffset.y, self.overlayCompassButton.frame.size.width, self.overlayCompassButton.frame.size.height);
869
- break;
870
- }
871
- }
872
-
873
- if (self.defaultCompassButton == nil) {
874
- for (UIView *subview in self.subviews) {
875
- if (![NSStringFromClass(subview.class) isEqualToString:@"MKPassThroughStackView"]) continue;
876
- for (UIView *subview2 in subview.subviews) {
877
- if (![NSStringFromClass(subview2.class) isEqualToString:@"MKCompassView"]) continue;
878
- self.defaultCompassButton = subview2;
879
- self.defaultCompassButton.hidden = YES;
880
- }
881
- break;
882
- }
883
- }
884
-
885
876
  }
886
877
 
887
878
  // based on https://medium.com/@dmytrobabych/getting-actual-rotation-and-zoom-level-for-mapkit-mkmapview-e7f03f430aa9
888
879
  - (CGFloat)getZoomLevel {
889
880
  CGFloat cameraAngle = self.camera.heading;
890
-
881
+
891
882
  if (cameraAngle > 270) {
892
883
  cameraAngle = 360 - cameraAngle;
893
884
  } else if (cameraAngle > 90) {
894
885
  cameraAngle = fabs(cameraAngle - 180);
895
886
  }
896
-
887
+
897
888
  CGFloat angleRad = M_PI * cameraAngle / 180; // map rotation in radians
898
889
  CGFloat width = self.frame.size.width;
899
890
  CGFloat height = self.frame.size.height;
900
891
  CGFloat heightOffset = 20; // the offset (status bar height) which is taken by MapKit into consideration to calculate visible area height
901
-
892
+
902
893
  // calculating Longitude span corresponding to normal (non-rotated) width
903
894
  CGFloat spanStraight = width * self.region.span.longitudeDelta / (width * cos(angleRad) + (height - heightOffset) * sin(angleRad));
904
895
  int normalizingFactor = 512;
905
-
896
+
906
897
  return log2(360 * ((width / normalizingFactor) / spanStraight));
907
898
  }
908
899