Mapserverの利用

ミネソタMapserverはOpenGIS Webマッピングサーバ仕様に適合するインターネットWebマッピングサーバです.

基本的な使い方

Mapserverと一緒にPostGISを使うためには,Mapserverの設定の仕方について知る必要があるでしょう.それはこのドキュメントの範囲を越えています.この節では,PostGIS固有の問題と詳細設定をカバーします.

Mapserverと一緒にPostGISを使うためには,以下のものが必要になるでしょう.

Mapserverは,他のPostgreSQLクライアントのように --libpqを使って-- PostGIS/PostgreSQLのデータにアクセスします.このことはシステムがlibpq PostgreSQLクライアントライブラリがあれば,PostGISサーバにネットワークアクセスできる任意のマシンにMapserverをインストールできることを意味します.

  1. "--with-postgis"設定オプションを含む,あなたの望むオプションをつけてMapserverをコンパイルし,インストールしてください.

  2. Mapserverのマップファイルに,PostGISレイヤを追加してください.例えば:

      LAYER
        CONNECTIONTYPE postgis
        NAME "widehighways"
        # Connect to a remote spatial database
        CONNECTION "user=dbuser dbname=gisdatabase host=bigserver"
        # Get the lines from the 'geom' column of the 'roads' table
        DATA "geom from roads"
        STATUS ON
        TYPE LINE
        # Of the lines in the extents, only render the wide highways
        FILTER "type = 'highway' and numlanes >= 4"
        CLASS
          # Make the superhighways brighter and 2 pixels wide
          EXPRESSION ([numlanes] >= 6)
          COLOR 255 22 22      
          SYMBOL "solid"
          SIZE 2
        END
        CLASS
          # All the rest are darker and only 1 pixel wide
          EXPRESSION ([numlanes] < 6)
          COLOR 205 92 82      
        END
      END

    上記の例のうち,PostGIS固有の設定は以下のようになります:

    CONNECTIONTYPE

    PostGISレイヤでは,これは常に"postgis"になります.

    CONNECTION

    データベース接続は,このような標準的なキーと値の組によって既定されます(<>の中は既定値):

    user=<username> password=<password> dbname=<username> hostname=<server> port=<5432>

    空の接続文字列はまだ有効で,任意のキーと値のペアは省略することができます.一般的には少なくとも接続に使うデータベース名とユーザ名は記述します(supply).

    DATA

    このパラメータの書式は,"<column> from <tablename>"です.ここで,columnは地図に表現される空間カラムです.

    FILTER

    フィルタは,通常SQLクエリの"WHERE"キーワードに続く論理式に対応する有効なSQL文字列である必要があります.例えば,6以車線以上の道だけを表示するには,"num_lanes >= 6"のフィルタを使ってください.

  3. 空間データベースで,描画する任意のレイヤ用に空間インデックス(GiST)を構築したか確認してください.

      CREATE INDEX [indexname]
        ON [tablename] 
        USING GIST ( [geometrycolumn] GIST_GEOMETRY_OPS );
  4. もし,Mapserverを使ってレイヤに問合せを行いたいのなら,"oid index"も必要になるでしょう.

    Mapserverはクエリ実行時に各空間レコードに対してユニークな識別子を必要とします.そして,MpaserverのPostGISモジュールは,ユニークな識別子を提供するためにPostGISのoidの値を用います.このことの副作用は,問合せの間レコードへのランダムアクセスを高速に行うために,oidのインデックスが必要となることです.

    "oid index"を作るには,以下のSQLを使ってください:

      CREATE INDEX [indexname] ON [tablename] ( oid );

高度な使い方

USING 擬似SQL節はより複雑なクエリの結果をmapserverが理解するのを助けるために,いくつかの情報を追加するのに使われます.具体的には,viewかsubselectのどちらかが元のテーブル(source table)として使われた(データ定義の"FROM"の右側に位置すること)場合,各行のユニークな識別子とテーブルのSRIDとをmapserverが自動的に決定することはより困難です.USING節はmapserverに,以下のような2つの情報の断片を提供できます:

  DATA "the_geom FROM (SELECT table1.the_geom AS the_geom, table1.oid AS oid, table2.data AS data
  	FROM table1 LEFT JOIN table2 ON table1.id = table2.id) AS new_table USING UNIQUE oid USING SRID=-1"

USING UNIQUE <uniqueid>

Mapserverはマップクエリを実行するとき,行を識別するために各行に対してユニークなIDを必要とします.通常,ユニークな識別子としてoidが使われますが,viewとsubselectは自動的にoidカラムを持つことができません.Mapserverのクエリ機能を使いたい場合は,viewまたはsubselectにユニークなカラムを追加し,それをUSING UNIQUEで宣言する必要があります.例えば,この目的のために,テーブルのoid値の一つ,もしくは結果集合においてユニークとなることが保証される他の任意のカラムを選択することができるでしょう.

マップクエリを実行する場合,USINGステートメントは,単純なDATAステートメントに対しても便利になるでしょう.以前は,マップクエリのパフォーマンスを素ピーとアップするために,クエリが実行されるレイヤとして用いられるテーブルのoidカラムにインデックスを追加することが推奨されていました.しかしながら,USING節を用いて,mapserverにmapクエリのための識別とするテーブルのプライマリキーを教えることが可能になりました.そのため,もはや追加のインデックスを持つ必要はなくなりました.

注:"Querying a Map"は,クリックした場所の地図図形についての情報をたずねるために,地図上をクリックする動作です.DATA定義の中のSQLクエリを伴う"map queries"と混同しないで下さい.

USING SRID=<srid>

PostGISは,mapserverに正しいデータを返すために,どの参照系がジオメトリに使われているかを知る必要があります.通常それは,PostGISデータベースの"geometry_columns"にあるこの情報を見つけることができます.しかしながら,subselctやviewのようなその場で(on the fly)生成されるテーブルでは見つけることができません.そのため,USING SRID=オプションは,DATA定義の中で正しいSRIDを記述できるようにします.

簡単な例からはじめて,向上していきましょう.以下のMapserver例や定義を考えます.

  LAYER
  	CONNECTIONTYPE postgis
  	NAME "roads"
  	CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  	DATA "the_geom FROM roads"
  	STATUS ON
  	TYPE LINE
  	CLASS
  		COLOR 0 0 0
  	END
  END

このレイヤは,roadsテーブル中の全ての道ジオメトリを黒い線で表示するでしょう.

今度は仮に,高速道路だけを最低1:100000スケールまで拡大した状態で表示してみましょう - 次の2つの例やがこの結果を実現するでしょう. Now lets say we want to show only the highways until we get zoomed in to at least a 1:100000 scale - the next two layers will acheive this effect:

  LAYER
  	CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  	DATA "the_geom FROM roads"
  	MINSCALE 100000
  	STATUS ON
  	TYPE LINE
  	FILTER "road_type = 'highway'"
  	CLASS
  		COLOR 0 0 0
  	END
  END
  
  LAYER
  	CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  	DATA "the_geom FROM roads"
  	MAXSCALE 100000
  	STATUS ON
  	TYPE LINE
  	CLASSITEM road_type
  	CLASS
  		EXPRESSION "highway"
  		SIZE 2
  		COLOR 255 0 0
  	END
  	CLASS
  		COLOR 0 0 0
  	END
  END

最初のレイヤは,縮尺が1:10000より大きいときに使われ,タイプが"highway"の道だけを黒い線で表示します.FILTERオプションは,表示することにタイプ"highway"の道だけ緒を与えます.

2番目のレイヤは,縮尺が1:100000より小さいときに使われ,高速道路は2倍の幅の赤い線で,その他の道は普通の黒い線で表示するでしょう.

そのようにして,mapserverの機能だけを使って1組の面白いことをしましたが,DATAステートメントは単純なままです.道路名が(どういうわけか)他のテーブルに格納されいるて,それを得るために結合を行い,道にラベル付けをしたいと仮定します.

  LAYER
  	CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  	DATA "the_geom FROM (SELECT roads.oid AS oid, roads.the_geom AS the_geom, road_names.name as name
  			FROM roads LEFT JOIN road_names ON roads.road_name_id = road_names.road_name_id) AS named_roads
  			USING UNIQUE oid USING SRID=-1"
  	MAXSCALE 20000
  	STATUS ON
  	TYPE ANNOTATION
  	LABELITEM road_name
  	CLASS
  		LABEL
  			ANGLE auto
  			SIZE 8
  			COLOR 0 192 0
  			TYPE truetype
  			FONT arial
  		END
  	END
  END

この注釈(annotation)レイヤは,縮尺が1:20000以下になったときに緑のラベルを全ての道に追加します.それは,DATA定義でのSQL joinの使い方を実演(demonstrate)します.