ios 如何调用 iPhone 地图以获取当前位置作为起始地址的路线
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/576768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to invoke iPhone Maps for Directions with Current Location as Start Address
提问by eriaac
I know it's possible to start the iPhone maps application by calling openURL
on a google maps URL with parameters saddr
and daddr
with location strings or Lat/Long (see example below).
我知道可以通过openURL
使用参数saddr
和daddr
位置字符串或 Lat/Long调用谷歌地图 URL来启动 iPhone 地图应用程序(参见下面的示例)。
But I'm wondering if it's possible to make the start address be the "Current Location"maps bookmark so that I can use the Mapsapp's location handling code. My Google search has been pretty fruitless.
但我想知道是否可以将起始地址设为“当前位置”地图书签,以便我可以使用地图应用程序的位置处理代码。我的谷歌搜索一直没有结果。
For example:
例如:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat: @"http://maps.google.com/maps?saddr=%@&daddr=%@", myLatLong, latlong]]];
Except with something to invoke the current location bookmark in place of myLatLong
.
除了调用当前位置书签代替myLatLong
.
回答by Nate
Pre iOS 6
iOS 6 之前
You need to use Core Location to get the current location, but with that lat/long pair, you can get Maps to route you from there, to a street address or location. Like so:
您需要使用 Core Location 来获取当前位置,但使用该纬度/经度对,您可以获得地图以将您从那里路由到街道地址或位置。像这样:
CLLocationCoordinate2D currentLocation = [self getCurrentLocation];
// this uses an address for the destination. can use lat/long, too with %f,%f format
NSString* address = @"123 Main St., New York, NY, 10001";
NSString* url = [NSString stringWithFormat: @"http://maps.google.com/maps?saddr=%f,%f&daddr=%@",
currentLocation.latitude, currentLocation.longitude,
[address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];
Finally, if you do want to avoid using CoreLocation to explicitly find the current location, and want to use the @"http://maps.google.com/maps?saddr=Current+Location&daddr=%@"
url instead, then see this link that I provided in comments belowfor how to localize the Current+Locationstring. However, you are taking advantage of another undocumented feature, and as Jason McCreary points out below, it may not work reliably in future releases.
最后,如果您确实想避免使用 CoreLocation 来显式查找当前位置,而想使用@"http://maps.google.com/maps?saddr=Current+Location&daddr=%@"
url,请参阅我在下面的评论中提供的此链接,了解如何本地化Current+Location字符串。但是,您正在利用另一个未记录的功能,正如 Jason McCreary 在下面指出的那样,它在未来的版本中可能无法可靠地工作。
Update for iOS 6
iOS 6 更新
Originally, Mapsused Google maps, but now, Apple and Google have separate maps apps.
最初,地图使用谷歌地图,但现在,苹果和谷歌有单独的地图应用程序。
1)If you wish to route using the Google Maps app, use the comgooglemaps URL scheme:
1)如果您希望使用 Google Maps 应用程序进行路由,请使用comgooglemaps URL 方案:
NSString* url = [NSString stringWithFormat: @"comgooglemaps://?daddr=%@&directionsmode=driving",
[address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
BOOL opened = [[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];
2)To use Apple Maps, you can use the new MKMapItem
class for iOS 6. See the Apple API docs here
2)要使用 Apple Maps,您可以使用MKMapItem
iOS 6的新类。 请参阅此处的 Apple API 文档
Basically, you will use something like this, if routing to destination coordinates(latlong
):
基本上,如果路由到目的地坐标( latlong
) ,您将使用类似的方法:
MKPlacemark* place = [[MKPlacemark alloc] initWithCoordinate: latlong addressDictionary: nil];
MKMapItem* destination = [[MKMapItem alloc] initWithPlacemark: place];
destination.name = @"Name Here!";
NSArray* items = [[NSArray alloc] initWithObjects: destination, nil];
NSDictionary* options = [[NSDictionary alloc] initWithObjectsAndKeys:
MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsDirectionsModeKey, nil];
[MKMapItem openMapsWithItems: items launchOptions: options];
In order to support both iOS 6+ and pre iOS 6 in the same code, I'd recommend using something like this code that Apple has on the MKMapItem
API doc page:
为了在同一代码中同时支持 iOS 6+ 和 iOS 6 之前的版本,我建议使用类似 Apple 在MKMapItem
API 文档页面上提供的代码:
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {
// iOS 6 MKMapItem available
} else {
// use pre iOS 6 technique
}
This would assume that your Xcode Base SDK is iOS 6 (or Latest iOS).
这将假设您的 Xcode Base SDK 是 iOS 6(或最新的 iOS)。
回答by Tchettane
NSString* addr = [NSString stringWithFormat:@"http://maps.google.com/maps?daddr=Current Location&saddr=%@",startAddr];
NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
[url release];
This works but only when the iPhone/iPod language is set in English. If you want to support other languages you'll have to use a localized string to match the Maps bookmark name.
这有效,但仅当 iPhone/iPod 语言设置为英语时。如果您想支持其他语言,则必须使用本地化字符串来匹配地图书签名称。
回答by bob
回答by TheInterestedOne
You can use a preprocessor #define like:
您可以使用预处理器#define,如:
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
to understand your iOS version. Then, I can use this code to support iOS 6, too:
了解您的 iOS 版本。然后,我也可以使用此代码来支持 iOS 6:
NSString* addr = nil;
if (SYSTEM_VERSION_LESS_THAN(@"6.0")) {
addr = [NSString stringWithFormat:@"http://maps.google.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];
} else {
addr = [NSString stringWithFormat:@"http://maps.apple.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];
}
NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
回答by August
Because of sandboxing, you don't have access to the Map application's bookmarks.
由于沙盒,您无权访问地图应用程序的书签。
Instead, use Core Location to determine the current location yourself. Then use that location (the lat and long) in the URL you build to open Maps.
相反,使用 Core Location 自己确定当前位置。然后在您构建的 URL 中使用该位置(经纬度)来打开地图。
回答by Joe Hughes
I recommend checking out CMMapLauncher, a mini-library that I built to launch Apple, Google, and other iOS mapping apps with a specific mapping request. With CMMapLauncher, the code to get the directions in your question would be:
我建议查看CMMapLauncher,这是我构建的一个迷你库,用于启动具有特定映射请求的 Apple、Google 和其他 iOS 映射应用程序。使用 CMMapLauncher,获取问题方向的代码将是:
[CMMapLauncher launchMapApp:CMMapAppAppleMaps
forDirectionsFrom:[CMMapPoint mapPointWithName:@"Origin"
coordinate:myLatLong]
to:[CMMapPoint mapPointWithName:@"Destination"
coordinate:latlong]];
As you can see, it also encapsulates the version checking required between iOS 6 & others.
如您所见,它还封装了 iOS 6 和其他版本之间所需的版本检查。
回答by Armel Larcier
Hey since iOS6 is out!
嘿,因为iOS6 出来了!
Apple did something remarkable in a bad way (from my point of view).
苹果以一种糟糕的方式做了一些了不起的事情(从我的角度来看)。
Apple's maps are launched and for devices running iOS 6 you should not use maps.google.com/?q=
if you want the iDevice to open the native Plan app. Now it would be maps.apple.com/?q=
.
Apple 的地图已启动,对于运行 iOS 6 的设备,maps.google.com/?q=
如果您希望 iDevice 打开本机计划应用程序,则不应使用。现在就可以了maps.apple.com/?q=
。
So that developers don't have to much work, the friendly maps.apple.com server redirects all non-Apple devices to maps.google.com so the change is transparent.
为了让开发人员不必做太多工作,友好的 maps.apple.com 服务器将所有非 Apple 设备重定向到 maps.google.com,因此更改是透明的。
This way we developpers just have to switch all google query strings to apple ones. This is what I dislike a lot.
这样我们开发人员只需将所有谷歌查询字符串切换为苹果查询字符串。这是我非常不喜欢的。
I had to implement that functionnality today so I did it. But I felt I should not just rewrite every url lying in mobile website to target Apple's maps server so I thought I'd just detect iDevices server-side and serve apple urls just for those. I thought I'd share.
我今天必须实现该功能,所以我做到了。但我觉得我不应该只是重写移动网站上的每个 url 来定位 Apple 的地图服务器,所以我想我只是检测 iDevices 服务器端并为那些提供苹果 url。我以为我会分享。
I'm using PHP so I used the opensource Mobile Detect library : http://code.google.com/p/php-mobile-detect/
我使用的是 PHP,所以我使用了开源 Mobile Detect 库:http: //code.google.com/p/php-mobile-detect/
Just use the isiPad
pseudo method as a boolean getter and you're done, you wont convert google into apple ;-)
只需将isiPad
伪方法用作布尔 getter 即可完成,您不会将 google 转换为 Apple ;-)
$server=$detect->isiPad()?"apple":"google";
$href="http://maps.{$server}.com/?q=..."
Cheers!
干杯!
回答by Roland Keesom
If you don't want to ask for location permissions and don't have the lat and lng, use the following.
如果您不想请求位置权限并且没有 lat 和 lng,请使用以下命令。
NSString *destinationAddress = @"Amsterdam";
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:destinationAddress completionHandler:^(NSArray *placemarks, NSError *error) {
if([placemarks count] > 0) {
MKPlacemark *placeMark = [[MKPlacemark alloc] initWithPlacemark:[placemarks objectAtIndex:0]];
MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:placeMark];
MKMapItem *mapItem2 = [MKMapItem mapItemForCurrentLocation];
NSArray *mapItems = @[mapItem, mapItem2];
NSDictionary *options = @{
MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsMapTypeKey:
[NSNumber numberWithInteger:MKMapTypeStandard],
MKLaunchOptionsShowsTrafficKey:@YES
};
[MKMapItem openMapsWithItems:mapItems launchOptions:options];
} else {
//error nothing found
}
}];
return;
} else {
NSString *sourceAddress = [LocalizedCurrentLocation currentLocationStringForCurrentLanguage];
NSString *urlToOpen = [NSString stringWithFormat:@"http://maps.google.com/maps?saddr=%@&daddr=%@",
[sourceAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[destinationAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlToOpen]];
}
For ios5, the Current Location needs to be in the correct language. I use the LocalizedCurrentLocation from this post http://www.martip.net/blog/localized-current-location-string-for-iphone-apps
对于 ios5,当前位置需要使用正确的语言。我使用这篇文章中的 LocalizedCurrentLocation http://www.martip.net/blog/localized-current-location-string-for-iphone-apps
For ios6, I use the CLGeocoder to get the placemark and then open the map with it and the current location.
对于 ios6,我使用 CLGeocoder 来获取地标,然后用它和当前位置打开地图。
Remember to add CoreLocation.framework and MapKit.framework
记得添加 CoreLocation.framework 和 MapKit.framework
回答by mal
You can do this now in html just from a url on your mobile device only. Here's an example. The cool thing is if you turn this into a qr code you have a way of someone getting directions to you from wherever they are just by scanning it on their phone.
您现在可以仅通过移动设备上的 url 在 html 中执行此操作。这是一个例子。很酷的事情是,如果您将其转换为二维码,您就可以让某人通过在手机上扫描它来从他们所在的任何地方获取到您的路线。
回答by joneswah
For iOS6 the apple docs recommend using the equivalent maps.apple.com URL Scheme
对于 iOS6,苹果文档推荐使用等效的 maps.apple.com URL Scheme
so use
所以用
http://maps.apple.com/maps?saddr=%f,%f&daddr=%f,%f
instead of
代替
http://maps.google.com/maps?saddr=%f,%f&daddr=%f,%f
to be backwards compatible the code would be
要向后兼容,代码将是
NSString* versionNum = [[UIDevice currentDevice] systemVersion];
NSString *nativeMapScheme = @"maps.apple.com";
if ([versionNum compare:@"6.0" options:NSNumericSearch] == NSOrderedAscending)
nativeMapScheme = @"maps.google.com";
}
NSString* url = [NSString stringWithFormat: @"http://%@/maps?saddr=%f,%f&daddr=%f,%f", nativeMapScheme
startCoordinate.latitude, startCoordinate.longitude,
endCoordinate.latitude, endCoordinate.longitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
there is a whole load of other supported parameters for the Apple Maps URL scheme : Apple URL Scheme Reference
Apple Maps URL 方案有很多其他受支持的参数:Apple URL Scheme Reference
you can use these iOS version detection macros if you have conditional code in other parts of your code. iOS version macros
如果您的代码的其他部分有条件代码,您可以使用这些 iOS 版本检测宏。iOS 版本宏