¿Cambiar el tipo de geometría de punto a multipunto dentro de la tabla existente en PostGIS?

31

¿Existe una función PostGIS que pueda cambiar el tipo de geometría para una tabla existente?

Necesitamos cambiar de PUNTO a MULTIPUNTO.

La tabla estará vacía cuando cambiemos el tipo de geometría y no podemos simplemente soltar / crear la tabla.

Ulrik Balslev
fuente

Respuestas:

62

Para PostGIS 2.x , puede usar ALTER TABLE DDL usando una expresión .

Para convertir de una geometría de una sola parte a varias, use ST_Multi :

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

Para convertir de una geometría de varias partes a una de una sola parte, es un poco más complicado ya que solo puede usar una parte e ignorar todas las demás (si existen). Primero verifique sus datos para ver si tiene algunas geometrías con más de una parte:

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

Si ve multi_geommás de 0, correrá el riesgo de perder datos, y probablemente debería mantenerlos como una geometría de varias partes. Si ve 0, entonces es seguro convertirlo en una geometría de una sola pieza con:

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

Para PostGIS 1.x , es un poco más complicado, ya que hay varios pasos (¡gracias @ rec.thegeom!).

Suponiendo una tabla my_tabley una columna de geometría geom, estos son los pasos para convertir a varias 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
fuente
Hola @ Mike Toews (y Ulrik). No creo que tu segundo paso para PostGIS 1.x sea necesario en este caso, Mike. Ulrik dijo que la tabla estará vacía en el momento de la conversión de tipo, por lo que no habrá ningún valor no múltiple para causar un error con 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' :: text OR the_geom IS NULL); luego 3) ACTUALIZAR geometry_columns SET type = 'MULTIPOINT' WHERE f_table_name = 'my_table'; (quizás el comentario más
descuidado de
@ rec.thegeom correcto; con una tabla vacía no habría nada que actualizar. ¡Gracias por publicar los comandos reales!
Mike T
Si tiene datos complejos en varias formas como, GEOMETRYCOLLECTION (MULTIPOLYGON(...))entonces es posible que desee cambiar la consulta para la detección de más de una geometría. Con check like ST_NumGeometries(ST_CollectionHomogenize(geom)) > 1y usa algo similar para USINGwith: ST_GeometryN(ST_Multi(ST_CollectionHomogenize (geom)), 1)o similar.
Ravbaker
4

Cambio, no lo creo. Pero puede crear una nueva tabla con una estructura idéntica, excepto la columna geom, luego ejecutar:

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
fuente