Mengubah tipe geometri dari Point ke Multipoint dalam tabel yang ada di PostGIS?

31

Apakah ada fungsi PostGIS yang dapat mengubah tipe geometri untuk tabel yang ada?

Kita perlu mengubah dari POINT ke MULTIPOINT.

Tabel akan kosong ketika kita mengubah tipe geometri dan kita tidak bisa hanya menjatuhkan / membuat tabel.

Ulrik Balslev
sumber

Jawaban:

62

Untuk PostGIS 2.x , Anda dapat menggunakan ALTER TABLE DDL menggunakan ekspresi .

Untuk mengkonversi dari geometri satu bagian ke banyak bagian, gunakan ST_Multi :

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

Untuk mengkonversi dari multi-bagian ke geometri satu-bagian, ini sedikit lebih rumit karena Anda hanya dapat menggunakan satu bagian, dan abaikan semua bagian lainnya (jika ada). Periksa data Anda terlebih dahulu untuk melihat apakah Anda memiliki beberapa geometri dengan lebih dari satu bagian:

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

Jika Anda melihat multi_geomlebih besar dari 0, maka Anda akan berisiko kehilangan data, dan Anda mungkin harus menyimpannya sebagai geometri multi-bagian. Jika Anda melihat 0, maka aman untuk menjadikannya geometri satu bagian dengan:

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

Untuk PostGIS 1.x , ini sedikit lebih berantakan, karena ada beberapa langkah (terima kasih @ rec.thegeom!).

Dengan asumsi tabel my_tabledan kolom geometri geom, berikut adalah langkah-langkah untuk mengonversi menjadi multi-bagian:

-- 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
sumber
Hai @Mike Toews (dan Ulrik). Saya rasa langkah kedua Anda untuk PostGIS 1.x tidak diperlukan dalam kasus ini, Mike. Ulrik mengatakan tabel tersebut akan kosong pada saat konversi jenis, sehingga tidak akan ada nilai non-multi untuk menyebabkan kesalahan dengan sesuatu seperti: 1) ALTER TABLE my_table DROP CONSTRAINT menegakkan_geotype_the_geom; 2) ALTER TABEL my_table ADD CONSTRAINT penegakan_geotype_the_geom PERIKSA (geometrytype (the_geom) = 'MULTIPOINT' :: teks ATAU the_geom IS NULL); kemudian 3) UPDATE geometry_columns SET type = 'MULTIPOINT' WHERE f_table_name = 'my_table'; (mungkin komentar paling sembrono - buruk saya)
rec.thegeom
@ rec.thegeom benar; dengan tabel kosong tidak akan ada pembaruan. Terima kasih telah memposting perintah yang sebenarnya!
Mike T
Jika Anda memiliki data kompleks dalam berbagai bentuk seperti GEOMETRYCOLLECTION (MULTIPOLYGON(...))maka Anda mungkin ingin mengubah kueri untuk mendeteksi lebih dari satu geometri. Dengan centang suka ST_NumGeometries(ST_CollectionHomogenize(geom)) > 1dan gunakan hal serupa untuk USINGdengan: ST_GeometryN(ST_Multi(ST_CollectionHomogenize (geom)), 1)atau serupa.
Ravbaker
4

Ubah, kurasa tidak. Tapi Anda bisa membuat tabel baru dengan struktur yang identik, kecuali untuk kolom geom, lalu jalankan:

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
sumber