react-native-maps 1.21.0-alpha.2 → 1.21.0-alpha.20
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.
- package/android/build.gradle +19 -4
- package/android/src/main/java/com/rnmaps/fabric/NativeAirMapsModule.java +51 -0
- package/android/src/main/java/com/rnmaps/maps/MapAirModulePackage.java +46 -0
- package/ios/AirGoogleMaps/AIRGoogleMap.h +8 -2
- package/ios/AirGoogleMaps/AIRGoogleMap.m +166 -11
- package/ios/AirGoogleMaps/AIRGoogleMapCircle.h +0 -1
- package/ios/AirGoogleMaps/AIRGoogleMapCoordinate.h +13 -0
- package/ios/AirGoogleMaps/AIRGoogleMapCoordinate.m +10 -0
- package/ios/AirGoogleMaps/AIRGoogleMapManager.h +7 -0
- package/ios/AirGoogleMaps/AIRGoogleMapManager.m +28 -119
- package/ios/AirGoogleMaps/AIRGoogleMapMarker.h +2 -0
- package/ios/AirGoogleMaps/AIRGoogleMapMarker.m +344 -243
- package/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +0 -1
- package/ios/AirGoogleMaps/AIRGoogleMapOverlay.h +0 -1
- package/ios/AirGoogleMaps/AIRGoogleMapPolygon.h +5 -4
- package/ios/AirGoogleMaps/AIRGoogleMapPolygon.m +29 -2
- package/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m +3 -3
- package/ios/AirGoogleMaps/AIRGoogleMapPolyline.h +3 -2
- package/ios/AirGoogleMaps/AIRGoogleMapPolyline.m +2 -3
- package/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m +2 -2
- package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.h +1 -1
- package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.m +2 -2
- package/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h +3 -0
- package/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m +18 -0
- package/ios/AirGoogleMaps/RNMapsGoogleMapView.h +26 -0
- package/ios/AirGoogleMaps/RNMapsGoogleMapView.mm +599 -0
- package/ios/AirGoogleMaps/RNMapsGoogleMapViewManager.mm +25 -0
- package/ios/AirGoogleMaps/RNMapsGooglePolygonView.h +26 -0
- package/ios/AirGoogleMaps/RNMapsGooglePolygonView.mm +217 -0
- package/ios/AirGoogleMaps/RNMapsGooglePolygonViewManager.mm +25 -0
- package/ios/AirMaps/AIRMap.h +8 -4
- package/ios/AirMaps/AIRMap.m +227 -137
- package/ios/AirMaps/AIRMapManager.m +9 -21
- package/ios/AirMaps/AIRMapMarker.m +8 -2
- package/ios/AirMaps/RCTConvert+AirMap.h +4 -0
- package/ios/AirMaps/RCTConvert+AirMap.m +2 -0
- package/ios/AirMaps/RNMapsAirModule.h +3 -0
- package/ios/AirMaps/RNMapsAirModule.mm +40 -171
- package/ios/AirMaps/RNMapsAirModuleDelegate.h +24 -0
- package/ios/AirMaps/RNMapsHostVewDelegate.h +17 -0
- package/ios/AirMaps/RNMapsMapView.h +6 -3
- package/ios/AirMaps/RNMapsMapView.mm +340 -334
- package/ios/AirMaps/UIView +AirMap.m +20 -0
- package/ios/AirMaps/UIView+AirMap.h +11 -0
- package/lib/MapMarker.d.ts +2 -2
- package/lib/MapMarker.js +12 -5
- package/lib/MapMarkerNativeComponent.js +0 -2
- package/lib/MapOverlay.d.ts +1 -1
- package/lib/MapView.d.ts +4 -22
- package/lib/MapView.js +28 -21
- package/lib/{FabricMapView.d.ts → createFabricMap.d.ts} +7 -6
- package/lib/createFabricMap.js +175 -0
- package/lib/decorateMapComponent.js +18 -0
- package/lib/specs/NativeComponentGoogleMapView.d.ts +713 -0
- package/lib/specs/NativeComponentGoogleMapView.js +21 -0
- package/lib/specs/NativeComponentGooglePolygon.d.ts +75 -0
- package/lib/specs/NativeComponentGooglePolygon.js +9 -0
- package/lib/specs/NativeComponentMapView.d.ts +21 -45
- package/lib/specs/NativeComponentMarker.d.ts +245 -0
- package/lib/specs/NativeComponentMarker.js +20 -0
- package/package.json +10 -7
- package/react-native-maps.podspec +1 -1
- package/lib/FabricMapView.js +0 -175
package/ios/AirMaps/AIRMap.m
CHANGED
|
@@ -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;
|
|
@@ -51,7 +50,8 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
51
50
|
UIView *_legalLabel;
|
|
52
51
|
BOOL _initialRegionSet;
|
|
53
52
|
BOOL _initialCameraSet;
|
|
54
|
-
|
|
53
|
+
BOOL _initialized;
|
|
54
|
+
|
|
55
55
|
// Array to manually track RN subviews
|
|
56
56
|
//
|
|
57
57
|
// AIRMap implicitly creates subviews that aren't regular RN children
|
|
@@ -69,7 +69,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
69
69
|
if ((self = [super init])) {
|
|
70
70
|
_hasStartedRendering = NO;
|
|
71
71
|
_reactSubviews = [NSMutableArray new];
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
// Find Apple link label
|
|
74
74
|
for (UIView *subview in self.subviews) {
|
|
75
75
|
if ([NSStringFromClass(subview.class) isEqualToString:@"MKAttributionLabel"]) {
|
|
@@ -79,16 +79,17 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
79
79
|
break;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
// 3rd-party callout view for MapKit that has more options than the built-in. It's painstakingly built to
|
|
84
84
|
// be identical to the built-in callout view (which has a private API)
|
|
85
85
|
self.calloutView = [SMCalloutView platformCalloutView];
|
|
86
86
|
self.calloutView.delegate = self;
|
|
87
|
-
|
|
88
|
-
self.
|
|
89
|
-
self.
|
|
87
|
+
|
|
88
|
+
self.minZoom = 0;
|
|
89
|
+
self.maxZoom = AIRMapMaxZoomLevel;
|
|
90
90
|
self.compassOffset = CGPointMake(0, 0);
|
|
91
91
|
self.legacyZoomConstraintsEnabled = YES;
|
|
92
|
+
_initialized = YES;
|
|
92
93
|
}
|
|
93
94
|
return self;
|
|
94
95
|
}
|
|
@@ -100,6 +101,9 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
100
101
|
[super addSubview:view];
|
|
101
102
|
}
|
|
102
103
|
}
|
|
104
|
+
- (void) didSetRegion {
|
|
105
|
+
_initialRegionSet = YES;
|
|
106
|
+
}
|
|
103
107
|
|
|
104
108
|
#pragma clang diagnostic push
|
|
105
109
|
#pragma clang diagnostic ignored "-Wobjc-missing-super-calls"
|
|
@@ -199,36 +203,25 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
199
203
|
}
|
|
200
204
|
return marker;
|
|
201
205
|
}
|
|
206
|
+
// Create Polyline with coordinates
|
|
207
|
+
-(void) fitToCoordinates:(NSArray<AIRMapCoordinate*>*) coordinates edgePadding:(UIEdgeInsets) edgeInsets animated:(Boolean) animated {
|
|
208
|
+
CLLocationCoordinate2D coords[coordinates.count];
|
|
209
|
+
for(int i = 0; i < coordinates.count; i++)
|
|
210
|
+
{
|
|
211
|
+
coords[i] = coordinates[i].coordinate;
|
|
212
|
+
}
|
|
213
|
+
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordinates.count];
|
|
202
214
|
|
|
215
|
+
// Set Map viewport
|
|
216
|
+
|
|
217
|
+
[self setVisibleMapRect:[polyline boundingMapRect] edgePadding:edgeInsets animated:animated];
|
|
218
|
+
}
|
|
203
219
|
- (CGRect) frameForMarker:(AIRMapMarker*) mrkAnn {
|
|
204
220
|
MKAnnotationView* mrkView = [self viewForAnnotation: mrkAnn];
|
|
205
221
|
CGRect mrkFrame = mrkView.frame;
|
|
206
222
|
return mrkFrame;
|
|
207
223
|
}
|
|
208
224
|
|
|
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
225
|
|
|
233
226
|
- (AIRMapMarker*) markerAtPoint:(CGPoint)point {
|
|
234
227
|
AIRMapMarker* mrk = nil;
|
|
@@ -257,16 +250,16 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
257
250
|
// Allow touches to be sent to our calloutview.
|
|
258
251
|
// See this for some discussion of why we need to override this: https://github.com/nfarina/calloutview/pull/9
|
|
259
252
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
|
260
|
-
|
|
253
|
+
|
|
261
254
|
CGPoint touchPoint = [self.calloutView convertPoint:point fromView:self];
|
|
262
255
|
UIView *touchedView = [self.calloutView hitTest:touchPoint withEvent:event];
|
|
263
|
-
|
|
256
|
+
|
|
264
257
|
if (touchedView) {
|
|
265
258
|
UIWindow* win = [[[UIApplication sharedApplication] windows] firstObject];
|
|
266
259
|
AIRMapCalloutSubview* calloutSubview = nil;
|
|
267
260
|
AIRMapCallout* callout = nil;
|
|
268
261
|
AIRMapMarker* marker = nil;
|
|
269
|
-
|
|
262
|
+
|
|
270
263
|
UIView* tmp = touchedView;
|
|
271
264
|
while (tmp && tmp != win && tmp != self.calloutView) {
|
|
272
265
|
if ([tmp respondsToSelector:@selector(onPress)]) {
|
|
@@ -278,7 +271,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
278
271
|
}
|
|
279
272
|
tmp = tmp.superview;
|
|
280
273
|
}
|
|
281
|
-
|
|
274
|
+
|
|
282
275
|
if (callout) {
|
|
283
276
|
marker = [self markerForCallout:callout];
|
|
284
277
|
if (marker) {
|
|
@@ -288,49 +281,49 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
288
281
|
}
|
|
289
282
|
}
|
|
290
283
|
}
|
|
291
|
-
|
|
284
|
+
|
|
292
285
|
return calloutSubview ? calloutSubview : touchedView;
|
|
293
286
|
}
|
|
294
|
-
|
|
287
|
+
|
|
295
288
|
return [super hitTest:point withEvent:event];
|
|
296
289
|
}
|
|
297
290
|
|
|
298
291
|
#pragma mark SMCalloutViewDelegate
|
|
299
292
|
|
|
300
293
|
- (NSTimeInterval)calloutView:(SMCalloutView *)calloutView delayForRepositionWithSize:(CGSize)offset {
|
|
301
|
-
|
|
294
|
+
|
|
302
295
|
// When the callout is being asked to present in a way where it or its target will be partially offscreen, it asks us
|
|
303
296
|
// if we'd like to reposition our surface first so the callout is completely visible. Here we scroll the map into view,
|
|
304
297
|
// but it takes some math because we have to deal in lon/lat instead of the given offset in pixels.
|
|
305
|
-
|
|
298
|
+
|
|
306
299
|
CLLocationCoordinate2D coordinate = self.region.center;
|
|
307
|
-
|
|
300
|
+
|
|
308
301
|
// where's the center coordinate in terms of our view?
|
|
309
302
|
CGPoint center = [self convertCoordinate:coordinate toPointToView:self];
|
|
310
|
-
|
|
303
|
+
|
|
311
304
|
// move it by the requested offset
|
|
312
305
|
center.x -= offset.width;
|
|
313
306
|
center.y -= offset.height;
|
|
314
|
-
|
|
307
|
+
|
|
315
308
|
// and translate it back into map coordinates
|
|
316
309
|
coordinate = [self convertPoint:center toCoordinateFromView:self];
|
|
317
|
-
|
|
310
|
+
|
|
318
311
|
// move the map!
|
|
319
312
|
[self setCenterCoordinate:coordinate animated:YES];
|
|
320
|
-
|
|
313
|
+
|
|
321
314
|
// tell the callout to wait for a while while we scroll (we assume the scroll delay for MKMapView matches UIScrollView)
|
|
322
315
|
return kSMCalloutViewRepositionDelayForUIScrollView;
|
|
323
316
|
}
|
|
324
317
|
|
|
325
|
-
#pragma mark
|
|
318
|
+
#pragma mark RNMapsAirModuleDelegate.h
|
|
326
319
|
|
|
327
320
|
- (NSArray *)getMapBoundaries
|
|
328
321
|
{
|
|
329
322
|
MKMapRect mapRect = self.visibleMapRect;
|
|
330
|
-
|
|
323
|
+
|
|
331
324
|
CLLocationCoordinate2D northEast = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMaxX(mapRect), mapRect.origin.y));
|
|
332
325
|
CLLocationCoordinate2D southWest = MKCoordinateForMapPoint(MKMapPointMake(mapRect.origin.x, MKMapRectGetMaxY(mapRect)));
|
|
333
|
-
|
|
326
|
+
|
|
334
327
|
return @[
|
|
335
328
|
@[
|
|
336
329
|
[NSNumber numberWithDouble:northEast.longitude],
|
|
@@ -342,6 +335,169 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
342
335
|
]
|
|
343
336
|
];
|
|
344
337
|
}
|
|
338
|
+
- (NSDictionary *) getPointForCoordinates:(CLLocationCoordinate2D) location
|
|
339
|
+
{
|
|
340
|
+
CGPoint touchPoint = [self convertCoordinate:location toPointToView:self];
|
|
341
|
+
|
|
342
|
+
return @{
|
|
343
|
+
@"x": @(touchPoint.x),
|
|
344
|
+
@"y": @(touchPoint.y),
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
- (NSDictionary *) getCoordinatesForPoint:(CGPoint)point
|
|
348
|
+
{
|
|
349
|
+
CLLocationCoordinate2D coordinate = [self convertPoint:point toCoordinateFromView:self];
|
|
350
|
+
return @{
|
|
351
|
+
@"latitude": @(coordinate.latitude),
|
|
352
|
+
@"longitude": @(coordinate.longitude),
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
- (NSDictionary*) getMarkersFramesWithOnlyVisible:(BOOL)onlyVisible {
|
|
358
|
+
NSMutableDictionary* markersFrames = [NSMutableDictionary new];
|
|
359
|
+
for (AIRMapMarker* mrkAnn in self.markers) {
|
|
360
|
+
CGRect frame = [self frameForMarker:mrkAnn];
|
|
361
|
+
CGPoint point = [self convertCoordinate:mrkAnn.coordinate toPointToView:self];
|
|
362
|
+
NSDictionary* frameDict = @{
|
|
363
|
+
@"x": @(frame.origin.x),
|
|
364
|
+
@"y": @(frame.origin.y),
|
|
365
|
+
@"width": @(frame.size.width),
|
|
366
|
+
@"height": @(frame.size.height)
|
|
367
|
+
};
|
|
368
|
+
NSDictionary* pointDict = @{
|
|
369
|
+
@"x": @(point.x),
|
|
370
|
+
@"y": @(point.y)
|
|
371
|
+
};
|
|
372
|
+
NSString* k = mrkAnn.identifier;
|
|
373
|
+
BOOL isVisible = CGRectIntersectsRect(self.bounds, frame);
|
|
374
|
+
if (k != nil && (!onlyVisible || isVisible)) {
|
|
375
|
+
[markersFrames setObject:@{ @"frame": frameDict, @"point": pointDict } forKey:k];
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return markersFrames;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
- (NSDictionary *) getCamera {
|
|
382
|
+
MKMapCamera *camera = [self camera];
|
|
383
|
+
return @{
|
|
384
|
+
@"center": @{
|
|
385
|
+
@"latitude": @(camera.centerCoordinate.latitude),
|
|
386
|
+
@"longitude": @(camera.centerCoordinate.longitude),
|
|
387
|
+
},
|
|
388
|
+
@"pitch": @(camera.pitch),
|
|
389
|
+
@"heading": @(camera.heading),
|
|
390
|
+
@"altitude": @(camera.altitude),
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
- (void)takeSnapshotWithConfig:(NSDictionary *)config
|
|
394
|
+
callback:(RCTPromiseResolveBlock) callback
|
|
395
|
+
{
|
|
396
|
+
|
|
397
|
+
MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
|
|
398
|
+
|
|
399
|
+
options.mapType = self.mapType;
|
|
400
|
+
NSNumber *width = config[@"width"];
|
|
401
|
+
NSNumber *height = config[@"height"];
|
|
402
|
+
NSNumber *quality = config[@"quality"];
|
|
403
|
+
NSString*format =config[@"format"];
|
|
404
|
+
NSString*result =config[@"result"];
|
|
405
|
+
MKCoordinateRegion region = [RCTConvert MKCoordinateRegion:config[@"region"]];
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
options.region = (region.center.latitude && region.center.longitude) ? region : self.region;
|
|
409
|
+
options.size = CGSizeMake(
|
|
410
|
+
([width floatValue] == 0) ? self.bounds.size.width : [width floatValue],
|
|
411
|
+
([height floatValue] == 0) ? self.bounds.size.height : [height floatValue]
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
options.scale = [[UIScreen mainScreen] scale];
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
|
|
418
|
+
|
|
419
|
+
[self takeMapSnapshot:snapshotter
|
|
420
|
+
format:format
|
|
421
|
+
quality:[quality floatValue]
|
|
422
|
+
result:result
|
|
423
|
+
callback:callback];
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
#pragma mark Take Snapshot
|
|
427
|
+
- (void)takeMapSnapshot:(MKMapSnapshotter *) snapshotter
|
|
428
|
+
format:(NSString *)format
|
|
429
|
+
quality:(CGFloat) quality
|
|
430
|
+
result:(NSString *)result
|
|
431
|
+
callback:(RCTPromiseResolveBlock) callback {
|
|
432
|
+
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
|
|
433
|
+
NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.%@", timeStamp, format];
|
|
434
|
+
NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent];
|
|
435
|
+
|
|
436
|
+
[snapshotter startWithQueue:dispatch_get_main_queue()
|
|
437
|
+
completionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
|
|
438
|
+
if (error) {
|
|
439
|
+
callback(@[error]);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:nil];
|
|
443
|
+
|
|
444
|
+
UIImage *image = snapshot.image;
|
|
445
|
+
UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
|
|
446
|
+
{
|
|
447
|
+
[image drawAtPoint:CGPointMake(0.0f, 0.0f)];
|
|
448
|
+
|
|
449
|
+
CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
|
|
450
|
+
|
|
451
|
+
for (id <AIRMapSnapshot> overlay in self.overlays) {
|
|
452
|
+
if ([overlay respondsToSelector:@selector(drawToSnapshot:context:)]) {
|
|
453
|
+
[overlay drawToSnapshot:snapshot context:UIGraphicsGetCurrentContext()];
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
for (id <MKAnnotation> annotation in self.annotations) {
|
|
458
|
+
CGPoint point = [snapshot pointForCoordinate:annotation.coordinate];
|
|
459
|
+
|
|
460
|
+
MKAnnotationView* anView = [self viewForAnnotation: annotation];
|
|
461
|
+
|
|
462
|
+
if (anView){
|
|
463
|
+
pin = anView;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (CGRectContainsPoint(rect, point)) {
|
|
467
|
+
point.x = point.x + pin.centerOffset.x - (pin.bounds.size.width / 2.0f);
|
|
468
|
+
point.y = point.y + pin.centerOffset.y - (pin.bounds.size.height / 2.0f);
|
|
469
|
+
if (pin.image) {
|
|
470
|
+
[pin.image drawAtPoint:point];
|
|
471
|
+
} else {
|
|
472
|
+
CGRect pinRect = CGRectMake(point.x, point.y, pin.bounds.size.width, pin.bounds.size.height);
|
|
473
|
+
[pin drawViewHierarchyInRect:pinRect afterScreenUpdates:NO];
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
UIImage *compositeImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
479
|
+
|
|
480
|
+
NSData *data;
|
|
481
|
+
if ([format isEqualToString:@"png"]) {
|
|
482
|
+
data = UIImagePNGRepresentation(compositeImage);
|
|
483
|
+
}
|
|
484
|
+
else if([format isEqualToString:@"jpg"]) {
|
|
485
|
+
data = UIImageJPEGRepresentation(compositeImage, quality);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if ([result isEqualToString:@"file"]) {
|
|
489
|
+
[data writeToFile:filePath atomically:YES];
|
|
490
|
+
callback(filePath);
|
|
491
|
+
}
|
|
492
|
+
else if ([result isEqualToString:@"base64"]) {
|
|
493
|
+
callback([data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
UIGraphicsEndImageContext();
|
|
497
|
+
}];
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
|
|
345
501
|
|
|
346
502
|
- (void)setShowsUserLocation:(BOOL)showsUserLocation
|
|
347
503
|
{
|
|
@@ -380,13 +536,14 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
380
536
|
_userLocationCalloutEnabled = calloutEnabled;
|
|
381
537
|
}
|
|
382
538
|
|
|
383
|
-
- (void)setHandlePanDrag:(BOOL)
|
|
539
|
+
- (void)setHandlePanDrag:(BOOL)handlePanDrag {
|
|
384
540
|
for (UIGestureRecognizer *recognizer in [self gestureRecognizers]) {
|
|
385
541
|
if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
|
|
386
|
-
recognizer.enabled =
|
|
542
|
+
recognizer.enabled = handlePanDrag;
|
|
387
543
|
break;
|
|
388
544
|
}
|
|
389
545
|
}
|
|
546
|
+
_handlePanDrag = handlePanDrag;
|
|
390
547
|
}
|
|
391
548
|
|
|
392
549
|
- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated
|
|
@@ -395,7 +552,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
395
552
|
if (!CLLocationCoordinate2DIsValid(region.center)) {
|
|
396
553
|
return;
|
|
397
554
|
}
|
|
398
|
-
|
|
555
|
+
|
|
399
556
|
// If new span values are nil, use old values instead
|
|
400
557
|
if (!region.span.latitudeDelta) {
|
|
401
558
|
region.span.latitudeDelta = self.region.span.latitudeDelta;
|
|
@@ -403,12 +560,15 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
403
560
|
if (!region.span.longitudeDelta) {
|
|
404
561
|
region.span.longitudeDelta = self.region.span.longitudeDelta;
|
|
405
562
|
}
|
|
406
|
-
|
|
563
|
+
|
|
407
564
|
// Animate/move to new position
|
|
408
565
|
[super setRegion:region animated:animated];
|
|
409
566
|
}
|
|
410
567
|
|
|
411
568
|
- (void)setInitialRegion:(MKCoordinateRegion)initialRegion {
|
|
569
|
+
if (!CLLocationCoordinate2DIsValid(initialRegion.center)) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
412
572
|
if (!_initialRegionSet) {
|
|
413
573
|
_initialRegionSet = YES;
|
|
414
574
|
[self setRegion:initialRegion animated:NO];
|
|
@@ -471,25 +631,25 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
471
631
|
|
|
472
632
|
- (void)setCameraZoomRange:(NSDictionary *)cameraZoomRange {
|
|
473
633
|
if (@available(iOS 13.0, *)) {
|
|
474
|
-
|
|
634
|
+
|
|
475
635
|
if (cameraZoomRange == nil) {
|
|
476
636
|
cameraZoomRange = @{};
|
|
477
637
|
}
|
|
478
|
-
|
|
638
|
+
|
|
479
639
|
NSNumber *minValue = cameraZoomRange[@"minCenterCoordinateDistance"];
|
|
480
640
|
NSNumber *maxValue = cameraZoomRange[@"maxCenterCoordinateDistance"];
|
|
481
|
-
|
|
641
|
+
|
|
482
642
|
if (minValue == nil && maxValue == nil) {
|
|
483
643
|
self.legacyZoomConstraintsEnabled = YES;
|
|
484
|
-
|
|
644
|
+
|
|
485
645
|
MKMapCameraZoomRange *defaultZoomRange = [[MKMapCameraZoomRange alloc] initWithMinCenterCoordinateDistance:MKMapCameraZoomDefault maxCenterCoordinateDistance:MKMapCameraZoomDefault];
|
|
486
646
|
[super setCameraZoomRange:defaultZoomRange animated:NO];
|
|
487
|
-
|
|
647
|
+
|
|
488
648
|
return;
|
|
489
649
|
}
|
|
490
|
-
|
|
650
|
+
|
|
491
651
|
MKMapCameraZoomRange *zoomRange = nil;
|
|
492
|
-
|
|
652
|
+
|
|
493
653
|
if (minValue != nil && maxValue != nil) {
|
|
494
654
|
zoomRange = [[MKMapCameraZoomRange alloc] initWithMinCenterCoordinateDistance:[minValue doubleValue] maxCenterCoordinateDistance:[maxValue doubleValue]];
|
|
495
655
|
} else if (minValue != nil) {
|
|
@@ -497,61 +657,14 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
497
657
|
} else if (maxValue != nil) {
|
|
498
658
|
zoomRange = [[MKMapCameraZoomRange alloc] initWithMaxCenterCoordinateDistance:[maxValue doubleValue]];
|
|
499
659
|
}
|
|
500
|
-
|
|
660
|
+
|
|
501
661
|
BOOL animated = [cameraZoomRange[@"animated"] boolValue];
|
|
502
|
-
|
|
662
|
+
|
|
503
663
|
self.legacyZoomConstraintsEnabled = NO;
|
|
504
664
|
[super setCameraZoomRange:zoomRange animated:animated];
|
|
505
665
|
}
|
|
506
666
|
}
|
|
507
667
|
|
|
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
|
-
}
|
|
533
|
-
|
|
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
668
|
|
|
556
669
|
- (void)setScrollEnabled:(BOOL)scrollEnabled {
|
|
557
670
|
self.shouldScrollEnabled = [NSNumber numberWithBool:scrollEnabled];
|
|
@@ -597,7 +710,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
597
710
|
else {
|
|
598
711
|
self.cacheImageView.image = nil;
|
|
599
712
|
self.cacheImageView.hidden = YES;
|
|
600
|
-
|
|
713
|
+
|
|
601
714
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
602
715
|
self.cacheImageView.image = nil;
|
|
603
716
|
self.cacheImageView.hidden = YES;
|
|
@@ -605,12 +718,12 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
605
718
|
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
|
|
606
719
|
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
|
607
720
|
UIGraphicsEndImageContext();
|
|
608
|
-
|
|
721
|
+
|
|
609
722
|
self.cacheImageView.image = image;
|
|
610
723
|
self.cacheImageView.hidden = NO;
|
|
611
724
|
});
|
|
612
725
|
}
|
|
613
|
-
|
|
726
|
+
|
|
614
727
|
[self updateScrollEnabled];
|
|
615
728
|
[self updateZoomEnabled];
|
|
616
729
|
[self updateLegalLabelInsets];
|
|
@@ -706,50 +819,27 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
706
819
|
- (void)layoutSubviews {
|
|
707
820
|
[super layoutSubviews];
|
|
708
821
|
[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
822
|
}
|
|
733
823
|
|
|
734
824
|
// based on https://medium.com/@dmytrobabych/getting-actual-rotation-and-zoom-level-for-mapkit-mkmapview-e7f03f430aa9
|
|
735
825
|
- (CGFloat)getZoomLevel {
|
|
736
826
|
CGFloat cameraAngle = self.camera.heading;
|
|
737
|
-
|
|
827
|
+
|
|
738
828
|
if (cameraAngle > 270) {
|
|
739
829
|
cameraAngle = 360 - cameraAngle;
|
|
740
830
|
} else if (cameraAngle > 90) {
|
|
741
831
|
cameraAngle = fabs(cameraAngle - 180);
|
|
742
832
|
}
|
|
743
|
-
|
|
833
|
+
|
|
744
834
|
CGFloat angleRad = M_PI * cameraAngle / 180; // map rotation in radians
|
|
745
835
|
CGFloat width = self.frame.size.width;
|
|
746
836
|
CGFloat height = self.frame.size.height;
|
|
747
837
|
CGFloat heightOffset = 20; // the offset (status bar height) which is taken by MapKit into consideration to calculate visible area height
|
|
748
|
-
|
|
838
|
+
|
|
749
839
|
// calculating Longitude span corresponding to normal (non-rotated) width
|
|
750
840
|
CGFloat spanStraight = width * self.region.span.longitudeDelta / (width * cos(angleRad) + (height - heightOffset) * sin(angleRad));
|
|
751
841
|
int normalizingFactor = 512;
|
|
752
|
-
|
|
842
|
+
|
|
753
843
|
return log2(360 * ((width / normalizingFactor) / spanStraight));
|
|
754
844
|
}
|
|
755
845
|
|
|
@@ -350,23 +350,8 @@ RCT_EXPORT_METHOD(fitToCoordinates:(nonnull NSNumber *)reactTag
|
|
|
350
350
|
RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view);
|
|
351
351
|
} else {
|
|
352
352
|
AIRMap *mapView = (AIRMap *)view;
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
CLLocationCoordinate2D coords[coordinates.count];
|
|
356
|
-
for(int i = 0; i < coordinates.count; i++)
|
|
357
|
-
{
|
|
358
|
-
coords[i] = coordinates[i].coordinate;
|
|
359
|
-
}
|
|
360
|
-
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordinates.count];
|
|
361
|
-
|
|
362
|
-
// Set Map viewport
|
|
363
|
-
CGFloat top = [RCTConvert CGFloat:edgePadding[@"top"]];
|
|
364
|
-
CGFloat right = [RCTConvert CGFloat:edgePadding[@"right"]];
|
|
365
|
-
CGFloat bottom = [RCTConvert CGFloat:edgePadding[@"bottom"]];
|
|
366
|
-
CGFloat left = [RCTConvert CGFloat:edgePadding[@"left"]];
|
|
367
|
-
|
|
368
|
-
[mapView setVisibleMapRect:[polyline boundingMapRect] edgePadding:UIEdgeInsetsMake(top, left, bottom, right) animated:animated];
|
|
369
|
-
|
|
353
|
+
UIEdgeInsets edgeInsets = [RCTConvert UIEdgeInsets:edgePadding];
|
|
354
|
+
[mapView fitToCoordinates: coordinates edgePadding:edgeInsets animated:animated];
|
|
370
355
|
}
|
|
371
356
|
}];
|
|
372
357
|
}
|
|
@@ -966,6 +951,8 @@ static int kDragCenterContext;
|
|
|
966
951
|
|
|
967
952
|
mapView.pendingCenter = mapView.region.center;
|
|
968
953
|
mapView.pendingSpan = mapView.region.span;
|
|
954
|
+
// reset original state (checkout setCamera / region animated)
|
|
955
|
+
mapView.ignoreRegionChanges = NO;
|
|
969
956
|
}
|
|
970
957
|
|
|
971
958
|
- (void)mapViewWillStartRenderingMap:(AIRMap *)mapView
|
|
@@ -980,6 +967,7 @@ static int kDragCenterContext;
|
|
|
980
967
|
- (void)mapViewDidFinishRenderingMap:(AIRMap *)mapView fullyRendered:(BOOL)fullyRendered
|
|
981
968
|
{
|
|
982
969
|
[mapView finishLoading];
|
|
970
|
+
mapView.ignoreRegionChanges = NO;
|
|
983
971
|
}
|
|
984
972
|
|
|
985
973
|
#pragma mark Private
|
|
@@ -1175,11 +1163,11 @@ static int kDragCenterContext;
|
|
|
1175
1163
|
|
|
1176
1164
|
CGFloat zoomLevel = [mapView getZoomLevel];
|
|
1177
1165
|
|
|
1178
|
-
if (zoomLevel < mapView.
|
|
1179
|
-
[self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.
|
|
1166
|
+
if (zoomLevel < mapView.minZoom) {
|
|
1167
|
+
[self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.minZoom animated:TRUE mapView:mapView];
|
|
1180
1168
|
}
|
|
1181
|
-
else if (zoomLevel > mapView.
|
|
1182
|
-
[self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.
|
|
1169
|
+
else if (zoomLevel > mapView.maxZoom) {
|
|
1170
|
+
[self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.maxZoom animated:TRUE mapView:mapView];
|
|
1183
1171
|
}
|
|
1184
1172
|
}
|
|
1185
1173
|
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
#import <React/RCTImageLoaderProtocol.h>
|
|
15
15
|
#import <React/RCTUtils.h>
|
|
16
16
|
#import <React/UIView+React.h>
|
|
17
|
+
#import <React/RCTImageLoader.h>
|
|
18
|
+
#import <React/RCTBridge+Private.h>
|
|
17
19
|
|
|
18
20
|
NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
19
21
|
|
|
@@ -68,6 +70,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
68
70
|
self.calloutView = (AIRMapCallout *)subview;
|
|
69
71
|
} else {
|
|
70
72
|
[super insertReactSubview:(UIView *)subview atIndex:atIndex];
|
|
73
|
+
[self addSubview:subview];
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
- (void) setFrame:(CGRect)frame {
|
|
@@ -84,6 +87,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
84
87
|
self.calloutView = nil;
|
|
85
88
|
} else {
|
|
86
89
|
[super removeReactSubview:(UIView *)subview];
|
|
90
|
+
[(UIView *) subview removeFromSuperview];
|
|
87
91
|
}
|
|
88
92
|
}
|
|
89
93
|
|
|
@@ -344,7 +348,8 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
344
348
|
_reloadImageCancellationBlock();
|
|
345
349
|
_reloadImageCancellationBlock = nil;
|
|
346
350
|
}
|
|
347
|
-
|
|
351
|
+
|
|
352
|
+
_reloadImageCancellationBlock = [[[RCTBridge currentBridge] moduleForName:@"ImageLoader"] loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc]
|
|
348
353
|
size:self.bounds.size
|
|
349
354
|
scale:RCTScreenScale()
|
|
350
355
|
clipped:YES
|
|
@@ -352,9 +357,10 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
352
357
|
progressBlock:nil
|
|
353
358
|
partialLoadBlock:nil
|
|
354
359
|
completionBlock:^(NSError *error, UIImage *image) {
|
|
360
|
+
NSLog(@"image load completed");
|
|
355
361
|
if (error) {
|
|
356
362
|
// TODO(lmr): do something with the error?
|
|
357
|
-
NSLog(@"%@", error);
|
|
363
|
+
NSLog(@"failed to load image: %@", error);
|
|
358
364
|
}
|
|
359
365
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
360
366
|
self.image = image;
|