一、百度坐标转换成gps坐标
搜了很多资料,几乎都是下面这个方法,但是都是根据计js来的,并没有安卓里面可以使用的方案。
js中百度坐标转成gps坐标的方法
上面链接中的方案大致如下:
1.将要转换的百度坐标a先假设成gps坐标;
2.将该坐标a按照百度sdk说明文档转换成百度坐标b(看到这里是不是觉得博主有病–!);
3.根据公式计算出我们需要的真正的gps坐标值
X = 2*Xa-Xb,Y = 2*Ya-Yb
代码如下。
public static LatLng convert2GpsLocation(LatLng sourceLatLng) {
double x1 = sourceLatLng.latitude;
double y1 = sourceLatLng.longitude;
// 将google地图、soso地图、aliyun地图、mapabc地图和amap地图
// 所用坐标转换成百度坐标
CoordinateConverter converter = new CoordinateConverter();
converter.from(CoordinateConverter.CoordType.GPS);
// sourceLatLng待转换坐标
converter.coord(sourceLatLng);
LatLng tempLatLng = converter.convert();
double x2 = tempLatLng.latitude;
double y2 = tempLatLng.longitude;
return new LatLng(2 * x1 - x2, 2 * y1 - y2);
}
注意方法中的第9行,百度官方文档坐标转换中给的默认值是CoordType.COMMON,但是根据实际测试,这个转换后的结果是有误差的,虽然也不是很远,但是用CoordType.GPS转换来的值是十分精确的。
二、overlay.zoomToSpan()无效的问题
有人说按照下面的方式改,然并卵。而且很多时候都出现了空指针的问题,下面那个routeOverlay经常是空的,因为做路线规划的时候这个对象的值要通过联网计算来获得,这个过程所花费的时间是不可预计的。
但是如果加一个非空判断的话,又走不到那句 zoomToSpan了。(不知道是不是我理解错了,总之我用的时候下面这种方法是不行的。)
mBaidumap.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
//zoomtospan 需要知道mapview 的宽和高才能计算
//但是当 onCreate 时 mapview 的宽和 高都还不知道
//所以 zoomtospan 应该在地图初始化以后再调用
routeOverlay.zoomToSpan();
});
也有人说新起线程,延迟更新。这个方法一开始也想过,只是觉得是种投机取巧的方式,但是项目没剩太多时间了,所以只能采取这种方式。(有时间的话再看看吧。)
mBaidumap.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
//由于线程异步的原因,该方案并不总是有效,因此需要延迟一会儿再缩放
mMapView.postDelayed(new Runnable() {
@Override
public void run() {
// zoomtospan 需要知道mapview 的宽和高才能计算
// 但是当 onCreate 时 mapview 的宽和 高都还不知道
// 所以 zoomtospan 应该在地图初始化以后再调用
if (null != routeOverlay)
routeOverlay.zoomToSpan();
}
}, 500);//延迟0.5s
}
});
三、通过坐标获取城市名
BaiduMap sdk中并没有提供直接的工具方法,但是有提供类似的方法,可以曲线救国。(见demo中的GeoCoderDemo。)
1.首先声明一个GeoCoder对象
GeoCoder mSearch = null;
2.在activity中初始化并设置监听器
mSearch = GeoCoder.newInstance();
mSearch.setOnGetGeoCodeResultListener(this);
3.OnGetGeoCodeResultListener接口内容如下:
public interface OnGetGeoCoderResultListener {
void onGetGeoCodeResult(GeoCodeResult var1);
void onGetReverseGeoCodeResult(ReverseGeoCodeResult var1);
}
我们要做的就是反编码,调用下面的方法即可,反编码结果将在上面的onGetReverseGeoCodeResult方法中回调。
// 反Geo搜索
mSearch.reverseGeoCode(new ReverseGeoCodeOption()
.location(你要反编码的LatLng));
4.回调方法中的参数为ReverseGeoCodeResult对象,通过调用下面的方法可以获得一个AddressComponent对象,该对象即包含了你所要的全部位置信息了。
ReverseGeoCodeResult.getAddressDetail();
四、请求位置时得到坐标为4.9E-324
1.这个值是sdk中的默认值,请求后得到这个值说明定位失败了,可能是信号不好也可能是你配置不对。
2.特别提示的是,如果定位后提示“离线定位成功,离线定位结果也是有效的”或者“网络不同导致定位失败,请检查网络是否通畅”,你可能需要考虑换一种坐标系定位了。
比如我的项目里在魅族三星的手机上面可以正常定位,但是到华为和荣耀的手机上面定位到的是上面这个值;而且这两个华为手机,连公司的2g网络无法定位,切换另一个网络的时候就能正常定位了;但是魅族和三星的手机连2g又能正常定位。
所以不知道是手机的问题还是网络的问题。
后来发现定位默认采用的坐标系是gcj02,将坐标系改成bd09ll就没有这个问题了。
五、 Exception in thread “main” java.lang.UnsatisfiedLinkError:
1.动态链接库库没有配置好,sdk中所有的so文件必须一一对应放在libs目录下面,异常中提示的名字就是so文件名。
2.有时候你发现已经配置好了动态链接库,但是还是有那个异常,有可能是cpu不兼容的问题。做项目的时候一开始在魅族上面有问题,然后华为手机也有问题。
在libs目录下新建arm64-v8a、armeabi、armeabi-v7a这三个目录,将so文件都复制过去,即可兼容不同cpu的手机。(这三种cpu的区别这里不多讲,详细可百度。)
还有一些x86的,市面上这些类型的手机很少,可忽略。(因为so文件也占一定体积,打包发布的时候会使apk变得很大。)
六、baidumap sdk最好做成library或者moudle
千万不要直接集成到项目!千万不要直接集成到项目!千万不要直接集成到项目!!
重要的事情说三遍,至于为什么,到你更新baidumap的sdk的时候就知道了,相当十分非常痛苦!
七、baidumap的so文件在Android studio工程中的位置问题
这个其实跟百度地图没多大关系,刚才第五点提到了apk体积变大的问题,顺便提下。
先交代下背景,之前eclipse中的so文件都是放在libs目录下面的,但是在androidstudio中,网上很多人都说要放在src/main/jniLibs/目录下,然后在gradle文件中配置一下。
但是按照这种方式,打包之后发现apk变得异常的大,100+M!!解压后发现,so文件竟然复制成了两份,除了jniLibs目录下面有一份,libs目录下面也有一份。
难道apk的文件结构中其实还是按照eclipse中的那种结构来的吗?百思不得其解。
继续百度,发现studio中除了上面的那种放置so文件的方法,其实也可以直接将so放在libs下,只要在build.gradle中添加如下配置
jniLibs.srcDirs = ['libs']
配置后的完整代码如下:
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res', 'src/main/res', 'res/values-normal-hdpi-800x480']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
八、写在结尾
还有些问题不记得了,项目做的有点久所以忘了,把记得的这些总结下,让后来了少走点弯路吧。