I am implementing an iOS application, and I want to draw a polyline between several given coordinates on the map.
I wrote the code and got the polylines being drawn from my point reaching an infinite point. In other words the beginning point of the line starts from the my given lat and long point, but the end of the line is infinite and not the other point.
This is my code...
I filled the coordinates in a NSMutableArray
called routeLatitudes
. The array cells are being filled one for latitude and one for longitude.
MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * [routeLatitudes count]);
for(int idx = 0; idx < [routeLatitudes count]; idx=idx+2)
{
CLLocationCoordinate2D workingCoordinate;
workingCoordinate.latitude=[[routeLatitudes objectAtIndex:idx] doubleValue];
workingCoordinate.longitude=[[routeLatitudes objectAtIndex:idx+1] doubleValue];
MKMapPoint point = MKMapPointForCoordinate(workingCoordinate);
pointArr[idx] = point;
}
// create the polyline based on the array of points.
routeLine = [MKPolyline polylineWithPoints:pointArr count:[routeLatitudes count]];
[mapView addOverlay:self.routeLine];
free(pointArr);
and overlay delegate
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKOverlayView* overlayView = nil;
if(overlay == routeLine)
{
self.routeLineView = [[[MKPolylineView alloc] initWithPolyline:self.routeLine] autorelease];
self.routeLineView.fillColor = [UIColor colorWithRed:51 green:51 blue:255 alpha:1];
self.routeLineView.strokeColor = [UIColor colorWithRed:204 green:0 blue:0 alpha:1];
self.routeLineView.lineWidth = 3;
overlayView = routeLineView;
}
return overlayView;
}
So I need the lines to be drawn between the points over the map. The beginning of the line is the first dropped pin, and the end is on the last dropped pin.
According to the code, the routeLatitudes
array has objects listed like this:
index 0: latitude for point 1
index 1: longitude for point 1
index 2: latitude for point 2
index 3: longitude for point 2
index 4: latitude for point 3
index 5: longitude for point 3
...
So if routeLatitudes.count
is 6, it actually has only 3 points.
This means the malloc
is allocating the wrong number of points and the polylineWithPoints
call is also specifying the wrong number of points for the overlay.
The other problem is that since pointArr
will contain only half the objects that routeLatitudes
has, you can't use the same index value for both arrays.
The for
loop index counter idx
is being incremented by 2 at each iteration because that's how the routeLatitudes
points are layed out but then the same idx
value is used to set pointArr
.
So for idx=0
, pointArr[0]
is set but then for idx=2
, pointArr[2]
is set (instead of pointArr[1]
), and so on. This means every other position in pointArr
is left uninitialized resulting in the lines "going to infinity".
So the corrected code might look like this:
int pointCount = [routeLatitudes count] / 2;
MKMapPoint* pointArr = malloc(sizeof(MKMapPoint) * pointCount);
int pointArrIndex = 0; //it's simpler to keep a separate index for pointArr
for (int idx = 0; idx < [routeLatitudes count]; idx=idx+2)
{
CLLocationCoordinate2D workingCoordinate;
workingCoordinate.latitude=[[routeLatitudes objectAtIndex:idx] doubleValue];
workingCoordinate.longitude=[[routeLatitudes objectAtIndex:idx+1] doubleValue];
MKMapPoint point = MKMapPointForCoordinate(workingCoordinate);
pointArr[pointArrIndex] = point;
pointArrIndex++;
}
// create the polyline based on the array of points.
routeLine = [MKPolyline polylineWithPoints:pointArr count:pointCount];
[mapView addOverlay:routeLine];
free(pointArr);
Also note in the malloc
line, I corrected sizeof(CLLocationCoordinate2D)
to sizeof(MKMapPoint)
. This technically wasn't causing a problem because those two structs happen to be the same length but it's correct to use sizeof(MKMapPoint)
since that's what the array is going to contain.