ST_FrechetDistance() și ST_HausdorffDistance() în MySQL

Măsoară cât de asemănătoare sunt două linii (de exemplu două trasee GPS); 0 înseamnă trasee identice.

Sintaxă
ST_FrechetDistance(g1, g2 [, unitate])
ST_HausdorffDistance(g1, g2 [, unitate])

Ce face ST_FrechetDistance() și ST_HausdorffDistance()

Ambele funcții (din MySQL 8.0.23) compară forme, nu doar cea mai mică distanță. Distanța Hausdorff este cea mai mare distanță de la un punct al unei geometrii până la cea mai apropiată parte a celeilalte. Distanța Fréchet ține cont și de ordinea punctelor: este ca lesa cea mai scurtă dintre un om și câine care merg pe două trasee, fiecare doar înainte.

Sunt variantele discrete: se iau în calcul doar punctele scrise în geometrii, nu și punctele de pe segmente. ST_FrechetDistance() acceptă doar LINESTRING; ST_HausdorffDistance() acceptă și combinații de puncte și MULTI.... Pentru SRID 4326, rezultatul este în metri (sau în unitatea cerută).

Parametri

Parametru Descriere
g1, g2 Geometriile comparate (linii, pentru Fréchet).
unitate Opțional: unitatea rezultatului (doar pentru SRID diferit de 0).

Ce returnează

Un număr cu zecimale.

Exemple

Exemplul 1: Cât de diferite sunt două trasee

SET @planificat = ST_GeomFromText('LINESTRING(0 0,0 5,5 5)');
SET @parcurs = ST_GeomFromText('LINESTRING(0 1,0 6,3 3,5 6)');

SELECT ST_FrechetDistance(@planificat, @parcurs) AS frechet,
       ST_HausdorffDistance(@planificat, @parcurs) AS hausdorff,
       ST_Distance(@planificat, @parcurs) AS distanta_minima;

Rezultat

+--------------------+-----------+-----------------+
| frechet            | hausdorff | distanta_minima |
+--------------------+-----------+-----------------+
| 2.8284271247461903 |         1 |               0 |
+--------------------+-----------+-----------------+

Exemplul 2: Două înregistrări GPS ale drumului Iași – Cluj

SET @tura1 = ST_GeomFromText('LINESTRING(47.1585 27.6014, 47.05 25.90, 46.7712 23.6236)', 4326);
SET @tura2 = ST_GeomFromText('LINESTRING(47.1585 27.6014, 46.95 26.40, 46.7712 23.6236)', 4326);

SELECT ROUND(ST_FrechetDistance(@tura1, @tura2, 'kilometre'), 1) AS frechet_km,
       ROUND(ST_HausdorffDistance(@tura1, @tura2, 'kilometre'), 1) AS hausdorff_km;

Rezultat

+------------+--------------+
| frechet_km | hausdorff_km |
+------------+--------------+
|       39.6 |         39.6 |
+------------+--------------+

Greșeli frecvente

  • Folosești ST_Distance() ca să compari trasee. Două trasee care pornesc din același loc au distanța 0, oricât de diferite ar fi; pentru asemănare folosește aceste funcții.

Comenzi înrudite

  • ST_Distance(): Returnează distanța minimă dintre două geometrii; pentru SRID 4326, în metri, calculată pe elipsoidul Pământului.
  • ST_Simplify(): Simplifică o geometrie (algoritmul Douglas-Peucker): elimină punctele care abat linia cu mai puțin de o distanță dată.
  • LineString(): Construiește o linie frântă (LINESTRING) din două sau mai multe puncte.