ST_Contains() în MySQL

Verifică dacă prima geometrie o conține complet pe a doua (de exemplu un punct în interiorul unui poligon).

Sintaxă
ST_Contains(g1, g2)

Ce face ST_Contains()

ST_Contains(g1, g2) returnează 1 dacă toate punctele lui g2 sunt în g1 și măcar un punct este în interiorul lui g1. Un punct aflat exact pe marginea poligonului nu este „conținut”. Este relația inversă lui ST_Within(): ST_Contains(a, b) = ST_Within(b, a).

Funcția folosește forma exactă a geometriilor, nu dreptunghiul de încadrare. Funcționează și pentru SRID 4326. Dacă o coloană are index spațial (SPATIAL INDEX), MySQL îl poate folosi pentru a găsi rapid candidații.

Parametri

Parametru Descriere
g1 Geometria care ar trebui să conțină.
g2 Geometria verificată.

Ce returnează

1, 0 sau NULL (dacă un argument este NULL sau gol).

Exemple

Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.

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))'));

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));

Exemplul 1: În ce cartier este fiecare magazin

SELECT m.nume AS magazin, c.nume AS cartier
FROM magazine m
JOIN cartiere c ON ST_Contains(c.forma, m.loc)
ORDER BY m.id;

Rezultat

+-----------------+-------------+
| magazin         | cartier     |
+-----------------+-------------+
| Librăria Ana    | Centru      |
| Florăria Dan    | Copou       |
| Brutăria Ioana  | Tătărași    |
| Cafeneaua Mara  | Tătărași    |
| Atelierul Radu  | Galata      |
+-----------------+-------------+

Exemplul 2: Punct în interior, pe margine și în afară

SET @centru = ST_GeomFromText('POLYGON((0 0,4 0,4 4,0 4,0 0))');

SELECT ST_Contains(@centru, Point(1, 1)) AS interior,
       ST_Contains(@centru, Point(4, 2)) AS pe_margine,
       ST_Contains(@centru, Point(9, 9)) AS in_afara;

Rezultat

+----------+------------+----------+
| interior | pe_margine | in_afara |
+----------+------------+----------+
|        1 |          0 |        0 |
+----------+------------+----------+

Greșeli frecvente

  • Te aștepți ca un punct de pe margine să fie conținut. Nu este (Cafeneaua Mara, la x = 4, lipsește din Centru); dacă vrei să incluzi marginea, folosește ST_Intersects() sau MBRCovers().

Comenzi înrudite

  • ST_Within(): Verifică dacă prima geometrie se află complet în interiorul celei de-a doua (de exemplu un punct într-o zonă).
  • ST_Intersects(): Verifică dacă două geometrii au măcar un punct comun (inclusiv pe margine).
  • MBRContains() și MBRWithin(): Verifică dacă dreptunghiul de încadrare al unei geometrii îl conține pe al celeilalte; un test rapid, aproximativ.
  • ST_Touches(): Verifică dacă două geometrii se ating doar pe margine, fără ca interioarele lor să se suprapună.