@lugg/maps 0.2.0-alpha.9 → 1.0.0-beta.1
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 -20
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/luggmaps/LuggCalloutView.kt +74 -0
- package/android/src/main/java/com/luggmaps/LuggCalloutViewManager.kt +38 -0
- package/android/src/main/java/com/luggmaps/LuggMapView.kt +290 -0
- package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +99 -36
- package/android/src/main/java/com/luggmaps/LuggMapWrapperView.kt +11 -14
- package/android/src/main/java/com/luggmaps/LuggMarkerView.kt +187 -21
- package/android/src/main/java/com/luggmaps/LuggMarkerViewManager.kt +28 -0
- package/android/src/main/java/com/luggmaps/LuggPackage.kt +8 -4
- package/android/src/main/java/com/luggmaps/LuggPolygonView.kt +85 -0
- package/android/src/main/java/com/luggmaps/LuggPolygonViewManager.kt +100 -0
- 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/core/GoogleMapProvider.kt +874 -0
- package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +60 -0
- package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +89 -24
- package/android/src/main/java/com/luggmaps/events/LongPressEvent.kt +29 -0
- package/android/src/main/java/com/luggmaps/events/MarkerDragEvent.kt +41 -0
- package/android/src/main/java/com/luggmaps/events/MarkerPressEvent.kt +34 -0
- package/android/src/main/java/com/luggmaps/events/PolygonPressEvent.kt +12 -0
- package/android/src/main/java/com/luggmaps/events/PressEvent.kt +29 -0
- package/ios/LuggCalloutView.h +23 -0
- package/ios/LuggCalloutView.mm +145 -0
- package/ios/LuggMapView.h +9 -0
- package/ios/LuggMapView.mm +343 -0
- package/ios/LuggMarkerView.h +15 -0
- package/ios/LuggMarkerView.mm +136 -2
- package/ios/LuggPolygonView.h +31 -0
- package/ios/LuggPolygonView.mm +151 -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 +1173 -0
- package/ios/core/GMSPolylineAnimator.h +3 -0
- package/ios/core/GMSPolylineAnimator.m +101 -15
- package/ios/core/GoogleMapProvider.h +13 -0
- package/ios/core/GoogleMapProvider.mm +798 -0
- package/ios/core/LuggAnnotationView.h +12 -0
- package/ios/core/LuggAnnotationView.mm +55 -0
- package/ios/core/MKPolylineAnimator.h +4 -0
- package/ios/core/MKPolylineAnimator.m +167 -42
- package/ios/core/MapProviderDelegate.h +84 -0
- package/ios/core/PolylineAnimatorBase.h +24 -1
- package/ios/core/PolylineAnimatorBase.m +82 -19
- package/ios/events/LongPressEvent.h +29 -0
- package/ios/events/MarkerDragEvent.h +69 -0
- package/ios/events/MarkerPressEvent.h +29 -0
- package/ios/events/PolygonPressEvent.h +20 -0
- package/ios/events/PressEvent.h +29 -0
- package/ios/extensions/MKMapView+Zoom.h +2 -0
- package/ios/extensions/MKMapView+Zoom.m +14 -4
- package/lib/module/MapProvider.js +2 -4
- package/lib/module/MapProvider.js.map +1 -1
- package/lib/module/MapProvider.web.js +14 -7
- package/lib/module/MapProvider.web.js.map +1 -1
- package/lib/module/MapView.js +33 -16
- package/lib/module/MapView.js.map +1 -1
- package/lib/module/MapView.web.js +296 -181
- package/lib/module/MapView.web.js.map +1 -1
- package/lib/module/components/GeoJson.js +159 -0
- package/lib/module/components/GeoJson.js.map +1 -0
- package/lib/module/components/GeoJson.types.js +4 -0
- package/lib/module/components/GeoJson.types.js.map +1 -0
- package/lib/module/components/Marker.js +49 -8
- package/lib/module/components/Marker.js.map +1 -1
- package/lib/module/components/Marker.types.js +4 -0
- package/lib/module/components/Marker.types.js.map +1 -0
- package/lib/module/components/Marker.web.js +159 -24
- package/lib/module/components/Marker.web.js.map +1 -1
- package/lib/module/components/Polygon.js +46 -0
- package/lib/module/components/Polygon.js.map +1 -0
- package/lib/module/components/Polygon.types.js +4 -0
- package/lib/module/components/Polygon.types.js.map +1 -0
- package/lib/module/components/Polygon.web.js +87 -0
- package/lib/module/components/Polygon.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.types.js +4 -0
- package/lib/module/components/Polyline.types.js.map +1 -0
- package/lib/module/components/Polyline.web.js +108 -31
- package/lib/module/components/Polyline.web.js.map +1 -1
- package/lib/module/components/index.js +4 -2
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/components/index.web.js +2 -0
- package/lib/module/components/index.web.js.map +1 -1
- package/lib/module/fabric/LuggCalloutViewNativeComponent.ts +20 -0
- package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +43 -7
- package/lib/module/fabric/LuggMarkerViewNativeComponent.ts +49 -1
- package/lib/module/fabric/LuggPolygonViewNativeComponent.ts +25 -0
- package/lib/module/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/lib/module/index.js +4 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +4 -1
- package/lib/module/index.web.js.map +1 -1
- package/lib/typescript/src/MapProvider.d.ts +1 -1
- package/lib/typescript/src/MapProvider.d.ts.map +1 -1
- package/lib/typescript/src/MapProvider.web.d.ts +23 -1
- package/lib/typescript/src/MapProvider.web.d.ts.map +1 -1
- 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 +35 -9
- package/lib/typescript/src/MapView.types.d.ts.map +1 -1
- package/lib/typescript/src/MapView.web.d.ts +2 -11
- package/lib/typescript/src/MapView.web.d.ts.map +1 -1
- package/lib/typescript/src/components/GeoJson.d.ts +4 -0
- package/lib/typescript/src/components/GeoJson.d.ts.map +1 -0
- package/lib/typescript/src/components/GeoJson.types.d.ts +89 -0
- package/lib/typescript/src/components/GeoJson.types.d.ts.map +1 -0
- package/lib/typescript/src/components/Marker.d.ts +6 -33
- package/lib/typescript/src/components/Marker.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.types.d.ts +100 -0
- package/lib/typescript/src/components/Marker.types.d.ts.map +1 -0
- package/lib/typescript/src/components/Marker.web.d.ts +2 -5
- package/lib/typescript/src/components/Marker.web.d.ts.map +1 -1
- package/lib/typescript/src/components/Polygon.d.ts +10 -0
- package/lib/typescript/src/components/Polygon.d.ts.map +1 -0
- package/lib/typescript/src/components/Polygon.types.d.ts +33 -0
- package/lib/typescript/src/components/Polygon.types.d.ts.map +1 -0
- package/lib/typescript/src/components/Polygon.web.d.ts +3 -0
- package/lib/typescript/src/components/Polygon.web.d.ts.map +1 -0
- package/lib/typescript/src/components/Polyline.d.ts +6 -21
- package/lib/typescript/src/components/Polyline.d.ts.map +1 -1
- package/lib/typescript/src/components/Polyline.types.d.ts +53 -0
- package/lib/typescript/src/components/Polyline.types.d.ts.map +1 -0
- package/lib/typescript/src/components/Polyline.web.d.ts +2 -5
- package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -1
- package/lib/typescript/src/components/index.d.ts +8 -2
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/components/index.web.d.ts +6 -2
- package/lib/typescript/src/components/index.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggCalloutViewNativeComponent.d.ts +13 -0
- package/lib/typescript/src/fabric/LuggCalloutViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +30 -4
- package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts +45 -1
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggPolygonViewNativeComponent.d.ts +18 -0
- package/lib/typescript/src/fabric/LuggPolygonViewNativeComponent.d.ts.map +1 -0
- 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 +11 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +9 -1
- package/lib/typescript/src/index.web.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +11 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +11 -9
- package/src/MapProvider.tsx +1 -3
- package/src/MapProvider.web.tsx +22 -3
- package/src/MapView.tsx +32 -26
- package/src/MapView.types.ts +43 -9
- package/src/MapView.web.tsx +368 -210
- package/src/components/GeoJson.tsx +221 -0
- package/src/components/GeoJson.types.ts +118 -0
- package/src/components/Marker.tsx +75 -38
- package/src/components/Marker.types.ts +102 -0
- package/src/components/Marker.web.tsx +197 -19
- package/src/components/Polygon.tsx +52 -0
- package/src/components/Polygon.types.ts +33 -0
- package/src/components/Polygon.web.tsx +104 -0
- package/src/components/Polyline.tsx +23 -22
- package/src/components/Polyline.types.ts +55 -0
- package/src/components/Polyline.web.tsx +151 -37
- package/src/components/index.ts +17 -2
- package/src/components/index.web.ts +6 -2
- package/src/fabric/LuggCalloutViewNativeComponent.ts +20 -0
- package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +43 -7
- package/src/fabric/LuggMarkerViewNativeComponent.ts +49 -1
- package/src/fabric/LuggPolygonViewNativeComponent.ts +25 -0
- package/src/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/src/index.ts +30 -1
- package/src/index.web.ts +16 -1
- package/src/types.ts +13 -0
- package/android/src/main/java/com/luggmaps/LuggGoogleMapView.kt +0 -511
- package/ios/LuggAppleMapView.h +0 -16
- package/ios/LuggAppleMapView.mm +0 -592
- package/ios/LuggGoogleMapView.h +0 -13
- package/ios/LuggGoogleMapView.mm +0 -455
- 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,1173 @@
|
|
|
1
|
+
#import "AppleMapProvider.h"
|
|
2
|
+
#import "../LuggCalloutView.h"
|
|
3
|
+
#import "../LuggMarkerView.h"
|
|
4
|
+
#import "../LuggPolygonView.h"
|
|
5
|
+
#import "../LuggPolylineView.h"
|
|
6
|
+
#import "../extensions/MKMapView+Zoom.h"
|
|
7
|
+
#import "LuggAnnotationView.h"
|
|
8
|
+
#import "MKPolylineAnimator.h"
|
|
9
|
+
|
|
10
|
+
@interface AppleMarkerAnnotation : NSObject <MKAnnotation>
|
|
11
|
+
@property(nonatomic, assign) CLLocationCoordinate2D coordinate;
|
|
12
|
+
@property(nonatomic, copy, nullable) NSString *title;
|
|
13
|
+
@property(nonatomic, copy, nullable) NSString *subtitle;
|
|
14
|
+
@property(nonatomic, strong) LuggMarkerView *markerView;
|
|
15
|
+
@property(nonatomic, weak) MKAnnotationView *annotationView;
|
|
16
|
+
@end
|
|
17
|
+
|
|
18
|
+
@implementation AppleMarkerAnnotation
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
@implementation LuggAppleMapViewContent
|
|
22
|
+
@end
|
|
23
|
+
|
|
24
|
+
@interface AppleMapProvider () <
|
|
25
|
+
LuggMarkerViewDelegate, LuggCalloutViewDelegate, LuggPolylineViewDelegate,
|
|
26
|
+
LuggPolygonViewDelegate, UIGestureRecognizerDelegate>
|
|
27
|
+
@end
|
|
28
|
+
|
|
29
|
+
@implementation AppleMapProvider {
|
|
30
|
+
UIView *_wrapperView;
|
|
31
|
+
LuggAppleMapViewContent *_mapView;
|
|
32
|
+
BOOL _isMapReady;
|
|
33
|
+
BOOL _isDragging;
|
|
34
|
+
double _minZoom;
|
|
35
|
+
double _maxZoom;
|
|
36
|
+
NSMapTable<id<MKOverlay>, LuggPolylineView *> *_overlayToPolylineMap;
|
|
37
|
+
NSMapTable<id<MKOverlay>, LuggPolygonView *> *_overlayToPolygonMap;
|
|
38
|
+
UITapGestureRecognizer *_tapGesture;
|
|
39
|
+
UILongPressGestureRecognizer *_longPressGesture;
|
|
40
|
+
LuggMarkerView *_activeNonBubbledMarker;
|
|
41
|
+
BOOL _isReselectingAnnotation;
|
|
42
|
+
// Edge insets animation
|
|
43
|
+
CADisplayLink *_edgeInsetsDisplayLink;
|
|
44
|
+
UIEdgeInsets _edgeInsetsFrom;
|
|
45
|
+
UIEdgeInsets _edgeInsetsTo;
|
|
46
|
+
CFTimeInterval _edgeInsetsAnimationStart;
|
|
47
|
+
CFTimeInterval _edgeInsetsAnimationDuration;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@synthesize delegate = _delegate;
|
|
51
|
+
|
|
52
|
+
- (instancetype)init {
|
|
53
|
+
if (self = [super init]) {
|
|
54
|
+
_overlayToPolylineMap = [NSMapTable strongToWeakObjectsMapTable];
|
|
55
|
+
_overlayToPolygonMap = [NSMapTable strongToWeakObjectsMapTable];
|
|
56
|
+
}
|
|
57
|
+
return self;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
- (BOOL)isMapReady {
|
|
61
|
+
return _isMapReady;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
- (MKMapView *)mapView {
|
|
65
|
+
return _mapView;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#pragma mark - MapProvider
|
|
69
|
+
|
|
70
|
+
- (void)initializeMapInView:(UIView *)wrapperView
|
|
71
|
+
initialCoordinate:(CLLocationCoordinate2D)coordinate
|
|
72
|
+
initialZoom:(double)zoom {
|
|
73
|
+
if (_mapView)
|
|
74
|
+
return;
|
|
75
|
+
|
|
76
|
+
_mapView = [[LuggAppleMapViewContent alloc] initWithFrame:wrapperView.bounds];
|
|
77
|
+
_mapView.autoresizingMask =
|
|
78
|
+
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
79
|
+
_mapView.delegate = self;
|
|
80
|
+
_mapView.insetsLayoutMarginsFromSafeArea = NO;
|
|
81
|
+
|
|
82
|
+
[self applyZoomRange];
|
|
83
|
+
|
|
84
|
+
_tapGesture =
|
|
85
|
+
[[UITapGestureRecognizer alloc] initWithTarget:self
|
|
86
|
+
action:@selector(handleTap:)];
|
|
87
|
+
_tapGesture.cancelsTouchesInView = NO;
|
|
88
|
+
_tapGesture.delegate = self;
|
|
89
|
+
[_mapView addGestureRecognizer:_tapGesture];
|
|
90
|
+
|
|
91
|
+
_longPressGesture = [[UILongPressGestureRecognizer alloc]
|
|
92
|
+
initWithTarget:self
|
|
93
|
+
action:@selector(handleLongPress:)];
|
|
94
|
+
_longPressGesture.delegate = self;
|
|
95
|
+
[_mapView addGestureRecognizer:_longPressGesture];
|
|
96
|
+
|
|
97
|
+
[_tapGesture requireGestureRecognizerToFail:_longPressGesture];
|
|
98
|
+
|
|
99
|
+
_wrapperView = wrapperView;
|
|
100
|
+
[wrapperView addSubview:_mapView];
|
|
101
|
+
|
|
102
|
+
MKCoordinateRegion region = [_mapView regionForCenterCoordinate:coordinate
|
|
103
|
+
zoomLevel:zoom];
|
|
104
|
+
[_mapView setRegion:region animated:NO];
|
|
105
|
+
|
|
106
|
+
_isMapReady = YES;
|
|
107
|
+
|
|
108
|
+
[_delegate mapProviderDidReady];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
- (void)destroy {
|
|
112
|
+
[self dismissNonBubbledCallout];
|
|
113
|
+
[self stopEdgeInsetsAnimation];
|
|
114
|
+
if (_tapGesture) {
|
|
115
|
+
[_mapView removeGestureRecognizer:_tapGesture];
|
|
116
|
+
_tapGesture = nil;
|
|
117
|
+
}
|
|
118
|
+
if (_longPressGesture) {
|
|
119
|
+
[_mapView removeGestureRecognizer:_longPressGesture];
|
|
120
|
+
_longPressGesture = nil;
|
|
121
|
+
}
|
|
122
|
+
[_mapView removeFromSuperview];
|
|
123
|
+
_mapView = nil;
|
|
124
|
+
_isMapReady = NO;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
#pragma mark - Props
|
|
128
|
+
|
|
129
|
+
- (void)setZoomEnabled:(BOOL)enabled {
|
|
130
|
+
_mapView.zoomEnabled = enabled;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
- (void)setScrollEnabled:(BOOL)enabled {
|
|
134
|
+
_mapView.scrollEnabled = enabled;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
- (void)setRotateEnabled:(BOOL)enabled {
|
|
138
|
+
_mapView.rotateEnabled = enabled;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
- (void)setPitchEnabled:(BOOL)enabled {
|
|
142
|
+
_mapView.pitchEnabled = enabled;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
- (void)setUserLocationEnabled:(BOOL)enabled {
|
|
146
|
+
_mapView.showsUserLocation = enabled;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
- (void)setTheme:(NSInteger)theme {
|
|
150
|
+
switch (theme) {
|
|
151
|
+
case 1: // Dark
|
|
152
|
+
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
|
|
153
|
+
break;
|
|
154
|
+
case 0: // Light
|
|
155
|
+
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
|
|
156
|
+
break;
|
|
157
|
+
default: // System
|
|
158
|
+
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
- (void)setMinZoom:(double)minZoom {
|
|
164
|
+
_minZoom = minZoom;
|
|
165
|
+
[self applyZoomRange];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
- (void)setMaxZoom:(double)maxZoom {
|
|
169
|
+
_maxZoom = maxZoom;
|
|
170
|
+
[self applyZoomRange];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets
|
|
174
|
+
oldEdgeInsets:(UIEdgeInsets)oldEdgeInsets {
|
|
175
|
+
CGFloat oldOffsetX = (oldEdgeInsets.left - oldEdgeInsets.right) / 2.0;
|
|
176
|
+
CGFloat oldOffsetY = (oldEdgeInsets.top - oldEdgeInsets.bottom) / 2.0;
|
|
177
|
+
CGFloat newOffsetX = (edgeInsets.left - edgeInsets.right) / 2.0;
|
|
178
|
+
CGFloat newOffsetY = (edgeInsets.top - edgeInsets.bottom) / 2.0;
|
|
179
|
+
|
|
180
|
+
CGFloat deltaX = newOffsetX - oldOffsetX;
|
|
181
|
+
CGFloat deltaY = newOffsetY - oldOffsetY;
|
|
182
|
+
|
|
183
|
+
_mapView.layoutMargins = edgeInsets;
|
|
184
|
+
|
|
185
|
+
if (deltaX != 0 || deltaY != 0) {
|
|
186
|
+
CLLocationCoordinate2D currentCenter = _mapView.centerCoordinate;
|
|
187
|
+
CGPoint centerPoint = [_mapView convertCoordinate:currentCenter
|
|
188
|
+
toPointToView:_mapView];
|
|
189
|
+
CGPoint newPoint =
|
|
190
|
+
CGPointMake(centerPoint.x - deltaX, centerPoint.y - deltaY);
|
|
191
|
+
CLLocationCoordinate2D newCenter = [_mapView convertPoint:newPoint
|
|
192
|
+
toCoordinateFromView:_mapView];
|
|
193
|
+
[_mapView setCenterCoordinate:newCenter animated:NO];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets
|
|
198
|
+
oldEdgeInsets:(UIEdgeInsets)oldEdgeInsets
|
|
199
|
+
duration:(double)duration {
|
|
200
|
+
[self stopEdgeInsetsAnimation];
|
|
201
|
+
|
|
202
|
+
if (duration != 0 && _mapView) {
|
|
203
|
+
double actualDuration = duration < 0 ? 0.3 : duration / 1000.0;
|
|
204
|
+
_edgeInsetsFrom = oldEdgeInsets;
|
|
205
|
+
_edgeInsetsTo = edgeInsets;
|
|
206
|
+
_edgeInsetsAnimationDuration = actualDuration;
|
|
207
|
+
_edgeInsetsAnimationStart = CACurrentMediaTime();
|
|
208
|
+
|
|
209
|
+
_edgeInsetsDisplayLink = [CADisplayLink
|
|
210
|
+
displayLinkWithTarget:self
|
|
211
|
+
selector:@selector(edgeInsetsAnimationTick:)];
|
|
212
|
+
[_edgeInsetsDisplayLink addToRunLoop:[NSRunLoop mainRunLoop]
|
|
213
|
+
forMode:NSRunLoopCommonModes];
|
|
214
|
+
} else {
|
|
215
|
+
[self setEdgeInsets:edgeInsets oldEdgeInsets:oldEdgeInsets];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
- (void)edgeInsetsAnimationTick:(CADisplayLink *)displayLink {
|
|
220
|
+
CFTimeInterval elapsed = CACurrentMediaTime() - _edgeInsetsAnimationStart;
|
|
221
|
+
CGFloat progress = MIN(elapsed / _edgeInsetsAnimationDuration, 1.0);
|
|
222
|
+
|
|
223
|
+
// Ease out cubic
|
|
224
|
+
CGFloat t = 1.0 - (1.0 - progress) * (1.0 - progress) * (1.0 - progress);
|
|
225
|
+
|
|
226
|
+
UIEdgeInsets current = UIEdgeInsetsMake(
|
|
227
|
+
_edgeInsetsFrom.top + (_edgeInsetsTo.top - _edgeInsetsFrom.top) * t,
|
|
228
|
+
_edgeInsetsFrom.left + (_edgeInsetsTo.left - _edgeInsetsFrom.left) * t,
|
|
229
|
+
_edgeInsetsFrom.bottom +
|
|
230
|
+
(_edgeInsetsTo.bottom - _edgeInsetsFrom.bottom) * t,
|
|
231
|
+
_edgeInsetsFrom.right +
|
|
232
|
+
(_edgeInsetsTo.right - _edgeInsetsFrom.right) * t);
|
|
233
|
+
|
|
234
|
+
[self setEdgeInsets:current oldEdgeInsets:_mapView.layoutMargins];
|
|
235
|
+
|
|
236
|
+
if (progress >= 1.0) {
|
|
237
|
+
[self stopEdgeInsetsAnimation];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
- (void)stopEdgeInsetsAnimation {
|
|
242
|
+
[_edgeInsetsDisplayLink invalidate];
|
|
243
|
+
_edgeInsetsDisplayLink = nil;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
- (CLLocationDistance)cameraDistanceForZoomLevel:(double)zoomLevel {
|
|
247
|
+
return 128000000.0 / pow(2, zoomLevel);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
- (void)applyZoomRange {
|
|
251
|
+
if (!_mapView)
|
|
252
|
+
return;
|
|
253
|
+
|
|
254
|
+
CLLocationDistance minDistance =
|
|
255
|
+
_maxZoom > 0 ? [self cameraDistanceForZoomLevel:_maxZoom] : 0;
|
|
256
|
+
CLLocationDistance maxDistance =
|
|
257
|
+
_minZoom > 0 ? [self cameraDistanceForZoomLevel:_minZoom] : -1;
|
|
258
|
+
|
|
259
|
+
MKMapCameraZoomRange *zoomRange = [[MKMapCameraZoomRange alloc]
|
|
260
|
+
initWithMinCenterCoordinateDistance:minDistance
|
|
261
|
+
maxCenterCoordinateDistance:maxDistance];
|
|
262
|
+
_mapView.cameraZoomRange = zoomRange;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
- (LuggPolygonView *)hitTestPolygonAtPoint:(CGPoint)point {
|
|
266
|
+
CLLocationCoordinate2D tapCoordinate = [_mapView convertPoint:point
|
|
267
|
+
toCoordinateFromView:_mapView];
|
|
268
|
+
MKMapPoint mapPoint = MKMapPointForCoordinate(tapCoordinate);
|
|
269
|
+
CGPoint mapPointAsCGP = CGPointMake(mapPoint.x, mapPoint.y);
|
|
270
|
+
|
|
271
|
+
NSArray<id<MKOverlay>> *overlays = _mapView.overlays;
|
|
272
|
+
for (NSInteger i = overlays.count - 1; i >= 0; i--) {
|
|
273
|
+
id<MKOverlay> overlay = overlays[i];
|
|
274
|
+
if (![overlay isKindOfClass:[MKPolygon class]])
|
|
275
|
+
continue;
|
|
276
|
+
|
|
277
|
+
LuggPolygonView *polygonView = [_overlayToPolygonMap objectForKey:overlay];
|
|
278
|
+
if (!polygonView || !polygonView.tappable)
|
|
279
|
+
continue;
|
|
280
|
+
|
|
281
|
+
NSArray<CLLocation *> *coordinates = polygonView.coordinates;
|
|
282
|
+
if (coordinates.count == 0)
|
|
283
|
+
continue;
|
|
284
|
+
|
|
285
|
+
CGMutablePathRef path = CGPathCreateMutable();
|
|
286
|
+
for (NSUInteger j = 0; j < coordinates.count; j++) {
|
|
287
|
+
MKMapPoint mp = MKMapPointForCoordinate(coordinates[j].coordinate);
|
|
288
|
+
if (j == 0) {
|
|
289
|
+
CGPathMoveToPoint(path, NULL, mp.x, mp.y);
|
|
290
|
+
} else {
|
|
291
|
+
CGPathAddLineToPoint(path, NULL, mp.x, mp.y);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
CGPathCloseSubpath(path);
|
|
295
|
+
|
|
296
|
+
for (NSArray<CLLocation *> *hole in polygonView.holes) {
|
|
297
|
+
for (NSUInteger j = 0; j < hole.count; j++) {
|
|
298
|
+
MKMapPoint mp = MKMapPointForCoordinate(hole[j].coordinate);
|
|
299
|
+
if (j == 0) {
|
|
300
|
+
CGPathMoveToPoint(path, NULL, mp.x, mp.y);
|
|
301
|
+
} else {
|
|
302
|
+
CGPathAddLineToPoint(path, NULL, mp.x, mp.y);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
CGPathCloseSubpath(path);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
BOOL contains = CGPathContainsPoint(path, NULL, mapPointAsCGP, YES);
|
|
309
|
+
CGPathRelease(path);
|
|
310
|
+
|
|
311
|
+
if (contains)
|
|
312
|
+
return polygonView;
|
|
313
|
+
}
|
|
314
|
+
return nil;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
- (BOOL)hitTestAnnotationAtPoint:(CGPoint)point {
|
|
318
|
+
for (id<MKAnnotation> annotation in _mapView.annotations) {
|
|
319
|
+
MKAnnotationView *view = [_mapView viewForAnnotation:annotation];
|
|
320
|
+
if (!view)
|
|
321
|
+
continue;
|
|
322
|
+
CGPoint local = [view convertPoint:point fromView:_mapView];
|
|
323
|
+
if ([view pointInside:local withEvent:nil])
|
|
324
|
+
return YES;
|
|
325
|
+
}
|
|
326
|
+
return NO;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
- (BOOL)hitTestCalloutAtPoint:(CGPoint)point {
|
|
330
|
+
if (!_activeNonBubbledMarker)
|
|
331
|
+
return NO;
|
|
332
|
+
|
|
333
|
+
UIView *contentView = _activeNonBubbledMarker.calloutView.contentView;
|
|
334
|
+
CGPoint local = [contentView convertPoint:point fromView:_mapView];
|
|
335
|
+
return [contentView pointInside:local withEvent:nil];
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
- (void)handleTap:(UITapGestureRecognizer *)gesture {
|
|
339
|
+
if (gesture.state != UIGestureRecognizerStateEnded)
|
|
340
|
+
return;
|
|
341
|
+
|
|
342
|
+
CGPoint point = [gesture locationInView:_mapView];
|
|
343
|
+
if ([self hitTestCalloutAtPoint:point])
|
|
344
|
+
return;
|
|
345
|
+
|
|
346
|
+
[self dismissNonBubbledCallout];
|
|
347
|
+
|
|
348
|
+
if ([self hitTestAnnotationAtPoint:point])
|
|
349
|
+
return;
|
|
350
|
+
|
|
351
|
+
LuggPolygonView *polygonView = [self hitTestPolygonAtPoint:point];
|
|
352
|
+
if (polygonView) {
|
|
353
|
+
[polygonView emitPressEvent];
|
|
354
|
+
} else {
|
|
355
|
+
CLLocationCoordinate2D coordinate = [_mapView convertPoint:point
|
|
356
|
+
toCoordinateFromView:_mapView];
|
|
357
|
+
[_delegate mapProviderDidPress:coordinate.latitude
|
|
358
|
+
longitude:coordinate.longitude
|
|
359
|
+
x:point.x
|
|
360
|
+
y:point.y];
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture {
|
|
365
|
+
if (gesture.state != UIGestureRecognizerStateBegan)
|
|
366
|
+
return;
|
|
367
|
+
|
|
368
|
+
CGPoint point = [gesture locationInView:_mapView];
|
|
369
|
+
CLLocationCoordinate2D coordinate = [_mapView convertPoint:point
|
|
370
|
+
toCoordinateFromView:_mapView];
|
|
371
|
+
[_delegate mapProviderDidLongPress:coordinate.latitude
|
|
372
|
+
longitude:coordinate.longitude
|
|
373
|
+
x:point.x
|
|
374
|
+
y:point.y];
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
|
|
378
|
+
shouldRecognizeSimultaneouslyWithGestureRecognizer:
|
|
379
|
+
(UIGestureRecognizer *)otherGestureRecognizer {
|
|
380
|
+
return YES;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
#pragma mark - MKMapViewDelegate
|
|
384
|
+
|
|
385
|
+
- (BOOL)isUserInteracting {
|
|
386
|
+
UIView *mapContainerView = _mapView.subviews.firstObject;
|
|
387
|
+
for (UIGestureRecognizer *gesture in mapContainerView.gestureRecognizers) {
|
|
388
|
+
if (gesture.state == UIGestureRecognizerStateBegan ||
|
|
389
|
+
gesture.state == UIGestureRecognizerStateChanged) {
|
|
390
|
+
return YES;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return NO;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
|
|
397
|
+
_isDragging = [self isUserInteracting];
|
|
398
|
+
if (_isDragging) {
|
|
399
|
+
for (LuggPolylineView *polylineView in _overlayToPolylineMap
|
|
400
|
+
.objectEnumerator) {
|
|
401
|
+
MKPolylineAnimator *renderer =
|
|
402
|
+
(MKPolylineAnimator *)polylineView.renderer;
|
|
403
|
+
[renderer pause];
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
- (void)mapViewDidChangeVisibleRegion:(MKMapView *)mapView {
|
|
409
|
+
[_delegate mapProviderDidMoveCamera:mapView.centerCoordinate.latitude
|
|
410
|
+
longitude:mapView.centerCoordinate.longitude
|
|
411
|
+
zoom:mapView.zoomLevel
|
|
412
|
+
gesture:_isDragging];
|
|
413
|
+
[self positionNonBubbledCallout];
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
|
|
417
|
+
BOOL wasDragging = _isDragging;
|
|
418
|
+
_isDragging = NO;
|
|
419
|
+
if (wasDragging) {
|
|
420
|
+
for (LuggPolylineView *polylineView in _overlayToPolylineMap
|
|
421
|
+
.objectEnumerator) {
|
|
422
|
+
MKPolylineAnimator *renderer =
|
|
423
|
+
(MKPolylineAnimator *)polylineView.renderer;
|
|
424
|
+
[renderer resume];
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
[_delegate mapProviderDidIdleCamera:mapView.centerCoordinate.latitude
|
|
428
|
+
longitude:mapView.centerCoordinate.longitude
|
|
429
|
+
zoom:mapView.zoomLevel
|
|
430
|
+
gesture:wasDragging];
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
- (MKAnnotationView *)mapView:(MKMapView *)mapView
|
|
434
|
+
viewForAnnotation:(id<MKAnnotation>)annotation {
|
|
435
|
+
if (![annotation isKindOfClass:[AppleMarkerAnnotation class]]) {
|
|
436
|
+
return nil;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
AppleMarkerAnnotation *markerAnnotation = (AppleMarkerAnnotation *)annotation;
|
|
440
|
+
LuggMarkerView *markerView = markerAnnotation.markerView;
|
|
441
|
+
|
|
442
|
+
if (!markerView) {
|
|
443
|
+
return nil;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (!markerView.hasCustomView) {
|
|
447
|
+
LuggMarkerAnnotationView *markerAnnotationView =
|
|
448
|
+
[[LuggMarkerAnnotationView alloc] initWithAnnotation:annotation
|
|
449
|
+
reuseIdentifier:nil];
|
|
450
|
+
markerAnnotationView.canShowCallout = YES;
|
|
451
|
+
markerAnnotationView.displayPriority = MKFeatureDisplayPriorityRequired;
|
|
452
|
+
markerAnnotationView.layer.zPosition = markerView.zIndex;
|
|
453
|
+
markerAnnotationView.zPriority = markerView.zIndex;
|
|
454
|
+
markerAnnotationView.draggable = markerView.draggable;
|
|
455
|
+
[self applyCalloutView:markerView annotationView:markerAnnotationView];
|
|
456
|
+
[self addCenterTapGesture:markerAnnotationView];
|
|
457
|
+
markerAnnotation.annotationView = markerAnnotationView;
|
|
458
|
+
return markerAnnotationView;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
LuggAnnotationView *annotationView =
|
|
462
|
+
[[LuggAnnotationView alloc] initWithAnnotation:annotation
|
|
463
|
+
reuseIdentifier:nil];
|
|
464
|
+
annotationView.canShowCallout = YES;
|
|
465
|
+
annotationView.displayPriority = MKFeatureDisplayPriorityRequired;
|
|
466
|
+
annotationView.layer.zPosition = markerView.zIndex;
|
|
467
|
+
annotationView.zPriority = markerView.zIndex;
|
|
468
|
+
annotationView.draggable = markerView.draggable;
|
|
469
|
+
[self addCenterTapGesture:annotationView];
|
|
470
|
+
|
|
471
|
+
[self applyCalloutView:markerView annotationView:annotationView];
|
|
472
|
+
|
|
473
|
+
if (!markerView.rasterize) {
|
|
474
|
+
UIView *iconView = markerView.iconView;
|
|
475
|
+
[iconView removeFromSuperview];
|
|
476
|
+
[annotationView addSubview:iconView];
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
[self applyMarkerStyle:markerView annotationView:annotationView];
|
|
480
|
+
markerAnnotation.annotationView = annotationView;
|
|
481
|
+
|
|
482
|
+
return annotationView;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView
|
|
486
|
+
rendererForOverlay:(id<MKOverlay>)overlay {
|
|
487
|
+
if ([overlay isKindOfClass:[MKPolyline class]]) {
|
|
488
|
+
LuggPolylineView *polylineView =
|
|
489
|
+
[_overlayToPolylineMap objectForKey:overlay];
|
|
490
|
+
MKPolyline *polyline = (MKPolyline *)overlay;
|
|
491
|
+
|
|
492
|
+
if (polylineView) {
|
|
493
|
+
NSArray<UIColor *> *colors = polylineView.strokeColors;
|
|
494
|
+
|
|
495
|
+
MKPolylineAnimator *renderer =
|
|
496
|
+
[[MKPolylineAnimator alloc] initWithPolyline:polyline];
|
|
497
|
+
renderer.lineWidth = polylineView.strokeWidth;
|
|
498
|
+
renderer.strokeColor = colors.firstObject;
|
|
499
|
+
if (colors.count > 1) {
|
|
500
|
+
renderer.strokeColors = colors;
|
|
501
|
+
}
|
|
502
|
+
renderer.animatedOptions = polylineView.animatedOptions;
|
|
503
|
+
renderer.animated = polylineView.animated;
|
|
504
|
+
polylineView.renderer = renderer;
|
|
505
|
+
return renderer;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
MKPolylineRenderer *renderer =
|
|
509
|
+
[[MKPolylineRenderer alloc] initWithPolyline:polyline];
|
|
510
|
+
return renderer;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if ([overlay isKindOfClass:[MKPolygon class]]) {
|
|
514
|
+
LuggPolygonView *polygonView = [_overlayToPolygonMap objectForKey:overlay];
|
|
515
|
+
MKPolygon *polygon = (MKPolygon *)overlay;
|
|
516
|
+
|
|
517
|
+
MKPolygonRenderer *renderer =
|
|
518
|
+
[[MKPolygonRenderer alloc] initWithPolygon:polygon];
|
|
519
|
+
if (polygonView) {
|
|
520
|
+
renderer.fillColor = polygonView.fillColor;
|
|
521
|
+
renderer.strokeColor = polygonView.strokeColor;
|
|
522
|
+
renderer.lineWidth = polygonView.strokeWidth;
|
|
523
|
+
polygonView.renderer = renderer;
|
|
524
|
+
}
|
|
525
|
+
return renderer;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return nil;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
- (void)mapView:(MKMapView *)mapView
|
|
532
|
+
didSelectAnnotationView:(MKAnnotationView *)view {
|
|
533
|
+
if (![view.annotation isKindOfClass:[AppleMarkerAnnotation class]])
|
|
534
|
+
return;
|
|
535
|
+
|
|
536
|
+
AppleMarkerAnnotation *annotation = (AppleMarkerAnnotation *)view.annotation;
|
|
537
|
+
LuggMarkerView *markerView = annotation.markerView;
|
|
538
|
+
|
|
539
|
+
if (markerView) {
|
|
540
|
+
CGPoint point = [_mapView convertCoordinate:markerView.coordinate
|
|
541
|
+
toPointToView:_mapView];
|
|
542
|
+
[markerView emitPressEventWithPoint:point];
|
|
543
|
+
|
|
544
|
+
LuggCalloutView *calloutView = markerView.calloutView;
|
|
545
|
+
if (calloutView && !calloutView.bubbled && calloutView.hasCustomContent) {
|
|
546
|
+
[self showNonBubbledCallout:markerView];
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
- (void)mapView:(MKMapView *)mapView
|
|
552
|
+
didDeselectAnnotationView:(MKAnnotationView *)view {
|
|
553
|
+
if (![view.annotation isKindOfClass:[AppleMarkerAnnotation class]])
|
|
554
|
+
return;
|
|
555
|
+
|
|
556
|
+
AppleMarkerAnnotation *annotation = (AppleMarkerAnnotation *)view.annotation;
|
|
557
|
+
LuggMarkerView *markerView = annotation.markerView;
|
|
558
|
+
|
|
559
|
+
if (markerView && _activeNonBubbledMarker == markerView &&
|
|
560
|
+
!_isReselectingAnnotation) {
|
|
561
|
+
_isReselectingAnnotation = YES;
|
|
562
|
+
[_mapView selectAnnotation:annotation animated:NO];
|
|
563
|
+
_isReselectingAnnotation = NO;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
- (void)showNonBubbledCallout:(LuggMarkerView *)markerView {
|
|
568
|
+
[self dismissNonBubbledCallout];
|
|
569
|
+
|
|
570
|
+
LuggCalloutView *calloutView = markerView.calloutView;
|
|
571
|
+
UIView *contentView = calloutView.contentView;
|
|
572
|
+
[contentView removeFromSuperview];
|
|
573
|
+
|
|
574
|
+
contentView.userInteractionEnabled = YES;
|
|
575
|
+
calloutView.delegate = self;
|
|
576
|
+
|
|
577
|
+
AppleMarkerAnnotation *annotation =
|
|
578
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
579
|
+
MKAnnotationView *annotationView = annotation.annotationView;
|
|
580
|
+
if (annotationView) {
|
|
581
|
+
annotationView.clipsToBounds = NO;
|
|
582
|
+
[annotationView addSubview:contentView];
|
|
583
|
+
} else {
|
|
584
|
+
[_wrapperView addSubview:contentView];
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
_activeNonBubbledMarker = markerView;
|
|
588
|
+
[self positionNonBubbledCallout];
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
- (void)calloutViewDidUpdate:(LuggCalloutView *)calloutView {
|
|
592
|
+
[self positionNonBubbledCallout];
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
- (void)positionNonBubbledCallout {
|
|
596
|
+
if (!_activeNonBubbledMarker)
|
|
597
|
+
return;
|
|
598
|
+
|
|
599
|
+
LuggCalloutView *calloutView = _activeNonBubbledMarker.calloutView;
|
|
600
|
+
UIView *contentView = calloutView.contentView;
|
|
601
|
+
CGSize contentSize = contentView.bounds.size;
|
|
602
|
+
if (contentSize.width <= 0 || contentSize.height <= 0)
|
|
603
|
+
return;
|
|
604
|
+
|
|
605
|
+
CGPoint anchor = calloutView.anchor;
|
|
606
|
+
|
|
607
|
+
AppleMarkerAnnotation *annotation =
|
|
608
|
+
(AppleMarkerAnnotation *)_activeNonBubbledMarker.marker;
|
|
609
|
+
MKAnnotationView *annotationView = annotation.annotationView;
|
|
610
|
+
|
|
611
|
+
if (annotationView && contentView.superview == annotationView) {
|
|
612
|
+
CGPoint center = CGPointMake(annotationView.bounds.size.width / 2.0 +
|
|
613
|
+
contentSize.width * (0.5 - anchor.x),
|
|
614
|
+
annotationView.bounds.size.height / 2.0 +
|
|
615
|
+
contentSize.height * (0.5 - anchor.y));
|
|
616
|
+
contentView.center = center;
|
|
617
|
+
} else {
|
|
618
|
+
CGPoint point =
|
|
619
|
+
[_mapView convertCoordinate:_activeNonBubbledMarker.coordinate
|
|
620
|
+
toPointToView:_wrapperView];
|
|
621
|
+
contentView.center =
|
|
622
|
+
CGPointMake(point.x + contentSize.width * (0.5 - anchor.x),
|
|
623
|
+
point.y + contentSize.height * (0.5 - anchor.y));
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
- (void)dismissNonBubbledCallout {
|
|
628
|
+
if (!_activeNonBubbledMarker)
|
|
629
|
+
return;
|
|
630
|
+
|
|
631
|
+
LuggMarkerView *markerView = _activeNonBubbledMarker;
|
|
632
|
+
_activeNonBubbledMarker = nil;
|
|
633
|
+
|
|
634
|
+
markerView.calloutView.delegate = nil;
|
|
635
|
+
[markerView.calloutView.contentView removeFromSuperview];
|
|
636
|
+
|
|
637
|
+
AppleMarkerAnnotation *annotation =
|
|
638
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
639
|
+
if (annotation) {
|
|
640
|
+
[_mapView deselectAnnotation:annotation animated:NO];
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
- (void)mapView:(MKMapView *)mapView
|
|
645
|
+
annotationView:(MKAnnotationView *)view
|
|
646
|
+
didChangeDragState:(MKAnnotationViewDragState)newState
|
|
647
|
+
fromOldState:(MKAnnotationViewDragState)oldState {
|
|
648
|
+
if (![view.annotation isKindOfClass:[AppleMarkerAnnotation class]])
|
|
649
|
+
return;
|
|
650
|
+
|
|
651
|
+
AppleMarkerAnnotation *annotation = (AppleMarkerAnnotation *)view.annotation;
|
|
652
|
+
LuggMarkerView *markerView = annotation.markerView;
|
|
653
|
+
if (!markerView)
|
|
654
|
+
return;
|
|
655
|
+
|
|
656
|
+
CLLocationCoordinate2D coord = annotation.coordinate;
|
|
657
|
+
CGPoint point = [_mapView convertCoordinate:coord toPointToView:_mapView];
|
|
658
|
+
|
|
659
|
+
switch (newState) {
|
|
660
|
+
case MKAnnotationViewDragStateStarting:
|
|
661
|
+
[markerView updateCoordinate:coord];
|
|
662
|
+
[markerView emitDragStartEventWithPoint:point];
|
|
663
|
+
[view setDragState:MKAnnotationViewDragStateDragging animated:YES];
|
|
664
|
+
break;
|
|
665
|
+
case MKAnnotationViewDragStateDragging:
|
|
666
|
+
[markerView updateCoordinate:coord];
|
|
667
|
+
[markerView emitDragChangeEventWithPoint:point];
|
|
668
|
+
break;
|
|
669
|
+
case MKAnnotationViewDragStateEnding:
|
|
670
|
+
[markerView updateCoordinate:coord];
|
|
671
|
+
[markerView emitDragEndEventWithPoint:point];
|
|
672
|
+
[view setDragState:MKAnnotationViewDragStateNone animated:YES];
|
|
673
|
+
break;
|
|
674
|
+
case MKAnnotationViewDragStateCanceling:
|
|
675
|
+
[view setDragState:MKAnnotationViewDragStateNone animated:YES];
|
|
676
|
+
break;
|
|
677
|
+
default:
|
|
678
|
+
break;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
- (void)addCenterTapGesture:(MKAnnotationView *)view {
|
|
683
|
+
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
|
|
684
|
+
initWithTarget:self
|
|
685
|
+
action:@selector(handleAnnotationTap:)];
|
|
686
|
+
tap.cancelsTouchesInView = NO;
|
|
687
|
+
[view addGestureRecognizer:tap];
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
- (void)handleAnnotationTap:(UITapGestureRecognizer *)gesture {
|
|
691
|
+
MKAnnotationView *view = (MKAnnotationView *)gesture.view;
|
|
692
|
+
if ([view.annotation isKindOfClass:[AppleMarkerAnnotation class]]) {
|
|
693
|
+
AppleMarkerAnnotation *annotation =
|
|
694
|
+
(AppleMarkerAnnotation *)view.annotation;
|
|
695
|
+
[_mapView setCenterCoordinate:annotation.coordinate animated:YES];
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
- (void)applyCalloutView:(LuggMarkerView *)markerView
|
|
700
|
+
annotationView:(MKAnnotationView *)annotationView {
|
|
701
|
+
LuggCalloutView *calloutView = markerView.calloutView;
|
|
702
|
+
if (!calloutView) {
|
|
703
|
+
annotationView.detailCalloutAccessoryView = nil;
|
|
704
|
+
annotationView.rightCalloutAccessoryView = nil;
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
annotationView.rightCalloutAccessoryView = nil;
|
|
709
|
+
|
|
710
|
+
if (!calloutView.bubbled) {
|
|
711
|
+
annotationView.canShowCallout = NO;
|
|
712
|
+
annotationView.detailCalloutAccessoryView = nil;
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
annotationView.detailCalloutAccessoryView =
|
|
717
|
+
calloutView.hasCustomContent ? calloutView.contentView : nil;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
#pragma mark - MarkerViewDelegate
|
|
721
|
+
|
|
722
|
+
- (void)markerViewDidLayout:(LuggMarkerView *)markerView {
|
|
723
|
+
AppleMarkerAnnotation *annotation =
|
|
724
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
725
|
+
if (annotation) {
|
|
726
|
+
[self updateAnnotationViewFrame:annotation];
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
- (void)markerViewDidUpdate:(LuggMarkerView *)markerView {
|
|
731
|
+
AppleMarkerAnnotation *annotation =
|
|
732
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
733
|
+
|
|
734
|
+
if (!annotation)
|
|
735
|
+
return;
|
|
736
|
+
|
|
737
|
+
annotation.coordinate = markerView.coordinate;
|
|
738
|
+
annotation.title = markerView.title;
|
|
739
|
+
annotation.subtitle = markerView.markerDescription;
|
|
740
|
+
|
|
741
|
+
MKAnnotationView *annotationView = annotation.annotationView;
|
|
742
|
+
if (annotationView) {
|
|
743
|
+
annotationView.draggable = markerView.draggable;
|
|
744
|
+
annotationView.layer.zPosition = markerView.zIndex;
|
|
745
|
+
annotationView.zPriority = markerView.zIndex;
|
|
746
|
+
[self applyCalloutView:markerView annotationView:annotationView];
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
[self updateAnnotationViewFrame:annotation];
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
#pragma mark - PolylineViewDelegate
|
|
753
|
+
|
|
754
|
+
- (void)polylineViewDidUpdate:(LuggPolylineView *)polylineView {
|
|
755
|
+
[self syncPolylineView:polylineView];
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
#pragma mark - PolygonViewDelegate
|
|
759
|
+
|
|
760
|
+
- (void)polygonViewDidUpdate:(LuggPolygonView *)polygonView {
|
|
761
|
+
[self syncPolygonView:polygonView];
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
#pragma mark - Marker Management
|
|
765
|
+
|
|
766
|
+
- (void)addMarkerView:(LuggMarkerView *)markerView {
|
|
767
|
+
markerView.delegate = self;
|
|
768
|
+
|
|
769
|
+
AppleMarkerAnnotation *annotation = [[AppleMarkerAnnotation alloc] init];
|
|
770
|
+
annotation.markerView = markerView;
|
|
771
|
+
markerView.marker = annotation;
|
|
772
|
+
|
|
773
|
+
if (_mapView) {
|
|
774
|
+
[_mapView addAnnotation:annotation];
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
[self markerViewDidUpdate:markerView];
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
- (void)removeMarkerView:(LuggMarkerView *)markerView {
|
|
781
|
+
markerView.delegate = nil;
|
|
782
|
+
|
|
783
|
+
AppleMarkerAnnotation *annotation =
|
|
784
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
785
|
+
|
|
786
|
+
if (annotation) {
|
|
787
|
+
annotation.annotationView.transform = CGAffineTransformIdentity;
|
|
788
|
+
annotation.markerView = nil;
|
|
789
|
+
annotation.annotationView = nil;
|
|
790
|
+
[_mapView removeAnnotation:annotation];
|
|
791
|
+
markerView.marker = nil;
|
|
792
|
+
}
|
|
793
|
+
[markerView resetIconViewTransform];
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
- (void)syncMarkerView:(LuggMarkerView *)markerView {
|
|
797
|
+
[self markerViewDidUpdate:markerView];
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
- (void)applyMarkerStyle:(LuggMarkerView *)markerView
|
|
801
|
+
annotationView:(MKAnnotationView *)annotationView {
|
|
802
|
+
annotationView.transform = CGAffineTransformIdentity;
|
|
803
|
+
|
|
804
|
+
UIView *iconView = markerView.iconView;
|
|
805
|
+
CGRect frame = iconView.frame;
|
|
806
|
+
if (frame.size.width <= 0 || frame.size.height <= 0)
|
|
807
|
+
return;
|
|
808
|
+
|
|
809
|
+
CGFloat scale = markerView.scale;
|
|
810
|
+
CGPoint anchor = markerView.anchor;
|
|
811
|
+
|
|
812
|
+
if (markerView.rasterize) {
|
|
813
|
+
annotationView.image = [markerView createScaledIconImage];
|
|
814
|
+
} else {
|
|
815
|
+
iconView.layer.anchorPoint = anchor;
|
|
816
|
+
iconView.transform = CGAffineTransformMakeScale(scale, scale);
|
|
817
|
+
iconView.frame =
|
|
818
|
+
CGRectMake(frame.size.width * (0.5 - anchor.x) * (scale - 1),
|
|
819
|
+
frame.size.height * (0.5 - anchor.y) * (scale - 1),
|
|
820
|
+
frame.size.width, frame.size.height);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
annotationView.bounds =
|
|
824
|
+
CGRectMake(0, 0, frame.size.width * scale, frame.size.height * scale);
|
|
825
|
+
annotationView.centerOffset =
|
|
826
|
+
CGPointMake(frame.size.width * scale * (anchor.x - 0.5),
|
|
827
|
+
-frame.size.height * scale * (anchor.y - 0.5));
|
|
828
|
+
annotationView.transform =
|
|
829
|
+
CGAffineTransformMakeRotation(markerView.rotate * M_PI / 180.0);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
- (void)updateAnnotationViewFrame:(AppleMarkerAnnotation *)annotation {
|
|
833
|
+
MKAnnotationView *annotationView = annotation.annotationView;
|
|
834
|
+
LuggMarkerView *markerView = annotation.markerView;
|
|
835
|
+
|
|
836
|
+
if (!annotationView || !markerView)
|
|
837
|
+
return;
|
|
838
|
+
|
|
839
|
+
[self applyMarkerStyle:markerView annotationView:annotationView];
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
#pragma mark - Polyline Management
|
|
843
|
+
|
|
844
|
+
- (void)addPolylineView:(LuggPolylineView *)polylineView {
|
|
845
|
+
polylineView.delegate = self;
|
|
846
|
+
[self addPolylineOverlayToMap:polylineView];
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
- (void)removePolylineView:(LuggPolylineView *)polylineView {
|
|
850
|
+
polylineView.delegate = nil;
|
|
851
|
+
MKPolyline *polyline = (MKPolyline *)polylineView.polyline;
|
|
852
|
+
if (polyline) {
|
|
853
|
+
[_overlayToPolylineMap removeObjectForKey:polyline];
|
|
854
|
+
[_mapView removeOverlay:polyline];
|
|
855
|
+
polylineView.polyline = nil;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
- (void)syncPolylineView:(LuggPolylineView *)polylineView {
|
|
860
|
+
if (!_mapView)
|
|
861
|
+
return;
|
|
862
|
+
|
|
863
|
+
MKPolylineAnimator *renderer = (MKPolylineAnimator *)polylineView.renderer;
|
|
864
|
+
MKPolyline *oldPolyline = (MKPolyline *)polylineView.polyline;
|
|
865
|
+
|
|
866
|
+
NSArray<CLLocation *> *coordinates = polylineView.coordinates;
|
|
867
|
+
if (coordinates.count == 0) {
|
|
868
|
+
if (renderer) {
|
|
869
|
+
renderer.animated = NO;
|
|
870
|
+
}
|
|
871
|
+
if (oldPolyline) {
|
|
872
|
+
[_overlayToPolylineMap removeObjectForKey:oldPolyline];
|
|
873
|
+
[_mapView removeOverlay:oldPolyline];
|
|
874
|
+
polylineView.polyline = nil;
|
|
875
|
+
polylineView.renderer = nil;
|
|
876
|
+
}
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
|
|
881
|
+
sizeof(CLLocationCoordinate2D) * coordinates.count);
|
|
882
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
883
|
+
coords[i] = coordinates[i].coordinate;
|
|
884
|
+
}
|
|
885
|
+
MKPolyline *newPolyline =
|
|
886
|
+
[MKPolyline polylineWithCoordinates:coords count:coordinates.count];
|
|
887
|
+
free(coords);
|
|
888
|
+
|
|
889
|
+
polylineView.polyline = newPolyline;
|
|
890
|
+
[_overlayToPolylineMap setObject:polylineView forKey:newPolyline];
|
|
891
|
+
|
|
892
|
+
if (renderer && oldPolyline) {
|
|
893
|
+
[_overlayToPolylineMap removeObjectForKey:oldPolyline];
|
|
894
|
+
[_mapView removeOverlay:oldPolyline];
|
|
895
|
+
[self insertOverlay:newPolyline withZIndex:polylineView.zIndex];
|
|
896
|
+
[renderer updatePolyline:newPolyline];
|
|
897
|
+
renderer.lineWidth = polylineView.strokeWidth;
|
|
898
|
+
renderer.strokeColor = polylineView.strokeColors.firstObject;
|
|
899
|
+
renderer.strokeColors =
|
|
900
|
+
polylineView.strokeColors.count > 1 ? polylineView.strokeColors : nil;
|
|
901
|
+
renderer.animatedOptions = polylineView.animatedOptions;
|
|
902
|
+
renderer.animated = polylineView.animated;
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
if (oldPolyline) {
|
|
907
|
+
[_overlayToPolylineMap removeObjectForKey:oldPolyline];
|
|
908
|
+
[_mapView removeOverlay:oldPolyline];
|
|
909
|
+
}
|
|
910
|
+
[self insertOverlay:newPolyline withZIndex:polylineView.zIndex];
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
- (void)addPolylineOverlayToMap:(LuggPolylineView *)polylineView {
|
|
914
|
+
if (!_mapView)
|
|
915
|
+
return;
|
|
916
|
+
|
|
917
|
+
NSArray<CLLocation *> *coordinates = polylineView.coordinates;
|
|
918
|
+
if (coordinates.count == 0)
|
|
919
|
+
return;
|
|
920
|
+
|
|
921
|
+
CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
|
|
922
|
+
sizeof(CLLocationCoordinate2D) * coordinates.count);
|
|
923
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
924
|
+
coords[i] = coordinates[i].coordinate;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords
|
|
928
|
+
count:coordinates.count];
|
|
929
|
+
free(coords);
|
|
930
|
+
|
|
931
|
+
polylineView.polyline = polyline;
|
|
932
|
+
[_overlayToPolylineMap setObject:polylineView forKey:polyline];
|
|
933
|
+
[self insertOverlay:polyline withZIndex:polylineView.zIndex];
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
#pragma mark - Polygon Management
|
|
937
|
+
|
|
938
|
+
- (void)addPolygonView:(LuggPolygonView *)polygonView {
|
|
939
|
+
polygonView.delegate = self;
|
|
940
|
+
[self addPolygonOverlayToMap:polygonView];
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
- (void)removePolygonView:(LuggPolygonView *)polygonView {
|
|
944
|
+
polygonView.delegate = nil;
|
|
945
|
+
MKPolygon *polygon = (MKPolygon *)polygonView.polygon;
|
|
946
|
+
if (polygon) {
|
|
947
|
+
[_overlayToPolygonMap removeObjectForKey:polygon];
|
|
948
|
+
[_mapView removeOverlay:polygon];
|
|
949
|
+
polygonView.polygon = nil;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
- (void)syncPolygonView:(LuggPolygonView *)polygonView {
|
|
954
|
+
if (!_mapView)
|
|
955
|
+
return;
|
|
956
|
+
|
|
957
|
+
MKPolygon *oldPolygon = (MKPolygon *)polygonView.polygon;
|
|
958
|
+
|
|
959
|
+
NSArray<CLLocation *> *coordinates = polygonView.coordinates;
|
|
960
|
+
if (coordinates.count == 0) {
|
|
961
|
+
if (oldPolygon) {
|
|
962
|
+
[_overlayToPolygonMap removeObjectForKey:oldPolygon];
|
|
963
|
+
[_mapView removeOverlay:oldPolygon];
|
|
964
|
+
polygonView.polygon = nil;
|
|
965
|
+
polygonView.renderer = nil;
|
|
966
|
+
}
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
|
|
971
|
+
sizeof(CLLocationCoordinate2D) * coordinates.count);
|
|
972
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
973
|
+
coords[i] = coordinates[i].coordinate;
|
|
974
|
+
}
|
|
975
|
+
NSArray<MKPolygon *> *interiorPolygons =
|
|
976
|
+
[self interiorPolygonsFromHoles:polygonView.holes];
|
|
977
|
+
MKPolygon *newPolygon = [MKPolygon polygonWithCoordinates:coords
|
|
978
|
+
count:coordinates.count
|
|
979
|
+
interiorPolygons:interiorPolygons];
|
|
980
|
+
free(coords);
|
|
981
|
+
|
|
982
|
+
polygonView.polygon = newPolygon;
|
|
983
|
+
[_overlayToPolygonMap setObject:polygonView forKey:newPolygon];
|
|
984
|
+
|
|
985
|
+
MKPolygonRenderer *renderer = (MKPolygonRenderer *)polygonView.renderer;
|
|
986
|
+
if (renderer && oldPolygon) {
|
|
987
|
+
[_overlayToPolygonMap removeObjectForKey:oldPolygon];
|
|
988
|
+
[_mapView removeOverlay:oldPolygon];
|
|
989
|
+
[self insertOverlay:newPolygon withZIndex:polygonView.zIndex];
|
|
990
|
+
polygonView.renderer = nil;
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
if (oldPolygon) {
|
|
995
|
+
[_overlayToPolygonMap removeObjectForKey:oldPolygon];
|
|
996
|
+
[_mapView removeOverlay:oldPolygon];
|
|
997
|
+
}
|
|
998
|
+
[self insertOverlay:newPolygon withZIndex:polygonView.zIndex];
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
- (void)addPolygonOverlayToMap:(LuggPolygonView *)polygonView {
|
|
1002
|
+
if (!_mapView)
|
|
1003
|
+
return;
|
|
1004
|
+
|
|
1005
|
+
NSArray<CLLocation *> *coordinates = polygonView.coordinates;
|
|
1006
|
+
if (coordinates.count == 0)
|
|
1007
|
+
return;
|
|
1008
|
+
|
|
1009
|
+
CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
|
|
1010
|
+
sizeof(CLLocationCoordinate2D) * coordinates.count);
|
|
1011
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
1012
|
+
coords[i] = coordinates[i].coordinate;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
NSArray<MKPolygon *> *interiorPolygons =
|
|
1016
|
+
[self interiorPolygonsFromHoles:polygonView.holes];
|
|
1017
|
+
MKPolygon *polygon = [MKPolygon polygonWithCoordinates:coords
|
|
1018
|
+
count:coordinates.count
|
|
1019
|
+
interiorPolygons:interiorPolygons];
|
|
1020
|
+
free(coords);
|
|
1021
|
+
|
|
1022
|
+
polygonView.polygon = polygon;
|
|
1023
|
+
[_overlayToPolygonMap setObject:polygonView forKey:polygon];
|
|
1024
|
+
[self insertOverlay:polygon withZIndex:polygonView.zIndex];
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
- (NSArray<MKPolygon *> *)interiorPolygonsFromHoles:
|
|
1028
|
+
(NSArray<NSArray<CLLocation *> *> *)holes {
|
|
1029
|
+
if (holes.count == 0)
|
|
1030
|
+
return @[];
|
|
1031
|
+
|
|
1032
|
+
NSMutableArray<MKPolygon *> *interiorPolygons = [NSMutableArray array];
|
|
1033
|
+
for (NSArray<CLLocation *> *hole in holes) {
|
|
1034
|
+
if (hole.count == 0)
|
|
1035
|
+
continue;
|
|
1036
|
+
CLLocationCoordinate2D *holeCoords = (CLLocationCoordinate2D *)malloc(
|
|
1037
|
+
sizeof(CLLocationCoordinate2D) * hole.count);
|
|
1038
|
+
for (NSUInteger i = 0; i < hole.count; i++) {
|
|
1039
|
+
holeCoords[i] = hole[i].coordinate;
|
|
1040
|
+
}
|
|
1041
|
+
MKPolygon *interiorPolygon = [MKPolygon polygonWithCoordinates:holeCoords
|
|
1042
|
+
count:hole.count];
|
|
1043
|
+
free(holeCoords);
|
|
1044
|
+
[interiorPolygons addObject:interiorPolygon];
|
|
1045
|
+
}
|
|
1046
|
+
return [interiorPolygons copy];
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
- (void)insertOverlay:(id<MKOverlay>)overlay withZIndex:(NSInteger)zIndex {
|
|
1050
|
+
if (zIndex == 0) {
|
|
1051
|
+
[_mapView addOverlay:overlay];
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
NSArray<id<MKOverlay>> *overlays = _mapView.overlays;
|
|
1056
|
+
NSInteger insertIndex = overlays.count;
|
|
1057
|
+
|
|
1058
|
+
for (NSInteger i = 0; i < overlays.count; i++) {
|
|
1059
|
+
NSInteger existingZIndex = 0;
|
|
1060
|
+
LuggPolylineView *existingPolylineView =
|
|
1061
|
+
[_overlayToPolylineMap objectForKey:overlays[i]];
|
|
1062
|
+
LuggPolygonView *existingPolygonView =
|
|
1063
|
+
[_overlayToPolygonMap objectForKey:overlays[i]];
|
|
1064
|
+
if (existingPolylineView) {
|
|
1065
|
+
existingZIndex = existingPolylineView.zIndex;
|
|
1066
|
+
} else if (existingPolygonView) {
|
|
1067
|
+
existingZIndex = existingPolygonView.zIndex;
|
|
1068
|
+
} else {
|
|
1069
|
+
continue;
|
|
1070
|
+
}
|
|
1071
|
+
if (existingZIndex > zIndex) {
|
|
1072
|
+
insertIndex = i;
|
|
1073
|
+
break;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
[_mapView insertOverlay:overlay atIndex:insertIndex];
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
#pragma mark - Lifecycle
|
|
1081
|
+
|
|
1082
|
+
- (void)pauseAnimations {
|
|
1083
|
+
for (LuggPolylineView *polylineView in _overlayToPolylineMap
|
|
1084
|
+
.objectEnumerator) {
|
|
1085
|
+
MKPolylineAnimator *renderer = (MKPolylineAnimator *)polylineView.renderer;
|
|
1086
|
+
[renderer pause];
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
- (void)resumeAnimations {
|
|
1091
|
+
for (LuggPolylineView *polylineView in _overlayToPolylineMap
|
|
1092
|
+
.objectEnumerator) {
|
|
1093
|
+
MKPolylineAnimator *renderer = (MKPolylineAnimator *)polylineView.renderer;
|
|
1094
|
+
[renderer resume];
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
#pragma mark - Commands
|
|
1099
|
+
|
|
1100
|
+
- (void)moveCamera:(double)latitude
|
|
1101
|
+
longitude:(double)longitude
|
|
1102
|
+
zoom:(double)zoom
|
|
1103
|
+
duration:(double)duration {
|
|
1104
|
+
if (!_mapView)
|
|
1105
|
+
return;
|
|
1106
|
+
|
|
1107
|
+
double targetZoom = zoom > 0 ? zoom : _mapView.zoomLevel;
|
|
1108
|
+
|
|
1109
|
+
if (duration < 0) {
|
|
1110
|
+
[_mapView
|
|
1111
|
+
setCenterCoordinate:CLLocationCoordinate2DMake(latitude, longitude)
|
|
1112
|
+
zoomLevel:targetZoom
|
|
1113
|
+
animated:YES];
|
|
1114
|
+
} else if (duration > 0) {
|
|
1115
|
+
CLLocationCoordinate2D center =
|
|
1116
|
+
CLLocationCoordinate2DMake(latitude, longitude);
|
|
1117
|
+
MKCoordinateRegion region = [_mapView regionForCenterCoordinate:center
|
|
1118
|
+
zoomLevel:targetZoom];
|
|
1119
|
+
[UIView animateWithDuration:duration / 1000.0
|
|
1120
|
+
animations:^{
|
|
1121
|
+
[self->_mapView setRegion:region animated:NO];
|
|
1122
|
+
}];
|
|
1123
|
+
} else {
|
|
1124
|
+
[_mapView
|
|
1125
|
+
setCenterCoordinate:CLLocationCoordinate2DMake(latitude, longitude)
|
|
1126
|
+
zoomLevel:targetZoom
|
|
1127
|
+
animated:NO];
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
- (void)fitCoordinates:(NSArray *)coordinates
|
|
1132
|
+
edgeInsetsTop:(double)edgeInsetsTop
|
|
1133
|
+
edgeInsetsLeft:(double)edgeInsetsLeft
|
|
1134
|
+
edgeInsetsBottom:(double)edgeInsetsBottom
|
|
1135
|
+
edgeInsetsRight:(double)edgeInsetsRight
|
|
1136
|
+
duration:(double)duration {
|
|
1137
|
+
if (!_mapView || coordinates.count == 0)
|
|
1138
|
+
return;
|
|
1139
|
+
|
|
1140
|
+
CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(
|
|
1141
|
+
sizeof(CLLocationCoordinate2D) * coordinates.count);
|
|
1142
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
1143
|
+
NSDictionary *coord = coordinates[i];
|
|
1144
|
+
coords[i] = CLLocationCoordinate2DMake([coord[@"latitude"] doubleValue],
|
|
1145
|
+
[coord[@"longitude"] doubleValue]);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
MKMapRect mapRect = MKMapRectNull;
|
|
1149
|
+
for (NSUInteger i = 0; i < coordinates.count; i++) {
|
|
1150
|
+
MKMapPoint point = MKMapPointForCoordinate(coords[i]);
|
|
1151
|
+
MKMapRect pointRect = MKMapRectMake(point.x, point.y, 0, 0);
|
|
1152
|
+
mapRect = MKMapRectUnion(mapRect, pointRect);
|
|
1153
|
+
}
|
|
1154
|
+
free(coords);
|
|
1155
|
+
|
|
1156
|
+
UIEdgeInsets insets = UIEdgeInsetsMake(edgeInsetsTop, edgeInsetsLeft,
|
|
1157
|
+
edgeInsetsBottom, edgeInsetsRight);
|
|
1158
|
+
|
|
1159
|
+
if (duration < 0) {
|
|
1160
|
+
[_mapView setVisibleMapRect:mapRect edgePadding:insets animated:YES];
|
|
1161
|
+
} else if (duration > 0) {
|
|
1162
|
+
[UIView animateWithDuration:duration / 1000.0
|
|
1163
|
+
animations:^{
|
|
1164
|
+
[self->_mapView setVisibleMapRect:mapRect
|
|
1165
|
+
edgePadding:insets
|
|
1166
|
+
animated:NO];
|
|
1167
|
+
}];
|
|
1168
|
+
} else {
|
|
1169
|
+
[_mapView setVisibleMapRect:mapRect edgePadding:insets animated:NO];
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
@end
|