在iPhone SDK中的MapKit中绘制路线

我想在地图上的两个位置之间绘制一条路线。 像导游一样。 当游客点击另一个地点时,我希望能够绘制路线; 以及通知距离当前位置的距离。

我知道互联网上的网站,告诉如何在地图上绘制多段线。 但是,大多数的例子都有一个带有各种坐标的预加载的.csv文件。

有没有其他的方式来获得谷歌或任何其他供应商的坐标,因为该位置是dynamicselect的。

如果否,我如何获得中间坐标信息?

iOS 6是否提供了解决这个问题的直接方法?

这是一个棘手的问题。 MapKit没有办法做到这一点:在知道坐标时很容易绘制线条,但MapKit不会让您访问道路或其他路由信息。 我想说,你需要调用一个外部的API来获取你的数据。

我一直在玩cloudmade.com API。 vectorstream服务器应该返回你所需要的,然后你可以在你的地图上绘制它。 但是,Google地图和云制作所使用的OSM地图之间的差异可能会让您想要一路使用cloudmade地图:它们与MapKit具有相同的function。

PS:其他地图提供商 – Google,Bing等也可能提供等效的数据提要。 我刚刚在OSM / Cloudmade上看过。

PPS:这些都不是新鲜的东西! 祝你好运!

下面的viewDidLoad将(1)设置两个位置,(2)删除所有以前的注释,(3)调用用户定义的帮助函数(获取路线点和绘制路线)。

 -(void)viewDidLoad { [super viewDidLoad]; // Origin Location. CLLocationCoordinate2D loc1; loc1.latitude = 29.0167; loc1.longitude = 77.3833; Annotation *origin = [[Annotation alloc] initWithTitle:@"loc1" subTitle:@"Home1" andCoordinate:loc1]; [objMapView addAnnotation:origin]; // Destination Location. CLLocationCoordinate2D loc2; loc2.latitude = 19.076000; loc2.longitude = 72.877670; Annotation *destination = [[Annotation alloc] initWithTitle:@"loc2" subTitle:@"Home2" andCoordinate:loc2]; [objMapView addAnnotation:destination]; if(arrRoutePoints) // Remove all annotations [objMapView removeAnnotations:[objMapView annotations]]; arrRoutePoints = [self getRoutePointFrom:origin to:destination]; [self drawRoute]; [self centerMap]; } 

以下是MKMapViewDelegate方法,它绘制覆盖(iOS 4.0和更高版本)。

 /* MKMapViewDelegate Meth0d -- for viewForOverlay*/ - (MKOverlayView*)mapView:(MKMapView*)theMapView viewForOverlay:(id <MKOverlay>)overlay { MKPolylineView *view = [[MKPolylineView alloc] initWithPolyline:objPolyline]; view.fillColor = [UIColor blackColor]; view.strokeColor = [UIColor blackColor]; view.lineWidth = 4; return view; } 

下面的函数将得到这两个位置,并准备URL来获得所有的路线点。 当然,会调用stringWithURL。

 /* This will get the route coordinates from the Google API. */ - (NSArray*)getRoutePointFrom:(Annotation *)origin to:(Annotation *)destination { NSString* saddr = [NSString stringWithFormat:@"%f,%f", origin.coordinate.latitude, origin.coordinate.longitude]; NSString* daddr = [NSString stringWithFormat:@"%f,%f", destination.coordinate.latitude, destination.coordinate.longitude]; NSString* apiUrlStr = [NSString stringWithFormat:@"http://maps.google.com/maps?output=dragdir&saddr=%@&daddr=%@", saddr, daddr]; NSURL* apiUrl = [NSURL URLWithString:apiUrlStr]; NSError *error; NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSUTF8StringEncoding error:&error]; NSString* encodedPoints = [apiResponse stringByMatching:@"points:\\\"([^\\\"]*)\\\"" capture:1L]; return [self decodePolyLine:[encodedPoints mutableCopy]]; } 

下面的代码是真正的魔术(我们从API获得的响应的解码器)。 我不会修改该代码,除非我知道我在做什么:)

 - (NSMutableArray *)decodePolyLine:(NSMutableString *)encodedString { [encodedString replaceOccurrencesOfString:@"\\\\" withString:@"\\" options:NSLiteralSearch range:NSMakeRange(0, [encodedString length])]; NSInteger len = [encodedString 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 = [encodedString 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 = [encodedString 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("\n[%f,", [latitude doubleValue]); printf("%f]", [longitude doubleValue]); CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]]; [array addObject:loc]; } return array; } 

此function将绘制一条路线,并将添加一个覆盖。

 - (void)drawRoute { int numPoints = [arrRoutePoints count]; if (numPoints > 1) { CLLocationCoordinate2D* coords = malloc(numPoints * sizeof(CLLocationCoordinate2D)); for (int i = 0; i < numPoints; i++) { CLLocation* current = [arrRoutePoints objectAtIndex:i]; coords[i] = current.coordinate; } self.objPolyline = [MKPolyline polylineWithCoordinates:coords count:numPoints]; free(coords); [objMapView addOverlay:objPolyline]; [objMapView setNeedsDisplay]; } } 

以下代码将居中alignment地图。

 - (void)centerMap { MKCoordinateRegion region; CLLocationDegrees maxLat = -90; CLLocationDegrees maxLon = -180; CLLocationDegrees minLat = 90; CLLocationDegrees minLon = 180; for(int idx = 0; idx < arrRoutePoints.count; idx++) { CLLocation* currentLocation = [arrRoutePoints 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; region.center.longitude = (maxLon + minLon) / 2; region.span.latitudeDelta = maxLat - minLat; region.span.longitudeDelta = maxLon - minLon; [objMapView setRegion:region animated:YES]; } 

我希望这会帮助别人。

Andiih说得对。 MapKit不会让你这样做。 不幸的是,Google不会让你做你想做的事情。

当苹果宣布MapKit和所有的,他们也明确表示,任何导航应用程序将是BYOM:带自己的地图,所以任何导航应用程序使用自己的一套映射工具。

Google的服务条款限制您甚至不在地图上显示路线:

http://code.google.com/intl/de/apis/maps/iphone/terms.html

许可限制:

10.9将服务或内容用于以下任何产品,系统或应用程序:

(a)实时导航或路线引导,包括但不限于与用户的启用传感器的设备的位置同步的逐转路线引导;

(b)用于自动或自主控制车辆行为的任何系统或function; 要么

(c)调度,车队pipe理,业务资产跟踪或类似的企业应用程序(只要跟踪应用程序向公众开放,Google Maps API就可用于跟踪资产(如汽车,公交车或其他车辆)例如,您可以提供一个免费的公开的Maps API实现,显示实时的公共交通或其他运输状态信息。

可悲的是,这包括你想要做的事情。 希望有一天MapKit将被扩展,以允许这样的function…虽然不太可能。

祝你好运。

您可能需要查看https://github.com/leviathan/nvpolyline此解决scheme特别针对v.4.0之前的iPhone OS版本

虽然它也可以在v.4.0中使用希望这有助于。

试试MapKit-Route-Directions ( GitHub )。

MapQuest有一个SDK,可以直接替代MapKit。 目前处于testing阶段,但处于积极的发展阶段。

它允许覆盖,路由和地理编码。

MapQuest iOS Maps API

只是为了澄清,看起来有几件事正在讨论。 一种是获取路线顶点的方法,另一种是使用这些顶点在地图上绘制覆盖图。 我知道MapQuest API,所以我有一些链接,下面的人 – 谷歌和Bing有我认为的等值。

1)获取路线的顶点
如果您正在寻找绘制路线覆盖图的路线的新坐标,则可以使用Web服务调用路由Web服务 – 我假设您在此处使用JavaScript来显示地图。 如果您使用的是本地代码,您仍然可以访问Web服务,也可以使用本机调用(即MapQuest iPhone SDK具有本地路由调用)。

大多数路线服务应返回路线的“形状点”,以便您可以绘制。

下面是一些使用MapQuest-Directions Web服务获取形状点的例子(请参阅Shape返回对象) – http://www.mapquestapi.com/directions/

2)绘制一个覆盖
一旦你有了顶点,你需要画出它们。 我认为大多数JavaScript地图API都会有某种重叠类。 这是MapQuest的一个: http : //developer.mapquest.com/web/documentation/sdk/javascript/v7.0/overlays#line

3)一个电话做
MapQuest也有一些便利的function,可以为你打电话和画线 – 我不能发布两个以上的链接! 因此,转到上面的链接,并在左侧导航栏中查找“路由”。

使用iOS 7 API获取和绘制地图上的路线非常简单:

 MKDirectionsRequest *directionsRequest = [[MKDirectionsRequest alloc] init]; // Set the origin of the route to be current user location [directionsRequest setSource:[MKMapItem mapItemForCurrentLocation]]; // Set the destination point of the route CLLocationCoordinate2D destinationCoordinate = CLLocationCoordinate2DMake(34.0872, 76.235); MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoordinate addressDictionary:nil]; [directionsRequest setDestination:[[MKMapItem alloc] initWithPlacemark:destinationPlacemark]]; MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest]; // Requesting route information from Apple Map services [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) { if (error) { NSLog(@"Cannot calculate directions: %@",[error localizedDescription]); } else { // Displaying the route on the map MKRoute *route = [response.routes firstObject]; [mapView addOverlay:route.polyline]; } }]; 

为了更新这个问题,从iOS7开始就不需要外部的apk。

这里有一个非常简单有效的解决scheme

http://technet.weblineindia.com/mobile/draw-route-between-2-points-on-map-with-ios7-mapkit-api/2/

我知道这个问题是关于iOS 6的,但我相信这个解决scheme对于很多人来说都是有用的。

在这个解决scheme中唯一缺less的是实现下面的委托方法来显示开始和结束的引脚

 -(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation