Вопрос

I want to display a route from my location to a destination. I took this code http://code.google.com/p/octomapkit and I have added a few logging messages. Go got the route coordinates ( around 103) properly. They are on the way and filling the route from my location to destination, so the google call and parsing the elements is good. But when I want to display in MKMapView than it shows only the starting the polyline. Like 15 or 20 not more.

I will try to post the code from top to bottom:

The original code took the first element only and I was thinking maybe if I get the last I will see something else, if yes, than I will add all overlays - that's why the for loop.

otherwise : MKPolyline *polyLine = [self.mapView.overlays objectAtIndex:0];

#pragma mark MKMapViewDelegate
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
    MKPolylineView *routeLineView = nil;
    // should take the objectAtIndex:0 , but for test I will check if it has more
    for(int i=0;  i <self.mapView.overlays.count; i++ ){

        MKPolyline *polyLine = [self.mapView.overlays objectAtIndex:i];       

        routeLineView = [[[MKPolylineView alloc] initWithPolyline:polyLine] autorelease];
        routeLineView.fillColor = [UIColor redColor];
        routeLineView.strokeColor = [UIColor redColor];
        routeLineView.lineWidth = 3;   
    }   

    return routeLineView;
}


-(void) routeLoadSucceededWithRoutePoints:(MKMapPoint*)routePoints count:(int)pointNumber {
    //NSLog(@"MKMapVew+OctoRoute.routeLoadSucceededWithRoutePoints count: %d", pointNumber);

    MKPolyline* routeLine = nil;
    routeLine = [MKPolyline polylineWithPoints:routePoints count:pointNumber];

    // add the overlay to the map
    if (nil != routeLine) {

        // added zoom support:
        if(shouldZoom){
            MKCoordinateRegion region = [self coordinateRegion];
            [self setRegion:region animated:YES];
        }


        //[self removeOverlays:self.overlays];
        [self addOverlay:routeLine];
    }
}

the //[self removeOverlays:self.overlays]; has no effect if is commented or not, Iwas hoping it will create more :) -but not.

Inside mapPointCArrayFromJSONString I see the coordinates properly:

-(void) jsonLoadSucceededWithData:(NSData*)loadedData {
    self.routeParser.jsonStr = [[[NSString alloc] initWithData:loadedData encoding:NSUTF8StringEncoding] autorelease];
    MKMapPoint *mapPointCArray = [self.routeParser mapPointCArrayFromJSONString];

    //NSLog(@"OctoRouteService.jsonLoadSucceededWithData : %d"+ mapPointCArray.);
    [delegate routeLoadSucceededWithRoutePoints:mapPointCArray count:[self.routeParser numberOfPoints]];
}

The steps has the coordinated for sure. Checked many times.

-(MKMapPoint*) mapPointCArrayFromJSONString {   
    NSArray *steps = [self routeStepsArrayFromJSONString];

    //NSLog(@"OctoRouteParser.mapPointCArrayFromJSONString steps:%d ", steps.count);
    if(steps.count == 0){
        return nil;
    }

    MKMapPoint *mapPointCArray = malloc(sizeof(CLLocationCoordinate2D) * [steps count]*2 -1);
    numberOfPoints = [steps count]-1;

    int index=0;
    for (NSDictionary *stepDict in steps) {
        [self addRouteStepDict:stepDict toMapPointCArray:mapPointCArray atIndex:index];
        index = index+2;        
    }

    return mapPointCArray;
}

I can't see a reason why is only the first fraction of the route on my map, with red line.

Any suggestion?

Это было полезно?

Решение

The viewForOverlay delegate method will be called by the map view for each overlay it needs to display a view for. It may also call it more than once for each overlay.

Your code only needs to worry about creating and returning a view for the single overlay passed as a parameter to that method.

The code there should be something like this:

MKPolylineView *routeLineView = [[[MKPolylineView alloc] initWithPolyline:overlay] autorelease];
routeLineView.fillColor = [UIColor redColor];
routeLineView.strokeColor = [UIColor redColor];
routeLineView.lineWidth = 3;   
return routeLineView;

The existing code in your question returns the view corresponding to the last overlay that happens to be in the overlays array for every overlay the map view calls viewForOverlay for.


Additionally, that octomapkit has a bug in the mapPointCArrayFromJSONString method. These lines:

MKMapPoint *mapPointCArray = malloc(sizeof(CLLocationCoordinate2D) 
                                        * [steps count]*2 -1);
numberOfPoints = [steps count]-1;

should be:

MKMapPoint *mapPointCArray = malloc(sizeof(CLLocationCoordinate2D) 
                                        * [steps count]*2);
numberOfPoints = [steps count]*2;

The original first line is wrong because it excludes the end point of the last line segment.

The original second line is very wrong because numberOfPoints is supposed to reflect the number of points in the mapPointCArray (not the last index in the steps array). The way it was, the overlay would only show half the route.

It would be cleaner to change that code so the calculation is done only once:

numberOfPoints = [steps count]*2;
MKMapPoint *mapPointCArray = malloc(sizeof(CLLocationCoordinate2D) 
                                        * numberOfPoints);


The viewForOverlay method should still be coded as explained earlier. It should only work with the overlay parameter passed to it and not directly with the map view's overlays array.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top