mysql中geometry类型的简单使用

编写本文的目的:

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

建表脚本

CREATE TABLE `z_gis` (
`id` varchar() NOT NULL,
`name` varchar() NOT NULL COMMENT '姓名',
`gis` geometry NOT NULL COMMENT '空间位置信息',
`geohash` varchar() GENERATED ALWAYS AS (st_geohash(`gis`,)) 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执行结果 

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 = ;

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执行结果 

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) <
AND name != '张三'; 

sql执行结果 

    如果表中数据非常多时,这样查效率会非常低,这时就会用到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 = '张三'),),'%')
AND ST_DISTANCE_SPHERE((SELECT
gis
FROM
z_gis
WHERE
name = '张三'),
gis) <
AND name != '张三';

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

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

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

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

最新文章

  1. ServiceStack 概念参考文摘
  2. requst方法简单用一下
  3. python 包管理工具
  4. android- Auto Monitor Logcat
  5. DWR3.0 dwr 返回值(数组,集合,Map)
  6. hdu 4300(kmp)
  7. Qt 自动搜索串口号列表
  8. easy ui datagrid在没有数据时显示相关提示内容
  9. 解决win service 2003 IIS发布Gis网站后,访问地图服务出错,无法正常打开而且 事件查看器出现错误提示。
  10. 浅析CSS中的haslayout
  11. 12_Python的(匿名函数)Lambda表达式_Python编程之路
  12. Java中float型最大值大于long型?
  13. vue2.0 element-ui中el-upload的before-upload方法返回false时submit()不生效解决方法
  14. Linux:修改和删除已有变量
  15. 【三分钟视频教程】iOS开发中 Xcode 报 apple-o linker 错误的#解决方案#
  16. 006-Redis 发布订阅
  17. 2:5 视图控制器result的配置
  18. Python -- xlrd,xlwt,xlutils 读写同一个Excel
  19. html头标签meta实现refresh重定向
  20. Mahout实战---运行第一个推荐引擎

热门文章

  1. ubuntu系统设置密码报错 Module is unknown
  2. 关于print()里面的sep和end参数的使用
  3. HashMap是不是有序的?
  4. Linux统计根分区使用率
  5. Java Heap and Stack
  6. [转]如何升级gcc版本
  7. Unity 如何修改 particle system 的 start color 属性
  8. 拾遗:不用使 sizeof 获取数组大小
  9. 基于三角形与位置指纹识别算法的WiFi定位比较
  10. lasso数学解释