Ajout d'une colonne de géométrie supplémentaire dans PostGIS?

10

J'importe de nombreux ensembles de géodonnées dans PostGIS, et ils ont différents SRID. (Certains l'ont EPSG:3857, certains EPSG:4326, quelque chose d'autre).

Je voudrais en créer un supplémentaire geometry column, par exemple. the_geom_mercatoravec SRID EPSG:3857, et conservez également la geomcolonne d' origine dans tout ce SRIDqu'elle contient.

Comment puis-je le faire avec une fonction PostGIS?

knutole
la source

Réponses:

18

Pour ajouter une colonne à une table existante, utilisez le DDL ALTER TABLE , par exemple:

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

qui peut être remplie à partir d'une autre colonne (the_geom) en utilisant:

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

(la troisième ligne FROM spatial_ref_sys ...n'est pas nécessaire, mais elle protège les tentatives de transformation avec des projections inconnues ou invalides, ce qui soulève des erreurs).

Et si cette table doit être maintenue (ajoutée / mise à jour), vous pouvez utiliser une fonction déclencheur pour mettre à jour le_geom_mercator, par exemple:

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

Notez que ST_Transform doit intercepter les erreurs et afficher un avertissement, par exemple:

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
la source
Merci pour une excellente réponse. C'est vraiment bien d'utiliser des déclencheurs, je vais commencer à le faire. Puis-je ajouter ce déclencheur à la base de données, de sorte que je n'ai pas à ajouter ce déclencheur pour chaque nouvelle table?
knutole
J'ajoute des données à PostGis avec shp2psqlet la table est créée lorsqu'elle est redirigée psql. Je ne peux donc pas vraiment ajouter de déclencheur avant que la table existe?
knutole
1
Si vous utilisez shp2pgsql, utilisez une instruction de mise à jour, voir ci-dessus. Un déclencheur est utile si vous devez gérer une table, mais pas pour le chargement.
Mike T
2

Créez d'abord une table non spatiale normale, que vous avez déjà. Ajoutez ensuite une colonne spatiale à la table à l'aide de la fonction OpenGIS "AddGeometryColumn".

Exemple:

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

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

Vous pouvez créer une colonne de géométrie SRID sans contrainte pour contenir la forme native, puis la transformer en existante. Voici un exemple artificiel en supposant que vous avez des polygones que vous copiez à partir d'une table intermédiaire (si vous avez mélangé, vous pouvez définir le type sur la géométrie, par exemple la géométrie (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
la source
Merci pour votre réponse. Existe-t-il un moyen de le faire sur des tables déjà existantes (c'est-à-dire sans utiliser de tables intermédiaires)? Disons que j'ai déjà une table, avec une geomcolonne, et je veux simplement ajouter une autre the_geom_webmercatorcolonne. Comment ferais-je ça?
knutole