從區劃邊界geojson中查詢經緯度座標對應的省市區縣鄉鎮名稱,開源Java工具,記憶體佔用低、高效能

xiangyuecn發表於2022-06-30

座標邊界查詢工具:AreaCity-Query-Geometry

本工具核心功能:使用jts庫省市區縣鄉鎮邊界資料AreaCity-JsSpider-StatsGov開源庫)或geojson邊界資料檔案中查詢出和任意點、線、面有相交的向量邊界,記憶體佔用低,效能優良。

GitHub地址:https://github.com/xiangyuecn/AreaCity-Query-Geometry
Gitee映象庫:https://gitee.com/xiangyuecn/AreaCity-Query-Geometry

主要特性:

  • 查詢一個座標點對應的城市資訊;
  • 查詢一條路徑經過的所有城市;
  • 查詢一個向量範圍覆蓋的所有城市;
  • 查詢一個城市或下一級所有邊界資料(WKT格式);
  • 支援通過HTTP API服務進行查詢呼叫;
  • 支援通過Java程式碼進行查詢呼叫;
  • 原始碼簡單,包括測試bat指令碼共5個檔案,無需IDE即可修改和執行,copy即用。

可以只copy AreaCityQuery.java 檔案到專案中使用,專案中引入jts庫,就能使用 AreaCityQuery 中的所有查詢功能了。也可以clone整個專案程式碼雙擊 編譯和執行Test.java直接測試.bat 即可直接執行測試。

API和圖形介面:此工具自帶了一個HTTP API服務,執行測試然後通過選單啟動此服務,然後就可以直接在瀏覽器上訪問這些介面;此API介面可以直接在 ECharts Map四級下鑽線上測試和預覽 頁面的自定義資料來源中進行呼叫測試,頁面會立即繪製查詢出來的邊界圖形。

效果圖:

HTTP API圖形介面:
HTTP API圖形介面

控制檯執行:
控制檯執行

效能測試資料

測試資料來源:AreaCity-JsSpider-StatsGov開源庫2021.220321.220428版本下載的ok_geo.csv檔案按省市區匯出成不同的geojson檔案。

測試採用開啟多執行緒進行隨機座標點的查詢(Test.java控制檯5號選單),測試機器配置:8核 2.20GHz CPU,SSD 硬碟。

測試一:Init_StoreInWkbsFile 記憶體佔用很低(效能受IO限制)

資料來源 檔案大小 資料量 記憶體佔用 7核QPS 單核QPS 單次查詢耗時
省市區三級 176MB 3632條 41MB 6212 887 1.13ms
僅區級 107MB 3208條 24MB 13818 1974 0.51ms
僅省級 20MB 34條 4MB 19832 2833 0.35ms

Init_StoreInWkbsFile:用載入資料到結構化資料檔案的模式進行初始化,推薦使用本方法初始化,邊界圖形資料存入結構化資料檔案中,記憶體佔用很低,查詢時會反覆讀取檔案對應內容,查詢效能消耗主要在IO上,IO效能極高問題不大。

測試二:Init_StoreInMemory 記憶體佔用和json檔案差不多大(效能豪放)

資料來源 檔案大小 資料量 記憶體佔用 7核QPS 單核QPS 單次查詢耗時
省市區三級 176MB 3632條 161MB 77242 11034 0.091ms
僅區級 107MB 3208條 96MB 121228 17318 0.058ms
僅省級 20MB 34條 18MB 465940 66562 0.015ms

Init_StoreInMemory:用載入資料到記憶體的模式進行初始化,邊界圖形資料存入記憶體中,記憶體佔用和json資料檔案大小差不多大,查詢效能極高;另外可通過設定 AreaCityQuery.SetInitStoreInMemoryUseObject=true 來進一步提升效能,但記憶體佔用會增大一倍多,省市區三級單核可達到 15000 QPS。

參考:資料庫查詢測試對比

資料來源 資料量 查詢座標 MySQL單次查詢耗時 SQL Server單次查詢耗時
省市區三級 3632條 深圳-龍華區 163ms 25ms
省市區三級 3632條 北京-房山區 173ms 47ms

資料庫查詢座標點:POINT(114.044346 22.691963) 深圳市 龍華區;POINT(116.055588 39.709385) 北京市 房山區(查詢受內蒙envelope干擾影響效能)

查詢座標對應的省市區縣鄉鎮名稱

使用此工具進行座標省市區縣鄉鎮查詢,先要準備一個省市區縣鄉鎮的邊界geojson資料檔案。

資料中有哪一級的邊界就能查詢出哪一級的名稱;比如你只有區級的資料,那麼給一個座標就能查詢出此座標所在的區縣名稱(需另外查詢出上級的省市名稱);如果有省市區三級的邊界,那一次性就能查詢出省市區三級的名稱,如果有鄉鎮的邊界,就能查詢出鄉鎮這級的名稱。

步驟一:準備好省市區縣鄉鎮邊界的geojson檔案

如果你沒有邊界json檔案,可以按以下步驟獲得最新的全國省市區縣鄉鎮邊界資料json檔案:

  1. 到開源庫下載省市區邊界資料ok_geo.csv檔案: https://github.com/xiangyuecn/AreaCity-JsSpider-StatsGov (github可換成gitee);
  2. 下載開源庫裡面的AreaCity-Geo格式轉換工具軟體
  3. 開啟轉換工具軟體,選擇ok_geo.csv,然後匯出成geojson檔案即可(預設會匯出全國的省級資料,通過填寫不同城市名字首可以匯出不同城市)。

如果你有多個geojson檔案,需要合併成一個才行,可以通過上面下載的 AreaCity-Geo格式轉換工具軟體 中的 高階功能-GeoJSON多個檔案合併成一個檔案 來合併。

步驟二:執行測試程式進行初始化

雙擊 編譯和執行Test.java直接測試.bat 執行測試控制檯程式;根據控制檯選單命令進行初始化,有兩種初始化方式,隨便哪種都行:

  1. Init_StoreInWkbsFile:記憶體佔用很低,但查詢速度相對StoreInMemory慢很多,但也很快的,推薦用此方法初始化;
  2. Init_StoreInMemory:記憶體佔用大一點,但查詢速度非常快。

選擇了初始方式後會要求填寫geojson檔案路徑,填寫上一步準備好的json檔案完整路徑即可;或者直接將json檔案放到程式根目錄,會自動初始化。

步驟三:查詢座標獲得省市區名稱

初始化完成後,所有的選單都可以使用了,可以直接在控制檯中使用對應的選單進入選單查詢功能,然後輸入座標查詢即可。

建議使用HTTP API來進行查詢,在選單中啟動好HTTP服務後,就能通過網址訪問查詢介面,或者直接使用線上的視覺化介面進行查詢操作:

座標查詢視覺化效果

附:通過Java程式碼進行查詢

//先初始化,全域性只會初始化一次,每次查詢前都呼叫即可(查詢會在初始化完成後進行),兩種初始化方式根據自己業務情況二選一
//首次初始化會從.json或.geojson檔案中讀取邊界圖形資料,速度比較慢,會自動生成.wkbs結尾的結構化檔案,下次初始化就很快了
AreaCityQuery.Init_StoreInWkbsFile("geojson檔案路徑", "geojson檔案路徑.wkbs", true);
//AreaCityQuery.Init_StoreInMemory("geojson檔案路徑", "geojson檔案路徑.wkbs", true);

//AreaCityQuery.OnInitProgress=(initInfo)->{ ... } //初始化過程中的回撥,可以繫結一個函式,接收初始化進度資訊

//查詢包含一個座標點的所有邊界圖形的屬性資料,可通過res引數讓查詢額外返回wkt格式邊界資料
QueryResult res1=AreaCityQuery.QueryPoint(114.044346, 22.691963, null, null);

//查詢和一個圖形(點、線、面)有交點的所有邊界圖形的屬性資料,可通過res引數讓查詢額外返回wkt格式邊界資料
Geometry geom=new WKTReader(AreaCityQuery.Factory).read("LINESTRING(114.233963 30.546038, 114.468109 30.544264)");
QueryResult res2=AreaCityQuery.QueryGeometry(geom, null, null);

//讀取省市區的邊界資料wkt格式,這個例子會篩選出武漢市所有區縣
QueryResult res3=AreaCityQuery.ReadWKT_FromWkbsFile("wkt_polygon", null, (prop)->{return prop.contains("武漢市 ");}, null);


System.out.println(res1+"\n"+res2+"\n"+res3);

【END】

相關文章