Problem beim Laden des OS OpenData-Mehrpunkt-Shapefiles in PostGIS

8

Ich versuche, das OS OpenData Strategi-Shapefile-Dataset in eine PostGIS-Datenbank zu laden. Ich hatte keine Probleme mit den Polylinien- und Polygon-Shapefiles, aber ich kann die Punkt-Shapefiles nicht laden.

Ich verwende die folgende shp2pgsql-Befehlszeile, um die Tabelle zu erstellen und die Daten zu laden:

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

Der Fehler, den ich bekomme, ist:

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

Der letzte Fehler wird nur für jede Einfügung wiederholt. Das generierte SQL sieht folgendermaßen aus:

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');

und dann noch viel mehr Beilagen, die alle gleich aussehen.

Ich habe alle möglichen Variationen ausprobiert. mit und ohne SRID; mit und ohne PRJ-Datei; eine neue Testdatenbank ohne andere Daten erstellt; mit einfachen Geometrien; aber alles ohne Wirkung.

Ich habe eine Zip-Datei mit Shapefile zur Verfügung gestellt, wenn jemand die Zeit hat, dies selbst zu versuchen:

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

Ich verwende eine vollständig aktuelle Fedora 14, Postgres 8.4.6, PostGIS 1.5.1.

Einige aktualisierte Hinweise basierend auf dem Vorschlag, SPIT zu verwenden:

Wenn ich shp2pgsql im Modus "Nur Tabelle erstellen" verwende, erhalte ich eine Tabelle mit den folgenden Einschränkungen:

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)

Wenn ich mir die von SPIT erstellte Tabelle ansehe, erhalte ich etwas andere Einschränkungen:

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

Ich denke, ich könnte shp2pgsql -p verwenden, um die Tabelle zu erstellen, und dann psql verwenden, um die Einschränkung erzwingen_geotype_the_geom zu entfernen, und mein Massenimport von der Befehlszeile mit shp2pgsql -a sollte funktionieren.

Ich möchte immer noch verstehen, warum diese Einschränkung ein Problem verursacht.

Vielen Dank,

Keith.

Keith Sharp
quelle

Antworten:

6

Wie aus anderen Antworten hervorgeht, hängt das Problem mit den Typen POINT und MULTIPOINT zusammen. shp2pgsql (und ogrinfo) erkennt den Geometrietyp als MULTIPOINT. Beim Erstellen der EWKB-Darstellung der Geometrie (dem Wert, der in die Spalte_geom eingefügt werden soll) wird jedoch anscheinend eine POINT-Geometrie generiert:

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

(Ich habe den ersten generierten Datensatz genommen)

Laut der Manpage shp2pgsql gibt es ein Flag, das das einfache Erstellen neuer Geometrien erzwingen sollte, aber anscheinend funktioniert es nicht bei Punkten:

   -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.

Anstatt die fehlerhafte Einschränkung zu löschen, werde ich vorschlagen, die Geometriespalte im generierten SQL-Skript zu ändern, bevor sie mit psql ausgeführt wird:

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

Auf diese Weise werden Ihre Datensätze geladen und gleichzeitig eine Einschränkung beibehalten, die Ihre Datenintegrität in Zukunft sicherstellen kann.

Amercader
quelle
3

Ich weiß nicht, warum Sie diesen Fehler erhalten, aber ich habe nur versucht, Ihr komprimiertes Shapefile mit dem SPIT-Plugin in QGIS zu laden, und es wurde einwandfrei importiert. Dies überraschte mich, als ich annahm, dass SPIT nur eine GUI für shp2pgsql war! Ich verwende QGIS 1.6 unter Windows, aber es sollte unter Fedora genauso gut funktionieren.

Hoffe das hilft

Jo

Archaeogeek
quelle
Das PostGIS Manager-Plugin verwendet sicherlich shp2pgsql und schlägt mit dem oben gezeigten Fehler fehl. SPIT hat auch bei mir gut funktioniert. Nun wäre der interessante Teil, was es anders macht.
underdark
SPIT funktioniert auch mit Fedora, QGIS Version 1.6.0. Ich habe einige Informationen zu den Tabellenstrukturen basierend auf dem obigen Punkt von @ underdark aktualisiert.
Keith Sharp
2
Nun, SPIT verwendet kein shp2pgsql. Es macht alles von alleine. (Quellcode: svn.osgeo.org/qgis/trunk/qgis/src/plugins/spit )
underdark
2

Basierend auf den Hinweisen von @Archaogeek und @underdark habe ich eine Lösung gefunden.

Verwenden Sie shp2pgsql, um die grundlegende Tabellenstruktur zu erstellen:

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

Starten Sie psql und entfernen Sie die störende Einschränkung:

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

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

Kehren Sie dann zur Verwendung von shp2pgsql zurück, um alle meine Punktdaten per Bulk zu laden (gesteuert durch ein Shell-Skript):

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

Ich würde das Problem mit dieser Einschränkung immer noch gerne verstehen.

Keith.

Keith Sharp
quelle
Ich frage mich, ob das Problem darin bestehen könnte, dass alle MULTIPOINTS tatsächlich nur ein Koordinatenpaar enthalten. Vielleicht werden sie irgendwann nur noch als PUNKTE statt als MEHRPUNKTE erkannt.
Underdark
2

Dies ist jetzt auf dem PostGIS-Trunk behoben, obwohl ich nicht sicher bin, in welcher Version es landen wird.

-S funktioniert jetzt für MULTIPOINT -> POINT (http://trac.osgeo.org/postgis/ticket/779)

Einzelpunktpunkte in einem Mehrpunkt-Shapefile werden jetzt korrekt als Einzelpunkt-Mehrpunktpunkte geladen, anstatt zu versuchen, einen PUNKT einzufügen. (http://trac.osgeo.org/postgis/ticket/864)

Jeff
quelle
1

Ich denke, das Problem ist, dass es wahrscheinlich einige MULTIPOINT-Features in der Form gibt, und aus diesem Grund muss shp2pgsql MULTIPOINT anstelle von POINT verwenden. Wenn dann ein PUNKT anstelle von MULTIPOINT kommt, liegt ein Einschränkungsproblem vor.

Ich hatte eine Option erwartet, um alle Punkte auf MULTIPOINT zu zwingen, und ich dachte dort, wo, aber ich kann es nicht in der Dokumentation finden. Es gibt eine Funktion, um dies bei denjenigen zu tun, die in die Datenbank geladen sind: ST_Multi , aber das ist wenig hilfreich, wenn Sie versuchen, es zu laden.

Ich denke, das muss in den PostGIS-Listen besprochen worden sein, aber ich konnte es nicht leicht finden.

/ Nicklas

Nicklas Avén
quelle