@lugg/maps 0.2.0-alpha.3 → 0.2.0-alpha.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -3
- package/android/src/main/java/com/luggmaps/LuggMapView.kt +265 -0
- package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +75 -36
- package/android/src/main/java/com/luggmaps/LuggMapWrapperView.kt +6 -5
- package/android/src/main/java/com/luggmaps/LuggMarkerView.kt +136 -14
- package/android/src/main/java/com/luggmaps/LuggMarkerViewManager.kt +21 -0
- package/android/src/main/java/com/luggmaps/LuggPackage.kt +1 -4
- package/android/src/main/java/com/luggmaps/LuggPolylineView.kt +16 -0
- package/android/src/main/java/com/luggmaps/LuggPolylineViewManager.kt +22 -0
- package/android/src/main/java/com/luggmaps/{LuggGoogleMapView.kt → core/GoogleMapProvider.kt} +251 -241
- package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +55 -0
- package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +163 -52
- package/ios/LuggMapView.h +9 -0
- package/ios/LuggMapView.mm +312 -0
- package/ios/LuggMarkerView.h +9 -0
- package/ios/LuggMarkerView.mm +79 -0
- package/ios/LuggPolylineView.h +4 -0
- package/ios/LuggPolylineView.mm +23 -0
- package/ios/core/AppleMapProvider.h +15 -0
- package/ios/core/AppleMapProvider.mm +664 -0
- package/ios/core/GMSPolylineAnimator.h +3 -0
- package/ios/core/GMSPolylineAnimator.m +175 -40
- package/ios/core/GoogleMapProvider.h +13 -0
- package/ios/core/GoogleMapProvider.mm +513 -0
- package/ios/core/MKPolylineAnimator.h +4 -0
- package/ios/core/MKPolylineAnimator.m +224 -68
- package/ios/core/MapProviderDelegate.h +72 -0
- package/ios/core/PolylineAnimatorBase.h +24 -1
- package/ios/core/PolylineAnimatorBase.m +82 -19
- package/ios/extensions/MKMapView+Zoom.h +2 -0
- package/ios/extensions/MKMapView+Zoom.m +14 -4
- package/lib/module/MapProvider.js +13 -0
- package/lib/module/MapProvider.js.map +1 -0
- package/lib/module/MapProvider.types.js +4 -0
- package/lib/module/MapProvider.types.js.map +1 -0
- package/lib/module/MapProvider.web.js +20 -0
- package/lib/module/MapProvider.web.js.map +1 -0
- package/lib/module/MapView.js +29 -16
- package/lib/module/MapView.js.map +1 -1
- package/lib/module/MapView.web.js +290 -0
- package/lib/module/MapView.web.js.map +1 -0
- package/lib/module/components/Marker.js +19 -2
- package/lib/module/components/Marker.js.map +1 -1
- package/lib/module/components/Marker.web.js +33 -0
- package/lib/module/components/Marker.web.js.map +1 -0
- package/lib/module/components/Polyline.js +17 -4
- package/lib/module/components/Polyline.js.map +1 -1
- package/lib/module/components/Polyline.web.js +229 -0
- package/lib/module/components/Polyline.web.js.map +1 -0
- package/lib/module/components/index.js +2 -2
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/components/index.web.js +5 -0
- package/lib/module/components/index.web.js.map +1 -0
- package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +19 -7
- package/lib/module/fabric/LuggMarkerViewNativeComponent.ts +7 -1
- package/lib/module/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/lib/module/index.js +4 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +7 -0
- package/lib/module/index.web.js.map +1 -0
- package/lib/typescript/src/MapProvider.d.ts +8 -0
- package/lib/typescript/src/MapProvider.d.ts.map +1 -0
- package/lib/typescript/src/MapProvider.types.d.ts +16 -0
- package/lib/typescript/src/MapProvider.types.d.ts.map +1 -0
- package/lib/typescript/src/MapProvider.web.d.ts +11 -0
- package/lib/typescript/src/MapProvider.web.d.ts.map +1 -0
- package/lib/typescript/src/MapView.d.ts +4 -4
- package/lib/typescript/src/MapView.d.ts.map +1 -1
- package/lib/typescript/src/MapView.types.d.ts +23 -7
- package/lib/typescript/src/MapView.types.d.ts.map +1 -1
- package/lib/typescript/src/MapView.web.d.ts +3 -0
- package/lib/typescript/src/MapView.web.d.ts.map +1 -0
- package/lib/typescript/src/components/Marker.d.ts +25 -1
- package/lib/typescript/src/components/Marker.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.web.d.ts +3 -0
- package/lib/typescript/src/components/Marker.web.d.ts.map +1 -0
- package/lib/typescript/src/components/Polyline.d.ts +36 -1
- package/lib/typescript/src/components/Polyline.d.ts.map +1 -1
- package/lib/typescript/src/components/Polyline.web.d.ts +3 -0
- package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -0
- package/lib/typescript/src/components/index.d.ts +4 -2
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/components/index.web.d.ts +5 -0
- package/lib/typescript/src/components/index.web.d.ts.map +1 -0
- package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +8 -4
- package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts +4 -1
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts +7 -0
- package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +8 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +10 -0
- package/lib/typescript/src/index.web.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +4 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +17 -3
- package/src/MapProvider.tsx +10 -0
- package/src/MapProvider.types.ts +16 -0
- package/src/MapProvider.web.tsx +14 -0
- package/src/MapView.tsx +28 -26
- package/src/MapView.types.ts +24 -7
- package/src/MapView.web.tsx +364 -0
- package/src/components/Marker.tsx +50 -4
- package/src/components/Marker.web.tsx +33 -0
- package/src/components/Polyline.tsx +51 -2
- package/src/components/Polyline.web.tsx +287 -0
- package/src/components/index.ts +8 -2
- package/src/components/index.web.ts +4 -0
- package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +19 -7
- package/src/fabric/LuggMarkerViewNativeComponent.ts +7 -1
- package/src/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/src/index.ts +18 -2
- package/src/index.web.ts +20 -0
- package/src/types.ts +5 -0
- package/ios/LuggAppleMapView.h +0 -16
- package/ios/LuggAppleMapView.mm +0 -580
- package/ios/LuggGoogleMapView.h +0 -13
- package/ios/LuggGoogleMapView.mm +0 -454
- package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
- package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -54
- package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
- package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
- package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
|
@@ -0,0 +1,664 @@
|
|
|
1
|
+
#import "AppleMapProvider.h"
|
|
2
|
+
#import "../LuggMarkerView.h"
|
|
3
|
+
#import "../LuggPolylineView.h"
|
|
4
|
+
#import "../extensions/MKMapView+Zoom.h"
|
|
5
|
+
#import "MKPolylineAnimator.h"
|
|
6
|
+
|
|
7
|
+
@interface AppleMarkerAnnotation : NSObject <MKAnnotation>
|
|
8
|
+
@property(nonatomic, assign) CLLocationCoordinate2D coordinate;
|
|
9
|
+
@property(nonatomic, copy, nullable) NSString *title;
|
|
10
|
+
@property(nonatomic, copy, nullable) NSString *subtitle;
|
|
11
|
+
@property(nonatomic, strong) LuggMarkerView *markerView;
|
|
12
|
+
@property(nonatomic, weak) MKAnnotationView *annotationView;
|
|
13
|
+
@end
|
|
14
|
+
|
|
15
|
+
@implementation AppleMarkerAnnotation
|
|
16
|
+
@end
|
|
17
|
+
|
|
18
|
+
@implementation LuggAppleMapViewContent
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
@interface AppleMapProvider () <LuggMarkerViewDelegate,
|
|
22
|
+
LuggPolylineViewDelegate>
|
|
23
|
+
@end
|
|
24
|
+
|
|
25
|
+
@implementation AppleMapProvider {
|
|
26
|
+
LuggAppleMapViewContent *_mapView;
|
|
27
|
+
BOOL _isMapReady;
|
|
28
|
+
BOOL _isDragging;
|
|
29
|
+
double _minZoom;
|
|
30
|
+
double _maxZoom;
|
|
31
|
+
NSMapTable<id<MKOverlay>, LuggPolylineView *> *_overlayToPolylineMap;
|
|
32
|
+
|
|
33
|
+
// Edge insets animation
|
|
34
|
+
CADisplayLink *_edgeInsetsDisplayLink;
|
|
35
|
+
UIEdgeInsets _edgeInsetsFrom;
|
|
36
|
+
UIEdgeInsets _edgeInsetsTo;
|
|
37
|
+
CFTimeInterval _edgeInsetsAnimationStart;
|
|
38
|
+
CFTimeInterval _edgeInsetsAnimationDuration;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@synthesize delegate = _delegate;
|
|
42
|
+
|
|
43
|
+
- (instancetype)init {
|
|
44
|
+
if (self = [super init]) {
|
|
45
|
+
_overlayToPolylineMap = [NSMapTable strongToWeakObjectsMapTable];
|
|
46
|
+
}
|
|
47
|
+
return self;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
- (BOOL)isMapReady {
|
|
51
|
+
return _isMapReady;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
- (MKMapView *)mapView {
|
|
55
|
+
return _mapView;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#pragma mark - MapProvider
|
|
59
|
+
|
|
60
|
+
- (void)initializeMapInView:(UIView *)wrapperView
|
|
61
|
+
initialCoordinate:(CLLocationCoordinate2D)coordinate
|
|
62
|
+
initialZoom:(double)zoom {
|
|
63
|
+
if (_mapView)
|
|
64
|
+
return;
|
|
65
|
+
|
|
66
|
+
_mapView = [[LuggAppleMapViewContent alloc] initWithFrame:wrapperView.bounds];
|
|
67
|
+
_mapView.autoresizingMask =
|
|
68
|
+
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
69
|
+
_mapView.delegate = self;
|
|
70
|
+
_mapView.insetsLayoutMarginsFromSafeArea = NO;
|
|
71
|
+
|
|
72
|
+
[self applyZoomRange];
|
|
73
|
+
|
|
74
|
+
[wrapperView addSubview:_mapView];
|
|
75
|
+
|
|
76
|
+
MKCoordinateRegion region = [_mapView regionForCenterCoordinate:coordinate
|
|
77
|
+
zoomLevel:zoom];
|
|
78
|
+
[_mapView setRegion:region animated:NO];
|
|
79
|
+
|
|
80
|
+
_isMapReady = YES;
|
|
81
|
+
|
|
82
|
+
[_delegate mapProviderDidReady];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
- (void)destroy {
|
|
86
|
+
[self stopEdgeInsetsAnimation];
|
|
87
|
+
[_mapView removeFromSuperview];
|
|
88
|
+
_mapView = nil;
|
|
89
|
+
_isMapReady = NO;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
#pragma mark - Props
|
|
93
|
+
|
|
94
|
+
- (void)setZoomEnabled:(BOOL)enabled {
|
|
95
|
+
_mapView.zoomEnabled = enabled;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
- (void)setScrollEnabled:(BOOL)enabled {
|
|
99
|
+
_mapView.scrollEnabled = enabled;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
- (void)setRotateEnabled:(BOOL)enabled {
|
|
103
|
+
_mapView.rotateEnabled = enabled;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
- (void)setPitchEnabled:(BOOL)enabled {
|
|
107
|
+
_mapView.pitchEnabled = enabled;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
- (void)setUserLocationEnabled:(BOOL)enabled {
|
|
111
|
+
_mapView.showsUserLocation = enabled;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
- (void)setTheme:(NSInteger)theme {
|
|
115
|
+
switch (theme) {
|
|
116
|
+
case 1: // Dark
|
|
117
|
+
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
|
|
118
|
+
break;
|
|
119
|
+
case 0: // Light
|
|
120
|
+
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
|
|
121
|
+
break;
|
|
122
|
+
default: // System
|
|
123
|
+
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
- (void)setMinZoom:(double)minZoom {
|
|
129
|
+
_minZoom = minZoom;
|
|
130
|
+
[self applyZoomRange];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
- (void)setMaxZoom:(double)maxZoom {
|
|
134
|
+
_maxZoom = maxZoom;
|
|
135
|
+
[self applyZoomRange];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets
|
|
139
|
+
oldEdgeInsets:(UIEdgeInsets)oldEdgeInsets {
|
|
140
|
+
CGFloat oldOffsetX = (oldEdgeInsets.left - oldEdgeInsets.right) / 2.0;
|
|
141
|
+
CGFloat oldOffsetY = (oldEdgeInsets.top - oldEdgeInsets.bottom) / 2.0;
|
|
142
|
+
CGFloat newOffsetX = (edgeInsets.left - edgeInsets.right) / 2.0;
|
|
143
|
+
CGFloat newOffsetY = (edgeInsets.top - edgeInsets.bottom) / 2.0;
|
|
144
|
+
|
|
145
|
+
CGFloat deltaX = newOffsetX - oldOffsetX;
|
|
146
|
+
CGFloat deltaY = newOffsetY - oldOffsetY;
|
|
147
|
+
|
|
148
|
+
_mapView.layoutMargins = edgeInsets;
|
|
149
|
+
|
|
150
|
+
if (deltaX != 0 || deltaY != 0) {
|
|
151
|
+
CLLocationCoordinate2D currentCenter = _mapView.centerCoordinate;
|
|
152
|
+
CGPoint centerPoint = [_mapView convertCoordinate:currentCenter
|
|
153
|
+
toPointToView:_mapView];
|
|
154
|
+
CGPoint newPoint =
|
|
155
|
+
CGPointMake(centerPoint.x - deltaX, centerPoint.y - deltaY);
|
|
156
|
+
CLLocationCoordinate2D newCenter = [_mapView convertPoint:newPoint
|
|
157
|
+
toCoordinateFromView:_mapView];
|
|
158
|
+
[_mapView setCenterCoordinate:newCenter animated:NO];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets
|
|
163
|
+
oldEdgeInsets:(UIEdgeInsets)oldEdgeInsets
|
|
164
|
+
duration:(double)duration {
|
|
165
|
+
[self stopEdgeInsetsAnimation];
|
|
166
|
+
|
|
167
|
+
if (duration != 0 && _mapView) {
|
|
168
|
+
double actualDuration = duration < 0 ? 0.3 : duration / 1000.0;
|
|
169
|
+
_edgeInsetsFrom = oldEdgeInsets;
|
|
170
|
+
_edgeInsetsTo = edgeInsets;
|
|
171
|
+
_edgeInsetsAnimationDuration = actualDuration;
|
|
172
|
+
_edgeInsetsAnimationStart = CACurrentMediaTime();
|
|
173
|
+
|
|
174
|
+
_edgeInsetsDisplayLink = [CADisplayLink
|
|
175
|
+
displayLinkWithTarget:self
|
|
176
|
+
selector:@selector(edgeInsetsAnimationTick:)];
|
|
177
|
+
[_edgeInsetsDisplayLink addToRunLoop:[NSRunLoop mainRunLoop]
|
|
178
|
+
forMode:NSRunLoopCommonModes];
|
|
179
|
+
} else {
|
|
180
|
+
[self setEdgeInsets:edgeInsets oldEdgeInsets:oldEdgeInsets];
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
- (void)edgeInsetsAnimationTick:(CADisplayLink *)displayLink {
|
|
185
|
+
CFTimeInterval elapsed = CACurrentMediaTime() - _edgeInsetsAnimationStart;
|
|
186
|
+
CGFloat progress = MIN(elapsed / _edgeInsetsAnimationDuration, 1.0);
|
|
187
|
+
|
|
188
|
+
// Ease out cubic
|
|
189
|
+
CGFloat t = 1.0 - (1.0 - progress) * (1.0 - progress) * (1.0 - progress);
|
|
190
|
+
|
|
191
|
+
UIEdgeInsets current = UIEdgeInsetsMake(
|
|
192
|
+
_edgeInsetsFrom.top + (_edgeInsetsTo.top - _edgeInsetsFrom.top) * t,
|
|
193
|
+
_edgeInsetsFrom.left + (_edgeInsetsTo.left - _edgeInsetsFrom.left) * t,
|
|
194
|
+
_edgeInsetsFrom.bottom +
|
|
195
|
+
(_edgeInsetsTo.bottom - _edgeInsetsFrom.bottom) * t,
|
|
196
|
+
_edgeInsetsFrom.right +
|
|
197
|
+
(_edgeInsetsTo.right - _edgeInsetsFrom.right) * t);
|
|
198
|
+
|
|
199
|
+
[self setEdgeInsets:current oldEdgeInsets:_mapView.layoutMargins];
|
|
200
|
+
|
|
201
|
+
if (progress >= 1.0) {
|
|
202
|
+
[self stopEdgeInsetsAnimation];
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
- (void)stopEdgeInsetsAnimation {
|
|
207
|
+
[_edgeInsetsDisplayLink invalidate];
|
|
208
|
+
_edgeInsetsDisplayLink = nil;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
- (CLLocationDistance)cameraDistanceForZoomLevel:(double)zoomLevel {
|
|
212
|
+
return 128000000.0 / pow(2, zoomLevel);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
- (void)applyZoomRange {
|
|
216
|
+
if (!_mapView)
|
|
217
|
+
return;
|
|
218
|
+
|
|
219
|
+
CLLocationDistance minDistance =
|
|
220
|
+
_maxZoom > 0 ? [self cameraDistanceForZoomLevel:_maxZoom] : 0;
|
|
221
|
+
CLLocationDistance maxDistance =
|
|
222
|
+
_minZoom > 0 ? [self cameraDistanceForZoomLevel:_minZoom] : -1;
|
|
223
|
+
|
|
224
|
+
MKMapCameraZoomRange *zoomRange = [[MKMapCameraZoomRange alloc]
|
|
225
|
+
initWithMinCenterCoordinateDistance:minDistance
|
|
226
|
+
maxCenterCoordinateDistance:maxDistance];
|
|
227
|
+
_mapView.cameraZoomRange = zoomRange;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
#pragma mark - MKMapViewDelegate
|
|
231
|
+
|
|
232
|
+
- (BOOL)isUserInteracting {
|
|
233
|
+
UIView *mapContainerView = _mapView.subviews.firstObject;
|
|
234
|
+
for (UIGestureRecognizer *gesture in mapContainerView.gestureRecognizers) {
|
|
235
|
+
if (gesture.state == UIGestureRecognizerStateBegan ||
|
|
236
|
+
gesture.state == UIGestureRecognizerStateChanged) {
|
|
237
|
+
return YES;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return NO;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
|
|
244
|
+
_isDragging = [self isUserInteracting];
|
|
245
|
+
if (_isDragging) {
|
|
246
|
+
for (LuggPolylineView *polylineView in _overlayToPolylineMap
|
|
247
|
+
.objectEnumerator) {
|
|
248
|
+
MKPolylineAnimator *renderer =
|
|
249
|
+
(MKPolylineAnimator *)polylineView.renderer;
|
|
250
|
+
[renderer pause];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
- (void)mapViewDidChangeVisibleRegion:(MKMapView *)mapView {
|
|
256
|
+
[_delegate mapProviderDidMoveCamera:mapView.centerCoordinate.latitude
|
|
257
|
+
longitude:mapView.centerCoordinate.longitude
|
|
258
|
+
zoom:mapView.zoomLevel
|
|
259
|
+
gesture:_isDragging];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
|
|
263
|
+
BOOL wasDragging = _isDragging;
|
|
264
|
+
_isDragging = NO;
|
|
265
|
+
if (wasDragging) {
|
|
266
|
+
for (LuggPolylineView *polylineView in _overlayToPolylineMap
|
|
267
|
+
.objectEnumerator) {
|
|
268
|
+
MKPolylineAnimator *renderer =
|
|
269
|
+
(MKPolylineAnimator *)polylineView.renderer;
|
|
270
|
+
[renderer resume];
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
[_delegate mapProviderDidIdleCamera:mapView.centerCoordinate.latitude
|
|
274
|
+
longitude:mapView.centerCoordinate.longitude
|
|
275
|
+
zoom:mapView.zoomLevel
|
|
276
|
+
gesture:wasDragging];
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
- (MKAnnotationView *)mapView:(MKMapView *)mapView
|
|
280
|
+
viewForAnnotation:(id<MKAnnotation>)annotation {
|
|
281
|
+
if (![annotation isKindOfClass:[AppleMarkerAnnotation class]]) {
|
|
282
|
+
return nil;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
AppleMarkerAnnotation *markerAnnotation = (AppleMarkerAnnotation *)annotation;
|
|
286
|
+
LuggMarkerView *markerView = markerAnnotation.markerView;
|
|
287
|
+
|
|
288
|
+
if (!markerView || !markerView.hasCustomView) {
|
|
289
|
+
return nil;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
MKAnnotationView *annotationView =
|
|
293
|
+
[[MKAnnotationView alloc] initWithAnnotation:annotation
|
|
294
|
+
reuseIdentifier:nil];
|
|
295
|
+
annotationView.canShowCallout = YES;
|
|
296
|
+
annotationView.displayPriority = MKFeatureDisplayPriorityRequired;
|
|
297
|
+
annotationView.layer.zPosition = markerView.zIndex;
|
|
298
|
+
annotationView.zPriority = markerView.zIndex;
|
|
299
|
+
|
|
300
|
+
if (!markerView.rasterize) {
|
|
301
|
+
UIView *iconView = markerView.iconView;
|
|
302
|
+
[iconView removeFromSuperview];
|
|
303
|
+
[annotationView addSubview:iconView];
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
[self applyMarkerStyle:markerView annotationView:annotationView];
|
|
307
|
+
markerAnnotation.annotationView = annotationView;
|
|
308
|
+
|
|
309
|
+
return annotationView;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView
|
|
313
|
+
rendererForOverlay:(id<MKOverlay>)overlay {
|
|
314
|
+
if ([overlay isKindOfClass:[MKPolyline class]]) {
|
|
315
|
+
LuggPolylineView *polylineView =
|
|
316
|
+
[_overlayToPolylineMap objectForKey:overlay];
|
|
317
|
+
MKPolyline *polyline = (MKPolyline *)overlay;
|
|
318
|
+
|
|
319
|
+
if (polylineView) {
|
|
320
|
+
NSArray<UIColor *> *colors = polylineView.strokeColors;
|
|
321
|
+
|
|
322
|
+
MKPolylineAnimator *renderer =
|
|
323
|
+
[[MKPolylineAnimator alloc] initWithPolyline:polyline];
|
|
324
|
+
renderer.lineWidth = polylineView.strokeWidth;
|
|
325
|
+
renderer.strokeColor = colors.firstObject;
|
|
326
|
+
if (colors.count > 1) {
|
|
327
|
+
renderer.strokeColors = colors;
|
|
328
|
+
}
|
|
329
|
+
renderer.animatedOptions = polylineView.animatedOptions;
|
|
330
|
+
renderer.animated = polylineView.animated;
|
|
331
|
+
polylineView.renderer = renderer;
|
|
332
|
+
return renderer;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
MKPolylineRenderer *renderer =
|
|
336
|
+
[[MKPolylineRenderer alloc] initWithPolyline:polyline];
|
|
337
|
+
return renderer;
|
|
338
|
+
}
|
|
339
|
+
return nil;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
#pragma mark - MarkerViewDelegate
|
|
343
|
+
|
|
344
|
+
- (void)markerViewDidLayout:(LuggMarkerView *)markerView {
|
|
345
|
+
AppleMarkerAnnotation *annotation =
|
|
346
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
347
|
+
if (annotation) {
|
|
348
|
+
[self updateAnnotationViewFrame:annotation];
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
- (void)markerViewDidUpdate:(LuggMarkerView *)markerView {
|
|
353
|
+
AppleMarkerAnnotation *annotation =
|
|
354
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
355
|
+
|
|
356
|
+
if (!annotation)
|
|
357
|
+
return;
|
|
358
|
+
|
|
359
|
+
annotation.coordinate = markerView.coordinate;
|
|
360
|
+
annotation.title = markerView.title;
|
|
361
|
+
annotation.subtitle = markerView.markerDescription;
|
|
362
|
+
|
|
363
|
+
MKAnnotationView *annotationView = annotation.annotationView;
|
|
364
|
+
if (annotationView) {
|
|
365
|
+
annotationView.layer.zPosition = markerView.zIndex;
|
|
366
|
+
annotationView.zPriority = markerView.zIndex;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
[self updateAnnotationViewFrame:annotation];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
#pragma mark - PolylineViewDelegate
|
|
373
|
+
|
|
374
|
+
- (void)polylineViewDidUpdate:(LuggPolylineView *)polylineView {
|
|
375
|
+
[self syncPolylineView:polylineView];
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
#pragma mark - Marker Management
|
|
379
|
+
|
|
380
|
+
- (void)addMarkerView:(LuggMarkerView *)markerView {
|
|
381
|
+
markerView.delegate = self;
|
|
382
|
+
|
|
383
|
+
AppleMarkerAnnotation *annotation = [[AppleMarkerAnnotation alloc] init];
|
|
384
|
+
annotation.markerView = markerView;
|
|
385
|
+
markerView.marker = annotation;
|
|
386
|
+
|
|
387
|
+
if (_mapView) {
|
|
388
|
+
[_mapView addAnnotation:annotation];
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
[self markerViewDidUpdate:markerView];
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
- (void)removeMarkerView:(LuggMarkerView *)markerView {
|
|
395
|
+
markerView.delegate = nil;
|
|
396
|
+
|
|
397
|
+
AppleMarkerAnnotation *annotation =
|
|
398
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
399
|
+
|
|
400
|
+
if (annotation) {
|
|
401
|
+
annotation.annotationView.transform = CGAffineTransformIdentity;
|
|
402
|
+
annotation.markerView = nil;
|
|
403
|
+
annotation.annotationView = nil;
|
|
404
|
+
[_mapView removeAnnotation:annotation];
|
|
405
|
+
markerView.marker = nil;
|
|
406
|
+
}
|
|
407
|
+
[markerView resetIconViewTransform];
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
- (void)syncMarkerView:(LuggMarkerView *)markerView {
|
|
411
|
+
[self markerViewDidUpdate:markerView];
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
- (void)applyMarkerStyle:(LuggMarkerView *)markerView
|
|
415
|
+
annotationView:(MKAnnotationView *)annotationView {
|
|
416
|
+
annotationView.transform = CGAffineTransformIdentity;
|
|
417
|
+
|
|
418
|
+
UIView *iconView = markerView.iconView;
|
|
419
|
+
CGRect frame = iconView.frame;
|
|
420
|
+
if (frame.size.width <= 0 || frame.size.height <= 0)
|
|
421
|
+
return;
|
|
422
|
+
|
|
423
|
+
CGFloat scale = markerView.scale;
|
|
424
|
+
CGPoint anchor = markerView.anchor;
|
|
425
|
+
|
|
426
|
+
if (markerView.rasterize) {
|
|
427
|
+
annotationView.image = [markerView createScaledIconImage];
|
|
428
|
+
} else {
|
|
429
|
+
iconView.layer.anchorPoint = anchor;
|
|
430
|
+
iconView.transform = CGAffineTransformMakeScale(scale, scale);
|
|
431
|
+
iconView.frame =
|
|
432
|
+
CGRectMake(frame.size.width * (0.5 - anchor.x) * (scale - 1),
|
|
433
|
+
frame.size.height * (0.5 - anchor.y) * (scale - 1),
|
|
434
|
+
frame.size.width, frame.size.height);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
annotationView.bounds =
|
|
438
|
+
CGRectMake(0, 0, frame.size.width * scale, frame.size.height * scale);
|
|
439
|
+
annotationView.centerOffset =
|
|
440
|
+
CGPointMake(frame.size.width * scale * (anchor.x - 0.5),
|
|
441
|
+
-frame.size.height * scale * (anchor.y - 0.5));
|
|
442
|
+
annotationView.transform =
|
|
443
|
+
CGAffineTransformMakeRotation(markerView.rotate * M_PI / 180.0);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
- (void)updateAnnotationViewFrame:(AppleMarkerAnnotation *)annotation {
|
|
447
|
+
MKAnnotationView *annotationView = annotation.annotationView;
|
|
448
|
+
LuggMarkerView *markerView = annotation.markerView;
|
|
449
|
+
|
|
450
|
+
if (!annotationView || !markerView)
|
|
451
|
+
return;
|
|
452
|
+
|
|
453
|
+
[self applyMarkerStyle:markerView annotationView:annotationView];
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
#pragma mark - Polyline Management
|
|
457
|
+
|
|
458
|
+
- (void)addPolylineView:(LuggPolylineView *)polylineView {
|
|
459
|
+
polylineView.delegate = self;
|
|
460
|
+
[self addPolylineOverlayToMap:polylineView];
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
- (void)removePolylineView:(LuggPolylineView *)polylineView {
|
|
464
|
+
polylineView.delegate = nil;
|
|
465
|
+
MKPolyline *polyline = (MKPolyline *)polylineView.polyline;
|
|
466
|
+
if (polyline) {
|
|
467
|
+
[_overlayToPolylineMap removeObjectForKey:polyline];
|
|
468
|
+
[_mapView removeOverlay:polyline];
|
|
469
|
+
polylineView.polyline = nil;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
- (void)syncPolylineView:(LuggPolylineView *)polylineView {
|
|
474
|
+
if (!_mapView)
|
|
475
|
+
return;
|
|
476
|
+
|
|
477
|
+
MKPolylineAnimator *renderer = (MKPolylineAnimator *)polylineView.renderer;
|
|
478
|
+
MKPolyline *oldPolyline = (MKPolyline *)polylineView.polyline;
|
|
479
|
+
|
|
480
|
+
NSArray<CLLocation *> *coordinates = polylineView.coordinates;
|
|
481
|
+
if (coordinates.count == 0) {
|
|
482
|
+
if (renderer) {
|
|
483
|
+
renderer.animated = NO;
|
|
484
|
+
}
|
|
485
|
+
if (oldPolyline) {
|
|
486
|
+
[_overlayToPolylineMap removeObjectForKey:oldPolyline];
|
|
487
|
+
[_mapView removeOverlay:oldPolyline];
|
|
488
|
+
polylineView.polyline = nil;
|
|
489
|
+
polylineView.renderer = nil;
|
|
490
|
+
}
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
|
|
495
|
+
sizeof(CLLocationCoordinate2D) * coordinates.count);
|
|
496
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
497
|
+
coords[i] = coordinates[i].coordinate;
|
|
498
|
+
}
|
|
499
|
+
MKPolyline *newPolyline =
|
|
500
|
+
[MKPolyline polylineWithCoordinates:coords count:coordinates.count];
|
|
501
|
+
free(coords);
|
|
502
|
+
|
|
503
|
+
polylineView.polyline = newPolyline;
|
|
504
|
+
[_overlayToPolylineMap setObject:polylineView forKey:newPolyline];
|
|
505
|
+
|
|
506
|
+
if (renderer && oldPolyline) {
|
|
507
|
+
[_overlayToPolylineMap removeObjectForKey:oldPolyline];
|
|
508
|
+
[_mapView removeOverlay:oldPolyline];
|
|
509
|
+
[self insertOverlay:newPolyline withZIndex:polylineView.zIndex];
|
|
510
|
+
[renderer updatePolyline:newPolyline];
|
|
511
|
+
renderer.lineWidth = polylineView.strokeWidth;
|
|
512
|
+
renderer.strokeColor = polylineView.strokeColors.firstObject;
|
|
513
|
+
renderer.strokeColors =
|
|
514
|
+
polylineView.strokeColors.count > 1 ? polylineView.strokeColors : nil;
|
|
515
|
+
renderer.animatedOptions = polylineView.animatedOptions;
|
|
516
|
+
renderer.animated = polylineView.animated;
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if (oldPolyline) {
|
|
521
|
+
[_overlayToPolylineMap removeObjectForKey:oldPolyline];
|
|
522
|
+
[_mapView removeOverlay:oldPolyline];
|
|
523
|
+
}
|
|
524
|
+
[self insertOverlay:newPolyline withZIndex:polylineView.zIndex];
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
- (void)addPolylineOverlayToMap:(LuggPolylineView *)polylineView {
|
|
528
|
+
if (!_mapView)
|
|
529
|
+
return;
|
|
530
|
+
|
|
531
|
+
NSArray<CLLocation *> *coordinates = polylineView.coordinates;
|
|
532
|
+
if (coordinates.count == 0)
|
|
533
|
+
return;
|
|
534
|
+
|
|
535
|
+
CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
|
|
536
|
+
sizeof(CLLocationCoordinate2D) * coordinates.count);
|
|
537
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
538
|
+
coords[i] = coordinates[i].coordinate;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords
|
|
542
|
+
count:coordinates.count];
|
|
543
|
+
free(coords);
|
|
544
|
+
|
|
545
|
+
polylineView.polyline = polyline;
|
|
546
|
+
[_overlayToPolylineMap setObject:polylineView forKey:polyline];
|
|
547
|
+
[self insertOverlay:polyline withZIndex:polylineView.zIndex];
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
- (void)insertOverlay:(id<MKOverlay>)overlay withZIndex:(NSInteger)zIndex {
|
|
551
|
+
if (zIndex == 0) {
|
|
552
|
+
[_mapView addOverlay:overlay];
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
NSArray<id<MKOverlay>> *overlays = _mapView.overlays;
|
|
557
|
+
NSInteger insertIndex = overlays.count;
|
|
558
|
+
|
|
559
|
+
for (NSInteger i = 0; i < overlays.count; i++) {
|
|
560
|
+
LuggPolylineView *existingPolylineView =
|
|
561
|
+
[_overlayToPolylineMap objectForKey:overlays[i]];
|
|
562
|
+
if (existingPolylineView && existingPolylineView.zIndex > zIndex) {
|
|
563
|
+
insertIndex = i;
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
[_mapView insertOverlay:overlay atIndex:insertIndex];
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
#pragma mark - Lifecycle
|
|
572
|
+
|
|
573
|
+
- (void)pauseAnimations {
|
|
574
|
+
for (LuggPolylineView *polylineView in _overlayToPolylineMap
|
|
575
|
+
.objectEnumerator) {
|
|
576
|
+
MKPolylineAnimator *renderer = (MKPolylineAnimator *)polylineView.renderer;
|
|
577
|
+
[renderer pause];
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
- (void)resumeAnimations {
|
|
582
|
+
for (LuggPolylineView *polylineView in _overlayToPolylineMap
|
|
583
|
+
.objectEnumerator) {
|
|
584
|
+
MKPolylineAnimator *renderer = (MKPolylineAnimator *)polylineView.renderer;
|
|
585
|
+
[renderer resume];
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
#pragma mark - Commands
|
|
590
|
+
|
|
591
|
+
- (void)moveCamera:(double)latitude
|
|
592
|
+
longitude:(double)longitude
|
|
593
|
+
zoom:(double)zoom
|
|
594
|
+
duration:(double)duration {
|
|
595
|
+
if (!_mapView)
|
|
596
|
+
return;
|
|
597
|
+
|
|
598
|
+
double targetZoom = zoom > 0 ? zoom : _mapView.zoomLevel;
|
|
599
|
+
|
|
600
|
+
if (duration < 0) {
|
|
601
|
+
[_mapView
|
|
602
|
+
setCenterCoordinate:CLLocationCoordinate2DMake(latitude, longitude)
|
|
603
|
+
zoomLevel:targetZoom
|
|
604
|
+
animated:YES];
|
|
605
|
+
} else if (duration > 0) {
|
|
606
|
+
CLLocationCoordinate2D center =
|
|
607
|
+
CLLocationCoordinate2DMake(latitude, longitude);
|
|
608
|
+
MKCoordinateRegion region = [_mapView regionForCenterCoordinate:center
|
|
609
|
+
zoomLevel:targetZoom];
|
|
610
|
+
[UIView animateWithDuration:duration / 1000.0
|
|
611
|
+
animations:^{
|
|
612
|
+
[self->_mapView setRegion:region animated:NO];
|
|
613
|
+
}];
|
|
614
|
+
} else {
|
|
615
|
+
[_mapView
|
|
616
|
+
setCenterCoordinate:CLLocationCoordinate2DMake(latitude, longitude)
|
|
617
|
+
zoomLevel:targetZoom
|
|
618
|
+
animated:NO];
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
- (void)fitCoordinates:(NSArray *)coordinates
|
|
623
|
+
edgeInsetsTop:(double)edgeInsetsTop
|
|
624
|
+
edgeInsetsLeft:(double)edgeInsetsLeft
|
|
625
|
+
edgeInsetsBottom:(double)edgeInsetsBottom
|
|
626
|
+
edgeInsetsRight:(double)edgeInsetsRight
|
|
627
|
+
duration:(double)duration {
|
|
628
|
+
if (!_mapView || coordinates.count == 0)
|
|
629
|
+
return;
|
|
630
|
+
|
|
631
|
+
CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
|
|
632
|
+
sizeof(CLLocationCoordinate2D) * coordinates.count);
|
|
633
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
634
|
+
NSDictionary *coord = coordinates[i];
|
|
635
|
+
coords[i] = CLLocationCoordinate2DMake([coord[@"latitude"] doubleValue],
|
|
636
|
+
[coord[@"longitude"] doubleValue]);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
MKMapRect mapRect = MKMapRectNull;
|
|
640
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
641
|
+
MKMapPoint point = MKMapPointForCoordinate(coords[i]);
|
|
642
|
+
MKMapRect pointRect = MKMapRectMake(point.x, point.y, 0, 0);
|
|
643
|
+
mapRect = MKMapRectUnion(mapRect, pointRect);
|
|
644
|
+
}
|
|
645
|
+
free(coords);
|
|
646
|
+
|
|
647
|
+
UIEdgeInsets insets = UIEdgeInsetsMake(edgeInsetsTop, edgeInsetsLeft,
|
|
648
|
+
edgeInsetsBottom, edgeInsetsRight);
|
|
649
|
+
|
|
650
|
+
if (duration < 0) {
|
|
651
|
+
[_mapView setVisibleMapRect:mapRect edgePadding:insets animated:YES];
|
|
652
|
+
} else if (duration > 0) {
|
|
653
|
+
[UIView animateWithDuration:duration / 1000.0
|
|
654
|
+
animations:^{
|
|
655
|
+
[self->_mapView setVisibleMapRect:mapRect
|
|
656
|
+
edgePadding:insets
|
|
657
|
+
animated:NO];
|
|
658
|
+
}];
|
|
659
|
+
} else {
|
|
660
|
+
[_mapView setVisibleMapRect:mapRect edgePadding:insets animated:NO];
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
@end
|