I am trying to track user's route and drawing lines of the route, but the addOverlay
only gives me correct points but no connection between each point.
-(void)viewWillAppear:(BOOL)animated{
self.trackPointArray = [[NSMutableArray alloc] init];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(CLLocation *)userLocation
{
[self.trackPointArray addObject:userLocation];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 1000, 1000);
[self.myMapView setRegion:[self.myMapView regionThatFits:region] animated:YES];
NSInteger stepsNumber = self.trackPointArray.count;
CLLocationCoordinate2D coordinates[stepsNumber];
for (NSInteger index = 0; index < stepsNumber; index++) {
CLLocation *location = [self.trackPointArray objectAtIndex:index];
coordinates[index] = [location coordinate];
}
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:stepsNumber];
[self.myMapView addOverlay:polyLine];
}
- (MKOverlayRenderer *)mapView:(MKMapView *)myMapView rendererForOverlay:(id<MKOverlay>)overlay
{
MKPolylineRenderer *polylineRenderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
polylineRenderer.lineWidth = 4.0f;
polylineRenderer.strokeColor = [UIColor redColor];
return polylineRenderer;
}
The userLocation
object the map view passes to the didUpdateUserLocation
delegate method is the same object every time.
The coordinate
inside the object may be different at each moment but each call to the delegate method always points to the same container object.
Specifically, it always points to the same object that the map view's userLocation
property points to (mapView.userLocation
). You can see this if you NSLog
userLocation
and mapView.userLocation
and notice their memory addresses are the same each time.
For this reason, when the code does this:
[self.trackPointArray addObject:userLocation];
it just adds the same object reference to the array multiple times.
Later, when the code loops through the trackPointArray
array, each call to [location coordinate]
returns the same coordinate every time because location
always points to the same object (mapView.userLocation
) and the coordinate does not change during the loop.
So each time the delegate method is called, a polyline is created with N coordinates (all the same) which ends up drawing a "dot".
The reason you see multiple dots is because the code is not removing previous overlays.
To fix all this, one easy way is to create a new CLLocation
instance each time you want to add the updated coordinates:
CLLocation *tpLocation = [[CLLocation alloc]
initWithLatitude:userLocation.coordinate.latitude
longitude:userLocation.coordinate.longitude];
[self.trackPointArray addObject:tpLocation];
Additionally, you should remove the previous overlay before adding the updated line. You won't notice the previous lines if you don't do this but they'll be there using up memory and performance:
[self.myMapView removeOverlays:self.myMapView.overlays];
[self.myMapView addOverlay:polyLine];