11. Relaciones Espaciales¶
Hasta ahora solo hemos usado funciones espaciales que miden (ST_Area, ST_Length), serializan (ST_GeomFromText) o deserializan (ST_AsGML) geometrías. Lo que estas funciones tienen en común es que solo trabajan con una geometría a la vez.
Las bases de datos espaciales son potentes porque no solo almacenan geometrías, también tienen la capacidad de comparar relaciones entre geometrías.
Preguntas como «¿Cuáles son los parqueaderos de bicicletas más cercanos a un parque?» o «¿Dónde están las intersecciones de líneas de metro y calles?» solo pueden responderse comparando geometrías que representan los parqueaderos de bicicletas, las calles y las líneas de metro.
El estándar OGC define el siguiente conjunto de métodos para comparar geometrías.
11.1. ST_Equals¶
ST_Equals(geometry A, geometry B) prueba la igualdad espacial de dos geometrías.

ST_Equals devuelve TRUE si dos geometrías del mismo tipo tienen valores de coordenadas x,y idénticos, es decir, si la segunda forma es igual (idéntica) a la primera.
Primero, recuperemos una representación de un punto de nuestra tabla nyc_subway_stations
. Tomaremos solo la entrada de “Broad St”.
SELECT name, geom
FROM nyc_subway_stations
WHERE name = 'Broad St';
name | geom
----------+---------------------------------------------------
Broad St | 0101000020266900000EEBD4CF27CF2141BC17D69516315141
Luego, volvemos a usar la representación de la geometría en una prueba ST_Equals:
SELECT name
FROM nyc_subway_stations
WHERE ST_Equals(
geom,
'0101000020266900000EEBD4CF27CF2141BC17D69516315141');
Broad St
Nota
La representación del punto no era muy legible para humanos (0101000020266900000EEBD4CF27CF2141BC17D69516315141
) pero era una representación exacta de los valores de coordenadas. Para una prueba como la de igualdad, usar las coordenadas exactas es necesario.
11.2. ST_Intersects, ST_Disjoint, ST_Crosses y ST_Overlaps¶
ST_Intersects, ST_Crosses y ST_Overlaps prueban si los interiores de las geometrías se intersectan.

ST_Intersects(geometry A, geometry B) devuelve t (TRUE) si las dos formas tienen algún espacio en común, es decir, si sus límites o interiores se intersectan.

El opuesto de ST_Intersects es ST_Disjoint(geometry A , geometry B). Si dos geometrías son disjuntas, no se intersectan, y viceversa. De hecho, a menudo es más eficiente probar «no intersecta» que probar «disjunta» porque las pruebas de intersección pueden estar indexadas espacialmente, mientras que la prueba de disjunción no.

Para comparaciones multipunto/polígono, multipunto/linestring, linestring/linestring, linestring/polígono y linestring/multipolígono, ST_Crosses(geometry A, geometry B) devuelve t (TRUE) si la intersección da como resultado una geometría cuya dimensión es una menos que la dimensión máxima de las dos geometrías de origen y el conjunto de intersección está en el interior de ambas geometrías de origen.

ST_Overlaps(geometry A, geometry B) compara dos geometrías de la misma dimensión y devuelve TRUE si su conjunto de intersección da como resultado una geometría diferente de ambas pero de la misma dimensión.
Tomemos nuestra estación de metro Broad Street y determinemos su vecindario usando la función ST_Intersects:
SELECT name, ST_AsText(geom)
FROM nyc_subway_stations
WHERE name = 'Broad St';
POINT(583571 4506714)
SELECT name, boroname
FROM nyc_neighborhoods
WHERE ST_Intersects(geom, ST_GeomFromText('POINT(583571 4506714)',26918));
name | boroname
--------------------+-----------
Financial District | Manhattan
11.3. ST_Touches¶
ST_Touches prueba si dos geometrías se tocan en sus límites, pero no se intersectan en sus interiores

ST_Touches(geometry A, geometry B) devuelve TRUE si los límites de cualquiera de las geometrías se intersectan o si solo el interior de una de las geometrías intersecta el límite de la otra.
11.4. ST_Within y ST_Contains¶
ST_Within y ST_Contains prueban si una geometría está completamente dentro de la otra.

ST_Within(geometry A , geometry B) devuelve TRUE si la primera geometría está completamente dentro de la segunda geometría. ST_Within prueba exactamente el resultado opuesto de ST_Contains.
ST_Contains(geometry A, geometry B) devuelve TRUE si la segunda geometría está completamente contenida por la primera geometría.
11.5. ST_Distance y ST_DWithin¶
Una pregunta de SIG extremadamente común es «encontrar todas las cosas dentro de la distancia X de esta otra cosa».
La función ST_Distance(geometry A, geometry B) calcula la distancia más corta entre dos geometrías y la devuelve como un número de punto flotante. Esto es útil para informar realmente la distancia entre objetos.
SELECT ST_Distance(
ST_GeometryFromText('POINT(0 5)'),
ST_GeometryFromText('LINESTRING(-2 2, 2 2)'));
3
Para probar si dos objetos están dentro de una distancia entre sí, la función ST_DWithin proporciona una prueba de verdadero/falso acelerada por índice. Esto es útil para preguntas como «¿cuántos árboles están dentro de un buffer de 500 metros de la carretera?». No tienes que calcular un buffer real, solo tienes que probar la relación de distancia.

Usando nuevamente nuestra estación de metro Broad Street, podemos encontrar las calles cercanas (a menos de 10 metros) de la parada de metro:
SELECT name
FROM nyc_streets
WHERE ST_DWithin(
geom,
ST_GeomFromText('POINT(583571 4506714)',26918),
10
);
name
--------------
Wall St
Broad St
Nassau St
Y podemos verificar la respuesta en un mapa. La estación Broad St está realmente en la intersección de Wall, Broad y Nassau Streets.

11.6. Lista de funciones¶
ST_Contains(geometry A, geometry B): Devuelve true si y solo si ningún punto de B se encuentra en el exterior de A, y al menos un punto del interior de B se encuentra en el interior de A.
ST_Crosses(geometry A, geometry B): Devuelve TRUE si las geometrías suministradas tienen algunos, pero no todos, los puntos interiores en común.
ST_Disjoint(geometry A , geometry B): Devuelve TRUE si las geometrías no «intersectan espacialmente», es decir, si no comparten ningún espacio.
ST_Distance(geometry A, geometry B): Devuelve la distancia cartesiana bidimensional mínima (basada en la referencia espacial) entre dos geometrías en unidades proyectadas.
ST_DWithin(geometry A, geometry B, radius): Devuelve true si las geometrías están dentro de la distancia especificada (radio) una de la otra.
ST_Equals(geometry A, geometry B): Devuelve true si las geometrías dadas representan la misma geometría. Se ignora la direccionalidad.
ST_Intersects(geometry A, geometry B): Devuelve TRUE si las geometrías/geografías «intersectan espacialmente» (comparten alguna porción del espacio) y FALSE si no lo hacen (son disjuntas).
ST_Overlaps(geometry A, geometry B): Devuelve TRUE si las geometrías comparten espacio, son de la misma dimensión, pero no están completamente contenidas una por la otra.
ST_Touches(geometry A, geometry B): Devuelve TRUE si las geometrías tienen al menos un punto en común, pero sus interiores no se intersectan.
ST_Within(geometry A , geometry B): Devuelve true si la geometría A está completamente dentro de la geometría B