16. Projektering av data¶
Jorden är inte platt, och det finns inget enkelt sätt att avbilda den på en platt papperskarta (eller datorskärm), så människor har kommit på alla möjliga geniala lösningar, var och en med för- och nackdelar. Vissa projektioner bevarar ytan, så att alla objekt har en relativ storlek i förhållande till varandra; andra projektioner bevarar vinklar (konforma) som Mercator-projektionen; vissa projektioner försöker hitta en bra mellanliggande mix med endast liten förvrängning på flera parametrar. Gemensamt för alla projektioner är att de omvandlar den (sfäriska) världen till ett platt kartesiskt koordinatsystem, och vilken projektion som ska väljas beror på hur du ska använda data.
Vi har redan stött på projektioner när vi laddade våra nyc-data. (Minns den där irriterande SRID 26918). Ibland behöver du dock transformera och omprojicera mellan spatiala referenssystem. PostGIS har inbyggt stöd för att ändra projektionen av data med hjälp av funktionen ST_Transform(geometry, srid). För att hantera de spatiala referensidentifierarna på geometrier tillhandahåller PostGIS funktionerna ST_SRID(geometry) och ST_SetSRID(geometry, srid).
Vi kan bekräfta SRID för våra data med funktionen ST_SRID:
SELECT ST_SRID(geom) FROM nyc_streets LIMIT 1;
26918
Och vad är definitionen av ”26918”? Som vi såg i ”loading data section”, finns definitionen i tabellen spatial_ref_sys
. Faktum är att två definitioner finns där. Definitionen ”well-known text” (WKT) finns i kolumnen srtext
, och det finns en andra definition i ”proj.4” format i kolumnen proj4text
.
SELECT * FROM spatial_ref_sys WHERE srid = 26918;
PostGIS reprojektionsmotor kommer att försöka hitta den bästa projektionen från tabellen spatial_ref_sys
:
auth_name / auth_srid Om proj kan hitta ett giltigt ”authority name” och ”authority srid” i sin interna katalog, kommer den att använda det för att generera en projektionsdefinition.
srtext Om proj kan tolka och skapa ett definitionsobjekt från
srtext
kommer det att användas.proj4text Slutligen kommer proj att försöka bearbeta
proj4text
.
All denna redundans innebär att allt du behöver för att skapa en ny projektion i PostGIS är antingen en giltig rtext
-sträng eller proj4text
-sträng. Alla par av namn/kod för gemensamma myndigheter är redan inlästa i tabellen som standard.
Om du har möjlighet att välja när du skapar en anpassad projektion, fyll i kolumnen rtext
, eftersom den kolumnen också används av externa program som GeoServer, QGIS och FME m.fl.
16.1. Jämförelse av data¶
Tillsammans definierar en koordinat och en SRID en plats på jordklotet. Utan en SRID är en koordinat bara ett abstrakt begrepp. Ett ”kartesiskt” koordinatplan definieras som ett ”platt” koordinatsystem placerat på jordens yta. Eftersom PostGIS-funktioner arbetar i ett sådant plan, kräver jämförelseoperationer att båda geometrierna representeras i samma SRID.
Om du matar in geometrier med olika SRID:er kommer du bara att få ett felmeddelande:
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)
Observera
Var försiktig så att du inte blir alltför nöjd med att använda ST_Transform för konvertering direkt. Spatiala index byggs upp med hjälp av SRID för de lagrade geometrierna. Om jämförelsen görs i en annan SRID används (ofta) inte spatiala index. Bästa praxis är att välja ett SRID för alla tabeller i databasen. Använd endast transformationsfunktionen när du läser eller skriver data till externa applikationer.
16.2. Omvandling av data¶
Om vi återgår till vår proj4-definition för SRID 26918 kan vi se att vår arbetsprojektion är UTM (Universal Transverse Mercator) i zon 18, med meter som måttenhet.
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"]]
Låt oss konvertera några data från vår arbetsprojektion till geografiska koordinater - även kända som ”longitud/latitud”.
För att konvertera data från en SRID till en annan måste du först verifiera att din geometri har en giltig SRID. Eftersom vi redan har bekräftat en giltig SRID behöver vi nästa SRID för projektionen att transformera till. Med andra ord, vad är SRID för geografiska koordinater?
Den vanligaste SRID:en för geografiska koordinater är 4326, vilket motsvarar ”longitud/latitud på sfäroiden WGS84”. Du kan se definitionen här:
Du kan också hämta definitionerna från tabellen 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"]]
Låt oss omvandla koordinaterna för tunnelbanestationen ”Broad St” till geografi:
SELECT ST_AsText(ST_Transform(geom,4326))
FROM nyc_subway_stations
WHERE name = 'Broad St';
POINT(-74.01067146887341 40.70710481558761)
Om du laddar data eller skapar en ny geometri utan att ange en SRID, kommer SRID-värdet att vara 0. Kom ihåg i Geometrier, att när vi skapade vår geometries
-tabell angav vi inte någon SRID. Om vi gör en sökning i vår databas kan vi förvänta oss att alla nyc_
-tabeller har SRID 26918, medan tabellen geometries
som standard har SRID 0.
Om du vill visa en tabells SRID-tilldelning ställer du en fråga till databasens tabell geometry_columns
.
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
Men om du vet vad koordinaternas SRID ska vara kan du ställa in den i efterhand genom att använda ST_SetSRID på geometrin. Då kommer du att kunna transformera geometrin till andra system.
SELECT ST_AsText(
ST_Transform(
ST_SetSRID(geom,26918),
4326)
)
FROM geometries;
16.3. Funktionslista¶
ST_AsText: Returnerar WKT-representationen (Well-Known Text) av geometrin/geografin utan SRID-metadata.
ST_SetSRID(geometry, srid): Ställer in SRID på en geometri till ett visst heltalsvärde.
ST_SRID(geometri): Returnerar den spatiala referensidentifieraren för ST_Geometry enligt definitionen i tabellen spatial_ref_sys.
ST_Transform(geometry, srid): Returnerar en ny geometri med dess koordinater transformerade till den SRID som refereras till av heltalsparametern.