@lugg/maps 1.0.0-beta.17 → 1.0.0-beta.19
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/android/src/main/java/com/luggmaps/LuggMapView.kt +33 -0
- package/android/src/main/java/com/luggmaps/LuggMapViewManager.kt +9 -0
- package/android/src/main/java/com/luggmaps/LuggMapWrapperView.kt +27 -2
- package/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt +110 -5
- package/ios/LuggMapView.mm +153 -2
- package/ios/LuggMapWrapperView.h +5 -0
- package/ios/LuggMapWrapperView.mm +18 -0
- package/ios/LuggMarkerView.mm +2 -0
- package/ios/core/AppleMapProvider.h +8 -0
- package/ios/core/AppleMapProvider.mm +41 -28
- package/ios/core/AppleStaticMapProvider.h +14 -0
- package/ios/core/AppleStaticMapProvider.mm +146 -0
- package/ios/core/GoogleMapProvider.h +10 -0
- package/ios/core/GoogleMapProvider.mm +47 -41
- package/ios/core/GoogleStaticMapProvider.h +21 -0
- package/ios/core/GoogleStaticMapProvider.mm +207 -0
- package/ios/core/MKPolylineAnimator.m +67 -43
- package/ios/core/MapProviderDelegate.h +6 -0
- package/ios/core/StaticMapProviderBase.h +70 -0
- package/ios/core/StaticMapProviderBase.mm +777 -0
- package/ios/extensions/MKMapView+Zoom.h +14 -0
- package/ios/extensions/MKMapView+Zoom.m +17 -15
- package/ios/extensions/UIView+Snapshot.h +16 -0
- package/ios/extensions/UIView+Snapshot.m +27 -0
- package/lib/module/MapView.js +4 -0
- package/lib/module/MapView.js.map +1 -1
- package/lib/module/MapView.web.js +8 -5
- package/lib/module/MapView.web.js.map +1 -1
- package/lib/module/fabric/LuggMapViewNativeComponent.ts +2 -0
- package/lib/typescript/src/MapView.d.ts.map +1 -1
- package/lib/typescript/src/MapView.types.d.ts +18 -0
- package/lib/typescript/src/MapView.types.d.ts.map +1 -1
- package/lib/typescript/src/MapView.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts +2 -0
- package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/MapView.tsx +4 -0
- package/src/MapView.types.ts +18 -0
- package/src/MapView.web.tsx +14 -10
- package/src/fabric/LuggMapViewNativeComponent.ts +2 -0
|
@@ -35,8 +35,9 @@
|
|
|
35
35
|
NSArray<NSNumber *> *_cumulativeDistances;
|
|
36
36
|
CGFloat _totalLength;
|
|
37
37
|
CGColorSpaceRef _colorSpace;
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// Immutable snapshot read by background draws; rebuilt (never mutated)
|
|
39
|
+
// on the main thread
|
|
40
|
+
NSData *_colorCacheData;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
- (id)initWithPolyline:(MKPolyline *)polyline {
|
|
@@ -61,7 +62,6 @@
|
|
|
61
62
|
|
|
62
63
|
- (void)dealloc {
|
|
63
64
|
[self stopAnimation];
|
|
64
|
-
free(_colorCache);
|
|
65
65
|
if (_colorSpace) {
|
|
66
66
|
CGColorSpaceRelease(_colorSpace);
|
|
67
67
|
_colorSpace = NULL;
|
|
@@ -123,20 +123,25 @@
|
|
|
123
123
|
_displayLink.paused = NO;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
- (NSUInteger)indexForDistance:(CGFloat)distance
|
|
126
|
+
- (NSUInteger)indexForDistance:(CGFloat)distance
|
|
127
|
+
inDistances:(NSArray<NSNumber *> *)distances {
|
|
128
|
+
if (distances.count < 2) {
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
127
132
|
NSUInteger left = 0;
|
|
128
|
-
NSUInteger right =
|
|
133
|
+
NSUInteger right = distances.count - 1;
|
|
129
134
|
|
|
130
135
|
while (left < right) {
|
|
131
136
|
NSUInteger mid = (left + right + 1) / 2;
|
|
132
|
-
if (
|
|
137
|
+
if (distances[mid].doubleValue <= distance) {
|
|
133
138
|
left = mid;
|
|
134
139
|
} else {
|
|
135
140
|
right = mid - 1;
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
|
|
139
|
-
return MIN(left,
|
|
144
|
+
return MIN(left, distances.count - 2);
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
- (CGFloat)applyEasing:(CGFloat)t {
|
|
@@ -208,44 +213,52 @@
|
|
|
208
213
|
}
|
|
209
214
|
|
|
210
215
|
- (void)rebuildColorCache {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
216
|
+
NSUInteger count = _strokeColors.count;
|
|
217
|
+
if (count == 0) {
|
|
218
|
+
_colorCacheData = nil;
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
NSMutableData *data =
|
|
223
|
+
[NSMutableData dataWithLength:sizeof(RGBAComponents) * count];
|
|
224
|
+
RGBAComponents *cache = (RGBAComponents *)data.mutableBytes;
|
|
225
|
+
for (NSUInteger i = 0; i < count; i++) {
|
|
226
|
+
[_strokeColors[i] getRed:&cache[i].r
|
|
227
|
+
green:&cache[i].g
|
|
228
|
+
blue:&cache[i].b
|
|
229
|
+
alpha:&cache[i].a];
|
|
222
230
|
}
|
|
231
|
+
_colorCacheData = data;
|
|
223
232
|
}
|
|
224
233
|
|
|
225
234
|
- (void)colorAtGradientPosition:(CGFloat)position rgba:(RGBAComponents *)out {
|
|
226
|
-
|
|
235
|
+
NSData *cacheData = _colorCacheData;
|
|
236
|
+
const RGBAComponents *cache = (const RGBAComponents *)cacheData.bytes;
|
|
237
|
+
NSUInteger count = cacheData.length / sizeof(RGBAComponents);
|
|
238
|
+
|
|
239
|
+
if (count == 0) {
|
|
227
240
|
CGFloat r, g, b, a;
|
|
228
241
|
[self.strokeColor getRed:&r green:&g blue:&b alpha:&a];
|
|
229
242
|
*out = (RGBAComponents){r, g, b, a};
|
|
230
243
|
return;
|
|
231
244
|
}
|
|
232
|
-
if (
|
|
233
|
-
*out =
|
|
245
|
+
if (count == 1) {
|
|
246
|
+
*out = cache[0];
|
|
234
247
|
return;
|
|
235
248
|
}
|
|
236
249
|
|
|
237
250
|
position = MAX(0, MIN(1, position));
|
|
238
|
-
CGFloat scaledPos = position * (
|
|
251
|
+
CGFloat scaledPos = position * (count - 1);
|
|
239
252
|
NSUInteger index = (NSUInteger)scaledPos;
|
|
240
253
|
CGFloat t = scaledPos - index;
|
|
241
254
|
|
|
242
|
-
if (index >=
|
|
243
|
-
*out =
|
|
255
|
+
if (index >= count - 1) {
|
|
256
|
+
*out = cache[count - 1];
|
|
244
257
|
return;
|
|
245
258
|
}
|
|
246
259
|
|
|
247
|
-
RGBAComponents c1 =
|
|
248
|
-
RGBAComponents c2 =
|
|
260
|
+
RGBAComponents c1 = cache[index];
|
|
261
|
+
RGBAComponents c2 = cache[index + 1];
|
|
249
262
|
out->r = c1.r + (c2.r - c1.r) * t;
|
|
250
263
|
out->g = c1.g + (c2.g - c1.g) * t;
|
|
251
264
|
out->b = c1.b + (c2.b - c1.b) * t;
|
|
@@ -272,13 +285,20 @@
|
|
|
272
285
|
CGContextSetLineCap(context, self.lineCap);
|
|
273
286
|
CGContextSetLineJoin(context, self.lineJoin);
|
|
274
287
|
|
|
275
|
-
|
|
276
|
-
|
|
288
|
+
// drawMapRect: runs on MapKit's background render queues while
|
|
289
|
+
// updatePolyline: swaps these ivars on the main thread; snapshot them so
|
|
290
|
+
// one frame draws from a consistent pair
|
|
291
|
+
MKPolyline *polyline = _polyline;
|
|
292
|
+
NSArray<NSNumber *> *distances = _cumulativeDistances;
|
|
293
|
+
CGFloat totalLength = _totalLength;
|
|
294
|
+
|
|
295
|
+
if (polyline.pointCount < 2) {
|
|
277
296
|
return;
|
|
278
297
|
}
|
|
298
|
+
NSUInteger segmentCount = polyline.pointCount - 1;
|
|
279
299
|
|
|
280
300
|
// Snake animation: grow from start, then shrink from start
|
|
281
|
-
if (_animated &&
|
|
301
|
+
if (_animated && distances.count > 1 && totalLength > 0) {
|
|
282
302
|
CGFloat trailLength = MAX(0.01, MIN(1.0, _animatedOptions.trailLength));
|
|
283
303
|
CGFloat maxProgress = (trailLength < 1.0) ? 1.0 : 2.0;
|
|
284
304
|
CGFloat progress = MIN(_animationProgress, maxProgress);
|
|
@@ -287,15 +307,15 @@
|
|
|
287
307
|
CGFloat headDist, tailDist;
|
|
288
308
|
|
|
289
309
|
if (trailLength < 1.0) {
|
|
290
|
-
headDist = easedProgress *
|
|
291
|
-
tailDist = MAX(0, headDist -
|
|
310
|
+
headDist = easedProgress * totalLength;
|
|
311
|
+
tailDist = MAX(0, headDist - totalLength * trailLength);
|
|
292
312
|
} else if (easedProgress <= 1.0) {
|
|
293
313
|
tailDist = 0;
|
|
294
|
-
headDist = easedProgress *
|
|
314
|
+
headDist = easedProgress * totalLength;
|
|
295
315
|
} else {
|
|
296
316
|
CGFloat shrinkProgress = easedProgress - 1.0;
|
|
297
|
-
tailDist = shrinkProgress *
|
|
298
|
-
headDist =
|
|
317
|
+
tailDist = shrinkProgress * totalLength;
|
|
318
|
+
headDist = totalLength;
|
|
299
319
|
}
|
|
300
320
|
|
|
301
321
|
if (headDist <= tailDist) {
|
|
@@ -303,19 +323,23 @@
|
|
|
303
323
|
}
|
|
304
324
|
|
|
305
325
|
CGFloat visibleLength = headDist - tailDist;
|
|
306
|
-
NSUInteger startIndex = [self indexForDistance:tailDist];
|
|
307
|
-
NSUInteger endIndex = [self indexForDistance:headDist];
|
|
326
|
+
NSUInteger startIndex = [self indexForDistance:tailDist inDistances:distances];
|
|
327
|
+
NSUInteger endIndex = [self indexForDistance:headDist inDistances:distances];
|
|
328
|
+
|
|
329
|
+
// distances may lag behind the polyline (or vice versa) for a frame;
|
|
330
|
+
// never index past either
|
|
331
|
+
NSUInteger maxSegment = MIN(segmentCount, distances.count - 1);
|
|
308
332
|
|
|
309
|
-
for (NSUInteger i = startIndex; i <= endIndex && i <
|
|
310
|
-
CGFloat segStartDist =
|
|
311
|
-
CGFloat segEndDist =
|
|
333
|
+
for (NSUInteger i = startIndex; i <= endIndex && i < maxSegment; i++) {
|
|
334
|
+
CGFloat segStartDist = distances[i].doubleValue;
|
|
335
|
+
CGFloat segEndDist = distances[i + 1].doubleValue;
|
|
312
336
|
|
|
313
337
|
if (segEndDist <= tailDist || segStartDist >= headDist) {
|
|
314
338
|
continue;
|
|
315
339
|
}
|
|
316
340
|
|
|
317
|
-
CGPoint segStart = [self pointForMapPoint:
|
|
318
|
-
CGPoint segEnd = [self pointForMapPoint:
|
|
341
|
+
CGPoint segStart = [self pointForMapPoint:polyline.points[i]];
|
|
342
|
+
CGPoint segEnd = [self pointForMapPoint:polyline.points[i + 1]];
|
|
319
343
|
|
|
320
344
|
CGPoint drawStart = segStart;
|
|
321
345
|
CGPoint drawEnd = segEnd;
|
|
@@ -368,8 +392,8 @@
|
|
|
368
392
|
// Static gradient rendering
|
|
369
393
|
if (_strokeColors && _strokeColors.count > 1) {
|
|
370
394
|
for (NSUInteger i = 0; i < segmentCount; i++) {
|
|
371
|
-
CGPoint startPoint = [self pointForMapPoint:
|
|
372
|
-
CGPoint endPoint = [self pointForMapPoint:
|
|
395
|
+
CGPoint startPoint = [self pointForMapPoint:polyline.points[i]];
|
|
396
|
+
CGPoint endPoint = [self pointForMapPoint:polyline.points[i + 1]];
|
|
373
397
|
|
|
374
398
|
CGFloat gradientStart = (CGFloat)i / segmentCount;
|
|
375
399
|
CGFloat gradientEnd = (CGFloat)(i + 1) / segmentCount;
|
|
@@ -13,6 +13,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
13
13
|
|
|
14
14
|
@protocol MapProviderDelegate <NSObject>
|
|
15
15
|
- (void)mapProviderDidReady;
|
|
16
|
+
- (void)mapProviderDidFinishStaticSnapshot;
|
|
17
|
+
- (void)mapProviderDidCaptureStaticImage:(UIImage *)image;
|
|
16
18
|
- (void)mapProviderDidMoveCamera:(double)latitude
|
|
17
19
|
longitude:(double)longitude
|
|
18
20
|
zoom:(double)zoom
|
|
@@ -36,6 +38,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
36
38
|
@property(nonatomic, weak, nullable) id<MapProviderDelegate> delegate;
|
|
37
39
|
@property(nonatomic, readonly) BOOL isMapReady;
|
|
38
40
|
|
|
41
|
+
// Non-interactive static map. Must be set before initializeMapInView.
|
|
42
|
+
// Once fully rendered, the live map is replaced with a snapshot image.
|
|
43
|
+
@property(nonatomic, assign) BOOL staticMode;
|
|
44
|
+
|
|
39
45
|
- (void)initializeMapInView:(UIView *)wrapperView
|
|
40
46
|
initialCoordinate:(CLLocationCoordinate2D)coordinate
|
|
41
47
|
initialZoom:(double)zoom;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#import "MapProviderDelegate.h"
|
|
2
|
+
#import <MapKit/MapKit.h>
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
/// Projects a coordinate into view points for a static map covering mapRect
|
|
7
|
+
CGPoint LuggStaticPointForCoordinate(MKMapRect mapRect, CGSize size,
|
|
8
|
+
CLLocationCoordinate2D coordinate);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Shared behavior for static (non-interactive) map providers - the iOS
|
|
12
|
+
* equivalent of Android's lite mode. The base map renders asynchronously
|
|
13
|
+
* (subclass-specific), so static maps keep loading while the user scrolls
|
|
14
|
+
* without blocking the main thread.
|
|
15
|
+
*
|
|
16
|
+
* Markers are live views positioned over the base map via a mercator
|
|
17
|
+
* projection (mirroring Android's live markers on lite maps), so async
|
|
18
|
+
* marker content (e.g. remote images) still updates when it loads.
|
|
19
|
+
* Polylines, polygons, circles and ground overlays are drawn into a
|
|
20
|
+
* single CoreGraphics overlay view. All overlays stay hidden over the
|
|
21
|
+
* placeholder and reveal together with the base map. Tile overlays are
|
|
22
|
+
* not supported.
|
|
23
|
+
*/
|
|
24
|
+
@interface StaticMapProviderBase : NSObject <MapProvider>
|
|
25
|
+
|
|
26
|
+
/// Previously captured base map for the same cache key; when set, the base
|
|
27
|
+
/// render is skipped and the image is shown immediately.
|
|
28
|
+
@property(nonatomic, strong, nullable) UIImage *cachedBaseImage;
|
|
29
|
+
|
|
30
|
+
// State for subclasses
|
|
31
|
+
@property(nonatomic, readonly, nullable) UIView *wrapperView;
|
|
32
|
+
@property(nonatomic, readonly) CLLocationCoordinate2D coordinate;
|
|
33
|
+
@property(nonatomic, readonly) double zoom;
|
|
34
|
+
@property(nonatomic, readonly) MKMapRect mapRect;
|
|
35
|
+
@property(nonatomic, readonly) CGSize projectedSize;
|
|
36
|
+
@property(nonatomic, readonly) UIEdgeInsets edgeInsets;
|
|
37
|
+
@property(nonatomic, readonly) BOOL projectionReady;
|
|
38
|
+
@property(nonatomic, readonly) facebook::react::LuggMapViewMapType mapType;
|
|
39
|
+
@property(nonatomic, readonly) facebook::react::LuggMapViewTheme theme;
|
|
40
|
+
|
|
41
|
+
/// Shows the base image below the overlays, emits the static snapshot
|
|
42
|
+
/// delegate callbacks and marks the base render done.
|
|
43
|
+
- (void)displayBaseImage:(UIImage *)image fromCache:(BOOL)fromCache;
|
|
44
|
+
|
|
45
|
+
/// Shows the marker and shape overlays (idempotent). Called automatically
|
|
46
|
+
/// when the base image displays; subclasses whose base map is already
|
|
47
|
+
/// visible earlier (e.g. a live warmup map) can call it sooner.
|
|
48
|
+
- (void)revealOverlays;
|
|
49
|
+
|
|
50
|
+
#pragma mark - Subclass hooks
|
|
51
|
+
|
|
52
|
+
/// The map rect the base render covers for the given view size; must match
|
|
53
|
+
/// the SDK's camera framing so overlays align with the base map exactly.
|
|
54
|
+
- (MKMapRect)mapRectForSize:(CGSize)size;
|
|
55
|
+
|
|
56
|
+
/// Overlay view shown for markers without a custom child view.
|
|
57
|
+
- (UIView *)newDefaultMarkerOverlayView;
|
|
58
|
+
|
|
59
|
+
/// Starts rendering the base map for the current projection (guaranteed
|
|
60
|
+
/// projectionReady, no cached image). Called after mount (once initial
|
|
61
|
+
/// props have applied), after a resize, and from resumeAnimations to retry
|
|
62
|
+
/// a failed or cancelled render (e.g. device back online).
|
|
63
|
+
- (void)renderBaseMap;
|
|
64
|
+
|
|
65
|
+
/// Cancels an in-flight base render (resize or teardown).
|
|
66
|
+
- (void)cancelBaseRender;
|
|
67
|
+
|
|
68
|
+
@end
|
|
69
|
+
|
|
70
|
+
NS_ASSUME_NONNULL_END
|