@lugg/maps 1.0.0-beta.0 → 1.0.0-beta.10

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 (186) hide show
  1. package/README.md +4 -1
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/luggmaps/LuggCalloutView.kt +79 -0
  4. package/android/src/main/java/com/luggmaps/LuggCalloutViewManager.kt +39 -0
  5. package/android/src/main/java/com/luggmaps/LuggCircleView.kt +85 -0
  6. package/android/src/main/java/com/luggmaps/LuggCircleViewManager.kt +79 -0
  7. package/android/src/main/java/com/luggmaps/LuggGroundOverlayView.kt +81 -0
  8. package/android/src/main/java/com/luggmaps/LuggGroundOverlayViewManager.kt +82 -0
  9. package/android/src/main/java/com/luggmaps/LuggMapView.kt +49 -0
  10. package/android/src/main/java/com/luggmaps/LuggMapViewManager.kt +31 -0
  11. package/android/src/main/java/com/luggmaps/LuggMapWrapperView.kt +0 -11
  12. package/android/src/main/java/com/luggmaps/LuggMarkerView.kt +99 -51
  13. package/android/src/main/java/com/luggmaps/LuggMarkerViewManager.kt +13 -0
  14. package/android/src/main/java/com/luggmaps/LuggPackage.kt +11 -1
  15. package/android/src/main/java/com/luggmaps/LuggPolylineView.kt +1 -22
  16. package/android/src/main/java/com/luggmaps/LuggTileOverlayView.kt +92 -0
  17. package/android/src/main/java/com/luggmaps/LuggTileOverlayViewManager.kt +80 -0
  18. package/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt +628 -18
  19. package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +14 -0
  20. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +12 -7
  21. package/android/src/main/java/com/luggmaps/events/CirclePressEvent.kt +12 -0
  22. package/android/src/main/java/com/luggmaps/events/GroundOverlayPressEvent.kt +12 -0
  23. package/android/src/main/java/com/luggmaps/events/TileOverlayPressEvent.kt +12 -0
  24. package/android/src/main/java/com/luggmaps/extensions/ViewExtensions.kt +11 -0
  25. package/ios/LuggCalloutView.h +23 -0
  26. package/ios/LuggCalloutView.mm +155 -0
  27. package/ios/LuggCircleView.h +31 -0
  28. package/ios/LuggCircleView.mm +133 -0
  29. package/ios/LuggGroundOverlayView.h +30 -0
  30. package/ios/LuggGroundOverlayView.mm +125 -0
  31. package/ios/LuggMapView.mm +84 -2
  32. package/ios/LuggMarkerView.h +5 -0
  33. package/ios/LuggMarkerView.mm +40 -2
  34. package/ios/LuggTileOverlayView.h +31 -0
  35. package/ios/LuggTileOverlayView.mm +130 -0
  36. package/ios/core/AppleMapProvider.mm +838 -34
  37. package/ios/core/GMSPolylineAnimator.m +6 -3
  38. package/ios/core/GoogleMapProvider.mm +506 -19
  39. package/ios/core/LuggAnnotationView.h +12 -0
  40. package/ios/core/LuggAnnotationView.mm +55 -0
  41. package/ios/core/MapProviderDelegate.h +20 -1
  42. package/ios/events/CirclePressEvent.h +20 -0
  43. package/ios/events/GroundOverlayPressEvent.h +20 -0
  44. package/ios/events/TileOverlayPressEvent.h +20 -0
  45. package/lib/module/MapProvider.web.js +7 -2
  46. package/lib/module/MapProvider.web.js.map +1 -1
  47. package/lib/module/MapView.js +12 -1
  48. package/lib/module/MapView.js.map +1 -1
  49. package/lib/module/MapView.web.js +36 -20
  50. package/lib/module/MapView.web.js.map +1 -1
  51. package/lib/module/components/Circle.js +46 -0
  52. package/lib/module/components/Circle.js.map +1 -0
  53. package/lib/module/components/Circle.types.js +4 -0
  54. package/lib/module/components/Circle.types.js.map +1 -0
  55. package/lib/module/components/Circle.web.js +79 -0
  56. package/lib/module/components/Circle.web.js.map +1 -0
  57. package/lib/module/components/GeoJson.js +3 -3
  58. package/lib/module/components/GeoJson.js.map +1 -1
  59. package/lib/module/components/GroundOverlay.js +45 -0
  60. package/lib/module/components/GroundOverlay.js.map +1 -0
  61. package/lib/module/components/GroundOverlay.types.js +4 -0
  62. package/lib/module/components/GroundOverlay.types.js.map +1 -0
  63. package/lib/module/components/GroundOverlay.web.js +77 -0
  64. package/lib/module/components/GroundOverlay.web.js.map +1 -0
  65. package/lib/module/components/Marker.js +41 -6
  66. package/lib/module/components/Marker.js.map +1 -1
  67. package/lib/module/components/Marker.web.js +103 -26
  68. package/lib/module/components/Marker.web.js.map +1 -1
  69. package/lib/module/components/Polygon.web.js +3 -3
  70. package/lib/module/components/Polygon.web.js.map +1 -1
  71. package/lib/module/components/Polyline.web.js +6 -12
  72. package/lib/module/components/Polyline.web.js.map +1 -1
  73. package/lib/module/components/TileOverlay.js +44 -0
  74. package/lib/module/components/TileOverlay.js.map +1 -0
  75. package/lib/module/components/TileOverlay.types.js +4 -0
  76. package/lib/module/components/TileOverlay.types.js.map +1 -0
  77. package/lib/module/components/TileOverlay.web.js +69 -0
  78. package/lib/module/components/TileOverlay.web.js.map +1 -0
  79. package/lib/module/components/index.js +3 -0
  80. package/lib/module/components/index.js.map +1 -1
  81. package/lib/module/components/index.web.js +3 -0
  82. package/lib/module/components/index.web.js.map +1 -1
  83. package/lib/module/fabric/LuggCalloutViewNativeComponent.ts +20 -0
  84. package/lib/module/fabric/LuggCircleViewNativeComponent.ts +25 -0
  85. package/lib/module/fabric/LuggGroundOverlayViewNativeComponent.ts +29 -0
  86. package/lib/module/fabric/LuggMapViewNativeComponent.ts +13 -5
  87. package/lib/module/fabric/LuggMarkerViewNativeComponent.ts +14 -2
  88. package/lib/module/fabric/LuggTileOverlayViewNativeComponent.ts +30 -0
  89. package/lib/module/index.js +3 -0
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/module/index.web.js +3 -0
  92. package/lib/module/index.web.js.map +1 -1
  93. package/lib/typescript/src/MapProvider.web.d.ts +9 -2
  94. package/lib/typescript/src/MapProvider.web.d.ts.map +1 -1
  95. package/lib/typescript/src/MapView.d.ts +1 -1
  96. package/lib/typescript/src/MapView.d.ts.map +1 -1
  97. package/lib/typescript/src/MapView.types.d.ts +36 -1
  98. package/lib/typescript/src/MapView.types.d.ts.map +1 -1
  99. package/lib/typescript/src/MapView.web.d.ts +1 -1
  100. package/lib/typescript/src/MapView.web.d.ts.map +1 -1
  101. package/lib/typescript/src/components/Circle.d.ts +10 -0
  102. package/lib/typescript/src/components/Circle.d.ts.map +1 -0
  103. package/lib/typescript/src/components/Circle.types.d.ts +33 -0
  104. package/lib/typescript/src/components/Circle.types.d.ts.map +1 -0
  105. package/lib/typescript/src/components/Circle.web.d.ts +3 -0
  106. package/lib/typescript/src/components/Circle.web.d.ts.map +1 -0
  107. package/lib/typescript/src/components/GeoJson.d.ts +2 -1
  108. package/lib/typescript/src/components/GeoJson.d.ts.map +1 -1
  109. package/lib/typescript/src/components/GeoJson.types.d.ts +11 -1
  110. package/lib/typescript/src/components/GeoJson.types.d.ts.map +1 -1
  111. package/lib/typescript/src/components/GroundOverlay.d.ts +10 -0
  112. package/lib/typescript/src/components/GroundOverlay.d.ts.map +1 -0
  113. package/lib/typescript/src/components/GroundOverlay.types.d.ts +35 -0
  114. package/lib/typescript/src/components/GroundOverlay.types.d.ts.map +1 -0
  115. package/lib/typescript/src/components/GroundOverlay.web.d.ts +3 -0
  116. package/lib/typescript/src/components/GroundOverlay.web.d.ts.map +1 -0
  117. package/lib/typescript/src/components/Marker.d.ts +6 -3
  118. package/lib/typescript/src/components/Marker.d.ts.map +1 -1
  119. package/lib/typescript/src/components/Marker.types.d.ts +40 -2
  120. package/lib/typescript/src/components/Marker.types.d.ts.map +1 -1
  121. package/lib/typescript/src/components/Marker.web.d.ts +3 -2
  122. package/lib/typescript/src/components/Marker.web.d.ts.map +1 -1
  123. package/lib/typescript/src/components/Polygon.web.d.ts +1 -1
  124. package/lib/typescript/src/components/Polygon.web.d.ts.map +1 -1
  125. package/lib/typescript/src/components/Polyline.web.d.ts +1 -1
  126. package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -1
  127. package/lib/typescript/src/components/TileOverlay.d.ts +10 -0
  128. package/lib/typescript/src/components/TileOverlay.d.ts.map +1 -0
  129. package/lib/typescript/src/components/TileOverlay.types.d.ts +36 -0
  130. package/lib/typescript/src/components/TileOverlay.types.d.ts.map +1 -0
  131. package/lib/typescript/src/components/TileOverlay.web.d.ts +3 -0
  132. package/lib/typescript/src/components/TileOverlay.web.d.ts.map +1 -0
  133. package/lib/typescript/src/components/index.d.ts +7 -1
  134. package/lib/typescript/src/components/index.d.ts.map +1 -1
  135. package/lib/typescript/src/components/index.web.d.ts +7 -1
  136. package/lib/typescript/src/components/index.web.d.ts.map +1 -1
  137. package/lib/typescript/src/fabric/LuggCalloutViewNativeComponent.d.ts +13 -0
  138. package/lib/typescript/src/fabric/LuggCalloutViewNativeComponent.d.ts.map +1 -0
  139. package/lib/typescript/src/fabric/LuggCircleViewNativeComponent.d.ts +18 -0
  140. package/lib/typescript/src/fabric/LuggCircleViewNativeComponent.d.ts.map +1 -0
  141. package/lib/typescript/src/fabric/LuggGroundOverlayViewNativeComponent.d.ts +21 -0
  142. package/lib/typescript/src/fabric/LuggGroundOverlayViewNativeComponent.d.ts.map +1 -0
  143. package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts +10 -5
  144. package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -1
  145. package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts +8 -1
  146. package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts.map +1 -1
  147. package/lib/typescript/src/fabric/LuggTileOverlayViewNativeComponent.d.ts +21 -0
  148. package/lib/typescript/src/fabric/LuggTileOverlayViewNativeComponent.d.ts.map +1 -0
  149. package/lib/typescript/src/index.d.ts +10 -4
  150. package/lib/typescript/src/index.d.ts.map +1 -1
  151. package/lib/typescript/src/index.web.d.ts +9 -3
  152. package/lib/typescript/src/index.web.d.ts.map +1 -1
  153. package/lib/typescript/src/types.d.ts +0 -4
  154. package/lib/typescript/src/types.d.ts.map +1 -1
  155. package/package.json +6 -2
  156. package/src/MapProvider.web.tsx +15 -3
  157. package/src/MapView.tsx +12 -1
  158. package/src/MapView.types.ts +118 -1
  159. package/src/MapView.web.tsx +379 -322
  160. package/src/components/Circle.tsx +52 -0
  161. package/src/components/Circle.types.ts +33 -0
  162. package/src/components/Circle.web.tsx +95 -0
  163. package/src/components/GeoJson.tsx +3 -3
  164. package/src/components/GeoJson.types.ts +12 -1
  165. package/src/components/GroundOverlay.tsx +47 -0
  166. package/src/components/GroundOverlay.types.ts +36 -0
  167. package/src/components/GroundOverlay.web.tsx +81 -0
  168. package/src/components/Marker.tsx +59 -5
  169. package/src/components/Marker.types.ts +42 -2
  170. package/src/components/Marker.web.tsx +235 -99
  171. package/src/components/Polygon.web.tsx +93 -89
  172. package/src/components/Polyline.web.tsx +235 -235
  173. package/src/components/TileOverlay.tsx +44 -0
  174. package/src/components/TileOverlay.types.ts +37 -0
  175. package/src/components/TileOverlay.web.tsx +97 -0
  176. package/src/components/index.ts +11 -0
  177. package/src/components/index.web.ts +10 -1
  178. package/src/fabric/LuggCalloutViewNativeComponent.ts +20 -0
  179. package/src/fabric/LuggCircleViewNativeComponent.ts +25 -0
  180. package/src/fabric/LuggGroundOverlayViewNativeComponent.ts +29 -0
  181. package/src/fabric/LuggMapViewNativeComponent.ts +13 -5
  182. package/src/fabric/LuggMarkerViewNativeComponent.ts +14 -2
  183. package/src/fabric/LuggTileOverlayViewNativeComponent.ts +30 -0
  184. package/src/index.ts +14 -1
  185. package/src/index.web.ts +17 -1
  186. package/src/types.ts +0 -5
@@ -2,6 +2,7 @@
2
2
  #import <QuartzCore/QuartzCore.h>
3
3
 
4
4
  static const NSUInteger kMaxAnimationSpans = 16;
5
+ static const NSUInteger kMaxGradientSpans = 512;
5
6
 
6
7
  @interface GMSDisplayLinkProxy : NSObject
7
8
  @property(nonatomic, weak) id target;
@@ -272,12 +273,14 @@ static const NSUInteger kMaxAnimationSpans = 16;
272
273
  - (NSArray<GMSStyleSpan *> *)createGradientSpans {
273
274
  NSMutableArray<GMSStyleSpan *> *spans = [NSMutableArray array];
274
275
  NSUInteger segmentCount = self.coordinates.count - 1;
276
+ NSUInteger spanCount = MIN(segmentCount, kMaxGradientSpans);
277
+ double segmentsPerSpan = (double)segmentCount / spanCount;
275
278
 
276
- for (NSUInteger i = 0; i < segmentCount; i++) {
277
- CGFloat position = (CGFloat)i / (CGFloat)segmentCount;
279
+ for (NSUInteger i = 0; i < spanCount; i++) {
280
+ CGFloat position = ((CGFloat)i + 0.5) / spanCount;
278
281
  UIColor *color = [self colorAtGradientPosition:position];
279
282
  GMSStrokeStyle *style = [GMSStrokeStyle solidColor:color];
280
- [spans addObject:[GMSStyleSpan spanWithStyle:style]];
283
+ [spans addObject:[GMSStyleSpan spanWithStyle:style segments:segmentsPerSpan]];
281
284
  }
282
285
 
283
286
  return spans;
@@ -1,28 +1,48 @@
1
1
  #import "GoogleMapProvider.h"
2
+
3
+ using facebook::react::LuggMapViewInsetAdjustment;
4
+ using facebook::react::LuggMapViewMapType;
5
+ using facebook::react::LuggMapViewPoiFilterMode;
6
+ using facebook::react::LuggMapViewTheme;
7
+
8
+ #import "../LuggCalloutView.h"
9
+ #import "../LuggCircleView.h"
10
+ #import "../LuggGroundOverlayView.h"
2
11
  #import "../LuggMarkerView.h"
3
12
  #import "../LuggPolygonView.h"
4
13
  #import "../LuggPolylineView.h"
14
+ #import "../LuggTileOverlayView.h"
5
15
  #import "GMSPolylineAnimator.h"
6
16
  #import "PolylineAnimatorBase.h"
7
17
 
8
18
  static NSString *const kDemoMapId = @"DEMO_MAP_ID";
9
19
 
10
20
  @interface GoogleMapProvider () <
11
- LuggMarkerViewDelegate, LuggPolylineViewDelegate, LuggPolygonViewDelegate>
21
+ LuggMarkerViewDelegate, LuggCalloutViewDelegate, LuggPolylineViewDelegate,
22
+ LuggPolygonViewDelegate, LuggCircleViewDelegate,
23
+ LuggGroundOverlayViewDelegate, LuggTileOverlayViewDelegate>
12
24
  @end
13
25
 
14
26
  @implementation GoogleMapProvider {
27
+ UIView *_wrapperView;
15
28
  GMSMapView *_mapView;
16
29
  BOOL _isMapReady;
17
30
  BOOL _isDragging;
18
- NSInteger _theme;
31
+ LuggMapViewTheme _theme;
19
32
  UIEdgeInsets _edgeInsets;
20
33
  NSMutableArray<LuggMarkerView *> *_pendingMarkerViews;
21
34
  NSMutableArray<LuggPolylineView *> *_pendingPolylineViews;
22
35
  NSMutableArray<LuggPolygonView *> *_pendingPolygonViews;
36
+ NSMutableArray<LuggCircleView *> *_pendingCircleViews;
37
+ NSMutableArray<LuggGroundOverlayView *> *_pendingGroundOverlayViews;
38
+ NSMutableArray<LuggTileOverlayView *> *_pendingTileOverlayViews;
23
39
  NSMapTable<LuggPolylineView *, GMSPolylineAnimator *> *_polylineAnimators;
24
40
  NSMapTable<GMSPolygon *, LuggPolygonView *> *_polygonToViewMap;
41
+ NSMapTable<GMSCircle *, LuggCircleView *> *_circleToViewMap;
25
42
  NSMapTable<GMSMarker *, LuggMarkerView *> *_markerToViewMap;
43
+ NSMapTable<GMSGroundOverlay *, LuggGroundOverlayView *>
44
+ *_groundOverlayToViewMap;
45
+ LuggMarkerView *_activeNonBubbledMarker;
26
46
 
27
47
  // Edge insets animation
28
48
  CADisplayLink *_edgeInsetsDisplayLink;
@@ -41,9 +61,14 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
41
61
  _pendingMarkerViews = [NSMutableArray array];
42
62
  _pendingPolylineViews = [NSMutableArray array];
43
63
  _pendingPolygonViews = [NSMutableArray array];
64
+ _pendingCircleViews = [NSMutableArray array];
65
+ _pendingGroundOverlayViews = [NSMutableArray array];
66
+ _pendingTileOverlayViews = [NSMutableArray array];
44
67
  _polylineAnimators = [NSMapTable weakToStrongObjectsMapTable];
45
68
  _polygonToViewMap = [NSMapTable strongToWeakObjectsMapTable];
69
+ _circleToViewMap = [NSMapTable strongToWeakObjectsMapTable];
46
70
  _markerToViewMap = [NSMapTable strongToWeakObjectsMapTable];
71
+ _groundOverlayToViewMap = [NSMapTable strongToWeakObjectsMapTable];
47
72
  }
48
73
  return self;
49
74
  }
@@ -88,6 +113,7 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
88
113
  _mapView.paddingAdjustmentBehavior =
89
114
  kGMSMapViewPaddingAdjustmentBehaviorNever;
90
115
 
116
+ _wrapperView = wrapperView;
91
117
  [wrapperView addSubview:_mapView];
92
118
 
93
119
  [self applyTheme];
@@ -96,6 +122,9 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
96
122
  [self processPendingMarkers];
97
123
  [self processPendingPolylines];
98
124
  [self processPendingPolygons];
125
+ [self processPendingCircles];
126
+ [self processPendingGroundOverlays];
127
+ [self processPendingTileOverlays];
99
128
 
100
129
  [_delegate mapProviderDidReady];
101
130
  }
@@ -105,9 +134,14 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
105
134
  [_pendingMarkerViews removeAllObjects];
106
135
  [_pendingPolylineViews removeAllObjects];
107
136
  [_pendingPolygonViews removeAllObjects];
137
+ [_pendingCircleViews removeAllObjects];
138
+ [_pendingGroundOverlayViews removeAllObjects];
139
+ [_pendingTileOverlayViews removeAllObjects];
108
140
  [_polylineAnimators removeAllObjects];
109
141
  [_polygonToViewMap removeAllObjects];
142
+ [_circleToViewMap removeAllObjects];
110
143
  [_markerToViewMap removeAllObjects];
144
+ [_groundOverlayToViewMap removeAllObjects];
111
145
  [_mapView clear];
112
146
  [_mapView removeFromSuperview];
113
147
  _mapView = nil;
@@ -136,7 +170,43 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
136
170
  _mapView.myLocationEnabled = enabled;
137
171
  }
138
172
 
139
- - (void)setTheme:(NSInteger)theme {
173
+ - (void)setInsetAdjustment:(LuggMapViewInsetAdjustment)insetAdjustment {
174
+ _mapView.paddingAdjustmentBehavior =
175
+ (insetAdjustment == LuggMapViewInsetAdjustment::Automatic)
176
+ ? kGMSMapViewPaddingAdjustmentBehaviorAlways
177
+ : kGMSMapViewPaddingAdjustmentBehaviorNever;
178
+ }
179
+
180
+ - (void)setPoiEnabled:(BOOL)enabled {
181
+ }
182
+
183
+ - (void)setPoiFilterMode:(LuggMapViewPoiFilterMode)mode {
184
+ }
185
+
186
+ - (void)setPoiFilterCategories:(NSArray<NSString *> *)categories {
187
+ }
188
+
189
+ - (void)setMapType:(LuggMapViewMapType)mapType {
190
+ if (!_mapView)
191
+ return;
192
+
193
+ switch (mapType) {
194
+ case LuggMapViewMapType::Satellite:
195
+ _mapView.mapType = kGMSTypeSatellite;
196
+ break;
197
+ case LuggMapViewMapType::Terrain:
198
+ _mapView.mapType = kGMSTypeTerrain;
199
+ break;
200
+ case LuggMapViewMapType::Hybrid:
201
+ _mapView.mapType = kGMSTypeHybrid;
202
+ break;
203
+ default:
204
+ _mapView.mapType = kGMSTypeNormal;
205
+ break;
206
+ }
207
+ }
208
+
209
+ - (void)setTheme:(LuggMapViewTheme)theme {
140
210
  _theme = theme;
141
211
  [self applyTheme];
142
212
  }
@@ -146,13 +216,13 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
146
216
  return;
147
217
 
148
218
  switch (_theme) {
149
- case 1: // Dark
219
+ case LuggMapViewTheme::Dark:
150
220
  _mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
151
221
  break;
152
- case 0: // Light
222
+ case LuggMapViewTheme::Light:
153
223
  _mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
154
224
  break;
155
- default: // System
225
+ default:
156
226
  _mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
157
227
  break;
158
228
  }
@@ -248,6 +318,7 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
248
318
  longitude:position.target.longitude
249
319
  zoom:position.zoom
250
320
  gesture:_isDragging];
321
+ [self positionNonBubbledCallout];
251
322
  }
252
323
 
253
324
  - (void)mapView:(GMSMapView *)mapView
@@ -267,6 +338,7 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
267
338
 
268
339
  - (void)mapView:(GMSMapView *)mapView
269
340
  didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
341
+ [self dismissNonBubbledCallout];
270
342
  CGPoint point = [mapView.projection pointForCoordinate:coordinate];
271
343
  [_delegate mapProviderDidPress:coordinate.latitude
272
344
  longitude:coordinate.longitude
@@ -284,22 +356,55 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
284
356
  }
285
357
 
286
358
  - (void)mapView:(GMSMapView *)mapView didTapOverlay:(GMSOverlay *)overlay {
287
- if (![overlay isKindOfClass:[GMSPolygon class]])
288
- return;
289
-
290
- GMSPolygon *polygon = (GMSPolygon *)overlay;
291
- LuggPolygonView *polygonView = [_polygonToViewMap objectForKey:polygon];
292
- if (!polygonView || !polygonView.tappable)
293
- return;
294
-
295
- [polygonView emitPressEvent];
359
+ if ([overlay isKindOfClass:[GMSPolygon class]]) {
360
+ GMSPolygon *polygon = (GMSPolygon *)overlay;
361
+ LuggPolygonView *polygonView = [_polygonToViewMap objectForKey:polygon];
362
+ if (polygonView && polygonView.tappable) {
363
+ [polygonView emitPressEvent];
364
+ }
365
+ } else if ([overlay isKindOfClass:[GMSCircle class]]) {
366
+ GMSCircle *circle = (GMSCircle *)overlay;
367
+ LuggCircleView *circleView = [_circleToViewMap objectForKey:circle];
368
+ if (circleView && circleView.tappable) {
369
+ [circleView emitPressEvent];
370
+ }
371
+ } else if ([overlay isKindOfClass:[GMSGroundOverlay class]]) {
372
+ GMSGroundOverlay *groundOverlay = (GMSGroundOverlay *)overlay;
373
+ LuggGroundOverlayView *groundOverlayView =
374
+ [_groundOverlayToViewMap objectForKey:groundOverlay];
375
+ if (groundOverlayView && groundOverlayView.tappable) {
376
+ [groundOverlayView emitPressEvent];
377
+ }
378
+ }
296
379
  }
297
380
 
298
381
  - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
382
+ [self dismissNonBubbledCallout];
383
+
299
384
  LuggMarkerView *markerView = [_markerToViewMap objectForKey:marker];
300
385
  if (markerView) {
301
386
  CGPoint point = [_mapView.projection pointForCoordinate:marker.position];
302
387
  [markerView emitPressEventWithPoint:point];
388
+
389
+ LuggCalloutView *calloutView = markerView.calloutView;
390
+ if (calloutView && calloutView.hasCustomContent) {
391
+ if (markerView.centerOnPress) {
392
+ [mapView animateToLocation:marker.position];
393
+ }
394
+
395
+ mapView.selectedMarker = marker;
396
+
397
+ if (!calloutView.bubbled) {
398
+ [self showNonBubbledCallout:markerView];
399
+ }
400
+
401
+ return YES;
402
+ }
403
+
404
+ if (!markerView.centerOnPress) {
405
+ mapView.selectedMarker = marker;
406
+ return YES;
407
+ }
303
408
  }
304
409
  return NO;
305
410
  }
@@ -332,6 +437,129 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
332
437
  }
333
438
  }
334
439
 
440
+ - (UIView *)rasterizedCalloutView:(LuggCalloutView *)calloutView {
441
+ UIView *contentView = calloutView.contentView;
442
+ [contentView layoutIfNeeded];
443
+
444
+ CGSize size = contentView.bounds.size;
445
+ if (size.width <= 0 || size.height <= 0)
446
+ return nil;
447
+
448
+ UIGraphicsImageRendererFormat *format =
449
+ [UIGraphicsImageRendererFormat defaultFormat];
450
+ format.scale = [UIScreen mainScreen].scale;
451
+ UIGraphicsImageRenderer *renderer =
452
+ [[UIGraphicsImageRenderer alloc] initWithSize:size format:format];
453
+ UIImage *image =
454
+ [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) {
455
+ [contentView.layer renderInContext:context.CGContext];
456
+ }];
457
+
458
+ return [[UIImageView alloc] initWithImage:image];
459
+ }
460
+
461
+ - (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker {
462
+ // Non-bubbled callouts are rendered as live views, not info windows
463
+ return nil;
464
+ }
465
+
466
+ - (UIView *)mapView:(GMSMapView *)mapView
467
+ markerInfoContents:(GMSMarker *)marker {
468
+ LuggMarkerView *markerView = [_markerToViewMap objectForKey:marker];
469
+ if (!markerView || !markerView.calloutView ||
470
+ !markerView.calloutView.hasCustomContent)
471
+ return nil;
472
+
473
+ if (markerView.calloutView.bubbled) {
474
+ return [self rasterizedCalloutView:markerView.calloutView];
475
+ }
476
+
477
+ return nil;
478
+ }
479
+
480
+ - (void)showNonBubbledCallout:(LuggMarkerView *)markerView {
481
+ [self dismissNonBubbledCallout];
482
+ _mapView.selectedMarker = nil;
483
+
484
+ LuggCalloutView *calloutView = markerView.calloutView;
485
+ UIView *contentView = calloutView.contentView;
486
+ [contentView removeFromSuperview];
487
+
488
+ contentView.userInteractionEnabled = YES;
489
+ contentView.hidden = YES;
490
+ calloutView.delegate = self;
491
+ [_wrapperView addSubview:contentView];
492
+
493
+ _activeNonBubbledMarker = markerView;
494
+ dispatch_async(dispatch_get_main_queue(), ^{
495
+ [self positionNonBubbledCallout];
496
+ contentView.hidden = NO;
497
+ });
498
+ }
499
+
500
+ - (void)calloutViewDidUpdate:(LuggCalloutView *)calloutView {
501
+ [self positionNonBubbledCallout];
502
+ }
503
+
504
+ - (void)dismissNonBubbledCallout {
505
+ if (!_activeNonBubbledMarker)
506
+ return;
507
+
508
+ LuggCalloutView *calloutView = _activeNonBubbledMarker.calloutView;
509
+ calloutView.delegate = nil;
510
+ [calloutView.contentView removeFromSuperview];
511
+ _activeNonBubbledMarker = nil;
512
+ }
513
+
514
+ - (void)positionNonBubbledCallout {
515
+ if (!_activeNonBubbledMarker)
516
+ return;
517
+
518
+ LuggCalloutView *calloutView = _activeNonBubbledMarker.calloutView;
519
+ UIView *contentView = calloutView.contentView;
520
+ CGSize contentSize = contentView.bounds.size;
521
+ if (contentSize.width <= 0 || contentSize.height <= 0)
522
+ return;
523
+
524
+ CGPoint offset = calloutView.offset;
525
+ CGPoint point = [_mapView.projection
526
+ pointForCoordinate:_activeNonBubbledMarker.coordinate];
527
+
528
+ UIView *iconView = _activeNonBubbledMarker.iconView;
529
+ CGFloat markerHeight =
530
+ iconView.bounds.size.height * _activeNonBubbledMarker.scale;
531
+
532
+ contentView.center =
533
+ CGPointMake(point.x + offset.x,
534
+ point.y - markerHeight * _activeNonBubbledMarker.anchor.y -
535
+ contentSize.height / 2.0 + offset.y);
536
+ }
537
+
538
+ - (void)showCalloutForMarkerView:(LuggMarkerView *)markerView {
539
+ LuggCalloutView *calloutView = markerView.calloutView;
540
+ if (calloutView && calloutView.hasCustomContent) {
541
+ [self dismissNonBubbledCallout];
542
+ GMSMarker *marker = (GMSMarker *)markerView.marker;
543
+ if (calloutView.bubbled) {
544
+ _mapView.selectedMarker = marker;
545
+ } else {
546
+ [self showNonBubbledCallout:markerView];
547
+ }
548
+ return;
549
+ }
550
+
551
+ if (markerView.title.length > 0) {
552
+ _mapView.selectedMarker = (GMSMarker *)markerView.marker;
553
+ }
554
+ }
555
+
556
+ - (void)hideCalloutForMarkerView:(LuggMarkerView *)markerView {
557
+ [self dismissNonBubbledCallout];
558
+ if (_mapView.selectedMarker == markerView.marker) {
559
+ _mapView.selectedMarker = nil;
560
+ }
561
+ }
562
+
335
563
  #pragma mark - MarkerViewDelegate
336
564
 
337
565
  - (void)markerViewDidLayout:(LuggMarkerView *)markerView {
@@ -354,6 +582,24 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
354
582
  [self syncPolygonView:polygonView];
355
583
  }
356
584
 
585
+ #pragma mark - CircleViewDelegate
586
+
587
+ - (void)circleViewDidUpdate:(LuggCircleView *)circleView {
588
+ [self syncCircleView:circleView];
589
+ }
590
+
591
+ #pragma mark - GroundOverlayViewDelegate
592
+
593
+ - (void)groundOverlayViewDidUpdate:(LuggGroundOverlayView *)groundOverlayView {
594
+ [self syncGroundOverlayView:groundOverlayView];
595
+ }
596
+
597
+ #pragma mark - TileOverlayViewDelegate
598
+
599
+ - (void)tileOverlayViewDidUpdate:(LuggTileOverlayView *)tileOverlayView {
600
+ [self syncTileOverlayView:tileOverlayView];
601
+ }
602
+
357
603
  #pragma mark - Marker Management
358
604
 
359
605
  - (void)addMarkerView:(LuggMarkerView *)markerView {
@@ -387,8 +633,10 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
387
633
 
388
634
  GMSAdvancedMarker *marker = (GMSAdvancedMarker *)markerView.marker;
389
635
  marker.position = markerView.coordinate;
390
- marker.title = markerView.title;
391
- marker.snippet = markerView.markerDescription;
636
+ marker.title = markerView.title.length > 0 ? markerView.title : nil;
637
+ marker.snippet = markerView.markerDescription.length > 0
638
+ ? markerView.markerDescription
639
+ : nil;
392
640
  marker.zIndex = (int)markerView.zIndex;
393
641
  marker.draggable = markerView.draggable;
394
642
  [self applyMarkerStyle:markerView marker:marker];
@@ -410,8 +658,10 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
410
658
 
411
659
  GMSAdvancedMarker *marker = [[GMSAdvancedMarker alloc] init];
412
660
  marker.position = markerView.coordinate;
413
- marker.title = markerView.title;
414
- marker.snippet = markerView.markerDescription;
661
+ marker.title = markerView.title.length > 0 ? markerView.title : nil;
662
+ marker.snippet = markerView.markerDescription.length > 0
663
+ ? markerView.markerDescription
664
+ : nil;
415
665
  marker.zIndex = (int)markerView.zIndex;
416
666
  marker.draggable = markerView.draggable;
417
667
 
@@ -614,6 +864,243 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
614
864
  [_polygonToViewMap setObject:polygonView forKey:polygon];
615
865
  }
616
866
 
867
+ #pragma mark - Circle Management
868
+
869
+ - (void)addCircleView:(LuggCircleView *)circleView {
870
+ circleView.delegate = self;
871
+ [self syncCircleView:circleView];
872
+ }
873
+
874
+ - (void)removeCircleView:(LuggCircleView *)circleView {
875
+ GMSCircle *circle = (GMSCircle *)circleView.circle;
876
+ if (circle) {
877
+ [_circleToViewMap removeObjectForKey:circle];
878
+ circle.map = nil;
879
+ circleView.circle = nil;
880
+ }
881
+ }
882
+
883
+ - (void)syncCircleView:(LuggCircleView *)circleView {
884
+ if (!_mapView) {
885
+ if (![_pendingCircleViews containsObject:circleView]) {
886
+ [_pendingCircleViews addObject:circleView];
887
+ }
888
+ return;
889
+ }
890
+
891
+ if (!circleView.circle) {
892
+ [self addCircleViewToMap:circleView];
893
+ return;
894
+ }
895
+
896
+ GMSCircle *circle = (GMSCircle *)circleView.circle;
897
+ circle.position = circleView.center;
898
+ circle.radius = circleView.radius;
899
+ circle.fillColor = circleView.fillColor;
900
+ circle.strokeColor = circleView.strokeColor;
901
+ circle.strokeWidth = circleView.strokeWidth;
902
+ circle.zIndex = (int)circleView.zIndex;
903
+ circle.tappable = circleView.tappable;
904
+ }
905
+
906
+ - (void)processPendingCircles {
907
+ if (!_mapView)
908
+ return;
909
+
910
+ for (LuggCircleView *circleView in _pendingCircleViews) {
911
+ [self addCircleViewToMap:circleView];
912
+ }
913
+ [_pendingCircleViews removeAllObjects];
914
+ }
915
+
916
+ - (void)addCircleViewToMap:(LuggCircleView *)circleView {
917
+ if (!_mapView)
918
+ return;
919
+
920
+ GMSCircle *circle = [GMSCircle circleWithPosition:circleView.center
921
+ radius:circleView.radius];
922
+ circle.fillColor = circleView.fillColor;
923
+ circle.strokeColor = circleView.strokeColor;
924
+ circle.strokeWidth = circleView.strokeWidth;
925
+ circle.zIndex = (int)circleView.zIndex;
926
+ circle.tappable = circleView.tappable;
927
+ circle.map = _mapView;
928
+ circleView.circle = circle;
929
+ [_circleToViewMap setObject:circleView forKey:circle];
930
+ }
931
+
932
+ #pragma mark - Ground Overlay Management
933
+
934
+ - (void)addGroundOverlayView:(LuggGroundOverlayView *)groundOverlayView {
935
+ groundOverlayView.delegate = self;
936
+ [self syncGroundOverlayView:groundOverlayView];
937
+ }
938
+
939
+ - (void)removeGroundOverlayView:(LuggGroundOverlayView *)groundOverlayView {
940
+ groundOverlayView.delegate = nil;
941
+ GMSGroundOverlay *overlay = (GMSGroundOverlay *)groundOverlayView.overlay;
942
+ if (overlay) {
943
+ [_groundOverlayToViewMap removeObjectForKey:overlay];
944
+ overlay.map = nil;
945
+ groundOverlayView.overlay = nil;
946
+ }
947
+ }
948
+
949
+ - (void)syncGroundOverlayView:(LuggGroundOverlayView *)groundOverlayView {
950
+ if (!_mapView) {
951
+ if (![_pendingGroundOverlayViews containsObject:groundOverlayView]) {
952
+ [_pendingGroundOverlayViews addObject:groundOverlayView];
953
+ }
954
+ return;
955
+ }
956
+
957
+ NSString *imageUri = groundOverlayView.imageUri;
958
+ if (imageUri.length == 0)
959
+ return;
960
+
961
+ // Remove old overlay
962
+ GMSGroundOverlay *oldOverlay = (GMSGroundOverlay *)groundOverlayView.overlay;
963
+ if (oldOverlay) {
964
+ [_groundOverlayToViewMap removeObjectForKey:oldOverlay];
965
+ oldOverlay.map = nil;
966
+ groundOverlayView.overlay = nil;
967
+ }
968
+
969
+ // Load image and create overlay
970
+ NSURL *url = [NSURL URLWithString:imageUri];
971
+ if (!url)
972
+ return;
973
+
974
+ __weak __typeof(self) weakSelf = self;
975
+ __weak LuggGroundOverlayView *weakOverlayView = groundOverlayView;
976
+ dispatch_async(
977
+ dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
978
+ NSData *data = [NSData dataWithContentsOfURL:url];
979
+ UIImage *image = data ? [UIImage imageWithData:data] : nil;
980
+ dispatch_async(dispatch_get_main_queue(), ^{
981
+ [weakSelf addGroundOverlayToMap:weakOverlayView image:image];
982
+ });
983
+ });
984
+ }
985
+
986
+ - (void)addGroundOverlayToMap:(LuggGroundOverlayView *)groundOverlayView
987
+ image:(UIImage *)image {
988
+ if (!_mapView || !groundOverlayView || !image)
989
+ return;
990
+
991
+ GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc]
992
+ initWithCoordinate:groundOverlayView.southwest
993
+ coordinate:groundOverlayView.northeast];
994
+
995
+ GMSGroundOverlay *overlay = [GMSGroundOverlay groundOverlayWithBounds:bounds
996
+ icon:image];
997
+ overlay.opacity = groundOverlayView.opacity;
998
+ overlay.bearing = groundOverlayView.bearing;
999
+ overlay.zIndex = (int)groundOverlayView.zIndex;
1000
+ overlay.tappable = groundOverlayView.tappable;
1001
+ overlay.map = _mapView;
1002
+
1003
+ groundOverlayView.overlay = overlay;
1004
+ [_groundOverlayToViewMap setObject:groundOverlayView forKey:overlay];
1005
+ }
1006
+
1007
+ - (void)processPendingGroundOverlays {
1008
+ if (!_mapView)
1009
+ return;
1010
+
1011
+ for (LuggGroundOverlayView *view in _pendingGroundOverlayViews) {
1012
+ [self syncGroundOverlayView:view];
1013
+ }
1014
+ [_pendingGroundOverlayViews removeAllObjects];
1015
+ }
1016
+
1017
+ #pragma mark - Tile Overlay Management
1018
+
1019
+ - (void)addTileOverlayView:(LuggTileOverlayView *)tileOverlayView {
1020
+ tileOverlayView.delegate = self;
1021
+ [self syncTileOverlayView:tileOverlayView];
1022
+ }
1023
+
1024
+ - (void)removeTileOverlayView:(LuggTileOverlayView *)tileOverlayView {
1025
+ tileOverlayView.delegate = nil;
1026
+ GMSTileLayer *tileLayer = (GMSTileLayer *)tileOverlayView.overlay;
1027
+ if (tileLayer) {
1028
+ tileLayer.map = nil;
1029
+ tileOverlayView.overlay = nil;
1030
+ }
1031
+ }
1032
+
1033
+ - (void)syncTileOverlayView:(LuggTileOverlayView *)tileOverlayView {
1034
+ if (!_mapView) {
1035
+ if (![_pendingTileOverlayViews containsObject:tileOverlayView]) {
1036
+ [_pendingTileOverlayViews addObject:tileOverlayView];
1037
+ }
1038
+ return;
1039
+ }
1040
+
1041
+ NSString *urlTemplate = tileOverlayView.urlTemplate;
1042
+ if (urlTemplate.length == 0)
1043
+ return;
1044
+
1045
+ // Remove old tile layer
1046
+ GMSTileLayer *oldLayer = (GMSTileLayer *)tileOverlayView.overlay;
1047
+ if (oldLayer) {
1048
+ oldLayer.map = nil;
1049
+ tileOverlayView.overlay = nil;
1050
+ }
1051
+
1052
+ BOOL hasBounds = tileOverlayView.hasBounds;
1053
+ CLLocationCoordinate2D sw = tileOverlayView.southwest;
1054
+ CLLocationCoordinate2D ne = tileOverlayView.northeast;
1055
+
1056
+ GMSTileURLConstructor constructor = ^NSURL *(NSUInteger x, NSUInteger y,
1057
+ NSUInteger zoom) {
1058
+ if (hasBounds) {
1059
+ double n = pow(2.0, zoom);
1060
+ double tileSW_lat =
1061
+ 180.0 / M_PI * atan(sinh(M_PI * (1 - 2.0 * (y + 1) / n)));
1062
+ double tileNE_lat = 180.0 / M_PI * atan(sinh(M_PI * (1 - 2.0 * y / n)));
1063
+ double tileSW_lng = x / n * 360.0 - 180.0;
1064
+ double tileNE_lng = (x + 1) / n * 360.0 - 180.0;
1065
+
1066
+ if (tileNE_lat < sw.latitude || tileSW_lat > ne.latitude ||
1067
+ tileNE_lng < sw.longitude || tileSW_lng > ne.longitude) {
1068
+ return nil;
1069
+ }
1070
+ }
1071
+
1072
+ NSString *urlString =
1073
+ [urlTemplate stringByReplacingOccurrencesOfString:@"{x}"
1074
+ withString:[@(x) stringValue]];
1075
+ urlString =
1076
+ [urlString stringByReplacingOccurrencesOfString:@"{y}"
1077
+ withString:[@(y) stringValue]];
1078
+ urlString =
1079
+ [urlString stringByReplacingOccurrencesOfString:@"{z}"
1080
+ withString:[@(zoom) stringValue]];
1081
+ return [NSURL URLWithString:urlString];
1082
+ };
1083
+
1084
+ GMSURLTileLayer *tileLayer =
1085
+ [GMSURLTileLayer tileLayerWithURLConstructor:constructor];
1086
+ tileLayer.tileSize = tileOverlayView.tileSize;
1087
+ tileLayer.opacity = tileOverlayView.opacity;
1088
+ tileLayer.zIndex = (int)tileOverlayView.zIndex;
1089
+ tileLayer.map = _mapView;
1090
+
1091
+ tileOverlayView.overlay = tileLayer;
1092
+ }
1093
+
1094
+ - (void)processPendingTileOverlays {
1095
+ if (!_mapView)
1096
+ return;
1097
+
1098
+ for (LuggTileOverlayView *view in _pendingTileOverlayViews) {
1099
+ [self syncTileOverlayView:view];
1100
+ }
1101
+ [_pendingTileOverlayViews removeAllObjects];
1102
+ }
1103
+
617
1104
  #pragma mark - Lifecycle
618
1105
 
619
1106
  - (void)pauseAnimations {
@@ -0,0 +1,12 @@
1
+ #import <MapKit/MapKit.h>
2
+
3
+ @interface LuggAnnotationView : MKAnnotationView
4
+ @end
5
+
6
+ @interface LuggMarkerAnnotationView : MKMarkerAnnotationView
7
+ @end
8
+
9
+ // Shared hit-test helpers for annotation views with subviews outside bounds
10
+ BOOL LuggAnnotationPointInside(UIView *self, CGPoint point, UIEvent *event);
11
+ UIView *_Nullable LuggAnnotationHitTest(UIView *self, CGPoint point,
12
+ UIEvent *event);