最近在做导航,所以把自己找到的资料总结一下!
无论是百度地图、高德地图、谷歌地图还是腾讯地图它们都有自己的SDK,我们只需要在自己的工程中导入SDK并查看相应的官方文档,基本上就可以实现导航。但是这样每个地图的SDK都导入不但麻烦而且占用APP的内存。最关键的是我们上传到AppStore的包文件是有限制的。所以我的原则是能不导入的SDK 就不导入。
还有一种方式就是是以URI跳转的方式(在iOS中就是以URL Scheme的方式),直接跳到对应的地图APP中,直接利用对方的功能来导航。缺点是用户没有安装对应的APP就不能使用其进行导航。
点击导航按钮会出现如下的弹窗, 当然手机上未安装的地图 其名称就不会出现在弹窗上。
在 iOS9之后 若想用URI方式跳转到百度地图、高德地图、腾讯地图、谷歌地图,需要你在info.plist加入这些东西。(ps:LSApplicationQueriesSchemes,短的自己手打吧,另外注意类型!)
下面进入正题
以下出行的默认方式都是驾车
一、百度地图
说到百度地图,就不得不说它很坑爹。因为百度地图获取的经纬度,是在GCJ-02(火星坐标)进行偏移得到的经纬度,而高德、谷歌、腾讯都是使用GCJ-02坐标体系得到的经纬度。这样使用百度地图获取到的经纬度在高德、谷歌、腾讯上导航都会出现很大的偏差。所以自己做的APP中需要地图功能最好不要导入百度地图的SDK(使用上面三个中任何一个地图获取到的经纬度都可以很容易的转换成百度地图需要的经纬度),如果你是像我这样中途接手的项目,百度地图的相应功能已经做好了,那你可以用下面的方式换算一下经纬度(最下方)。
代码如下 :需传入起点和终点的经纬度
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://map/"]])
{
UIAlertAction *baiduMapAction = [UIAlertAction actionWithTitle:@"百度地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *baiduParameterFormat = @"baidumap://map/direction?origin=latlng:%f,%f|name:我的位置&destination=latlng:%f,%f|name:终点&mode=driving";
NSString *urlString = [[NSString stringWithFormat:baiduParameterFormat,
userLocation.location.coordinate.latitude,
userLocation.location.coordinate.longitude,
self.destinationCoordinate.latitude,
self.destinationCoordinate.longitude]
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] ;
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:urlString]];
}];
[actionSheet addAction:baiduMapAction];
}
各个参数代表的含义可参考百度地图官方文档。
二、高德地图
只需传入终点经纬度
高德地图能够跳转回你的APP,前提是backScheme=%@(你的APP的URL)要填写。代码如下
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://map/"]])
{
UIAlertAction *gaodeMapAction = [UIAlertAction actionWithTitle:@"高德地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *gaodeParameterFormat = @"iosamap://navi?sourceApplication=%@&backScheme=%@&poiname=%@&lat=%f&lon=%f&dev=1&style=2";
NSString *urlString = [[NSString stringWithFormat:gaodeParameterFormat,
@"yourAppName",
@"yourAppUrlSchema",
@"终点",
self.destinationCoordinate.latitude,
self.destinationCoordinate.longitude]
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:urlString]];
}];
[actionSheet addAction:gaodeMapAction];
}
各个参数的含义可参考高德地图官方文档
三、苹果地图
需传入起点和终点的经纬度,并导入头文件#import MapKit/MKMapItem.h>
[actionSheet addAction:[UIAlertAction actionWithTitle:@"苹果地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//起点
MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];
CLLocationCoordinate2D desCorrdinate = CLLocationCoordinate2DMake(self.destinationCoordinate.latitude, self.destinationCoordinate.longitude);
//终点
MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:desCorrdinate addressDictionary:nil]];
//默认驾车
[MKMapItem openMapsWithItems:@[currentLocation, toLocation]
launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsShowsTrafficKey: [NSNumber numberWithBool:YES]}];
}]];
各个参数的含义可参考苹果地图官方文档
四、谷歌地图
只需传入终点的经纬度
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"comgooglemaps://map/"]])
{
[actionSheet addAction:[UIAlertAction actionWithTitle:@"苹果地图"style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",
appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}]];
}
各个参数的含义可参考谷歌地图官方文档
五、腾讯地图
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"qqmap://map/"]])
{
[actionSheet addAction:[UIAlertAction actionWithTitle:@"腾讯地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *QQParameterFormat = @"qqmap://map/routeplan?type=drive&fromcoord=%f, %f&tocoord=%f,%f&coord_type=1&policy=0&refer=%@";
NSString *urlString = [[NSString stringWithFormat:QQParameterFormat,
userLocation.location.coordinate.latitude,
userLocation.location.coordinate.longitude,
self.destinationCoordinate.latitude,
self.destinationCoordinate.longitude,
@"yourAppName"]
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}]];
}
各个参数的含义可参考腾讯地图官方文档
修改于2016-10-20:
GCJ-02坐标转换成BD-09坐标 和逆转换
/**
* 将GCJ-02坐标转换为BD-09坐标 即将高德地图上获取的坐标转换成百度坐标
*/
- (CLLocationCoordinate2D)gcj02CoordianteToBD09:(CLLocationCoordinate2D)gdCoordinate
{
double x_PI = M_PI * 3000 /180.0;
double gd_lat = gdCoordinate.latitude;
double gd_lon = gdCoordinate.longitude;
double z = sqrt(gd_lat * gd_lat + gd_lon * gd_lon) + 0.00002 * sin(gd_lat * x_PI);
double theta = atan2(gd_lat, gd_lon) + 0.000003 * cos(gd_lon * x_PI);
return CLLocationCoordinate2DMake(z * sin(theta) + 0.006, z * cos(theta) + 0.0065);
}
/**
* 将BD-09坐标转换为GCJ-02坐标 即将百度地图上获取的坐标转换成高德地图的坐标
*/
- (CLLocationCoordinate2D)bd09CoordinateToGCJ02:(CLLocationCoordinate2D)bdCoordinate
{
double x_PI = M_PI * 3000 /180.0;
double bd_lat = bdCoordinate.latitude - 0.006;
double bd_lon = bdCoordinate.longitude - 0.0065;
double z = sqrt(bd_lat * bd_lat + bd_lon * bd_lon) + 0.00002 * sin(bd_lat * x_PI);
double theta = atan2(bd_lat, bd_lon) + 0.000003 * cos(bd_lon * x_PI);
return CLLocationCoordinate2DMake(z * cos(theta), z * sin(theta));
}
另外无论你导入的是百度SDK还是高德SDK,他们内部都封装了将目标经纬度转换为高德坐标系或百度坐标系(文档上的接口可能被弃用没有及时更新,是不是很坑爹),但是没有将高德或百度坐标转换为别的坐标系下的坐标的接口。所以感觉情不自禁想问一下这个接口还有毛用。。。。
设置URL Scheme:http://blog.csdn.net/wm9028/article/details/49995329