Für MySQL 5.7+
wir Gegeben hilft 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 von einem anderen Punkt (Anmerkung: Wir haben innerhalb eines Polygons suchen) erhalten mit der folgenden Kombination von st Funktionen:
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);
Sie sollten so etwas wie dies als Ergebnis 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
als Referenz auf Abstand, wenn wir die Einschränkung das Ergebnis für den Test entfernen Punkt sieht 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 lnglat genannt wird, da das ist die richtige Reihenfolge, wenn Sie von Punkten als (x, y) denken, und ist auch die um die meisten Funktionen (wie Punkt) Akzeptieren Sie den Parameter
Hinweis 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, aber räumliche Indizes können es nicht indizieren, wenn es nullfähig ist (alle Felder im Index müssen nicht null sein).
Anmerkung 3: ST_Buffer betrachtet wird (von der Dokumentation), schlecht zu sein für diesen Anwendungsfall
Anmerkung 4: die oben genannten Funktionen (insbesondere st_distance_sphere) sind so schnell dokumentiert, aber nicht unbedingt super präzise ; Wenn Ihre Daten super empfindlich sind, fügen Sie ein bisschen Wackelraum zur Suche hinzu und tun Sie etwas Feineinstellung zum Ergebnissatz
Was haben Sie getan, um das zu beheben? Ich habe Schwierigkeiten mit der Entscheidung, entweder MySQL 5.7 Spacial-Funktionen zu verwenden oder die Haversine-Formel zu verwenden. – Jethro