移动端GIS功能开发
1.概述
去年⾃⼰参与了⼀款含有GIS核⼼功能的App开发,开发结束后⾃⼰在笔记软件做了项⽬总结,今天特意想起来,就将其搬到博客这⾥来,并进⾏⼀定的修改优化。庆幸⾃⼰⼀直有做完项⽬即时做总结的习惯,否则此时再去回顾,多半⽆从下⼿。
此款软件,为了降低开发成本,我们采⽤了跨平台的React-Native框架。App主体功能有两个:GIS功能和表单功能。其中,GIS功能包括地图展⽰、图例绘制、地点搜索、地点导航、轨迹搜集等;表格功能即是信息展⽰、信息填写、信息上传等⼀般表单包含的功能。虽然说⾃⼰也参与部分表单功能的开发(⽐如区域选择器、表单内容约束机制等),但GIS功能主要由我负责,⾃⼰对这块体会更加深刻,因此,本⽂主要介绍移动端GIS功能开发,包括使⽤的框架、核⼼包\组件、遇到的问题及解决⽅法等。
2.框架及核⼼库
安卓app开发用什么框架
App采⽤跨平台的React-Native框架,⽽地图页⾯是H5页⾯,GIS库采⽤Leaflet。
1. 上述框架确定前的技术预研及踩坑:
A、在GIS库⽅⾯,我在Leaflet、OpenLayers、MapboxGL三款基础地图库中,根据稳定性、软件成熟度、社区⽣态链完善程度⼏项指标,选择了Leaflet作为基础地图库,后续开发证明选择确实没错,“Leaflet包含了⼤量第三⽅插件,需要什么功能,都可以先到Github上搜索,常见的功能都有对应的第三⽅库实现了。同时,Leaflet⽂档也相当完善及⾼质量。”
B、在决定采⽤H5页⾯开发⽅⾯,前期⾃⼰先检索了React-Native的第三⽅地图包,结果都没有到合适的,例如react-native-maps需要⽤到⾕歌地图,因此不适合国内。最后才确定在react-native中嵌⼊H5页⾯,⽽H5页⾯⽤⼀个新项⽬实现,⽤webpack打包⼯具打包。
2. 使⽤到的核⼼库/组件:
react-native-webview: ⽤于在React-Native项⽬中嵌⼊H5页⾯。
react-native-loaction: ⽤于获取⼿机当前位置。
react-native-foreground-service: ⽤于安卓⼿机开启前台任务。
HtmlWebpackInlineSourcePlugin: ⽤于将引⽤到js⽂件及css⽂件都打包进html⽂件中。
天地图: 提供地图源服务及搜索服务。
腾讯地图/⾼德地图/百度地图: 提供跳转到App进⾏导航的api。
3.问题及解决⽅法(需求及实现⽅式)
1.H5页⾯路径: 由于在android上,传给react-native-webview包source参数的值需要是绝对路径
(‘file:///android_asset/pages/index.html’),⽽在ios上,传⼊的值可以是相对路径,因此需要将H5页⾯引⽤到的js⽂件、css⽂件都复制到android/app/src/asset⽬录下以及另外⼀个路径(⽤于ios)。
2.调试H5页⾯: react-native-webview调试需要⽤到Chrome Inspect⼯具,需要;调试前,需要将地图页⾯项⽬webpack配置中的HtmlWebpackInlineSourcePlugin插件去掉,否则⽆法定位问题⾄具体的js⽂件。
ner() 监听RN发送过来的消息,⽽ios平台则是通过window.addEventListener()。为了在页⾯初始化前能获知平台类型,需要通过react-native-webview的injectedJavaScriptBeforeContentLoaded属性传⼊字符串赋值。
4.实时获取⼿机当前位置:
定位功能:⾸先,尝试使⽤Leaflet地图库的api及Html5的api,两者都可以实现,Leaflet的api实际上是在Html5的api做了封装⽽已,但在适配ios时出现了位置权限提⽰的问题(弹窗提⽰"xx/xx/index.html想使⽤您当前位置"),⽽且在外边的react-native已经请求过权限了,因此重新了react-native-location包实现定位功能。
轨迹搜集功能:⾸先,因为react-native-location的getLatestLocation() api经常返回过时的位置,因此没办法⽤ “定时调⽤该api来实现轨迹搜集” ;接着,由于配置不对,所以react-native-location的subscribeToLocationUpdates api不能及时更新位置;最后,修改了 "
interval;maxWaitTime" 这两个参数实现实时获取⽤户位置的功能。
后台运⾏轨迹搜集:⾸先,由于expo包有后台获取位置的api,所以先尝试⽤expo的api去获取位置,但发现始终没返回,猜测是GooglePlay的原因,但没能验证,所以也没有放弃;然后,尝试通过expo
的BackgroundFetch api定时调⽤其它包的位置获取api来实现功能,但间隔时间最短没有少于1min,⽆法实现功能需求;接着,尝试使⽤之前的定位功能时会报 “你的设备不⽀持
GooglePlay,因此⽆法运⾏xxx” 的问题,最终调试是expo-location包的原因,因此得出expo包获取位置是需要⾕歌服务的,因此放弃expo⽅案;最后,由间隔时间最短限制查到android⽂档上说明了android8+以上会对后台应⽤做程序运⾏频率进⾏限制,同时看到了成为前台应⽤的⼏个条件,其中⼀个是有前台任务,因此去github前台任务的react-native包,最终到了react-native-foreground-service,⾄此,完成了安卓后台运⾏轨迹搜集功能;⽽针对ios平台,则是看到了react-native-location包中有⼀个设置“allowsBackgroundLocationUpdates”,最终开启这个设置便实现了后台运⾏。
4.总结
经验证,移动端GIS功能开发可以采⽤如下框架及技术:
1.采⽤React-Native作为App主体框架,地图页⾯作为⼀个单独项⽬,最终打包成H5页⾯,⽤react-native-webview组件加载H5页⾯。
2.地图页⾯采⽤Leaflet基础地图库,地图源使⽤天地图(免费),天地图同时也提供POI搜索、路线规划等GIS服务。
3.地图页⾯页⾯上:图例展⽰、绘制、点击等由Leaflet实现;POI搜索由天地图服务提供,地点导航由⾼德地图、腾讯地图、百度地图提供api跳转实现;定位功能及轨迹搜集功能借助react-native-loaction实现。
整体来说,采⽤全部免费的框架及技术实现,难度会⽐直接使⽤收费的地图库⼤很多,⽽且实现效果也完全⽐不上,⽐如说⽤ react-
native-loaction 第三⽅库实现的轨迹搜集功能,会存在GPS漂移、轨迹路线不顺滑等问题,如果想进⼀步优化,可以采⽤卡尔曼滤波优化,这种优化有检索过,没有实现过。总之,收费的才是最好的(@_@)。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。