Für MySQL 5.7+
Angenommen, wir haben die folgende einfache Tabelle,
create table example (
id bigint not null auto_increment primary key,
lnglat point not null
);
create spatial index example_lnglat
on example (lnglat);
Mit den folgenden einfachen Daten,
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));
Sie würden die Punkte innerhalb eines bestimmten Bereichs eines anderen Punkts (Hinweis:Wir müssen innerhalb eines Polygons suchen) mit der folgenden Kombination von st-Funktionen erhalten:
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);
Als Ergebnis sollten Sie in etwa Folgendes sehen:
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
Wenn wir die Einschränkung entfernen, sieht das Ergebnis für den Testpunkt wie folgt aus:
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
Anmerkung 1 :Das Feld heißt lnglat, da dies die richtige Reihenfolge ist, wenn Sie sich Punkte als (x, y) vorstellen, und dies auch die Reihenfolge ist, in der die meisten Funktionen (wie Punkt) den Parameter akzeptieren
Anmerkung 2 :Sie können räumliche Indizes nicht wirklich nutzen, wenn Sie Kreise verwenden würden; Beachten Sie auch, dass das Punktfeld so eingestellt werden kann, dass es null akzeptiert, räumliche Indizes es jedoch nicht indizieren können, wenn es nullfähig ist (alle Felder im Index müssen nicht null sein).
Anmerkung 3 :st_buffer wird (von der Dokumentation) als schlecht für diesen Anwendungsfall angesehen
Anmerkung 4 :Die obigen Funktionen (insbesondere st_distance_sphere) sind als schnell, aber nicht unbedingt supergenau dokumentiert; Wenn Ihre Daten sehr empfindlich darauf reagieren, geben Sie der Suche etwas Spielraum und nehmen Sie eine Feinabstimmung der Ergebnismenge vor