Problema al cargar el archivo de forma multipunto OpenData del sistema operativo en PostGIS

8

Estoy tratando de cargar el conjunto de datos del archivo de forma de OpenData Strategi del sistema operativo en una base de datos PostGIS. No he tenido problemas con los archivos de forma de polilínea y polígono, pero no puedo cargar los archivos de forma de punto.

Estoy usando la siguiente línea de comando shp2pgsql para crear la tabla y cargar los datos:

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

El error que obtengo es:

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

El último error solo se repite para cada inserción. El SQL generado se ve así:

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

y luego muchos más insertos, todos parecidos.

He intentado todo tipo de variaciones; con y sin SRID; con y sin archivo .prj; creó una nueva base de datos de prueba sin otros datos; usando geometrías simples; pero todo sin efecto.

He puesto a disposición un archivo zip de shapefile si alguien tiene tiempo para probarlo por sí mismo:

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

Estoy usando un Fedora 14 completamente actualizado, Postgres 8.4.6, PostGIS 1.5.1.

Algunas notas actualizadas basadas en la sugerencia de usar SPIT:

Si uso shp2pgsql en modo "crear solo tabla", obtengo una tabla con las siguientes restricciones:

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)

Mirando la tabla creada por SPIT obtengo restricciones ligeramente diferentes:

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

Supongo que podría usar shp2pgsql -p para crear la tabla y luego usar psql para eliminar la restricción enforce_geotype_the_geom y mi importación masiva desde la línea de comandos usando shp2pgsql -a debería funcionar.

Todavía me gustaría entender por qué esa restricción está causando un problema?

Gracias,

Keith

Keith Sharp
fuente

Respuestas:

6

Como sugieren otras respuestas, el problema está relacionado con los tipos POINT y MULTIPOINT. shp2pgsql (y ogrinfo) detecta el tipo de geometría como MULTIPOINT, pero luego, al crear la representación EWKB de la geometría (el valor para insertar en la columna_geom), parece estar generando una geometría POINT:

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

(Tomé el primer registro generado)

De acuerdo con la página de manual de shp2pgsql, hay una bandera que debería forzar la creación de nuevas geometrías simples, pero aparentemente, no funciona en puntos:

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

En lugar de eliminar la restricción ofensiva, sugeriré cambiar la columna de geometría en el script SQL generado antes de ejecutarlo con psql:

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

De esta forma, cargará sus registros y, al mismo tiempo, mantendrá una restricción que puede garantizar la integridad de sus datos en el futuro.

amercader
fuente
3

No sé por qué está recibiendo ese error, pero solo intenté cargar su archivo de forma comprimido usando el complemento SPIT en QGIS, e importó muy bien. ¡Esto me sorprendió cuando asumí que SPIT era solo una interfaz gráfica de usuario para shp2pgsql! Estoy usando QGIS 1.6 en Windows, pero debería funcionar igual de bien en Fedora.

Espero que esto ayude

Jo

Archaeogeek
fuente
El complemento PostGIS Manager ciertamente usa shp2pgsql y falla con el error que se muestra arriba. SPIT también funcionó bien para mí. Ahora la parte interesante sería lo que hace de manera diferente.
oscuro
SPIT también funciona en Fedora, QGIS versión 1.6.0. He actualizado alguna información sobre las estructuras de la tabla basada en el punto anterior de @ underdark.
Keith Sharp el
2
Bueno, SPIT no usa shp2pgsql. Lo hace todo por sí mismo. (Código fuente: svn.osgeo.org/qgis/trunk/qgis/src/plugins/spit )
underdark
2

Basado en los consejos de @Archaogeek y @underdark, he encontrado una solución.

Use shp2pgsql para crear la estructura básica de la tabla:

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

Encienda psql y elimine la restricción ofensiva:

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

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

Luego, vuelva a usar shp2pgsql para cargar en masa todos mis datos de puntos (impulsados ​​por un script de shell):

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

Todavía me gustaría entender el problema con esa restricción.

Keith

Keith Sharp
fuente
Me pregunto si el problema podría ser que todos los MULTIPUNTOS en realidad contienen solo un par de coordenadas. Quizás en algún momento solo se reconocen como PUNTOS en lugar de MULTIPUNTOS.
oscuro
2

Esto ahora está arreglado en el tronco de PostGIS, aunque no estoy seguro de en qué versión terminará.

-S ahora funciona para MULTIPOINT -> POINT (http://trac.osgeo.org/postgis/ticket/779)

Y los puntos de un solo vértice en un archivo de forma multipunto ahora se cargan correctamente como multipuntos de un solo vértice en lugar de intentar insertar un PUNTO. (http://trac.osgeo.org/postgis/ticket/864)

Jeff
fuente
1

Creo que el problema es que probablemente haya algunas características MULTIPUNTO en la forma, y ​​por eso, shp2pgsql tiene que usar MULTIPOINT en lugar de POINT. Luego, cuando viene un PUNTO en lugar de MULTIPUNTO, hay un problema de restricción.

Esperaba una opción para forzar todos los puntos a PUNTOS MÚLTIPLES, y pensé dónde, pero no puedo encontrarla en la documentación. Hay una función para hacerlo cuando está cargada en la base de datos: ST_Multi , pero es de poca ayuda cuando se trata de cargarla.

Supongo que esto debe haber sido discutido en las listas de PostGIS, pero no pude encontrarlo fácilmente.

/ Nicklas

Nicklas Avén
fuente