Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions example/bare/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PODS:
- hermes-engine (250829098.0.10):
- hermes-engine/Pre-built (= 250829098.0.10)
- hermes-engine/Pre-built (250829098.0.10)
- LuggMaps (1.0.0-beta.14):
- LuggMaps (1.0.0-beta.16):
- GoogleMaps
- hermes-engine
- RCTRequired
Expand Down Expand Up @@ -2427,7 +2427,7 @@ SPEC CHECKSUMS:
FBLazyVector: 24e62c765683b8d89006a88a2c8f5cf019f0074d
GoogleMaps: 0608099d4870cac8754bdba9b6953db543432438
hermes-engine: a43fcac5345a0a468667778019547c5fd282c6e2
LuggMaps: b69f00e83f91bd2e00fb32341dff2d2cc57e794a
LuggMaps: 7f6539e8b1f2d1c328f6c9634cc0544a78b39076
RCTDeprecation: a4c521821fab57cbb125b36effe84d897d0dfa12
RCTRequired: 9f3a7e5645d4bc3f551593de7550bb66ab6e42bc
RCTSwiftUI: 239ed2eb9e73de5a6f518810630f0c95e01c8702
Expand Down
6 changes: 6 additions & 0 deletions example/shared/src/components/CrewMarker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface CrewMarkerProps {
loaded?: boolean;
speed?: number;
zoom?: number;
onSegment?: (index: number) => void;
}

const getBearing = (from: Coordinate, to: Coordinate, currentBearing = 0) => {
Expand Down Expand Up @@ -57,7 +58,10 @@ export const CrewMarker = ({
loaded = false,
speed = 1,
zoom = BASE_ZOOM,
onSegment,
}: CrewMarkerProps) => {
const onSegmentRef = useRef(onSegment);
onSegmentRef.current = onSegment;
const latitude = useSharedValue(route[0]?.latitude ?? 0);
const longitude = useSharedValue(route[0]?.longitude ?? 0);
const bearingValue = useSharedValue(0);
Expand Down Expand Up @@ -102,6 +106,8 @@ export const CrewMarker = ({
return;
}

onSegmentRef.current?.(index);

const from = route[index]!;
const to = route[index + 1]!;

Expand Down
14 changes: 12 additions & 2 deletions example/shared/src/components/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ export const Map = memo(
[markers]
);

const [truckIndex, setTruckIndex] = useState(0);
const routeAhead = useMemo(
() => smoothedRoute.slice(truckIndex),
[smoothedRoute, truckIndex]
);

const centerPinStyle = useAnimatedStyle(() => {
const bottom = animatedPosition
? screenHeight - animatedPosition.value
Expand Down Expand Up @@ -353,8 +359,12 @@ export const Map = memo(
provider === 'apple' || Platform.OS === 'android'
)
)}
<Route coordinates={smoothedRoute} />
<CrewMarker route={smoothedRoute} zoom={zoom} />
<Route coordinates={routeAhead} />
<CrewMarker
route={smoothedRoute}
zoom={zoom}
onSegment={setTruckIndex}
/>
<Polygon
coordinates={CIRCLE_COORDS}
holes={CIRCLE_HOLES}
Expand Down
55 changes: 40 additions & 15 deletions ios/core/GMSPolylineAnimator.m
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,25 @@ - (void)update {
}

GMSMutablePath *path = [GMSMutablePath path];
for (CLLocation *location in self.coordinates) {
[path addCoordinate:location.coordinate];
CLLocationCoordinate2D lastCoord = self.coordinates.firstObject.coordinate;
[path addCoordinate:lastCoord];
for (NSUInteger i = 1; i < self.coordinates.count; i++) {
CLLocationCoordinate2D coord = self.coordinates[i].coordinate;
if (coord.latitude == lastCoord.latitude && coord.longitude == lastCoord.longitude) {
continue;
}
[path addCoordinate:coord];
lastCoord = coord;
}

// Clear stale spans before swapping the path so Google Maps never rebuilds
// span models against a path with fewer segments (GMSModelStyleBuilder
// couldNotInstantiate -> EXC_BAD_ACCESS). Reassign spans once the new path is set.
_polyline.spans = nil;
_polyline.path = path;

if (self.strokeColors.count > 1) {
_polyline.spans = [self createGradientSpans];
if (path.count > 1 && self.strokeColors.count > 1) {
_polyline.spans = [self createGradientSpansForSegmentCount:path.count - 1];
} else {
_polyline.strokeColor = self.strokeColors.firstObject ?: [UIColor blackColor];
}
Expand Down Expand Up @@ -222,35 +234,44 @@ - (void)updateAnimatedPolyline {
}

if (headDist <= tailDist) {
_polyline.spans = nil;
_polyline.path = [GMSMutablePath path];
return;
}

CGFloat visibleLength = headDist - tailDist;
NSUInteger startIndex = [self indexForDistance:tailDist];
NSUInteger endIndex = [self indexForDistance:headDist];

GMSMutablePath *path = [GMSMutablePath path];
NSMutableArray<GMSStyleSpan *> *spans = [NSMutableArray array];

CLLocationCoordinate2D startCoord = [self coordinateAtDistance:tailDist];
[path addCoordinate:startCoord];
CLLocationCoordinate2D lastCoord = [self coordinateAtDistance:tailDist];
[path addCoordinate:lastCoord];

for (NSUInteger i = startIndex + 1; i <= endIndex; i++) {
[path addCoordinate:self.coordinates[i].coordinate];
CLLocationCoordinate2D coord = self.coordinates[i].coordinate;
if (coord.latitude == lastCoord.latitude && coord.longitude == lastCoord.longitude) {
continue;
}
[path addCoordinate:coord];
lastCoord = coord;
}

CLLocationCoordinate2D endCoord = [self coordinateAtDistance:headDist];
CLLocationCoordinate2D lastAdded =
(endIndex < self.coordinates.count) ? self.coordinates[endIndex].coordinate : endCoord;
if (endCoord.latitude != lastAdded.latitude || endCoord.longitude != lastAdded.longitude) {
if (endCoord.latitude != lastCoord.latitude || endCoord.longitude != lastCoord.longitude) {
[path addCoordinate:endCoord];
}

NSUInteger pathCount = path.count;
NSUInteger segmentCount = pathCount - 1;
NSUInteger segmentCount = (pathCount > 1) ? pathCount - 1 : 0;

if (segmentCount == 0) {
_polyline.spans = nil;
_polyline.path = path;
return;
}

if (self.strokeColors.count <= 1) {
_polyline.spans = nil;
_polyline.path = path;
_polyline.strokeColor = self.strokeColors.firstObject ?: [UIColor blackColor];
return;
Expand All @@ -259,20 +280,24 @@ - (void)updateAnimatedPolyline {
NSUInteger spanCount = MIN(segmentCount, kMaxAnimationSpans);
double segmentsPerSpan = (double)segmentCount / spanCount;

NSMutableArray<GMSStyleSpan *> *spans = [NSMutableArray array];
for (NSUInteger i = 0; i < spanCount; i++) {
CGFloat gradientPos = ((CGFloat)i + 0.5) / spanCount;
UIColor *color = [self colorAtGradientPosition:gradientPos];
GMSStrokeStyle *style = [GMSStrokeStyle solidColor:color];
[spans addObject:[GMSStyleSpan spanWithStyle:style segments:segmentsPerSpan]];
}

// Clear stale spans before swapping the path so Google Maps never rebuilds
// span models against a path with fewer segments (GMSModelStyleBuilder
// couldNotInstantiate -> EXC_BAD_ACCESS). Reassign spans once the new path is set.
_polyline.spans = nil;
_polyline.path = path;
_polyline.spans = spans;
}

- (NSArray<GMSStyleSpan *> *)createGradientSpans {
- (NSArray<GMSStyleSpan *> *)createGradientSpansForSegmentCount:(NSUInteger)segmentCount {
NSMutableArray<GMSStyleSpan *> *spans = [NSMutableArray array];
NSUInteger segmentCount = self.coordinates.count - 1;
NSUInteger spanCount = MIN(segmentCount, kMaxGradientSpans);
double segmentsPerSpan = (double)segmentCount / spanCount;

Expand Down
Loading