根據(jù)經(jīng)緯度坐標(biāo)獲得省市區(qū)縣行政區(qū)劃城市名稱,自建數(shù)據(jù)庫(kù) java python php c# .net 均適用

在LBS應(yīng)用中,根據(jù)坐標(biāo)來(lái)解析獲得對(duì)應(yīng)是哪個(gè)城市是一個(gè)很常見(jiàn)的功能,比如App里面通過(guò)手機(jī)定位自動(dòng)選擇城市;本文介紹的是通過(guò)自己建的數(shù)據(jù)庫(kù),利用SQL空間查詢來(lái)進(jìn)行坐標(biāo)解析得到對(duì)應(yīng)的省市區(qū),絕大部分支持空間數(shù)據(jù)類型(Spatial)的數(shù)據(jù)庫(kù)均支持,包括但不限于:MySQL、SQL ServerOracle、PostgreSQL等;開(kāi)發(fā)語(yǔ)言不限,只要能進(jìn)行數(shù)據(jù)庫(kù)查詢就都支持,用Java、Python、PHP、C#均能很簡(jiǎn)單的實(shí)現(xiàn)。

省市區(qū)邊界數(shù)據(jù)在線預(yù)覽、下載:https://xiangyuecn.gitee.io/areacity-jsspider-statsgov/
GitHub地址:https://github.com/xiangyuecn/AreaCity-JsSpider-StatsGov

通過(guò)坐標(biāo)來(lái)獲取地址:百度地圖提供的接口叫 “地址逆解析”,高德地圖提供的接口叫 “地理逆編碼”,它們開(kāi)放平臺(tái)均提供了前后端接口,發(fā)個(gè)http請(qǐng)求就可以拿到數(shù)據(jù),相關(guān)的接口調(diào)用請(qǐng)自行閱讀平臺(tái)開(kāi)發(fā)文檔,使用起來(lái)很方便。

當(dāng)然這篇文章不會(huì)去介紹怎么搞街道門牌號(hào)這些完整地址,也不講怎么樣調(diào)用人家的接口,只介紹坐標(biāo)對(duì)應(yīng)的省市區(qū)名稱的獲取,自建數(shù)據(jù)庫(kù)寫SQL進(jìn)行空間查詢,完全自己實(shí)現(xiàn),比調(diào)開(kāi)放平臺(tái)接口相對(duì)會(huì)復(fù)雜些。

由于全國(guó)區(qū)縣每年都會(huì)有比較多的變更,所以省市區(qū)邊界數(shù)據(jù)需要經(jīng)常去同步維護(hù),好在這上面這個(gè)開(kāi)源庫(kù)有在持續(xù)的長(zhǎng)期維護(hù),新數(shù)據(jù)發(fā)布后更新相對(duì)容易很多。由于開(kāi)源庫(kù)更新維護(hù)數(shù)據(jù)比較及時(shí),所以只要開(kāi)源庫(kù)沒(méi)有被關(guān)閉,本文介紹的提取方法就一直適用; 比那些上傳到下載平臺(tái)就萬(wàn)年不更新的數(shù)據(jù)優(yōu)秀很多。

查詢效果展示:

數(shù)據(jù)庫(kù)查詢效果

從這里隨便拿的一個(gè)坐標(biāo):

坐標(biāo)位置

直觀的效果如上圖,在百度地圖里面隨便點(diǎn)選一下(或App定位獲得的坐標(biāo))得到一個(gè)坐標(biāo),然后到數(shù)據(jù)庫(kù)里面利用空間查詢SQL就能查詢到坐標(biāo)所在的城市。

步驟一、下載省市區(qū)邊界數(shù)據(jù)

到開(kāi)源庫(kù)里面下載最新的 ok_geo.csv.7z 文件(13M大小,解壓130M+),點(diǎn)此下載。下載好后解壓得到 ok_geo.csv,此文件內(nèi)包含了最新全國(guó)所有的省市區(qū)縣坐標(biāo)邊界矢量數(shù)據(jù)。

注:這個(gè)文件只包含三級(jí)(省市區(qū))數(shù)據(jù)不含第四級(jí)(鄉(xiāng)鎮(zhèn)街道),如需鄉(xiāng)鎮(zhèn)坐標(biāo)邊界數(shù)據(jù),可以請(qǐng)點(diǎn)此下載 ok_geo4_*.csv 文件(90MB+壓縮包 導(dǎo)出后300M+)。

步驟二、解析CSV文件導(dǎo)入數(shù)據(jù)庫(kù)

下載好的文件 ok_geo.csv 是純文本文件,可以自行編寫腳本進(jìn)行解析,然后導(dǎo)進(jìn)數(shù)據(jù)庫(kù)中,自行解析處理比較復(fù)雜,請(qǐng)參考開(kāi)源庫(kù)內(nèi)文檔;開(kāi)源庫(kù)內(nèi)提供了一個(gè)格式轉(zhuǎn)換工具,此工具支持將CSV數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù),因此我們直接在下載數(shù)據(jù)時(shí)順帶把工具下載好,點(diǎn)此下載

此轉(zhuǎn)換工具除了支持將 ok_geo.csv 導(dǎo)入數(shù)據(jù)庫(kù)外,還支持導(dǎo)出:sql、shpgeojson,和坐標(biāo)系轉(zhuǎn)換;還可執(zhí)行自定義 JavaScript 腳本,擴(kuò)展出豐富功能;軟件是Windows版,如果需要在MacOs中用,可以用虛擬機(jī)。

導(dǎo)入操作

轉(zhuǎn)換工具執(zhí)行導(dǎo)入數(shù)據(jù)庫(kù)操作:

  1. 點(diǎn)擊 選擇ok_geo.csv文件 按鈕,選擇解壓出來(lái)的CSV文件;
  2. 數(shù)據(jù)庫(kù)設(shè)置中選擇要導(dǎo)入的數(shù)據(jù)庫(kù)類型,這里選的是MySQL,再填寫數(shù)據(jù)庫(kù)連接,包括:端口、數(shù)據(jù)庫(kù)名稱、賬號(hào)密碼;
  3. 點(diǎn)擊導(dǎo)入數(shù)據(jù)庫(kù)按鈕,等待一會(huì),大約3分鐘左右,所有數(shù)據(jù)就都導(dǎo)入到了數(shù)據(jù)庫(kù)按今天日期新建的表里面。

注:csv文件內(nèi)的邊界數(shù)據(jù)默認(rèn)是高德地圖GCJ-02火星坐標(biāo)系,如果需要其他坐標(biāo)系,比如百度的BD-09或GPS的WGS-84,可以通過(guò)高級(jí)腳本中的坐標(biāo)系轉(zhuǎn)換插件進(jìn)行轉(zhuǎn)換,選擇好對(duì)應(yīng)的插件后,點(diǎn)擊應(yīng)用就可以了,在導(dǎo)入數(shù)據(jù)庫(kù)時(shí)會(huì)自動(dòng)進(jìn)行坐標(biāo)系轉(zhuǎn)換。

注:這個(gè)工具限制每次操作只可導(dǎo)出一個(gè)城市和它的下一級(jí)數(shù)據(jù),導(dǎo)出少量數(shù)據(jù)還是很輕松的,所以我們可以多操作幾次,將需要的城市數(shù)據(jù)全部導(dǎo)入數(shù)據(jù)庫(kù);比如要深圳的所有區(qū)縣數(shù)據(jù):第一遍導(dǎo)入全國(guó)所有的省,第二遍在城市名前綴中填寫廣東省(結(jié)尾帶一個(gè)空格)導(dǎo)入廣東所有的市,第三遍在城市名前綴中填寫廣東省 深圳市(結(jié)尾帶一個(gè)空格)導(dǎo)入深圳所有的區(qū)。如果在密鑰輸入框中填寫了密鑰,此工具就沒(méi)有這些限制了,開(kāi)源庫(kù)里面會(huì)不定期發(fā)放密鑰搞福利,點(diǎn)擊一次操作即可導(dǎo)出全國(guó)所有的省市區(qū)三級(jí)數(shù)據(jù)。

表結(jié)構(gòu)和空間字段(MySQL版,其他數(shù)據(jù)庫(kù)類似):

CREATE TABLE Areacity_Geo_20220216 (
  id int NOT NULL, --城市id
  pid int NOT NULL, --上級(jí)城市id
  deep int NOT NULL, --層級(jí):0省、1市、2區(qū)
  name varchar(250) NOT NULL, --城市名稱:`深圳市`
  ext_path varchar(255) NOT NULL, --省市區(qū)三級(jí)完整名稱:廣東省 深圳市 羅湖區(qū)
  geo geometry NOT NULL, --城市中心坐標(biāo),空間數(shù)據(jù)格式
                --,ST_AsText轉(zhuǎn)成WKT文本后:`POINT EMPTY`、`POINT (123.456 34.567)`
  polygon geometry NOT NULL --城市邊界范圍圖形,空間數(shù)據(jù)格式
                --,ST_AsText轉(zhuǎn)成WKT文本后:`POLYGON EMPTY`、`POLYGON ((123.456 34.567,...))`、`MULTIPOLYGON (((123.456 34.567,...)),...)`
)

對(duì)空間字段的查詢,需要用`ST_AsText()`方法才能查詢出字符串文本(WKT: Well Known Text),否則查詢出來(lái)的是二進(jìn)制數(shù)據(jù)
-- MySQL版:
SELECT id, name, ST_AsText(geo) AS geo, ST_AsText(polygon) AS polygon FROM 表名
-- SQL Server版:
SELECT id, name, geo.STAsText() AS geo, polygon.STAsText() AS polygon FROM 表名

步驟三、在程序中根據(jù)坐標(biāo)解析獲得城市

省市區(qū)邊界導(dǎo)入到了數(shù)據(jù)庫(kù)后,我們就可以在在 JavaPython、PHP、C# 等程序中對(duì)數(shù)據(jù)庫(kù)進(jìn)行查詢,通過(guò)SQL的空間計(jì)算函數(shù)ST_Intersects來(lái)查詢一個(gè)坐標(biāo)在哪些邊界范圍內(nèi),就能得到對(duì)應(yīng)的省市區(qū)信息了。

空間查詢SQL語(yǔ)句

比如要查詢坐標(biāo)`lng:113.929976 lat:22.529497`是在哪個(gè)城市
-- MySQL版:
SELECT id,deep,name FROM 表名 WHERE ST_Intersects(polygon, ST_GeomFromText('POINT(113.929976 22.529497)',0))=1
-- SQL Server版:
SELECT id,deep,name FROM 表名 WHERE polygon.STIntersects(geometry::STGeomFromText('POINT(113.929976 22.529497)',0))=1

查詢結(jié)果例子(MySQL版,其他數(shù)據(jù)庫(kù)類似)

MySQL查詢效果

程序代碼連接上數(shù)據(jù)庫(kù),通過(guò)以上SQL查詢到數(shù)據(jù)庫(kù)數(shù)據(jù)后,就獲得了省市區(qū)信息,可以通過(guò)deep字段來(lái)區(qū)分哪條數(shù)據(jù)是省(deep=0)、市(deep=1)、區(qū)縣(deep=2)

通過(guò)以上三步,我們就完全是自己實(shí)現(xiàn)了根據(jù)經(jīng)緯度坐標(biāo)來(lái)解析獲得對(duì)應(yīng)是哪個(gè)城市這一功能。

【END】

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容