本文主要介绍云助理原生安卓客户端地理位置相关功能开发过程中遇到的问题和解决方法。
在地理位置相关功能开发中,遇到的最棘手的问题不是具体功能的实现,而是坐标系问题;所以在开发地理位置功能前,首先要考虑清楚的就是使用哪种坐标系。
由于处于安全考虑,国家要求对定位获取的原始坐标(wgs84)至少进行一次加密(即加密成gcj02),所以国内就有了以下一堆常见坐标系:
wgs84:GPS坐标,这是最原始的坐标系,直接通过GPS系统卫星定位获得的坐标;移动设备通过wlan、移动网络获取的坐标也多为采用wgs84坐标。
gcj02:国测局加密坐标,国家以安全原因为由,要求在中国使用的地图产品使用的都必须至少是加密一次后的坐标,这套加密后的坐标就是gcj02;网上也称之为火星坐标。
bd09ll:百度经纬度坐标,单位为度,是百度在gcj02的基础上将坐标二次加密成了bd09ll坐标。
bd09mc:百度墨卡托坐标,墨卡托坐标是一种投影坐标,单位为米,而不是用经纬度来表示,多用于航海图、航空图。
基于国家的规定,国内地图使用的坐标系就五花八门了:
bd09ll坐标系:百度地图
gcj02坐标系:高德地图、google地图(中国地区)
mapbar坐标系:图吧
其中google地图在中国以外地区使用的是wgs84坐标系。
暂不确定腾讯地图(即soso地图)是否采用gcj02,并未在腾讯地图官网查到直接的介绍。(腾讯地图官网关于采用的坐标系说明只有一句“采用经纬度坐标,单位为度”,等于没说)
建议选择gcj02坐标系作为使用和存储的坐标系,有以下几个原因:
云助理原生安卓客户端使用百度地图定位插件来获取用户的当前位置。
用户登录成功后,云助理客户端会每隔5分钟获取用户当前位置,并与上一次获取到的位置进行比较,如果大于阈值,则向服务器发送用户当前位置,否则不发送。
阈值判断:前后两次位置的直线距离如果大于前后两次位置的精确度中较大的值,则发送用户当前地理位置
云助理地图插件是基于百度地图SDK进行开发,具体开发步骤建议阅读百度地图开放平台的开发指南。在这里介绍开发中的一些经验总结:
百度地图初始化时会显示默认地图中心为北京,这样就会每次都出现先显示北京地区的地图,然后显示地图又马上改变为当前位置;为了避免出现这种情况,在打开地图插件时我们有传入一个经纬度坐标,在地图onCreate的时候,把这个坐标设置为地图的默认中心。
传入的这个坐标可以设置为用户上次使用地图插件时选择的位置,也可以是通过通过定位插件获取的用户当前位置。
云助理lbs功能需要根据消息中的地理位置参数,在地图上显示对应位置的标注覆盖物(marker)。如果直接把覆盖物图片显示在地图上,存在几个问题:
我们的解决方法是这样的:
在打开地图时,把marker的图片转化为bitmap,并获取当前设备屏幕的宽度deviceWidth;然后根据当前设备宽度来等比例改变marker的长宽,这样可以保证在不同尺寸设备上能有相同的显示效果。
Bitmap bmp = BitmapFactory.decodeStream(getResources().openRawResource(icon)).copy(Bitmap.Config.ARGB_8888, true);
int width = (int) (deviceWidth * 0.075);
int height = (int) (deviceWidth * 0.075 * bmp.getHeight() / bmp.getWidth());
bmp = Bitmap.createScaledBitmap(bmp, width, height, true);
然后使用Canvas,在bitmap上画上对应的序号。
在地图初始化时,地图插件就会生成好所有marker对应的bitmap并保存起来,在关闭地图时再释放所有的bitmap资源。
发送地理位置类型的消息时,云助理有调用百度地图静态图接口来生成加上了marker的对应位置的地图图片,并作为地理位置消息的图片显示在消息列表上,以下是关于静态图功能的简单说明。
通过 百度LBS开放平台的静态图API 生成,基本使用说明如下:
http://api.map.baidu.com/staticimage?width=图片宽度&height=图片高度¢er=&markers=标签经度,标签纬度&zoom=地图缩放级别&scale=图片类型&markerStyles=标签大小,,标签颜色
参数说明:
图片尺寸:图片长宽比建议设为3:2
地图缩放级别:数值越大,图片放大级别越大,高清图范围[3, 18];低清图范围[3,19]
标签:需要显示多个标签,每个标签请用“|”隔开
图片类型:1(低清图),2(高清图);客户端默认生成的是低清图
标签大小:有大中小三个值,分别为l、m、s
标签颜色:十六进制数值表示的颜色