罗孚想要制做一份疫情场所分布地图,最初是由于看到我所在的城市(上海)疫情场所位置不许,想本身作一份数据并显示在地图上,结果一拖再拖而后疫情都快结束了[尴尬],不过我仍是花了一天时间研究了一下,因而有了这篇《如何制做一份疫情场所分布地图?》,要不就当罗孚手把手教你制做一份疫情场所分布地图吧[捂脸]。
本文是以上海地图数据为基础、基于高德地图API设计制做的一份城市地图,若是你收集了你所在城市的地图数据,那么按照本文文末提供的源码和数据结构,你也能够直接复制出一份城市疫情场所地图。要是你真实现了,记得要回来show给我看一下哦。javascript
上图是几个主要功能的预览
不过只给个图不给体验,这不是罗孚的风格,直接上体验网址:https://rovertang.com/map/shncov/
疫情场所分布地图现有的功能:php
其余:缩放控件显示、地图范围限定等
因为是第一版,仅仅研究探讨,因此更强大的功能还没法实现,不过我会在下文中展望一下更强大的功能。html
两个文件就实现了所有功能,还要作个概要设计?很差意思,请让罗孚装一下[捂脸]。实际上,罗孚在这事情上确实走了弯路。java
罗孚最开始考虑的实现方案,超级简单,简单到甚至不须要写代码和制做数据文件。
不论是高德、百度仍是腾讯,都提供了地图数据管理方案,高德的云图、百度地图的LBS云、腾讯地图的地点云,直接使用他们的云存储,而后在地图上添加一个自定义云图层或者经过数据检索API取出数据后marker到地图就好了。
云数据方案是好的,但罗孚使用下来,居然都很差用,要么没法在地图上显示,要么API接口不返回数据,只能说罗孚做为一个非专业开发人员,确实太菜了一些。固然,也要批评一下高德,地图若是是3D模式时,没法使用云地图图层,这一信息是在某一文档的一行小字中找到的,擦,这坑挖的够深。
自建数据库成了惟一的选择。
不过,为了让方案简单易复制,使用MySQL彷佛重了一点,要不使用sqlite吧。但一想到要写数据库的增删改查,又增长了很多麻烦,为了快速实现,直接将最终数据作成了json文本,数据库的操做,之后再考虑吧。
大言不惭的说,最后的实现框架是:json+js。嗯,两个文件,一个json数据文件,一个js文件(写在html文件里了)。[憨笑]sql
扒别人的位置数据
罗孚的初衷是想本身收集和标注,自力更生是我国人民的传统美德,但本人懒癌严重,因此最后也是取了个巧,扒了份别人的数据(仅使用了上海部分啊,其余城市的没要)。
固然,如何扒其余平台的数据,彷佛又能够写一篇文章,考虑同本教程有较大出入,加上这见不得人的伎俩,之后再说吧。数据库
肯定好框架,定义好数据,能够开始开发了,但因为和地图相关,在此多讨论一下地图平台的问题。
通常来讲,使用商业公司成熟的地图API是最佳选择:
高德和百度地图的API:推荐。毕竟是国内不分伯仲的顶尖API。
腾讯地图API:可用。可能能够算国内老三,但用的人真少,看在微信、小程序都是鹅厂的产品,也是值得考虑的,看了下API,也基本能用。
mapbox API:可用,有难度。mapbox是开源地图解决方案公司,属于国际顶尖(在地图上甚至比Google还强大哦),如今正在大力发展国内市场,这次制做的疫情地图也超级漂亮(欣赏一下)。
Google maps API:不能用。虽然国际顶尖(地图API鼻祖),但不能用的道理,你懂得。(有兴趣的能够了解一下我十年前拆解的Google Maps API v3离线开发包)
除了商业公司的方案,固然也可使用开源方案,好比leaflet。我看到天地图上海作的地方疫情地图就是用了leaflet。开源方案主要是功能框架,但地图底图数据,要么用商业公司的,要么就仍是本身扒了(罗孚也扒过:Google Maps瓦片(tile)地图文件下载(1-11层级),今年过年太无聊,又扒了更多更细的数据[捂脸])。
地图平台的探讨,真能够再写几篇文章,对于本文的地图平台,最终选择了高德,主要缘由是站在别人肩膀上的选择。百度地图API虽然我想用,但考虑到百度地图坐标是在GCJ02坐标系下又作了一次加密,想到后续的数据坐标混乱,仍是罢了罢了。json
继续大言不惭的说说功能实现的详细设计吧,咱们针对每一项功能作详细的介绍以及实现上的注意事项,顺便把我参考的地图示例贴出来供你们参考。小程序
而地图的风格,normal的色调太亮,换一个官方的远山黛whitesmoke主题吧。
参考示例:
地图建立:https://lbs.amap.com/api/javascript-api/example/map-lifecycle/map-show
设置地图中心点/级别:https://lbs.amap.com/api/javascript-api/example/map/change-map-center
标准样式主题:https://lbs.amap.com/api/javascript-api/example/personalized-map/set-theme-style
地图类:https://lbs.amap.com/api/javascript-api/reference/mapapi
这一步算是本地图DEMO的最核心功能了,虽然说比较简单,就是遍历json,而后批量添加marker到地图就能够了,但这里遇到了一个坑,在marker上绑定click事件后,居然click任何一个marker,都是响应最后一个marker的气泡框。
调整半天、搜索半天都没能解决,罗孚差点想把整个DEMO都放弃,最后仍是搜索到了一个小小的提示,才解决了这个问题。感慨百度搜索真心不灵。
这个问题的解决方法:使用marker的extData。
参考示例:
覆盖物的添加与移除:https://lbs.amap.com/api/javascript-api/example/map-componets/map-overlays
点标记:https://lbs.amap.com/api/javascript-api/example/marker/marker-content
自定义图标:https://lbs.amap.com/api/javascript-api/example/marker/custom-icon
获取某个覆盖物(关于extData的使用):https://lbs.amap.com/api/javascript-api/example/common/ext-data/
默认样式信息窗体:https://lbs.amap.com/api/javascript-api/example/infowindow/default-style-infowindow
Marker类:https://lbs.amap.com/api/javascript-api/reference/overlay#marker
InfoWindow 类:https://lbs.amap.com/api/javascript-api/reference/infowindow#InfoWindow浏览器
此功能是显示本身的位置,若是定位成功,则基于自身位置显示半径为1千米和3千米的圈,以了解附近范围内大概有多少疫情场所marker。
须要注意,本处使用的是AMap.Geolocation,是高德地图API的定位插件。
定位的一些细节逻辑:当定位成功后,原则上是须要将地图的中心点移动到定位位置的。但若是定位信息中的citycode不是021,那么就不要移动地图中心点。对于没法定位和定位成功返回的citycode不是021,那么仍然是以上海市人民广场为地图中心点。
参考示例:
浏览器精肯定位:https://lbs.amap.com/api/javascript-api/example/location/browser-location
圆的绘制和编辑:https://lbs.amap.com/api/javascript-api/example/overlayers/circle-draw-and-edit
AMap.Geolocation插件:https://lbs.amap.com/api/javascript-api/reference/location#m_AMap.Geolocation
能够查看自身位置信息了解自身周边的疫情状况,那么想看看某一小区或商场附近的疫情状况是否能够实现呢?这就须要用到查询功能了。
这里咱们使用高德的AMap.Autocomplete,是输入提示插件,虽然不是地点搜索,但已经足够用了,能出如今提示中的结果都是搜索频率较高的结果,同时这个插件的使用也超级简单,输入绑定到某一输入框,好比id为search的input,结果绑定到某一div,好比id为result的div,功能就实现了,你只要输入内容,result中就出现结果了(简单到让罗孚瞠目结舌)。
完成上述操做,结果内容是没法选择的,好在插件提供了返回结果功能,在AMap中设置一个监听事件,选择某一结果后就能够获得该结果的详细信息,我主要是取经纬度信息,而后在地图上显示一个marker就行了。
参考示例:
输入提示:https://lbs.amap.com/api/javascript-api/example/input/input-prompt
添加简易控件,就是在地图右下角的放大和缩小按钮,使用AMap.ToolBar便可,是地图操做工具条插件。
为了让地图范围在某一范围中显示,能够给地图设置一个bound,使用map.setLimitBounds方法便可。
参考示例:
地图控件:https://lbs.amap.com/api/javascript-api/example/map-componets/map-with-function-control
限制地图显示范围:https://lbs.amap.com/api/javascript-api/example/map/limit-map-show-range
地图操做工具条插件:https://lbs.amap.com/api/javascript-api/reference/map-control#AMap.ToolBar
本demo中使用的数据,总量100+,不算不少,但若数据量达到1000+,那么加载的时间顺序就显得尤其重要,因此咱们在地图加载完成(使用map.on 'complete')后,再去加载json数据。
这样作的优点:先让地图显示,而后看到地图上出现marker,避免地图长时间等待加载,毕竟用户的耐心是有限的。
关于事件,因为主要是针对地图或覆盖物类,因此使用这些类的on成员方法实现对事件的绑定。好比上面加载json数据是绑定在map的complete事件上的,好比气泡框的显示是绑定在marker的click事件上的。
对于非地图或覆盖物类的事件,那就只能增长addListener事件了,好比对输入提示结果的操做。
参考示例:
地图加载完成:https://lbs.amap.com/api/javascript-api/example/map-lifecycle/map-complete
事件:https://lbs.amap.com/api/javascript-api/reference/event
输入提示后查询:https://lbs.amap.com/api/javascript-api/example/poi-search/search-after-enter-prompt/
引入其余地图API
使用高德地图API,虽然实现了此DEMO,但毕竟有自身的局限性,绑定在了此平台上,能够考虑使用同一份数据制做基于百度地图API、腾讯地图API以及leaflet库的地图。
还有不少不少,没法一一叙述,后续能够考虑写一篇疫情地图功能对比的文章,看看别人在产品制做上的优劣。
专业的人作专业的事
罗孚本人不是程序猿,也应该有10年以上没有碰过代码了,此次作个DEMO都费了老半天的劲,只能感慨专业的事仍是由专业的人来作吧。
不过上面产品思考的功能开发,若是在屏幕前的你,有兴趣帮助完成,那也欢迎联系我。不论是互相学习交流,仍是互相帮助提高,罗孚都愿意,毕竟罗孚也是热心肠嘛[憨笑]。
本文太啰嗦,一篇技术文章写成了记叙文,罗孚自身也在感慨,看来之后能够考虑作成PPT或视频的形式,要么更简单明了,要么更详细清晰。
本文标题和开篇均提到了源码和数据,若是是懂技术的你,应该是不屑的,或者Ctrl+U一下就拿到了(加密版本)。若是确实须要下载,能够在“罗孚传说”公众号上回复“疫情场所地图”便可(未加密版本)。若是须要带详细注释的文件来研究,请加入罗孚的知识星球来取(带注释版本),固然还能够附送超详细瓦片地图离线文件哦,后续也有更多内容分享。 好了,用地图API制做一份疫情场所分布地图,今天,你会了吗?欢迎联系罗孚,欢迎关注罗孚的公众号(罗孚传说)作更多交流,更欢迎加入罗孚的知识星球赞助罗孚得到更多有价值内容,咱们下一篇文章中见。