Zmieniasz typ geometrii z punktu na wielopunkt w obrębie istniejącej tabeli w PostGIS?

31

Czy istnieje funkcja PostGIS, która może zmienić typ geometrii dla istniejącej tabeli?

Musimy zmienić POINT na MULTIPOINT.

Tabela będzie pusta, gdy zmienimy typ geometrii i nie będziemy mogli po prostu upuścić / utworzyć tabeli.

Ulrik Balslev
źródło

Odpowiedzi:

62

W przypadku PostGIS 2.x można użyć ALTER TABLE DDL przy użyciu wyrażenia .

Aby przekonwertować z geometrii jednoczęściowej na wieloczęściową, użyj ST_Multi :

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

Przekształcenie geometrii wieloczęściowej w geometrię jednoczęściową jest nieco trudniejsze, ponieważ można użyć tylko jednej części i zignorować wszystkie inne części (jeśli istnieją). Najpierw sprawdź swoje dane, aby sprawdzić, czy masz jakieś geometrie z więcej niż jedną częścią:

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

Jeśli zobaczysz multi_geomwięcej niż 0, ryzykujesz utratą danych i prawdopodobnie powinieneś zachować je jako geometrię wieloczęściową. Jeśli zobaczysz 0, możesz bezpiecznie utworzyć geometrię jednoczęściową za pomocą:

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

W przypadku PostGIS 1.x jest nieco bardziej niechlujny, ponieważ jest kilka kroków (dzięki @ rec.thegeom!).

Zakładając tabelę my_tablei kolumnę geometrii geom, oto kroki do konwersji na wiele części:

-- 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.
źródło
Cześć @ Mike Toews (i Ulrik). Nie wydaje mi się, żeby w tym przypadku potrzebny był drugi krok dla PostGIS 1.x, Mike. Ulrik powiedział, że tabela będzie pusta w czasie konwersji typu, więc nie będzie żadnych wartości innych niż wiele, które spowodowałyby błąd z czymś takim jak: 1) ALTER TABLE my_table DROP CONSTRAINT enforce_geotype_the_geom; 2) ZMIEŃ TABELĘ moja_tabela DODAJ OGRANICZENIE enforce_geotype_the_geom CHECK (typ geometrii (the_geom) = 'MULTIPOINT' :: text OR the_geom IS NULL); następnie 3) UPDATE geometry_columns SET type = 'MULTIPOINT' WHERE f_table_name = 'my_table'; (być może najbardziej niechlujny komentarz w historii - mój zły)
rec. thegeom
@ rec. thegeom poprawne; przy pustej tabeli nie byłoby nic do zaktualizowania. Dziękujemy za opublikowanie rzeczywistych poleceń!
Mike T
Jeśli masz złożone dane w różnych formach, np. GEOMETRYCOLLECTION (MULTIPOLYGON(...))Możesz zmienić zapytanie w celu wykrycia więcej niż jednej geometrii. Sprawdź jak ST_NumGeometries(ST_CollectionHomogenize(geom)) > 1i użyj podobnej rzeczy USINGz: ST_GeometryN(ST_Multi(ST_CollectionHomogenize (geom)), 1)lub podobnym.
Ravbaker
4

Zmień, nie wydaje mi się. Ale możesz utworzyć nową tabelę o identycznej strukturze, z wyjątkiem kolumny geom, a następnie uruchomić:

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
źródło