Masalah saat memuat OS OpenData multipoint shapefile ke PostGIS

8

Saya mencoba memuat dataset shapefile Strategi OpenData OS ke dalam database PostGIS. Saya tidak punya masalah dengan polyline dan poligon shapefile, tetapi saya tidak bisa mendapatkan titik shapefile untuk dimuat.

Saya menggunakan baris perintah shp2pgsql berikut untuk membuat tabel dan memuat data:

shp2pgsql -c -I -s 27700 admin_font_point strategi_point | psql -d opendata

Kesalahan yang saya dapatkan adalah:

Shapefile type: MultiPoint
Postgis type: MULTIPOINT[2]
SET
SET
BEGIN
NOTICE:  CREATE TABLE will create implicit sequence "strategi_point_gid_seq" for serial column "strategi_point.gid"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "strategi_point_pkey" for table "strategi_point"
CREATE TABLE
                         addgeometrycolumn                         
-------------------------------------------------------------------
public.strategi_point.the_geom SRID:27700 TYPE:MULTIPOINT DIMS:2 
(1 row)

ERROR:  new row for relation "strategi_point" violates check constraint "enforce_geotype_the_geom"
ERROR:  current transaction is aborted, commands ignored until end of transaction block

Kesalahan terakhir hanya mengulangi untuk setiap sisipan. SQL yang dihasilkan terlihat seperti:

SET CLIENT_ENCODING TO UTF8;
SET STANDARD_CONFORMING_STRINGS TO ON;
BEGIN;
CREATE TABLE "strategi_point" (gid serial PRIMARY KEY,
"code" int4,
"legend" varchar(42),
"file_name" varchar(16),
"number" numeric(11,0),
"name" varchar(180),
"number0" varchar(64),
"admin_name" varchar(50),
"type" varchar(40),
"ferry_from" varchar(50),
"ferry_to" varchar(50),
"ferry_time" varchar(10),
"ferry_type" varchar(20),
"restrictio" varchar(20),
"access" varchar(30),
"amended" date,
"usage" varchar(64),
"location" varchar(30),
"gis" varchar(80),
"owner" varchar(60),
"north" varchar(60),
"south" varchar(60),
"east" varchar(60),
"west" varchar(60),
"clockwise" varchar(60),
"anticlockw" varchar(60),
"imperial" int4,
"metric" int4);
SELECT AddGeometryColumn('','strategi_point','the_geom','27700','MULTIPOINT',2);
INSERT INTO "strategi_point" ("code","legend","file_name","number","name","number0","admin_name","type","ferry_from","ferry_to","ferry_time","ferry_type","restrictio","access","amended","usage","location","gis","owner","north","south","east","west","clockwise","anticlockw","imperial","metric",the_geom) VALUES ('5734','Administrative Detached Attribute Point','gb_north','5307',NULL,NULL,'ISLE OF MAN',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'20000413',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'-9999','-9999','0101000020346C000000000000302A0A4100000000304F1C41');

dan kemudian banyak lagi sisipan yang semuanya tampak sama.

Saya telah mencoba segala macam variasi; dengan dan tanpa SRID; dengan dan tanpa file .prj; membuat database pengujian baru tanpa data lain; menggunakan geometri sederhana; tetapi semua tidak berpengaruh.

Saya telah menyediakan file zip shapefile jika ada yang punya waktu untuk mencobanya sendiri:

http://www.passback.org.uk/tmp/admin_font_point.zip

Saya menggunakan Fedora 14 yang sepenuhnya terkini, Postgres 8.4.6, PostGIS 1.5.1.

Beberapa catatan yang diperbarui berdasarkan saran untuk menggunakan SPIT:

Jika saya menggunakan shp2pgsql dalam mode "buat tabel saja" saya mendapatkan tabel dengan batasan berikut:

Check constraints:
    "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2)
    "enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'MULTIPOINT'::text OR the_geom IS NULL)
    "enforce_srid_the_geom" CHECK (st_srid(the_geom) = 27700)

Melihat tabel yang dibuat oleh SPIT saya mendapatkan batasan yang sedikit berbeda:

Check constraints:
    "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2)
    "enforce_srid_the_geom" CHECK (st_srid(the_geom) = 27700)

Saya kira saya bisa menggunakan shp2pgsql -p untuk membuat tabel dan kemudian menggunakan psql untuk menghapus batasan menegakkan_geotype_the_geom dan impor massal saya dari baris perintah menggunakan shp2pgsql -a harus bekerja.

Saya masih ingin memahami mengapa kendala itu menyebabkan masalah?

Terima kasih,

Keith.

Keith Sharp
sumber

Jawaban:

6

Seperti yang disarankan oleh jawaban lain, masalahnya terkait dengan jenis POINT dan MULTIPOINT. shp2pgsql (dan ogrinfo) mendeteksi tipe geometri sebagai MULTIPOINT, tetapi kemudian, ketika membuat representasi geometri EWKB (nilai untuk disisipkan di kolom _geom), sepertinya akan menghasilkan geometri POINT:

select geometrytype('0101000020346C000000000000302A0A4100000000304F1C41');
--POINT

(Saya mengambil catatan yang dihasilkan pertama)

Menurut halaman manual shp2pgsql, ada bendera yang harus memaksa geometri baru dibuat sederhana, tetapi tampaknya, itu tidak bekerja pada poin:

   -S     Generate simple Geometries instead of MULTIgeometries. Shape files don't differ between LINESTRINGs and MULTILINESTRINGs, so shp2pgsql generates MUL
          TILINESTRINGs  by  default. This switch will produce LINESTRINGs instead, but shp2pgsql will fail when it hits a real MULTILINESTRING. The same works
          for POLYGONs vs. MULTIPOLYGONs.

Alih-alih menjatuhkan batasan yang menyinggung, saya akan menyarankan mengubah kolom geometri dalam skrip SQL yang dihasilkan sebelum menjalankannya dengan psql:

SELECT AddGeometryColumn('','strategi_point','the_geom','27700','POINT',2);

Dengan cara ini Anda akan mendapatkan catatan Anda dimuat, dan pada saat yang sama menjaga kendala yang dapat memastikan integritas data Anda di masa depan.

amercader
sumber
3

Saya tidak tahu mengapa Anda mendapatkan kesalahan itu, tapi saya hanya mencoba memuat shapefile zip Anda menggunakan plugin SPIT di QGIS, dan itu diimpor dengan baik. Ini mengejutkan saya karena saya menganggap SPIT hanyalah gui untuk shp2pgsql! Saya menggunakan QGIS 1.6 di windows tetapi seharusnya berfungsi dengan baik pada fedora.

Semoga ini membantu

Jo

Archaeogeek
sumber
Plugin PostGIS Manager pasti menggunakan shp2pgsql dan gagal dengan kesalahan yang ditunjukkan di atas. Meludah juga bekerja dengan baik untuk saya. Sekarang bagian yang menarik adalah apa yang dilakukannya secara berbeda.
underdark
SPIT juga berfungsi pada Fedora, QGIS versi 1.6.0. Saya telah memperbarui beberapa informasi tentang struktur tabel berdasarkan titik @ underdark di atas.
Keith Sharp
2
Yah, SPIT tidak menggunakan shp2pgsql. Itu melakukan semuanya dengan sendirinya. (Kode sumber: svn.osgeo.org/qgis/trunk/qgis/src/plugins/spit )
underdark
2

Berdasarkan petunjuk dari @Archaogeek dan @underdark saya telah menemukan solusi.

Gunakan shp2pgsql untuk membuat struktur tabel dasar:

shp2pgsql -p -s 27700 admin_font_point strategi_point | psql -d opendata

Jalankan psql dan hapus kendala yang menyinggung:

$ psql -d opendata
psql (8.4.6)
Type "help" for help.

opendata=# ALTER TABLE strategi_point DROP CONSTRAINT enforce_geotype_the_geom;
ALTER TABLE

Kemudian kembali menggunakan shp2pgsql untuk memuat semua data titik saya (didorong oleh skrip shell) secara massal:

shp2pgsql -a -s 27700 admin_font_point strategi_point | psql -d opendata

Saya masih ingin memahami masalah dengan kendala itu.

Keith.

Keith Sharp
sumber
Saya ingin tahu apakah masalahnya adalah bahwa semua MULTIPOINTS sebenarnya hanya berisi satu pasangan koordinat. Mungkin pada titik tertentu hanya dikenali sebagai POIN, bukan MULTIPOIN.
underdark
2

Ini sekarang diperbaiki pada postGIS trunk, meskipun saya tidak yakin rilis apa yang akan berakhir.

-S sekarang berfungsi untuk MULTIPOINT -> POINT (http://trac.osgeo.org/postgis/ticket/779)

Dan titik-titik tunggal dalam bentuk multipoint sekarang memuat dengan benar sebagai titik-titik tunggal multi-titik daripada mencoba memasukkan POINT. (http://trac.osgeo.org/postgis/ticket/864)

Jeff
sumber
1

Saya pikir masalahnya adalah bahwa mungkin ada beberapa fitur MULTIPOINT dalam bentuk, dan karena itu, shp2pgsql harus menggunakan MULTIPOINT bukan TITIK. Kemudian ketika POINT datang bukan MULTIPOINT ada masalah kendala.

Saya mengharapkan opsi untuk memaksa semua poin ke MULTIPOINT, dan saya pikir ada di mana, tetapi saya tidak dapat menemukannya di dokumentasi. Ada fungsi untuk melakukannya pada saat itu dimuat dalam database: ST_Multi , tetapi itu sedikit membantu ketika mencoba memuatnya.

Saya kira ini pasti sudah dibahas dalam daftar PostGIS, tetapi saya tidak dapat menemukannya dengan mudah.

/ Nicklas

Nicklas Avén
sumber