MapKit - Make route line follow streets when map zoomed in

自古美人都是妖i 提交于 2019-12-21 17:46:51

问题


I wrote simple application which draws route between two locations on MapKit. I am using Google Map API. I used resources I found online and here's the code I am using to make request to Google:

_httpClient = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://maps.googleapis.com/"]];
    [_httpClient registerHTTPOperationClass: [AFJSONRequestOperation class]];
    [_httpClient setDefaultHeader:@"Accept" value:@"application/json"];

    NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
    [parameters setObject:[NSString stringWithFormat:@"%f,%f", coordinate.latitude, coordinate.longitude] forKey:@"origin"];
    [parameters setObject:[NSString stringWithFormat:@"%f,%f", endCoordinate.latitude, endCoordinate.longitude] forKey:@"destination"];
    [parameters setObject:@"true" forKey:@"sensor"];

    NSMutableURLRequest *request = [_httpClient requestWithMethod:@"GET" path: @"maps/api/directions/json" parameters:parameters];
    request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];    
    [operation  setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject){
        NSInteger statusCode = operation.response.statusCode;

        if (statusCode == 200)
        {
            NSLog(@"Success: %@", operation.responseString);
        }
        else
        {
            NSLog(@"Status code = %d", statusCode);
        }
    }
                                      failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                          NSLog(@"Error: %@",  operation.responseString);

                                      }
     ];

    [_httpClient enqueueHTTPRequestOperation:operation];

This works flawlessly. When I run this and try to show route between LA and Chicago, here's how it looks like:

BUT. When I zoom map to street level, here's how route looks like:

Does anyone know how can I achieve that route I am drawing follows streets when map is zoomed? I'd like route to show exact path through the streets. I don't know if some additional parameter needs to be added to my request to Google.

Any help or advice would be great. Many thanks in advance!


[edit #1: Adding request URL and response from Google]

My request URL after creating operation object from code above looks like this:

http://maps.googleapis.com/maps/api/directions/json?sensor=true&destination=34%2E052360,-118%2E243560&origin=41%2E903630,-87%2E629790

Just paste that URL to your browser and you will see the JSON data Google sends as the response which I get in my code also.


[edit #2: Parsing answer from Google and building the path]

- (void)parseResponse:(NSData *)response
{
    NSDictionary *dictResponse = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableContainers error:nil];
    NSArray *routes = [dictResponse objectForKey:@"routes"];
    NSDictionary *route = [routes lastObject];

    if (route)
    {
        NSString *overviewPolyline = [[route objectForKey: @"overview_polyline"] objectForKey:@"points"];
        _path = [self decodePolyLine:overviewPolyline];
    }
}

- (NSMutableArray *)decodePolyLine:(NSString *)encodedStr
{
    NSMutableString *encoded = [[NSMutableString alloc] initWithCapacity:[encodedStr length]];
    [encoded appendString:encodedStr];
    [encoded replaceOccurrencesOfString:@"\\\\" withString:@"\\"
                                options:NSLiteralSearch
                                  range:NSMakeRange(0, [encoded length])];
    NSInteger len = [encoded length];
    NSInteger index = 0;
    NSMutableArray *array = [[NSMutableArray alloc] init];
    NSInteger lat=0;
    NSInteger lng=0;

    while (index < len)
    {
        NSInteger b;
        NSInteger shift = 0;
        NSInteger result = 0;

        do
        {
            b = [encoded characterAtIndex:index++] - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);

        NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
        lat += dlat;
        shift = 0;
        result = 0;

        do
        {
            b = [encoded characterAtIndex:index++] - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);

        NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
        lng += dlng;
        NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5];
        NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];

        CLLocation *location = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
        [array addObject:location];
    }

    return array;
}

回答1:


It looks like Google is not giving you all the points, or you are not looking at all the points. Actually, I'd expect polylines between placemarks, not only placemarks like you seem to have (with a straight line).

  • Check DirectionsStatus in the response to see if you are limited
  • Provide the json data that Google sends back.

I'm not so sure they use a radically different Mercator projection from the one used by Google.




回答2:


I believe that the projection used by MapKit is different than that used by Google Maps. MapKit uses Cylindrical Mercator, while Google uses a variant of the Mercator Projection.

Converting Between Coordinate Systems Although you normally specify points on the map using latitude and longitude values, there may be times when you need to convert to and from other coordinate systems. For example, you typically use map points when specifying the shape of overlays.

Quoted from Apple:



来源:https://stackoverflow.com/questions/13013873/mapkit-make-route-line-follow-streets-when-map-zoomed-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!