Voor MySQL 5.7+
Aangezien we de volgende eenvoudige tabel hebben,
create table example (
id bigint not null auto_increment primary key,
lnglat point not null
);
create spatial index example_lnglat
on example (lnglat);
Met de volgende eenvoudige gegevens,
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));
Je zou de punten binnen een bepaald bereik van een ander punt krijgen (let op:we moeten binnen een polygoon zoeken) met de volgende combinatie van st-functies:
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);
Je zou zoiets als dit moeten zien:
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
Ter referentie op afstand, als we de beperking verwijderen, ziet het resultaat voor het testpunt er als volgt uit:
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
Opmerking 1 :het veld heet lnglat omdat dat de juiste volgorde is als je aan punten denkt als (x, y) en het is ook de volgorde waarin de meeste functies (zoals punt) de parameter accepteren
Opmerking 2 :je kunt niet echt profiteren van ruimtelijke indexen als je cirkels zou gebruiken; Houd er ook rekening mee dat het puntveld kan worden ingesteld om null te accepteren, maar ruimtelijke indexen kunnen het niet indexeren als het nullable is (alle velden in de index moeten niet-null zijn).
Opmerking 3 :st_buffer wordt (door de documentatie) beschouwd als slecht voor deze use case
Opmerking 4 :de bovenstaande functies (in het bijzonder st_distance_sphere) zijn gedocumenteerd als snel, maar niet noodzakelijk supernauwkeurig; als je gegevens daar supergevoelig voor zijn, voeg dan wat speelruimte toe aan de zoekopdracht en verfijn de resultatenset