Aggiunta di una colonna geometrica aggiuntiva in PostGIS?


10

Sto importando molti set di geodati in PostGIS e ne hanno di diversi SRID. (Alcuni hanno EPSG:3857, alcuni EPSG:4326, qualcos'altro).

Vorrei crearne uno aggiuntivo geometry column, ad es. the_geom_mercatorcon SRID EPSG:3857e mantieni anche la geomcolonna originale in qualunque cosa SRIDsia entrata.

Come posso farlo con una funzione PostGIS?

Risposte:


18

Per aggiungere una colonna a una tabella esistente, utilizzare ALTER TABLE DDL , ad esempio:

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

che può essere popolato da un'altra colonna (the_geom) usando:

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

(la terza riga FROM spatial_ref_sys ...non è necessaria, ma protegge i tentativi di trasformazione con proiezioni sconosciute o non valide, che generano errori).

E se questa tabella deve essere mantenuta (aggiunta / aggiornata), è possibile utilizzare una funzione di trigger per aggiornare the_geom_mercator, ad esempio:

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();

Si noti che ST_Transform dovrebbe intercettare errori e mostrare un avviso, ad esempio:

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

Grazie per un'ottima risposta È davvero bello usare i grilletti, inizierò a farlo. Potrei invece aggiungere quel trigger al database, in modo da non dover aggiungere questo trigger per ogni nuova tabella?
knutole,

Sto aggiungendo i dati a Postgis shp2psqle la tabella viene creata quando viene inviata psql. Quindi non posso davvero aggiungere un trigger prima che esista una tabella?
knutole,

1
Se si utilizza shp2pgsql, utilizzare un'istruzione di aggiornamento, vedere sopra. Un trigger è utile se è necessario mantenere una tabella, ma non per il caricamento.
Mike T,

2

Per prima cosa crea una normale tabella non spaziale, che hai già. In secondo luogo aggiungere una colonna spaziale alla tabella utilizzando la funzione "AddGeometryColumn" di OpenGIS.

Esempio:

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

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

1

È possibile creare una colonna di geometria SRID non vincolata per contenere la forma nativa e trasformarla in esistente. Ecco un esempio inventato supponendo che tu abbia poligoni che stai copiando da una tabella di gestione temporanea (se hai mescolato, puoi impostare il tipo su geometria, ad esempio geometria (Geometria, 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;

Grazie per la tua risposta. C'è un modo per farlo su tabelle già esistenti (ad es. Senza utilizzare tabelle di gestione temporanea)? Diciamo che ho già una tabella, con una geomcolonna, e voglio semplicemente aggiungere un'altra the_geom_webmercatorcolonna. Come potrei farlo?
knutole,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.