Changer le type de géométrie de Point en Multipoint dans la table existante dans PostGIS?

31

Existe-t-il une fonction PostGIS qui peut changer le type de géométrie d'une table existante?

Nous devons passer de POINT à MULTIPOINT.

La table sera vide lorsque nous changerons le type de géométrie et nous ne pouvons pas simplement déposer / créer la table.

Ulrik Balslev
la source

Réponses:

62

Pour PostGIS 2.x , vous pouvez utiliser le DDL ALTER TABLE à l' aide d'une expression .

Pour convertir d'une géométrie mono-pièce en multi-pièce, utilisez ST_Multi :

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

Pour convertir d'une géométrie en plusieurs parties en une géométrie en une seule partie, c'est un peu plus compliqué car vous ne pouvez utiliser qu'une seule partie et ignorer toutes les autres parties (si elles existent). Vérifiez d'abord vos données pour voir si vous avez des géométries avec plus d'une pièce:

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

Si vous voyez multi_geomplus de 0, vous risquez de perdre des données et vous devriez probablement les conserver en tant que géométrie en plusieurs parties. Si vous voyez 0, alors il est sûr de faire une géométrie en une seule pièce avec:

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

Pour PostGIS 1.x , c'est un peu plus compliqué, car il y a plusieurs étapes (merci @ rec.thegeom!).

En supposant une table my_tableet une colonne de géométrie geom, voici les étapes pour convertir en plusieurs parties:

-- 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
la source
Salut @Mike Toews (et Ulrik). Je ne pense pas que votre deuxième étape pour PostGIS 1.x soit nécessaire dans ce cas, Mike. Ulrik a déclaré que la table sera vide au moment de la conversion de type, donc il n'y aura pas de valeurs non multi pour provoquer une erreur avec quelque chose comme: 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); puis 3) UPDATE geometry_columns SET type = 'MULTIPOINT' WHERE f_table_name = 'my_table'; (peut-être le commentaire le plus bâclé de tous les temps - ma mauvaise)
rec.thegeom
@ rec.thegeom correct; avec une table vide il n'y aurait rien à mettre à jour. Merci d'avoir publié les commandes réelles!
Mike T
Si vous avez des données complexes sous diverses formes, GEOMETRYCOLLECTION (MULTIPOLYGON(...))alors vous souhaiterez peut-être modifier la requête pour la détection de plusieurs géométries. Avec check like ST_NumGeometries(ST_CollectionHomogenize(geom)) > 1et utilisez une chose similaire pour le USINGwith: ST_GeometryN(ST_Multi(ST_CollectionHomogenize (geom)), 1)ou similaire.
Ravbaker
4

Changez, je ne pense pas. Mais vous pouvez créer une nouvelle table avec une structure identique, à l'exception de la colonne geom, puis exécuter:

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
la source