在iPhone上的MapKit上find两个点之间的path/路线

我正试图在Mapkit上find两个位置之间的path。 我只有两个地点。 现在我必须find这些点之间的确切path,并使用MapKit在这些点之间画一条线。 我经历了几个使用.csv文件的例子。 在.csv文件中,他们已经存储了基于这些值的完整path和绘制线的经度和纬度值。

但是我在这里试图画出一条线,而不知道path。 那么有什么方法可以dynamic地findpath并画出一条线?

以下是在两个位置之间findpath和绘制线的代码。

要实现以下课程:

_mapRecord = [[PSMapDirection alloc] initWithFrame:CGRectMake(0.0, 49.0, 320.0, 411.0)]; [self.view addSubview:_mapRecord]; 

MapDirection.h

 #import <UIKit/UIKit.h> #import <MapKit/MapKit.h> #import "RegexKitLite.h" @interface MapDirection : UIView<MKMapViewDelegate> { MKMapView* mapView; NSArray* routes; BOOL isUpdatingRoutes; } -(void) showRouteFrom: (MKAnnotation*) f to:(MKAnnotation*) t; @end 

MapDirection.m

 #import "MapDirection.h" @interface MapDirection() -(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) from to: (CLLocationCoordinate2D) to; -(void) centerMap; @end - (id) initWithFrame:(CGRect) frame { self = [super initWithFrame:frame]; if (self != nil) { mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; mapView.showsUserLocation = NO; [mapView setDelegate:self]; [self addSubview:mapView]; } return self; } - (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; } -(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t { NSString* saddr = [NSString stringWithFormat:@"%f,%f", f.latitude, f.longitude]; NSString* daddr = [NSString stringWithFormat:@"%f,%f", t.latitude, t.longitude]; NSString* apiUrlStr = [NSString stringWithFormat:@"http://maps.google.com/maps?output=dragdir&saddr=%@&daddr=%@", saddr, daddr]; NSURL* apiUrl = [NSURL URLWithString:apiUrlStr]; //NSLog(@"api url: %@", apiUrl); NSError* error = nil; NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error]; NSString *encodedPoints = [apiResponse stringByMatching:@"points:\\\"([^\\\"]*)\\\"" capture:1L]; return [self decodePolyLine:[encodedPoints mutableCopy]]; } -(void) centerMap { MKCoordinateRegion region; CLLocationDegrees maxLat = -90.0; CLLocationDegrees maxLon = -180.0; CLLocationDegrees minLat = 90.0; CLLocationDegrees minLon = 180.0; for(int idx = 0; idx < routes.count; idx++) { CLLocation* currentLocation = [routes objectAtIndex:idx]; if(currentLocation.coordinate.latitude > maxLat) maxLat = currentLocation.coordinate.latitude; if(currentLocation.coordinate.latitude < minLat) minLat = currentLocation.coordinate.latitude; if(currentLocation.coordinate.longitude > maxLon) maxLon = currentLocation.coordinate.longitude; if(currentLocation.coordinate.longitude < minLon) minLon = currentLocation.coordinate.longitude; } region.center.latitude = (maxLat + minLat) / 2.0; region.center.longitude = (maxLon + minLon) / 2.0; region.span.latitudeDelta = 0.01; region.span.longitudeDelta = 0.01; region.span.latitudeDelta = ((maxLat - minLat)<0.0)?100.0:(maxLat - minLat); region.span.longitudeDelta = ((maxLon - minLon)<0.0)?100.0:(maxLon - minLon); [mapView setRegion:region animated:YES]; } -(void) showRouteFrom: (MKAnnotation*) f to:(MKAnnotation*) t { if(routes) { [mapView removeAnnotations:[mapView annotations]]; } [mapView addAnnotation:f]; [mapView addAnnotation:t]; routes = [self calculateRoutesFrom:f.coordinate to:t.coordinate]; NSInteger numberOfSteps = routes.count; CLLocationCoordinate2D coordinates[numberOfSteps]; for (NSInteger index = 0; index < numberOfSteps; index++) { CLLocation *location = [routes objectAtIndex:index]; CLLocationCoordinate2D coordinate = location.coordinate; coordinates[index] = coordinate; } MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps]; [mapView addOverlay:polyLine]; [self centerMap]; } #pragma mark MKPolyline delegate functions - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay { MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay]; polylineView.strokeColor = [UIColor purpleColor]; polylineView.lineWidth = 5.0; return polylineView; } @end 

起点的示例地图路线– “41.967659,-87.627869”和目的地点 – “41.574361,-91.083069

地图路线

这里我能够在两点之间绘制方向(位置)。


首先从这个链接下载谷歌地图SDK并集成到您的应用程序。

现在需要API密钥,您可以在此链接上创build参考指南。

以下是两地之间在谷歌地图上绘制方向的代码。


 -(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t { NSString* saddr = [NSString stringWithFormat:@"%f,%f", f.latitude, f.longitude]; NSString* daddr = [NSString stringWithFormat:@"%f,%f", t.latitude, t.longitude]; NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/directions/json?origin=%@&destination=%@&sensor=false&avoid=highways&mode=driving",saddr,daddr]]; NSError *error=nil; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ; [request setURL:url]; [request setHTTPMethod:@"POST"]; NSURLResponse *response = nil; NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error: &error]; NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONWritingPrettyPrinted error:nil]; return [self decodePolyLine:[self parseResponse:dic]]; } - (NSString *)parseResponse:(NSDictionary *)response { NSArray *routes = [response objectForKey:@"routes"]; NSDictionary *route = [routes lastObject]; if (route) { NSString *overviewPolyline = [[route objectForKey: @"overview_polyline"] objectForKey:@"points"]; return overviewPolyline; } return @""; } -(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; } - (void)loadMapViewWithDirection { float lat = 23.050671; float lng = 72.541351; GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:lat longitude:lng zoom:10]; GMSMapView * mapView = [GMSMapView mapWithFrame:CGRectMake(0, 75, 320, self.view.frame.size.height-kHeaderRect.size.height) camera:camera]; self.mapView.myLocationEnabled = YES; float sourceLatitude = 23.050671; float sourceLongitude = 72.541351; float destLatitude = 23.036138; float destLongitude = 72.603836; GMSMarker *sourceMarker = [[GMSMarker alloc] init]; marker.position = CLLocationCoordinate2DMake(sourceLatitude, sourceLongitude); marker.map = self.mapView; GMSMarker *destMarker = [[GMSMarker alloc] init]; marker.position = CLLocationCoordinate2DMake(destLatitude, destLongitude); marker.map = self.mapView; self.mapView.delegate = self; [self drawDirection:CLLocationCoordinate2DMake(sourceLatitude, sourceLongitude) and:CLLocationCoordinate2DMake(destLatitude, destLongitude)]; [self.view addSubview:self.mapView]; } - (void) drawDirection:(CLLocationCoordinate2D)source and:(CLLocationCoordinate2D) dest { GMSPolyline *polyline = [[GMSPolyline alloc] init]; GMSMutablePath *path = [GMSMutablePath path]; NSArray * points = [self calculateRoutesFrom:source to:dest]; NSInteger numberOfSteps = points.count; for (NSInteger index = 0; index < numberOfSteps; index++) { CLLocation *location = [points objectAtIndex:index]; CLLocationCoordinate2D coordinate = location.coordinate; [path addCoordinate:coordinate]; } polyline.path = path; polyline.strokeColor = [UIColor redColor]; polyline.strokeWidth = 2.f; polyline.map = self.mapView; // Copy the previous polyline, change its color, and mark it as geodesic. polyline = [polyline copy]; polyline.strokeColor = [UIColor greenColor]; polyline.geodesic = YES; polyline.map = self.mapView; } - (void)viewDidLoad { [super viewDidLoad]; [self loadMapViewWithDirection]; } 

你可以参考这个代码 ,它确实是你想要的。
编辑: 这也是

我不认为你可以在本地做到这一点。 在两个GPS点之间寻找path的algorithm需要大量的input数据(来自地图的数据),而你没有这个。 只有一个地图提供者可以负担得起实现这个algorithm,并暴露一个API来使用它。 我认为Google有路由API ,但我没有玩过它…

https://developers.google.com/maps/documentation/directions/

请注意,TOS表示您必须在Google地图上显示结果,因此您必须禁用下一个iOS版本的function