OS OpenDataマルチポイントシェープファイルをPostGISにロードする際の問題


8

OS OpenData StrategiシェープファイルデータセットをPostGISデータベースにロードしようとしています。ポリラインとポリゴンのシェープファイルに問題はありませんでしたが、ポイントシェープファイルをロードできません。

次のshp2pgsqlコマンドラインを使用してテーブルを作成し、データをロードしています。

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

私が得るエラーは:

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

最後のエラーは、挿入ごとに繰り返されます。生成されたSQLは次のようになります。

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

さらに多くのインサートがすべて同じように見えます。

私はあらゆる種類のバリエーションを試しました。SRIDあり、なし .prjファイルありとなし。他のデータを含まない新しいテストデータベースを作成しました。単純なジオメトリを使用します。しかし、効果はありません。

自分で試してみる時間があれば、シェープファイルのzipファイルを用意しました。

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

私は完全に最新のFedora 14、Postgres 8.4.6、PostGIS 1.5.1を使用しています。

SPITを使用するための提案に基づくいくつかの更新されたメモ:

「テーブルのみを作成する」モードでshp2pgsqlを使用すると、次の制約を持つテーブルが表示されます。

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)

SPITによって作成されたテーブルを見ると、わずかに異なる制約があります。

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

shp2pgsql -pを使用してテーブルを作成し、psqlを使用して、enforce_geotype_the_geom制約を削除すると、shp2pgsql -aを使用してコマンドラインから一括インポートが機能するはずです。

その制約が問題を引き起こしている理由を私はまだ理解したいですか?

おかげで、

キース。

回答:


6

他の回答で示唆されているように、問題はPOINTおよびMULTIPOINTタイプに関連しています。shp2pgsql(およびogrinfo)は、ジオメトリタイプをMULTIPOINTとして検出しますが、ジオメトリのEWKB表現(_geom列に挿入する値)を作成するときに、POINTジオメトリを生成しているようです。

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

(私は最初に生成されたレコードを取った)

shp2pgsqlのmanページによると、新しいジオメトリを簡単に作成するように強制するフラグがありますが、明らかにポイントでは機能しません。

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

問題のある制約を削除する代わりに、psqlで実行する前に、生成されたSQLスクリプトのジオメトリ列を変更することをお勧めします。

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

このようにして、レコードをロードすると同時に、将来のデータの整合性を保証する制約を維持します。


3

なぜそのエラーが発生するのかはわかりませんが、QGISのSPITプラグインを使用して圧縮したシェイプファイルをロードしようとしたところ、問題なくインポートされました。SPITはshp2pgsqlの単なるguiだと思っていたので、これは私を驚かせました!私はWindowsでQGIS 1.6を使用していますが、fedoraでも同様に動作するはずです。

お役に立てれば

ジョー


PostGIS Managerプラグインは確かにshp2pgsqlを使用し、上記のエラーで失敗します。SPITは私にとってもうまくいきました。ここで興味深いのは、それが別様に行うことです。
アンダーダーク

SPITはFedora、QGISバージョン1.6.0でも動作します。上記の@underdarkのポイントに基づいて、テーブル構造に関するいくつかの情報を更新しました。
Keith Sharp

2
まあ、SPITはshp2pgsqlを使用しません。それはすべてそれを単独で行います。(ソースコード:svn.osgeo.org/qgis/trunk/qgis/src/plugins/spit
アンダーダーク

2

@Archaogeekと@underdarkからのポインタに基づいて、解決策を考え出しました。

shp2pgsqlを使用して、基本的なテーブル構造を作成します。

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

psqlを起動し、問題のある制約を削除します。

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

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

次に、shp2pgsqlを使用してすべてのポイントデータを一括読み込みする(シェルスクリプトによって駆動される)に戻ります。

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

その制約の問題を理解したいと思います。

キース。


問題は、すべてのマルチポイントに実際に座標ペアが1つだけ含まれていることかもしれません。多分ある時点で、マルチポイントではなくポイントとしてのみ認識されます。
アンダーダーク

2

これは現在PostGISトランクで修正されていますが、どのリリースに組み込まれるかはわかりません。

-SがMULTIPOINT-> POINT(http://trac.osgeo.org/postgis/ticket/779)で機能するようになりました

また、マルチポイントシェープファイルの単一頂点ポイントは、POINTを挿入しようとするのではなく、単一頂点マルチポイントとして正しくロードされるようになりました。(http://trac.osgeo.org/postgis/ticket/864)


1

問題はおそらく形状にいくつかのMULTIPOINT機能があり、そのため、shp2pgsqlはPOINTではなくMULTIPOINTを使用する必要があることです。次に、マルチポイントの代わりにポイントが来ると、制約の問題があります。

すべてのポイントをMULTIPOINTに強制するオプションを期待していましたが、そこではどこにあるのかと考えましたが、ドキュメントでは見つかりませんでした。データベースにロードされるものでそれを行う関数があります:ST_Multiですが、それをロードしようとする場合、それはほとんど役に立ちません。

これはPostGISリストで議論されたに違いないと思いますが、簡単に見つけることができませんでした。

/ニクラス

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.