Android百度地图相关总结

来源:互联网 发布:个人简历免费下载软件 编辑:程序博客网 时间:2024/05/22 02:31

一、百度坐标转换成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']        }

八、写在结尾

还有些问题不记得了,项目做的有点久所以忘了,把记得的这些总结下,让后来了少走点弯路吧。

end。

0 0