2012-10-22 5 views
5

MapKitの2つの場所の間にルートを描く簡単なアプリケーションを作成しました。私はGoogle Map APIを使用しています。私は私がオンラインで見つけるのリソースを使用し、ここで私はGoogleにリクエストを行うために使用していたコードです:MapKit - マップが拡大されたときに通りを通りにする

_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]; 

これは完璧に動作します。

LA - Chicago route zoomed out

しかし:私はこれを実行し、LAとシカゴの間のルートを表示しようとすると、それがどのように見えるか、ここにあります。私はストリートレベルにマップズームすると、ここでのルートがどのように見えるかです:

LA - Chicago route zoomed in

誰でもマップがズームされたときに、私は私が描いています、そのルートは通りを次の達成できる方法を知っていますか?私は通りを通って正確な道を示すためにルートをしたいです。 Googleにリクエストする際に追加する必要があるパラメータがあるかどうかはわかりません。

助けや助言があれば助かります。事前に多くの感謝!


[編集#1:GoogleからのリクエストURLと応答の追加]:ちょうどそれを貼り付ける

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

マイリクエストURL上記のコードから操作対象を作成した後は、次のようになりますブラウザのURLを入力すると、Googleがコードで取得する応答としてGoogleが送信するJSONデータが表示されます。


[編集#2:Googleからの回答を解析し、パスを構築]

- (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; 
} 
+0

このライブラリを使用しています。これは私のためにうまくいっています。 https://github.com/kadirpekel/MapWithRoutes –

答えて

1

Googleはあなたにすべてのポイントを与えていない、またはあなたがすべてのポイントを見ていないように見えます。実際には、私はあなたのような目印だけでなく(直線で)いるように、目印の間にポリラインがあると思います。

  • あなたが
  • 限定されている場合、Googleが戻って送信するJSONデータを提供します見に応じてDirectionsStatusを確認してください。

私は、Googleが使用しているものとは根本的に異なるメルカトル投影法を使用しているとはよく分かりません。

+0

回答ありがとう、シリル。私の質問で#1の編集を確認し、あなたがそこに尋ねたデータを提供しました。 – uerceg

+0

編集#2では、Googleの回答を解析してパスを構築するソースコードを追加しました。私はDRIVINGからWALKINGにモードを変更しようとしましたが、面白いのは、GoogleのJSONレスポンスはDRIVINGモードよりも明らかに大きかったのですが、私はまだ205行目のWALKINGの座標を取得しています。パス。奇妙な。 – uerceg

+0

残念ながら、今後のお手伝いをするための道案内APIに関する知識は不十分です。 「overview_polylineには、結果のルートの近似(平滑)されたパスを表す符号化された点の配列を保持するオブジェクトが含まれています」というドキュメントの重要な要素だと思います。同じリクエストを短いルートで試して、それがより正確かどうかを確認してください。より良いルートが必要な場合は、NYまたはLAのような本当に平方なルートを試してみてください。 –

0

私はMapKitで使用される投影は、Googleマップで使用されるものとは異なると考えています。 MapKit uses Cylindrical Mercatorであり、Google uses a variant of the Mercator Projectionである。座標系 間の変換

普段緯度と経度の値を使用して地図上に 点を指定しているが、あなたが他の座標系へと変換する必要がある場合、 時間があってもよいです。 たとえば、 オーバーレイのシェイプを指定するときにマップポイントを使用します。 Appleから引用

関連する問題