react-native-maps 1.21.0-alpha.7 → 1.21.0-alpha.71

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 (148) hide show
  1. package/android/build.gradle +38 -13
  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 +17 -0
  12. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsMapViewManagerDelegate.java +200 -0
  13. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsMapViewManagerInterface.java +71 -0
  14. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsMarkerManagerDelegate.java +104 -0
  15. package/android/generated/java/com/facebook/react/viewmanagers/RNMapsMarkerManagerInterface.java +39 -0
  16. package/android/generated/jni/CMakeLists.txt +36 -0
  17. package/android/generated/jni/RNMapsSpecs-generated.cpp +68 -0
  18. package/android/generated/jni/RNMapsSpecs.h +31 -0
  19. package/android/generated/jni/react/renderer/components/RNMapsSpecs/ComponentDescriptors.cpp +26 -0
  20. package/android/generated/jni/react/renderer/components/RNMapsSpecs/ComponentDescriptors.h +28 -0
  21. package/android/generated/jni/react/renderer/components/RNMapsSpecs/EventEmitters.cpp +918 -0
  22. package/android/generated/jni/react/renderer/components/RNMapsSpecs/EventEmitters.h +787 -0
  23. package/android/generated/jni/react/renderer/components/RNMapsSpecs/Props.cpp +154 -0
  24. package/android/generated/jni/react/renderer/components/RNMapsSpecs/Props.h +1058 -0
  25. package/android/generated/jni/react/renderer/components/RNMapsSpecs/RNMapsSpecsJSI-generated.cpp +74 -0
  26. package/android/generated/jni/react/renderer/components/RNMapsSpecs/RNMapsSpecsJSI.h +268 -0
  27. package/android/generated/jni/react/renderer/components/RNMapsSpecs/ShadowNodes.cpp +21 -0
  28. package/android/generated/jni/react/renderer/components/RNMapsSpecs/ShadowNodes.h +76 -0
  29. package/android/generated/jni/react/renderer/components/RNMapsSpecs/States.cpp +16 -0
  30. package/android/generated/jni/react/renderer/components/RNMapsSpecs/States.h +77 -0
  31. package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  32. package/android/src/main/java/com/rnmaps/fabric/CalloutManager.java +77 -0
  33. package/android/src/main/java/com/rnmaps/fabric/JSONUtil.java +86 -0
  34. package/android/src/main/java/com/rnmaps/fabric/MapViewManager.java +593 -0
  35. package/android/src/main/java/com/rnmaps/fabric/MarkerManager.java +259 -0
  36. package/android/src/main/java/com/rnmaps/fabric/NativeAirMapsModule.java +156 -4
  37. package/android/src/main/java/com/rnmaps/fabric/event/OnCalloutPressEvent.java +25 -0
  38. package/android/src/main/java/com/rnmaps/fabric/event/OnDeselectEvent.java +28 -0
  39. package/android/src/main/java/com/rnmaps/fabric/event/OnDragEndEvent.java +28 -0
  40. package/android/src/main/java/com/rnmaps/fabric/event/OnDragEvent.java +28 -0
  41. package/android/src/main/java/com/rnmaps/fabric/event/OnDragStartEvent.java +28 -0
  42. package/android/src/main/java/com/rnmaps/fabric/event/OnLongPressEvent.java +28 -0
  43. package/android/src/main/java/com/rnmaps/fabric/event/OnMapLoadedEvent.java +29 -0
  44. package/android/src/main/java/com/rnmaps/fabric/event/OnMapReadyEvent.java +29 -0
  45. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDeselectEvent.java +28 -0
  46. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDragEndEvent.java +28 -0
  47. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDragEvent.java +28 -0
  48. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDragStartEvent.java +28 -0
  49. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerPressEvent.java +28 -0
  50. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerSelectEvent.java +28 -0
  51. package/android/src/main/java/com/rnmaps/fabric/event/OnPoiClickEvent.java +27 -0
  52. package/android/src/main/java/com/rnmaps/fabric/event/OnPressEvent.java +27 -0
  53. package/android/src/main/java/com/rnmaps/fabric/event/OnRegionChangeCompleteEvent.java +30 -0
  54. package/android/src/main/java/com/rnmaps/fabric/event/OnRegionChangeEvent.java +48 -0
  55. package/android/src/main/java/com/rnmaps/fabric/event/OnRegionChangeStartEvent.java +33 -0
  56. package/android/src/main/java/com/rnmaps/fabric/event/OnSelectEvent.java +28 -0
  57. package/android/src/main/java/com/rnmaps/fabric/event/OnUserLocationChangeEvent.java +28 -0
  58. package/android/src/main/java/com/rnmaps/maps/MapAirModulePackage.java +22 -2
  59. package/android/src/main/java/com/rnmaps/maps/MapCallout.java +18 -0
  60. package/android/src/main/java/com/rnmaps/maps/MapManager.java +14 -14
  61. package/android/src/main/java/com/rnmaps/maps/MapMarker.java +79 -3
  62. package/android/src/main/java/com/rnmaps/maps/MapModule.java +206 -206
  63. package/android/src/main/java/com/rnmaps/maps/MapView.java +1618 -1346
  64. package/ios/AirGoogleMaps/AIRGoogleMap.h +3 -2
  65. package/ios/AirGoogleMaps/AIRGoogleMap.m +153 -48
  66. package/ios/AirGoogleMaps/AIRGoogleMapCircle.m +23 -11
  67. package/ios/AirGoogleMaps/AIRGoogleMapManager.m +17 -28
  68. package/ios/AirGoogleMaps/AIRGoogleMapMarker.h +2 -0
  69. package/ios/AirGoogleMaps/AIRGoogleMapMarker.m +347 -243
  70. package/ios/AirGoogleMaps/AIRGoogleMapPolygon.h +2 -1
  71. package/ios/AirGoogleMaps/AIRGoogleMapPolygon.m +30 -0
  72. package/ios/AirGoogleMaps/AIRGoogleMapPolyline.h +0 -1
  73. package/ios/AirGoogleMaps/AIRGoogleMapPolyline.m +0 -7
  74. package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.h +1 -1
  75. package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.m +2 -2
  76. package/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h +3 -0
  77. package/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m +2 -0
  78. package/ios/AirGoogleMaps/RNMapsGoogleMapView.h +3 -3
  79. package/ios/AirGoogleMaps/RNMapsGoogleMapView.mm +161 -61
  80. package/ios/AirGoogleMaps/RNMapsGooglePolygonView.h +26 -0
  81. package/ios/AirGoogleMaps/RNMapsGooglePolygonView.mm +217 -0
  82. package/ios/AirGoogleMaps/RNMapsGooglePolygonViewManager.mm +25 -0
  83. package/ios/AirMaps/AIRMap.h +6 -3
  84. package/ios/AirMaps/AIRMap.m +289 -145
  85. package/ios/AirMaps/AIRMapManager.m +8 -17
  86. package/ios/AirMaps/AIRMapMarker.h +1 -0
  87. package/ios/AirMaps/AIRMapMarker.m +165 -103
  88. package/ios/AirMaps/Callout/SMCalloutView.m +1 -1
  89. package/ios/AirMaps/RCTConvert+AirMap.h +4 -0
  90. package/ios/AirMaps/RCTConvert+AirMap.m +2 -0
  91. package/ios/AirMaps/RNMapsAirModule.h +1 -1
  92. package/ios/AirMaps/RNMapsAirModule.mm +42 -172
  93. package/ios/AirMaps/RNMapsAirModuleDelegate.h +24 -0
  94. package/ios/AirMaps/RNMapsHostVewDelegate.h +17 -0
  95. package/ios/AirMaps/RNMapsMapView.h +3 -3
  96. package/ios/AirMaps/RNMapsMapView.mm +344 -307
  97. package/ios/AirMaps/RNMapsMarkerView.h +24 -0
  98. package/ios/AirMaps/RNMapsMarkerView.mm +430 -0
  99. package/ios/AirMaps/RNMapsMarkerViewManager.mm +21 -0
  100. package/ios/AirMaps/UIView +AirMap.m +20 -0
  101. package/ios/AirMaps/UIView+AirMap.h +11 -0
  102. package/ios/AirMaps.xcodeproj/project.pbxproj +60 -0
  103. package/ios/generated/RCTAppDependencyProvider.h +25 -0
  104. package/ios/generated/RCTAppDependencyProvider.mm +55 -0
  105. package/ios/generated/RCTModulesConformingToProtocolsProvider.h +18 -0
  106. package/ios/generated/RCTModulesConformingToProtocolsProvider.mm +33 -0
  107. package/ios/generated/RCTThirdPartyComponentsProvider.h +16 -0
  108. package/ios/generated/RCTThirdPartyComponentsProvider.mm +26 -0
  109. package/ios/generated/RNMapsSpecs/ComponentDescriptors.cpp +26 -0
  110. package/ios/generated/RNMapsSpecs/ComponentDescriptors.h +28 -0
  111. package/ios/generated/RNMapsSpecs/EventEmitters.cpp +918 -0
  112. package/ios/generated/RNMapsSpecs/EventEmitters.h +787 -0
  113. package/ios/generated/RNMapsSpecs/Props.cpp +154 -0
  114. package/ios/generated/RNMapsSpecs/Props.h +1058 -0
  115. package/ios/generated/RNMapsSpecs/RCTComponentViewHelpers.h +549 -0
  116. package/ios/generated/RNMapsSpecs/RNMapsSpecs-generated.mm +92 -0
  117. package/ios/generated/RNMapsSpecs/RNMapsSpecs.h +137 -0
  118. package/ios/generated/RNMapsSpecs/ShadowNodes.cpp +21 -0
  119. package/ios/generated/RNMapsSpecs/ShadowNodes.h +76 -0
  120. package/ios/generated/RNMapsSpecs/States.cpp +16 -0
  121. package/ios/generated/RNMapsSpecs/States.h +77 -0
  122. package/ios/generated/RNMapsSpecsJSI-generated.cpp +74 -0
  123. package/ios/generated/RNMapsSpecsJSI.h +268 -0
  124. package/ios/generated/ReactAppDependencyProvider.podspec +34 -0
  125. package/lib/MapCallout.js +1 -0
  126. package/lib/MapMarker.d.ts +15 -2
  127. package/lib/MapMarker.js +53 -9
  128. package/lib/MapMarkerNativeComponent.js +0 -2
  129. package/lib/MapOverlay.js +2 -8
  130. package/lib/MapPolyline.d.ts +1 -1
  131. package/lib/MapView.d.ts +7 -22
  132. package/lib/MapView.js +83 -94
  133. package/lib/{FabricMapView.d.ts → createFabricMap.d.ts} +7 -11
  134. package/lib/createFabricMap.js +175 -0
  135. package/lib/decorateMapComponent.js +22 -0
  136. package/lib/specs/NativeAirMapsModule.d.ts +2 -2
  137. package/lib/specs/NativeComponentCallout.d.ts +46 -0
  138. package/lib/specs/NativeComponentCallout.js +9 -0
  139. package/lib/specs/NativeComponentGoogleMapView.d.ts +12 -12
  140. package/lib/specs/NativeComponentGooglePolygon.d.ts +75 -0
  141. package/lib/specs/NativeComponentGooglePolygon.js +9 -0
  142. package/lib/specs/NativeComponentMapView.d.ts +19 -36
  143. package/lib/specs/NativeComponentMapView.js +1 -3
  144. package/lib/specs/NativeComponentMarker.d.ts +258 -0
  145. package/lib/specs/NativeComponentMarker.js +19 -0
  146. package/package.json +15 -10
  147. package/react-native-maps.podspec +2 -1
  148. package/lib/FabricMapView.js +0 -181
@@ -20,6 +20,7 @@
20
20
  #import "AIRMapWMSTile.h"
21
21
  #import "AIRMapLocalTile.h"
22
22
  #import "AIRMapOverlay.h"
23
+ #import "AIRMapSnapshot.h"
23
24
 
24
25
  const NSTimeInterval AIRMapRegionChangeObserveInterval = 0.1;
25
26
  const CGFloat AIRMapZoomBoundBuffer = 0.01;
@@ -38,8 +39,6 @@ const NSInteger AIRMapMaxZoomLevel = 20;
38
39
  @property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView;
39
40
  @property (nonatomic, assign) NSNumber *shouldZoomEnabled;
40
41
  @property (nonatomic, assign) NSNumber *shouldScrollEnabled;
41
- @property (nonatomic, strong) MKCompassButton *defaultCompassButton;
42
- @property (nonatomic, strong) MKCompassButton *overlayCompassButton;
43
42
 
44
43
  - (void)updateScrollEnabled;
45
44
  - (void)updateZoomEnabled;
@@ -50,8 +49,12 @@ const NSInteger AIRMapMaxZoomLevel = 20;
50
49
  {
51
50
  UIView *_legalLabel;
52
51
  BOOL _initialRegionSet;
52
+ BOOL _initialRegionProvided;
53
+ BOOL _initialCameraProvided;
53
54
  BOOL _initialCameraSet;
54
-
55
+ BOOL _initialized;
56
+ BOOL _loadingStarted;
57
+
55
58
  // Array to manually track RN subviews
56
59
  //
57
60
  // AIRMap implicitly creates subviews that aren't regular RN children
@@ -69,7 +72,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
69
72
  if ((self = [super init])) {
70
73
  _hasStartedRendering = NO;
71
74
  _reactSubviews = [NSMutableArray new];
72
-
75
+
73
76
  // Find Apple link label
74
77
  for (UIView *subview in self.subviews) {
75
78
  if ([NSStringFromClass(subview.class) isEqualToString:@"MKAttributionLabel"]) {
@@ -79,16 +82,18 @@ const NSInteger AIRMapMaxZoomLevel = 20;
79
82
  break;
80
83
  }
81
84
  }
82
-
85
+
83
86
  // 3rd-party callout view for MapKit that has more options than the built-in. It's painstakingly built to
84
87
  // be identical to the built-in callout view (which has a private API)
85
88
  self.calloutView = [SMCalloutView platformCalloutView];
86
89
  self.calloutView.delegate = self;
87
-
90
+
88
91
  self.minZoom = 0;
89
92
  self.maxZoom = AIRMapMaxZoomLevel;
90
93
  self.compassOffset = CGPointMake(0, 0);
91
94
  self.legacyZoomConstraintsEnabled = YES;
95
+ _initialized = YES;
96
+ [self listenToMemoryWarnings];
92
97
  }
93
98
  return self;
94
99
  }
@@ -199,6 +204,20 @@ const NSInteger AIRMapMaxZoomLevel = 20;
199
204
  }
200
205
  return marker;
201
206
  }
207
+ // Create Polyline with coordinates
208
+ -(void) fitToCoordinates:(NSArray<AIRMapCoordinate*>*) coordinates edgePadding:(UIEdgeInsets) edgeInsets animated:(Boolean) animated {
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];
215
+
216
+ // Set Map viewport
217
+
218
+ [self setVisibleMapRect:[polyline boundingMapRect] edgePadding:edgeInsets animated:animated];
219
+ }
220
+
202
221
 
203
222
  - (CGRect) frameForMarker:(AIRMapMarker*) mrkAnn {
204
223
  MKAnnotationView* mrkView = [self viewForAnnotation: mrkAnn];
@@ -206,29 +225,6 @@ const NSInteger AIRMapMaxZoomLevel = 20;
206
225
  return mrkFrame;
207
226
  }
208
227
 
209
- - (NSDictionary*) getMarkersFramesWithOnlyVisible:(BOOL)onlyVisible {
210
- NSMutableDictionary* markersFrames = [NSMutableDictionary new];
211
- for (AIRMapMarker* mrkAnn in self.markers) {
212
- CGRect frame = [self frameForMarker:mrkAnn];
213
- CGPoint point = [self convertCoordinate:mrkAnn.coordinate toPointToView:self];
214
- NSDictionary* frameDict = @{
215
- @"x": @(frame.origin.x),
216
- @"y": @(frame.origin.y),
217
- @"width": @(frame.size.width),
218
- @"height": @(frame.size.height)
219
- };
220
- NSDictionary* pointDict = @{
221
- @"x": @(point.x),
222
- @"y": @(point.y)
223
- };
224
- NSString* k = mrkAnn.identifier;
225
- BOOL isVisible = CGRectIntersectsRect(self.bounds, frame);
226
- if (k != nil && (!onlyVisible || isVisible)) {
227
- [markersFrames setObject:@{ @"frame": frameDict, @"point": pointDict } forKey:k];
228
- }
229
- }
230
- return markersFrames;
231
- }
232
228
 
233
229
  - (AIRMapMarker*) markerAtPoint:(CGPoint)point {
234
230
  AIRMapMarker* mrk = nil;
@@ -257,16 +253,16 @@ const NSInteger AIRMapMaxZoomLevel = 20;
257
253
  // Allow touches to be sent to our calloutview.
258
254
  // See this for some discussion of why we need to override this: https://github.com/nfarina/calloutview/pull/9
259
255
  - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
260
-
256
+
261
257
  CGPoint touchPoint = [self.calloutView convertPoint:point fromView:self];
262
258
  UIView *touchedView = [self.calloutView hitTest:touchPoint withEvent:event];
263
-
259
+
264
260
  if (touchedView) {
265
261
  UIWindow* win = [[[UIApplication sharedApplication] windows] firstObject];
266
262
  AIRMapCalloutSubview* calloutSubview = nil;
267
263
  AIRMapCallout* callout = nil;
268
264
  AIRMapMarker* marker = nil;
269
-
265
+
270
266
  UIView* tmp = touchedView;
271
267
  while (tmp && tmp != win && tmp != self.calloutView) {
272
268
  if ([tmp respondsToSelector:@selector(onPress)]) {
@@ -278,7 +274,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
278
274
  }
279
275
  tmp = tmp.superview;
280
276
  }
281
-
277
+
282
278
  if (callout) {
283
279
  marker = [self markerForCallout:callout];
284
280
  if (marker) {
@@ -288,49 +284,49 @@ const NSInteger AIRMapMaxZoomLevel = 20;
288
284
  }
289
285
  }
290
286
  }
291
-
287
+
292
288
  return calloutSubview ? calloutSubview : touchedView;
293
289
  }
294
-
290
+
295
291
  return [super hitTest:point withEvent:event];
296
292
  }
297
293
 
298
294
  #pragma mark SMCalloutViewDelegate
299
295
 
300
296
  - (NSTimeInterval)calloutView:(SMCalloutView *)calloutView delayForRepositionWithSize:(CGSize)offset {
301
-
297
+
302
298
  // When the callout is being asked to present in a way where it or its target will be partially offscreen, it asks us
303
299
  // if we'd like to reposition our surface first so the callout is completely visible. Here we scroll the map into view,
304
300
  // but it takes some math because we have to deal in lon/lat instead of the given offset in pixels.
305
-
301
+
306
302
  CLLocationCoordinate2D coordinate = self.region.center;
307
-
303
+
308
304
  // where's the center coordinate in terms of our view?
309
305
  CGPoint center = [self convertCoordinate:coordinate toPointToView:self];
310
-
306
+
311
307
  // move it by the requested offset
312
308
  center.x -= offset.width;
313
309
  center.y -= offset.height;
314
-
310
+
315
311
  // and translate it back into map coordinates
316
312
  coordinate = [self convertPoint:center toCoordinateFromView:self];
317
-
313
+
318
314
  // move the map!
319
315
  [self setCenterCoordinate:coordinate animated:YES];
320
-
316
+
321
317
  // tell the callout to wait for a while while we scroll (we assume the scroll delay for MKMapView matches UIScrollView)
322
318
  return kSMCalloutViewRepositionDelayForUIScrollView;
323
319
  }
324
320
 
325
- #pragma mark Accessors
321
+ #pragma mark RNMapsAirModuleDelegate.h
326
322
 
327
323
  - (NSArray *)getMapBoundaries
328
324
  {
329
325
  MKMapRect mapRect = self.visibleMapRect;
330
-
326
+
331
327
  CLLocationCoordinate2D northEast = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMaxX(mapRect), mapRect.origin.y));
332
328
  CLLocationCoordinate2D southWest = MKCoordinateForMapPoint(MKMapPointMake(mapRect.origin.x, MKMapRectGetMaxY(mapRect)));
333
-
329
+
334
330
  return @[
335
331
  @[
336
332
  [NSNumber numberWithDouble:northEast.longitude],
@@ -342,6 +338,174 @@ const NSInteger AIRMapMaxZoomLevel = 20;
342
338
  ]
343
339
  ];
344
340
  }
341
+ - (NSDictionary *) getPointForCoordinates:(CLLocationCoordinate2D) location
342
+ {
343
+ CGPoint touchPoint = [self convertCoordinate:location toPointToView:self];
344
+
345
+ return @{
346
+ @"x": @(touchPoint.x),
347
+ @"y": @(touchPoint.y),
348
+ };
349
+ }
350
+ - (NSDictionary *) getCoordinatesForPoint:(CGPoint)point
351
+ {
352
+ CLLocationCoordinate2D coordinate = [self convertPoint:point toCoordinateFromView:self];
353
+ return @{
354
+ @"latitude": @(coordinate.latitude),
355
+ @"longitude": @(coordinate.longitude),
356
+ };
357
+
358
+ }
359
+
360
+ - (NSDictionary*) getMarkersFramesWithOnlyVisible:(BOOL)onlyVisible {
361
+ NSMutableDictionary* markersFrames = [NSMutableDictionary new];
362
+ for (AIRMapMarker* mrkAnn in self.markers) {
363
+ CGRect frame = [self frameForMarker:mrkAnn];
364
+ CGPoint point = [self convertCoordinate:mrkAnn.coordinate toPointToView:self];
365
+ NSDictionary* frameDict = @{
366
+ @"x": @(frame.origin.x),
367
+ @"y": @(frame.origin.y),
368
+ @"width": @(frame.size.width),
369
+ @"height": @(frame.size.height)
370
+ };
371
+ NSDictionary* pointDict = @{
372
+ @"x": @(point.x),
373
+ @"y": @(point.y)
374
+ };
375
+ NSString* k = mrkAnn.identifier;
376
+ BOOL isVisible = CGRectIntersectsRect(self.bounds, frame);
377
+ if (k != nil && (!onlyVisible || isVisible)) {
378
+ [markersFrames setObject:@{ @"frame": frameDict, @"point": pointDict } forKey:k];
379
+ }
380
+ }
381
+ return markersFrames;
382
+ }
383
+
384
+ - (NSDictionary *) getCameraDic {
385
+ MKMapCamera *camera = [self camera];
386
+ return @{
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),
394
+ };
395
+ }
396
+ - (void)takeSnapshotWithConfig:(NSDictionary *)config
397
+ success:(RCTPromiseResolveBlock)success error:(RCTPromiseRejectBlock)error
398
+ {
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];
430
+ }
431
+
432
+ #pragma mark Take Snapshot
433
+ - (void)takeMapSnapshot:(MKMapSnapshotter *) snapshotter
434
+ format:(NSString *)format
435
+ quality:(CGFloat) quality
436
+ result:(NSString *)result
437
+ success:(RCTPromiseResolveBlock) success
438
+ error:(RCTPromiseRejectBlock) errorCallback {
439
+ NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
440
+ NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.%@", timeStamp, format];
441
+ NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent];
442
+
443
+ [snapshotter startWithQueue:dispatch_get_main_queue()
444
+ completionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
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
+ }];
506
+ }
507
+
508
+
345
509
 
346
510
  - (void)setShowsUserLocation:(BOOL)showsUserLocation
347
511
  {
@@ -352,7 +516,6 @@ const NSInteger AIRMapMaxZoomLevel = 20;
352
516
 
353
517
  - (void)setUserInterfaceStyle:(NSString*)userInterfaceStyle
354
518
  {
355
- if (@available(iOS 13.0, *)) {
356
519
  if([userInterfaceStyle isEqualToString:@"light"]) {
357
520
  self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
358
521
  } else if([userInterfaceStyle isEqualToString:@"dark"]) {
@@ -360,9 +523,6 @@ const NSInteger AIRMapMaxZoomLevel = 20;
360
523
  } else {
361
524
  self.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
362
525
  }
363
- } else {
364
- NSLog(@"UserInterfaceStyle not supported below iOS 13");
365
- }
366
526
  }
367
527
 
368
528
  - (void)setTintColor:(UIColor *)tintColor
@@ -380,13 +540,14 @@ const NSInteger AIRMapMaxZoomLevel = 20;
380
540
  _userLocationCalloutEnabled = calloutEnabled;
381
541
  }
382
542
 
383
- - (void)setHandlePanDrag:(BOOL)handleMapDrag {
543
+ - (void)setHandlePanDrag:(BOOL)handlePanDrag {
384
544
  for (UIGestureRecognizer *recognizer in [self gestureRecognizers]) {
385
545
  if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
386
- recognizer.enabled = handleMapDrag;
546
+ recognizer.enabled = handlePanDrag;
387
547
  break;
388
548
  }
389
549
  }
550
+ _handlePanDrag = handlePanDrag;
390
551
  }
391
552
 
392
553
  - (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated
@@ -395,7 +556,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
395
556
  if (!CLLocationCoordinate2DIsValid(region.center)) {
396
557
  return;
397
558
  }
398
-
559
+
399
560
  // If new span values are nil, use old values instead
400
561
  if (!region.span.latitudeDelta) {
401
562
  region.span.latitudeDelta = self.region.span.latitudeDelta;
@@ -403,13 +564,28 @@ const NSInteger AIRMapMaxZoomLevel = 20;
403
564
  if (!region.span.longitudeDelta) {
404
565
  region.span.longitudeDelta = self.region.span.longitudeDelta;
405
566
  }
406
-
567
+
407
568
  // Animate/move to new position
408
569
  [super setRegion:region animated:animated];
409
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
+ }
410
581
 
411
582
  - (void)setInitialRegion:(MKCoordinateRegion)initialRegion {
412
- if (!_initialRegionSet) {
583
+ if (!CLLocationCoordinate2DIsValid(initialRegion.center)) {
584
+ return;
585
+ }
586
+ _initialRegion = initialRegion;
587
+ _initialRegionProvided = YES;
588
+ if (!_initialRegionSet && _loadingStarted) {
413
589
  _initialRegionSet = YES;
414
590
  [self setRegion:initialRegion animated:NO];
415
591
  }
@@ -422,9 +598,13 @@ const NSInteger AIRMapMaxZoomLevel = 20;
422
598
 
423
599
 
424
600
  - (void)setInitialCamera:(MKMapCamera*)initialCamera {
425
- if (!_initialCameraSet) {
426
- _initialCameraSet = YES;
427
- [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
+ }
428
608
  }
429
609
  }
430
610
 
@@ -470,26 +650,24 @@ const NSInteger AIRMapMaxZoomLevel = 20;
470
650
  }
471
651
 
472
652
  - (void)setCameraZoomRange:(NSDictionary *)cameraZoomRange {
473
- if (@available(iOS 13.0, *)) {
474
-
475
653
  if (cameraZoomRange == nil) {
476
654
  cameraZoomRange = @{};
477
655
  }
478
-
656
+
479
657
  NSNumber *minValue = cameraZoomRange[@"minCenterCoordinateDistance"];
480
658
  NSNumber *maxValue = cameraZoomRange[@"maxCenterCoordinateDistance"];
481
-
659
+
482
660
  if (minValue == nil && maxValue == nil) {
483
661
  self.legacyZoomConstraintsEnabled = YES;
484
-
662
+
485
663
  MKMapCameraZoomRange *defaultZoomRange = [[MKMapCameraZoomRange alloc] initWithMinCenterCoordinateDistance:MKMapCameraZoomDefault maxCenterCoordinateDistance:MKMapCameraZoomDefault];
486
664
  [super setCameraZoomRange:defaultZoomRange animated:NO];
487
-
665
+
488
666
  return;
489
667
  }
490
-
668
+
491
669
  MKMapCameraZoomRange *zoomRange = nil;
492
-
670
+
493
671
  if (minValue != nil && maxValue != nil) {
494
672
  zoomRange = [[MKMapCameraZoomRange alloc] initWithMinCenterCoordinateDistance:[minValue doubleValue] maxCenterCoordinateDistance:[maxValue doubleValue]];
495
673
  } else if (minValue != nil) {
@@ -497,61 +675,13 @@ const NSInteger AIRMapMaxZoomLevel = 20;
497
675
  } else if (maxValue != nil) {
498
676
  zoomRange = [[MKMapCameraZoomRange alloc] initWithMaxCenterCoordinateDistance:[maxValue doubleValue]];
499
677
  }
500
-
678
+
501
679
  BOOL animated = [cameraZoomRange[@"animated"] boolValue];
502
-
680
+
503
681
  self.legacyZoomConstraintsEnabled = NO;
504
682
  [super setCameraZoomRange:zoomRange animated:animated];
505
- }
506
- }
507
-
508
- // Include properties of MKMapView which are only available on iOS 9+
509
- // and check if their selector is available before calling super method.
510
-
511
- - (void)setShowsCompass:(BOOL)showsCompass {
512
- if (self.overlayCompassButton != nil) {
513
- self.overlayCompassButton.compassVisibility = showsCompass ? MKFeatureVisibilityAdaptive : MKFeatureVisibilityHidden;
514
- }
515
- if ([MKMapView instancesRespondToSelector:@selector(setShowsCompass:)]) {
516
- [super setShowsCompass:showsCompass];
517
- }
518
- }
519
-
520
- - (BOOL)showsCompass {
521
- if ([MKMapView instancesRespondToSelector:@selector(showsCompass)]) {
522
- return [super showsCompass];
523
- } else {
524
- return NO;
525
- }
526
- }
527
-
528
- - (void)setShowsScale:(BOOL)showsScale {
529
- if ([MKMapView instancesRespondToSelector:@selector(setShowsScale:)]) {
530
- [super setShowsScale:showsScale];
531
- }
532
683
  }
533
684
 
534
- - (BOOL)showsScale {
535
- if ([MKMapView instancesRespondToSelector:@selector(showsScale)]) {
536
- return [super showsScale];
537
- } else {
538
- return NO;
539
- }
540
- }
541
-
542
- - (void)setShowsTraffic:(BOOL)showsTraffic {
543
- if ([MKMapView instancesRespondToSelector:@selector(setShowsTraffic:)]) {
544
- [super setShowsTraffic:showsTraffic];
545
- }
546
- }
547
-
548
- - (BOOL)showsTraffic {
549
- if ([MKMapView instancesRespondToSelector:@selector(showsTraffic)]) {
550
- return [super showsTraffic];
551
- } else {
552
- return NO;
553
- }
554
- }
555
685
 
556
686
  - (void)setScrollEnabled:(BOOL)scrollEnabled {
557
687
  self.shouldScrollEnabled = [NSNumber numberWithBool:scrollEnabled];
@@ -597,7 +727,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
597
727
  else {
598
728
  self.cacheImageView.image = nil;
599
729
  self.cacheImageView.hidden = YES;
600
-
730
+
601
731
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
602
732
  self.cacheImageView.image = nil;
603
733
  self.cacheImageView.hidden = YES;
@@ -605,18 +735,47 @@ const NSInteger AIRMapMaxZoomLevel = 20;
605
735
  [self.layer renderInContext:UIGraphicsGetCurrentContext()];
606
736
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
607
737
  UIGraphicsEndImageContext();
608
-
738
+
609
739
  self.cacheImageView.image = image;
610
740
  self.cacheImageView.hidden = NO;
611
741
  });
612
742
  }
613
-
743
+
614
744
  [self updateScrollEnabled];
615
745
  [self updateZoomEnabled];
616
746
  [self updateLegalLabelInsets];
617
747
  }
618
748
  }
619
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
+
620
779
  - (void)updateLegalLabelInsets {
621
780
  if (_legalLabel) {
622
781
  dispatch_async(dispatch_get_main_queue(), ^{
@@ -660,6 +819,14 @@ const NSInteger AIRMapMaxZoomLevel = 20;
660
819
  self.loadingView.hidden = YES;
661
820
  }
662
821
  }
822
+ _loadingStarted = YES;
823
+ // display initialRegion/Camera
824
+ if (_initialRegionProvided){
825
+ [self setInitialRegion:_initialRegion];
826
+ }
827
+ if (_initialCameraProvided){
828
+ [self setInitialCamera:_initialCamera];
829
+ }
663
830
  }
664
831
 
665
832
  - (void)finishLoading {
@@ -706,50 +873,27 @@ const NSInteger AIRMapMaxZoomLevel = 20;
706
873
  - (void)layoutSubviews {
707
874
  [super layoutSubviews];
708
875
  [self cacheViewIfNeeded];
709
-
710
- if (self.overlayCompassButton == nil) {
711
- for (UIView *subview in self.subviews) {
712
- if (![NSStringFromClass(subview.class) isEqualToString:@"MKPassThroughStackView"]) continue;
713
- self.overlayCompassButton = [MKCompassButton compassButtonWithMapView:self];
714
- [subview addSubview:self.overlayCompassButton];
715
- 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);
716
- break;
717
- }
718
- }
719
-
720
- if (self.defaultCompassButton == nil) {
721
- for (UIView *subview in self.subviews) {
722
- if (![NSStringFromClass(subview.class) isEqualToString:@"MKPassThroughStackView"]) continue;
723
- for (UIView *subview2 in subview.subviews) {
724
- if (![NSStringFromClass(subview2.class) isEqualToString:@"MKCompassView"]) continue;
725
- self.defaultCompassButton = subview2;
726
- self.defaultCompassButton.hidden = YES;
727
- }
728
- break;
729
- }
730
- }
731
-
732
876
  }
733
877
 
734
878
  // based on https://medium.com/@dmytrobabych/getting-actual-rotation-and-zoom-level-for-mapkit-mkmapview-e7f03f430aa9
735
879
  - (CGFloat)getZoomLevel {
736
880
  CGFloat cameraAngle = self.camera.heading;
737
-
881
+
738
882
  if (cameraAngle > 270) {
739
883
  cameraAngle = 360 - cameraAngle;
740
884
  } else if (cameraAngle > 90) {
741
885
  cameraAngle = fabs(cameraAngle - 180);
742
886
  }
743
-
887
+
744
888
  CGFloat angleRad = M_PI * cameraAngle / 180; // map rotation in radians
745
889
  CGFloat width = self.frame.size.width;
746
890
  CGFloat height = self.frame.size.height;
747
891
  CGFloat heightOffset = 20; // the offset (status bar height) which is taken by MapKit into consideration to calculate visible area height
748
-
892
+
749
893
  // calculating Longitude span corresponding to normal (non-rotated) width
750
894
  CGFloat spanStraight = width * self.region.span.longitudeDelta / (width * cos(angleRad) + (height - heightOffset) * sin(angleRad));
751
895
  int normalizingFactor = 512;
752
-
896
+
753
897
  return log2(360 * ((width / normalizingFactor) / spanStraight));
754
898
  }
755
899