如何制作一份疫情场所分布地图?(附数据和源码)
羅孚想要制作一份疫情場所分布地圖,最初是因為看到我所在的城市(上海)疫情場所位置不準,想自己做一份數(shù)據(jù)并顯示在地圖上,結果一拖再拖然后疫情都快結束了[尷尬],不過我還是花了一天時間研究了一下,于是有了這篇《如何制作一份疫情場所分布地圖?》,要不就當羅孚手把手教你制作一份疫情場所分布地圖吧[捂臉]。
本文是以上海地圖數(shù)據(jù)為基礎、基于高德地圖API設計制作的一份城市地圖,如果你收集了你所在城市的地圖數(shù)據(jù),那么按照本文文末提供的源碼和數(shù)據(jù)結構,你也可以直接復制出一份城市疫情場所地圖。要是你真實現(xiàn)了,記得要回來show給我看一下哦。
功能和效果預覽
上圖是幾個主要功能的預覽
不過只給個圖不給體驗,這不是羅孚的風格,直接上體驗網(wǎng)址:https://rovertang.com/map/shncov/
疫情場所分布地圖現(xiàn)有的功能:
地圖顯示
疫情場所顯示
個人位置顯示
地圖搜索
其他:縮放控件顯示、地圖范圍限定等
由于是初版,僅僅研究探討,所以更強大的功能還無法實現(xiàn),不過我會在下文中展望一下更強大的功能。
概要設計
兩個文件就實現(xiàn)了全部功能,還要做個概要設計?不好意思,請讓羅孚裝一下[捂臉]。實際上,羅孚在這事情上確實走了彎路。
實現(xiàn)框架
羅孚最開始考慮的實現(xiàn)方案,超級簡單,簡單到甚至不需要寫代碼和制作數(shù)據(jù)文件。
不管是高德、百度還是騰訊,都提供了地圖數(shù)據(jù)管理方案,高德的云圖、百度地圖的LBS云、騰訊地圖的地點云,直接使用他們的云存儲,然后在地圖上添加一個自定義云圖層或者通過數(shù)據(jù)檢索API取出數(shù)據(jù)后marker到地圖就行了。
云數(shù)據(jù)方案是好的,但羅孚使用下來,竟然都不好用,要么無法在地圖上顯示,要么API接口不返回數(shù)據(jù),只能說羅孚作為一個非專業(yè)開發(fā)人員,確實太菜了一些。當然,也要批評一下高德,地圖如果是3D模式時,無法使用云地圖圖層,這一信息是在某一文檔的一行小字中找到的,擦,這坑挖的夠深。
自建數(shù)據(jù)庫成了唯一的選擇。
不過,為了讓方案簡單易復制,使用MySQL似乎重了一點,要不使用sqlite吧。但一想到要寫數(shù)據(jù)庫的增刪改查,又增加了不少麻煩,為了快速實現(xiàn),直接將最終數(shù)據(jù)做成了json文本,數(shù)據(jù)庫的操作,以后再考慮吧。
大言不慚的說,最后的實現(xiàn)框架是:json+js。嗯,兩個文件,一個json數(shù)據(jù)文件,一個js文件(寫在html文件里了)。[憨笑]
數(shù)據(jù)的定義和來源
對于地圖數(shù)據(jù),必須的字段可能有:
名稱
經(jīng)度
緯度
地址(可選)
對于疫情,可能的字段有:
次數(shù) (有些省市會提供這個地址發(fā)生的次數(shù))
類型 (可以細分為小區(qū)、商場等)
時間 (發(fā)現(xiàn)時間)
來源 (數(shù)據(jù)源來自哪里)
呃,考慮的是不是有點復雜?羅孚實際上也沒有用這么多數(shù)據(jù)內(nèi)容,數(shù)據(jù)字段越多,內(nèi)容越豐富,實現(xiàn)難度也就越大,作為一個DEMO,就只考慮必須的名稱(實際是用地址代替的)和經(jīng)緯度吧。
定義完字段,就要制作數(shù)據(jù)了,這些點位數(shù)據(jù)怎么來呢?逃不出兩種方式:
自己收集和標注
扒別人的位置數(shù)據(jù)
羅孚的初衷是想自己收集和標注,自力更生是我國人民的傳統(tǒng)美德,但本人懶癌嚴重,所以最后也是取了個巧,扒了份別人的數(shù)據(jù)(僅使用了上海部分啊,其他城市的沒要)。
當然,如何扒其他平臺的數(shù)據(jù),似乎又可以寫一篇文章,考慮同本教程有較大出入,加上這見不得人的伎倆,以后再說吧。
地圖平臺的選擇
確定好框架,定義好數(shù)據(jù),可以開始開發(fā)了,但由于和地圖相關,在此多討論一下地圖平臺的問題。
一般來說,使用商業(yè)公司成熟的地圖API是最佳選擇:
高德和百度地圖的API:推薦。畢竟是國內(nèi)不分伯仲的頂尖API。
騰訊地圖API:可用??赡芸梢运銍鴥?nèi)老三,但用的人真少,看在微信、小程序都是鵝廠的產(chǎn)品,也是值得考慮的,看了下API,也基本能用。
mapbox API:可用,有難度。mapbox是開源地圖解決方案公司,屬于國際頂尖(在地圖上甚至比Google還強大哦),現(xiàn)在正在大力發(fā)展國內(nèi)市場,此次制作的疫情地圖也超級漂亮(欣賞一下)。
Google maps API:不能用。雖然國際頂尖(地圖API鼻祖),但不能用的道理,你懂得。(有興趣的可以了解一下我十年前拆解的Google Maps API v3離線開發(fā)包)
除了商業(yè)公司的方案,當然也可以使用開源方案,比如leaflet。我看到天地圖上海做的地方疫情地圖就是用了leaflet。開源方案主要是功能框架,但地圖底圖數(shù)據(jù),要么用商業(yè)公司的,要么就還是自己扒了(羅孚也扒過:Google Maps瓦片(tile)地圖文件下載(1-11層級),今年過年太無聊,又扒了更多更細的數(shù)據(jù)[捂臉])。
地圖平臺的探討,真可以再寫幾篇文章,對于本文的地圖平臺,最終選擇了高德,主要原因是站在別人肩膀上的選擇。百度地圖API雖然我想用,但考慮到百度地圖坐標是在GCJ02坐標系下又做了一次加密,想到后續(xù)的數(shù)據(jù)坐標混亂,還是罷了罷了。
詳細設計(功能實現(xiàn))
繼續(xù)大言不慚的說說功能實現(xiàn)的詳細設計吧,我們針對每一項功能做詳細的介紹以及實現(xiàn)上的注意事項,順便把我參考的地圖示例貼出來供大家參考。
地圖顯示
地圖顯示是最基本的功能,有一些地方需要注意,談談我在地圖上的一些考慮。
考慮到是地方地圖,那么全國地圖、世界地圖層級就不要顯示啦,所以我把地圖層級設置在了10-18之間。
既然是專題地圖,那么雜項就不要顯示了,比如室內(nèi)地圖、地圖上的熱點等,都設置為false吧。
而地圖的風格,normal的色調(diào)太亮,換一個官方的遠山黛whitesmoke主題吧。
參考示例:
地圖創(chuàng)建: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/map
添加疫情場所marker并彈出氣泡框
這一步算是本地圖DEMO的最核心功能了,雖說比較簡單,就是遍歷json,然后批量添加marker到地圖就可以了,但這里遇到了一個坑,在marker上綁定click事件后,竟然click任何一個marker,都是響應最后一個marker的氣泡框。
調(diào)整半天、搜索半天都沒能解決,羅孚差點想把整個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
InfoWindow 類:https://lbs.amap.com/api/javascript-api/reference/infowindow
添加自定位功能
此功能是顯示自己的位置,如果定位成功,則基于自身位置顯示半徑為1公里和3公里的圈,以了解附近范圍內(nèi)大概有多少疫情場所marker。
需要注意,本處使用的是AMap.Geolocation,是高德地圖API的定位插件。
定位的一些細節(jié)邏輯:當定位成功后,原則上是需要將地圖的中心點移動到定位位置的。但如果定位信息中的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
添加查詢功能
可以查看自身位置信息了解自身周邊的疫情情況,那么想看看某一小區(qū)或商場附近的疫情情況是否可以實現(xiàn)呢?這就需要用到查詢功能了。
這里我們使用高德的AMap.Autocomplete,是輸入提示插件,雖然不是地點搜索,但已經(jīng)足夠用了,能出現(xiàn)在提示中的結果都是搜索頻率較高的結果,同時這個插件的使用也超級簡單,輸入綁定到某一輸入框,比如id為search的input,結果綁定到某一div,比如id為result的div,功能就實現(xiàn)了,你只要輸入內(nèi)容,result中就出現(xiàn)結果了(簡單到讓羅孚瞠目結舌)。
完成上述操作,結果內(nèi)容是無法選擇的,好在插件提供了返回結果功能,在AMap中設置一個監(jiān)聽事件,選擇某一結果后就可以得到該結果的詳細信息,我主要是取經(jīng)緯度信息,然后在地圖上顯示一個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中使用的數(shù)據(jù),總量100+,不算很多,但若數(shù)據(jù)量達到1000+,那么加載的時間順序就顯得尤為重要,所以我們在地圖加載完成(使用map.on 'complete')后,再去加載json數(shù)據(jù)。
這樣做的優(yōu)勢:先讓地圖顯示,然后看到地圖上出現(xiàn)marker,避免地圖長時間等待加載,畢竟用戶的耐心是有限的。
關于事件,由于主要是針對地圖或覆蓋物類,所以使用這些類的on成員方法實現(xiàn)對事件的綁定。比如上面加載json數(shù)據(jù)是綁定在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/
延伸思考
產(chǎn)品思考
本文真的僅僅是一個DEMO,還有甚多的功能未能實現(xiàn):
數(shù)據(jù)管理后臺
直接使用json文本作為數(shù)據(jù)源,無法增刪改查確實是一個缺憾,需要多數(shù)據(jù)做一個管理,可以查詢地圖數(shù)據(jù)、添加數(shù)據(jù)、修改數(shù)據(jù),這個功能下也包含了不少的小功能。
更多地圖顯示方式
僅僅顯示marker,顯示方法太粗糙,marker按理是在詳圖層級(比如16級及以上)才顯示的內(nèi)容,可以考慮引入聚合圖和熱力圖。
比如10到12層級,可以考慮按照地區(qū)對疫情場所數(shù)據(jù)進行聚合顯示,按地區(qū)顯示每一區(qū)域總量總量的marker。
比如13到15層級,可以考慮顯示熱力圖,因為在此層級下查看疫情出現(xiàn)的熱度可能反而更直觀一些。
計算距離和提醒
在當前位置或查詢結果數(shù)據(jù)上,顯示距離最近的疫情場所和距離信息,以讓自身了解危險的程度。
引入其他地圖API
使用高德地圖API,雖然實現(xiàn)了此DEMO,但畢竟有自身的局限性,綁定在了此平臺上,可以考慮使用同一份數(shù)據(jù)制作基于百度地圖API、騰訊地圖API以及l(fā)eaflet庫的地圖。
還有很多很多,無法一一敘述,后續(xù)可以考慮寫一篇疫情地圖功能對比的文章,看看別人在產(chǎn)品制作上的優(yōu)劣。
開發(fā)思考
不是開發(fā)人員,但用代碼堆起了這個DEMO,那么也說說在開發(fā)上的思考吧。
不要重復造輪子
站在巨人肩膀上,用成熟的API,其實挺好的。
有時候你的目標是實現(xiàn)功能,而不是創(chuàng)造一個有競爭力的平臺,那么你就沒有必要思考自己開發(fā)一個平臺,甚至連選擇哪個平臺都不需要太多的顧慮。
專業(yè)的人做專業(yè)的事
羅孚本人不是程序猿,也應該有10年以上沒有碰過代碼了,這次做個DEMO都費了老半天的勁,只能感慨專業(yè)的事還是由專業(yè)的人來做吧。
不過上面產(chǎn)品思考的功能開發(fā),如果在屏幕前的你,有興趣幫助完成,那也歡迎聯(lián)系我。不管是互相學習交流,還是互相幫助提升,羅孚都愿意,畢竟羅孚也是熱心腸嘛[憨笑]。
福利時間
本文太啰嗦,一篇技術文章寫成了記敘文,羅孚自身也在感慨,看來以后可以考慮做成PPT或視頻的形式,要么更簡單明了,要么更詳細清晰。
本文標題和開篇均提到了源碼和數(shù)據(jù),如果是懂技術的你,應該是不屑的,或者Ctrl+U一下就拿到了(加密版本)。如果確實需要下載,可以在“羅孚傳說”公眾號上回復“疫情場所地圖”即可(未加密版本)。如果需要帶詳細注釋的文件來研究,請加入羅孚的知識星球來?。◣ё⑨尠姹荆?,當然還可以附送超詳細瓦片地圖離線文件哦,后續(xù)也有更多內(nèi)容分享。
好了,用地圖API制作一份疫情場所分布地圖,今天,你會了嗎?歡迎聯(lián)系羅孚,歡迎關注羅孚的公眾號(羅孚傳說)做更多交流,更歡迎加入羅孚的知識星球贊助羅孚獲得更多有價值內(nèi)容,我們下一篇文章中見。
總結
以上是生活随笔為你收集整理的如何制作一份疫情场所分布地图?(附数据和源码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 泡温泉注意事项(泡温泉有哪些注意事项?)
- 下一篇: 混合痔的症状(混合痔是怎么回事?)