9. Geometrías¶
9.1. Introducción¶
En la sección anterior, cargamos una variedad de datos. Antes de comenzar a trabajar con ellos, veamos algunos ejemplos más simples. En pgAdmin, selecciona nuevamente la base de datos nyc y abre la herramienta de consultas SQL. Pega este código de ejemplo en el editor SQL de pgAdmin (eliminando cualquier texto que haya allí) y ejecútalo.
CREATE TABLE geometries (name varchar, geom geometry);
INSERT INTO geometries VALUES
('Point', 'POINT(0 0)'),
('Linestring', 'LINESTRING(0 0, 1 1, 2 1, 2 2)'),
('Polygon', 'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
('PolygonWithHole', 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))'),
('Collection', 'GEOMETRYCOLLECTION(POINT(2 0),POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)))');
SELECT name, ST_AsText(geom) FROM geometries;

El ejemplo anterior crea una tabla (geometries) y luego inserta cinco geometrías: un punto, una línea, un polígono, un polígono con un agujero y una colección. Finalmente, las filas insertadas se seleccionan y se muestran en el panel de salida.
9.2. Tablas de metadatos¶
De acuerdo con la especificación Simple Features for SQL (SFSQL), PostGIS proporciona dos tablas para rastrear e informar sobre los tipos de geometría disponibles en una base de datos determinada.
La primera tabla, spatial_ref_sys, define todos los sistemas de referencia espacial conocidos por la base de datos (se explicará con más detalle más adelante).
La segunda tabla (en realidad, una vista), geometry_columns, proporciona una lista de todas las «features» (objetos con atributos geométricos) y los detalles básicos de esas entidades.

Veamos la tabla geometry_columns en nuestra base de datos. Pega este comando en la herramienta de consultas como antes:
SELECT * FROM geometry_columns;

f_table_catalog, f_table_schema y f_table_name proveen el nombre completo de la tabla de entidades que contiene una geometría. Dado que PostgreSQL no usa catálogos, f_table_catalog suele estar vacío.
f_geometry_column es el nombre de la columna que contiene la geometría. En tablas con múltiples columnas geométricas, habrá un registro por cada una.
coord_dimension y srid definen, respectivamente, la dimensión de la geometría (2, 3 o 4 dimensiones) y el identificador del sistema de referencia espacial que remite a la tabla spatial_ref_sys.
La columna type define el tipo de geometría. Hemos visto hasta ahora Point y Linestring.
Consultando esta tabla, los clientes SIG y bibliotecas pueden determinar qué esperar al recuperar datos y pueden realizar cualquier proyección, procesamiento o representación necesarios sin tener que inspeccionar cada geometría.
Nota
¿Algunas de tus tablas nyc no tienen un srid de 26918? Es fácil corregirlo actualizando la tabla.
ALTER TABLE nyc_neighborhoods
ALTER COLUMN geom
TYPE Geometry(MultiPolygon, 26918)
USING ST_SetSRID(geom, 26918);
9.3. Representación de objetos del mundo real¶
La especificación Simple Features for SQL (SFSQL), estándar guía original para el desarrollo de PostGIS, define cómo se representa un objeto del mundo real. Al tomar una forma continua y digitalizarla a una resolución fija se logra una representación aceptable del objeto. SFSQL solo manejaba representaciones bidimensionales. PostGIS ha extendido esto para incluir representaciones en 3 y 4 dimensiones; más recientemente la especificación SQL-Multimedia Parte 3 (SQL/MM) ha definido oficialmente su propia representación.
Nuestra tabla de ejemplo contiene una mezcla de diferentes tipos de geometrías. Podemos recopilar información general sobre cada objeto usando funciones que leen los metadatos de la geometría.
ST_GeometryType(geometry) devuelve el tipo de geometría
ST_NDims(geometry) devuelve el número de dimensiones de la geometría
ST_SRID(geometry) devuelve el número identificador de referencia espacial de la geometría
SELECT name, ST_GeometryType(geom), ST_NDims(geom), ST_SRID(geom)
FROM geometries;
name | st_geometrytype | st_ndims | st_srid
-----------------+-----------------------+----------+---------
Point | ST_Point | 2 | 0
Polygon | ST_Polygon | 2 | 0
PolygonWithHole | ST_Polygon | 2 | 0
Collection | ST_GeometryCollection | 2 | 0
Linestring | ST_LineString | 2 | 0
9.3.1. Puntos¶

Un punto espacial representa una única ubicación en la Tierra. Este punto se representa por una sola coordenada (que puede incluir 2, 3 o 4 dimensiones). Los puntos se usan para representar objetos cuando los detalles exactos, como forma y tamaño, no son importantes en la escala objetivo. Por ejemplo, las ciudades en un mapa del mundo pueden describirse como puntos, mientras que un mapa de un estado individual podría representarlas como polígonos.
SELECT ST_AsText(geom)
FROM geometries
WHERE name = 'Point';
POINT(0 0)
Algunas funciones espaciales específicas para trabajar con puntos son:
ST_X(geometry) devuelve la coordenada X
ST_Y(geometry) devuelve la coordenada Y
Por tanto, podemos leer las coordenadas de un punto como:
SELECT ST_X(geom), ST_Y(geom)
FROM geometries
WHERE name = 'Point';
Las estaciones de metro de Nueva York (nyc_subway_stations) son un conjunto de datos representado como puntos. La siguiente consulta SQL devuelve la geometría asociada con un punto (en la columna ST_AsText).
SELECT name, ST_AsText(geom)
FROM nyc_subway_stations
LIMIT 1;
9.3.2. Linestrings¶

Una linestring es un camino entre ubicaciones. Toma la forma de una serie ordenada de dos o más puntos. Las carreteras y ríos se representan típicamente como linestrings. Una linestring se dice que está cerrada si comienza y termina en el mismo punto. Se dice que es simple si no se cruza ni se toca a sí misma (excepto en sus extremos si está cerrada). Una linestring puede ser tanto cerrada como simple.
La red de calles de Nueva York (nyc_streets) se cargó anteriormente en el taller. Este conjunto de datos contiene detalles como nombre y tipo. Una calle real puede consistir en muchas linestrings, cada una representando un segmento de vía con diferentes atributos.
La siguiente consulta SQL devuelve la geometría asociada con una linestring (en la columna ST_AsText).
SELECT ST_AsText(geom)
FROM geometries
WHERE name = 'Linestring';
LINESTRING(0 0, 1 1, 2 1, 2 2)
Algunas funciones espaciales específicas para trabajar con linestrings son:
ST_Length(geometry) devuelve la longitud de la linestring
ST_StartPoint(geometry) devuelve la primera coordenada como un punto
ST_EndPoint(geometry) devuelve la última coordenada como un punto
ST_NPoints(geometry) devuelve el número de coordenadas en la linestring
Entonces, la longitud de nuestro linestring es:
SELECT ST_Length(geom)
FROM geometries
WHERE name = 'Linestring';
3.41421356237309
9.3.3. Polígonos¶

Un polígono es una representación de un área. El límite exterior del polígono está representado por un anillo. Este anillo es una linestring que es a la vez cerrada y simple. Los agujeros dentro del polígono también se representan mediante anillos.
Los polígonos se usan para representar objetos cuyo tamaño y forma son importantes. Límites de ciudades, parques, huellas de edificios o cuerpos de agua se representan comúnmente como polígonos cuando la escala es lo suficientemente grande para ver su área. Carreteras y ríos a veces pueden representarse como polígonos.
La siguiente consulta SQL devuelve la geometría asociada con un polígono (en la columna ST_AsText).
SELECT ST_AsText(geom)
FROM geometries
WHERE name LIKE 'Polygon%';
Nota
En lugar de usar un signo =
en nuestra cláusula WHERE
, estamos usando el operador LIKE
para realizar una operación de coincidencia de cadenas. Puede que estés acostumbrado al símbolo * como comodín de coincidencia, pero en SQL se usa el símbolo %
junto con el operador LIKE
para indicar “cualquier carácter”.
POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))
POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))
El primer polígono tiene solo un anillo. El segundo tiene un «agujero» interior. La mayoría de los sistemas gráficos incluyen el concepto de polígono, pero los sistemas GIS son relativamente únicos al permitir que los polígonos tengan agujeros explícitamente.

Algunas funciones espaciales específicas para trabajar con polígonos son:
ST_Area(geometría) devuelve el área de la geometría
ST_NRings(geometry) devuelve el número de anillos, usualmente 1 (o más si hay agujeros)
ST_ExteriorRing(geometry) devuelve el anillo exterior como una linestring
ST_InteriorRingN(geometry,n) devuelve un anillo interior específico como una linestring
ST_Perimeter(geometry) devuelve la longitud de todos los anillos
Podemos calcular el área de nuestros polígonos usando la función de área:
SELECT name, ST_Area(geom)
FROM geometries
WHERE name LIKE 'Polygon%';
Polygon 1
PolygonWithHole 99
Observe que el polígono con un agujero tiene un área que corresponde al área de la envolvente exterior (un cuadrado de 10x10) menos el área del agujero (un cuadrado de 1x1).
9.3.4. Colecciones¶
Existen cuatro tipos de colecciones, que agrupan múltiples geometrías simples en conjuntos.
MultiPoint, una colección de puntos
MultiLineString, una colección de líneas
MultiPolygon, una colección de polígonos
GeometryCollection, una colección heterogénea de cualquier geometría (incluyendo otras colecciones)
Las colecciones son otro concepto que aparece en el software SIG más que en el software gráfico genérico. Son útiles para modelar directamente objetos del mundo real como objetos espaciales. Por ejemplo, ¿cómo modelar un lote dividido por un derecho de vía? Como un MultiPolygon, con una parte a cada lado del derecho de vía.

Nuestro ejemplo de colección contiene un polígono y un punto:
SELECT name, ST_AsText(geom)
FROM geometries
WHERE name = 'Collection';
GEOMETRYCOLLECTION(POINT(2 0),POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)))

Algunas funciones espaciales específicas para trabajar con colecciones son:
ST_NumGeometries(geometry) devuelve el número de partes en la colección
ST_GeometryN(geometry,n) devuelve la parte especificada
ST_Area(geometry) devuelve el área total de todas las partes poligonales
ST_Length(geometry) devuelve la longitud total de todas las partes lineales
9.4. Entrada y salida de geometrías¶
Dentro de la base de datos, las geometrías se almacenan en disco en un formato usado solo por el programa PostGIS. Para que programas externos puedan insertar y recuperar geometrías útiles, deben convertirse a un formato que otras aplicaciones puedan entender. Afortunadamente, PostGIS admite la emisión y consumo de geometrías en muchos formatos:
Well-known text (WKT)
ST_GeomFromText(text, srid) devuelve
geometry
ST_AsText(geometry) devuelve
text
ST_AsEWKT(geometry) devuelve``text``
Well-known binary (WKB)
ST_GeomFromWKB(bytea) devuelve
geometry
ST_AsBinary(geometry) devuelve
bytea
ST_AsEWKB(geometry) devuelve
bytea
Geographic Mark-up Language (GML)
ST_GeomFromGML(text) devuelve
geometry
ST_AsGML(geometry) devuelve
text
Keyhole Mark-up Language (KML)
ST_GeomFromKML(text) devuelve
geometry
ST_AsKML(geometry) devuelve
text
-
ST_AsGeoJSON(geometry) devuelve
text
Scalable Vector Graphics (SVG)
ST_AsSVG(geometry) devuelve
text
El uso más común de un constructor es convertir una representación en texto de una geometría en una representación interna:
Además del parámetro de texto con la representación de la geometría, también hay un parámetro numérico que provee el SRID de la geometría.
La siguiente consulta SQL muestra un ejemplo de representación en WKB (la llamada a encode() es necesaria para convertir la salida binaria en una forma ASCII para impresión):
SELECT encode(
ST_AsBinary(ST_GeometryFromText('LINESTRING(0 0,1 0)')),
'hex');
01020000000200000000000000000000000000000000000000000000000000f03f0000000000000000
Para efectos de este taller continuaremos usando WKT para asegurar que se puedan leer y entender las geometrías que estamos viendo. Sin embargo, en la mayoría de procesos reales, como ver datos en una aplicación SIG, transferir datos a un servicio web o procesar datos remotamente, WKB es el formato preferido.
Dado que WKT y WKB fueron definidos en la especificación SFSQL, no manejan geometrías en 3 o 4 dimensiones. Para estos casos, PostGIS ha definido los formatos Extended Well Known Text (EWKT) y Extended Well Known Binary (EWKB). Estos proveen las mismas capacidades de formato de WKT y WKB con la dimensionalidad añadida.
Aquí un ejemplo de una linestring 3D en WKT:
SELECT ST_AsText(ST_GeometryFromText('LINESTRING(0 0 0,1 0 0,1 1 2)'));
LINESTRING Z (0 0 0,1 0 0,1 1 2)
Observa que la representación en texto cambia. Esto se debe a que la rutina de entrada de texto de PostGIS es flexible en lo que consume. Él consumirá
EWKB en hexadecimal
extended well-known text, y
well-known text según el estándar ISO.
En la salida, la función ST_AsText es conservadora y solo genera texto estándar well-known ISO.
Además de la función ST_GeometryFromText, existen muchas otras formas de crear geometrías a partir de texto well-known o entradas con formatos similares:
-- Using ST_GeomFromText with the SRID parameter
SELECT ST_GeomFromText('POINT(2 2)',4326);
-- Using ST_GeomFromText without the SRID parameter
SELECT ST_SetSRID(ST_GeomFromText('POINT(2 2)'),4326);
-- Using a ST_Make* function
SELECT ST_SetSRID(ST_MakePoint(2, 2), 4326);
-- Using PostgreSQL casting syntax and ISO WKT
SELECT ST_SetSRID('POINT(2 2)'::geometry, 4326);
-- Using PostgreSQL casting syntax and extended WKT
SELECT 'SRID=4326;POINT(2 2)'::geometry;
Además de los emisores para los distintos formatos (WKT, WKB, GML, KML, JSON, SVG), PostGIS también tiene consumidores para cuatro de ellos (WKT, WKB, GML, KML). La mayoría de aplicaciones usan las funciones de creación de geometrías WKT o WKB, pero las otras también funcionan. Aquí un ejemplo que consume GML y produce JSON:
SELECT ST_AsGeoJSON(ST_GeomFromGML('<gml:Point><gml:coordinates>1,1</gml:coordinates></gml:Point>'));

9.5. Conversión desde texto¶
Las cadenas WKT que hemos visto hasta ahora han sido de tipo “text” y las hemos convertido al tipo “geometry” usando funciones de PostGIS como ST_GeomFromText().
PostgreSQL incluye una sintaxis abreviada que permite convertir datos de un tipo a otro, la sintaxis de casting, oldata::newtype. Por ejemplo, este SQL convierte un doble en una cadena de texto.
SELECT 0.9::text;
Menos trivial, este SQL convierte una cadena WKT en una geometría:
SELECT 'POINT(0 0)'::geometry;
Una cosa a tener en cuenta al usar casting para crear geometrías: a menos que especifiques el SRID, obtendrás una geometría con un SRID desconocido. Puedes especificar el SRID usando la forma «extendida» de well-known text, que incluye un bloque SRID al inicio:
SELECT 'SRID=4326;POINT(0 0)'::geometry;
Es muy común usar la notación de casting cuando se trabaja con WKT, así como con columnas geometry y geography (ver Geografía).
9.6. Lista de funciones¶
ST_Area: Devuelve el área de la superficie si es un polígono o multipolígono. Para el tipo «geometry» el área está en unidades del SRID. Para «geography» el área está en metros cuadrados.
ST_AsText: Devuelve la representación Well-Known Text (WKT) de la geometría/geografía sin metadatos SRID.
ST_AsBinary: Devuelve la representación Well-Known Binary (WKB) de la geometría/geografía sin metadatos SRID.
ST_EndPoint: Devuelve el último punto de una geometría LINESTRING como un POINT.
ST_AsEWKB: Devuelve la representación Well-Known Binary (WKB) de la geometría con metadatos SRID.
ST_AsEWKT: Devuelve la representación Well-Known Text (WKT) de la geometría con metadatos SRID.
ST_AsGeoJSON: Devuelve la geometría como un elemento GeoJSON.
ST_AsGML: Devuelve la geometría como un elemento GML versión 2 o 3.
ST_AsKML: Devuelve la geometría como un elemento KML. Varias variantes. Versión predeterminada=2, precisión predeterminada=15.
ST_AsSVG: Devuelve una geometría en datos de ruta SVG dada una geometría u objeto geográfico.
ST_ExteriorRing: Devuelve una línea que representa el anillo exterior de la geometría POLYGON. Devuelve NULL si la geometría no es un polígono. No funciona con MULTIPOLYGON
ST_GeometryN: Devuelve la geometría N-ésima (1-based) si la geometría es GEOMETRYCOLLECTION, MULTIPOINT, MULTILINESTRING, MULTICURVE o MULTIPOLYGON. De lo contrario, devuelve NULL.
ST_GeomFromGML: Toma como entrada una representación GML de geometría y produce un objeto de geometría PostGIS.
ST_GeomFromKML: Toma como entrada una representación KML de geometría y produce un objeto de geometría PostGIS
ST_GeomFromText: Devuelve un valor ST_Geometry especificado a partir de una representación Well-Known Text (WKT).
ST_GeomFromWKB: Crea una instancia de geometría a partir de una representación Well-Known Binary (WKB) y un SRID opcional.
ST_GeometryType: Devuelve el tipo de geometría del valor ST_Geometry.
ST_InteriorRingN: Devuelve el N-ésimo anillo interior (linestring) de la geometría poligonal. Devuelve NULL si la geometría no es un polígono o si N está fuera de rango.
ST_Length: Devuelve la longitud 2D de la geometría si es una línea o multilínea. Para geometry está en unidades de la referencia espacial y para geography está en metros (esferoide predeterminado)
ST_NDims: Devuelve la dimensión de coordenadas de la geometría como un entero pequeño. Los valores son: 2, 3 o 4.
ST_NPoints: Devuelve el número de puntos (vértices) en una geometría.
ST_NRings: Si la geometría es un polígono o multipolígono devuelve el número de anillos.
ST_NumGeometries: Si la geometría es una GEOMETRYCOLLECTION (o MULTI*) devuelve el número de geometrías, de lo contrario devuelve NULL.
ST_Perimeter: Devuelve la medida de longitud del límite de un valor ST_Surface o ST_MultiSurface (Polygon, Multipolygon)
ST_SRID: Devuelve el identificador de referencia espacial para la ST_Geometry como se define en la tabla spatial_ref_sys.
ST_StartPoint: Devuelve el primer punto de una geometría LINESTRING como un POINT.
ST_X: Devuelve la coordenada X del punto, o NULL si no está disponible. La entrada debe ser un punto.
ST_Y: Devuelve la coordenada Y del punto, o NULL si no está disponible. La entrada debe ser un punto.