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)
上一篇 2021年11月3日 下午1:00
下一篇 2021年11月3日 下午2:00


相关推荐

  • 关于二叉树的前序、中序、后序三种遍历

    二叉树遍历分为三种:前序、中序、后序,其中序遍历最为重要。为啥叫这个名字?是根据根节点的顺序命名的。比如上图正常的一个满节点,A:根节点、B:左节点、C:右节点,前序顺序是ABC(根节点排最先,然后同级先左后右);中序顺序是BAC(先左后根最后右);后序顺序是BCA(先左后右最后根)。    比如上图二叉树遍历结果   前序遍历:ABCDEFGHK    中序遍历:BDCAEHGKF    后序…

    2022年4月9日
    62
  • bwapp安装教程_下载安装

    bwapp安装教程_下载安装1、什么是BWAPP?这就不用多说了吧,天知地知,你知我知。直接走下一步。2、去哪里下载?https://sourceforge.net/projects/bwapp/,进去点击download下载。3、打开BWAPP直接双击下面这个文件打开就可以了,打开后就是这个样子4、查看虚拟机ip,5、浏览器访问:http://192.168.43.116/b…

    2025年11月30日
    8
  • 恒流源差分放大电路静态分析_带有恒流源的差动放大电路

    恒流源差分放大电路静态分析_带有恒流源的差动放大电路由式 GS0512 可知 要想提高差动放大电路的共模抑制比 就要增大共模负馈电阻 Re 但增大 Re 会使其直流压降增大 要保持合适的静态工作点 EE 就要增大很多 这显然是不经济的 恒流源电路具有输出电阻很高而直流压降较小的特点 若用恒流源电路代替图 Z0502 电路中的 Re 就可在 EE 不高的情况下 获得很高的共模抑制比 图 Z0506 a 就是一个带有恒流源的差动放大电路 图 b 是它的简化表示 图中 T3 是恒

    2026年3月18日
    3
  • Mybatis中传递多个参数的4种方法总结[通俗易懂]

    Mybatis中传递多个参数的4种方法总结[通俗易懂]方法1:顺序传参法#{}里面的数字代表你传入参数的顺序。这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。方法2:@Param注解传参法#{}里面的名称对应的是注解 @Param括号里面修饰的名称。这种方法在参数不多的情况还是比较直观的,推荐使用。方法3:Map传参法#{}里面的名称对应的是 Map里面的key名称。这种方法适合传递多个参数…

    2022年6月13日
    43
  • 网络端口的作用及分类[通俗易懂]

    网络端口的作用及分类[通俗易懂]1.什么是网络端口?2.网络的端口的范围及其作用3.常见网络端口列举

    2025年11月5日
    5
  • python 字符转数字函数_excel将字符串转数字

    python 字符转数字函数_excel将字符串转数字chr(i)数字转ascii范围的字符unichr(i)数字转unicode字符ord(c)字符转成unicode码点

    2022年10月12日
    7

发表回复

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

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