Đối với MySQL 5.7+
Với chúng tôi có bảng đơn giản sau đây,
create table example (
id bigint not null auto_increment primary key,
lnglat point not null
);
create spatial index example_lnglat
on example (lnglat);
Với các dữ liệu đơn giản sau đây,
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));
Bạn sẽ nhận được điểm trong một phạm vi nhất định của một điểm (lưu ý: chúng ta phải tìm kiếm bên trong một đa giác) với sự kết hợp sau đây của các chức năng 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);
Bạn sẽ thấy một cái gì đó như thế này kết quả là:
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
để tham khảo vào khoảng cách, nếu chúng ta loại bỏ các hạn chế kết quả cho kỳ thi điểm trông như thế này:
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
Note 1: lĩnh vực này được gọi là lnglat vì đó là thứ tự chính xác nếu bạn nghĩ về điểm như (x, y) và cũng là thứ tự nhất chức năng (như điểm) chấp nhận tham số
Lưu ý 2: bạn không thể tận dụng lợi thế của các chỉ mục không gian nếu bạn sử dụng vòng kết nối; cũng lưu ý rằng trường điểm có thể được thiết lập để chấp nhận các chỉ mục không gian nhưng không thể lập chỉ mục nếu nó không có giá trị (tất cả các trường trong chỉ mục được yêu cầu là không null).
Note 3: st_buffer được coi (theo tài liệu) là xấu đối với trường hợp sử dụng này
Chú giải 4: các chức năng trên (trong st_distance_sphere cụ thể) là tài liệu càng nhanh nhưng không nhất thiết siêu chính xác ; nếu dữ liệu của bạn siêu nhạy cảm với điều đó, hãy thêm một chút phòng lung tung vào tìm kiếm và thực hiện một số điều chỉnh chính xác cho tập kết quả
Bạn đã làm gì để sửa lỗi này? Tôi đang đấu tranh với quyết định sử dụng MySQL 5.7 chức năng Spacial hoặc sử dụng công thức Haversine. – Jethro