문제

각 지점의 이름과 함께 위도/경도 좌표를 저장하기 위해 다음 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;

쿼리하려고합니다.

  • AN 내의 모든 포인트 N 주어진 지점의 마일 반경;
  • 주어진 지점에서 반환 된 각 지점의 거리는

내가 찾은 모든 예제는 반경이 아닌 최소 경계 사각형 (MBR)을 사용하는 것을 나타냅니다. 테이블에는 약 백만 포인트가 포함되어 있으므로 가능한 한 효율적이어야합니다.

도움이 되었습니까?

해결책 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: 포인트를 (x, y)로 생각하고 가장 많은 함수 (예 : 포인트) 인 경우 필드는 lnglat이라고합니다.

노트 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