Ce face ST_Distance()
Pentru SRID 0, distanța este cea din plan (Pitagora), în unitățile coordonatelor. Pentru un SRID geografic, ca 4326, distanța este geodezică: cea mai scurtă distanță pe elipsoidul WGS 84, în metri. Din MySQL 8.0.18 funcționează pe SRID geografic pentru orice tipuri de geometrii.
Pentru linii și poligoane se returnează cea mai mică distanță dintre ele (0 dacă se ating). Al treilea argument (din MySQL 8.0.14) cere altă unitate, de exemplu 'kilometre'; nu se poate folosi cu SRID 0.
Parametri
| Parametru | Descriere |
|---|---|
g1, g2 |
Geometriile, cu același SRID. |
unitate |
Opțional: unitatea rezultatului ('metre', 'kilometre', 'foot' etc.). |
Ce returnează
Un număr cu zecimale.
Exemple
Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.
CREATE TABLE orase (
id INT PRIMARY KEY,
nume VARCHAR(20),
loc POINT NOT NULL SRID 4326,
SPATIAL INDEX (loc)
);
INSERT INTO orase VALUES
(1, 'Iași', ST_GeomFromText('POINT(47.1585 27.6014)', 4326)),
(2, 'Cluj-Napoca', ST_GeomFromText('POINT(46.7712 23.6236)', 4326)),
(3, 'București', ST_GeomFromText('POINT(44.4268 26.1025)', 4326)),
(4, 'Timișoara', ST_GeomFromText('POINT(45.7489 21.2087)', 4326)),
(5, 'Constanța', ST_GeomFromText('POINT(44.1598 28.6348)', 4326));
CREATE TABLE magazine (
id INT PRIMARY KEY,
nume VARCHAR(20),
loc POINT NOT NULL
);
INSERT INTO magazine VALUES
(1, 'Librăria Ana', Point(1, 1)),
(2, 'Florăria Dan', Point(2, 6)),
(3, 'Brutăria Ioana', Point(5, 3)),
(4, 'Cafeneaua Mara', Point(4, 2)),
(5, 'Atelierul Radu', Point(12, 1));
CREATE TABLE cartiere (
id INT PRIMARY KEY,
nume VARCHAR(20),
forma POLYGON NOT NULL
);
INSERT INTO cartiere VALUES
(1, 'Centru', ST_GeomFromText('POLYGON((0 0,4 0,4 4,0 4,0 0))')),
(2, 'Copou', ST_GeomFromText('POLYGON((0 4,4 4,4 8,0 8,0 4))')),
(3, 'Tătărași', ST_GeomFromText('POLYGON((3 1,7 1,7 5,3 5,3 1))')),
(4, 'Galata', ST_GeomFromText('POLYGON((10 0,13 0,13 3,10 3,10 0))'));
Exemplul 1: Distanța de la Iași la celelalte orașe
SELECT b.nume, ROUND(ST_Distance(a.loc, b.loc, 'kilometre'), 1) AS km
FROM orase a JOIN orase b ON a.nume = 'Iași' AND b.id <> a.id
ORDER BY km;
Rezultat
+-------------+-------+
| nume | km |
+-------------+-------+
| Cluj-Napoca | 305.7 |
| București | 325.2 |
| Constanța | 342.9 |
| Timișoara | 515.3 |
+-------------+-------+
Exemplul 2: Cel mai apropiat magazin de un client (plan în km)
SET @client = Point(3, 3);
SELECT nume, ROUND(ST_Distance(loc, @client), 2) AS km
FROM magazine
ORDER BY km
LIMIT 3;
Rezultat
+-----------------+------+
| nume | km |
+-----------------+------+
| Cafeneaua Mara | 1.41 |
| Brutăria Ioana | 2 |
| Librăria Ana | 2.83 |
+-----------------+------+
Exemplul 3: Distanța de la un punct la un cartier
SELECT nume, ST_Distance(forma, Point(9, 2)) AS km_pana_la_margine
FROM cartiere
ORDER BY km_pana_la_margine;
Rezultat
+-------------+--------------------+
| nume | km_pana_la_margine |
+-------------+--------------------+
| Galata | 1 |
| Tătărași | 2 |
| Centru | 5 |
| Copou | 5.385164807134504 |
+-------------+--------------------+
Greșeli frecvente
- Calculezi distanțe GPS cu SRID 0. Rezultatul este în grade și nu se poate transforma corect în kilometri; folosește SRID 4326.
- Folosești
ORDER BY ST_Distance(...)pe tabele foarte mari fără alt filtru. Calculul se face pentru fiecare rând; restrânge mai întâi zona cuMBRContains()sauST_Within(), care pot folosi indexul spațial.
Comenzi înrudite
ST_Distance_Sphere(): Returnează distanța pe o sferă (în metri) dintre două puncte; un calcul rapid, aproximativ, pentru coordonate GPS.ST_Length(): Returnează lungimea unei linii (sau suma lungimilor dintr-un MULTILINESTRING); pe SRID 4326, în metri.ST_Buffer(): Returnează zona formată din toate punctele aflate la cel mult o distanță dată de o geometrie (o „zonă tampon”).ST_FrechetDistance() și ST_HausdorffDistance(): Măsoară cât de asemănătoare sunt două linii (de exemplu două trasee GPS); 0 înseamnă trasee identice.