@lugg/maps 0.2.0-alpha.21 → 0.2.0-alpha.23

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 (45) hide show
  1. package/README.md +5 -0
  2. package/android/src/main/java/com/luggmaps/LuggMapView.kt +201 -0
  3. package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +39 -29
  4. package/android/src/main/java/com/luggmaps/LuggPackage.kt +1 -4
  5. package/android/src/main/java/com/luggmaps/{LuggGoogleMapView.kt → core/GoogleMapProvider.kt} +174 -189
  6. package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +51 -0
  7. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +28 -24
  8. package/ios/LuggMapView.h +9 -0
  9. package/ios/LuggMapView.mm +303 -0
  10. package/ios/core/AppleMapProvider.h +15 -0
  11. package/ios/{LuggAppleMapView.mm → core/AppleMapProvider.mm} +317 -410
  12. package/ios/core/GMSPolylineAnimator.m +16 -4
  13. package/ios/core/GoogleMapProvider.h +13 -0
  14. package/ios/{LuggGoogleMapView.mm → core/GoogleMapProvider.mm} +179 -218
  15. package/ios/core/MapProviderDelegate.h +68 -0
  16. package/lib/module/MapView.js +9 -12
  17. package/lib/module/MapView.js.map +1 -1
  18. package/lib/module/MapView.web.js +4 -1
  19. package/lib/module/MapView.web.js.map +1 -1
  20. package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +4 -1
  21. package/lib/typescript/src/MapView.d.ts +0 -1
  22. package/lib/typescript/src/MapView.d.ts.map +1 -1
  23. package/lib/typescript/src/MapView.types.d.ts +6 -1
  24. package/lib/typescript/src/MapView.types.d.ts.map +1 -1
  25. package/lib/typescript/src/MapView.web.d.ts.map +1 -1
  26. package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +4 -2
  27. package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
  28. package/lib/typescript/src/index.d.ts +1 -1
  29. package/lib/typescript/src/index.d.ts.map +1 -1
  30. package/lib/typescript/src/types.d.ts +4 -0
  31. package/lib/typescript/src/types.d.ts.map +1 -1
  32. package/package.json +5 -3
  33. package/src/MapView.tsx +11 -21
  34. package/src/MapView.types.ts +6 -1
  35. package/src/MapView.web.tsx +10 -0
  36. package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +4 -1
  37. package/src/index.ts +1 -0
  38. package/src/types.ts +5 -0
  39. package/ios/LuggAppleMapView.h +0 -16
  40. package/ios/LuggGoogleMapView.h +0 -13
  41. package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
  42. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -54
  43. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
  44. package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
  45. package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
@@ -1,22 +1,8 @@
1
- #import "LuggAppleMapView.h"
2
- #import "LuggMapWrapperView.h"
3
- #import "LuggMarkerView.h"
4
- #import "LuggPolylineView.h"
5
- #import "core/MKPolylineAnimator.h"
6
- #import "events/CameraIdleEvent.h"
7
- #import "events/CameraMoveEvent.h"
8
- #import "events/ReadyEvent.h"
9
- #import "extensions/MKMapView+Zoom.h"
10
-
11
- #import <react/renderer/components/RNMapsSpec/ComponentDescriptors.h>
12
- #import <react/renderer/components/RNMapsSpec/EventEmitters.h>
13
- #import <react/renderer/components/RNMapsSpec/Props.h>
14
- #import <react/renderer/components/RNMapsSpec/RCTComponentViewHelpers.h>
15
-
16
- #import "RCTFabricComponentsPlugins.h"
17
-
18
- using namespace facebook::react;
19
- using namespace luggmaps::events;
1
+ #import "AppleMapProvider.h"
2
+ #import "../LuggMarkerView.h"
3
+ #import "../LuggPolylineView.h"
4
+ #import "../extensions/MKMapView+Zoom.h"
5
+ #import "MKPolylineAnimator.h"
20
6
 
21
7
  @interface AppleMarkerAnnotation : NSObject <MKAnnotation>
22
8
  @property(nonatomic, assign) CLLocationCoordinate2D coordinate;
@@ -32,14 +18,12 @@ using namespace luggmaps::events;
32
18
  @implementation LuggAppleMapViewContent
33
19
  @end
34
20
 
35
- @interface LuggAppleMapView () <RCTLuggAppleMapViewViewProtocol,
36
- MKMapViewDelegate, LuggMarkerViewDelegate,
21
+ @interface AppleMapProvider () <LuggMarkerViewDelegate,
37
22
  LuggPolylineViewDelegate>
38
23
  @end
39
24
 
40
- @implementation LuggAppleMapView {
25
+ @implementation AppleMapProvider {
41
26
  LuggAppleMapViewContent *_mapView;
42
- LuggMapWrapperView *_mapWrapperView;
43
27
  BOOL _isMapReady;
44
28
  BOOL _isDragging;
45
29
  double _minZoom;
@@ -47,171 +31,122 @@ using namespace luggmaps::events;
47
31
  NSMapTable<id<MKOverlay>, LuggPolylineView *> *_overlayToPolylineMap;
48
32
  }
49
33
 
50
- + (ComponentDescriptorProvider)componentDescriptorProvider {
51
- return concreteComponentDescriptorProvider<
52
- LuggAppleMapViewComponentDescriptor>();
53
- }
34
+ @synthesize delegate = _delegate;
54
35
 
55
- - (instancetype)initWithFrame:(CGRect)frame {
56
- if (self = [super initWithFrame:frame]) {
57
- static const auto defaultProps =
58
- std::make_shared<const LuggAppleMapViewProps>();
59
- _props = defaultProps;
36
+ - (instancetype)init {
37
+ if (self = [super init]) {
60
38
  _overlayToPolylineMap = [NSMapTable strongToWeakObjectsMapTable];
61
39
  }
62
-
63
40
  return self;
64
41
  }
65
42
 
66
- #pragma mark - View Lifecycle
43
+ - (BOOL)isMapReady {
44
+ return _isMapReady;
45
+ }
67
46
 
68
- - (void)mountChildComponentView:
69
- (UIView<RCTComponentViewProtocol> *)childComponentView
70
- index:(NSInteger)index {
71
- [super mountChildComponentView:childComponentView index:index];
47
+ - (MKMapView *)mapView {
48
+ return _mapView;
49
+ }
72
50
 
73
- if ([childComponentView isKindOfClass:[LuggMapWrapperView class]]) {
74
- _mapWrapperView = (LuggMapWrapperView *)childComponentView;
75
- } else if ([childComponentView isKindOfClass:[LuggMarkerView class]]) {
76
- LuggMarkerView *markerView = (LuggMarkerView *)childComponentView;
77
- markerView.delegate = self;
51
+ #pragma mark - MapProvider
78
52
 
79
- AppleMarkerAnnotation *annotation = [[AppleMarkerAnnotation alloc] init];
80
- annotation.markerView = markerView;
81
- markerView.marker = annotation;
53
+ - (void)initializeMapInView:(UIView *)wrapperView
54
+ initialCoordinate:(CLLocationCoordinate2D)coordinate
55
+ initialZoom:(double)zoom {
56
+ if (_mapView)
57
+ return;
82
58
 
83
- if (_mapView) {
84
- [_mapView addAnnotation:annotation];
85
- }
59
+ _mapView = [[LuggAppleMapViewContent alloc] initWithFrame:wrapperView.bounds];
60
+ _mapView.autoresizingMask =
61
+ UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
62
+ _mapView.delegate = self;
63
+ _mapView.insetsLayoutMarginsFromSafeArea = NO;
86
64
 
87
- [self markerViewDidUpdate:markerView];
88
- } else if ([childComponentView isKindOfClass:[LuggPolylineView class]]) {
89
- LuggPolylineView *polylineView = (LuggPolylineView *)childComponentView;
90
- polylineView.delegate = self;
91
- [self addPolylineViewToMap:polylineView];
92
- }
93
- }
65
+ [self applyZoomRange];
94
66
 
95
- - (void)unmountChildComponentView:
96
- (UIView<RCTComponentViewProtocol> *)childComponentView
97
- index:(NSInteger)index {
98
- if ([childComponentView isKindOfClass:[LuggMarkerView class]]) {
99
- LuggMarkerView *markerView = (LuggMarkerView *)childComponentView;
100
- markerView.delegate = nil;
67
+ [wrapperView addSubview:_mapView];
101
68
 
102
- AppleMarkerAnnotation *annotation =
103
- (AppleMarkerAnnotation *)markerView.marker;
69
+ MKCoordinateRegion region = [_mapView regionForCenterCoordinate:coordinate
70
+ zoomLevel:zoom];
71
+ [_mapView setRegion:region animated:NO];
104
72
 
105
- if (annotation) {
106
- annotation.annotationView.transform = CGAffineTransformIdentity;
107
- annotation.markerView = nil;
108
- annotation.annotationView = nil;
109
- [_mapView removeAnnotation:annotation];
110
- markerView.marker = nil;
111
- }
112
- [markerView resetIconViewTransform];
113
- } else if ([childComponentView isKindOfClass:[LuggPolylineView class]]) {
114
- LuggPolylineView *polylineView = (LuggPolylineView *)childComponentView;
115
- polylineView.delegate = nil;
116
- MKPolyline *polyline = (MKPolyline *)polylineView.polyline;
117
- if (polyline) {
118
- [_overlayToPolylineMap removeObjectForKey:polyline];
119
- [_mapView removeOverlay:polyline];
120
- polylineView.polyline = nil;
121
- }
122
- }
73
+ _isMapReady = YES;
123
74
 
124
- [super unmountChildComponentView:childComponentView index:index];
75
+ [_delegate mapProviderDidReady];
125
76
  }
126
77
 
127
- - (void)didMoveToWindow {
128
- [super didMoveToWindow];
129
- if (self.window && !_mapView && _mapWrapperView) {
130
- [self initializeMap];
131
- }
132
- }
133
-
134
- - (void)prepareForRecycle {
135
- [super prepareForRecycle];
136
-
78
+ - (void)destroy {
137
79
  [_mapView removeFromSuperview];
138
80
  _mapView = nil;
139
- _mapWrapperView = nil;
140
81
  _isMapReady = NO;
141
82
  }
142
83
 
143
- #pragma mark - Map Initialization
144
-
145
- - (void)initializeMap {
146
- if (_mapView || !_mapWrapperView) {
147
- return;
148
- }
84
+ #pragma mark - Props
149
85
 
150
- const auto &viewProps =
151
- *std::static_pointer_cast<LuggAppleMapViewProps const>(_props);
86
+ - (void)setZoomEnabled:(BOOL)enabled {
87
+ _mapView.zoomEnabled = enabled;
88
+ }
152
89
 
153
- _mapView =
154
- [[LuggAppleMapViewContent alloc] initWithFrame:_mapWrapperView.bounds];
155
- _mapView.autoresizingMask =
156
- UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
157
- _mapView.delegate = self;
158
- _mapView.insetsLayoutMarginsFromSafeArea = NO;
159
- _mapView.zoomEnabled = viewProps.zoomEnabled;
160
- _mapView.scrollEnabled = viewProps.scrollEnabled;
161
- _mapView.rotateEnabled = viewProps.rotateEnabled;
162
- _mapView.pitchEnabled = viewProps.pitchEnabled;
163
- _mapView.showsUserLocation = viewProps.userLocationEnabled;
164
-
165
- _minZoom = viewProps.minZoom;
166
- _maxZoom = viewProps.maxZoom;
167
- [self applyZoomRange];
90
+ - (void)setScrollEnabled:(BOOL)enabled {
91
+ _mapView.scrollEnabled = enabled;
92
+ }
168
93
 
169
- _mapView.layoutMargins =
170
- UIEdgeInsetsMake(viewProps.padding.top, viewProps.padding.left,
171
- viewProps.padding.bottom, viewProps.padding.right);
94
+ - (void)setRotateEnabled:(BOOL)enabled {
95
+ _mapView.rotateEnabled = enabled;
96
+ }
172
97
 
173
- [_mapWrapperView addSubview:_mapView];
98
+ - (void)setPitchEnabled:(BOOL)enabled {
99
+ _mapView.pitchEnabled = enabled;
100
+ }
174
101
 
175
- CLLocationCoordinate2D center =
176
- CLLocationCoordinate2DMake(viewProps.initialCoordinate.latitude,
177
- viewProps.initialCoordinate.longitude);
178
- MKCoordinateRegion region =
179
- [_mapView regionForCenterCoordinate:center
180
- zoomLevel:viewProps.initialZoom];
181
- [_mapView setRegion:region animated:NO];
102
+ - (void)setUserLocationEnabled:(BOOL)enabled {
103
+ _mapView.showsUserLocation = enabled;
104
+ }
182
105
 
183
- // Add annotations for any markers that were mounted before map was ready
184
- for (UIView *subview in self.subviews) {
185
- if ([subview isKindOfClass:[LuggMarkerView class]]) {
186
- LuggMarkerView *markerView = (LuggMarkerView *)subview;
187
- AppleMarkerAnnotation *annotation =
188
- (AppleMarkerAnnotation *)markerView.marker;
189
- if (annotation) {
190
- [_mapView addAnnotation:annotation];
191
- }
192
- } else if ([subview isKindOfClass:[LuggPolylineView class]]) {
193
- LuggPolylineView *polylineView = (LuggPolylineView *)subview;
194
- [self addPolylineViewToMap:polylineView];
195
- }
106
+ - (void)setTheme:(NSString *)theme {
107
+ if ([theme isEqualToString:@"dark"]) {
108
+ _mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
109
+ } else if ([theme isEqualToString:@"light"]) {
110
+ _mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
111
+ } else {
112
+ _mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
196
113
  }
114
+ }
197
115
 
198
- _isMapReady = YES;
116
+ - (void)setMinZoom:(double)minZoom {
117
+ _minZoom = minZoom;
118
+ [self applyZoomRange];
119
+ }
199
120
 
200
- ReadyEvent::emit<LuggAppleMapViewEventEmitter>(_eventEmitter);
121
+ - (void)setMaxZoom:(double)maxZoom {
122
+ _maxZoom = maxZoom;
123
+ [self applyZoomRange];
201
124
  }
202
125
 
203
- - (void)setCameraWithLatitude:(double)latitude
204
- longitude:(double)longitude
205
- zoom:(double)zoom
206
- animated:(BOOL)animated {
207
- CLLocationCoordinate2D center =
208
- CLLocationCoordinate2DMake(latitude, longitude);
209
- [_mapView setCenterCoordinate:center zoomLevel:zoom animated:animated];
126
+ - (void)setPadding:(UIEdgeInsets)padding oldPadding:(UIEdgeInsets)oldPadding {
127
+ CGFloat oldOffsetX = (oldPadding.left - oldPadding.right) / 2.0;
128
+ CGFloat oldOffsetY = (oldPadding.top - oldPadding.bottom) / 2.0;
129
+ CGFloat newOffsetX = (padding.left - padding.right) / 2.0;
130
+ CGFloat newOffsetY = (padding.top - padding.bottom) / 2.0;
131
+
132
+ CGFloat deltaX = newOffsetX - oldOffsetX;
133
+ CGFloat deltaY = newOffsetY - oldOffsetY;
134
+
135
+ _mapView.layoutMargins = padding;
136
+
137
+ if (deltaX != 0 || deltaY != 0) {
138
+ CLLocationCoordinate2D currentCenter = _mapView.centerCoordinate;
139
+ CGPoint centerPoint = [_mapView convertCoordinate:currentCenter
140
+ toPointToView:_mapView];
141
+ CGPoint newPoint =
142
+ CGPointMake(centerPoint.x - deltaX, centerPoint.y - deltaY);
143
+ CLLocationCoordinate2D newCenter = [_mapView convertPoint:newPoint
144
+ toCoordinateFromView:_mapView];
145
+ [_mapView setCenterCoordinate:newCenter animated:NO];
146
+ }
210
147
  }
211
148
 
212
149
  - (CLLocationDistance)cameraDistanceForZoomLevel:(double)zoomLevel {
213
- // Approximate conversion: at zoom 0, altitude ~128M km
214
- // Each zoom level halves the altitude
215
150
  return 128000000.0 / pow(2, zoomLevel);
216
151
  }
217
152
 
@@ -230,78 +165,189 @@ using namespace luggmaps::events;
230
165
  _mapView.cameraZoomRange = zoomRange;
231
166
  }
232
167
 
233
- - (MKMapView *)mapView {
234
- return _mapView;
168
+ #pragma mark - MKMapViewDelegate
169
+
170
+ - (BOOL)isUserInteracting {
171
+ UIView *mapContainerView = _mapView.subviews.firstObject;
172
+ for (UIGestureRecognizer *gesture in mapContainerView.gestureRecognizers) {
173
+ if (gesture.state == UIGestureRecognizerStateBegan ||
174
+ gesture.state == UIGestureRecognizerStateChanged) {
175
+ return YES;
176
+ }
177
+ }
178
+ return NO;
235
179
  }
236
180
 
237
- #pragma mark - Property Setters
181
+ - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
182
+ _isDragging = [self isUserInteracting];
183
+ if (_isDragging) {
184
+ for (LuggPolylineView *polylineView in _overlayToPolylineMap
185
+ .objectEnumerator) {
186
+ MKPolylineAnimator *renderer =
187
+ (MKPolylineAnimator *)polylineView.renderer;
188
+ [renderer pause];
189
+ }
190
+ }
191
+ }
238
192
 
239
- - (void)updateProps:(Props::Shared const &)props
240
- oldProps:(Props::Shared const &)oldProps {
241
- const auto &oldViewProps =
242
- *std::static_pointer_cast<LuggAppleMapViewProps const>(oldProps);
243
- const auto &newViewProps =
244
- *std::static_pointer_cast<LuggAppleMapViewProps const>(props);
193
+ - (void)mapViewDidChangeVisibleRegion:(MKMapView *)mapView {
194
+ [_delegate mapProviderDidMoveCamera:mapView.centerCoordinate.latitude
195
+ longitude:mapView.centerCoordinate.longitude
196
+ zoom:mapView.zoomLevel
197
+ gesture:_isDragging];
198
+ }
245
199
 
246
- if (_mapView) {
247
- _mapView.zoomEnabled = newViewProps.zoomEnabled;
248
- _mapView.scrollEnabled = newViewProps.scrollEnabled;
249
- _mapView.rotateEnabled = newViewProps.rotateEnabled;
250
- _mapView.pitchEnabled = newViewProps.pitchEnabled;
251
- _mapView.showsUserLocation = newViewProps.userLocationEnabled;
252
-
253
- // Check if padding changed
254
- BOOL paddingChanged =
255
- oldViewProps.padding.top != newViewProps.padding.top ||
256
- oldViewProps.padding.left != newViewProps.padding.left ||
257
- oldViewProps.padding.bottom != newViewProps.padding.bottom ||
258
- oldViewProps.padding.right != newViewProps.padding.right;
259
-
260
- if (paddingChanged) {
261
- // Calculate the offset difference to keep visual center stable
262
- CGFloat oldOffsetX =
263
- (oldViewProps.padding.left - oldViewProps.padding.right) / 2.0;
264
- CGFloat oldOffsetY =
265
- (oldViewProps.padding.top - oldViewProps.padding.bottom) / 2.0;
266
- CGFloat newOffsetX =
267
- (newViewProps.padding.left - newViewProps.padding.right) / 2.0;
268
- CGFloat newOffsetY =
269
- (newViewProps.padding.top - newViewProps.padding.bottom) / 2.0;
270
-
271
- CGFloat deltaX = newOffsetX - oldOffsetX;
272
- CGFloat deltaY = newOffsetY - oldOffsetY;
273
-
274
- // Apply new padding first
275
- _mapView.layoutMargins = UIEdgeInsetsMake(
276
- newViewProps.padding.top, newViewProps.padding.left,
277
- newViewProps.padding.bottom, newViewProps.padding.right);
278
-
279
- // Convert pixel offset to coordinate offset
280
- if (deltaX != 0 || deltaY != 0) {
281
- CLLocationCoordinate2D currentCenter = _mapView.centerCoordinate;
282
- CGPoint centerPoint = [_mapView convertCoordinate:currentCenter
283
- toPointToView:_mapView];
284
- CGPoint newPoint =
285
- CGPointMake(centerPoint.x - deltaX, centerPoint.y - deltaY);
286
- CLLocationCoordinate2D newCenter = [_mapView convertPoint:newPoint
287
- toCoordinateFromView:_mapView];
288
- [_mapView setCenterCoordinate:newCenter animated:NO];
200
+ - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
201
+ BOOL wasDragging = _isDragging;
202
+ _isDragging = NO;
203
+ if (wasDragging) {
204
+ for (LuggPolylineView *polylineView in _overlayToPolylineMap
205
+ .objectEnumerator) {
206
+ MKPolylineAnimator *renderer =
207
+ (MKPolylineAnimator *)polylineView.renderer;
208
+ [renderer resume];
209
+ }
210
+ }
211
+ [_delegate mapProviderDidIdleCamera:mapView.centerCoordinate.latitude
212
+ longitude:mapView.centerCoordinate.longitude
213
+ zoom:mapView.zoomLevel
214
+ gesture:wasDragging];
215
+ }
216
+
217
+ - (MKAnnotationView *)mapView:(MKMapView *)mapView
218
+ viewForAnnotation:(id<MKAnnotation>)annotation {
219
+ if (![annotation isKindOfClass:[AppleMarkerAnnotation class]]) {
220
+ return nil;
221
+ }
222
+
223
+ AppleMarkerAnnotation *markerAnnotation = (AppleMarkerAnnotation *)annotation;
224
+ LuggMarkerView *markerView = markerAnnotation.markerView;
225
+
226
+ if (!markerView || !markerView.hasCustomView) {
227
+ return nil;
228
+ }
229
+
230
+ MKAnnotationView *annotationView =
231
+ [[MKAnnotationView alloc] initWithAnnotation:annotation
232
+ reuseIdentifier:nil];
233
+ annotationView.canShowCallout = YES;
234
+ annotationView.displayPriority = MKFeatureDisplayPriorityRequired;
235
+ annotationView.layer.zPosition = markerView.zIndex;
236
+ annotationView.zPriority = markerView.zIndex;
237
+
238
+ if (!markerView.rasterize) {
239
+ UIView *iconView = markerView.iconView;
240
+ [iconView removeFromSuperview];
241
+ [annotationView addSubview:iconView];
242
+ }
243
+
244
+ [self applyMarkerStyle:markerView annotationView:annotationView];
245
+ markerAnnotation.annotationView = annotationView;
246
+
247
+ return annotationView;
248
+ }
249
+
250
+ - (MKOverlayRenderer *)mapView:(MKMapView *)mapView
251
+ rendererForOverlay:(id<MKOverlay>)overlay {
252
+ if ([overlay isKindOfClass:[MKPolyline class]]) {
253
+ LuggPolylineView *polylineView =
254
+ [_overlayToPolylineMap objectForKey:overlay];
255
+ MKPolyline *polyline = (MKPolyline *)overlay;
256
+
257
+ if (polylineView) {
258
+ NSArray<UIColor *> *colors = polylineView.strokeColors;
259
+
260
+ MKPolylineAnimator *renderer =
261
+ [[MKPolylineAnimator alloc] initWithPolyline:polyline];
262
+ renderer.lineWidth = polylineView.strokeWidth;
263
+ renderer.strokeColor = colors.firstObject;
264
+ if (colors.count > 1) {
265
+ renderer.strokeColors = colors;
289
266
  }
290
- } else {
291
- _mapView.layoutMargins = UIEdgeInsetsMake(
292
- newViewProps.padding.top, newViewProps.padding.left,
293
- newViewProps.padding.bottom, newViewProps.padding.right);
267
+ renderer.animatedOptions = polylineView.animatedOptions;
268
+ renderer.animated = polylineView.animated;
269
+ polylineView.renderer = renderer;
270
+ return renderer;
294
271
  }
295
272
 
296
- _minZoom = newViewProps.minZoom;
297
- _maxZoom = newViewProps.maxZoom;
298
- [self applyZoomRange];
273
+ MKPolylineRenderer *renderer =
274
+ [[MKPolylineRenderer alloc] initWithPolyline:polyline];
275
+ return renderer;
276
+ }
277
+ return nil;
278
+ }
279
+
280
+ #pragma mark - MarkerViewDelegate
281
+
282
+ - (void)markerViewDidLayout:(LuggMarkerView *)markerView {
283
+ AppleMarkerAnnotation *annotation =
284
+ (AppleMarkerAnnotation *)markerView.marker;
285
+ if (annotation) {
286
+ [self updateAnnotationViewFrame:annotation];
299
287
  }
288
+ }
300
289
 
301
- [super updateProps:props oldProps:oldProps];
290
+ - (void)markerViewDidUpdate:(LuggMarkerView *)markerView {
291
+ AppleMarkerAnnotation *annotation =
292
+ (AppleMarkerAnnotation *)markerView.marker;
293
+
294
+ if (!annotation)
295
+ return;
296
+
297
+ annotation.coordinate = markerView.coordinate;
298
+ annotation.title = markerView.title;
299
+ annotation.subtitle = markerView.markerDescription;
300
+
301
+ MKAnnotationView *annotationView = annotation.annotationView;
302
+ if (annotationView) {
303
+ annotationView.layer.zPosition = markerView.zIndex;
304
+ annotationView.zPriority = markerView.zIndex;
305
+ }
306
+
307
+ [self updateAnnotationViewFrame:annotation];
308
+ }
309
+
310
+ #pragma mark - PolylineViewDelegate
311
+
312
+ - (void)polylineViewDidUpdate:(LuggPolylineView *)polylineView {
313
+ [self syncPolylineView:polylineView];
302
314
  }
303
315
 
304
- #pragma mark - Annotation Helpers
316
+ #pragma mark - Marker Management
317
+
318
+ - (void)addMarkerView:(LuggMarkerView *)markerView {
319
+ markerView.delegate = self;
320
+
321
+ AppleMarkerAnnotation *annotation = [[AppleMarkerAnnotation alloc] init];
322
+ annotation.markerView = markerView;
323
+ markerView.marker = annotation;
324
+
325
+ if (_mapView) {
326
+ [_mapView addAnnotation:annotation];
327
+ }
328
+
329
+ [self markerViewDidUpdate:markerView];
330
+ }
331
+
332
+ - (void)removeMarkerView:(LuggMarkerView *)markerView {
333
+ markerView.delegate = nil;
334
+
335
+ AppleMarkerAnnotation *annotation =
336
+ (AppleMarkerAnnotation *)markerView.marker;
337
+
338
+ if (annotation) {
339
+ annotation.annotationView.transform = CGAffineTransformIdentity;
340
+ annotation.markerView = nil;
341
+ annotation.annotationView = nil;
342
+ [_mapView removeAnnotation:annotation];
343
+ markerView.marker = nil;
344
+ }
345
+ [markerView resetIconViewTransform];
346
+ }
347
+
348
+ - (void)syncMarkerView:(LuggMarkerView *)markerView {
349
+ [self markerViewDidUpdate:markerView];
350
+ }
305
351
 
306
352
  - (void)applyMarkerStyle:(LuggMarkerView *)markerView
307
353
  annotationView:(MKAnnotationView *)annotationView {
@@ -339,55 +385,36 @@ using namespace luggmaps::events;
339
385
  MKAnnotationView *annotationView = annotation.annotationView;
340
386
  LuggMarkerView *markerView = annotation.markerView;
341
387
 
342
- if (!annotationView || !markerView) {
388
+ if (!annotationView || !markerView)
343
389
  return;
344
- }
345
390
 
346
391
  [self applyMarkerStyle:markerView annotationView:annotationView];
347
392
  }
348
393
 
349
- #pragma mark - PolylineViewDelegate
350
-
351
- - (void)polylineViewDidUpdate:(LuggPolylineView *)polylineView {
352
- [self syncPolylineView:polylineView];
353
- }
354
-
355
394
  #pragma mark - Polyline Management
356
395
 
357
- - (void)addPolylineViewToMap:(LuggPolylineView *)polylineView {
358
- if (!_mapView) {
359
- return;
360
- }
396
+ - (void)addPolylineView:(LuggPolylineView *)polylineView {
397
+ polylineView.delegate = self;
398
+ [self addPolylineOverlayToMap:polylineView];
399
+ }
361
400
 
362
- NSArray<CLLocation *> *coordinates = polylineView.coordinates;
363
- if (coordinates.count == 0) {
364
- return;
401
+ - (void)removePolylineView:(LuggPolylineView *)polylineView {
402
+ polylineView.delegate = nil;
403
+ MKPolyline *polyline = (MKPolyline *)polylineView.polyline;
404
+ if (polyline) {
405
+ [_overlayToPolylineMap removeObjectForKey:polyline];
406
+ [_mapView removeOverlay:polyline];
407
+ polylineView.polyline = nil;
365
408
  }
366
-
367
- CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
368
- sizeof(CLLocationCoordinate2D) * coordinates.count);
369
- for (NSUInteger i = 0; i < coordinates.count; i++) {
370
- coords[i] = coordinates[i].coordinate;
371
- }
372
-
373
- MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords
374
- count:coordinates.count];
375
- free(coords);
376
-
377
- polylineView.polyline = polyline;
378
- [_overlayToPolylineMap setObject:polylineView forKey:polyline];
379
- [self insertOverlay:polyline withZIndex:polylineView.zIndex];
380
409
  }
381
410
 
382
411
  - (void)syncPolylineView:(LuggPolylineView *)polylineView {
383
- if (!_mapView) {
412
+ if (!_mapView)
384
413
  return;
385
- }
386
414
 
387
415
  MKPolylineAnimator *renderer = (MKPolylineAnimator *)polylineView.renderer;
388
416
  MKPolyline *oldPolyline = (MKPolyline *)polylineView.polyline;
389
417
 
390
- // Build new polyline from coordinates
391
418
  NSArray<CLLocation *> *coordinates = polylineView.coordinates;
392
419
  if (coordinates.count == 0) {
393
420
  if (renderer) {
@@ -414,7 +441,6 @@ using namespace luggmaps::events;
414
441
  polylineView.polyline = newPolyline;
415
442
  [_overlayToPolylineMap setObject:polylineView forKey:newPolyline];
416
443
 
417
- // If we have an existing renderer, update it in place
418
444
  if (renderer && oldPolyline) {
419
445
  [_overlayToPolylineMap removeObjectForKey:oldPolyline];
420
446
  [_mapView removeOverlay:oldPolyline];
@@ -429,7 +455,6 @@ using namespace luggmaps::events;
429
455
  return;
430
456
  }
431
457
 
432
- // Otherwise do full add
433
458
  if (oldPolyline) {
434
459
  [_overlayToPolylineMap removeObjectForKey:oldPolyline];
435
460
  [_mapView removeOverlay:oldPolyline];
@@ -437,6 +462,29 @@ using namespace luggmaps::events;
437
462
  [self insertOverlay:newPolyline withZIndex:polylineView.zIndex];
438
463
  }
439
464
 
465
+ - (void)addPolylineOverlayToMap:(LuggPolylineView *)polylineView {
466
+ if (!_mapView)
467
+ return;
468
+
469
+ NSArray<CLLocation *> *coordinates = polylineView.coordinates;
470
+ if (coordinates.count == 0)
471
+ return;
472
+
473
+ CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
474
+ sizeof(CLLocationCoordinate2D) * coordinates.count);
475
+ for (NSUInteger i = 0; i < coordinates.count; i++) {
476
+ coords[i] = coordinates[i].coordinate;
477
+ }
478
+
479
+ MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords
480
+ count:coordinates.count];
481
+ free(coords);
482
+
483
+ polylineView.polyline = polyline;
484
+ [_overlayToPolylineMap setObject:polylineView forKey:polyline];
485
+ [self insertOverlay:polyline withZIndex:polylineView.zIndex];
486
+ }
487
+
440
488
  - (void)insertOverlay:(id<MKOverlay>)overlay withZIndex:(NSInteger)zIndex {
441
489
  if (zIndex == 0) {
442
490
  [_mapView addOverlay:overlay];
@@ -448,7 +496,7 @@ using namespace luggmaps::events;
448
496
 
449
497
  for (NSInteger i = 0; i < overlays.count; i++) {
450
498
  LuggPolylineView *existingPolylineView =
451
- [self findPolylineViewForOverlay:overlays[i]];
499
+ [_overlayToPolylineMap objectForKey:overlays[i]];
452
500
  if (existingPolylineView && existingPolylineView.zIndex > zIndex) {
453
501
  insertIndex = i;
454
502
  break;
@@ -458,172 +506,40 @@ using namespace luggmaps::events;
458
506
  [_mapView insertOverlay:overlay atIndex:insertIndex];
459
507
  }
460
508
 
461
- - (LuggPolylineView *)findPolylineViewForOverlay:(id<MKOverlay>)overlay {
462
- return [_overlayToPolylineMap objectForKey:overlay];
463
- }
509
+ #pragma mark - Lifecycle
464
510
 
465
- #pragma mark - MarkerViewDelegate
466
-
467
- - (void)markerViewDidLayout:(LuggMarkerView *)markerView {
468
- AppleMarkerAnnotation *annotation =
469
- (AppleMarkerAnnotation *)markerView.marker;
470
- if (annotation) {
471
- [self updateAnnotationViewFrame:annotation];
511
+ - (void)pauseAnimations {
512
+ for (LuggPolylineView *polylineView in _overlayToPolylineMap
513
+ .objectEnumerator) {
514
+ MKPolylineAnimator *renderer = (MKPolylineAnimator *)polylineView.renderer;
515
+ [renderer pause];
472
516
  }
473
517
  }
474
518
 
475
- - (void)markerViewDidUpdate:(LuggMarkerView *)markerView {
476
- AppleMarkerAnnotation *annotation =
477
- (AppleMarkerAnnotation *)markerView.marker;
478
-
479
- if (!annotation) {
480
- RCTLogWarn(@"markerViewDidUpdate called without annotation");
481
- return;
482
- }
483
-
484
- annotation.coordinate = markerView.coordinate;
485
- annotation.title = markerView.title;
486
- annotation.subtitle = markerView.markerDescription;
487
-
488
- MKAnnotationView *annotationView = annotation.annotationView;
489
- if (annotationView) {
490
- annotationView.layer.zPosition = markerView.zIndex;
491
- annotationView.zPriority = markerView.zIndex;
492
- }
493
-
494
- [self updateAnnotationViewFrame:annotation];
495
- }
496
-
497
- #pragma mark - MKMapViewDelegate
498
-
499
- - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
500
- _isDragging = [self isUserInteracting:mapView];
501
- if (_isDragging) {
502
- for (UIView *subview in self.subviews) {
503
- if ([subview isKindOfClass:[LuggPolylineView class]]) {
504
- MKPolylineAnimator *renderer =
505
- (MKPolylineAnimator *)((LuggPolylineView *)subview).renderer;
506
- [renderer pause];
507
- }
508
- }
519
+ - (void)resumeAnimations {
520
+ for (LuggPolylineView *polylineView in _overlayToPolylineMap
521
+ .objectEnumerator) {
522
+ MKPolylineAnimator *renderer = (MKPolylineAnimator *)polylineView.renderer;
523
+ [renderer resume];
509
524
  }
510
525
  }
511
526
 
512
- - (BOOL)isUserInteracting:(MKMapView *)mapView {
513
- UIView *mapContainerView = mapView.subviews.firstObject;
514
- for (UIGestureRecognizer *gesture in mapContainerView.gestureRecognizers) {
515
- if (gesture.state == UIGestureRecognizerStateBegan ||
516
- gesture.state == UIGestureRecognizerStateChanged) {
517
- return YES;
518
- }
519
- }
520
- return NO;
521
- }
522
-
523
- - (void)mapViewDidChangeVisibleRegion:(MKMapView *)mapView {
524
- CameraMoveEvent{mapView.centerCoordinate.latitude,
525
- mapView.centerCoordinate.longitude, mapView.zoomLevel,
526
- _isDragging}
527
- .emit<LuggAppleMapViewEventEmitter>(_eventEmitter);
528
- }
529
-
530
- - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
531
- BOOL wasDragging = _isDragging;
532
- _isDragging = NO;
533
- if (wasDragging) {
534
- for (UIView *subview in self.subviews) {
535
- if ([subview isKindOfClass:[LuggPolylineView class]]) {
536
- MKPolylineAnimator *renderer =
537
- (MKPolylineAnimator *)((LuggPolylineView *)subview).renderer;
538
- [renderer resume];
539
- }
540
- }
541
- }
542
- CameraIdleEvent{mapView.centerCoordinate.latitude,
543
- mapView.centerCoordinate.longitude, mapView.zoomLevel,
544
- static_cast<bool>(wasDragging)}
545
- .emit<LuggAppleMapViewEventEmitter>(_eventEmitter);
546
- }
547
-
548
- - (MKAnnotationView *)mapView:(MKMapView *)mapView
549
- viewForAnnotation:(id<MKAnnotation>)annotation {
550
- if (![annotation isKindOfClass:[AppleMarkerAnnotation class]]) {
551
- return nil;
552
- }
553
-
554
- AppleMarkerAnnotation *markerAnnotation = (AppleMarkerAnnotation *)annotation;
555
- LuggMarkerView *markerView = markerAnnotation.markerView;
556
-
557
- if (!markerView || !markerView.hasCustomView) {
558
- return nil;
559
- }
560
-
561
- MKAnnotationView *annotationView =
562
- [[MKAnnotationView alloc] initWithAnnotation:annotation
563
- reuseIdentifier:nil];
564
- annotationView.canShowCallout = YES;
565
- annotationView.displayPriority = MKFeatureDisplayPriorityRequired;
566
- annotationView.layer.zPosition = markerView.zIndex;
567
- annotationView.zPriority = markerView.zIndex;
568
-
569
- if (!markerView.rasterize) {
570
- UIView *iconView = markerView.iconView;
571
- [iconView removeFromSuperview];
572
- [annotationView addSubview:iconView];
573
- }
574
-
575
- [self applyMarkerStyle:markerView annotationView:annotationView];
576
- markerAnnotation.annotationView = annotationView;
577
-
578
- return annotationView;
579
- }
580
-
581
- - (MKOverlayRenderer *)mapView:(MKMapView *)mapView
582
- rendererForOverlay:(id<MKOverlay>)overlay {
583
- if ([overlay isKindOfClass:[MKPolyline class]]) {
584
- LuggPolylineView *polylineView = [self findPolylineViewForOverlay:overlay];
585
- MKPolyline *polyline = (MKPolyline *)overlay;
586
-
587
- if (polylineView) {
588
- NSArray<UIColor *> *colors = polylineView.strokeColors;
589
-
590
- MKPolylineAnimator *renderer =
591
- [[MKPolylineAnimator alloc] initWithPolyline:polyline];
592
- renderer.lineWidth = polylineView.strokeWidth;
593
- renderer.strokeColor = colors.firstObject;
594
- if (colors.count > 1) {
595
- renderer.strokeColors = colors;
596
- }
597
- renderer.animatedOptions = polylineView.animatedOptions;
598
- renderer.animated = polylineView.animated;
599
- polylineView.renderer = renderer;
600
- return renderer;
601
- }
602
-
603
- MKPolylineRenderer *renderer =
604
- [[MKPolylineRenderer alloc] initWithPolyline:polyline];
605
- return renderer;
606
- }
607
- return nil;
608
- }
609
-
610
527
  #pragma mark - Commands
611
528
 
612
529
  - (void)moveCamera:(double)latitude
613
530
  longitude:(double)longitude
614
531
  zoom:(double)zoom
615
532
  duration:(double)duration {
616
- if (!_mapView) {
533
+ if (!_mapView)
617
534
  return;
618
- }
619
535
 
620
536
  double targetZoom = zoom > 0 ? zoom : _mapView.zoomLevel;
621
537
 
622
538
  if (duration < 0) {
623
- [self setCameraWithLatitude:latitude
624
- longitude:longitude
625
- zoom:targetZoom
626
- animated:YES];
539
+ [_mapView
540
+ setCenterCoordinate:CLLocationCoordinate2DMake(latitude, longitude)
541
+ zoomLevel:targetZoom
542
+ animated:YES];
627
543
  } else if (duration > 0) {
628
544
  CLLocationCoordinate2D center =
629
545
  CLLocationCoordinate2DMake(latitude, longitude);
@@ -634,10 +550,10 @@ using namespace luggmaps::events;
634
550
  [self->_mapView setRegion:region animated:NO];
635
551
  }];
636
552
  } else {
637
- [self setCameraWithLatitude:latitude
638
- longitude:longitude
639
- zoom:targetZoom
640
- animated:NO];
553
+ [_mapView
554
+ setCenterCoordinate:CLLocationCoordinate2DMake(latitude, longitude)
555
+ zoomLevel:targetZoom
556
+ animated:NO];
641
557
  }
642
558
  }
643
559
 
@@ -647,9 +563,8 @@ using namespace luggmaps::events;
647
563
  paddingBottom:(double)paddingBottom
648
564
  paddingRight:(double)paddingRight
649
565
  duration:(double)duration {
650
- if (!_mapView || coordinates.count == 0) {
566
+ if (!_mapView || coordinates.count == 0)
651
567
  return;
652
- }
653
568
 
654
569
  CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
655
570
  sizeof(CLLocationCoordinate2D) * coordinates.count);
@@ -684,12 +599,4 @@ using namespace luggmaps::events;
684
599
  }
685
600
  }
686
601
 
687
- - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
688
- RCTLuggAppleMapViewHandleCommand(self, commandName, args);
689
- }
690
-
691
- Class<RCTComponentViewProtocol> LuggAppleMapViewCls(void) {
692
- return LuggAppleMapView.class;
693
- }
694
-
695
602
  @end