笔者最近实践了利用openlayers在android app中实现离线地图应用,本文记录了笔者实践的思路。
android端移动地图功能设计:
1、加载本地的地图瓦片;
2、GPS定位;
3、叠加部件(矢量)图层;
准备工作
android端用webview加载在线页面或离线的html页面都是没问题的,同时,android原生与JS之间可以互相调用。这一部分不是本文的重点,参考资料如下:
- Android与HTML+JS交互入门 android原生与JS之间互相调用的例子
- android 与JS之间的交互 WebView加载本地资源的小结
- Android WebView 与JS的数据交互 如何将css js 图片等静态资源部署在APP中
ol如何加载手机端本地地图瓦片
笔者想到ol加载地瓦片地图时,可以用tileUrlFunction返回一个瓦片的链接,例如:
tileUrlFunction: function (tileCoord, pixelRatio, proj) {
var z = tileCoord[0] + 11;
var x = tileCoord[1];
var y = -tileCoord[2] - 1;
return "http://www.dzmap.cn/OneMapServer/rest/services/vector_service/MapServer/tile/" + z + "/" + y + "/" + x;
}
- tileUrlFunction返回一个地图瓦片的路径,ol请求瓦片并渲染。如果在此步骤将请求服务端的瓦片改为请求Android本地的资源,是否可行?
- android端本地无法提供一个http路径,我想到了用base64将图片编码的方式返回给ol,测试证明这是可行的。
- 那么加载本地瓦片就简单了,下载地图瓦片并组织好存储路径,tileUrlFunction中调用android原生的方法获取对应xyz的瓦片,然后用base64编码后,返回给ol。
- 进一步改进,用文件方式存储地图瓦片比较浪费,就想到了用sqlite mbtile方式存储瓦片。笔者在之前的地图瓦片下载工具基础上,增加了输出sqlite mbtile的功能,点击下载。
- MBTile相关介绍:
官方介绍
MBTiles移动存储简介 - 通过测试,发现用base64编码后的瓦片,ol的缓存功能貌似不好使了,查了一些资料,提到用base64编码后,就无法用到浏览器缓存了。没关系,在android端用Lrucache做缓存,也能很好的解决此问题。
实现GPS定位功能
- JS调用android原生获取GPS定位坐标,android端可以用原生的GPS定位,或使用baidu sdk,返回当前位置坐标。
- 为防止获取GPS位置时有较长的等待,笔者推荐用异步的方式。即,由JS调用Android端获取GPS位置,android启用异步方式获取当前位置,并立即返回;当Android端获取到位置后,回调JS端,传递当前位置给OL,ol标注当前位置。
叠加部件(矢量)图层
- 与上述加载本地瓦片类似,事先预处理好矢量图层,用spatialite(基于sqlite的空间数据库)存储矢量部件图层,建好空间索引;
- ol注册map.moveend事件,请求当前可视范围的矢量数据;
- 这里应该还可以用矢量瓦片来替代,还没来及实践。
本文献给大连机场,感谢您延误航班,使我有时间有耐心写完本文,谢谢。
网友评论