gpt4 book ai didi

mysql - MySQL中给定半径内的查询点

转载 作者:可可西里 更新时间:2023-11-01 06:29:59 25 4
gpt4 key购买 nike

我创建了以下 MySQL 表来存储纬度/经度坐标以及每个点的名称:

CREATE TABLE `points` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
`location` point NOT NULL,
PRIMARY KEY (`id`),
SPATIAL KEY `location` (`location`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

我正在尝试查询:

  • 给定点 n 英里半径内的所有点;
  • 每个返回点与给定点的距离

我发现的所有示例都涉及使用最小边界矩形 (MBR) 而不是半径。该表包含大约 100 万个点,因此需要尽可能高效。

最佳答案

适用于 MySQL 5.7+

鉴于我们有以下简单表格,

create table example (
id bigint not null auto_increment primary key,
lnglat point not null
);

create spatial index example_lnglat
on example (lnglat);

用下面的简单数据,

insert into example (lnglat) 
values
(point(-2.990435, 53.409246)),
(point(-2.990037, 53.409471)),
(point(-2.989736, 53.409676)),
(point(-2.989554, 53.409797)),
(point(-2.989350, 53.409906)),
(point(-2.989178, 53.410085)),
(point(-2.988739, 53.410309)),
(point(-2.985874, 53.412656)),
(point(-2.758019, 53.635928));

您将使用以下 st 函数组合获得另一个点的给定范围内的点(注意:我们必须在多边形内搜索):

set @px = -2.990497;
set @py = 53.410943;
set @range = 150; -- meters
set @rangeKm = @range / 1000;

set @search_area = st_makeEnvelope (
point((@px + @rangeKm / 111), (@py + @rangeKm / 111)),
point((@px - @rangeKm / 111), (@py - @rangeKm / 111))
);

select id,
st_x(lnglat) lng,
st_y(lnglat) lat,
st_distance_sphere(point(@px, @py), lnglat) as distance
from example
where st_contains(@search_area, lnglat);

你应该看到这样的结果:

3   -2.989736   53.409676   149.64084252776277
4 -2.989554 53.409797 141.93232714661812
5 -2.98935 53.409906 138.11516275402533
6 -2.989178 53.410085 129.40289289527473

作为距离引用,如果我们移除约束,测试点的结果如下所示:

1   -2.990435   53.409246   188.7421181457556
2 -2.990037 53.409471 166.49406509160158
3 -2.989736 53.409676 149.64084252776277
4 -2.989554 53.409797 141.93232714661812
5 -2.98935 53.409906 138.11516275402533
6 -2.989178 53.410085 129.40289289527473
7 -2.988739 53.410309 136.1875540498202
8 -2.985874 53.412656 360.78532732013963
9 -2.758019 53.635928 29360.27797292756

注意 1:该字段称为 lnglat,因为如果您将点视为 (x, y),那么这是正确的顺序,也是大多数函数(如点)接受参数的顺序

注意 2:如果您要使用圆圈,您实际上无法利用空间索引;另请注意,可以将点字段设置为接受空值,但如果它可以为空,则空间索引无法为其编制索引(索引中的所有字段都必须为非空)。

注意 3:st_buffer 被认为(根据文档)不适合这个用例

注意 4:上面的函数(特别是 st_distance_sphere)被记录为快速但不一定非常准确;如果您的数据对此非常敏感,请为搜索添加一些回旋余地并对结果集进行一些微调

关于mysql - MySQL中给定半径内的查询点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2411528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com