web-dev-qa-db-ja.com

iPhone用Objective-CでGoogle Directions APIポリラインフィールドを緯度経度のポイントにデコードする方法は?

Google Directions APIを介して取得しているルートJSONに対応する地図にルートを描画したい: http://code.google.com/apis/maps/documentation/directions/

歩数フィールドから緯度と経度を抽出する方法を考え出しましたが、これは曲がりくねった道路にはあまりうまくいきません。私はポリライン情報をデコードする必要があると思う、私はポリラインをエンコードする方法に関するGoogleの指示を見つけました: http://code.google.com/apis/maps/documentation/utilities/polylinealgorithm.html

ここでAndroidのコードと、ポリラインのデコードに関するJavascriptのコードを見つけました。たとえば:

Google Directions APIを使用したマップビューの描画方向-ポリラインのデコード

AndroidがGoogleルートを取得して解析する

しかし、Objective-CのiPhoneコードについては同じものを見つけることができません。誰も私を助けてくれますか必要な場合は自分でできると確信していますが、既にどこかで利用可能な場合は時間を節約できます...

編集:ここで重要なのは、文字ごとにbase64エンコードをデコードできることです。具体的には、GoogleのJSONで次のようなものを取得します。これは、特にbase64エンコードを使用してエンコードされています。

...   "overview_polyline" : {
        "points" : "ydelDz~vpN_@NO@QEKWIYIIO?YCS@WFGBEBICCAE?G@y@RKBEBEBAD?HTpB@LALALCNEJEFSP_@LyDv@aB\\GBMB"
       },
...

注:この質問はGoogle Maps API v1を指していることを言及する必要があります。v2では、GMSPolyLine polyLineWithPathを使用してこれを行う方がはるかに簡単です。

44
Alan Moore

質問に関連する場合は、自分自身にリンクすることはルールに反しないことを願っています ブログ投稿 過去にこの問題を解決しました。リンクされた投稿からのスタンドアロンの回答:

@implementation MKPolyline (MKPolyline_EncodedString)

+ (MKPolyline *)polylineWithEncodedString:(NSString *)encodedString {
    const char *bytes = [encodedString UTF8String];
    NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    NSUInteger idx = 0;

    NSUInteger count = length / 4;
    CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
    NSUInteger coordIdx = 0;

    float latitude = 0;
    float longitude = 0;
    while (idx < length) {
        char byte = 0;
        int res = 0;
        char shift = 0;

        do {
            byte = bytes[idx++] - 63;
            res |= (byte & 0x1F) << shift;
            shift += 5;
        } while (byte >= 0x20);

        float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
        latitude += deltaLat;

        shift = 0;
        res = 0;

        do {
            byte = bytes[idx++] - 0x3F;
            res |= (byte & 0x1F) << shift;
            shift += 5;
        } while (byte >= 0x20);

        float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
        longitude += deltaLon;

        float finalLat = latitude * 1E-5;
        float finalLon = longitude * 1E-5;

        CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
        coords[coordIdx++] = coord;

        if (coordIdx == count) {
            NSUInteger newCount = count + 10;
            coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
            count = newCount;
        }
    }

    MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordIdx];
    free(coords);

    return polyline;
}

@end
84
Sedate Alien

フレームワークでGoogleが提供する方法を使用するのが、最善かつ最も軽い答えです。

[GMSPolyline polylineWithPath:[GMSPath pathFromEncodedPath:encodedPath]]

31
cdescours

IOSでGoogleマップを使用しており、ポリラインを含むルートを描画する場合、Google自体がポリラインからGMSPathを取得する簡単な方法を提供します。

GMSPath *pathFromPolyline = [GMSPath pathFromEncodedPath:polyLinePoints];

完全なコードは次のとおりです。

+ (void)callGoogleServiceToGetRouteDataFromSource:(CLLocation *)sourceLocation toDestination:(CLLocation *)destinationLocation onMap:(GMSMapView *)mapView_{
    NSString *baseUrl = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false", sourceLocation.coordinate.latitude,  sourceLocation.coordinate.longitude, destinationLocation.coordinate.latitude,  destinationLocation.coordinate.longitude];

    NSURL *url = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSLog(@"Url: %@", url);

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        GMSMutablePath *path = [GMSMutablePath path];

        NSError *error = nil;
        NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

        NSArray *routes = [result objectForKey:@"routes"];

        NSDictionary *firstRoute = [routes objectAtIndex:0];

        NSDictionary *leg =  [[firstRoute objectForKey:@"legs"] objectAtIndex:0];

        NSArray *steps = [leg objectForKey:@"steps"];

        int stepIndex = 0;

        CLLocationCoordinate2D stepCoordinates[1  + [steps count] + 1];

        for (NSDictionary *step in steps) {

            NSDictionary *start_location = [step objectForKey:@"start_location"];
            stepCoordinates[++stepIndex] = [self coordinateWithLocation:start_location];
            [path addCoordinate:[self coordinateWithLocation:start_location]];

            NSString *polyLinePoints = [[step objectForKey:@"polyline"] objectForKey:@"points"];
            GMSPath *polyLinePath = [GMSPath pathFromEncodedPath:polyLinePoints];
            for (int p=0; p<polyLinePath.count; p++) {
                [path addCoordinate:[polyLinePath coordinateAtIndex:p]];
            }


            if ([steps count] == stepIndex){
                NSDictionary *end_location = [step objectForKey:@"end_location"];
                stepCoordinates[++stepIndex] = [self coordinateWithLocation:end_location];
                [path addCoordinate:[self coordinateWithLocation:end_location]];
            }
        }

        GMSPolyline *polyline = nil;
        polyline = [GMSPolyline polylineWithPath:path];
        polyline.strokeColor = [UIColor grayColor];
        polyline.strokeWidth = 3.f;
        polyline.map = mapView_;
    }];
}

+ (CLLocationCoordinate2D)coordinateWithLocation:(NSDictionary*)location
{
    double latitude = [[location objectForKey:@"lat"] doubleValue];
    double longitude = [[location objectForKey:@"lng"] doubleValue];

    return CLLocationCoordinate2DMake(latitude, longitude);
}
10
RootCode
- (MKPolyline *)polylineWithEncodedString:(NSString *)encodedString {
    const char *bytes = [encodedString UTF8String];
    NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    NSUInteger idx = 0;
    NSUInteger count = length / 4;
    CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
    NSUInteger coordIdx = 0;
    float latitude = 0;
    float longitude = 0;
    while (idx < length) {
        char byte = 0;
        int res = 0;
        char shift = 0;
        do {
            byte = bytes[idx++] - 63;
            res |= (byte & 0x1F) << shift;
            shift += 5;
        } while (byte >= 0x20);

        float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
        latitude += deltaLat;

        shift = 0;
        res = 0;

        do {
            byte = bytes[idx++] - 0x3F;
            res |= (byte & 0x1F) << shift;
            shift += 5;
        } while (byte >= 0x20);

        float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
        longitude += deltaLon;

        float finalLat = latitude * 1E-5;
        float finalLon = longitude * 1E-5;

        CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
        coords[coordIdx++] = coord;

        if (coordIdx == count) {
            NSUInteger newCount = count + 10;
            coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
            count = newCount;
        }
    }

    MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordIdx];
    free(coords);
    return polyline;
}
- (MKPolygonRenderer *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay {
  //  MKPolygonRenderer *polylineView = [[MKPolygonRenderer alloc] initWithOverlay:overlay];
    MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
    polylineView.strokeColor = [UIColor redColor];
    polylineView.lineWidth = 4.0;
    [self zoomToPolyLine:mapview polyline:overlay animated:YES];
    return polylineView;
}
-(void)zoomToPolyLine: (MKMapView*)map polyline: (MKPolyline*)polyline animated: (BOOL)animated
{
    [map setVisibleMapRect:[polyline boundingMapRect] edgePadding:UIEdgeInsetsMake(25.0, 25.0, 25.0, 25.0) animated:animated];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
   // NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;
    if (currentLocation != nil) {
      currlong  =  [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
       currlt = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
    }
    NSString *Origin = [NSString stringWithFormat:@"%@%@%@",currlt,@",",currlong];

    //I have just mention static location
    NSString *drivein = @"23.0472963,72.52757040000006";
    NSString *apikey = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%@&destination=%@",Origin,drivein];

    NSURL *url = [NSURL URLWithString:apikey];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLResponse *response;
    NSError *error;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

    if(!error)
    {
        NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data
                                                                     options:kNilOptions
                                                                       error:&error];
        NSArray *routesArray = [jsonResponse objectForKey:@"routes"];
        NSLog(@"route array %@",routesArray);
        if ([routesArray count] > 0)
        {
            NSDictionary *routeDict = [routesArray objectAtIndex:0];
            NSDictionary *routeOverviewPolyline = [routeDict objectForKey:@"overview_polyline"];
            NSString *points = [routeOverviewPolyline objectForKey:@"points"];
            MKPolyline *line = [self polylineWithEncodedString:points];
            [mapview addOverlay:line];
        }
    }
    MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(currentLocation.coordinate, 500, 500);
    MKCoordinateRegion adjustedRegion = [mapview regionThatFits:viewRegion];
    [mapview setRegion:adjustedRegion animated:YES];
    mapview.showsUserLocation = YES;

    MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
    point.coordinate = currentLocation.coordinate;
    point.title = @"Your current Locations";
    point.subtitle = @"You are here!";
    [mapview addAnnotation:point];
    [locationmanger stopUpdatingLocation];
}
5
kalpesh

ルートアプリでどのように行うかを以下に示します。 keyPlaceは宛先オブジェクトです

- (void)getDirections {

  CLLocation *newLocation;// = currentUserLocation;
  MKPointAnnotation *annotation = [[[MKPointAnnotation alloc] init] autorelease];
  annotation.coordinate = CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude);
  annotation.title = @"You";
  [mapView addAnnotation:annotation];

  CLLocationCoordinate2D endCoordinate;

  NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false&mode=walking", newLocation.coordinate.latitude, newLocation.coordinate.longitude, keyPlace.lat, keyPlace.lon]];
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  [request startSynchronous];

  if ([[request.responseString.JSONValue valueForKey:@"status"] isEqualToString:@"ZERO_RESULTS"]) {
    [[[[UIAlertView alloc] initWithTitle:@"Error"
                                 message:@"Could not route path from your current location"
                                delegate:nil
                       cancelButtonTitle:@"Close"
                       otherButtonTitles:nil, nil] autorelease] show];
    self.navigationController.navigationBar.userInteractionEnabled = YES;
    return; 
  }

  int points_count = 0;
  if ([[request.responseString.JSONValue objectForKey:@"routes"] count])
    points_count = [[[[[[request.responseString.JSONValue objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"] count];

  if (!points_count) {
    [[[[UIAlertView alloc] initWithTitle:@"Error"
                                 message:@"Could not route path from your current location"
                                delegate:nil
                       cancelButtonTitle:@"Close"
                       otherButtonTitles:nil, nil] autorelease] show];
    self.navigationController.navigationBar.userInteractionEnabled = YES;
    return;     
  }
  CLLocationCoordinate2D points[points_count * 2];

  int j = 0;
  NSArray *steps = nil;
  if (points_count && [[[[request.responseString.JSONValue objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] count])
    steps = [[[[[request.responseString.JSONValue objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"];
  for (int i = 0; i < points_count; i++) {

    double st_lat = [[[[steps objectAtIndex:i] objectForKey:@"start_location"] valueForKey:@"lat"] doubleValue];
    double st_lon = [[[[steps objectAtIndex:i] objectForKey:@"start_location"] valueForKey:@"lng"] doubleValue];
    //NSLog(@"lat lon: %f %f", st_lat, st_lon);
    if (st_lat > 0.0f && st_lon > 0.0f) {
      points[j] = CLLocationCoordinate2DMake(st_lat, st_lon);
      j++;
    }
    double end_lat = [[[[steps objectAtIndex:i] objectForKey:@"end_location"] valueForKey:@"lat"] doubleValue];
    double end_lon = [[[[steps objectAtIndex:i] objectForKey:@"end_location"] valueForKey:@"lng"] doubleValue];

    if (end_lat > 0.0f && end_lon > 0.0f) {
      points[j] = CLLocationCoordinate2DMake(end_lat, end_lon);
      endCoordinate = CLLocationCoordinate2DMake(end_lat, end_lon);
      j++;
    }
  }

  MKPolyline *polyline = [MKPolyline polylineWithCoordinates:points count:points_count * 2];
  [mapView addOverlay:polyline];


}

#pragma mark - MapKit
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
  MKPinAnnotationView *annView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"currentloc"] autorelease];
  annView.canShowCallout = YES;
  annView.animatesDrop = YES;
  return annView;
}

- (MKOverlayView *)mapView:(MKMapView *)mapView
            viewForOverlay:(id<MKOverlay>)overlay {
  MKPolylineView *overlayView = [[[MKPolylineView alloc] initWithOverlay:overlay] autorelease];
  overlayView.lineWidth = 5;
  overlayView.strokeColor = [UIColor purpleColor];
  overlayView.fillColor = [[UIColor purpleColor] colorWithAlphaComponent:0.5f];
  return overlayView;
}
3
Eugene

誰かがVBAでデコードコードを必要とする場合に備えて、ここに(動作する)ポートがあります。

    Function decodeGeopoints(encoded)
  decodeGeopoints = ""
  ' This code is a port to VBA from code published here:
  ' http://blog.synyx.de/2010/06/routing-driving-directions-on-Android-part-1-get-the-route/

  '//decoding
  'List poly = new ArrayList();

  '// replace two backslashes by one (some error from the transmission)
  'encoded = encoded.replace("\\", "\");
  encoded = Replace(encoded, "\\", "\")

  'int index = 0, len = encoded.length();
  Dim index As Long
  index = 0
  Dim leng As Long
  leng = Len(encoded)

  'int lat = 0, lng = 0;
  Dim lat As Long
  lat = 0
  Dim lng As Long
  lng = 0

  'while (index < len) {
  While (index < leng)
     'int b, shift = 0, result = 0;
     Dim b, shift, result As Long
     b = 0
     shift = 0
     result = 0

     'do {
     Do
        'b = encoded.charAt(index++) - 63;
        index = index + 1
        b = Asc(Mid(encoded, index, 1)) - 63
        'result |= (b & 0x1f) << shift;
        result = result Or ((b And 31) * (2 ^ shift))

        'shift += 5;
        shift = shift + 5
     '} while (b >= 0x20);
     Loop While (b >= 32)
     'int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
     Dim dlat As Long
     If (result And 1) <> 0 Then
      dlat = Not Int(result / 2)
     Else
      dlat = Int(result / 2)
     End If

     'lat += dlat;
     lat = lat + dlat

     'shift = 0;
     shift = 0
     'result = 0;
     result = 0
     'do {
     Do
       'b = encoded.charAt(index++) - 63;
       index = index + 1
       b = Asc(Mid(encoded, index, 1)) - 63
       'result |= (b & 0x1f) << shift;
        result = result Or ((b And 31) * (2 ^ shift))
       'shift += 5;
        shift = shift + 5
     '} while (b >= 0x20);
     Loop While (b >= 32)
     'int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
     Dim dlng As Long
     If (result And 1) <> 0 Then
      dlng = Not Int(result / 2)
     Else
      dlng = Int(result / 2)
     End If

     'lng += dlng;
     lng = lng + dlng

     'GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6), (int) (((double) lng / 1E5) * 1E6));
     Dim myLat, myLng As Double
     myLat = (lat / 100000)
     'myLat = myLat * 1000000
     myLng = (lng / 100000)
     'myLng = myLng * 1000000

     'poly.add(p);
     decodeGeopoints = decodeGeopoints & Comma2Dot(myLng) & "," & Comma2Dot(myLat) & ",0 "
  '}
  Wend

End Function
2
Martin

Swift 3.

let polyline = GMSPolyline(path: GMSPath.init(fromEncodedPath: encodedPolyline))
2
apinho

Googleマップの場合、既に単純なメソッドpolylineWithPathが用意されているので、このスニペットをお勧めします。

-(void)drawPathFrom:(CLLocation*)source toDestination:(CLLocation*)destination{

    NSString *baseUrl = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=true", source.coordinate.latitude,  source.coordinate.longitude, destination.coordinate.latitude,  destination.coordinate.longitude];

    NSURL *url = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    NSLog(@"Url: %@", url);
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if(!connectionError){
            NSDictionary *result        = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            NSArray *routes             = [result objectForKey:@"routes"];
            NSDictionary *firstRoute    = [routes objectAtIndex:0];
            NSString *encodedPath       = [firstRoute[@"overview_polyline"] objectForKey:@"points"];

            GMSPolyline *polyPath       = [GMSPolyline polylineWithPath:[GMSPath pathFromEncodedPath:encodedPath]];
            polyPath.strokeColor        = [UIColor redColor];
            polyPath.strokeWidth        = 3.5f;
            polyPath.map                = _mapView;
        }
    }];

}
2
Mrug

これは、Sedate Alienの答えに対する私自身の再訪です。重複したコードを削除し、手動で割り当てる代わりにNSMutableDataを使用する場合と同じ実装です。

@implementation MKPolyline (EncodedString)

+ (float)decodeBytes:(const char *)bytes atPos:(NSUInteger *)idx toValue:(float *)value {
  char byte  = 0;
  int  res   = 0;
  char shift = 0;

  do {
    byte   = bytes[(*idx)++] - 0x3F;
    res   |= (byte & 0x1F) << shift;
    shift += 5;
  }
  while (byte >= 0x20);

  (*value) += ((res & 1) ? ~(res >> 1) : (res >> 1));

  return (*value) * 1E-5;
}

+ (MKPolyline *)polylineWithEncodedString:(NSString *)encodedString {
  const char             *bytes  = [encodedString UTF8String];
  NSUInteger              length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
  NSUInteger              idx    = 0;
  NSMutableData          *data   = [NSMutableData data];
  float                   lat    = 0;
  float                   lon    = 0;
  CLLocationCoordinate2D  coords = CLLocationCoordinate2DMake(0, 0);

  while (idx < length) {

    coords.latitude  = [self decodeBytes:bytes atPos:&idx toValue:&lat];
    coords.longitude = [self decodeBytes:bytes atPos:&idx toValue:&lon];

    [data appendBytes:&coords length:sizeof(CLLocationCoordinate2D)];
  }

  return [MKPolyline polylineWithCoordinates:(CLLocationCoordinate2D *)data.bytes count:data.length / sizeof(CLLocationCoordinate2D)];
}

@end
1
Noberasco

ここでの他の答えは、Apple Maps、Googleマップを使用するために、@ SedateAlienの素晴らしいカテゴリにいくつかの変更を加えなければならなかったことがわかりました。

変更されたカテゴリ

+ (GMSPolyline *)polylineWithEncodedString:(NSString *)encodedString {
    const char *bytes = [encodedString UTF8String];
    NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    NSUInteger idx = 0;

    NSUInteger count = length / 4;
    CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
    NSUInteger coordIdx = 0;

    float latitude = 0;
    float longitude = 0;
    while (idx < length) {
        char byte = 0;
        int res = 0;
        char shift = 0;

        do {
            byte = bytes[idx++] - 63;
            res |= (byte & 0x1F) << shift;
            shift += 5;
        } while (byte >= 0x20);

        float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
        latitude += deltaLat;

        shift = 0;
        res = 0;

        do {
            byte = bytes[idx++] - 0x3F;
            res |= (byte & 0x1F) << shift;
            shift += 5;
        } while (byte >= 0x20);

        float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
        longitude += deltaLon;

        float finalLat = latitude * 1E-5;
        float finalLon = longitude * 1E-5;

        CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
        coords[coordIdx++] = coord;

        if (coordIdx == count) {
            NSUInteger newCount = count + 10;
            coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
            count = newCount;
        }
    }

    GMSMutablePath *path = [[GMSMutablePath alloc] init];

    int i;
    for (i = 0; i < coordIdx; i++)
    {
        [path addCoordinate:coords[i]];
    }

    GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
    free(coords);

    return polyline;
}

[〜#〜] usage [〜#〜]

// Here I make the call to the Google Maps API to get the routes between two points...

....

// Get the encoded array of points.
NSString *points = routes[@"routes"][0][@"overview_polyline"][@"points"];

// Use the modified category to get a polyline from the points.
GMSPolyline *polyline = [GMSPolyline polylineWithEncodedString:points];

// Add the polyline to the map.
polyline.strokeColor = [UIColor redColor];
polyline.strokeWidth = 10.f;
polyline.map = theMapView;
}
1
paulvs

他の誰かがSwiftでこれを行おうとしている場合、Swift(2.3):

let path = GMSMutablePath()
let steps = directionsToShowOnMap.steps
for (idx, step) in steps.enumerate() {
    path.addCoordinate(coordinateFromJson(step["start_location"]))
    if let polylinePoints = step["polyline"].string, subpath = GMSPath(fromEncodedPath: polylinePoints) {
        for c in 0 ..< subpath.count() {
            path.addCoordinate(subpath.coordinateAtIndex(c))
        }   
    }
    if idx == steps.count - 1 {
        path.addCoordinate(coordinateFromJson(step["end_location"]))
    }
}
let polyline = GMSPolyline(path: path)
polyline.strokeColor = UIColor.blueColor()
polyline.strokeWidth = 3
polyline.map = mapView

その後:

private func coordinateFromJson(location: JSON) -> CLLocationCoordinate2D {
    return CLLocationCoordinate2DMake(location["lat"].double!, location["lng"].double!)
}
0
Eric