Ändern des Geometrietyps von Punkt zu Mehrpunkt in vorhandener Tabelle in PostGIS?

31

Gibt es eine PostGIS-Funktion, mit der der Geometrietyp für eine vorhandene Tabelle geändert werden kann?

Wir müssen von POINT zu MULTIPOINT wechseln.

Die Tabelle ist leer, wenn wir den Geometrietyp ändern, und wir können die Tabelle nicht einfach löschen / erstellen.

Ulrik Balslev
quelle

Antworten:

62

Für PostGIS 2.x können Sie die DDL ALTER TABLE mithilfe eines Ausdrucks verwenden .

Verwenden Sie ST_Multi, um von einer einteiligen in eine mehrteilige Geometrie zu konvertieren :

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

Das Konvertieren von einer mehrteiligen in eine einteilige Geometrie ist etwas komplizierter, da Sie nur ein Teil verwenden und alle anderen Teile (sofern vorhanden) ignorieren können. Überprüfen Sie zuerst Ihre Daten, um festzustellen, ob Sie Geometrien mit mehr als einem Teil haben:

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

Wenn Sie multi_geommehr als 0 sehen, besteht die Gefahr, dass Sie Daten verlieren. Sie sollten diese wahrscheinlich als mehrteilige Geometrie beibehalten. Wenn Sie 0 sehen, ist es sicher, eine einteilige Geometrie zu erstellen mit:

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

Für PostGIS 1.x ist es etwas unordentlicher, da es mehrere Schritte gibt (danke @ rec.thegeom!).

Angenommen, eine Tabelle my_tableund eine Geometriespalte geomsind die folgenden Schritte zum Konvertieren in ein mehrteiliges Element:

-- 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
quelle
Hi @ Mike Toews (und Ulrik). Ich denke nicht, dass Ihr zweiter Schritt für PostGIS 1.x in diesem Fall notwendig ist, Mike. Ulrik sagte, dass die Tabelle zum Zeitpunkt der Typkonvertierung leer sein wird, so dass es keine Nicht-Multi-Werte gibt, die einen Fehler verursachen könnten: 1) ALTER TABLE my_table DROP CONSTRAINT enforce_geotype_the_geom; 2) ALTER TABLE my_table ADD CONSTRAINT enforce_geotype_the_geom CHECK (Geometrietyp (the_geom) = 'MULTIPOINT' :: text OR the_geom IS NULL); dann 3) UPDATE geometry_columns SET type = 'MULTIPOINT' WHERE f_table_name = 'my_table'; (vielleicht der schlampigste Kommentar, den ich je gemacht habe - mein schlechtes)
Rec.thegeom
@ rec.thegeom richtig; bei einer leeren Tabelle gäbe es nichts zu aktualisieren. Vielen Dank für das Posten der aktuellen Befehle!
Mike T
Wenn Sie komplexe Daten in verschiedenen Formen haben, GEOMETRYCOLLECTION (MULTIPOLYGON(...))möchten Sie möglicherweise die Abfrage für die Erkennung mehrerer Geometrien ändern. Mit check like ST_NumGeometries(ST_CollectionHomogenize(geom)) > 1und verwende ähnliches für das USINGwith: ST_GeometryN(ST_Multi(ST_CollectionHomogenize (geom)), 1)oder ähnliches.
Ravbaker
4

Ändern Sie, ich glaube nicht. Sie können jedoch eine neue Tabelle mit identischer Struktur erstellen, mit Ausnahme der Geom-Spalte. Führen Sie dann Folgendes aus:

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
quelle