我创建了以下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;
我正在尝试查询:
我发现的所有示例都是指使用最小边界矩形(MBR)而不是半径。该表包含大约100万个点,因此需要尽可能高效。
答案 0 :(得分:3)
感谢您的回答。
我最终在http://www.movable-type.co.uk/scripts/latlong-db.html找到了解决方案。
答案 1 :(得分:3)
对于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 :如果你要使用圈子,你实际上无法利用空间索引;另请注意,可以将点域设置为接受null,但如果空间索引可以为空,则空索引不能对其进行索引(索引中的所有字段都必须为非空)。
注3 :st_buffer被认为(通过文档)对此用例不利
注释4 :上述函数(特别是st_distance_sphere)记录为快速但不一定非常准确;如果您的数据对此非常敏感,请为搜索添加一些摆动空间并对结果集进行微调
答案 2 :(得分:2)
Radius无法有效索引。您应该使用边界矩形快速获取您可能正在寻找的点,然后过滤半径之外的点。
答案 3 :(得分:0)
我在半径为
的圆圈内的一个点做到了这一点SELECT
*
FROM
`locator`
WHERE
SQRT(POW(X(`center`) - 49.843317 , 2) + POW(Y(`center`) - 24.026642, 2)) * 100 < `radius`
详细信息以及此处的另一个示例查询http://dexxtr.com/post/83498801191/how-to-determine-point-inside-circle-using-mysql,希望这有助于