Alterar o tipo de geometria de Ponto para Multiponto na tabela existente no PostGIS?

31

Existe uma função PostGIS que pode alterar o tipo de geometria para uma tabela existente?

Precisamos mudar de POINT para MULTIPOINT.

A tabela ficará vazia quando alterarmos o tipo de geometria e não podemos simplesmente soltar / criar a tabela.

Ulrik Balslev
fonte

Respostas:

62

Para o PostGIS 2.x , você pode usar o DDL ALTER TABLE usando uma expressão .

Para converter de uma geometria de peça única para peça múltipla, use ST_Multi :

ALTER TABLE my_table
    ALTER COLUMN geom TYPE geometry(MultiPoint,4326) USING ST_Multi(geom);

Para converter de uma geometria de várias partes para uma única parte, é um pouco mais complicado, pois você pode usar apenas uma parte e ignorar todas as outras partes (se elas existirem). Verifique seus dados primeiro para ver se você tem algumas geometrias com mais de uma parte:

SELECT COUNT(CASE WHEN ST_NumGeometries(geom) > 1 THEN 1 END) AS multi_geom,
       COUNT(geom) AS total_geom
FROM my_table;

Se você multi_geomvir maior que 0, corre o risco de perder dados e provavelmente deve mantê-los como uma geometria de várias partes. Se você vir 0, é seguro transformar em uma geometria de peça única com:

ALTER TABLE my_table
    ALTER COLUMN geom TYPE geometry(Point,4326) USING ST_GeometryN(geom, 1);

Para o PostGIS 1.x , é um pouco mais confuso, pois existem várias etapas (obrigado @ rec.thegeom!).

Supondo uma tabela my_tablee coluna de geometria geom, aqui estão as etapas para converter em várias partes:

-- 1. Remove the geom_type constraint (if existing)
ALTER TABLE my_table DROP CONSTRAINT enforce_geotype_geom;

-- 2. Update the geometry data to multi-part -- skip if it is an empty table
UPDATE my_table SET geom = ST_Multi(geom);

-- 3. Re-add a different geometry constraint for the new type
ALTER TABLE my_table ADD CONSTRAINT enforce_geotype_geom
  CHECK (geometrytype(geom) = 'MULTIPOINT'::text OR geom IS NULL);

-- 4. Update the geometry_columns metadata table
UPDATE geometry_columns SET type = 'MULTIPOINT'
WHERE f_table_schema = 'public' AND f_table_name = 'my_table' AND f_geometry_column = 'geom';
Mike T
fonte
Olá, Mike Toews (e Ulrik). Eu não acho que o seu segundo passo para o PostGIS 1.x seja necessário neste caso, Mike. Ulrik disse que a tabela estará vazia no momento da conversão de tipo, portanto, não haverá valores não-multi para causar um erro com algo como: 1) ALTER TABLE my_table DROP CONSTRAINT enforce_geotype_the_geom; 2) ALTER TABLE my_table ADD CONSTRAINT enforce_geotype_the_geom CHECK (geometrytype (the_geom) = 'MULTIPOINT' :: texto OU the_geom IS NULL); 3) UPDATE geometry_columns SET type = 'MULTIPOINT' WHERE f_table_name = 'minha_tabela'; (talvez o comentário sloppiest nunca - meu mau)
rec.thegeom
@ rec.thegeom correto; com uma tabela vazia, não haveria nada para atualizar. Obrigado por postar os comandos reais!
Mike T
Se você tiver dados complexos de várias formas GEOMETRYCOLLECTION (MULTIPOLYGON(...)), poderá alterar a consulta para detecção de mais de uma geometria. Com check like ST_NumGeometries(ST_CollectionHomogenize(geom)) > 1e use algo semelhante para USINGwith: ST_GeometryN(ST_Multi(ST_CollectionHomogenize (geom)), 1)ou similar.
Ravbaker
4

Mudança, acho que não. Mas você pode criar uma nova tabela com estrutura idêntica, exceto a coluna geom, e depois executar:

SELECT AddGeometryColumn('new-pt_table','geom',<SRID>,'MULTIPOINT',2);

INSERT INTO new_pt_table (attr1, attr2, attr3, ..., geom) 
SELECT attr1, attr2, attr3, ... , ST_Multi(geom) FROM old_pt_table;
Micha
fonte