如何在Objective-C for iPhone中将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

我在这里find了一些用于Android的代码,并且在解码多段线时也使用了Javascript,例如:

地图视图使用谷歌方向API绘制方向 – 解码多义线

android获取并parsingGoogle Directions

但是我找不到Objective-C的iPhone代码,有谁能帮我解决这个问题? 如果必须的话,我相信我可以自己做,但是如果它已经在某个地方,那肯定会节省我一些时间。

编辑:这里的关键是能够解码一个字符的基础上的一个字符的base64编码。 更具体地说,我在Google中使用base64编码编码的JSON中获得了类似的内容:

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

注意:我应该提及的是,这个问题涉及到Google Maps API v1,使用GMSPolyLine polyLineWithPath在v2中执行此操作要容易得多,因为下面的许多答案都会告诉您(感谢@cdescours)。

如果这个问题与这个问题有关,我希望这个规则不违反我自己的博客文章 ,但是我已经解决了这个问题。 链接post的独立答案:

 @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 

最好的和最轻的答案应该是在框架中使用Google提供的方法:

[GMSPolyline polylineWithPath:[GMSPath pathFromEncodedPath:encodedPath]]

如果您正在使用iOS上的Google Map,并且想要绘制包含多段线的路线,则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); } 

以下是我在路线应用程序中的操作方法。 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; } 
 - (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]; } 

对于谷歌地图,它已经有一个简单的方法, 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; } }]; } 

Python实现

这不在Objective-C中,但是如果您想要从Google地图解码折线string,则此线程是Google放弃您的地方。 如果有其他人需要它(就像我做的那样),下面是一个用于解码折线string的Python实现。 这是从Mapbox JavaScript版本移植; 在我的回购页上find更多信息。

 def decode_polyline(polyline_str): index, lat, lng = 0, 0, 0 coordinates = [] changes = {'latitude': 0, 'longitude': 0} # Coordinates have variable length when encoded, so just keep # track of whether we've hit the end of the string. In each # while loop iteration, a single coordinate is decoded. while index < len(polyline_str): # Gather lat/lon changes, store them in a dictionary to apply them later for unit in ['latitude', 'longitude']: shift, result = 0, 0 while True: byte = ord(polyline_str[index]) - 63 index+=1 result |= (byte & 0x1f) << shift shift += 5 if not byte >= 0x20: break if (result & 1): changes[unit] = ~(result >> 1) else: changes[unit] = (result >> 1) lat += changes['latitude'] lng += changes['longitude'] coordinates.append((lat / 100000.0, lng / 100000.0)) return coordinates 

这是我对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 

如果有人需要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 

在这里的其他答案似乎是关于使用苹果地图,使用谷歌地图我发现我不得不做一些修改@ 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; } 

用法

 // 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; } 

如果其他人试图迅速做到这一点,这里的@ RootCode的答案适应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!) } 

Swift 3.0

 let polyline = GMSPolyline(path: GMSPath.init(fromEncodedPath: encodedPolyline)) 
Interesting Posts