mysql中geometry类型的简单使用

mysql中geometry类型的简单使用

mysql中geometry类型的简单使用

编写本文的目的:

    让和两天前的我一样的初学者,能够更快的使用geometry类型存储空间点数据
    也是为了自己加深印象,更熟练的使用geometry类型

建表脚本

CREATE TABLE `z_gis` (
  `id` varchar(45) NOT NULL,
  `name` varchar(10) NOT NULL COMMENT '姓名',
  `gis` geometry NOT NULL COMMENT '空间位置信息',
  `geohash` varchar(20) GENERATED ALWAYS AS (st_geohash(`gis`,8)) VIRTUAL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id` (`id`),
  SPATIAL KEY `idx_gis` (`gis`),
  KEY `idx_geohash` (`geohash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='空间位置信息'

这里我创建了一张位置信息表,每个人对应的经纬度都会以geometry类型存在表中,geohash字段是把坐标系分成很多小方格,然后将经纬度转化成字符串,其原理可自行百度,在这里就不多说了。
哦,对了,geometry类型好像不能为null,所以建表时必须为not null。
插入表数据

insert into z_gis(id,name,gis) values
(replace(uuid(),'-',''),'张三',geomfromtext('point(108.9498710632 34.2588125935)')),
(replace(uuid(),'-',''),'李四',geomfromtext('point(108.9465236664 34.2598766768)')),
(replace(uuid(),'-',''),'王五',geomfromtext('point(108.9477252960 34.2590342786)')),
(replace(uuid(),'-',''),'赵六',geomfromtext('point(108.9437770844 34.2553719653)')),
(replace(uuid(),'-',''),'小七',geomfromtext('point(108.9443349838 34.2595663206)')),
(replace(uuid(),'-',''),'孙八',geomfromtext('point(108.9473497868 34.2643456798)')),
(replace(uuid(),'-',''),'十九',geomfromtext('point(108.9530360699 34.2599476152)'));

名字是我随便起的,不要喷我哦,经纬度是我在地图上随便取的点,geomfromtext()函数是将字符串格式的点坐标,转化成geometry类型,还有个字段geohash是根据gis字段的值自动生成的,可以仔细看看建表脚本。
接下来是几个简单的查询例子
1. 查询张三的经纬度信息

select name, astext(gis) gis from z_gis where name = '张三';

    astext()函数是将geometry类型转化为字符串

sql执行结果 
mysql中geometry类型的简单使用
2. 修改张三的位置信息

update z_gis set gis = geomfromtext('point(108.9465236664 34.2598766768)') where name = '张三';

我用的Mysql Workbench工具,修改时报错如下:

You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.

好像是除了用id修改,其他修改都会报这个错,下面这样设置一下就OK了 。

set sql_safe_updates = 0;

3. 查询张三和李四之间的距离

select floor(st_distance_sphere(
    (select gis from z_gis where name= '张三'),
    gis
)) distance from z_gis where name= '李四';

    本来想格式化sql语句的,但是发现格式化之后的sql 基本全变成大写的了,我觉得辨识度更低了,所有大家就这样将就看吧,st_distance_sphere()函数是计算两点之间距离的,所以传两个参数,都是geometry类型的,floor()函数是把计算出的距离取整。

sql执行结果 
mysql中geometry类型的简单使用
4. 查询距离张三500米内的所有人

SELECT
    name,
    FLOOR(ST_DISTANCE_SPHERE((SELECT
                            gis
                        FROM
                            z_gis
                        WHERE
                            name = '张三'),
                    gis)) distance,
                    astext(gis) point
FROM
    z_gis
WHERE
    ST_DISTANCE_SPHERE((SELECT
                    gis
                FROM
                    z_gis
                WHERE
                    name = '张三'),
            gis) < 500
        AND name != '张三'

sql执行结果 
mysql中geometry类型的简单使用
    如果表中数据非常多时,这样查效率会非常低,这时就会用到geohash字段查询

sql语句如下:

SELECT
    name,
    floor(ST_DISTANCE_SPHERE((SELECT
                    gis
                FROM
                    z_gis
                WHERE
                    name = '张三'),
            gis)) distance,
            astext(gis) point
FROM
    z_gis
WHERE
    geohash like concat(left((select geohash from z_gis where name = '张三'),6),'%')
          AND ST_DISTANCE_SPHERE((SELECT
                    gis
                FROM
                    z_gis
                WHERE
                    name = '张三'),
            gis) < 500
        AND name != '张三';  

    前面说过geohash是把经纬度转成字符串,建表的时候我定义让它转成8位字符,当两个点离得越近时,它生成的geohash字符串前面相同的位数越多,所以我在这里先用left()截取前6位字符,前6位相同的误差在±600米左右,然后模糊查询,查出大概符合条件的数据,最后再精确比较,下面是geohash官方文档对geohash长度和距离误差的说明:

mysql中geometry类型的简单使用

    注意:用geohash 查询会有边界问题,所以查询出来的结果又可能不准确,可以用程序(例如java代码)先查出当前点周围8个范围的geohash值,然后再匹配这9个范围的所有数据,这样就解决了geohash 的边界问题。

geohash官方文档地址:https://en.wikipedia.org/wiki/Geohash

    之前没用过markdown编辑器,所以文档格式排版很乱,请大家见谅,上面有解释不对的地方,也请大佬们及时指出来,毕竟我也算是小白,还有很多地方需要学习。
———————
作者:MinjerZhang
来源:CSDN
原文:https://blog.csdn.net/MinjerZhang/article/details/78137795
版权声明:本文为博主原创文章,转载请附上博文链接!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/112671.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 数字证书原理,公钥私钥加密原理 – 因为这个太重要了[通俗易懂]

    文中首先解释了加密解密的一些基础知识和概念,然后通过一个加密通信过程的例子说明了加密算法的作用,以及数字证书的出现所起的作用。接着对数字证书做一个详细的解释,并讨论一下windows中数字证书的管理,最后演示使用makecert生成数字证书。如果发现文中有错误的地方,或者有什么地方说得不够清楚,欢迎指出!1、基础知识这部分内容主要解释一些概念和术语,最好是先理解这…

    2022年4月11日
    33
  • java实现靠边隐藏窗口

    java实现靠边隐藏窗口

    2022年2月23日
    72
  • python编程前景_Python前景如何,学完后可以从事方向?

    python编程前景_Python前景如何,学完后可以从事方向?前段时间浙江八年级新增了Python编程的课程,消息一出,引起了很多人的关注。连中学生都在学Python了,你还在犹豫要不要学习吗?对于想学Python,却又担心Python前景以及学完后可以从事方向的人,下面,小雷就给大家介绍一下。Python前景怎么样?目前国内外很多公司都在使用Python,例如搜索引擎Google的核心代码是Python完成的、迪士尼公司动画生成的Unix版本都内建了Pyt…

    2022年5月16日
    39
  • 计算机网络之TCP/UDP协议详解[通俗易懂]

    计算机网络之TCP/UDP协议详解[通俗易懂]深度理解TCP/IP1.TCP基础知识1.1什么是TCP?1.2什么是TCP连接?1.3TCP协议段格式1.4TCP主要特点2.UDP基础知识2.1UDP是什么?2.2UDP的协议段格式2.3UDP的主要特点2.4UDP的缓冲区3.TCP和UDP区别总结4.TCP保证可靠的机制4.1重传机制(这里只说了超时重传)4.2滑动窗口4.3流量控制4.3拥塞控制1.TCP基础知识1.1什么是TCP?TCP是⾯向连接的、可靠的、面向字节流的传输层通信协议面向连接:只能一对一连接,

    2022年5月9日
    34
  • drone无人机操作教程_无人机怎么起飞教程

    drone无人机操作教程_无人机怎么起飞教程教程:使用DroneKit在室内控制无人机DroneKit-Python是一个用于控制无人机的Python库。DroneKit提供了用于控制无人机的API,其代码独立于飞控,单独运行在机载电脑(CompanionComputer)或其他设备之上,通过串口或无线的方式经MAVLink协议与飞控板通信。除了DroneKit-Python以外,还有DroneKit-Android以及DroneKit-C

    2022年8月15日
    54
  • docker-Dockerfile文件详解

    docker-Dockerfile文件详解

    2022年4月2日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号