根据经纬度坐标获得省市区县⾏政区划城市名称,⾃建数据库
javapythonphpc#均适⽤
⽂章⽬录
在LBS应⽤中,根据坐标来解析获得对应是哪个城市是⼀个很常见的功能,⽐如App⾥⾯通过⼿机定位⾃动选择城市;本⽂介绍的是通过⾃⼰建的数据库,利⽤SQL空间查询来进⾏坐标解析得到对应的省市区,绝⼤部分⽀持空间数据类型(Spatial)的数据库均⽀持,包括但不限于:MySQL、SQL Server、Oracle、PostgreSQL等;开发语⾔不限,只要能进⾏数据库查询就都⽀持,⽤Java、Python、PHP、C#均能很简单的实现。
通过坐标来获取地址:百度地图提供的接⼝叫 “”,⾼德地图提供的接⼝叫 “”,它们开放平台均提供了前后端接⼝,发个http请求就可以拿到数据,相关的接⼝调⽤请⾃⾏阅读平台开发⽂档,使⽤起来很⽅便。
当然这篇⽂章不会去介绍怎么搞街道门牌号这些完整地址,也不讲怎么样调⽤⼈家的接⼝,只介绍坐标对应的省市区名称的获取,⾃建数据库写SQL进⾏空间查询,完全⾃⼰实现,⽐调开放平台接⼝相对会复杂些。
由于全国区县每年都会有⽐较多的变更,所以省市区边界数据需要经常去同步维护,好在这上⾯这个开源
库有在持续的长期维护,新数据发布后更新相对容易很多。由于开源库更新维护数据⽐较及时,所以只要开源库没有被关闭,本⽂介绍的提取⽅法就⼀直适⽤;
⽐那些上传到下载平台就万年不更新的数据优秀很多。
查询效果展⽰:
从这⾥随便拿的⼀个坐标:
直观的效果如上图,在百度地图⾥⾯随便点选⼀下(或App定位获得的坐标)得到⼀个坐标,然后到数据库⾥⾯利⽤空间查询SQL就能查询到坐标所在的城市。
步骤⼀、下载省市区边界数据
到开源库⾥⾯下载最新的 ok_geo.csv.7z ⽂件(13M⼤⼩,解压130M+),。下载好后解压得到 ok_geo.csv,此⽂件内包含了最新全国所有的省市区县坐标边界⽮量数据。
注:这个⽂件只包含三级(省市区)数据不含第四级(乡镇街道),如需乡镇坐标边界数据,可以请 ok_geo4_*.csv ⽂件(90MB+压缩包 导出后300M+)。
步骤⼆、解析CSV⽂件导⼊数据库
下载好的⽂件 ok_geo.csv 是纯⽂本⽂件,可以⾃⾏编写脚本进⾏解析,然后导进数据库中,⾃⾏解析处理⽐较复杂,请参考开源库内⽂档;开源库内提供了⼀个格式转换⼯具,此⼯具⽀持将CSV数据导⼊数据库,因此我们直接在下载数据时顺带把⼯具下载好,。
此转换⼯具除了⽀持将 ok_geo.csv 导⼊数据库外,还⽀持导出:sql、shp、geojson,和坐标系转换;还可执⾏⾃定义 JavaScript 脚本,扩展出丰富功能;软件是Windows版,如果需要在MacOs中⽤,可以⽤虚拟机。
转换⼯具执⾏导⼊数据库操作:
1. 点击 选择ok_geo.csv⽂件 按钮,选择解压出来的CSV⽂件;
2. 数据库设置中选择要导⼊的数据库类型,这⾥选的是MySQL,再填写数据库连接,包括:端⼝、数据库名称、账号密码;
3. 点击导⼊数据库按钮,等待⼀会,⼤约3分钟左右,所有数据就都导⼊到了数据库按今天⽇期新建的表⾥⾯。
注:csv⽂件内的边界数据默认是⾼德地图GCJ-02⽕星坐标系,如果需要其他坐标系,⽐如百度的BD-09或GPS的WGS-84,可以通过⾼级脚本中的坐标系转换插件进⾏转换,选择好对应的插件后,点击应⽤就可以了,在导⼊数据库时会⾃动进⾏坐标系转换。
注:这个⼯具限制每次操作只可导出⼀个城市和它的下⼀级数据,导出少量数据还是很轻松的,所以我们可以多操作⼏次,将需要的城市数据全部导⼊数据库;⽐如要深圳的所有区县数据:第⼀遍导⼊全国所有的省,第⼆遍在城市名前缀中填写⼴东省(结尾带⼀个空格)导⼊⼴东所有的市,第三遍在城市名前缀中填写⼴东省深圳市(结尾带⼀个空格)导⼊深圳所有的区。如果在密钥输⼊框中填写了密钥,此⼯具就没有这些限制了,开源库⾥⾯会不定期发放密钥搞福利,点击⼀次操作即可导出全国所有的省市区三级数据。
表结构和空间字段(MySQL版,其他数据库类似):
CREATE TABLE Areacity_Geo_20220216 (
id int NOT NULL,--城市id
pid int NOT NULL,--上级城市id
deep int NOT NULL,--层级:0省、1市、2区
name varchar(250)NOT NULL,--城市名称:`深圳市`
ext_path varchar(255)NOT NULL,--省市区三级完整名称:⼴东省深圳市罗湖区
geo geometry NOT NULL,--城市中⼼坐标,空间数据格式
--,ST_AsText转成WKT⽂本后:`POINT EMPTY`、`POINT (123.456 34.567)`
polygon geometry NOT NULL--城市边界范围图形,空间数据格式
--,ST_AsText转成WKT⽂本后:`POLYGON EMPTY`、`POLYGON ((123.456 34.567,...))`、`MULTIPOLYGON (((123.456 34.567,...)),...)`
)
对空间字段的查询,需要⽤`ST_AsText()`⽅法才能查询出字符串⽂本(WKT: Well Known Text),否则查询出来的是⼆进制数据
-- 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表名
步骤三、在程序中根据坐标解析获得城市
省市区边界导⼊到了数据库后,我们就可以在在 Java、Python、PHP、C# 等程序中对数据库进⾏查询,通过SQL的空间计算函
数ST_Intersects来查询⼀个坐标在哪些边界范围内,就能得到对应的省市区信息了。
空间查询SQL语句
⽐如要查询坐标`lng:113.929976 lat:22.529497`是在哪个城市
-- 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
查询结果例⼦(MySQL版,其他数据库类似)
程序代码连接上数据库,通过以上SQL查询到数据库数据后,就获得了省市区信息,可以通过deep字段来区分哪条数据是省(deep=0)、市(deep=1)、区县(deep=2)。
国外java php通过以上三步,我们就完全是⾃⼰实现了根据经纬度坐标来解析获得对应是哪个城市这⼀功能。
【END】
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论