@lugg/maps 1.0.0-beta.1 → 1.0.0-beta.11
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 +3 -0
- package/android/src/main/java/com/luggmaps/LuggCalloutView.kt +9 -2
- package/android/src/main/java/com/luggmaps/LuggCalloutViewManager.kt +4 -3
- 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/LuggMarkerView.kt +28 -0
- package/android/src/main/java/com/luggmaps/LuggMarkerViewManager.kt +13 -0
- package/android/src/main/java/com/luggmaps/LuggPackage.kt +4 -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 +451 -17
- package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +14 -0
- package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +27 -9
- 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 +1 -1
- package/ios/LuggCalloutView.mm +21 -11
- 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 +3 -0
- package/ios/LuggMarkerView.mm +23 -0
- package/ios/LuggTileOverlayView.h +31 -0
- package/ios/LuggTileOverlayView.mm +130 -0
- package/ios/core/AppleMapProvider.mm +697 -37
- package/ios/core/GMSPolylineAnimator.m +6 -3
- package/ios/core/GoogleMapProvider.mm +400 -22
- 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 +4 -1
- 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 +21 -18
- 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 +22 -4
- package/lib/module/components/Marker.js.map +1 -1
- package/lib/module/components/Marker.web.js +23 -10
- 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 +1 -1
- 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 +3 -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/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 +18 -6
- 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 +6 -0
- package/lib/typescript/src/components/index.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggCalloutViewNativeComponent.d.ts +1 -1
- 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 +9 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +7 -1
- 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 +5 -2
- package/src/MapProvider.web.tsx +5 -3
- package/src/MapView.tsx +12 -1
- package/src/MapView.types.ts +118 -1
- package/src/MapView.web.tsx +378 -345
- 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/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 +32 -6
- package/src/components/Marker.types.ts +19 -6
- package/src/components/Marker.web.tsx +196 -150
- 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 +10 -0
- package/src/components/index.web.ts +9 -0
- package/src/fabric/LuggCalloutViewNativeComponent.ts +1 -1
- 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 +12 -1
- package/src/index.web.ts +15 -0
- package/src/types.ts +0 -5
|
@@ -1,8 +1,17 @@
|
|
|
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
|
+
|
|
2
8
|
#import "../LuggCalloutView.h"
|
|
9
|
+
#import "../LuggCircleView.h"
|
|
10
|
+
#import "../LuggGroundOverlayView.h"
|
|
3
11
|
#import "../LuggMarkerView.h"
|
|
4
12
|
#import "../LuggPolygonView.h"
|
|
5
13
|
#import "../LuggPolylineView.h"
|
|
14
|
+
#import "../LuggTileOverlayView.h"
|
|
6
15
|
#import "../extensions/MKMapView+Zoom.h"
|
|
7
16
|
#import "LuggAnnotationView.h"
|
|
8
17
|
#import "MKPolylineAnimator.h"
|
|
@@ -13,17 +22,96 @@
|
|
|
13
22
|
@property(nonatomic, copy, nullable) NSString *subtitle;
|
|
14
23
|
@property(nonatomic, strong) LuggMarkerView *markerView;
|
|
15
24
|
@property(nonatomic, weak) MKAnnotationView *annotationView;
|
|
25
|
+
@property(nonatomic, copy, nullable) dispatch_block_t pendingScaleAnimation;
|
|
16
26
|
@end
|
|
17
27
|
|
|
18
28
|
@implementation AppleMarkerAnnotation
|
|
19
29
|
@end
|
|
20
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
|
+
|
|
21
107
|
@implementation LuggAppleMapViewContent
|
|
22
108
|
@end
|
|
23
109
|
|
|
24
110
|
@interface AppleMapProvider () <
|
|
25
111
|
LuggMarkerViewDelegate, LuggCalloutViewDelegate, LuggPolylineViewDelegate,
|
|
26
|
-
LuggPolygonViewDelegate,
|
|
112
|
+
LuggPolygonViewDelegate, LuggCircleViewDelegate,
|
|
113
|
+
LuggGroundOverlayViewDelegate, LuggTileOverlayViewDelegate,
|
|
114
|
+
UIGestureRecognizerDelegate>
|
|
27
115
|
@end
|
|
28
116
|
|
|
29
117
|
@implementation AppleMapProvider {
|
|
@@ -35,16 +123,25 @@
|
|
|
35
123
|
double _maxZoom;
|
|
36
124
|
NSMapTable<id<MKOverlay>, LuggPolylineView *> *_overlayToPolylineMap;
|
|
37
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;
|
|
38
130
|
UITapGestureRecognizer *_tapGesture;
|
|
39
131
|
UILongPressGestureRecognizer *_longPressGesture;
|
|
40
132
|
LuggMarkerView *_activeNonBubbledMarker;
|
|
41
133
|
BOOL _isReselectingAnnotation;
|
|
134
|
+
BOOL _isProgrammaticSelect;
|
|
42
135
|
// Edge insets animation
|
|
43
136
|
CADisplayLink *_edgeInsetsDisplayLink;
|
|
44
137
|
UIEdgeInsets _edgeInsetsFrom;
|
|
45
138
|
UIEdgeInsets _edgeInsetsTo;
|
|
139
|
+
UIEdgeInsets _edgeInsetsCurrent;
|
|
46
140
|
CFTimeInterval _edgeInsetsAnimationStart;
|
|
47
141
|
CFTimeInterval _edgeInsetsAnimationDuration;
|
|
142
|
+
BOOL _poiEnabled;
|
|
143
|
+
LuggMapViewPoiFilterMode _poiFilterMode;
|
|
144
|
+
NSArray<NSString *> *_poiFilterCategories;
|
|
48
145
|
}
|
|
49
146
|
|
|
50
147
|
@synthesize delegate = _delegate;
|
|
@@ -53,6 +150,12 @@
|
|
|
53
150
|
if (self = [super init]) {
|
|
54
151
|
_overlayToPolylineMap = [NSMapTable strongToWeakObjectsMapTable];
|
|
55
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 = @[];
|
|
56
159
|
}
|
|
57
160
|
return self;
|
|
58
161
|
}
|
|
@@ -146,15 +249,181 @@
|
|
|
146
249
|
_mapView.showsUserLocation = enabled;
|
|
147
250
|
}
|
|
148
251
|
|
|
149
|
-
|
|
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 {
|
|
150
419
|
switch (theme) {
|
|
151
|
-
case
|
|
420
|
+
case LuggMapViewTheme::Dark:
|
|
152
421
|
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
|
|
153
422
|
break;
|
|
154
|
-
case
|
|
423
|
+
case LuggMapViewTheme::Light:
|
|
155
424
|
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
|
|
156
425
|
break;
|
|
157
|
-
default:
|
|
426
|
+
default:
|
|
158
427
|
_mapView.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
|
|
159
428
|
break;
|
|
160
429
|
}
|
|
@@ -181,6 +450,7 @@
|
|
|
181
450
|
CGFloat deltaY = newOffsetY - oldOffsetY;
|
|
182
451
|
|
|
183
452
|
_mapView.layoutMargins = edgeInsets;
|
|
453
|
+
_edgeInsetsCurrent = edgeInsets;
|
|
184
454
|
|
|
185
455
|
if (deltaX != 0 || deltaY != 0) {
|
|
186
456
|
CLLocationCoordinate2D currentCenter = _mapView.centerCoordinate;
|
|
@@ -231,7 +501,7 @@
|
|
|
231
501
|
_edgeInsetsFrom.right +
|
|
232
502
|
(_edgeInsetsTo.right - _edgeInsetsFrom.right) * t);
|
|
233
503
|
|
|
234
|
-
[self setEdgeInsets:current oldEdgeInsets:
|
|
504
|
+
[self setEdgeInsets:current oldEdgeInsets:_edgeInsetsCurrent];
|
|
235
505
|
|
|
236
506
|
if (progress >= 1.0) {
|
|
237
507
|
[self stopEdgeInsetsAnimation];
|
|
@@ -314,6 +584,55 @@
|
|
|
314
584
|
return nil;
|
|
315
585
|
}
|
|
316
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
|
+
|
|
317
636
|
- (BOOL)hitTestAnnotationAtPoint:(CGPoint)point {
|
|
318
637
|
for (id<MKAnnotation> annotation in _mapView.annotations) {
|
|
319
638
|
MKAnnotationView *view = [_mapView viewForAnnotation:annotation];
|
|
@@ -348,6 +667,19 @@
|
|
|
348
667
|
if ([self hitTestAnnotationAtPoint:point])
|
|
349
668
|
return;
|
|
350
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
|
+
|
|
351
683
|
LuggPolygonView *polygonView = [self hitTestPolygonAtPoint:point];
|
|
352
684
|
if (polygonView) {
|
|
353
685
|
[polygonView emitPressEvent];
|
|
@@ -525,6 +857,37 @@
|
|
|
525
857
|
return renderer;
|
|
526
858
|
}
|
|
527
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
|
+
|
|
528
891
|
return nil;
|
|
529
892
|
}
|
|
530
893
|
|
|
@@ -537,10 +900,6 @@
|
|
|
537
900
|
LuggMarkerView *markerView = annotation.markerView;
|
|
538
901
|
|
|
539
902
|
if (markerView) {
|
|
540
|
-
CGPoint point = [_mapView convertCoordinate:markerView.coordinate
|
|
541
|
-
toPointToView:_mapView];
|
|
542
|
-
[markerView emitPressEventWithPoint:point];
|
|
543
|
-
|
|
544
903
|
LuggCalloutView *calloutView = markerView.calloutView;
|
|
545
904
|
if (calloutView && !calloutView.bubbled && calloutView.hasCustomContent) {
|
|
546
905
|
[self showNonBubbledCallout:markerView];
|
|
@@ -572,6 +931,7 @@
|
|
|
572
931
|
[contentView removeFromSuperview];
|
|
573
932
|
|
|
574
933
|
contentView.userInteractionEnabled = YES;
|
|
934
|
+
contentView.hidden = YES;
|
|
575
935
|
calloutView.delegate = self;
|
|
576
936
|
|
|
577
937
|
AppleMarkerAnnotation *annotation =
|
|
@@ -602,26 +962,26 @@
|
|
|
602
962
|
if (contentSize.width <= 0 || contentSize.height <= 0)
|
|
603
963
|
return;
|
|
604
964
|
|
|
605
|
-
CGPoint
|
|
965
|
+
CGPoint offset = calloutView.offset;
|
|
606
966
|
|
|
607
967
|
AppleMarkerAnnotation *annotation =
|
|
608
968
|
(AppleMarkerAnnotation *)_activeNonBubbledMarker.marker;
|
|
609
969
|
MKAnnotationView *annotationView = annotation.annotationView;
|
|
610
970
|
|
|
611
971
|
if (annotationView && contentView.superview == annotationView) {
|
|
612
|
-
CGPoint center =
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
contentSize.height * (0.5 - anchor.y));
|
|
972
|
+
CGPoint center =
|
|
973
|
+
CGPointMake(annotationView.bounds.size.width / 2.0 + offset.x,
|
|
974
|
+
-contentSize.height / 2.0 + offset.y);
|
|
616
975
|
contentView.center = center;
|
|
617
976
|
} else {
|
|
618
977
|
CGPoint point =
|
|
619
978
|
[_mapView convertCoordinate:_activeNonBubbledMarker.coordinate
|
|
620
979
|
toPointToView:_wrapperView];
|
|
621
|
-
contentView.center =
|
|
622
|
-
|
|
623
|
-
point.y + contentSize.height * (0.5 - anchor.y));
|
|
980
|
+
contentView.center = CGPointMake(
|
|
981
|
+
point.x + offset.x, point.y - contentSize.height / 2.0 + offset.y);
|
|
624
982
|
}
|
|
983
|
+
|
|
984
|
+
contentView.hidden = NO;
|
|
625
985
|
}
|
|
626
986
|
|
|
627
987
|
- (void)dismissNonBubbledCallout {
|
|
@@ -692,7 +1052,17 @@
|
|
|
692
1052
|
if ([view.annotation isKindOfClass:[AppleMarkerAnnotation class]]) {
|
|
693
1053
|
AppleMarkerAnnotation *annotation =
|
|
694
1054
|
(AppleMarkerAnnotation *)view.annotation;
|
|
695
|
-
|
|
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
|
+
}
|
|
696
1066
|
}
|
|
697
1067
|
}
|
|
698
1068
|
|
|
@@ -717,6 +1087,42 @@
|
|
|
717
1087
|
calloutView.hasCustomContent ? calloutView.contentView : nil;
|
|
718
1088
|
}
|
|
719
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];
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
720
1126
|
#pragma mark - MarkerViewDelegate
|
|
721
1127
|
|
|
722
1128
|
- (void)markerViewDidLayout:(LuggMarkerView *)markerView {
|
|
@@ -761,6 +1167,24 @@
|
|
|
761
1167
|
[self syncPolygonView:polygonView];
|
|
762
1168
|
}
|
|
763
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
|
+
|
|
764
1188
|
#pragma mark - Marker Management
|
|
765
1189
|
|
|
766
1190
|
- (void)addMarkerView:(LuggMarkerView *)markerView {
|
|
@@ -784,6 +1208,10 @@
|
|
|
784
1208
|
(AppleMarkerAnnotation *)markerView.marker;
|
|
785
1209
|
|
|
786
1210
|
if (annotation) {
|
|
1211
|
+
if (annotation.pendingScaleAnimation) {
|
|
1212
|
+
dispatch_block_cancel(annotation.pendingScaleAnimation);
|
|
1213
|
+
annotation.pendingScaleAnimation = nil;
|
|
1214
|
+
}
|
|
787
1215
|
annotation.annotationView.transform = CGAffineTransformIdentity;
|
|
788
1216
|
annotation.markerView = nil;
|
|
789
1217
|
annotation.annotationView = nil;
|
|
@@ -802,31 +1230,65 @@
|
|
|
802
1230
|
annotationView.transform = CGAffineTransformIdentity;
|
|
803
1231
|
|
|
804
1232
|
UIView *iconView = markerView.iconView;
|
|
805
|
-
|
|
806
|
-
|
|
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)
|
|
807
1243
|
return;
|
|
808
1244
|
|
|
809
1245
|
CGFloat scale = markerView.scale;
|
|
810
1246
|
CGPoint anchor = markerView.anchor;
|
|
1247
|
+
CGFloat scaledWidth = size.width * scale;
|
|
1248
|
+
CGFloat scaledHeight = size.height * scale;
|
|
811
1249
|
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
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));
|
|
828
1274
|
annotationView.transform =
|
|
829
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
|
+
}
|
|
830
1292
|
}
|
|
831
1293
|
|
|
832
1294
|
- (void)updateAnnotationViewFrame:(AppleMarkerAnnotation *)annotation {
|
|
@@ -1046,6 +1508,196 @@
|
|
|
1046
1508
|
return [interiorPolygons copy];
|
|
1047
1509
|
}
|
|
1048
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
|
+
|
|
1049
1701
|
- (void)insertOverlay:(id<MKOverlay>)overlay withZIndex:(NSInteger)zIndex {
|
|
1050
1702
|
if (zIndex == 0) {
|
|
1051
1703
|
[_mapView addOverlay:overlay];
|
|
@@ -1061,10 +1713,18 @@
|
|
|
1061
1713
|
[_overlayToPolylineMap objectForKey:overlays[i]];
|
|
1062
1714
|
LuggPolygonView *existingPolygonView =
|
|
1063
1715
|
[_overlayToPolygonMap objectForKey:overlays[i]];
|
|
1716
|
+
LuggCircleView *existingCircleView =
|
|
1717
|
+
[_overlayToCircleMap objectForKey:overlays[i]];
|
|
1718
|
+
LuggGroundOverlayView *existingGroundOverlayView =
|
|
1719
|
+
[_overlayToGroundOverlayMap objectForKey:overlays[i]];
|
|
1064
1720
|
if (existingPolylineView) {
|
|
1065
1721
|
existingZIndex = existingPolylineView.zIndex;
|
|
1066
1722
|
} else if (existingPolygonView) {
|
|
1067
1723
|
existingZIndex = existingPolygonView.zIndex;
|
|
1724
|
+
} else if (existingCircleView) {
|
|
1725
|
+
existingZIndex = existingCircleView.zIndex;
|
|
1726
|
+
} else if (existingGroundOverlayView) {
|
|
1727
|
+
existingZIndex = existingGroundOverlayView.zIndex;
|
|
1068
1728
|
} else {
|
|
1069
1729
|
continue;
|
|
1070
1730
|
}
|