Para MySQL 5.7+
Dado que tenemos la siguiente tabla simple,
create table example (
id bigint not null auto_increment primary key,
lnglat point not null
);
create spatial index example_lnglat
on example (lnglat);
Con los siguientes datos simples,
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));
Obtendría los puntos dentro de un rango dado de otro punto (nota:tenemos que buscar dentro de un polígono) con la siguiente combinación de funciones 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);
Debería ver algo como esto como resultado:
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
Como referencia sobre la distancia, si eliminamos la restricción, el resultado del punto de prueba se ve así:
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
Nota 2 :en realidad no puede aprovechar los índices espaciales si usara círculos; también tenga en cuenta que el campo de punto se puede configurar para aceptar nulo, pero los índices espaciales no pueden indexarlo si es anulable (se requiere que todos los campos en el índice no sean nulos).
Nota 3 :st_buffer se considera (según la documentación) como malo para este caso de uso
Nota 4 :las funciones anteriores (en particular, st_distance_sphere) están documentadas como rápidas pero no necesariamente súper precisas; si sus datos son muy sensibles a eso, agregue un poco de margen de maniobra a la búsqueda y ajuste el conjunto de resultados