Hinzufügen einer zusätzlichen Geometriespalte in PostGIS?

10

Ich importiere viele Sätze von Geodaten in PostGIS und sie haben unterschiedliche SRID. (Einige haben EPSG:3857, einige EPSG:4326, andere etwas anderes).

Ich möchte ein zusätzliches erstellen geometry column, z. the_geom_mercatormit SRID EPSG:3857, und behalten Sie auch die ursprüngliche geomSpalte in was auch immer SRIDes kam.

Wie kann ich das mit einer PostGIS-Funktion machen?

Knutole
quelle

Antworten:

18

Verwenden Sie zum Hinzufügen einer Spalte zu einer vorhandenen Tabelle die DDL ALTER TABLE , z.

ALTER TABLE my_table
  ADD COLUMN the_geom_mercator
    geometry(Geometry,3857);

die aus einer anderen Spalte (the_geom) ausgefüllt werden kann mit:

UPDATE my_table SET
  the_geom_mercator = ST_Transform(the_geom, 3857)
FROM spatial_ref_sys
WHERE ST_SRID(the_geom) = srid;

(Die dritte Zeile FROM spatial_ref_sys ...ist nicht erforderlich, schützt jedoch Transformationsversuche mit unbekannten oder ungültigen Projektionen, die Fehler auslösen.)

Und wenn diese Tabelle gepflegt (hinzugefügt / aktualisiert) werden soll, können Sie eine Triggerfunktion verwenden, um den_geom_mercator zu aktualisieren, z.

CREATE OR REPLACE FUNCTION my_table_tg_fn() RETURNS trigger AS
$BODY$BEGIN
  IF TG_OP = 'INSERT' AND NEW.the_geom ISNULL THEN
    RETURN NEW; -- no new geometry
  ELSIF TG_OP = 'UPDATE' THEN
    IF NEW.the_geom IS NOT DISTINCT FROM OLD.the_geom THEN
      RETURN NEW; -- same old geometry
    END IF;
  END IF;
  -- Attempt to transform a geometry
  BEGIN
    NEW.the_geom_mercator := ST_Transform(NEW.the_geom, 3857);
  EXCEPTION WHEN SQLSTATE 'XX000' THEN
    RAISE WARNING 'the_geom_mercator not updated: %', SQLERRM;
  END;
  RETURN NEW;
END;$BODY$ LANGUAGE plpgsql;

CREATE TRIGGER my_table_tg BEFORE INSERT OR UPDATE
   ON my_table FOR EACH ROW
   EXECUTE PROCEDURE my_table_tg_fn();

Beachten Sie, dass ST_Transform Fehler abfangen und eine Warnung anzeigen sollte, z.

postgis=# INSERT INTO my_table(the_geom)
postgis-# VALUES (ST_SetSRID(ST_MakePoint(0,1), 123))
postgis-# RETURNING the_geom, the_geom_mercator;
WARNING:  the_geom_mercator not updated: GetProj4StringSPI: Cannot find SRID (123) in spatial_ref_sys
-[ RECORD 1 ]-----+---------------------------------------------------
the_geom          | 01010000207B0000000000000000000000000000000000F03F
the_geom_mercator |

INSERT 0 1
Mike T.
quelle
Danke für eine tolle Antwort. Es ist wirklich ordentlich, Trigger zu verwenden, ich werde damit beginnen. Könnte ich diesen Trigger stattdessen zur Datenbank hinzufügen, damit ich diesen Trigger nicht für jede neue Tabelle hinzufügen muss?
Knutole
Ich füge Daten zu Postgis hinzu shp2psqlund die Tabelle wird erstellt, wenn sie weitergeleitet wird psql. Ich kann also keinen Trigger hinzufügen, bevor eine Tabelle existiert?
Knutole
1
Wenn Sie shp2pgsql verwenden, verwenden Sie eine Update-Anweisung (siehe oben). Ein Trigger ist nützlich, wenn Sie eine Tabelle pflegen müssen, aber nicht zum Laden.
Mike T
2

Erstellen Sie zunächst eine normale nicht räumliche Tabelle, die Sie bereits haben. Zweitens fügen Sie der Tabelle mit der OpenGIS-Funktion "AddGeometryColumn" eine räumliche Spalte hinzu.

Beispiel:

CREATE TABLE terrain_points ( 
ogc_fid serial NOT NULL, 
elevation double precision,
);

SELECT AddGeometryColumn('terrain_points', 'wkb_geometry', 3725, 'POINT', 3 );
hoogw
quelle
1

Sie können eine uneingeschränkte SRID-Geometriespalte erstellen, um das native Formular zu speichern und dann in ein vorhandenes zu transformieren. In diesem Beispiel wird davon ausgegangen, dass Sie Polygone haben, die Sie aus einer Staging-Tabelle kopieren (wenn Sie gemischt haben, können Sie den Typ auf Geometrie festlegen, z. B. Geometrie (Geometry, 3857):

CREATE TABLE poi(gid serial primary key, 
   geom_native geometry(POLYGON),  
   geom_mercator geometry(POLYGON,3857) );

INSERT INTO TABLE poi(geom_native, geom_mercator)
SELECT geom, ST_Transform(geom, 3857)
   FROM staging.imported_poly;
LR1234567
quelle
Danke für deine Antwort. Gibt es eine Möglichkeit, dies für bereits vorhandene Tabellen zu tun (dh ohne Staging-Tabellen zu verwenden)? Angenommen, ich habe bereits eine Tabelle mit einer geomSpalte und möchte einfach eine weitere the_geom_webmercatorSpalte hinzufügen . Wie würde ich das machen?
Knutole