16. Proyección de datos¶
La Tierra no es plana, y no hay una manera simple de representarla en un mapa de papel plano (o en una pantalla de computadora), por lo que se han ideado todo tipo de soluciones ingeniosas, cada una con pros y contras. Algunas proyecciones preservan el área, de modo que todos los objetos tienen un tamaño relativo entre sí; otras proyecciones preservan los ángulos (conformes), como la proyección de Mercator; algunas proyecciones intentan encontrar un buen equilibrio intermedio con poca distorsión en varios parámetros. Lo común a todas las proyecciones es que transforman el mundo (esférico) en un sistema de coordenadas cartesianas planas, y la proyección a elegir depende de cómo se usarán los datos.
Ya nos hemos encontrado con proyecciones cuando cargamos nuestros datos de nyc. (Recuerde ese molesto SRID 26918). Sin embargo, a veces es necesario transformar y reproyectar entre sistemas de referencia espacial. PostGIS incluye soporte integrado para cambiar la proyección de los datos, usando la función ST_Transform(geometry, srid). Para gestionar los identificadores de referencia espacial en geometrías, PostGIS proporciona las funciones ST_SRID(geometry) y ST_SetSRID(geometry, srid).
Podemos confirmar el SRID de nuestros datos con la función ST_SRID:
SELECT ST_SRID(geom) FROM nyc_streets LIMIT 1;
26918
¿Y cuál es la definición de «26918»? Como vimos en «sección de carga de datos», la definición está contenida en la tabla spatial_ref_sys
. De hecho, hay dos definiciones allí. La definición en «texto bien conocido» (WKT) está en la columna srtext
, y hay una segunda definición en formato «proj.4» en la columna proj4text
.
SELECT * FROM spatial_ref_sys WHERE srid = 26918;
El motor de reproyección de PostGIS intentará encontrar la mejor proyección de la tabla spatial_ref_sys
:
auth_name / auth_srid Si proj puede encontrar un «nombre de autoridad» y un «srid de autoridad» válidos en su catálogo interno, lo usará para generar una definición de proyección.
srtext Si proj puede analizar y formar un objeto de definición a partir de
srtext
, lo usará.proj4text Finalmente, proj intentará procesar el
proj4text
.
Toda esta redundancia significa que todo lo que necesita para crear una nueva proyección en PostGIS es una cadena srtext
válida o una cadena proj4text
válida. Todos los pares comunes de nombre/código de autoridad ya están cargados en la tabla de manera predeterminada.
Si tiene la opción al crear una proyección personalizada, complete la columna srtext
, ya que esa columna también es utilizada por programas externos como GeoServer, QGIS, y FME, entre otros.
16.1. Comparación de datos¶
Tomados en conjunto, una coordenada y un SRID definen una ubicación en el globo. Sin un SRID, una coordenada es solo una noción abstracta. Un plano de coordenadas «cartesiano» se define como un sistema de coordenadas «plano» colocado en la superficie de la Tierra. Dado que las funciones de PostGIS funcionan en dicho plano, las operaciones de comparación requieren que ambas geometrías estén representadas en el mismo SRID.
Si introduce geometrías con SRID diferentes, solo obtendrá un error:
SELECT ST_Equals(
ST_GeomFromText('POINT(0 0)', 4326),
ST_GeomFromText('POINT(0 0)', 26918)
);
ERROR: ST_Equals: Operation on mixed SRID geometries (Point, 4326) != (Point, 26918)
Nota
Tenga cuidado de abusar del uso de ST_Transform para conversiones al vuelo. Los índices espaciales se construyen usando el SRID de las geometrías almacenadas. Si las comparaciones se realizan en un SRID diferente, los índices espaciales (a menudo) no se usan. La mejor práctica es elegir un SRID para todas las tablas de su base de datos. Use la función de transformación solo cuando esté leyendo o escribiendo datos en aplicaciones externas.
16.2. Transformación de datos¶
Si volvemos a nuestra definición proj4 para el SRID 26918, podemos ver que nuestra proyección de trabajo es UTM (Transversa Universal de Mercator) de la zona 18, con metros como unidad de medida.
SELECT srtext FROM spatial_ref_sys WHERE srid = 26918;
PROJCS["NAD83 / UTM zone 18N",
GEOGCS["NAD83",
DATUM["North_American_Datum_1983",
SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],
TOWGS84[0,0,0,0,0,0,0],
AUTHORITY["EPSG","6269"]],
PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4269"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",0],
PARAMETER["central_meridian",-75],
PARAMETER["scale_factor",0.9996],
PARAMETER["false_easting",500000],
PARAMETER["false_northing",0],
UNIT["metre",1,AUTHORITY["EPSG","9001"]],
AXIS["Easting",EAST],AXIS["Northing",NORTH],
AUTHORITY["EPSG","26918"]]
Convirtamos algunos datos de nuestra proyección de trabajo a coordenadas geográficas —también conocidas como «longitud/latitud».
Para convertir datos de un SRID a otro, primero debe verificar que su geometría tenga un SRID válido. Como ya hemos confirmado un SRID válido, lo siguiente que necesitamos es el SRID de la proyección a la que se desea transformar. En otras palabras, ¿cuál es el SRID de las coordenadas geográficas?
El SRID más común para coordenadas geográficas es 4326, que corresponde a «longitud/latitud en el esferoide WGS84». Puede ver la definición aquí:
También puede extraer las definiciones de la tabla spatial_ref_sys
:
SELECT srtext FROM spatial_ref_sys WHERE srid = 4326;
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4326"]]
Convirtamos las coordenadas de la estación de metro “Broad St” a geográficas:
SELECT ST_AsText(ST_Transform(geom,4326))
FROM nyc_subway_stations
WHERE name = 'Broad St';
POINT(-74.01067146887341 40.70710481558761)
Si carga datos o crea una nueva geometría sin especificar un SRID, el valor de SRID será 0. Recuerde en geometrías, que cuando creamos nuestra tabla geometries
no especificamos un SRID. Si consultamos nuestra base de datos, deberíamos esperar que todas las tablas nyc_
tengan un SRID de 26918, mientras que la tabla geometries
tiene de manera predeterinada un SRID de 0.
Para ver la asignación de SRID de una tabla, consulte la tabla geometry_columns
de la base de datos.
SELECT f_table_name AS name, srid
FROM geometry_columns;
name | srid
---------------------+-------
nyc_census_blocks | 26918
nyc_homicides | 26918
nyc_neighborhoods | 26918
nyc_streets | 26918
nyc_subway_stations | 26918
geometries | 0
Sin embargo, si sabe cuál se supone que es el SRID de las coordenadas, puede establecerlo a posteriori usando ST_SetSRID en la geometría. Luego podrá transformar la geometría a otros sistemas.
SELECT ST_AsText(
ST_Transform(
ST_SetSRID(geom,26918),
4326)
)
FROM geometries;
16.3. Lista de funciones¶
ST_AsText: Devuelve la representación Well-Known Text (WKT) de la geometría/geografía sin metadatos SRID.
ST_SetSRID(geometry, srid) <http://postgis.net/docs/ST_SetSRID.html>_: Establece el SRID de una geometría en un valor entero específico.
ST_SRID(geometry) <http://postgis.net/docs/ST_SRID.html>_: Devuelve el identificador de referencia espacial (SRID) de la geometría definida en la tabla spatial_ref_sys.
ST_Transform(geometry, srid): Devuelve una nueva geometría con sus coordenadas transformadas al SRID indicado.