Pour MySQL 5.7+
Étant donné que nous avons le tableau simple suivant,
create table example (
id bigint not null auto_increment primary key,
lnglat point not null
);
create spatial index example_lnglat
on example (lnglat);
Avec les données simples suivantes,
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));
Vous obtiendriez les points dans une plage donnée d'un autre point (remarque :nous devons rechercher à l'intérieur d'un polygone) avec la combinaison suivante de fonctions 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);
Vous devriez voir quelque chose comme ceci :
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
Pour référence sur la distance, si nous supprimons la contrainte, le résultat pour le point de test ressemble à ceci :
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
Remarque 1 :le champ s'appelle lnglat car c'est le bon ordre si vous pensez aux points comme (x, y) et c'est aussi l'ordre dans lequel la plupart des fonctions (comme point) acceptent le paramètre
Remarque 2 :vous ne pouvez pas réellement profiter des index spatiaux si vous deviez utiliser des cercles ; notez également que le champ de point peut être défini pour accepter la valeur nulle, mais les index spatiaux ne peuvent pas l'indexer s'il est nullable (tous les champs de l'index doivent être non nuls).
Remarque 3 :st_buffer est considéré (par la documentation) comme mauvais pour ce cas d'utilisation
Remarque 4 :les fonctions ci-dessus (en particulier st_distance_sphere) sont documentées comme rapides mais pas nécessairement super précises ; si vos données sont très sensibles à cela, ajoutez un peu de marge de manœuvre à la recherche et affinez l'ensemble de résultats