MySQL空间数据存储及函数


Posted in MySQL onSeptember 25, 2021

前言:

不久前开发了一个地图相关的后端项目,需要提供一些点线面相关的存储、查询、分析相关的操作,于是对MySQL空间函数进行充分调研并应用在项目中;MySQL为空间数据存储及处理提供了专用的类型geometry(支持所有的空间结构),还有有细分类型Point, LineString, Polygon,MultiPoint,MultiLineString,MultiPolygon等等,我们了解了空间函数,在涉及到经纬度存储,路线存储方面的业务就能够使用此类型进行存储,使用相关空间函数进行分析业务实现,以下所有数据库操作基于MySQL5.7.20

一、数据类型

1.什么是MySQL空间数据

  • MySQL提供了数据类型geometry用来存储坐标信息,geometry类型支持以下三种数据存储
MySQL空间数据存储及函数

还有多点MULTIPOINT(多点)、MULTILINESTRING(多线)、MULTIPOLYGON(多面)、GEOMETRYCOLLECTION(集合,可放入点线面)等类型

2.什么是geojson

GeoJSON是一种对各种地理数据结构进行编码的格式。GeoJSON对象可以表示几何、特征或者特征集合。GeoJSON支持下面几何类型:点、线、面、多点、多线、多面和几何集合。GeoJSON里的特征包含一个几何对象和其他属性,特征集合表示一系列特征。一个完整的GeoJSON数据结构总是一个(JSON术语里的)对象。在GeoJSON里,对象由名/值对--也称作成员的集合组成。对每个成员来说,名字总是字符串。成员的值要么是字符串、数字、对象、数组,要么是下面文本常量中的一个:"true","false"和"null"。数组是由值是上面所说的元素组成

MySQL空间数据存储及函数

除了简单的点、线、面,为了满足复杂的地理环境及地图业务,还会有多点(MultiPoint),多线(MultiLineString),多面(MultiPolygon),几何集合(GeometryCollection)等,熟悉json就可以快速的熟悉并应用geojson

3.格式化空间数据类型(geometry相互转换geojson)

数据库存储的空间数据通过可视化工具展示的明文结构为上面示例中所见,结构并不易于客户端解析,所以MySQL提供了几个空间函数用来解析及格式化空间数据,geojson是gis空间数据展示的标准格式,前端地图框架及后端空间分析相关框架都会支持geojson格式

MySQL空间数据存储及函数

示例:

准备示例数据

MySQL空间数据存储及函数

函数应用示例

1.查询绿藤气象监测点信息将geometry处理成geojson格式

执行sql:

select id,point_name,ST_ASGEOJSON(point_geom) as geojson from meteorological_point where id = 1

查询结果:

MySQL空间数据存储及函数

2.新增一个点位信息,客户端提交的点位geometry字符串需要使用ST_GEOMFROMTEXT函数处理才能插入,否则会报错

客户端提交点位信息

{
    "point_name":"新帅集团监测点",
    "geotext":"POINT(117.420671499 40.194914201)"}
}

错误示例:

insert into meteorological_point(point_name, point_geom) values("新帅集团监测点", "POINT(117.420671499 40.194914201)")
报错 1416 - Cannot get geometry object from data you send to the GEOMETRY field

正确插入sql:

insert into meteorological_point(point_name, point_geom) values("新帅集团监测点", ST_GEOMFROMTEXT("POINT(117.420671499 40.194914201)"))

3.新增点位,客户端提交点位格式为geojson格式,需要使用ST_GeomFromGeoJSON函数处理后进行插入

客户端提交点位信息

{
    "point_name":"民爆公司监测点",
    "geojson":"{"type": "Point", "coordinates": [117.410671499, 40.1549142015]}"}
}

插入SQL

insert into meteorological_point(point_name, point_geom) values("民爆公司监测点", ST_GeomFromGeoJSON("{\"type\": \"Point\", \"coordinates\": [117.410671499, 40.1549142015]}"))

空间数据格式化小结

mysql geometry数据存储需要对geometry文本或geojson进行函数处理后才能进行存储,否则会报错,查询时候使用格式化函数转成geojson方便服务端传输和客户端框架解析

二、空间分析

在上一部分介绍了空间函数存储,查询格式化处理相关的操作,了解空间数据结构及geojson,这一部分介绍空间数据处理函数的应用

1、根据点位及半径,生成缓冲区

MySQL空间数据存储及函数

在地图功能中,缓冲区是非常常见的功能,一来可以查看点线面一定范围类的覆盖区域,二来在一些分析场景中,已知一个位子坐标信息及缓冲半径,生成缓冲区作为查询条件进行地理搜索

SELECT ST_ASGEOJSON(ST_BUFFER(ST_GeomFromGeoJSON('${geojsonStr}'),${radius}))

SQL解读

调用方传来一个geojson字符串及半径(米),使用ST_GeomFromGeoJSONgeojson字符串处理成数据库中的geometry,再使用ST_BUFFER(geometry, 半径)s生成缓冲区空间数据,函数返回的格式也是geometry,所以在外面包一层ST_ASGEOJSON函数将返回结果处理成geojson,便于客户端读取及渲染

示例:

  • 有一个点位的geojson字符串为 "{"type": "Point", "coordinates": [117.410671499, 40.1549142015]}",缓冲半径50米(注意:ST_BUFFER()的参数地理信息及返回值均使用墨卡托坐标系,如非墨卡托坐标系的geojson,需使用工具类进行转换处理)
public class MercatorUtils {
    /**
     * 点位geojson转墨卡托
     *
     * @param point
     * @return
     */
    public static JSONObject point2Mercator(JSONObject point) {
        JSONArray xy = point.getJSONArray(COORDINATES);
        JSONArray mercator = lngLat2Mercator(xy.getDouble(0), xy.getDouble(1));
        point.put(COORDINATES, mercator);
        return point;
    }
    /**
     * 经纬度转墨卡托
     */
    public static JSONArray lngLat2Mercator(double lng, double lat) {
        double x = lng * 20037508.342789 / 180;
        double y = Math.log(Math.tan((90 + lat) * M_PI / 360)) / (M_PI / 180);
        y = y * 20037508.34789 / 180;
        JSONArray xy = new JSONArray();
        xy.add(x);
        xy.add(y);
        return xy;
    }
    
    /**
     * 墨卡托坐标系数据转普通坐标系
     */
    public static JSONObject mercatorPolygon2Lnglat(JSONObject polygon) {
        JSONArray coordinates = polygon.getJSONArray(COORDINATES);
        JSONArray xy = coordinates.getJSONArray(0);
        JSONArray ms = new JSONArray();
        for (int i = 0; i < xy.size(); i++) {
            JSONArray p = xy.getJSONArray(i);
            JSONArray m = mercator2lngLat(p.getDouble(0), p.getDouble(1));
            ms.add(m);
        }
        JSONArray newCoordinates = new JSONArray();
        newCoordinates.add(ms);
        polygon.put(COORDINATES, newCoordinates);
        return polygon;
    }
}

转换后的geojson就可以作为上面缓冲区的sql生成缓冲区空间数据了,生成的缓冲区数据也是墨卡托坐标系,需使用mercatorPolygon2Lnglat进行处理后返回给客户端,调用流程如下:

  • 客户端提交点位geojson及半径
  • 使用墨卡托工具类将点位geojson转换成墨卡托坐标系的geojson
  • 调用sql进行缓冲区生成
  • 返回值使用墨卡托工具类转换成mercatorPolygon2Lnglat返回给调用方

小结:

上面介绍如何使用mysql st_buffer函数生成缓冲区,实际操作起来经过我在研发中的应用是可行的,实际开发中还可以使用一些工具包来实现缓冲区生成,如geotools...

三、判断点位所在城市

  • 判断用户点位所在城市-客户端提交用户的定位信息,判断用户所在城市(使用ST_INTERSECTS()判断两个几何是否相交即可,返回0或1)
SELECT ST_INTERSECTS(ST_GeomFromGeoJSON('${geoJsonStrA}'), ST_GeomFromGeoJSON('${geoJsonStrB}'))

SQL解读:

使用格式化函数将geojson处理成函数支持的geomtry格式,使用ST_INTERSECTS进行判断即可

四、常用的空间函数

MySQL空间数据存储及函数

总结:

MySQL为空间数据的存储及分析提供了丰富的数据类型及函数,我们学习此类函数能够帮助我们更好的处理地理信息,使用前需要对坐标系、geojson相关知识进行了解,避免踩坑,如果有相关问题也可以在评论区交流,如有误区请指正。

到此这篇关于MySQL空间数据存储及函数的文章就介绍到这了,更多相关MySQL空间数据存储及函数内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL索引篇之千万级数据实战测试
Apr 05 MySQL
mysql部分操作
Apr 05 MySQL
mysql多表查询-笔记七
Apr 05 MySQL
MySQL连表查询分组去重的实现示例
Jul 01 MySQL
mysql 直接拷贝data 目录下文件还原数据的实现
Jul 25 MySQL
MySQL子查询中order by不生效问题的解决方法
Aug 02 MySQL
sql注入教程之类型以及提交注入
Aug 02 MySQL
MySQL提取JSON字段数据实现查询
Apr 22 MySQL
详细介绍MySQL中limit和offset的用法
May 06 MySQL
MySQL 自动填充 create_time 和 update_time
May 20 MySQL
MySQL中EXPLAIN语句及用法
May 20 MySQL
MySQL数据库之存储过程 procedure
Jun 16 MySQL
MySQL基础快速入门知识总结(附思维导图)
MySQL连接控制插件介绍
Sep 25 #MySQL
Mysql案例刨析事务隔离级别
Sep 25 #MySQL
MySQL定时备份数据库(全库备份)的实现
Sep 25 #MySQL
MySQL修改默认引擎和字符集详情
Sep 25 #MySQL
MySQL 用 limit 为什么会影响性能
Sep 15 #MySQL
一次MySQL启动导致的事故实战记录
Sep 15 #MySQL
You might like
Zend的AutoLoad机制介绍
2012/09/27 PHP
基于php上传图片重命名的6种解决方法的详细介绍
2013/04/28 PHP
php获取Google机器人访问足迹的方法
2015/04/15 PHP
PHP+Ajax实现的无刷新分页功能详解【附demo源码下载】
2017/07/03 PHP
jQuery.Autocomplete实现自动完成功能(详解)
2010/07/13 Javascript
JavaScript 选中文字并响应获取的实现代码
2011/08/28 Javascript
jquery监听div内容的变化具体实现思路
2013/11/04 Javascript
使用JS实现jQuery的addClass, removeClass, hasClass函数功能
2014/10/31 Javascript
Jquery日期选择datepicker插件用法实例分析
2015/06/08 Javascript
jquery实现的代替传统checkbox样式插件
2015/06/19 Javascript
JS+CSS实现仿支付宝菜单选中效果代码
2015/09/25 Javascript
基于JS实现导航条之调用网页助手小精灵的方法
2016/06/17 Javascript
微信小程序 实战小程序实例
2016/10/08 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
2017/03/15 Javascript
Vue Prop属性功能与用法实例详解
2019/02/23 Javascript
vue+openlayers绘制省市边界线
2020/12/24 Vue.js
基于Python_脚本CGI、特点、应用、开发环境(详解)
2017/05/23 Python
python 列表删除所有指定元素的方法
2018/04/19 Python
python获取代理IP的实例分享
2018/05/07 Python
在IPython中进行Python程序执行时间的测量方法
2018/11/01 Python
对python实现模板生成脚本的方法详解
2019/01/30 Python
基于Python实现ComicReaper漫画自动爬取脚本过程解析
2019/11/11 Python
pytorch 获取tensor维度信息示例
2020/01/03 Python
Python格式化输出--%s,%d,%f的代码解析
2020/04/29 Python
Pytorch转onnx、torchscript方式
2020/05/25 Python
Python常用库Numpy进行矩阵运算详解
2020/07/21 Python
前端实现背景虚化但内容清晰且自适应 的实例代码
2019/08/01 HTML / CSS
缓解脚、腿和背部疼痛:Z-CoiL鞋
2019/03/12 全球购物
毕业生求职推荐信
2013/11/04 职场文书
总经理司机职责
2014/02/02 职场文书
大学生两会学习心得体会
2014/03/10 职场文书
公务员政审单位鉴定材料
2014/05/16 职场文书
优秀教师先进个人事迹材料
2014/08/31 职场文书
财务工作失误检讨书
2015/02/19 职场文书
护士自荐信怎么写
2015/03/06 职场文书
中国梦党课学习心得体会
2016/01/05 职场文书