Pour MySQL 5.7+
Étant donné que nous avoir 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 obtiendrez des points dans une plage donnée d'un autre point (note: 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 comme résultat:
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 on enlève la contrainte du résultat pour le test le point 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
Note 1: le champ est appelé lnglat puisque c'est l'ordre correct si vous pensez des points que (x, y) et est également l'ordre la plupart des fonctions (comme point) accepter le paramètre
Remarque 2: vous ne pouvez pas réellement tirer parti des index spatiaux si vous utilisiez des cercles; Notez également que le champ de point peut être défini pour accepter null, mais les index spatiaux ne peuvent pas l'indexer s'il est nullable (tous les champs de l'index doivent être non null).
Note 3: ST_Buffer est considéré (par la documentation) pour être mauvais pour ce cas d'utilisation
Note 4: les fonctions ci-dessus (en st_distance_sphere particulier) sont documentés aussi vite, mais pas nécessairement super précis ; Si vos données sont super sensibles à cela ajouter un peu de marge de manœuvre à la recherche et faire un réglage fin à l'ensemble des résultats
Qu'avez-vous fait pour résoudre ce problème? J'ai du mal à décider d'utiliser MySQL 5.7 Spacial ou d'utiliser la formule de Haversine. – Jethro