Draw polyline between given points on the map

2019-05-21 21:43发布

问题:

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.

回答1:

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.