GoogleMap API为两点之间的方向提供了错误的坐标

我正在使用GoogleMap API在GoogleMap上显示两点之间的绘制方向。

我想在iOS 6.1上给予支持,所以我使用谷歌地图,我知道iOS7恢复这个。

使用下面的代码进行解析并获取坐标的步骤以在地图上绘制折线:

NSString *str=@"http://maps.googleapis.com/maps/api/directions/json?origin=bharuch,gujarat&destination=vadodara,gujarat&sensor=false"; NSURL *url=[[NSURL alloc]initWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSError* error; NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; NSArray* latestRoutes = [json objectForKey:@"routes"]; NSMutableDictionary *legs=[[[latestRoutes objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0]; NSArray *steps=[legs objectForKey:@"steps"]; NSString *startLocation,*endLocation,*totalDistance,*totalDuration; CLLocationCoordinate2D startLoc,endLoc; startLocation = [legs objectForKey:@"start_address"]; endLocation = [legs objectForKey:@"end_address"]; totalDistance = [[legs objectForKey:@"distance"] objectForKey:@"text"]; totalDuration = [[legs objectForKey:@"duration"] objectForKey:@"text"]; startLoc=CLLocationCoordinate2DMake([[[legs objectForKey:@"start_location"] objectForKey:@"lat"] doubleValue], [[[legs objectForKey:@"start_location"] objectForKey:@"lng"] doubleValue]); endLoc=CLLocationCoordinate2DMake([[[legs objectForKey:@"end_location"] objectForKey:@"lat"] doubleValue], [[[legs objectForKey:@"end_location"] objectForKey:@"lng"] doubleValue]); NSMutableDictionary *tempDict; if ([steps count]!=0) { GMSMutablePath *path = [GMSMutablePath path]; for(int idx = 0; idx < [steps count]+2; idx++){ CLLocationCoordinate2D workingCoordinate; if (idx==0) { workingCoordinate=startLoc; [path addCoordinate:workingCoordinate]; } else if (idx==[steps count]+1){ workingCoordinate=endLoc; [path addCoordinate:workingCoordinate]; } else{ workingCoordinate=CLLocationCoordinate2DMake([[[[steps objectAtIndex:idx-1] objectForKey:@"start_location"] objectForKey:@"lat"] floatValue], [[[[steps objectAtIndex:idx-1] objectForKey:@"start_location"] objectForKey:@"lng"] floatValue]); [path addCoordinate:workingCoordinate]; } tempDict = nil; } // create the polyline based on the array of points. GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path]; rectangle.strokeWidth=5.0; rectangle.map = mapView_; } 

它只给出24个步骤意味着只有24个坐标用于创建点并在地图上绘制线条,如下图所示:

在地图上绘制线条并缩放到几个级别后

你可以看到这条线不在正确的道路上,所以我该怎么做才能解决这个问题呢? 我也想在地图上显示方向。

以下答案是在@ABáo的帮助下,两个位置之间的平滑路径:

 -(void)viewDidLoad { // Create a GMSCameraPosition that tells the map to display the GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:21.718472 longitude:73.030422 zoom:6]; mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera]; mapView_.delegate=self; mapView_.myLocationEnabled = YES; mapView_.settings.myLocationButton=YES; mapView_.settings.indoorPicker=NO; mapView_.settings.compassButton=YES; self.view = mapView_; NSString *str=@"http://maps.googleapis.com/maps/api/directions/json?origin=Bharuch,gujarat&destination=vadodara,gujarat&sensor=false"; NSURL *url=[[NSURL alloc]initWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSError* error; NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; NSArray* latestRoutes = [json objectForKey:@"routes"]; NSString *points=[[[latestRoutes objectAtIndex:0] objectForKey:@"overview_polyline"] objectForKey:@"points"]; @try { // TODO: better parsing. Regular expression? NSArray *temp= [self decodePolyLine:[points mutableCopy]]; GMSMutablePath *path = [GMSMutablePath path]; for(int idx = 0; idx < [temp count]; idx++) { CLLocation *location=[temp objectAtIndex:idx]; [path addCoordinate:location.coordinate]; } // create the polyline based on the array of points. GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path]; rectangle.strokeWidth=5.0; rectangle.map = mapView_; } @catch (NSException * e) { // TODO: show error } } -(NSMutableArray *)decodePolyLine: (NSMutableString *)encoded { [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] ; printf("[%f,", [latitude doubleValue]); printf("%f]", [longitude doubleValue]); CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]] ; [array addObject:loc]; } return array; } 

这段代码的屏幕截图您可以将它与之前用于询问的屏幕截图进行比较问题: 在此处输入图像描述

我确实将GMSMarker添加到每个点上的步骤数组,我确定使用步骤数组start_location和end_location不足以在地图中显示方向。 这是我从你的代码编辑的代码

 NSString *str=@"http://maps.googleapis.com/maps/api/directions/json?origin=bharuch,gujarat&destination=vadodara,gujarat&sensor=false"; NSURL *url=[[NSURL alloc]initWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSError *error; NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; NSArray* latestRoutes = [json objectForKey:@"routes"]; NSMutableDictionary *legs=[[[latestRoutes objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0]; NSArray *steps=[legs objectForKey:@"steps"]; NSString *startLocation,*endLocation,*totalDistance,*totalDuration; CLLocationCoordinate2D startLoc,endLoc; startLocation = [legs objectForKey:@"start_address"]; endLocation = [legs objectForKey:@"end_address"]; totalDistance = [[legs objectForKey:@"distance"] objectForKey:@"text"]; totalDuration = [[legs objectForKey:@"duration"] objectForKey:@"text"]; startLoc=CLLocationCoordinate2DMake([[[legs objectForKey:@"start_location"] objectForKey:@"lat"] doubleValue], [[[legs objectForKey:@"start_location"] objectForKey:@"lng"] doubleValue]); NSMutableDictionary *stopLegs=[[[latestRoutes objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0]; endLoc=CLLocationCoordinate2DMake([[[stopLegs objectForKey:@"end_location"] objectForKey:@"lat"] doubleValue], [[[stopLegs objectForKey:@"end_location"] objectForKey:@"lng"] doubleValue]); NSMutableDictionary *tempDict; if ([steps count]!=0) { // add marker NSDictionary *step; for (int i= 0; i < steps.count; i++) { step = [steps objectAtIndex:i]; NSDictionary *location = [step objectForKey:@"start_location"]; double lat = [[location objectForKey:@"lat"] doubleValue]; double lng = [[location objectForKey:@"lng"] doubleValue]; GMSMarker *marker = [[GMSMarker alloc] init]; marker.position = CLLocationCoordinate2DMake(lat, lng); marker.snippet = [NSString stringWithFormat:@"point (%d)", i+1]; marker.map = mapView_; } NSDictionary *location = [step objectForKey:@"end_location"]; double lat = [[location objectForKey:@"lat"] doubleValue]; double lng = [[location objectForKey:@"lng"] doubleValue]; GMSMarker *marker = [[GMSMarker alloc] init]; marker.position = CLLocationCoordinate2DMake(lat, lng); marker.snippet = [NSString stringWithFormat:@"point (%d)", steps.count]; marker.map = mapView_; // continue draw map GMSMutablePath *path = [GMSMutablePath path]; for(int idx = 0; idx < [steps count]+2; idx++){ CLLocationCoordinate2D workingCoordinate; if (idx==0) { workingCoordinate=startLoc; [path addCoordinate:workingCoordinate]; } else if (idx==[steps count]+1){ workingCoordinate=endLoc; [path addCoordinate:workingCoordinate]; } else{ workingCoordinate=CLLocationCoordinate2DMake([[[[steps objectAtIndex:idx-1] objectForKey:@"start_location"] objectForKey:@"lat"] floatValue], [[[[steps objectAtIndex:idx-1] objectForKey:@"start_location"] objectForKey:@"lng"] floatValue]); [path addCoordinate:workingCoordinate]; } tempDict = nil; } // create the polyline based on the array of points. GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path]; rectangle.strokeWidth=5.0; rectangle.map = mapView_; } 

你可以看到第12点和第13点之间的距离很远(60.2公里)。 但它只是一条路。 我确实发现,如果你想显示结果方向的近似(平滑)路径。 你需要使用“overview_polyline”字段。 overview_polyline:包含一个包含编码点数组的对象,这些编码点表示结果方向的近似(平滑)路径。 这个链接谷歌地图开发对你有帮助。 因此,为您工作的是找到从“overview_polyline”解码数据的方法,以获得两点之间的正确路径。 我绝对是解决问题的真正方法,因为我在编码折线算法格式中检查工具解码“overview_polyline”这个图像是我从解码得到的: 解码折线

要解码多边形字符串,您可以在此块找到http://objc.id.au/post/9245961184/mapkit-encoded-polylines

  • 继续,来自@jayraj mg的代码下面的答案是两个位置之间的平滑路径
 -(void)viewDidLoad { // Create a GMSCameraPosition that tells the map to display the GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:21.718472 longitude:73.030422 zoom:6]; mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera]; mapView_.delegate=self; mapView_.myLocationEnabled = YES; mapView_.settings.myLocationButton=YES; mapView_.settings.indoorPicker=NO; mapView_.settings.compassButton=YES; self.view = mapView_; NSString *str=@"http://maps.googleapis.com/maps/api/directions/json?origin=Bharuch,gujarat&destination=vadodara,gujarat&sensor=false"; NSURL *url=[[NSURL alloc]initWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSError* error; NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; NSArray* latestRoutes = [json objectForKey:@"routes"]; NSString *points=[[[latestRoutes objectAtIndex:0] objectForKey:@"overview_polyline"] objectForKey:@"points"]; @try { // TODO: better parsing. Regular expression? NSArray *temp= [self decodePolyLine:[points mutableCopy]]; GMSMutablePath *path = [GMSMutablePath path]; for(int idx = 0; idx < [temp count]; idx++) { CLLocation *location=[temp objectAtIndex:idx]; [path addCoordinate:location.coordinate]; } // create the polyline based on the array of points. GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path]; rectangle.strokeWidth=5.0; rectangle.map = mapView_; } @catch (NSException * e) { // TODO: show error } } -(NSMutableArray *)decodePolyLine: (NSMutableString *)encoded { [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] ; printf("[%f,", [latitude doubleValue]); printf("%f]", [longitude doubleValue]); CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]] ; [array addObject:loc]; } return array; } 

这段代码的屏幕截图您可以将它与之前用于询问的屏幕截图进行比较问题: 在此处输入图像描述

谢谢@jayraj mg

Interesting Posts