姐妹篇:利用GeoHash实现逆地理编码(经纬度坐标转换行政区划)
MySQL从4.x版本开始就对GIS(Geographic Information System)的数据类型进行支持,并且也有对应的空间索引;MBR(Minimum Bounding Rectangle)相关算法也是地图服务常见问题的一个解决方案。同姐妹篇利用GeoHash实现逆地理编码一样,本篇文章主要介绍,如何通过MBR和mysql的GIS数据类型实现逆地理编码,同样精确度也只能达到**区/县**级行政区划解析结果。
MBR全称是Minimum Bounding Rectangle,直译就是最小边界矩形。通常是指,针对一个不规则二维图形的边界,绘制出其最小的边界矩形;并且依托这个矩形产生了一系列算法。
MBR的计算方式非常简单,将一系列边界点进行遍历,获取这一系列边界点【最大经度】【最小经度】【最大纬度】【最小纬度】。那么构成这个MBR图形的四个坐标点应分别为:
坐标位置经度纬度西南点【最小经度】【最小纬度】西北点【最小经度】【最大纬度】东北点【最大经度】【最大纬度】东南点【最大经度】【最小纬度】在线绘制地址围栏 以江苏省(以最大polygon数据为主,去除其他岛屿等独立polygon数据,数据来源高德,再次感谢高德)示例,其为不规则图形,在地图中绘制效果如下: 遍历所有边界点,计算得到其最大最小经纬度分别为:
名称值最大经度121.975185最小经度116.362723最大纬度35.124513最小纬度30.757840对应其MBR四个坐标点分别为:
坐标位置经度纬度西南点116.36272330.757840西北点116.36272335.124513东北点121.97518535.124513东南点121.97518530.757840MBR结果在地图中绘制效果如下: 如图所示,该MBR图形是江苏省行政区划的最小边界外界矩形。
GIS(Geographic Information System)是地图信息系统,mysql 5.6版本及5.6以上版本,提供了地图信息系统相关数据结构的支持。
注意: 1> mysql的GIS相关函数和数据类型在进行压力测试时,即使有空间索引存在,其表现并不好;在并发数较高时,会迅速消耗数据库服务器CPU资源,最终成为整个调用链路的瓶颈,并且无法通过加机器等横向扩展方式解决。 2> mongoDB也存在GIS的支持,并且吞吐量比mysql要高很多,如果是中小型系统,建议选用mongoDB而不是mysql进行GIS相关计算。 3> 最终推荐:GIS相关计算在应用服务器上进行,横向扩展方便。相关算法可选用或参考java awt包中几何图形算法。
mysql提供了基本上可以覆盖所有地理模型的几何数据类型,如下图所示: mysql 8.0版本Geometry数据类型官方文档 比较常用的例如:
Point 点 以x,y平面直角坐标系建立的坐标点Polygon 多边形 以多个坐标点顺序连接构成闭环的2维多边形MultiPolygon 多多边形 多个2维多边形类似省、市、区县的行政区划边界点,可以直接使用MultiPolygon数据类型存储入数据库。
mysql 5.6版本GIS函数官方文档 mysql 8.0版本GIS函数官方文档 简单介绍一下我们使用场景中需要的函数ST_CONTAINS()或者ST_WITHIN(): **ST_CONTAINS()**函数是用于判断某一个二维几何数据结构是否包含另一个二维几何数据结构,返回1代表在包含,返回0代表不包含。(我们使用到的场景是判断一个经纬度坐标点是否在某一行政区划多边形内)**ST_WITHIN()**函数与其表述方式相反,结果相反。
逆地理编码指的是,将经纬度坐标转换为具体的标准的行政区划信息;以高德逆地理编码接口为例,坐标点118.797405,32.044227响应的结果如下:
{ "status": "1", "regeocode": { "addressComponent": { "city": "南京市", "province": "江苏省", "adcode": "320102", "district": "玄武区", "towncode": "320102002000", "streetNumber": { "number": "292号", "location": "118.797317,32.044008", "direction": "南", "distance": "25.7166", "street": "长江路" }, "country": "中国", "township": "梅园新村街道", "citycode": "025" }, "formatted_address": "江苏省南京市玄武区梅园新村街道总统府" }, "info": "OK", "infocode": "10000" }高德逆地理编码接口在线测试 精确度只有三级,同姐妹篇【利用GeoHash实现逆地理编码】
函数:
此篇文章主要是用于记录另一种逆地理编码的实现思路,可优化空间较大。 姐妹篇:利用GeoHash实现逆地理编码
