@lugg/maps 1.0.0-beta.2 → 1.0.0-beta.4

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 (112) hide show
  1. package/README.md +3 -0
  2. package/android/src/main/java/com/luggmaps/LuggCircleView.kt +85 -0
  3. package/android/src/main/java/com/luggmaps/LuggCircleViewManager.kt +79 -0
  4. package/android/src/main/java/com/luggmaps/LuggGroundOverlayView.kt +81 -0
  5. package/android/src/main/java/com/luggmaps/LuggGroundOverlayViewManager.kt +82 -0
  6. package/android/src/main/java/com/luggmaps/LuggMapView.kt +9 -0
  7. package/android/src/main/java/com/luggmaps/LuggPackage.kt +4 -1
  8. package/android/src/main/java/com/luggmaps/LuggTileOverlayView.kt +92 -0
  9. package/android/src/main/java/com/luggmaps/LuggTileOverlayViewManager.kt +80 -0
  10. package/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt +290 -1
  11. package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +9 -0
  12. package/android/src/main/java/com/luggmaps/events/CirclePressEvent.kt +12 -0
  13. package/android/src/main/java/com/luggmaps/events/GroundOverlayPressEvent.kt +12 -0
  14. package/android/src/main/java/com/luggmaps/events/TileOverlayPressEvent.kt +12 -0
  15. package/ios/LuggCircleView.h +31 -0
  16. package/ios/LuggCircleView.mm +133 -0
  17. package/ios/LuggGroundOverlayView.h +30 -0
  18. package/ios/LuggGroundOverlayView.mm +125 -0
  19. package/ios/LuggMapView.mm +43 -0
  20. package/ios/LuggTileOverlayView.h +31 -0
  21. package/ios/LuggTileOverlayView.mm +130 -0
  22. package/ios/core/AppleMapProvider.mm +402 -7
  23. package/ios/core/GoogleMapProvider.mm +305 -11
  24. package/ios/core/MapProviderDelegate.h +12 -0
  25. package/ios/events/CirclePressEvent.h +20 -0
  26. package/ios/events/GroundOverlayPressEvent.h +20 -0
  27. package/ios/events/TileOverlayPressEvent.h +20 -0
  28. package/lib/module/components/Circle.js +46 -0
  29. package/lib/module/components/Circle.js.map +1 -0
  30. package/lib/module/components/Circle.types.js +4 -0
  31. package/lib/module/components/Circle.types.js.map +1 -0
  32. package/lib/module/components/Circle.web.js +79 -0
  33. package/lib/module/components/Circle.web.js.map +1 -0
  34. package/lib/module/components/GroundOverlay.js +45 -0
  35. package/lib/module/components/GroundOverlay.js.map +1 -0
  36. package/lib/module/components/GroundOverlay.types.js +4 -0
  37. package/lib/module/components/GroundOverlay.types.js.map +1 -0
  38. package/lib/module/components/GroundOverlay.web.js +77 -0
  39. package/lib/module/components/GroundOverlay.web.js.map +1 -0
  40. package/lib/module/components/Marker.js +5 -1
  41. package/lib/module/components/Marker.js.map +1 -1
  42. package/lib/module/components/TileOverlay.js +44 -0
  43. package/lib/module/components/TileOverlay.js.map +1 -0
  44. package/lib/module/components/TileOverlay.types.js +4 -0
  45. package/lib/module/components/TileOverlay.types.js.map +1 -0
  46. package/lib/module/components/TileOverlay.web.js +69 -0
  47. package/lib/module/components/TileOverlay.web.js.map +1 -0
  48. package/lib/module/components/index.js +3 -0
  49. package/lib/module/components/index.js.map +1 -1
  50. package/lib/module/components/index.web.js +3 -0
  51. package/lib/module/components/index.web.js.map +1 -1
  52. package/lib/module/fabric/LuggCircleViewNativeComponent.ts +25 -0
  53. package/lib/module/fabric/LuggGroundOverlayViewNativeComponent.ts +29 -0
  54. package/lib/module/fabric/LuggTileOverlayViewNativeComponent.ts +30 -0
  55. package/lib/module/index.js +3 -0
  56. package/lib/module/index.js.map +1 -1
  57. package/lib/module/index.web.js +3 -0
  58. package/lib/module/index.web.js.map +1 -1
  59. package/lib/typescript/src/components/Circle.d.ts +10 -0
  60. package/lib/typescript/src/components/Circle.d.ts.map +1 -0
  61. package/lib/typescript/src/components/Circle.types.d.ts +33 -0
  62. package/lib/typescript/src/components/Circle.types.d.ts.map +1 -0
  63. package/lib/typescript/src/components/Circle.web.d.ts +3 -0
  64. package/lib/typescript/src/components/Circle.web.d.ts.map +1 -0
  65. package/lib/typescript/src/components/GroundOverlay.d.ts +10 -0
  66. package/lib/typescript/src/components/GroundOverlay.d.ts.map +1 -0
  67. package/lib/typescript/src/components/GroundOverlay.types.d.ts +35 -0
  68. package/lib/typescript/src/components/GroundOverlay.types.d.ts.map +1 -0
  69. package/lib/typescript/src/components/GroundOverlay.web.d.ts +3 -0
  70. package/lib/typescript/src/components/GroundOverlay.web.d.ts.map +1 -0
  71. package/lib/typescript/src/components/Marker.d.ts.map +1 -1
  72. package/lib/typescript/src/components/Marker.types.d.ts +4 -1
  73. package/lib/typescript/src/components/Marker.types.d.ts.map +1 -1
  74. package/lib/typescript/src/components/TileOverlay.d.ts +10 -0
  75. package/lib/typescript/src/components/TileOverlay.d.ts.map +1 -0
  76. package/lib/typescript/src/components/TileOverlay.types.d.ts +36 -0
  77. package/lib/typescript/src/components/TileOverlay.types.d.ts.map +1 -0
  78. package/lib/typescript/src/components/TileOverlay.web.d.ts +3 -0
  79. package/lib/typescript/src/components/TileOverlay.web.d.ts.map +1 -0
  80. package/lib/typescript/src/components/index.d.ts +6 -0
  81. package/lib/typescript/src/components/index.d.ts.map +1 -1
  82. package/lib/typescript/src/components/index.web.d.ts +6 -0
  83. package/lib/typescript/src/components/index.web.d.ts.map +1 -1
  84. package/lib/typescript/src/fabric/LuggCircleViewNativeComponent.d.ts +18 -0
  85. package/lib/typescript/src/fabric/LuggCircleViewNativeComponent.d.ts.map +1 -0
  86. package/lib/typescript/src/fabric/LuggGroundOverlayViewNativeComponent.d.ts +21 -0
  87. package/lib/typescript/src/fabric/LuggGroundOverlayViewNativeComponent.d.ts.map +1 -0
  88. package/lib/typescript/src/fabric/LuggTileOverlayViewNativeComponent.d.ts +21 -0
  89. package/lib/typescript/src/fabric/LuggTileOverlayViewNativeComponent.d.ts.map +1 -0
  90. package/lib/typescript/src/index.d.ts +6 -0
  91. package/lib/typescript/src/index.d.ts.map +1 -1
  92. package/lib/typescript/src/index.web.d.ts +6 -0
  93. package/lib/typescript/src/index.web.d.ts.map +1 -1
  94. package/package.json +5 -2
  95. package/src/components/Circle.tsx +52 -0
  96. package/src/components/Circle.types.ts +33 -0
  97. package/src/components/Circle.web.tsx +93 -0
  98. package/src/components/GroundOverlay.tsx +47 -0
  99. package/src/components/GroundOverlay.types.ts +36 -0
  100. package/src/components/GroundOverlay.web.tsx +85 -0
  101. package/src/components/Marker.tsx +4 -1
  102. package/src/components/Marker.types.ts +4 -1
  103. package/src/components/TileOverlay.tsx +44 -0
  104. package/src/components/TileOverlay.types.ts +37 -0
  105. package/src/components/TileOverlay.web.tsx +95 -0
  106. package/src/components/index.ts +9 -0
  107. package/src/components/index.web.ts +9 -0
  108. package/src/fabric/LuggCircleViewNativeComponent.ts +25 -0
  109. package/src/fabric/LuggGroundOverlayViewNativeComponent.ts +29 -0
  110. package/src/fabric/LuggTileOverlayViewNativeComponent.ts +30 -0
  111. package/src/index.ts +6 -0
  112. package/src/index.web.ts +12 -0
@@ -1,8 +1,11 @@
1
1
  #import "AppleMapProvider.h"
2
2
  #import "../LuggCalloutView.h"
3
+ #import "../LuggCircleView.h"
4
+ #import "../LuggGroundOverlayView.h"
3
5
  #import "../LuggMarkerView.h"
4
6
  #import "../LuggPolygonView.h"
5
7
  #import "../LuggPolylineView.h"
8
+ #import "../LuggTileOverlayView.h"
6
9
  #import "../extensions/MKMapView+Zoom.h"
7
10
  #import "LuggAnnotationView.h"
8
11
  #import "MKPolylineAnimator.h"
@@ -19,12 +22,90 @@
19
22
  @implementation AppleMarkerAnnotation
20
23
  @end
21
24
 
25
+ @interface GroundImageOverlay : NSObject <MKOverlay>
26
+ @property(nonatomic, assign) CLLocationCoordinate2D coordinate;
27
+ @property(nonatomic, assign) MKMapRect boundingMapRect;
28
+ @property(nonatomic, strong) UIImage *image;
29
+ @property(nonatomic, assign) CGFloat opacity;
30
+ @end
31
+
32
+ @implementation GroundImageOverlay
33
+ @end
34
+
35
+ @interface BoundedTileOverlay : MKTileOverlay
36
+ @property(nonatomic, assign) CLLocationCoordinate2D southwest;
37
+ @property(nonatomic, assign) CLLocationCoordinate2D northeast;
38
+ @end
39
+
40
+ @implementation BoundedTileOverlay
41
+
42
+ static double tileToLat(NSInteger y, NSInteger z) {
43
+ double n = M_PI - 2.0 * M_PI * y / pow(2.0, z);
44
+ return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n)));
45
+ }
46
+
47
+ static double tileToLng(NSInteger x, NSInteger z) {
48
+ return x / pow(2.0, z) * 360.0 - 180.0;
49
+ }
50
+
51
+ - (void)loadTileAtPath:(MKTileOverlayPath)path
52
+ result:(void (^)(NSData *_Nullable, NSError *_Nullable))result {
53
+ double tileSW_lat = tileToLat(path.y + 1, path.z);
54
+ double tileNE_lat = tileToLat(path.y, path.z);
55
+ double tileSW_lng = tileToLng(path.x, path.z);
56
+ double tileNE_lng = tileToLng(path.x + 1, path.z);
57
+
58
+ if (tileNE_lat < self.southwest.latitude ||
59
+ tileSW_lat > self.northeast.latitude ||
60
+ tileNE_lng < self.southwest.longitude ||
61
+ tileSW_lng > self.northeast.longitude) {
62
+ result(nil, nil);
63
+ return;
64
+ }
65
+
66
+ [super loadTileAtPath:path result:result];
67
+ }
68
+
69
+ @end
70
+
71
+ @interface GroundImageOverlayRenderer : MKOverlayRenderer
72
+ @property(nonatomic, strong) UIImage *image;
73
+ @property(nonatomic, assign) CGFloat overlayOpacity;
74
+ @end
75
+
76
+ @implementation GroundImageOverlayRenderer
77
+
78
+ - (void)drawMapRect:(MKMapRect)mapRect
79
+ zoomScale:(MKZoomScale)zoomScale
80
+ inContext:(CGContextRef)context {
81
+ MKMapRect overlayRect = self.overlay.boundingMapRect;
82
+ CGRect drawRect = [self rectForMapRect:overlayRect];
83
+
84
+ CGContextSaveGState(context);
85
+ CGContextSetAlpha(context, self.overlayOpacity);
86
+
87
+ // Flip the context for UIImage drawing
88
+ CGContextTranslateCTM(context, drawRect.origin.x,
89
+ drawRect.origin.y + drawRect.size.height);
90
+ CGContextScaleCTM(context, 1.0, -1.0);
91
+
92
+ CGRect imageRect =
93
+ CGRectMake(0, 0, drawRect.size.width, drawRect.size.height);
94
+ CGContextDrawImage(context, imageRect, self.image.CGImage);
95
+
96
+ CGContextRestoreGState(context);
97
+ }
98
+
99
+ @end
100
+
22
101
  @implementation LuggAppleMapViewContent
23
102
  @end
24
103
 
25
104
  @interface AppleMapProvider () <
26
105
  LuggMarkerViewDelegate, LuggCalloutViewDelegate, LuggPolylineViewDelegate,
27
- LuggPolygonViewDelegate, UIGestureRecognizerDelegate>
106
+ LuggPolygonViewDelegate, LuggCircleViewDelegate,
107
+ LuggGroundOverlayViewDelegate, LuggTileOverlayViewDelegate,
108
+ UIGestureRecognizerDelegate>
28
109
  @end
29
110
 
30
111
  @implementation AppleMapProvider {
@@ -36,6 +117,10 @@
36
117
  double _maxZoom;
37
118
  NSMapTable<id<MKOverlay>, LuggPolylineView *> *_overlayToPolylineMap;
38
119
  NSMapTable<id<MKOverlay>, LuggPolygonView *> *_overlayToPolygonMap;
120
+ NSMapTable<id<MKOverlay>, LuggCircleView *> *_overlayToCircleMap;
121
+ NSMapTable<id<MKOverlay>, LuggGroundOverlayView *>
122
+ *_overlayToGroundOverlayMap;
123
+ NSMapTable<id<MKOverlay>, LuggTileOverlayView *> *_overlayToTileOverlayMap;
39
124
  UITapGestureRecognizer *_tapGesture;
40
125
  UILongPressGestureRecognizer *_longPressGesture;
41
126
  LuggMarkerView *_activeNonBubbledMarker;
@@ -54,6 +139,9 @@
54
139
  if (self = [super init]) {
55
140
  _overlayToPolylineMap = [NSMapTable strongToWeakObjectsMapTable];
56
141
  _overlayToPolygonMap = [NSMapTable strongToWeakObjectsMapTable];
142
+ _overlayToCircleMap = [NSMapTable strongToWeakObjectsMapTable];
143
+ _overlayToGroundOverlayMap = [NSMapTable strongToWeakObjectsMapTable];
144
+ _overlayToTileOverlayMap = [NSMapTable strongToWeakObjectsMapTable];
57
145
  }
58
146
  return self;
59
147
  }
@@ -315,6 +403,55 @@
315
403
  return nil;
316
404
  }
317
405
 
406
+ - (LuggCircleView *)hitTestCircleAtPoint:(CGPoint)point {
407
+ CLLocationCoordinate2D tapCoordinate = [_mapView convertPoint:point
408
+ toCoordinateFromView:_mapView];
409
+ CLLocation *tapLocation =
410
+ [[CLLocation alloc] initWithLatitude:tapCoordinate.latitude
411
+ longitude:tapCoordinate.longitude];
412
+
413
+ NSArray<id<MKOverlay>> *overlays = _mapView.overlays;
414
+ for (NSInteger i = overlays.count - 1; i >= 0; i--) {
415
+ id<MKOverlay> overlay = overlays[i];
416
+ if (![overlay isKindOfClass:[MKCircle class]])
417
+ continue;
418
+
419
+ LuggCircleView *circleView = [_overlayToCircleMap objectForKey:overlay];
420
+ if (!circleView || !circleView.tappable)
421
+ continue;
422
+
423
+ CLLocation *center =
424
+ [[CLLocation alloc] initWithLatitude:circleView.center.latitude
425
+ longitude:circleView.center.longitude];
426
+ CLLocationDistance distance = [tapLocation distanceFromLocation:center];
427
+ if (distance <= circleView.radius)
428
+ return circleView;
429
+ }
430
+ return nil;
431
+ }
432
+
433
+ - (LuggGroundOverlayView *)hitTestGroundOverlayAtPoint:(CGPoint)point {
434
+ CLLocationCoordinate2D tapCoordinate = [_mapView convertPoint:point
435
+ toCoordinateFromView:_mapView];
436
+
437
+ NSArray<id<MKOverlay>> *overlays = _mapView.overlays;
438
+ for (NSInteger i = overlays.count - 1; i >= 0; i--) {
439
+ id<MKOverlay> overlay = overlays[i];
440
+ if (![overlay isKindOfClass:[GroundImageOverlay class]])
441
+ continue;
442
+
443
+ LuggGroundOverlayView *view =
444
+ [_overlayToGroundOverlayMap objectForKey:overlay];
445
+ if (!view || !view.tappable)
446
+ continue;
447
+
448
+ MKMapPoint mapPoint = MKMapPointForCoordinate(tapCoordinate);
449
+ if (MKMapRectContainsPoint(overlay.boundingMapRect, mapPoint))
450
+ return view;
451
+ }
452
+ return nil;
453
+ }
454
+
318
455
  - (BOOL)hitTestAnnotationAtPoint:(CGPoint)point {
319
456
  for (id<MKAnnotation> annotation in _mapView.annotations) {
320
457
  MKAnnotationView *view = [_mapView viewForAnnotation:annotation];
@@ -349,6 +486,19 @@
349
486
  if ([self hitTestAnnotationAtPoint:point])
350
487
  return;
351
488
 
489
+ LuggGroundOverlayView *groundOverlayView =
490
+ [self hitTestGroundOverlayAtPoint:point];
491
+ if (groundOverlayView) {
492
+ [groundOverlayView emitPressEvent];
493
+ return;
494
+ }
495
+
496
+ LuggCircleView *circleView = [self hitTestCircleAtPoint:point];
497
+ if (circleView) {
498
+ [circleView emitPressEvent];
499
+ return;
500
+ }
501
+
352
502
  LuggPolygonView *polygonView = [self hitTestPolygonAtPoint:point];
353
503
  if (polygonView) {
354
504
  [polygonView emitPressEvent];
@@ -526,6 +676,37 @@
526
676
  return renderer;
527
677
  }
528
678
 
679
+ if ([overlay isKindOfClass:[MKCircle class]]) {
680
+ LuggCircleView *circleView = [_overlayToCircleMap objectForKey:overlay];
681
+ MKCircle *circle = (MKCircle *)overlay;
682
+
683
+ MKCircleRenderer *renderer =
684
+ [[MKCircleRenderer alloc] initWithCircle:circle];
685
+ if (circleView) {
686
+ renderer.fillColor = circleView.fillColor;
687
+ renderer.strokeColor = circleView.strokeColor;
688
+ renderer.lineWidth = circleView.strokeWidth;
689
+ circleView.renderer = renderer;
690
+ }
691
+ return renderer;
692
+ }
693
+
694
+ if ([overlay isKindOfClass:[GroundImageOverlay class]]) {
695
+ GroundImageOverlay *groundOverlay = (GroundImageOverlay *)overlay;
696
+ GroundImageOverlayRenderer *renderer =
697
+ [[GroundImageOverlayRenderer alloc] initWithOverlay:overlay];
698
+ renderer.image = groundOverlay.image;
699
+ renderer.overlayOpacity = groundOverlay.opacity;
700
+ return renderer;
701
+ }
702
+
703
+ if ([overlay isKindOfClass:[MKTileOverlay class]]) {
704
+ MKTileOverlay *tileOverlay = (MKTileOverlay *)overlay;
705
+ MKTileOverlayRenderer *renderer =
706
+ [[MKTileOverlayRenderer alloc] initWithTileOverlay:tileOverlay];
707
+ return renderer;
708
+ }
709
+
529
710
  return nil;
530
711
  }
531
712
 
@@ -587,10 +768,7 @@
587
768
  }
588
769
 
589
770
  _activeNonBubbledMarker = markerView;
590
- dispatch_async(dispatch_get_main_queue(), ^{
591
- [self positionNonBubbledCallout];
592
- contentView.hidden = NO;
593
- });
771
+ [self positionNonBubbledCallout];
594
772
  }
595
773
 
596
774
  - (void)calloutViewDidUpdate:(LuggCalloutView *)calloutView {
@@ -616,8 +794,7 @@
616
794
  if (annotationView && contentView.superview == annotationView) {
617
795
  CGPoint center = CGPointMake(annotationView.bounds.size.width / 2.0 +
618
796
  contentSize.width * (0.5 - anchor.x),
619
- annotationView.bounds.size.height / 2.0 +
620
- contentSize.height * (0.5 - anchor.y));
797
+ contentSize.height * (0.5 - anchor.y));
621
798
  contentView.center = center;
622
799
  } else {
623
800
  CGPoint point =
@@ -627,6 +804,8 @@
627
804
  CGPointMake(point.x + contentSize.width * (0.5 - anchor.x),
628
805
  point.y + contentSize.height * (0.5 - anchor.y));
629
806
  }
807
+
808
+ contentView.hidden = NO;
630
809
  }
631
810
 
632
811
  - (void)dismissNonBubbledCallout {
@@ -766,6 +945,24 @@
766
945
  [self syncPolygonView:polygonView];
767
946
  }
768
947
 
948
+ #pragma mark - CircleViewDelegate
949
+
950
+ - (void)circleViewDidUpdate:(LuggCircleView *)circleView {
951
+ [self syncCircleView:circleView];
952
+ }
953
+
954
+ #pragma mark - GroundOverlayViewDelegate
955
+
956
+ - (void)groundOverlayViewDidUpdate:(LuggGroundOverlayView *)groundOverlayView {
957
+ [self syncGroundOverlayView:groundOverlayView];
958
+ }
959
+
960
+ #pragma mark - TileOverlayViewDelegate
961
+
962
+ - (void)tileOverlayViewDidUpdate:(LuggTileOverlayView *)tileOverlayView {
963
+ [self syncTileOverlayView:tileOverlayView];
964
+ }
965
+
769
966
  #pragma mark - Marker Management
770
967
 
771
968
  - (void)addMarkerView:(LuggMarkerView *)markerView {
@@ -1089,6 +1286,196 @@
1089
1286
  return [interiorPolygons copy];
1090
1287
  }
1091
1288
 
1289
+ #pragma mark - Circle Management
1290
+
1291
+ - (void)addCircleView:(LuggCircleView *)circleView {
1292
+ circleView.delegate = self;
1293
+ [self addCircleOverlayToMap:circleView];
1294
+ }
1295
+
1296
+ - (void)removeCircleView:(LuggCircleView *)circleView {
1297
+ circleView.delegate = nil;
1298
+ MKCircle *circle = (MKCircle *)circleView.circle;
1299
+ if (circle) {
1300
+ [_overlayToCircleMap removeObjectForKey:circle];
1301
+ [_mapView removeOverlay:circle];
1302
+ circleView.circle = nil;
1303
+ }
1304
+ }
1305
+
1306
+ - (void)syncCircleView:(LuggCircleView *)circleView {
1307
+ if (!_mapView)
1308
+ return;
1309
+
1310
+ MKCircle *oldCircle = (MKCircle *)circleView.circle;
1311
+
1312
+ MKCircle *newCircle = [MKCircle circleWithCenterCoordinate:circleView.center
1313
+ radius:circleView.radius];
1314
+
1315
+ circleView.circle = newCircle;
1316
+ [_overlayToCircleMap setObject:circleView forKey:newCircle];
1317
+
1318
+ MKCircleRenderer *renderer = (MKCircleRenderer *)circleView.renderer;
1319
+ if (renderer && oldCircle) {
1320
+ [_overlayToCircleMap removeObjectForKey:oldCircle];
1321
+ [_mapView removeOverlay:oldCircle];
1322
+ [self insertOverlay:newCircle withZIndex:circleView.zIndex];
1323
+ circleView.renderer = nil;
1324
+ return;
1325
+ }
1326
+
1327
+ if (oldCircle) {
1328
+ [_overlayToCircleMap removeObjectForKey:oldCircle];
1329
+ [_mapView removeOverlay:oldCircle];
1330
+ }
1331
+ [self insertOverlay:newCircle withZIndex:circleView.zIndex];
1332
+ }
1333
+
1334
+ - (void)addCircleOverlayToMap:(LuggCircleView *)circleView {
1335
+ if (!_mapView)
1336
+ return;
1337
+
1338
+ MKCircle *circle = [MKCircle circleWithCenterCoordinate:circleView.center
1339
+ radius:circleView.radius];
1340
+
1341
+ circleView.circle = circle;
1342
+ [_overlayToCircleMap setObject:circleView forKey:circle];
1343
+ [self insertOverlay:circle withZIndex:circleView.zIndex];
1344
+ }
1345
+
1346
+ #pragma mark - Ground Overlay Management
1347
+
1348
+ - (void)addGroundOverlayView:(LuggGroundOverlayView *)groundOverlayView {
1349
+ groundOverlayView.delegate = self;
1350
+ [self syncGroundOverlayView:groundOverlayView];
1351
+ }
1352
+
1353
+ - (void)removeGroundOverlayView:(LuggGroundOverlayView *)groundOverlayView {
1354
+ groundOverlayView.delegate = nil;
1355
+ GroundImageOverlay *overlay = (GroundImageOverlay *)groundOverlayView.overlay;
1356
+ if (overlay) {
1357
+ [_overlayToGroundOverlayMap removeObjectForKey:overlay];
1358
+ [_mapView removeOverlay:overlay];
1359
+ groundOverlayView.overlay = nil;
1360
+ }
1361
+ }
1362
+
1363
+ - (void)syncGroundOverlayView:(LuggGroundOverlayView *)groundOverlayView {
1364
+ if (!_mapView)
1365
+ return;
1366
+
1367
+ NSString *imageUri = groundOverlayView.imageUri;
1368
+ if (imageUri.length == 0)
1369
+ return;
1370
+
1371
+ // Remove old overlay
1372
+ GroundImageOverlay *oldOverlay =
1373
+ (GroundImageOverlay *)groundOverlayView.overlay;
1374
+ if (oldOverlay) {
1375
+ [_overlayToGroundOverlayMap removeObjectForKey:oldOverlay];
1376
+ [_mapView removeOverlay:oldOverlay];
1377
+ groundOverlayView.overlay = nil;
1378
+ }
1379
+
1380
+ NSURL *url = [NSURL URLWithString:imageUri];
1381
+ if (!url)
1382
+ return;
1383
+
1384
+ __weak __typeof(self) weakSelf = self;
1385
+ __weak LuggGroundOverlayView *weakOverlayView = groundOverlayView;
1386
+ dispatch_async(
1387
+ dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
1388
+ NSData *data = [NSData dataWithContentsOfURL:url];
1389
+ UIImage *image = data ? [UIImage imageWithData:data] : nil;
1390
+ dispatch_async(dispatch_get_main_queue(), ^{
1391
+ [weakSelf addGroundOverlayToMap:weakOverlayView image:image];
1392
+ });
1393
+ });
1394
+ }
1395
+
1396
+ - (void)addGroundOverlayToMap:(LuggGroundOverlayView *)groundOverlayView
1397
+ image:(UIImage *)image {
1398
+ if (!_mapView || !groundOverlayView || !image)
1399
+ return;
1400
+
1401
+ MKMapPoint sw = MKMapPointForCoordinate(groundOverlayView.southwest);
1402
+ MKMapPoint ne = MKMapPointForCoordinate(groundOverlayView.northeast);
1403
+
1404
+ MKMapRect mapRect = MKMapRectMake(MIN(sw.x, ne.x), MIN(sw.y, ne.y),
1405
+ fabs(ne.x - sw.x), fabs(ne.y - sw.y));
1406
+
1407
+ CLLocationCoordinate2D center =
1408
+ CLLocationCoordinate2DMake((groundOverlayView.northeast.latitude +
1409
+ groundOverlayView.southwest.latitude) /
1410
+ 2.0,
1411
+ (groundOverlayView.northeast.longitude +
1412
+ groundOverlayView.southwest.longitude) /
1413
+ 2.0);
1414
+
1415
+ GroundImageOverlay *overlay = [[GroundImageOverlay alloc] init];
1416
+ overlay.coordinate = center;
1417
+ overlay.boundingMapRect = mapRect;
1418
+ overlay.image = image;
1419
+ overlay.opacity = groundOverlayView.opacity;
1420
+
1421
+ groundOverlayView.overlay = overlay;
1422
+ [_overlayToGroundOverlayMap setObject:groundOverlayView forKey:overlay];
1423
+ [self insertOverlay:overlay withZIndex:groundOverlayView.zIndex];
1424
+ }
1425
+
1426
+ #pragma mark - Tile Overlay Management
1427
+
1428
+ - (void)addTileOverlayView:(LuggTileOverlayView *)tileOverlayView {
1429
+ tileOverlayView.delegate = self;
1430
+ [self syncTileOverlayView:tileOverlayView];
1431
+ }
1432
+
1433
+ - (void)removeTileOverlayView:(LuggTileOverlayView *)tileOverlayView {
1434
+ tileOverlayView.delegate = nil;
1435
+ MKTileOverlay *overlay = (MKTileOverlay *)tileOverlayView.overlay;
1436
+ if (overlay) {
1437
+ [_overlayToTileOverlayMap removeObjectForKey:overlay];
1438
+ [_mapView removeOverlay:overlay];
1439
+ tileOverlayView.overlay = nil;
1440
+ }
1441
+ }
1442
+
1443
+ - (void)syncTileOverlayView:(LuggTileOverlayView *)tileOverlayView {
1444
+ if (!_mapView)
1445
+ return;
1446
+
1447
+ NSString *urlTemplate = tileOverlayView.urlTemplate;
1448
+ if (urlTemplate.length == 0)
1449
+ return;
1450
+
1451
+ // Remove old overlay
1452
+ MKTileOverlay *oldOverlay = (MKTileOverlay *)tileOverlayView.overlay;
1453
+ if (oldOverlay) {
1454
+ [_overlayToTileOverlayMap removeObjectForKey:oldOverlay];
1455
+ [_mapView removeOverlay:oldOverlay];
1456
+ tileOverlayView.overlay = nil;
1457
+ }
1458
+
1459
+ MKTileOverlay *tileOverlay;
1460
+ if (tileOverlayView.hasBounds) {
1461
+ BoundedTileOverlay *bounded =
1462
+ [[BoundedTileOverlay alloc] initWithURLTemplate:urlTemplate];
1463
+ bounded.southwest = tileOverlayView.southwest;
1464
+ bounded.northeast = tileOverlayView.northeast;
1465
+ tileOverlay = bounded;
1466
+ } else {
1467
+ tileOverlay = [[MKTileOverlay alloc] initWithURLTemplate:urlTemplate];
1468
+ }
1469
+
1470
+ tileOverlay.tileSize =
1471
+ CGSizeMake(tileOverlayView.tileSize, tileOverlayView.tileSize);
1472
+ tileOverlay.canReplaceMapContent = NO;
1473
+
1474
+ tileOverlayView.overlay = tileOverlay;
1475
+ [_overlayToTileOverlayMap setObject:tileOverlayView forKey:tileOverlay];
1476
+ [_mapView addOverlay:tileOverlay level:MKOverlayLevelAboveRoads];
1477
+ }
1478
+
1092
1479
  - (void)insertOverlay:(id<MKOverlay>)overlay withZIndex:(NSInteger)zIndex {
1093
1480
  if (zIndex == 0) {
1094
1481
  [_mapView addOverlay:overlay];
@@ -1104,10 +1491,18 @@
1104
1491
  [_overlayToPolylineMap objectForKey:overlays[i]];
1105
1492
  LuggPolygonView *existingPolygonView =
1106
1493
  [_overlayToPolygonMap objectForKey:overlays[i]];
1494
+ LuggCircleView *existingCircleView =
1495
+ [_overlayToCircleMap objectForKey:overlays[i]];
1496
+ LuggGroundOverlayView *existingGroundOverlayView =
1497
+ [_overlayToGroundOverlayMap objectForKey:overlays[i]];
1107
1498
  if (existingPolylineView) {
1108
1499
  existingZIndex = existingPolylineView.zIndex;
1109
1500
  } else if (existingPolygonView) {
1110
1501
  existingZIndex = existingPolygonView.zIndex;
1502
+ } else if (existingCircleView) {
1503
+ existingZIndex = existingCircleView.zIndex;
1504
+ } else if (existingGroundOverlayView) {
1505
+ existingZIndex = existingGroundOverlayView.zIndex;
1111
1506
  } else {
1112
1507
  continue;
1113
1508
  }