Adicionando coluna de geometria adicional no PostGIS?


10

Estou importando muitos conjuntos de dados geográficos para o PostGIS, e eles têm diferentes SRID. (Alguns têm EPSG:3857, alguns EPSG:4326, alguns algo mais).

Eu gostaria de criar um adicional geometry column, por exemplo. the_geom_mercatorcom SRID EPSG:3857e também mantenha a geomcoluna original no local em que SRIDfoi inserida.

Como posso fazer isso com uma função PostGIS?

Respostas:


18

Para adicionar uma coluna a uma tabela existente, use o ALTER TABLE DDL , por exemplo:

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

que pode ser preenchido de outra coluna (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;

(a terceira linha FROM spatial_ref_sys ...não é necessária, mas protege as tentativas de transformação com projeções desconhecidas ou inválidas, o que gera erros).

E se essa tabela for mantida (adicionada / atualizada), você pode usar uma função de gatilho para atualizar o the_geom_mercator, por exemplo:

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

Observe que ST_Transform deve capturar erros e mostrar um aviso, por exemplo:

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

Obrigado por uma ótima resposta. É muito legal usar gatilhos, vou começar a fazê-lo. Em vez disso, eu poderia adicionar esse gatilho ao banco de dados, para não precisar adicionar esse gatilho para cada nova tabela?
knutole

Estou adicionando dados ao postgis shp2psqle a tabela é criada quando transmitida psql. Então, eu realmente não posso adicionar um gatilho antes da tabela existir?
knutole

1
Se você estiver usando shp2pgsql, use uma instrução de atualização, veja acima. Um acionador é útil se você precisar manter uma tabela, mas não para carregar.
Mike T

2

Primeiro, crie uma tabela não espacial normal, que você já possui. Segundo, adicione uma coluna espacial à tabela usando a função "AddGeometryColumn" do OpenGIS.

Exemplo:

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

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

1

Você pode criar uma coluna de geometria SRID irrestrita para manter o formulário nativo e depois transformar em existente. Aqui está um exemplo artificial, supondo que você tenha polígonos que você está copiando de uma tabela de preparo (se você tiver mixado, poderá definir o tipo como geometry, por exemplo, geometry (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;

Obrigado pela sua resposta. Existe alguma maneira de fazer isso em tabelas já existentes (ou seja, sem usar tabelas intermediárias)? Digamos que eu já tenho uma tabela, com uma geomcoluna, e simplesmente quero adicionar outra the_geom_webmercatorcoluna. Como eu faria isso?
Knutole
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.