编写本文的目的:
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 = '张三';
sql执行结果
name | gis |
---|---|
张三 | POINT(108.9498710632 34.2588125935) |
2. 修改张三的位置信息
update z_gis set gis = geomfromtext('point(108.9465236664 34.2598766768)') where name = '张三';
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.
3. 查询张三和李四之间的距离
select floor(st_distance_sphere(
(select gis from z_gis where name= '张三'),
gis
)) distance from z_gis where name= '李四';
sql执行结果
distance |
---|
329 |
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执行结果
name | distance | point |
---|---|---|
李四 | 329 | POINT(108.9465236664 34.2598766768) |
王五 | 198 | POINT(108.947725296 34.2590342786) |
十九 | 317 | POINT(108.9530360699 34.2599476152) |
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长度 | 误差距离(km) |
---|---|
1 | ±2500 |
2 | ±630 |
3 | ±78 |
4 | ±20 |
5 | ±2.4 |
6 | ±0.61 |
7 | ±0.076 |
8 | ±0.019 |
geohash官方文档地址:https://en.wikipedia.org/wiki/Geohash