我创建了以下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万点,因此这需要尽可能高效。

有帮助吗?

解决方案 2

谢谢你们的回答。

我最终找到了解决方案 http://www.movable-type.co.uk/scripts/latlong-db.html.

其他提示

对于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,但是如果空间索引可确定,则不能索引它(索引中的所有字段都必须为非null)。

注3: :st_buffer(通过文档)对此用例不利

注意4: :上面的功能(尤其是ST_DISTANCE_SPHERE)被记录为快速,但不一定是超准确的;如果您的数据对此非常敏感

半径不能有效地索引。您应该使用边界矩形快速获取可能要寻找的点,然后在半径外过滤点。

我在半径内在圆圈内做了一分

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, , 希望这可以帮助

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top