16.5. Lesson: ジオメトリの構成

このセクションではシンプルなジオメトリが SQL でどのように構成されているか少し掘り下げます。実際には、複雑なジオメトリをデジタイジングツールを使用して作るためには、QGIS のような GIS を使用するでしょう。しかし、それらがどのように形作られているかを知ることは、クエリを書いたりデータベースがどのように作られているかを理解するのに役立ちます。

このレッスンの目的 PostgreSQL/PostGIS で空間要素を直接作成する方法をよく理解する。

16.5.1. ラインストリングの作成

address データベースに戻って、他に一致する街路テーブルを取得してみましょう。すなわち、ジオメトリ、インデックスとGEOMETRY_COLUMNSテーブル中のエントリに制約を持ちます。

16.5.2. Try Yourself moderate

  • タイプST_LineStringのジオメトリ列を持つように 街路 テーブルを修正します。

  • ジオメトリ列のテーブルに伴う更新を行うことを忘れないでください!

  • また、ラインストリングまたはnullではありません追加されているすべてのジオメトリを防止するための制約を追加します。

  • 新しいジオメトリカラムに空間インデックスを作成します。

結果の確認

では、ラインストリングをstreetsテーブルに挿入しましょう。この場合は、既存の道路のレコードを更新します

update streets set the_geom = 'SRID=4326;LINESTRING(20 -33, 21 -34, 24 -33)'
where streets.id=2;

結果をQGISで確認してみます。(‘レイヤ’ パネルのstreetsレイヤを右クリックし、’レイヤの領域にズームする’を選択する必要があるかもしれません。)

いくつかはQGISから、いくつかはコマンドラインから道路の要素をもう少し追加します。

16.5.3. ポリゴンの作成

ポリゴンを作成することも簡単です。覚えておくことは、定義により、ポリゴンは最低4つの頂点を持ち、最初と最後の頂点は同じ場所になるということです:

insert into cities (name, the_geom)
values ('Tokyo', 'SRID=4326;POLYGON((10 -10, 5 -32, 30 -27, 10 -10))');

ノート

ポリゴンは、その座標リストの周りに二重括弧を必要とします。これにより、複数の連結していない領域を持つ複雑なポリゴンを追加できるようなります。例えば

insert into cities (name, the_geom)
values ('Tokyo Outer Wards', 'SRID=4326;POLYGON((20 10, 20 20, 35 20, 20 10),
      (-10 -30, -5 0, -15 -15, -10 -30))');

この手順に従った場合、QGISに都市データセットをロードし、属性テーブルを開き、新しいエントリを選択することで、何をしたか確認できます。二つの新しいポリゴンが1つのポリゴンのように振る舞うかに注意してください。

16.5.4. 練習:CitiesをPeopleにリンクする

この演習では次のことを行う必要があります。

  • peopleテーブルからすべてのデータを削除します。

  • 都市テーブルの主キーを参照する人々への外部キー列を追加します。

  • QGISを使用していくつかの都市をキャプチャします。

  • それぞれが関連付けられている通り、街を持っていることを確認して、いくつかの新しい人々のレコードを挿入するSQLを使用してください。

更新された人々のスキーマは次のようになります:

\d people

Table "public.people"
   Column   |         Type          |                      Modifiers
 -----------+-----------------------+--------------------------------------------
  id        | integer               | not null
            |                       | default nextval('people_id_seq'::regclass)
  name      | character varying(50) |
  house_no  | integer               | not null
  street_id | integer               | not null
  phone_no  | character varying     |
  the_geom  | geometry              |
  city_id   | integer               | not null
Indexes:
  "people_pkey" PRIMARY KEY, btree (id)
  "people_name_idx" btree (name)
Check constraints:
  "people_geom_point_chk" CHECK (st_geometrytype(the_geom) =
                       'ST_Point'::text OR the_geom IS NULL)
Foreign-key constraints:
  "people_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cities(id)
  "people_street_id_fkey" FOREIGN KEY (street_id) REFERENCES streets(id)

結果の確認

16.5.5. スキーマに着目する

スキーマはこのように見えるべきです:

../../../_images/final_schema.png

16.5.6. Try Yourself hard

その都市のすべてのアドレスの最小凸包を計算し、その領域の周りのバッファを計算することにより、都市の境界線を作成します。

16.5.7. サブオブジェクトへのアクセス

SFS-モデルの機能を使用すると、SFSジオメトリのサブオブジェクトにアクセスするためのさまざまなオプションを持っています。テーブルmyPolygonTable内のすべてのポリゴンジオメトリの最初の頂点を選択したいときは、このような方法でこれを実行する必要があります:

  • ラインストリングにポリゴン境界を変換する:

    select st_boundary(geometry) from myPolygonTable;
  • その結果ラインストリングの最初の頂点を選択します:

    select st_startpoint(myGeometry)
    from (
        select st_boundary(geometry) as myGeometry
        from myPolygonTable) as foo;

16.5.8. データプロセッシング

PostGISには、すべてのOGC SFS / MM標準では機能に準拠サポートしています。すべてのこれらの関数は `` ST_``で始まります。

16.5.9. クリッピング

データのサブパートをクリップするには、 ST_INTERSECT() 関数を使用できます。空のジオメトリを回避するために、以下を使用:

where not st_isempty(st_intersection(a.the_geom, b.the_geom))
../../../_images/qgis_001.png
select st_intersection(a.the_geom, b.the_geom), b.*
from clip as a, road_lines as b
where not st_isempty(st_intersection(st_setsrid(a.the_geom,32734),
  b.the_geom));
../../../_images/qgis_002.png

16.5.10. 他の形状から建物のジオメトリ

与えられたポイントテーブルから、ラインストリングを生成します。ポイントの順序は、その id によって定義されます。別の並べ方は、GPS受信機でウェイポイントをキャプチャするときに得るような、タイムスタンプになりうるかもしれません。

../../../_images/qgis_006.png

「ポイント」と呼ばれる新しいポイントレイヤーからラインストリングを作成するため、次のコマンドを実行できます:

select ST_LineFromMultiPoint(st_collect(the_geom)), 1 as id
from (
  select the_geom
  from points
  order by id
) as foo;

もちろん、これを行うのは現実世界の意味はほとんどないでしょうが、どのように機能するかを確認するには、「人」レイヤーにもこのコマンドを実行できます。

../../../_images/qgis_007.png

16.5.11. ジオメトリクリーニング

You can get more information for this topic in this blog entry.

16.5.12. テーブル間の違い

同じ構造を持つ2つのテーブル間の差を検出するには、PostgreSQLの EXCEPT キーワードを使用できます:

select * from table_a
except
select * from table_b;

結果として、table_aからtable_bに格納されていないすべてのレコードが得られるでしょう。

16.5.13. 表領域

Postgresは表領域を作成することにより、ディスク上のデータを保存する場所を定義できます:

CREATE TABLESPACE homespace LOCATION '/home/pg';

データベースを作成するときは、その後、例えば、使用する表領域を指定することができます:

createdb --tablespace=homespace t4a

16.5.14. In Conclusion

PostGISの文を使用して、より複雑な形状を作成する方法を学びました。これはGISのフロントエンドを通じて地理対応データベースを操作する場合、暗黙知を向上させることがほとんどであることに留意してください。通常、実際に手動でこれらのステートメントを入力する必要はありませんが、そうでなければ不可解なと思われるエラーが発生した場合は特に、GISを使用した場合、その構造の一般的な考えを持つことに役立ちます。