@lugg/maps 1.0.0-beta.0 → 1.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/luggmaps/LuggCalloutView.kt +79 -0
- package/android/src/main/java/com/luggmaps/LuggCalloutViewManager.kt +39 -0
- package/android/src/main/java/com/luggmaps/LuggCircleView.kt +85 -0
- package/android/src/main/java/com/luggmaps/LuggCircleViewManager.kt +79 -0
- package/android/src/main/java/com/luggmaps/LuggGroundOverlayView.kt +81 -0
- package/android/src/main/java/com/luggmaps/LuggGroundOverlayViewManager.kt +82 -0
- package/android/src/main/java/com/luggmaps/LuggMapView.kt +49 -0
- package/android/src/main/java/com/luggmaps/LuggMapViewManager.kt +31 -0
- package/android/src/main/java/com/luggmaps/LuggMapWrapperView.kt +0 -11
- package/android/src/main/java/com/luggmaps/LuggMarkerView.kt +99 -51
- package/android/src/main/java/com/luggmaps/LuggMarkerViewManager.kt +13 -0
- package/android/src/main/java/com/luggmaps/LuggPackage.kt +11 -1
- package/android/src/main/java/com/luggmaps/LuggPolylineView.kt +1 -22
- package/android/src/main/java/com/luggmaps/LuggTileOverlayView.kt +92 -0
- package/android/src/main/java/com/luggmaps/LuggTileOverlayViewManager.kt +80 -0
- package/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt +628 -18
- package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +14 -0
- package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +12 -7
- package/android/src/main/java/com/luggmaps/events/CirclePressEvent.kt +12 -0
- package/android/src/main/java/com/luggmaps/events/GroundOverlayPressEvent.kt +12 -0
- package/android/src/main/java/com/luggmaps/events/TileOverlayPressEvent.kt +12 -0
- package/android/src/main/java/com/luggmaps/extensions/ViewExtensions.kt +11 -0
- package/ios/LuggCalloutView.h +23 -0
- package/ios/LuggCalloutView.mm +155 -0
- package/ios/LuggCircleView.h +31 -0
- package/ios/LuggCircleView.mm +133 -0
- package/ios/LuggGroundOverlayView.h +30 -0
- package/ios/LuggGroundOverlayView.mm +125 -0
- package/ios/LuggMapView.mm +84 -2
- package/ios/LuggMarkerView.h +5 -0
- package/ios/LuggMarkerView.mm +40 -2
- package/ios/LuggTileOverlayView.h +31 -0
- package/ios/LuggTileOverlayView.mm +130 -0
- package/ios/core/AppleMapProvider.mm +838 -34
- package/ios/core/GMSPolylineAnimator.m +6 -3
- package/ios/core/GoogleMapProvider.mm +506 -19
- package/ios/core/LuggAnnotationView.h +12 -0
- package/ios/core/LuggAnnotationView.mm +55 -0
- package/ios/core/MapProviderDelegate.h +20 -1
- package/ios/events/CirclePressEvent.h +20 -0
- package/ios/events/GroundOverlayPressEvent.h +20 -0
- package/ios/events/TileOverlayPressEvent.h +20 -0
- package/lib/module/MapProvider.web.js +7 -2
- package/lib/module/MapProvider.web.js.map +1 -1
- package/lib/module/MapView.js +12 -1
- package/lib/module/MapView.js.map +1 -1
- package/lib/module/MapView.web.js +36 -20
- package/lib/module/MapView.web.js.map +1 -1
- package/lib/module/components/Circle.js +46 -0
- package/lib/module/components/Circle.js.map +1 -0
- package/lib/module/components/Circle.types.js +4 -0
- package/lib/module/components/Circle.types.js.map +1 -0
- package/lib/module/components/Circle.web.js +79 -0
- package/lib/module/components/Circle.web.js.map +1 -0
- package/lib/module/components/GeoJson.js +3 -3
- package/lib/module/components/GeoJson.js.map +1 -1
- package/lib/module/components/GroundOverlay.js +45 -0
- package/lib/module/components/GroundOverlay.js.map +1 -0
- package/lib/module/components/GroundOverlay.types.js +4 -0
- package/lib/module/components/GroundOverlay.types.js.map +1 -0
- package/lib/module/components/GroundOverlay.web.js +77 -0
- package/lib/module/components/GroundOverlay.web.js.map +1 -0
- package/lib/module/components/Marker.js +41 -6
- package/lib/module/components/Marker.js.map +1 -1
- package/lib/module/components/Marker.web.js +103 -26
- package/lib/module/components/Marker.web.js.map +1 -1
- package/lib/module/components/Polygon.web.js +3 -3
- package/lib/module/components/Polygon.web.js.map +1 -1
- package/lib/module/components/Polyline.web.js +6 -12
- package/lib/module/components/Polyline.web.js.map +1 -1
- package/lib/module/components/TileOverlay.js +44 -0
- package/lib/module/components/TileOverlay.js.map +1 -0
- package/lib/module/components/TileOverlay.types.js +4 -0
- package/lib/module/components/TileOverlay.types.js.map +1 -0
- package/lib/module/components/TileOverlay.web.js +69 -0
- package/lib/module/components/TileOverlay.web.js.map +1 -0
- package/lib/module/components/index.js +3 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/components/index.web.js +3 -0
- package/lib/module/components/index.web.js.map +1 -1
- package/lib/module/fabric/LuggCalloutViewNativeComponent.ts +20 -0
- package/lib/module/fabric/LuggCircleViewNativeComponent.ts +25 -0
- package/lib/module/fabric/LuggGroundOverlayViewNativeComponent.ts +29 -0
- package/lib/module/fabric/LuggMapViewNativeComponent.ts +13 -5
- package/lib/module/fabric/LuggMarkerViewNativeComponent.ts +14 -2
- package/lib/module/fabric/LuggTileOverlayViewNativeComponent.ts +30 -0
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +3 -0
- package/lib/module/index.web.js.map +1 -1
- package/lib/typescript/src/MapProvider.web.d.ts +9 -2
- package/lib/typescript/src/MapProvider.web.d.ts.map +1 -1
- package/lib/typescript/src/MapView.d.ts +1 -1
- package/lib/typescript/src/MapView.d.ts.map +1 -1
- package/lib/typescript/src/MapView.types.d.ts +36 -1
- package/lib/typescript/src/MapView.types.d.ts.map +1 -1
- package/lib/typescript/src/MapView.web.d.ts +1 -1
- package/lib/typescript/src/MapView.web.d.ts.map +1 -1
- package/lib/typescript/src/components/Circle.d.ts +10 -0
- package/lib/typescript/src/components/Circle.d.ts.map +1 -0
- package/lib/typescript/src/components/Circle.types.d.ts +33 -0
- package/lib/typescript/src/components/Circle.types.d.ts.map +1 -0
- package/lib/typescript/src/components/Circle.web.d.ts +3 -0
- package/lib/typescript/src/components/Circle.web.d.ts.map +1 -0
- package/lib/typescript/src/components/GeoJson.d.ts +2 -1
- package/lib/typescript/src/components/GeoJson.d.ts.map +1 -1
- package/lib/typescript/src/components/GeoJson.types.d.ts +11 -1
- package/lib/typescript/src/components/GeoJson.types.d.ts.map +1 -1
- package/lib/typescript/src/components/GroundOverlay.d.ts +10 -0
- package/lib/typescript/src/components/GroundOverlay.d.ts.map +1 -0
- package/lib/typescript/src/components/GroundOverlay.types.d.ts +35 -0
- package/lib/typescript/src/components/GroundOverlay.types.d.ts.map +1 -0
- package/lib/typescript/src/components/GroundOverlay.web.d.ts +3 -0
- package/lib/typescript/src/components/GroundOverlay.web.d.ts.map +1 -0
- package/lib/typescript/src/components/Marker.d.ts +6 -3
- package/lib/typescript/src/components/Marker.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.types.d.ts +40 -2
- package/lib/typescript/src/components/Marker.types.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.web.d.ts +3 -2
- package/lib/typescript/src/components/Marker.web.d.ts.map +1 -1
- package/lib/typescript/src/components/Polygon.web.d.ts +1 -1
- package/lib/typescript/src/components/Polygon.web.d.ts.map +1 -1
- package/lib/typescript/src/components/Polyline.web.d.ts +1 -1
- package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -1
- package/lib/typescript/src/components/TileOverlay.d.ts +10 -0
- package/lib/typescript/src/components/TileOverlay.d.ts.map +1 -0
- package/lib/typescript/src/components/TileOverlay.types.d.ts +36 -0
- package/lib/typescript/src/components/TileOverlay.types.d.ts.map +1 -0
- package/lib/typescript/src/components/TileOverlay.web.d.ts +3 -0
- package/lib/typescript/src/components/TileOverlay.web.d.ts.map +1 -0
- package/lib/typescript/src/components/index.d.ts +7 -1
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/components/index.web.d.ts +7 -1
- 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/LuggCircleViewNativeComponent.d.ts +18 -0
- package/lib/typescript/src/fabric/LuggCircleViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/LuggGroundOverlayViewNativeComponent.d.ts +21 -0
- package/lib/typescript/src/fabric/LuggGroundOverlayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts +10 -5
- package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts +8 -1
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggTileOverlayViewNativeComponent.d.ts +21 -0
- package/lib/typescript/src/fabric/LuggTileOverlayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +10 -4
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +9 -3
- package/lib/typescript/src/index.web.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +0 -4
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +6 -2
- package/src/MapProvider.web.tsx +15 -3
- package/src/MapView.tsx +12 -1
- package/src/MapView.types.ts +118 -1
- package/src/MapView.web.tsx +379 -322
- package/src/components/Circle.tsx +52 -0
- package/src/components/Circle.types.ts +33 -0
- package/src/components/Circle.web.tsx +95 -0
- package/src/components/GeoJson.tsx +3 -3
- package/src/components/GeoJson.types.ts +12 -1
- package/src/components/GroundOverlay.tsx +47 -0
- package/src/components/GroundOverlay.types.ts +36 -0
- package/src/components/GroundOverlay.web.tsx +81 -0
- package/src/components/Marker.tsx +59 -5
- package/src/components/Marker.types.ts +42 -2
- package/src/components/Marker.web.tsx +235 -99
- package/src/components/Polygon.web.tsx +93 -89
- package/src/components/Polyline.web.tsx +235 -235
- package/src/components/TileOverlay.tsx +44 -0
- package/src/components/TileOverlay.types.ts +37 -0
- package/src/components/TileOverlay.web.tsx +97 -0
- package/src/components/index.ts +11 -0
- package/src/components/index.web.ts +10 -1
- package/src/fabric/LuggCalloutViewNativeComponent.ts +20 -0
- package/src/fabric/LuggCircleViewNativeComponent.ts +25 -0
- package/src/fabric/LuggGroundOverlayViewNativeComponent.ts +29 -0
- package/src/fabric/LuggMapViewNativeComponent.ts +13 -5
- package/src/fabric/LuggMarkerViewNativeComponent.ts +14 -2
- package/src/fabric/LuggTileOverlayViewNativeComponent.ts +30 -0
- package/src/index.ts +14 -1
- package/src/index.web.ts +17 -1
- package/src/types.ts +0 -5
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
#import "AppleMapProvider.h"
|
|
2
|
+
|
|
3
|
+
using facebook::react::LuggMapViewInsetAdjustment;
|
|
4
|
+
using facebook::react::LuggMapViewMapType;
|
|
5
|
+
using facebook::react::LuggMapViewPoiFilterMode;
|
|
6
|
+
using facebook::react::LuggMapViewTheme;
|
|
7
|
+
|
|
8
|
+
#import "../LuggCalloutView.h"
|
|
9
|
+
#import "../LuggCircleView.h"
|
|
10
|
+
#import "../LuggGroundOverlayView.h"
|
|
2
11
|
#import "../LuggMarkerView.h"
|
|
3
12
|
#import "../LuggPolygonView.h"
|
|
4
13
|
#import "../LuggPolylineView.h"
|
|
14
|
+
#import "../LuggTileOverlayView.h"
|
|
5
15
|
#import "../extensions/MKMapView+Zoom.h"
|
|
16
|
+
#import "LuggAnnotationView.h"
|
|
6
17
|
#import "MKPolylineAnimator.h"
|
|
7
18
|
|
|
8
19
|
@interface AppleMarkerAnnotation : NSObject <MKAnnotation>
|
|
@@ -11,20 +22,100 @@
|
|
|
11
22
|
@property(nonatomic, copy, nullable) NSString *subtitle;
|
|
12
23
|
@property(nonatomic, strong) LuggMarkerView *markerView;
|
|
13
24
|
@property(nonatomic, weak) MKAnnotationView *annotationView;
|
|
25
|
+
@property(nonatomic, copy, nullable) dispatch_block_t pendingScaleAnimation;
|
|
14
26
|
@end
|
|
15
27
|
|
|
16
28
|
@implementation AppleMarkerAnnotation
|
|
17
29
|
@end
|
|
18
30
|
|
|
31
|
+
@interface GroundImageOverlay : NSObject <MKOverlay>
|
|
32
|
+
@property(nonatomic, assign) CLLocationCoordinate2D coordinate;
|
|
33
|
+
@property(nonatomic, assign) MKMapRect boundingMapRect;
|
|
34
|
+
@property(nonatomic, strong) UIImage *image;
|
|
35
|
+
@property(nonatomic, assign) CGFloat opacity;
|
|
36
|
+
@end
|
|
37
|
+
|
|
38
|
+
@implementation GroundImageOverlay
|
|
39
|
+
@end
|
|
40
|
+
|
|
41
|
+
@interface BoundedTileOverlay : MKTileOverlay
|
|
42
|
+
@property(nonatomic, assign) CLLocationCoordinate2D southwest;
|
|
43
|
+
@property(nonatomic, assign) CLLocationCoordinate2D northeast;
|
|
44
|
+
@end
|
|
45
|
+
|
|
46
|
+
@implementation BoundedTileOverlay
|
|
47
|
+
|
|
48
|
+
static double tileToLat(NSInteger y, NSInteger z) {
|
|
49
|
+
double n = M_PI - 2.0 * M_PI * y / pow(2.0, z);
|
|
50
|
+
return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n)));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static double tileToLng(NSInteger x, NSInteger z) {
|
|
54
|
+
return x / pow(2.0, z) * 360.0 - 180.0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
- (void)loadTileAtPath:(MKTileOverlayPath)path
|
|
58
|
+
result:(void (^)(NSData *_Nullable, NSError *_Nullable))result {
|
|
59
|
+
double tileSW_lat = tileToLat(path.y + 1, path.z);
|
|
60
|
+
double tileNE_lat = tileToLat(path.y, path.z);
|
|
61
|
+
double tileSW_lng = tileToLng(path.x, path.z);
|
|
62
|
+
double tileNE_lng = tileToLng(path.x + 1, path.z);
|
|
63
|
+
|
|
64
|
+
if (tileNE_lat < self.southwest.latitude ||
|
|
65
|
+
tileSW_lat > self.northeast.latitude ||
|
|
66
|
+
tileNE_lng < self.southwest.longitude ||
|
|
67
|
+
tileSW_lng > self.northeast.longitude) {
|
|
68
|
+
result(nil, nil);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
[super loadTileAtPath:path result:result];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@end
|
|
76
|
+
|
|
77
|
+
@interface GroundImageOverlayRenderer : MKOverlayRenderer
|
|
78
|
+
@property(nonatomic, strong) UIImage *image;
|
|
79
|
+
@property(nonatomic, assign) CGFloat overlayOpacity;
|
|
80
|
+
@end
|
|
81
|
+
|
|
82
|
+
@implementation GroundImageOverlayRenderer
|
|
83
|
+
|
|
84
|
+
- (void)drawMapRect:(MKMapRect)mapRect
|
|
85
|
+
zoomScale:(MKZoomScale)zoomScale
|
|
86
|
+
inContext:(CGContextRef)context {
|
|
87
|
+
MKMapRect overlayRect = self.overlay.boundingMapRect;
|
|
88
|
+
CGRect drawRect = [self rectForMapRect:overlayRect];
|
|
89
|
+
|
|
90
|
+
CGContextSaveGState(context);
|
|
91
|
+
CGContextSetAlpha(context, self.overlayOpacity);
|
|
92
|
+
|
|
93
|
+
// Flip the context for UIImage drawing
|
|
94
|
+
CGContextTranslateCTM(context, drawRect.origin.x,
|
|
95
|
+
drawRect.origin.y + drawRect.size.height);
|
|
96
|
+
CGContextScaleCTM(context, 1.0, -1.0);
|
|
97
|
+
|
|
98
|
+
CGRect imageRect =
|
|
99
|
+
CGRectMake(0, 0, drawRect.size.width, drawRect.size.height);
|
|
100
|
+
CGContextDrawImage(context, imageRect, self.image.CGImage);
|
|
101
|
+
|
|
102
|
+
CGContextRestoreGState(context);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@end
|
|
106
|
+
|
|
19
107
|
@implementation LuggAppleMapViewContent
|
|
20
108
|
@end
|
|
21
109
|
|
|
22
110
|
@interface AppleMapProvider () <
|
|
23
|
-
LuggMarkerViewDelegate,
|
|
111
|
+
LuggMarkerViewDelegate, LuggCalloutViewDelegate, LuggPolylineViewDelegate,
|
|
112
|
+
LuggPolygonViewDelegate, LuggCircleViewDelegate,
|
|
113
|
+
LuggGroundOverlayViewDelegate, LuggTileOverlayViewDelegate,
|
|
24
114
|
UIGestureRecognizerDelegate>
|
|
25
115
|
@end
|
|
26
116
|
|
|
27
117
|
@implementation AppleMapProvider {
|
|
118
|
+
UIView *_wrapperView;
|
|
28
119
|
LuggAppleMapViewContent *_mapView;
|
|
29
120
|
BOOL _isMapReady;
|
|
30
121
|
BOOL _isDragging;
|
|
@@ -32,14 +123,25 @@
|
|
|
32
123
|
double _maxZoom;
|
|
33
124
|
NSMapTable<id<MKOverlay>, LuggPolylineView *> *_overlayToPolylineMap;
|
|
34
125
|
NSMapTable<id<MKOverlay>, LuggPolygonView *> *_overlayToPolygonMap;
|
|
126
|
+
NSMapTable<id<MKOverlay>, LuggCircleView *> *_overlayToCircleMap;
|
|
127
|
+
NSMapTable<id<MKOverlay>, LuggGroundOverlayView *>
|
|
128
|
+
*_overlayToGroundOverlayMap;
|
|
129
|
+
NSMapTable<id<MKOverlay>, LuggTileOverlayView *> *_overlayToTileOverlayMap;
|
|
35
130
|
UITapGestureRecognizer *_tapGesture;
|
|
36
131
|
UILongPressGestureRecognizer *_longPressGesture;
|
|
132
|
+
LuggMarkerView *_activeNonBubbledMarker;
|
|
133
|
+
BOOL _isReselectingAnnotation;
|
|
134
|
+
BOOL _isProgrammaticSelect;
|
|
37
135
|
// Edge insets animation
|
|
38
136
|
CADisplayLink *_edgeInsetsDisplayLink;
|
|
39
137
|
UIEdgeInsets _edgeInsetsFrom;
|
|
40
138
|
UIEdgeInsets _edgeInsetsTo;
|
|
139
|
+
UIEdgeInsets _edgeInsetsCurrent;
|
|
41
140
|
CFTimeInterval _edgeInsetsAnimationStart;
|
|
42
141
|
CFTimeInterval _edgeInsetsAnimationDuration;
|
|
142
|
+
BOOL _poiEnabled;
|
|
143
|
+
LuggMapViewPoiFilterMode _poiFilterMode;
|
|
144
|
+
NSArray<NSString *> *_poiFilterCategories;
|
|
43
145
|
}
|
|
44
146
|
|
|
45
147
|
@synthesize delegate = _delegate;
|
|
@@ -48,6 +150,12 @@
|
|
|
48
150
|
if (self = [super init]) {
|
|
49
151
|
_overlayToPolylineMap = [NSMapTable strongToWeakObjectsMapTable];
|
|
50
152
|
_overlayToPolygonMap = [NSMapTable strongToWeakObjectsMapTable];
|
|
153
|
+
_overlayToCircleMap = [NSMapTable strongToWeakObjectsMapTable];
|
|
154
|
+
_overlayToGroundOverlayMap = [NSMapTable strongToWeakObjectsMapTable];
|
|
155
|
+
_overlayToTileOverlayMap = [NSMapTable strongToWeakObjectsMapTable];
|
|
156
|
+
_poiEnabled = YES;
|
|
157
|
+
_poiFilterMode = LuggMapViewPoiFilterMode::Including;
|
|
158
|
+
_poiFilterCategories = @[];
|
|
51
159
|
}
|
|
52
160
|
return self;
|
|
53
161
|
}
|
|
@@ -91,6 +199,7 @@
|
|
|
91
199
|
|
|
92
200
|
[_tapGesture requireGestureRecognizerToFail:_longPressGesture];
|
|
93
201
|
|
|
202
|
+
_wrapperView = wrapperView;
|
|
94
203
|
[wrapperView addSubview:_mapView];
|
|
95
204
|
|
|
96
205
|
MKCoordinateRegion region = [_mapView regionForCenterCoordinate:coordinate
|
|
@@ -103,6 +212,7 @@
|
|
|
103
212
|
}
|
|
104
213
|
|
|
105
214
|
- (void)destroy {
|
|
215
|
+
[self dismissNonBubbledCallout];
|
|
106
216
|
[self stopEdgeInsetsAnimation];
|
|
107
217
|
if (_tapGesture) {
|
|
108
218
|
[_mapView removeGestureRecognizer:_tapGesture];
|
|
@@ -139,15 +249,181 @@
|
|
|
139
249
|
_mapView.showsUserLocation = enabled;
|
|
140
250
|
}
|
|
141
251
|
|
|
142
|
-
|
|
252
|
+
static MKPointOfInterestCategory poiCategoryFromString(NSString *string) {
|
|
253
|
+
static NSDictionary<NSString *, MKPointOfInterestCategory> *map;
|
|
254
|
+
static dispatch_once_t onceToken;
|
|
255
|
+
dispatch_once(&onceToken, ^{
|
|
256
|
+
NSMutableDictionary<NSString *, MKPointOfInterestCategory> *m =
|
|
257
|
+
[NSMutableDictionary dictionaryWithDictionary:@{
|
|
258
|
+
@"airport" : MKPointOfInterestCategoryAirport,
|
|
259
|
+
@"amusement-park" : MKPointOfInterestCategoryAmusementPark,
|
|
260
|
+
@"aquarium" : MKPointOfInterestCategoryAquarium,
|
|
261
|
+
@"atm" : MKPointOfInterestCategoryATM,
|
|
262
|
+
@"bakery" : MKPointOfInterestCategoryBakery,
|
|
263
|
+
@"bank" : MKPointOfInterestCategoryBank,
|
|
264
|
+
@"beach" : MKPointOfInterestCategoryBeach,
|
|
265
|
+
@"brewery" : MKPointOfInterestCategoryBrewery,
|
|
266
|
+
@"cafe" : MKPointOfInterestCategoryCafe,
|
|
267
|
+
@"campground" : MKPointOfInterestCategoryCampground,
|
|
268
|
+
@"car-rental" : MKPointOfInterestCategoryCarRental,
|
|
269
|
+
@"ev-charger" : MKPointOfInterestCategoryEVCharger,
|
|
270
|
+
@"fire-station" : MKPointOfInterestCategoryFireStation,
|
|
271
|
+
@"fitness-center" : MKPointOfInterestCategoryFitnessCenter,
|
|
272
|
+
@"food-market" : MKPointOfInterestCategoryFoodMarket,
|
|
273
|
+
@"gas-station" : MKPointOfInterestCategoryGasStation,
|
|
274
|
+
@"hospital" : MKPointOfInterestCategoryHospital,
|
|
275
|
+
@"hotel" : MKPointOfInterestCategoryHotel,
|
|
276
|
+
@"laundry" : MKPointOfInterestCategoryLaundry,
|
|
277
|
+
@"library" : MKPointOfInterestCategoryLibrary,
|
|
278
|
+
@"marina" : MKPointOfInterestCategoryMarina,
|
|
279
|
+
@"movie-theater" : MKPointOfInterestCategoryMovieTheater,
|
|
280
|
+
@"museum" : MKPointOfInterestCategoryMuseum,
|
|
281
|
+
@"national-park" : MKPointOfInterestCategoryNationalPark,
|
|
282
|
+
@"nightlife" : MKPointOfInterestCategoryNightlife,
|
|
283
|
+
@"park" : MKPointOfInterestCategoryPark,
|
|
284
|
+
@"parking" : MKPointOfInterestCategoryParking,
|
|
285
|
+
@"pharmacy" : MKPointOfInterestCategoryPharmacy,
|
|
286
|
+
@"police" : MKPointOfInterestCategoryPolice,
|
|
287
|
+
@"post-office" : MKPointOfInterestCategoryPostOffice,
|
|
288
|
+
@"public-transport" : MKPointOfInterestCategoryPublicTransport,
|
|
289
|
+
@"restaurant" : MKPointOfInterestCategoryRestaurant,
|
|
290
|
+
@"restroom" : MKPointOfInterestCategoryRestroom,
|
|
291
|
+
@"school" : MKPointOfInterestCategorySchool,
|
|
292
|
+
@"stadium" : MKPointOfInterestCategoryStadium,
|
|
293
|
+
@"store" : MKPointOfInterestCategoryStore,
|
|
294
|
+
@"theater" : MKPointOfInterestCategoryTheater,
|
|
295
|
+
@"university" : MKPointOfInterestCategoryUniversity,
|
|
296
|
+
@"winery" : MKPointOfInterestCategoryWinery,
|
|
297
|
+
@"zoo" : MKPointOfInterestCategoryZoo,
|
|
298
|
+
}];
|
|
299
|
+
if (@available(iOS 18.0, *)) {
|
|
300
|
+
[m addEntriesFromDictionary:@{
|
|
301
|
+
@"animal-service" : MKPointOfInterestCategoryAnimalService,
|
|
302
|
+
@"automotive-repair" : MKPointOfInterestCategoryAutomotiveRepair,
|
|
303
|
+
@"baseball" : MKPointOfInterestCategoryBaseball,
|
|
304
|
+
@"basketball" : MKPointOfInterestCategoryBasketball,
|
|
305
|
+
@"beauty" : MKPointOfInterestCategoryBeauty,
|
|
306
|
+
@"bowling" : MKPointOfInterestCategoryBowling,
|
|
307
|
+
@"castle" : MKPointOfInterestCategoryCastle,
|
|
308
|
+
@"convention-center" : MKPointOfInterestCategoryConventionCenter,
|
|
309
|
+
@"distillery" : MKPointOfInterestCategoryDistillery,
|
|
310
|
+
@"fairground" : MKPointOfInterestCategoryFairground,
|
|
311
|
+
@"fishing" : MKPointOfInterestCategoryFishing,
|
|
312
|
+
@"fortress" : MKPointOfInterestCategoryFortress,
|
|
313
|
+
@"go-kart" : MKPointOfInterestCategoryGoKart,
|
|
314
|
+
@"golf" : MKPointOfInterestCategoryGolf,
|
|
315
|
+
@"hiking" : MKPointOfInterestCategoryHiking,
|
|
316
|
+
@"kayaking" : MKPointOfInterestCategoryKayaking,
|
|
317
|
+
@"landmark" : MKPointOfInterestCategoryLandmark,
|
|
318
|
+
@"mailbox" : MKPointOfInterestCategoryMailbox,
|
|
319
|
+
@"mini-golf" : MKPointOfInterestCategoryMiniGolf,
|
|
320
|
+
@"music-venue" : MKPointOfInterestCategoryMusicVenue,
|
|
321
|
+
@"national-monument" : MKPointOfInterestCategoryNationalMonument,
|
|
322
|
+
@"planetarium" : MKPointOfInterestCategoryPlanetarium,
|
|
323
|
+
@"rock-climbing" : MKPointOfInterestCategoryRockClimbing,
|
|
324
|
+
@"rv-park" : MKPointOfInterestCategoryRVPark,
|
|
325
|
+
@"skate-park" : MKPointOfInterestCategorySkatePark,
|
|
326
|
+
@"skating" : MKPointOfInterestCategorySkating,
|
|
327
|
+
@"skiing" : MKPointOfInterestCategorySkiing,
|
|
328
|
+
@"soccer" : MKPointOfInterestCategorySoccer,
|
|
329
|
+
@"spa" : MKPointOfInterestCategorySpa,
|
|
330
|
+
@"surfing" : MKPointOfInterestCategorySurfing,
|
|
331
|
+
@"swimming" : MKPointOfInterestCategorySwimming,
|
|
332
|
+
@"tennis" : MKPointOfInterestCategoryTennis,
|
|
333
|
+
@"volleyball" : MKPointOfInterestCategoryVolleyball,
|
|
334
|
+
}];
|
|
335
|
+
}
|
|
336
|
+
map = [m copy];
|
|
337
|
+
});
|
|
338
|
+
return map[string];
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
- (void)applyPoiFilter {
|
|
342
|
+
if (!_poiEnabled) {
|
|
343
|
+
_mapView.pointOfInterestFilter =
|
|
344
|
+
MKPointOfInterestFilter.filterExcludingAllCategories;
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
if (_poiFilterCategories.count > 0) {
|
|
348
|
+
NSMutableArray<MKPointOfInterestCategory> *categories =
|
|
349
|
+
[NSMutableArray array];
|
|
350
|
+
for (NSString *name in _poiFilterCategories) {
|
|
351
|
+
MKPointOfInterestCategory category = poiCategoryFromString(name);
|
|
352
|
+
if (category) {
|
|
353
|
+
[categories addObject:category];
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (categories.count > 0) {
|
|
357
|
+
if (_poiFilterMode == LuggMapViewPoiFilterMode::Excluding) {
|
|
358
|
+
_mapView.pointOfInterestFilter = [[MKPointOfInterestFilter alloc]
|
|
359
|
+
initExcludingCategories:categories];
|
|
360
|
+
} else {
|
|
361
|
+
_mapView.pointOfInterestFilter = [[MKPointOfInterestFilter alloc]
|
|
362
|
+
initIncludingCategories:categories];
|
|
363
|
+
}
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
_mapView.pointOfInterestFilter = nil;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
- (void)setInsetAdjustment:(LuggMapViewInsetAdjustment)insetAdjustment {
|
|
371
|
+
BOOL automatic = (insetAdjustment == LuggMapViewInsetAdjustment::Automatic);
|
|
372
|
+
if (_mapView.insetsLayoutMarginsFromSafeArea == automatic)
|
|
373
|
+
return;
|
|
374
|
+
|
|
375
|
+
CLLocationCoordinate2D center = _mapView.centerCoordinate;
|
|
376
|
+
_mapView.insetsLayoutMarginsFromSafeArea = automatic;
|
|
377
|
+
|
|
378
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
379
|
+
[self->_mapView setCenterCoordinate:center animated:NO];
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
- (void)setPoiEnabled:(BOOL)enabled {
|
|
384
|
+
_poiEnabled = enabled;
|
|
385
|
+
[self applyPoiFilter];
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
- (void)setPoiFilterMode:(LuggMapViewPoiFilterMode)mode {
|
|
389
|
+
_poiFilterMode = mode;
|
|
390
|
+
[self applyPoiFilter];
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
- (void)setPoiFilterCategories:(NSArray<NSString *> *)categories {
|
|
394
|
+
_poiFilterCategories = categories;
|
|
395
|
+
[self applyPoiFilter];
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
- (void)setMapType:(LuggMapViewMapType)mapType {
|
|
399
|
+
switch (mapType) {
|
|
400
|
+
case LuggMapViewMapType::Satellite:
|
|
401
|
+
_mapView.mapType = MKMapTypeSatellite;
|
|
402
|
+
break;
|
|
403
|
+
case LuggMapViewMapType::Terrain:
|
|
404
|
+
_mapView.mapType = MKMapTypeStandard;
|
|
405
|
+
break;
|
|
406
|
+
case LuggMapViewMapType::Hybrid:
|
|
407
|
+
_mapView.mapType = MKMapTypeHybrid;
|
|
408
|
+
break;
|
|
409
|
+
case LuggMapViewMapType::MutedStandard:
|
|
410
|
+
_mapView.mapType = MKMapTypeMutedStandard;
|
|
411
|
+
break;
|
|
412
|
+
default:
|
|
413
|
+
_mapView.mapType = MKMapTypeStandard;
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
- (void)setTheme:(LuggMapViewTheme)theme {
|
|
143
419
|
switch (theme) {
|
|
144
|
-
case
|
|
420
|
+
case LuggMapViewTheme::Dark:
|
|
145
421
|
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
|
|
146
422
|
break;
|
|
147
|
-
case
|
|
423
|
+
case LuggMapViewTheme::Light:
|
|
148
424
|
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
|
|
149
425
|
break;
|
|
150
|
-
default:
|
|
426
|
+
default:
|
|
151
427
|
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
|
|
152
428
|
break;
|
|
153
429
|
}
|
|
@@ -174,6 +450,7 @@
|
|
|
174
450
|
CGFloat deltaY = newOffsetY - oldOffsetY;
|
|
175
451
|
|
|
176
452
|
_mapView.layoutMargins = edgeInsets;
|
|
453
|
+
_edgeInsetsCurrent = edgeInsets;
|
|
177
454
|
|
|
178
455
|
if (deltaX != 0 || deltaY != 0) {
|
|
179
456
|
CLLocationCoordinate2D currentCenter = _mapView.centerCoordinate;
|
|
@@ -224,7 +501,7 @@
|
|
|
224
501
|
_edgeInsetsFrom.right +
|
|
225
502
|
(_edgeInsetsTo.right - _edgeInsetsFrom.right) * t);
|
|
226
503
|
|
|
227
|
-
[self setEdgeInsets:current oldEdgeInsets:
|
|
504
|
+
[self setEdgeInsets:current oldEdgeInsets:_edgeInsetsCurrent];
|
|
228
505
|
|
|
229
506
|
if (progress >= 1.0) {
|
|
230
507
|
[self stopEdgeInsetsAnimation];
|
|
@@ -307,6 +584,55 @@
|
|
|
307
584
|
return nil;
|
|
308
585
|
}
|
|
309
586
|
|
|
587
|
+
- (LuggCircleView *)hitTestCircleAtPoint:(CGPoint)point {
|
|
588
|
+
CLLocationCoordinate2D tapCoordinate = [_mapView convertPoint:point
|
|
589
|
+
toCoordinateFromView:_mapView];
|
|
590
|
+
CLLocation *tapLocation =
|
|
591
|
+
[[CLLocation alloc] initWithLatitude:tapCoordinate.latitude
|
|
592
|
+
longitude:tapCoordinate.longitude];
|
|
593
|
+
|
|
594
|
+
NSArray<id<MKOverlay>> *overlays = _mapView.overlays;
|
|
595
|
+
for (NSInteger i = overlays.count - 1; i >= 0; i--) {
|
|
596
|
+
id<MKOverlay> overlay = overlays[i];
|
|
597
|
+
if (![overlay isKindOfClass:[MKCircle class]])
|
|
598
|
+
continue;
|
|
599
|
+
|
|
600
|
+
LuggCircleView *circleView = [_overlayToCircleMap objectForKey:overlay];
|
|
601
|
+
if (!circleView || !circleView.tappable)
|
|
602
|
+
continue;
|
|
603
|
+
|
|
604
|
+
CLLocation *center =
|
|
605
|
+
[[CLLocation alloc] initWithLatitude:circleView.center.latitude
|
|
606
|
+
longitude:circleView.center.longitude];
|
|
607
|
+
CLLocationDistance distance = [tapLocation distanceFromLocation:center];
|
|
608
|
+
if (distance <= circleView.radius)
|
|
609
|
+
return circleView;
|
|
610
|
+
}
|
|
611
|
+
return nil;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
- (LuggGroundOverlayView *)hitTestGroundOverlayAtPoint:(CGPoint)point {
|
|
615
|
+
CLLocationCoordinate2D tapCoordinate = [_mapView convertPoint:point
|
|
616
|
+
toCoordinateFromView:_mapView];
|
|
617
|
+
|
|
618
|
+
NSArray<id<MKOverlay>> *overlays = _mapView.overlays;
|
|
619
|
+
for (NSInteger i = overlays.count - 1; i >= 0; i--) {
|
|
620
|
+
id<MKOverlay> overlay = overlays[i];
|
|
621
|
+
if (![overlay isKindOfClass:[GroundImageOverlay class]])
|
|
622
|
+
continue;
|
|
623
|
+
|
|
624
|
+
LuggGroundOverlayView *view =
|
|
625
|
+
[_overlayToGroundOverlayMap objectForKey:overlay];
|
|
626
|
+
if (!view || !view.tappable)
|
|
627
|
+
continue;
|
|
628
|
+
|
|
629
|
+
MKMapPoint mapPoint = MKMapPointForCoordinate(tapCoordinate);
|
|
630
|
+
if (MKMapRectContainsPoint(overlay.boundingMapRect, mapPoint))
|
|
631
|
+
return view;
|
|
632
|
+
}
|
|
633
|
+
return nil;
|
|
634
|
+
}
|
|
635
|
+
|
|
310
636
|
- (BOOL)hitTestAnnotationAtPoint:(CGPoint)point {
|
|
311
637
|
for (id<MKAnnotation> annotation in _mapView.annotations) {
|
|
312
638
|
MKAnnotationView *view = [_mapView viewForAnnotation:annotation];
|
|
@@ -319,15 +645,41 @@
|
|
|
319
645
|
return NO;
|
|
320
646
|
}
|
|
321
647
|
|
|
648
|
+
- (BOOL)hitTestCalloutAtPoint:(CGPoint)point {
|
|
649
|
+
if (!_activeNonBubbledMarker)
|
|
650
|
+
return NO;
|
|
651
|
+
|
|
652
|
+
UIView *contentView = _activeNonBubbledMarker.calloutView.contentView;
|
|
653
|
+
CGPoint local = [contentView convertPoint:point fromView:_mapView];
|
|
654
|
+
return [contentView pointInside:local withEvent:nil];
|
|
655
|
+
}
|
|
656
|
+
|
|
322
657
|
- (void)handleTap:(UITapGestureRecognizer *)gesture {
|
|
323
658
|
if (gesture.state != UIGestureRecognizerStateEnded)
|
|
324
659
|
return;
|
|
325
660
|
|
|
326
661
|
CGPoint point = [gesture locationInView:_mapView];
|
|
662
|
+
if ([self hitTestCalloutAtPoint:point])
|
|
663
|
+
return;
|
|
664
|
+
|
|
665
|
+
[self dismissNonBubbledCallout];
|
|
327
666
|
|
|
328
667
|
if ([self hitTestAnnotationAtPoint:point])
|
|
329
668
|
return;
|
|
330
669
|
|
|
670
|
+
LuggGroundOverlayView *groundOverlayView =
|
|
671
|
+
[self hitTestGroundOverlayAtPoint:point];
|
|
672
|
+
if (groundOverlayView) {
|
|
673
|
+
[groundOverlayView emitPressEvent];
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
LuggCircleView *circleView = [self hitTestCircleAtPoint:point];
|
|
678
|
+
if (circleView) {
|
|
679
|
+
[circleView emitPressEvent];
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
|
|
331
683
|
LuggPolygonView *polygonView = [self hitTestPolygonAtPoint:point];
|
|
332
684
|
if (polygonView) {
|
|
333
685
|
[polygonView emitPressEvent];
|
|
@@ -390,6 +742,7 @@
|
|
|
390
742
|
longitude:mapView.centerCoordinate.longitude
|
|
391
743
|
zoom:mapView.zoomLevel
|
|
392
744
|
gesture:_isDragging];
|
|
745
|
+
[self positionNonBubbledCallout];
|
|
393
746
|
}
|
|
394
747
|
|
|
395
748
|
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
|
|
@@ -423,22 +776,23 @@
|
|
|
423
776
|
}
|
|
424
777
|
|
|
425
778
|
if (!markerView.hasCustomView) {
|
|
426
|
-
|
|
427
|
-
[[
|
|
428
|
-
|
|
779
|
+
LuggMarkerAnnotationView *markerAnnotationView =
|
|
780
|
+
[[LuggMarkerAnnotationView alloc] initWithAnnotation:annotation
|
|
781
|
+
reuseIdentifier:nil];
|
|
429
782
|
markerAnnotationView.canShowCallout = YES;
|
|
430
783
|
markerAnnotationView.displayPriority = MKFeatureDisplayPriorityRequired;
|
|
431
784
|
markerAnnotationView.layer.zPosition = markerView.zIndex;
|
|
432
785
|
markerAnnotationView.zPriority = markerView.zIndex;
|
|
433
786
|
markerAnnotationView.draggable = markerView.draggable;
|
|
787
|
+
[self applyCalloutView:markerView annotationView:markerAnnotationView];
|
|
434
788
|
[self addCenterTapGesture:markerAnnotationView];
|
|
435
789
|
markerAnnotation.annotationView = markerAnnotationView;
|
|
436
790
|
return markerAnnotationView;
|
|
437
791
|
}
|
|
438
792
|
|
|
439
|
-
|
|
440
|
-
[[
|
|
441
|
-
|
|
793
|
+
LuggAnnotationView *annotationView =
|
|
794
|
+
[[LuggAnnotationView alloc] initWithAnnotation:annotation
|
|
795
|
+
reuseIdentifier:nil];
|
|
442
796
|
annotationView.canShowCallout = YES;
|
|
443
797
|
annotationView.displayPriority = MKFeatureDisplayPriorityRequired;
|
|
444
798
|
annotationView.layer.zPosition = markerView.zIndex;
|
|
@@ -446,6 +800,8 @@
|
|
|
446
800
|
annotationView.draggable = markerView.draggable;
|
|
447
801
|
[self addCenterTapGesture:annotationView];
|
|
448
802
|
|
|
803
|
+
[self applyCalloutView:markerView annotationView:annotationView];
|
|
804
|
+
|
|
449
805
|
if (!markerView.rasterize) {
|
|
450
806
|
UIView *iconView = markerView.iconView;
|
|
451
807
|
[iconView removeFromSuperview];
|
|
@@ -501,6 +857,37 @@
|
|
|
501
857
|
return renderer;
|
|
502
858
|
}
|
|
503
859
|
|
|
860
|
+
if ([overlay isKindOfClass:[MKCircle class]]) {
|
|
861
|
+
LuggCircleView *circleView = [_overlayToCircleMap objectForKey:overlay];
|
|
862
|
+
MKCircle *circle = (MKCircle *)overlay;
|
|
863
|
+
|
|
864
|
+
MKCircleRenderer *renderer =
|
|
865
|
+
[[MKCircleRenderer alloc] initWithCircle:circle];
|
|
866
|
+
if (circleView) {
|
|
867
|
+
renderer.fillColor = circleView.fillColor;
|
|
868
|
+
renderer.strokeColor = circleView.strokeColor;
|
|
869
|
+
renderer.lineWidth = circleView.strokeWidth;
|
|
870
|
+
circleView.renderer = renderer;
|
|
871
|
+
}
|
|
872
|
+
return renderer;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
if ([overlay isKindOfClass:[GroundImageOverlay class]]) {
|
|
876
|
+
GroundImageOverlay *groundOverlay = (GroundImageOverlay *)overlay;
|
|
877
|
+
GroundImageOverlayRenderer *renderer =
|
|
878
|
+
[[GroundImageOverlayRenderer alloc] initWithOverlay:overlay];
|
|
879
|
+
renderer.image = groundOverlay.image;
|
|
880
|
+
renderer.overlayOpacity = groundOverlay.opacity;
|
|
881
|
+
return renderer;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
if ([overlay isKindOfClass:[MKTileOverlay class]]) {
|
|
885
|
+
MKTileOverlay *tileOverlay = (MKTileOverlay *)overlay;
|
|
886
|
+
MKTileOverlayRenderer *renderer =
|
|
887
|
+
[[MKTileOverlayRenderer alloc] initWithTileOverlay:tileOverlay];
|
|
888
|
+
return renderer;
|
|
889
|
+
}
|
|
890
|
+
|
|
504
891
|
return nil;
|
|
505
892
|
}
|
|
506
893
|
|
|
@@ -513,9 +900,104 @@
|
|
|
513
900
|
LuggMarkerView *markerView = annotation.markerView;
|
|
514
901
|
|
|
515
902
|
if (markerView) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
903
|
+
LuggCalloutView *calloutView = markerView.calloutView;
|
|
904
|
+
if (calloutView && !calloutView.bubbled && calloutView.hasCustomContent) {
|
|
905
|
+
[self showNonBubbledCallout:markerView];
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
- (void)mapView:(MKMapView *)mapView
|
|
911
|
+
didDeselectAnnotationView:(MKAnnotationView *)view {
|
|
912
|
+
if (![view.annotation isKindOfClass:[AppleMarkerAnnotation class]])
|
|
913
|
+
return;
|
|
914
|
+
|
|
915
|
+
AppleMarkerAnnotation *annotation = (AppleMarkerAnnotation *)view.annotation;
|
|
916
|
+
LuggMarkerView *markerView = annotation.markerView;
|
|
917
|
+
|
|
918
|
+
if (markerView && _activeNonBubbledMarker == markerView &&
|
|
919
|
+
!_isReselectingAnnotation) {
|
|
920
|
+
_isReselectingAnnotation = YES;
|
|
921
|
+
[_mapView selectAnnotation:annotation animated:NO];
|
|
922
|
+
_isReselectingAnnotation = NO;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
- (void)showNonBubbledCallout:(LuggMarkerView *)markerView {
|
|
927
|
+
[self dismissNonBubbledCallout];
|
|
928
|
+
|
|
929
|
+
LuggCalloutView *calloutView = markerView.calloutView;
|
|
930
|
+
UIView *contentView = calloutView.contentView;
|
|
931
|
+
[contentView removeFromSuperview];
|
|
932
|
+
|
|
933
|
+
contentView.userInteractionEnabled = YES;
|
|
934
|
+
contentView.hidden = YES;
|
|
935
|
+
calloutView.delegate = self;
|
|
936
|
+
|
|
937
|
+
AppleMarkerAnnotation *annotation =
|
|
938
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
939
|
+
MKAnnotationView *annotationView = annotation.annotationView;
|
|
940
|
+
if (annotationView) {
|
|
941
|
+
annotationView.clipsToBounds = NO;
|
|
942
|
+
[annotationView addSubview:contentView];
|
|
943
|
+
} else {
|
|
944
|
+
[_wrapperView addSubview:contentView];
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
_activeNonBubbledMarker = markerView;
|
|
948
|
+
[self positionNonBubbledCallout];
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
- (void)calloutViewDidUpdate:(LuggCalloutView *)calloutView {
|
|
952
|
+
[self positionNonBubbledCallout];
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
- (void)positionNonBubbledCallout {
|
|
956
|
+
if (!_activeNonBubbledMarker)
|
|
957
|
+
return;
|
|
958
|
+
|
|
959
|
+
LuggCalloutView *calloutView = _activeNonBubbledMarker.calloutView;
|
|
960
|
+
UIView *contentView = calloutView.contentView;
|
|
961
|
+
CGSize contentSize = contentView.bounds.size;
|
|
962
|
+
if (contentSize.width <= 0 || contentSize.height <= 0)
|
|
963
|
+
return;
|
|
964
|
+
|
|
965
|
+
CGPoint offset = calloutView.offset;
|
|
966
|
+
|
|
967
|
+
AppleMarkerAnnotation *annotation =
|
|
968
|
+
(AppleMarkerAnnotation *)_activeNonBubbledMarker.marker;
|
|
969
|
+
MKAnnotationView *annotationView = annotation.annotationView;
|
|
970
|
+
|
|
971
|
+
if (annotationView && contentView.superview == annotationView) {
|
|
972
|
+
CGPoint center =
|
|
973
|
+
CGPointMake(annotationView.bounds.size.width / 2.0 + offset.x,
|
|
974
|
+
-contentSize.height / 2.0 + offset.y);
|
|
975
|
+
contentView.center = center;
|
|
976
|
+
} else {
|
|
977
|
+
CGPoint point =
|
|
978
|
+
[_mapView convertCoordinate:_activeNonBubbledMarker.coordinate
|
|
979
|
+
toPointToView:_wrapperView];
|
|
980
|
+
contentView.center = CGPointMake(
|
|
981
|
+
point.x + offset.x, point.y - contentSize.height / 2.0 + offset.y);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
contentView.hidden = NO;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
- (void)dismissNonBubbledCallout {
|
|
988
|
+
if (!_activeNonBubbledMarker)
|
|
989
|
+
return;
|
|
990
|
+
|
|
991
|
+
LuggMarkerView *markerView = _activeNonBubbledMarker;
|
|
992
|
+
_activeNonBubbledMarker = nil;
|
|
993
|
+
|
|
994
|
+
markerView.calloutView.delegate = nil;
|
|
995
|
+
[markerView.calloutView.contentView removeFromSuperview];
|
|
996
|
+
|
|
997
|
+
AppleMarkerAnnotation *annotation =
|
|
998
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
999
|
+
if (annotation) {
|
|
1000
|
+
[_mapView deselectAnnotation:annotation animated:NO];
|
|
519
1001
|
}
|
|
520
1002
|
}
|
|
521
1003
|
|
|
@@ -570,7 +1052,74 @@
|
|
|
570
1052
|
if ([view.annotation isKindOfClass:[AppleMarkerAnnotation class]]) {
|
|
571
1053
|
AppleMarkerAnnotation *annotation =
|
|
572
1054
|
(AppleMarkerAnnotation *)view.annotation;
|
|
573
|
-
|
|
1055
|
+
LuggMarkerView *markerView = annotation.markerView;
|
|
1056
|
+
|
|
1057
|
+
if (markerView) {
|
|
1058
|
+
CGPoint point = [_mapView convertCoordinate:markerView.coordinate
|
|
1059
|
+
toPointToView:_mapView];
|
|
1060
|
+
[markerView emitPressEventWithPoint:point];
|
|
1061
|
+
|
|
1062
|
+
if (markerView.centerOnPress) {
|
|
1063
|
+
[_mapView setCenterCoordinate:annotation.coordinate animated:YES];
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
- (void)applyCalloutView:(LuggMarkerView *)markerView
|
|
1070
|
+
annotationView:(MKAnnotationView *)annotationView {
|
|
1071
|
+
LuggCalloutView *calloutView = markerView.calloutView;
|
|
1072
|
+
if (!calloutView) {
|
|
1073
|
+
annotationView.detailCalloutAccessoryView = nil;
|
|
1074
|
+
annotationView.rightCalloutAccessoryView = nil;
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
annotationView.rightCalloutAccessoryView = nil;
|
|
1079
|
+
|
|
1080
|
+
if (!calloutView.bubbled) {
|
|
1081
|
+
annotationView.canShowCallout = NO;
|
|
1082
|
+
annotationView.detailCalloutAccessoryView = nil;
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
annotationView.detailCalloutAccessoryView =
|
|
1087
|
+
calloutView.hasCustomContent ? calloutView.contentView : nil;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
- (void)showCalloutForMarkerView:(LuggMarkerView *)markerView {
|
|
1091
|
+
LuggCalloutView *calloutView = markerView.calloutView;
|
|
1092
|
+
_isProgrammaticSelect = YES;
|
|
1093
|
+
|
|
1094
|
+
if (calloutView && calloutView.hasCustomContent) {
|
|
1095
|
+
[self dismissNonBubbledCallout];
|
|
1096
|
+
AppleMarkerAnnotation *annotation =
|
|
1097
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
1098
|
+
if (!calloutView.bubbled) {
|
|
1099
|
+
[self showNonBubbledCallout:markerView];
|
|
1100
|
+
} else if (annotation) {
|
|
1101
|
+
[_mapView selectAnnotation:annotation animated:YES];
|
|
1102
|
+
}
|
|
1103
|
+
_isProgrammaticSelect = NO;
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
if (markerView.title.length > 0) {
|
|
1108
|
+
AppleMarkerAnnotation *annotation =
|
|
1109
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
1110
|
+
if (annotation) {
|
|
1111
|
+
[_mapView selectAnnotation:annotation animated:YES];
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
_isProgrammaticSelect = NO;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
- (void)hideCalloutForMarkerView:(LuggMarkerView *)markerView {
|
|
1118
|
+
[self dismissNonBubbledCallout];
|
|
1119
|
+
AppleMarkerAnnotation *annotation =
|
|
1120
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
1121
|
+
if (annotation) {
|
|
1122
|
+
[_mapView deselectAnnotation:annotation animated:YES];
|
|
574
1123
|
}
|
|
575
1124
|
}
|
|
576
1125
|
|
|
@@ -600,6 +1149,7 @@
|
|
|
600
1149
|
annotationView.draggable = markerView.draggable;
|
|
601
1150
|
annotationView.layer.zPosition = markerView.zIndex;
|
|
602
1151
|
annotationView.zPriority = markerView.zIndex;
|
|
1152
|
+
[self applyCalloutView:markerView annotationView:annotationView];
|
|
603
1153
|
}
|
|
604
1154
|
|
|
605
1155
|
[self updateAnnotationViewFrame:annotation];
|
|
@@ -617,6 +1167,24 @@
|
|
|
617
1167
|
[self syncPolygonView:polygonView];
|
|
618
1168
|
}
|
|
619
1169
|
|
|
1170
|
+
#pragma mark - CircleViewDelegate
|
|
1171
|
+
|
|
1172
|
+
- (void)circleViewDidUpdate:(LuggCircleView *)circleView {
|
|
1173
|
+
[self syncCircleView:circleView];
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
#pragma mark - GroundOverlayViewDelegate
|
|
1177
|
+
|
|
1178
|
+
- (void)groundOverlayViewDidUpdate:(LuggGroundOverlayView *)groundOverlayView {
|
|
1179
|
+
[self syncGroundOverlayView:groundOverlayView];
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
#pragma mark - TileOverlayViewDelegate
|
|
1183
|
+
|
|
1184
|
+
- (void)tileOverlayViewDidUpdate:(LuggTileOverlayView *)tileOverlayView {
|
|
1185
|
+
[self syncTileOverlayView:tileOverlayView];
|
|
1186
|
+
}
|
|
1187
|
+
|
|
620
1188
|
#pragma mark - Marker Management
|
|
621
1189
|
|
|
622
1190
|
- (void)addMarkerView:(LuggMarkerView *)markerView {
|
|
@@ -640,6 +1208,10 @@
|
|
|
640
1208
|
(AppleMarkerAnnotation *)markerView.marker;
|
|
641
1209
|
|
|
642
1210
|
if (annotation) {
|
|
1211
|
+
if (annotation.pendingScaleAnimation) {
|
|
1212
|
+
dispatch_block_cancel(annotation.pendingScaleAnimation);
|
|
1213
|
+
annotation.pendingScaleAnimation = nil;
|
|
1214
|
+
}
|
|
643
1215
|
annotation.annotationView.transform = CGAffineTransformIdentity;
|
|
644
1216
|
annotation.markerView = nil;
|
|
645
1217
|
annotation.annotationView = nil;
|
|
@@ -658,31 +1230,65 @@
|
|
|
658
1230
|
annotationView.transform = CGAffineTransformIdentity;
|
|
659
1231
|
|
|
660
1232
|
UIView *iconView = markerView.iconView;
|
|
661
|
-
|
|
662
|
-
|
|
1233
|
+
iconView.transform = CGAffineTransformIdentity;
|
|
1234
|
+
|
|
1235
|
+
// Clean up iconView from in-progress rasterize animation
|
|
1236
|
+
if (markerView.rasterize && [iconView superview] == annotationView) {
|
|
1237
|
+
[iconView removeFromSuperview];
|
|
1238
|
+
iconView.layer.anchorPoint = CGPointMake(0.5, 0.5);
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
CGSize size = iconView.bounds.size;
|
|
1242
|
+
if (size.width <= 0 || size.height <= 0)
|
|
663
1243
|
return;
|
|
664
1244
|
|
|
665
1245
|
CGFloat scale = markerView.scale;
|
|
666
1246
|
CGPoint anchor = markerView.anchor;
|
|
1247
|
+
CGFloat scaledWidth = size.width * scale;
|
|
1248
|
+
CGFloat scaledHeight = size.height * scale;
|
|
667
1249
|
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
1250
|
+
AppleMarkerAnnotation *annotation =
|
|
1251
|
+
(AppleMarkerAnnotation *)markerView.marker;
|
|
1252
|
+
|
|
1253
|
+
// Cancel any pending rasterize
|
|
1254
|
+
if (annotation.pendingScaleAnimation) {
|
|
1255
|
+
dispatch_block_cancel(annotation.pendingScaleAnimation);
|
|
1256
|
+
annotation.pendingScaleAnimation = nil;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
// Use live iconView during rapid updates (skip expensive rasterize per frame)
|
|
1260
|
+
if (markerView.rasterize && [iconView superview] != annotationView) {
|
|
1261
|
+
annotationView.image = nil;
|
|
1262
|
+
[annotationView addSubview:iconView];
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
iconView.layer.anchorPoint = anchor;
|
|
1266
|
+
iconView.bounds = CGRectMake(0, 0, size.width, size.height);
|
|
1267
|
+
iconView.center =
|
|
1268
|
+
CGPointMake(scaledWidth * anchor.x, scaledHeight * anchor.y);
|
|
1269
|
+
iconView.transform = CGAffineTransformMakeScale(scale, scale);
|
|
1270
|
+
|
|
1271
|
+
annotationView.bounds = CGRectMake(0, 0, scaledWidth, scaledHeight);
|
|
1272
|
+
annotationView.centerOffset = CGPointMake(scaledWidth * (0.5 - anchor.x),
|
|
1273
|
+
scaledHeight * (0.5 - anchor.y));
|
|
684
1274
|
annotationView.transform =
|
|
685
1275
|
CGAffineTransformMakeRotation(markerView.rotate * M_PI / 180.0);
|
|
1276
|
+
|
|
1277
|
+
// Debounce: rasterize once updates settle
|
|
1278
|
+
if (markerView.rasterize) {
|
|
1279
|
+
dispatch_block_t rasterizeBlock =
|
|
1280
|
+
dispatch_block_create((dispatch_block_flags_t)0, ^{
|
|
1281
|
+
annotation.pendingScaleAnimation = nil;
|
|
1282
|
+
annotationView.image = [markerView createScaledIconImage];
|
|
1283
|
+
[iconView removeFromSuperview];
|
|
1284
|
+
[markerView resetIconViewTransform];
|
|
1285
|
+
});
|
|
1286
|
+
|
|
1287
|
+
annotation.pendingScaleAnimation = rasterizeBlock;
|
|
1288
|
+
dispatch_after(
|
|
1289
|
+
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(150 * NSEC_PER_MSEC)),
|
|
1290
|
+
dispatch_get_main_queue(), rasterizeBlock);
|
|
1291
|
+
}
|
|
686
1292
|
}
|
|
687
1293
|
|
|
688
1294
|
- (void)updateAnnotationViewFrame:(AppleMarkerAnnotation *)annotation {
|
|
@@ -902,6 +1508,196 @@
|
|
|
902
1508
|
return [interiorPolygons copy];
|
|
903
1509
|
}
|
|
904
1510
|
|
|
1511
|
+
#pragma mark - Circle Management
|
|
1512
|
+
|
|
1513
|
+
- (void)addCircleView:(LuggCircleView *)circleView {
|
|
1514
|
+
circleView.delegate = self;
|
|
1515
|
+
[self addCircleOverlayToMap:circleView];
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
- (void)removeCircleView:(LuggCircleView *)circleView {
|
|
1519
|
+
circleView.delegate = nil;
|
|
1520
|
+
MKCircle *circle = (MKCircle *)circleView.circle;
|
|
1521
|
+
if (circle) {
|
|
1522
|
+
[_overlayToCircleMap removeObjectForKey:circle];
|
|
1523
|
+
[_mapView removeOverlay:circle];
|
|
1524
|
+
circleView.circle = nil;
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
- (void)syncCircleView:(LuggCircleView *)circleView {
|
|
1529
|
+
if (!_mapView)
|
|
1530
|
+
return;
|
|
1531
|
+
|
|
1532
|
+
MKCircle *oldCircle = (MKCircle *)circleView.circle;
|
|
1533
|
+
|
|
1534
|
+
MKCircle *newCircle = [MKCircle circleWithCenterCoordinate:circleView.center
|
|
1535
|
+
radius:circleView.radius];
|
|
1536
|
+
|
|
1537
|
+
circleView.circle = newCircle;
|
|
1538
|
+
[_overlayToCircleMap setObject:circleView forKey:newCircle];
|
|
1539
|
+
|
|
1540
|
+
MKCircleRenderer *renderer = (MKCircleRenderer *)circleView.renderer;
|
|
1541
|
+
if (renderer && oldCircle) {
|
|
1542
|
+
[_overlayToCircleMap removeObjectForKey:oldCircle];
|
|
1543
|
+
[_mapView removeOverlay:oldCircle];
|
|
1544
|
+
[self insertOverlay:newCircle withZIndex:circleView.zIndex];
|
|
1545
|
+
circleView.renderer = nil;
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
if (oldCircle) {
|
|
1550
|
+
[_overlayToCircleMap removeObjectForKey:oldCircle];
|
|
1551
|
+
[_mapView removeOverlay:oldCircle];
|
|
1552
|
+
}
|
|
1553
|
+
[self insertOverlay:newCircle withZIndex:circleView.zIndex];
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
- (void)addCircleOverlayToMap:(LuggCircleView *)circleView {
|
|
1557
|
+
if (!_mapView)
|
|
1558
|
+
return;
|
|
1559
|
+
|
|
1560
|
+
MKCircle *circle = [MKCircle circleWithCenterCoordinate:circleView.center
|
|
1561
|
+
radius:circleView.radius];
|
|
1562
|
+
|
|
1563
|
+
circleView.circle = circle;
|
|
1564
|
+
[_overlayToCircleMap setObject:circleView forKey:circle];
|
|
1565
|
+
[self insertOverlay:circle withZIndex:circleView.zIndex];
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
#pragma mark - Ground Overlay Management
|
|
1569
|
+
|
|
1570
|
+
- (void)addGroundOverlayView:(LuggGroundOverlayView *)groundOverlayView {
|
|
1571
|
+
groundOverlayView.delegate = self;
|
|
1572
|
+
[self syncGroundOverlayView:groundOverlayView];
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
- (void)removeGroundOverlayView:(LuggGroundOverlayView *)groundOverlayView {
|
|
1576
|
+
groundOverlayView.delegate = nil;
|
|
1577
|
+
GroundImageOverlay *overlay = (GroundImageOverlay *)groundOverlayView.overlay;
|
|
1578
|
+
if (overlay) {
|
|
1579
|
+
[_overlayToGroundOverlayMap removeObjectForKey:overlay];
|
|
1580
|
+
[_mapView removeOverlay:overlay];
|
|
1581
|
+
groundOverlayView.overlay = nil;
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
- (void)syncGroundOverlayView:(LuggGroundOverlayView *)groundOverlayView {
|
|
1586
|
+
if (!_mapView)
|
|
1587
|
+
return;
|
|
1588
|
+
|
|
1589
|
+
NSString *imageUri = groundOverlayView.imageUri;
|
|
1590
|
+
if (imageUri.length == 0)
|
|
1591
|
+
return;
|
|
1592
|
+
|
|
1593
|
+
// Remove old overlay
|
|
1594
|
+
GroundImageOverlay *oldOverlay =
|
|
1595
|
+
(GroundImageOverlay *)groundOverlayView.overlay;
|
|
1596
|
+
if (oldOverlay) {
|
|
1597
|
+
[_overlayToGroundOverlayMap removeObjectForKey:oldOverlay];
|
|
1598
|
+
[_mapView removeOverlay:oldOverlay];
|
|
1599
|
+
groundOverlayView.overlay = nil;
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
NSURL *url = [NSURL URLWithString:imageUri];
|
|
1603
|
+
if (!url)
|
|
1604
|
+
return;
|
|
1605
|
+
|
|
1606
|
+
__weak __typeof(self) weakSelf = self;
|
|
1607
|
+
__weak LuggGroundOverlayView *weakOverlayView = groundOverlayView;
|
|
1608
|
+
dispatch_async(
|
|
1609
|
+
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
1610
|
+
NSData *data = [NSData dataWithContentsOfURL:url];
|
|
1611
|
+
UIImage *image = data ? [UIImage imageWithData:data] : nil;
|
|
1612
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1613
|
+
[weakSelf addGroundOverlayToMap:weakOverlayView image:image];
|
|
1614
|
+
});
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
- (void)addGroundOverlayToMap:(LuggGroundOverlayView *)groundOverlayView
|
|
1619
|
+
image:(UIImage *)image {
|
|
1620
|
+
if (!_mapView || !groundOverlayView || !image)
|
|
1621
|
+
return;
|
|
1622
|
+
|
|
1623
|
+
MKMapPoint sw = MKMapPointForCoordinate(groundOverlayView.southwest);
|
|
1624
|
+
MKMapPoint ne = MKMapPointForCoordinate(groundOverlayView.northeast);
|
|
1625
|
+
|
|
1626
|
+
MKMapRect mapRect = MKMapRectMake(MIN(sw.x, ne.x), MIN(sw.y, ne.y),
|
|
1627
|
+
fabs(ne.x - sw.x), fabs(ne.y - sw.y));
|
|
1628
|
+
|
|
1629
|
+
CLLocationCoordinate2D center =
|
|
1630
|
+
CLLocationCoordinate2DMake((groundOverlayView.northeast.latitude +
|
|
1631
|
+
groundOverlayView.southwest.latitude) /
|
|
1632
|
+
2.0,
|
|
1633
|
+
(groundOverlayView.northeast.longitude +
|
|
1634
|
+
groundOverlayView.southwest.longitude) /
|
|
1635
|
+
2.0);
|
|
1636
|
+
|
|
1637
|
+
GroundImageOverlay *overlay = [[GroundImageOverlay alloc] init];
|
|
1638
|
+
overlay.coordinate = center;
|
|
1639
|
+
overlay.boundingMapRect = mapRect;
|
|
1640
|
+
overlay.image = image;
|
|
1641
|
+
overlay.opacity = groundOverlayView.opacity;
|
|
1642
|
+
|
|
1643
|
+
groundOverlayView.overlay = overlay;
|
|
1644
|
+
[_overlayToGroundOverlayMap setObject:groundOverlayView forKey:overlay];
|
|
1645
|
+
[self insertOverlay:overlay withZIndex:groundOverlayView.zIndex];
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
#pragma mark - Tile Overlay Management
|
|
1649
|
+
|
|
1650
|
+
- (void)addTileOverlayView:(LuggTileOverlayView *)tileOverlayView {
|
|
1651
|
+
tileOverlayView.delegate = self;
|
|
1652
|
+
[self syncTileOverlayView:tileOverlayView];
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
- (void)removeTileOverlayView:(LuggTileOverlayView *)tileOverlayView {
|
|
1656
|
+
tileOverlayView.delegate = nil;
|
|
1657
|
+
MKTileOverlay *overlay = (MKTileOverlay *)tileOverlayView.overlay;
|
|
1658
|
+
if (overlay) {
|
|
1659
|
+
[_overlayToTileOverlayMap removeObjectForKey:overlay];
|
|
1660
|
+
[_mapView removeOverlay:overlay];
|
|
1661
|
+
tileOverlayView.overlay = nil;
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
- (void)syncTileOverlayView:(LuggTileOverlayView *)tileOverlayView {
|
|
1666
|
+
if (!_mapView)
|
|
1667
|
+
return;
|
|
1668
|
+
|
|
1669
|
+
NSString *urlTemplate = tileOverlayView.urlTemplate;
|
|
1670
|
+
if (urlTemplate.length == 0)
|
|
1671
|
+
return;
|
|
1672
|
+
|
|
1673
|
+
// Remove old overlay
|
|
1674
|
+
MKTileOverlay *oldOverlay = (MKTileOverlay *)tileOverlayView.overlay;
|
|
1675
|
+
if (oldOverlay) {
|
|
1676
|
+
[_overlayToTileOverlayMap removeObjectForKey:oldOverlay];
|
|
1677
|
+
[_mapView removeOverlay:oldOverlay];
|
|
1678
|
+
tileOverlayView.overlay = nil;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
MKTileOverlay *tileOverlay;
|
|
1682
|
+
if (tileOverlayView.hasBounds) {
|
|
1683
|
+
BoundedTileOverlay *bounded =
|
|
1684
|
+
[[BoundedTileOverlay alloc] initWithURLTemplate:urlTemplate];
|
|
1685
|
+
bounded.southwest = tileOverlayView.southwest;
|
|
1686
|
+
bounded.northeast = tileOverlayView.northeast;
|
|
1687
|
+
tileOverlay = bounded;
|
|
1688
|
+
} else {
|
|
1689
|
+
tileOverlay = [[MKTileOverlay alloc] initWithURLTemplate:urlTemplate];
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
tileOverlay.tileSize =
|
|
1693
|
+
CGSizeMake(tileOverlayView.tileSize, tileOverlayView.tileSize);
|
|
1694
|
+
tileOverlay.canReplaceMapContent = NO;
|
|
1695
|
+
|
|
1696
|
+
tileOverlayView.overlay = tileOverlay;
|
|
1697
|
+
[_overlayToTileOverlayMap setObject:tileOverlayView forKey:tileOverlay];
|
|
1698
|
+
[_mapView addOverlay:tileOverlay level:MKOverlayLevelAboveRoads];
|
|
1699
|
+
}
|
|
1700
|
+
|
|
905
1701
|
- (void)insertOverlay:(id<MKOverlay>)overlay withZIndex:(NSInteger)zIndex {
|
|
906
1702
|
if (zIndex == 0) {
|
|
907
1703
|
[_mapView addOverlay:overlay];
|
|
@@ -917,10 +1713,18 @@
|
|
|
917
1713
|
[_overlayToPolylineMap objectForKey:overlays[i]];
|
|
918
1714
|
LuggPolygonView *existingPolygonView =
|
|
919
1715
|
[_overlayToPolygonMap objectForKey:overlays[i]];
|
|
1716
|
+
LuggCircleView *existingCircleView =
|
|
1717
|
+
[_overlayToCircleMap objectForKey:overlays[i]];
|
|
1718
|
+
LuggGroundOverlayView *existingGroundOverlayView =
|
|
1719
|
+
[_overlayToGroundOverlayMap objectForKey:overlays[i]];
|
|
920
1720
|
if (existingPolylineView) {
|
|
921
1721
|
existingZIndex = existingPolylineView.zIndex;
|
|
922
1722
|
} else if (existingPolygonView) {
|
|
923
1723
|
existingZIndex = existingPolygonView.zIndex;
|
|
1724
|
+
} else if (existingCircleView) {
|
|
1725
|
+
existingZIndex = existingCircleView.zIndex;
|
|
1726
|
+
} else if (existingGroundOverlayView) {
|
|
1727
|
+
existingZIndex = existingGroundOverlayView.zIndex;
|
|
924
1728
|
} else {
|
|
925
1729
|
continue;
|
|
926
1730
|
}
|