2009年7月26日日曜日

東京都の地図 円積図(平成20年版)

東京都の地図 円積図(平成20年版)

人口を円積図で表します。人口によって円の大きさを変えて表示します。

レイヤ部分を記述します。
階級区分のマップファイルのうち、SYMBOLオブジェクトを追加し、gyoseikai2のレイヤを削除、totalpopレイヤを次のように修正します。

MAP
NAME tokyo_pgis_circle.map
---
SCALEBAR
TRANSPARENT TRUE
END

SYMBOL
NAME 'circle'
TYPE ELLIPSE
FILLED TRUE
POINTS
1 1
END
END
---
LAYER
NAME totalpop
GROUP totalpop
TYPE ANNOTATION
STATUS ON
CONNECTIONTYPE POSTGIS
CONNECTION "dbname=tokyo host=localhost user=user password=password"
DATA "the_geom FROM (
SELECT gyoseikai.gid AS gid,
gyoseikai.con AS con,
gyoseikai.cn2 AS cn2,
gyoseikai.aac AS aac,
gyoseikai.the_geom AS the_geom,
population.total AS total,
population.male AS male,
population.female AS female,
population.foreigner AS foreigner
FROM gyoseikai LEFT OUTER JOIN population ON gyoseikai.aac = population.aac)
AS gyosei_pop USING UNIQUE gid USING SRID=-1"
LABELITEM "total"
CLASSITEM "total"
METADATA
"group_title" "人口"
END
CLASS
NAME "50万人以上"
EXPRESSION ([total] >= 500000)
LABEL
SIZE tiny
COLOR 255 204 204
OUTLINECOLOR 102 51 51
POSITION ul
END
STYLE
SYMBOL 'circle'
COLOR 255 0 0
SIZE 20
END
END
CLASS
NAME "40万-50万人"
EXPRESSION ([total] < 500000 AND [total] >= 400000)
LABEL
SIZE tiny
COLOR 255 204 204
OUTLINECOLOR 102 51 51
POSITION ul
END
STYLE
SYMBOL 'circle'
COLOR 255 0 0
SIZE 17
END
END
CLASS
NAME "30万-40万人"
EXPRESSION ([total] < 400000 AND [total] >= 300000)
LABEL
SIZE tiny
COLOR 255 204 204
OUTLINECOLOR 102 51 51
POSITION ul
END
STYLE
SYMBOL 'circle'
COLOR 255 0 0
SIZE 14
END
END
CLASS
NAME "20万-30万人"
EXPRESSION ([total] < 300000 AND [total] >= 200000)
LABEL
SIZE tiny
COLOR 255 204 204
OUTLINECOLOR 102 51 51
POSITION ul
END
STYLE
SYMBOL 'circle'
COLOR 255 0 0
SIZE 11
END
END
CLASS
NAME "10万-20万人"
EXPRESSION ([total] < 200000 AND [total] >= 100000)
LABEL
SIZE tiny
COLOR 255 204 204
OUTLINECOLOR 102 51 51
POSITION ul
END
STYLE
SYMBOL 'circle'
COLOR 255 0 0
SIZE 8
END
END
CLASS
NAME "10万人以下"
EXPRESSION ([total] < 100000)
LABEL
SIZE tiny
COLOR 255 204 204
OUTLINECOLOR 102 51 51
POSITION ul
END
STYLE
SYMBOL 'circle'
COLOR 255 0 0
SIZE 5
END
END
END
---

東京都の地図 グラフ
奥多摩町のグラフも正常に表示されました。
totalpop レイヤを次のように修正しました。

MAP
NAME tokyo_pgis_graph.map
---
SCALEBAR
TRANSPARENT TRUE
END

# SYMBOL
# NAME 'circle'
# TYPE ELLIPSE
# FILLED TRUE
# POINTS
# 1 1
# END
# END
---
LAYER
NAME totalpop
GROUP totalpop
TYPE chart
STATUS ON
CONNECTIONTYPE POSTGIS
CONNECTION "dbname=tokyo host=localhost user=nob61 password=balanced"
DATA "the_geom from (
SELECT gyoseikai.gid AS gid,
gyoseikai.con AS con,
gyoseikai.cn2 AS cn2,
gyoseikai.aac AS aac,
gyoseikai.the_geom AS the_geom,
population.total AS total,
population.male AS male,
population.female AS female,
population.foreigner AS foreigner
FROM gyoseikai LEFT OUTER JOIN population ON gyoseikai.aac = population.aac
)
AS gyosei_pop USING UNIQUE gid USING SRID=-1"
LABELITEM "total"
CLASSITEM "total"
METADATA
"group_title" "人口"
END
CLASS
NAME "男"
STYLE
SIZE [male]
COLOR 51 51 255
END
END
CLASS
NAME "女"
STYLE
SIZE [female]
COLOR 255 51 51
END
END
CLASS
NAME "外国人"
STYLE
SIZE [foreigner]
COLOR 51 255 51
END
END
END
---

東京都のマップファイルと地図(平成20年版)

東京都の人口を階級区分して色分けする例です。

tokyo_shp2.mapをコピーしてtokyo_pgis_color.mapを作成します。
マップファイルのレイヤ部分を記述します。

MAP
NAME tokyo_pgis_color_map
---
LAYER
NAME gyoseikai
GROUP gyoseikai
TYPE POLYGON
STATUS ON
CONNECTIONTYPE POSTGIS
CONNECTION "dbname=tokyo host=localhost user=user password=password"
DATA "the_geom FROM (
SELECT gyoseikai.gid AS gid,
gyoseikai.con AS con,
gyoseikai.cn2 AS cn2,
gyoseikai.aac AS aac,
gyoseikai.the_geom AS the_geom,
population.total AS total,
population.male AS male,
population.female AS female,
population.foreigner AS foreigner
FROM gyoseikai LEFT OUTER JOIN population ON gyoseikai.aac = population.aac)
AS gyosei_pop USING UNIQUE gid USING SRID=-1"
LABELITEM "cn2"
METADATA
"group_title" "行政界"
"queryable" "true"
"searchfield" "cn2"
"fields" "con:郡政令,cn2:市区町村,total:人口"
END
CLASS
NAME "行政界"
STYLE
OUTLINECOLOR 153 153 153
END
LABEL
MINFEATURESIZE 40
TYPE TRUETYPE
FONT vl-gothic
ENCODING UTF-8
SIZE 8
END
END
TEMPLATE temp_tokyo_pgis.html #ここを修正
END

LAYER #ダミーのレイヤ
NAME gyoseikai2
GROUP totalpop
TYPE POLYGON
STATUS ON
CONNECTIONTYPE POSTGIS
CONNECTION "dbname=tokyo host=localhost user=user password=password"
DATA "the_geom FROM (
SELECT gyoseikai.gid AS gid,
gyoseikai.con AS con,
gyoseikai.cn2 AS cn2,
gyoseikai.aac AS aac,
gyoseikai.the_geom AS the_geom,
population.total AS total,
population.male AS male,
population.female AS female,
population.foreigner AS foreigner
FROM gyoseikai LEFT OUTER JOIN population ON gyoseikai.aac = population.aac)
AS gyosei_pop USING UNIQUE gid USING SRID=-1"
LABELITEM "cn2"
METADATA
"group_title" "人口"
END
CLASS
NAME "行政界"
STYLE
OUTLINECOLOR 153 153 153
END
LABEL
MINFEATURESIZE 40
TYPE TRUETYPE
FONT vl-gothic
ENCODING UTF-8
SIZE 8
END
END
END

LAYER #このレイヤを追加
NAME totalpop
GROUP totalpop
TYPE POLYGON
STATUS ON
CONNECTIONTYPE POSTGIS
CONNECTION "dbname=tokyo host=localhost user=user password=password"
DATA "the_geom FROM (
SELECT gyoseikai.gid AS gid,
gyoseikai.con AS con,
gyoseikai.cn2 AS cn2,
gyoseikai.aac AS aac,
gyoseikai.the_geom AS the_geom,
population.total AS total,
population.male AS male,
population.female AS female,
population.foreigner AS foreigner
FROM gyoseikai LEFT OUTER JOIN population ON gyoseikai.aac = population.aac)
AS gyosei_pop USING UNIQUE gid USING SRID=-1"
OPACITY 50
CLASSITEM "total"
METADATA
"group_title" "人口"
END
CLASS
NAME "50万人以上"
EXPRESSION ([total] >= 500000)
COLOR 255 0 0
END
CLASS
NAME "40万-50万人"
EXPRESSION ([total] < 500000 AND [total] >= 400000)
COLOR 255 51 51
END
CLASS
NAME "30万-40万人"
EXPRESSION ([total] < 400000 AND [total] >= 300000)
COLOR 255 102 102
END
CLASS
NAME "20万-30万人"
EXPRESSION ([total] < 300000 AND [total] >= 200000)
COLOR 255 153 153
END
CLASS
NAME "10万人-20万人"
EXPRESSION ([total] < 200000 AND [total] >= 100000)
COLOR 255 204 204
END
END

LAYER
NAME gun_seirei
GROUP gun_seirei
TYPE ANNOTATION
STATUS ON
CONNECTIONTYPE POSTGIS
CONNECTION "dbname=tokyo host=localhost user=user password=password"
DATA "the_geom FROM (
SELECT gyoseikai.gid AS gid,
gyoseikai.con AS con,
gyoseikai.cn2 AS cn2,
gyoseikai.aac AS aac,
gyoseikai.the_geom AS the_geom,
population.total AS total,
population.male AS male,
population.female AS female,
population.foreigner AS foreigner
FROM gyoseikai LEFT OUTER JOIN population ON gyoseikai.aac = population.aac)
AS gyosei_pop USING UNIQUE gid USING SRID=-1"
LABELITEM "con"
METADATA
"group_title" "郡政令"
"searchfield" "con"
"fields" "con:郡政令,cn2:市区町村,total:人口"
END
CLASS
NAME "郡政令"
LABEL
MINFEATURESIZE 40
TYPE TRUETYPE
FONT vl-gothic
ENCODING UTF-8
SIZE 8
POSITION uc
END
END
TEMPLATE temp_tokyo_pgis.html #ここを修正
END

END #MAP END


temp_tokyo_pgis.htmlを作成します。
temp_tokyo_shp.htmlをコピーしてファイル名を変えます。
内容を次のように修正します。

<html>
<head>
<title>Tokyo pgis Template</title> #ここを修正
</head>
<body>
<li>[con]
<li>[cn2]
<li>[total] #ここを追加
</body>
</html>

config.phpの内容をつぎのように修正します。

$aszTokyo = array (
'title' => 'Tokyo',
'path' => '/home/nob61/mapfile/tokyo_pgis_color.map',
'scales' => array( 500000, 250000, 100000 ),
'format' =>'PNG'
);

東京都の人口データ(平成20年)の準備とテーブルの作成

東京都の人口データ(平成20年)の準備

住民基本台帳による世帯と人口
http://www.toukei.metro.tokyo.jp/juukim/jm-index.htm

平成20年6月のデータをダウンロードしました。
これを人口総数(A+B)、男、女、外国人登録人口に行政コードを追加した単純な表にします。

例えば、
0 OpenOffice.org Calc でダウンロードしたファイルを開く
1 データをコピーし、別のファイルに
編集->形式を選択して張り付け->「テキスト、数」だけチェックして「OK」
2 列のタイトルは1行にする
3 市区町村の行以外を削除する(空行や合計行など)
4 市区町村名、人口総数(A+B)、男、女、外国人登録人口以外の列を削除する
5 行政コードを追加する (行政コード、市区町村名、人口総数(A+B)、男、女、外国人登録人口の順にしました。)
6 タイトル行を削除する
7 CSVファイルとして出力

行政コードは、インターネットで探すか、次のようにマップデータから作成します。

Eclipseを起動して tokyo データベースに接続します。
データベース構造(Database Structure) ウィンドウの

public -> テーブル(table) -> gyoseikai

をクリックを右クリックし、 Selectステートメントの生成 をクリックします。
SQLエディタ に次のように入力して実行します。

select distinct con, cn2, aac from "public"."gyoseikai"

表示された結果を右クリックして、 エクスポート->export to .csv をクリックします。
include column header をチェックし、宛先 ボタンをクリックして保存先とファイル名を指定し、OK ボタンをクリックします。

csvファイルを開き aac で「並べ替え」した後、aac (行政コード)をコピーし、加工した人口データに貼り付けます。


*コマンドでCSVファイルに出力

user@debian:~$ psql -F ',' -A -t -c 'SELECT DISTINCT con, cn2, aac from gyoseikai' tokyo > gyosei_code.csv


参考

user@debian:~$ psql tokyo
Welcome to psql 8.1.11, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

tokyo=> \o gyosei_aac.txt
tokyo=> SELECT DISTINCT con, cn2, aac from gyoseikai;
tokyo=> \!less gyosei_aac.txt
tokyo=> \o
tokyo=> \q

バージョン8.3なら次も可能

tokyo=> \COPY (SELECT DISTINCT con, cn2, aac from gyoseikai) TO 'aac2.csv' WITH DELIMITER ','

ファイルの内容

葛飾区,\N,13122
江戸川区,\N,13123
江東区,\N,13108
---


東京都の人口テーブルの作成

データベースtokyoに次のようにテーブルを作成します。

Eclipseの場合(2009.7.22現在、実行が完了してもテーブルが生成できないか、エラーが表示されました。)
データベース構造(Database Structure) ウィンドウの

public -> テーブル(table) -> gyoseikai

をクリックを右クリックし、 Create Table スクリプト をクリックします。
SQL エディタ を次のように修正して実行します。


CREATE TABLE "public"."population"(
aac varchar(5),
shikuchoso varchar(14),
total int4,
male int4,
female int4,
foreigner int4);


データベース構造(Database Structure) ウィンドウのテーブル(table)を右クリックし、更新 をクリックすると population テーブルが表示されます。

*コマンドで population テーブルを作成(2009.7.22現在、こちらでテーブルを作成しました。)

user@debian:~$ psql tokyo
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

tokyo=> CREATE TABLE population (
tokyo(> aac varchar(5),
tokyo(> shikuchoso varchar(14),
tokyo(> total int4,
tokyo(> male int4,
tokyo(> female int4,
tokyo(> foreigner int4);
NOTICE: CREATE TABLE will create implicit sequence "population_aac_seq" for serial column "population.aac"
CREATE TABLE
tokyo=> \q

tokyo_population.csv の内容を population テーブルに追加します。
スーパユーザー(postgres)で

nob61@debian:~$ su - postgres
パスワード:
postgres@debian:~$ psql tokyo
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

tokyo=# COPY population FROM '/home/nob61/download/tokyo_population/tokyo_population.csv' CSV;
COPY 62
tokyo=# \q

tokyo_pgis.mapの DATA の部分を次のように修正します。

DATA "the_geom from (
SELECT gyoseikai.gid AS gid,
gyoseikai.con AS con,
gyoseikai.cn2 AS cn2,
gyoseikai.aac AS aac,
gyoseikai.the_geom AS the_geom,
population.total AS total,
population.male AS male,
population.female AS female,
population.foreigner AS foreigner
FROM gyoseikai LEFT OUTER JOIN population ON gyoseikai.aac = population.aac
)
AS gyosei_pop USING UNIQUE gid USING SRID=-1"

東京(平成20年)の国土数値地図を PostGIS で

Synapticパッケージマネージャで次のパッケージをインストールします。
リポジトリの変更はありません。
現在の安定版 "lenny" では次のバージョンがインストールされます。

postgresql-8.3-postgis

データベースの作成は、
PostGISホームページ
http://postgis.refractions.net/

のDocumentation(html)の

PostGIS Manual
http://postgis.refractions.net/documentation/

の左サイドバーの Documentation: Stable Releases ●1.3 [html] (v1.3.6) をクリックして、

Chapter 2. Installation
http://postgis.refractions.net/documentation/manual-1.3/ch02.html

の2.2. PostGIS Compile from Source and Installの7,8,9,10を参考に前回使用した東京都のデータを使用したデータベースを作成します。
これには4つのステップがあります。

1:PostgreSQLのpl/pgsql言語サポートの有効化
2:lwpostgis.sqlの読み込み
3:spatial_ref_sys.sqlの読み込み
4:postgis_comments.sqlの読み込み(ver.1.3.3にはありませんでした)

です。
pl/pgsqlはデータベース内に組み込むことができる内部的なプログラミング言語をサポートします。
lwpostgis.sqlはPostGISの機能で、pl/pgsqlが有効になって読み込むことができます。
spatial_ref_sys.sqlは投影法に関する情報です。
postgis_comments.sqlは postgis が持つ機能についてのヘルプ文章です。

次に、2.2.1. Creating PostGIS spatially-enabled databases from an in-built template を参考にテンプレートを作成してデータベースを作成します。

nob61@debian:~/mapdata/tokyo$ psql tokyo
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

tokyo=> \dt
List of relations
Schema | Name | Type | Owner
--------+------------------+-------+-------
public | geometry_columns | table | nob61
public | gyoseikai | table | nob61
public | spatial_ref_sys | table | nob61
(3 rows)

tokyo=> \d gyoseikai
Table "public.gyoseikai"
Column | Type | Modifiers
----------+-----------------------+---------------------------------------------------------
gid | integer | not null default nextval('gyoseikai_gid_seq'::regclass)
prn | character varying(6) |
sun | character varying(1) |
con | character varying(8) |
cn2 | character varying(10) |
aac | character varying(5) |
the_geom | geometry |
Indexes:
"gyoseikai_pkey" PRIMARY KEY, btree (gid)
Check constraints:
"enforce_dims_the_geom" CHECK (ndims(the_geom) = 2)
"enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL)
"enforce_srid_the_geom" CHECK (srid(the_geom) = (-1))


*Galileoの場合
1 メニューバーの ヘルプ->新規ソフトウェアのインストール をクリックします。
2 使用可能なソフトウェアが表示されたら 追加 ボタンをクリックします。
3 サイトの追加 ポップアップウィンドウの 名前に SQL Explorer ロケーション に次のURLを入力して OK ボタンをクリックします。
http://eclipsesql.sourceforge.net/
4 使用可能なソフトウェア ポップアップウィンドウ表示されたら、追加されたsqlexplorer のアップデートサイトのチェックボックスをクリックしてチェックし、次へ ボタンをクリックします。
(項目をカテゴリー別にグループ化 のチェックを外してください。)
5 インストール詳細 ポップアップウィンドウ表示されたら 次へ ボタンをクリックします。
6 ライセンスのビュー が表示されたら 使用条項の条件に同意します をクリックし 完了 ボタンをクリックします。
7 インストールが終了したら ソフトウェア更新 ポップアップウィンドウ表示されるので はい ボタンをクリックし、eclipseを再起動します。


メニューバーの ウィンドウ->パースペクティブを開く->その他 で パースペクティブを開く ポップアップウィンドウ表示されるので SQL Explorer をクリックし OK ボタンをクリックします。
ウインドウ->設定 をクリックします。
設定ポップアップウィンドウの SQL Explorer->JDBC ドライバー をクリックします。
PostgreSQL を選択して 編集 ボタンをクリックします。
Change Driverポップアップウィンドウの 追加クラス・パス タブをクリックし、新規 ボタンをクリックします。
ポップアップウィンドウで /usr/share/java/postgresql-jdbc3-8.2.jar を選んで OK ボタンをクリックします。
(ない場合は、Synapticパッケージマネージャで libpg-java をインストールしてください。)
Change Driverポップアップウィンドウで postgresql-jdbc3-8.2.jar を選んで ドライバーをリス をボタンをクリックし、ドライバクラス名 が表示されたら OK ボタンをクリックします。
設定 ポップアップウィンドウの OK ボタンをクリックします。

接続 ウィンドウ上で右クリックし、新規接続プロファイル をクリックします。
新規接続プロファイル作成 ポップアップで次のように入力します。

Name:tokyo
Drivers:PostgreSQL
URL:jdbc:postgresql:[[:<5432>/]]
->jdbc:postgresql://localhost:5432/tokyo
User Name:user
Password:*******
Auto Logon:チェック(お好みで)

OK ボタンをクリックします。
接続 ウィンドウ上の tokyo の user を右クリックし 接続 をクリックします。
データベース構造(Database Structure) ウィンドウの

public -> テーブル(table) -> gyoseikai

をクリックし データベース詳細(Database Detail) ウィンドウの プレビュー(Preview) タブをクリックすると gyoseikaiテーブル のデータ内容が表示されます。

tokyo_pgis.map

MAP
NAME tokyo_pgis_map # 名前を変更
---
LAYER
NAME gyoseikai
TYPE POLYGON
STATUS ON
# DATA "../mapdata/tokyo/N03-090320_13_EC01.shp" # 削除
CONNECTIONTYPE POSTGIS # 追加
CONNECTION "dbname=tokyo host=localhost user=nob61 password=balanced" # 追加
DATA "the_geom from gyoseikai" # 追加
LABELITEM cn2 # PostGISでは大文字小文字を区別します
METADATA
"group_title" "行政界"
# "layer_encoding" "SJIS" # 削除
"queryable" "true"
"searchfield" "cn2" # PostGISでは大文字小文字を区別します
"fields" "con:郡政令,cn2:市区町村" # PostGISでは大文字小文字を区別します
END
CLASS
# NAME "City Boundaries"
NAME "行政界"
STYLE
OUTLINECOLOR 153 153 153
END
LABEL
MINFEATURESIZE 40
TYPE TRUETYPE
FONT vl-gothic
ENCODING UTF-8
SIZE 8
END
END
TEMPLATE temp_tokyo_shp.html
END

LAYER
NAME gun_seirei
GROUP gun_seirei
TYPE ANNOTATION
STATUS ON
# DATA "../mapdata/tokyo/N03-090320_13_EC01.shp" # 削除
CONNECTIONTYPE POSTGIS # 追加
CONNECTION "dbname=tokyo host=localhost user=nob61 password=balanced" # 追加
DATA "the_geom from gyoseikai" # 追加
LABELITEM con # PostGISでは大文字小文字を区別します
METADATA
"group_title" "郡政令"
# "layer_encoding" "SJIS" # 削除
"searchfield" "con" # PostGISでは大文字小文字を区別します
"fields" "con:郡政令,cn2:市区町村" # PostGISでは大文字小文字を区別します
END
CLASS
NAME "Gun Seirei Label"
LABEL
MINFEATURESIZE 40
TYPE TRUETYPE
FONT vl-gothic
ENCODING UTF-8
SIZE 8
POSITION uc
END
END
TEMPLATE temp_tokyo_shp.html
END

END # End of Mapfile

2009年7月21日火曜日

東京(平成20年)の国土数値地図

行政界の東京のデータはN03-090320_13(平成20年)です。
ダウンロードしたファイルは解凍するとXMLファイルになります。
ksjtoolでシェイプファイルに変換してください。
変換したシェイプファイルは、名前がtokyoのフォルダに入れておくとわかりやくなります。

シェイプファイルの内容は、

user@debian:~/mapdata$ ogrinfo tokyo
INFO: Open of `tokyo'
using driver `ESRI Shapefile' successful.
1: N03-090320_13_EC01 (Polygon)
user@debian:~/mapdata$ ogrinfo -summary tokyo N03-090320_13_EC01
INFO: Open of `tokyo'
using driver `ESRI Shapefile' successful.

Layer name: N03-090320_13_EC01
Geometry: Polygon
Feature Count: 3298
Extent: (136.069482, 20.425119) - (153.986900, 35.898424)
Layer SRS WKT:
(unknown)
PRN: String (6.0)
SUN: String (1.0)
CON: String (8.0)
CN2: String (10.0)
AAC: String (5.0)


東京都ではデータが次のようになっています。
このままデータを使用します。
マップファイルもこれを使って修正します。

PRN: 都道府県
SUN: ?
CON: 郡政令、23区名と西多摩郡
CN2: 市区町村、市町村名
AAC: 行政コード

マップファイルのレイヤの例(tokyo_shp.map)

---
LAYER
NAME gyoseikai
TYPE POLYGON
STATUS ON
DATA "../mapdata/tokyo/N03-090320_13_EC01.shp"
LABELITEM CN2
METADATA
"group_title" "行政界"
"layer_encoding" "SJIS"
"queryable" "true"
"searchfield" "CN2"
"fields" "CON:郡政令,CN2:市区町村"
END
CLASS
# NAME "City Boundaries"
NAME "行政界"
STYLE
OUTLINECOLOR 153 153 153
END
LABEL
MINFEATURESIZE 40
TYPE TRUETYPE
FONT vl-gothic
ENCODING SJIS
SIZE 8
END
END
TEMPLATE temp_tokyo_shp.html
END

LAYER
NAME gun_seirei
GROUP gun_seirei
TYPE ANNOTATION
STATUS ON
DATA "../mapdata/tokyo/N03-090320_13_EC01.shp"
LABELITEM CON
METADATA
"group_title" "郡政令"
"layer_encoding" "SJIS"
"searchfield" "CON"
"fields" "CON:郡政令,CN2:市区町村"
END
CLASS
NAME "Gun Seirei Label"
LABEL
MINFEATURESIZE 40
TYPE TRUETYPE
FONT vl-gothic
ENCODING SJIS
SIZE 8
POSITION uc
END
END
TEMPLATE temp_tokyo_shp.html
END

END # End of Mapfile

2009年7月19日日曜日

Eclipse "Galileo" のインストール

Debian 5.0 "lenny" を再インストールしたので、MapServer を最初からインストールしています。


Eclipse がバージョンアップしたので、そちらをインストールしました。

"Galileo" Eclipse IDE for Java Developers Linux 32bit

インストールは以前と同じ方法でしました。


日本語化のため Pleiades をインストールしました。

最新版(1.3.1.I* 2009.7.16現在)は Debian で unzip できませんでした。
WindowsXP で解凍後、Debianに移動。
次のようなエラーが出て Eclipse が起動できませんでした。

nob61@m-net:~/Desktop/eclipse$ ./eclipse -clean
INFO 16:47:32.168 [main] (PropertySet) load 0.026 秒 - 13 エントリー config.ini
クラスパス上にファイルが見つかりません。/.marker java.io.FileNotFoundException: クラスパス上にファイルが見つかりません。/.marker
Pleiades AOP 翻訳コンテナーの起動に失敗しました。起動オプションに -clean を指定して起動してください。
java.lang.ExceptionInInitializerError

所有者を替えても起動できなかったので、安定版をインストールすることにしました。

安定版 1.3.0 2009.7.16現在


Pleiades の splash 画面

2009年7月14日火曜日

座標データから描画する例でやり残したこと

XML データ関連でベクトル図を描画する例でやり残したことは、GeoRSS を利用した例と、SLD(Styled Layer Descriptor)を利用した例です。

OpenLayers の example サイトにある GeoRSS 関連の地図は、

GeoRSS Example(georss.html) georss.xmlファイルはPlatial地図投稿サービスサイトのRDF Site Summary(RSS 0.9とRSS 1.0)。現在はRSS2.0。
GeoRSS Marker Example(georss-markers.html)yelp-georss.xmlファイルはyelp地図検索サイトのAtom + georss.xml。
GeoRSS from Flickr in OpenLayers(georss-flickr.html)georss-flickr.xmlはflickr写真共有サイトのRSS2.0。GeoFeedのリンクがあります。
(GeoRSS Point Track in OpenLayers は track1.xml のデータの元が分かりませんでした。)

です。

今回は Google マップを使って RSS2.0 の地図を描画してみましたが、スケール(units) が メータ(meter) の地図では表示されませんでした。
いろいろ試した結果、

<georss:point>x(経度) y(緯度)</georss:point>



<georss:point>y x</georss:point>

にすると表示されました。
緯度経度(degree)では出力した RSS のままで表示されます。

Styled Layer Descriptor (SLD) Example は複雑なので単純な例を探しましたがいいものが見つかりませんでした。


OpenLayers の Example で他にやってみたいことは、

BBOX Strategy Example - Show images on map
Cluster Strategy Example - Show images list under
Paging Strategy Example - Show images on map each pages

Click Handler Example
Click Event Example
Event Handling
Hover Handler Example

などがあります。
画像データをたくさん用意したり、自分のスキルで理解できるかということがあるので時間がかかると思います。

VMWare で設定した仮想の容量もいっぱいのなってきて、Debian からインストールしなおそうと思っていますので、しばらくは GIS に興味を持った理由を書きたいと思います。

2009年7月12日日曜日

Openlayers 19f Intersects ベクトル図のデータ入出力

OpenLayers Geometry Intersection Example (intercects.html)
参考に、描画した図のデータ表示とデータで図の描画をしてみます。

CSS、javascript、HTML を次のようにします。
Vector Layer(描画レイヤ) を Overlay にして、地図上に Vector Layer を表示できるようにしました。

---
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
#leftcol { /* 全体を囲むボックス */
position: absolute;
top: 0;
left: 1em;
padding: 0;
width: 512px;
}
#map {
width: 512px;
height: 512px;
border: 1px solid black;
}
#input { /* "text" と "add feature" ボタンを囲むボックス */
width: 512px;
}
#text { /* "text" ボックス */
font-size: 0.85em;
margin: 1em 0 1em 0;
width: 100%;
height: 10em;
}
#info { /* "features" と "intersections" を囲むボックス */
position: relative;
padding: 2em 0;
margin-left: 520px;
}
#features { /* "features" ボックス */
font-size: 0.8em;
width: 100%;
height: 200px;
}
#intersections { /* "intersections" ボックス */
font-size: 0.8em;
width: 100%;
height: 200px;
}
p {
margin: 0;
padding: 0.75em 0 0.75em 0;
}
</style>
<script src="lib/Firebug/firebug.js"></script>
<script src="lib/OpenLayers.js"></script>
<script type="text/javascript">
var map, vectros, geojson;
var layer1;
var extent = new OpenLayers.Bounds(-31337.715508,-77650.134635,-21796.513842,-70055.061952);

function init(){
OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url=";

var mapOptions = {
numZoomLevels: 10,
maxResolution: 'auto',
units: 'meters',
maxExtent: extent
};
map = new OpenLayers.Map('map', mapOptions);

layer1 = new OpenLayers.Layer.WMS("Kamakura Chojikai Sen WMS", "http://localhost/cgi-bin/mapserv?", {
map: '/home/nob61/mapfile/kamakura_pgis.map',
layers: 'chojisen,kenchiku,doro,tetsudo',
format: 'image/png'
}, {
projection: 'EPSG:2451'
});
map.addLayer(layer1);

vectors = new OpenLayers.Layer.Vector(
"Vector Layer" /*,
{isBaseLayer: true} // Vector Layer(描画レイヤ) を Overlay にする
*/);

map.addLayers([vectors]);
map.addControl(new OpenLayers.Control.MousePosition()); //地図右下のマウス位置座標

var panel = new OpenLayers.Control.EditingToolbar(vectors); //描画ツールパネル
map.addControl(panel);

geojson = new OpenLayers.Format.GeoJSON();

map.zoomToMaxExtent();

map.addControl(new OpenLayers.Control.LayerSwitcher()); //レイヤスイッチャー

} //End of init()

// ここから描画図のデータ出力、追加スクリプト
function serialize() {
var str = geojson.write(vectors.features, true);
document.getElementById('features').value = str;
}

function deserialize() {
var element = document.getElementById('text');
var features = geojson.read(element.value);
var bounds;
if(features) {
if(features.constructor != Array) {
features = [features];
}
for(var i=0; i<features.length; ++i) {
if (!bounds) {
bounds = features[i].geometry.getBounds();
} else {
bounds.extend(features[i].geometry.getBounds());
}
}
vectors.addFeatures(features);
map.zoomToExtent(bounds);
var plural = (features.length > 1) ? 's' : '';
element.value = features.length + ' feature' + plural + ' added'
} else {
element.value = 'Bad input';
}
}

function intersect() {
var features = vectors.features;
var feat1, feat2, intersects12, intersects21;
var parts = [];
// reset attributes
for(var i=0; i<features.length; ++i) {
features[i].attributes.intersectsWith = [];
}
for(var i=0; i<features.length-1; ++i) {
feat1 = features[i];
for(var j=i+1; j<features.length; ++j) {
feat2 = features[j];
intersects12 = feat1.geometry.intersects(feat2.geometry);
if(intersects12) {
feat1.attributes.intersectsWith.push("f" + j);
parts.push("f" + i + " intersects f" + j + "\n");
}
intersects21 = feat2.geometry.intersects(feat1.geometry);
if(intersects21) {
feat2.attributes.intersectsWith.push("f" + i);
parts.push("f" + j + " intersects f" + i + "\n");
}
if(intersects12 != intersects21) {
parts.push("trouble with " + i + " and " + j + "\n");
}
}
}
if(parts.length > 0) {
document.getElementById("intersections").value = parts.join("");
} else {
document.getElementById("intersections").value = "no intersections";
}
}

// preload images
(function() {
var roots = ["draw_point", "draw_line", "draw_polygon", "pan"];
var onImages = [];
var offImages = [];
for(var i=0; i<roots.length; ++i) {
onImages[i] = new Image();
onImages[i].src = "../theme/default/img/" + roots[i] + "_on.png";
offImages[i] = new Image();
offImages[i].src = "../theme/default/img/" + roots[i] + "_on.png";
}
})();
// ここまで
</script>
</head>
<body onload="init()">
<div id="leftcol">
<h1 id="title">Display Data10</h1>
<div id="map"></div>
<div id="input">
<textarea id="text"></textarea>
<input type="button" value="add feature" onclick="deserialize();" />
<span id="selected"></span>
</div>
</div>
<div id="info">
Features
<input type="button" value="refresh" onclick="serialize();" /><br />
<textarea id="features"></textarea>
Intersections
<input type="button" value="intersect all" onclick="intersect();" /><br />
<textarea id="intersections"></textarea>
</div>
</body>
</html>


// 出力データの例

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "OpenLayers.Feature.Vector_143",
"properties": {
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-27293.885895652344,
-72715.85356376172
],
[
-25188.11287171094,
-74038.94988853905
],
[
-27554.778128707032,
-75250.23525629296
],
[
-27293.885895652344,
-72715.85356376172
]
]
]
}
}
]
}


図1:描画したベクトル図のデータ出力


図2:出力したデータを入力


図3:出力したデータで描画

2009年7月11日土曜日

OpenLayers 19d GeoJSON でレイヤ描画

GeoJSON Example(geojson.html)を参考にベクトル図を描画してみます。

最初に、JSON(JavaScript Object Notation)について簡単に説明します。
JSON のホームページ(http://json.org/)よると、JavaScript用の軽量データ交換フォーマットとあります。
その基本的な構造は、

(オブジェクト) { 名前 : 値 }

で、複数の内容はカンマ(,)で区切り、配列にはハッシュ(hash)を使います。

(オブジェクト) { 名前1 : 値1, 名前2 : [ 値2, 値3, 値4 ] }

GeoJSON は、GeoJSON のホームページ(http://geojson.org/)spec サイト(http://geojson.org/geojson-spec.html)の 「1. Introduction」 によると、地理データ構造をエンコーディングするフォーマットです。
GeoJSON で Point は、次のように表記します。

{ "type": "Point", "coordinates": [100.0, 0.0] }

詳しい内容は GeoJSON のホームページの spec サイトをみてください。

OpenLayers の GeoJSON Example(geojson.html)の GeoJSON 部分をみてみます。
(数値は、鎌倉市に描画できるように直してあります。)

次のスクリプトを追加します。

---
// ここから追加
var featurecollection = { //オブジェクトの宣言
"type": "FeatureCollection", //オブジェクトの型
"features": [ //フィーチャズ
{"geometry": { //フィーチャズの地理データ(値が入れ子になっている)
"type": "GeometryCollection", // 「geometry」の型
"geometries": [ //「geometry」の地理データ(ハッシュ配列)
{
"type": "LineString", //「geometry」の地理データ-線
"coordinates": // 座標
[[-26659.018612,-71776.660019], // 経度, 緯度
[-27159.018612,-72276.660019],
[-27159.018612,-72776.660019]]
},
{
"type": "Polygon", //「geometry」の地理データ-ポリゴン
"coordinates":
[[[-27159.018612,-72776.660019],
[-27659.018612,-73276.660019],
[-27359.018612,-73776.660019],
[-26859.018612,-73776.660019],
[-26359.018612,-73276.660019],
[-27159.018612,-72776.660019]]]
},
{
"type":"Point", //「geometry」の地理データ-点
"coordinates":[-26659.018612,-71776.660019]
}
]
},
"type": "Feature", //フィーチャズの型(「Feature」はフィーチャのオブジェクト)
"properties": {}} //「Feature」は必ず「properties」を持ち、値は「JSONオブジェクト」または「null」
]
};

var geojson_format = new OpenLayers.Format.GeoJSON();
var vector_layer = new OpenLayers.Layer.Vector();
map.addLayer(vector_layer);
vector_layer.addFeatures(geojson_format.read(featurecollection));
// ここまで

} // End of function init()
---

2009年7月9日木曜日

OpenLayers 19c KMLでレイヤを描画 ポップアップ

KML Layer Example(sundials.html)を参考に、KMLでポップアップ表示する」レイヤを描画してみます。
(OpenLayers-2.6の場合。2.8ではスクリプトが違うので注意してください。)

次のスクリプトを追加します。(以前の変数などが重複していことがあるので、新しくスクリプトを作成しました。)

---
<script type="text/javascript">
var popup;
var map = null;
var layer1
var running = false;
var extent = new OpenLayers.Bounds(-31337.715508,-77650.134635,-21796.513842,-70055.061952);

function init(){
OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url=";
var mapOptions = {
numZoomLevels: 10,
maxResolution: 'auto',
units: 'meters',
maxExtent: extent
};
map = new OpenLayers.Map('map', mapOptions);
layer1 = new OpenLayers.Layer.WMS("Kamakura Chojikai Sen WMS", "http://localhost/cgi-bin/mapserv?", {
map: '/home/user/mapfile/kamakura_pgis.map',
layers: 'chojisen,kenchiku,doro,tetsudo',
format: 'image/png'
}, {
projection: 'EPSG:2451'
});
map.addLayer(layer1);
map.zoomToMaxExtent();

// ここから追加
map.addLayer(new OpenLayers.Layer.GML("KML", "kml_point2.kml",
{
format: OpenLayers.Format.KML,
formatOptions: {
extractStyles: true,
extractAttributes: true
}
}));
selectControl = new OpenLayers.Control.SelectFeature(map.layers[1],
{onSelect: onFeatureSelect, onUnselect: onFeatureUnselect});

map.addControl(selectControl);
selectControl.activate();
// ここまで

} // End of function init()

// ここから追加
function onPopupClose(evt) {
selectControl.unselect(selectedFeature);
}
function onFeatureSelect(feature) {
selectedFeature = feature;
popup = new OpenLayers.Popup.FramedCloud("chicken",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(100,100),
"<h2>"+feature.attributes.name + "</h2>" + feature.attributes.description,
null, true, onPopupClose);
feature.popup = popup;
map.addPopup(popup);
}
function onFeatureUnselect(feature) {
map.removePopup(feature.popup);
feature.popup.destroy();
feature.popup = null;
}
//ここまで
</script>
---

kml_point2.xml ファイルの内容を次のようにします。

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document> <!-- アイテムとスタイルのコンテナ -->
<name>Sundial Collection.kmz</name>
<Style id="sn_sunny_copy69"> <!-- StyleMap や Feature で参照できる、呼び出し可能なスタイル グループを定義 -->
<IconStyle> <!-- アイコンの描画方法を指定 -->
<scale>1.2</scale> <!-- アイコンの x、y 方向のスケーリングを指定 -->
<Icon> <!-- アイコンの画像を指定 -->
<href>http://maps.google.com/mapfiles/kml/shapes/sunny.png</href>
</Icon>
<hotSpot x="0.5" y="0.5" xunits="fraction" yunits="fraction"/> <!-- <Point> に「固定されている」アイコン内の位置を指定 -->
</IconStyle>
<LabelStyle> <!-- Feature の <name> の描画方法を指定 -->
<color>ff00aaff</color> <!-- αRGB -->
</LabelStyle>
</Style>
<Style id="sh_sunny_copy70">
<IconStyle>
<scale>1.4</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/shapes/sunny.png</href>
</Icon>
<hotSpot x="0.5" y="0.5" xunits="fraction" yunits="fraction"/> <!-- Placemark 内で指定した <Point> に「固定されている」アイコン内の位置を指定 -->
</IconStyle>
<LabelStyle>
<color>ff00aaff</color>
</LabelStyle>
</Style>
<StyleMap id="msn_sunny_copy70"> <!-- カーソルを重ねたときに強調 -->
<Pair> <!-- 通常 -->
<key>normal</key>
<styleUrl>#sn_sunny_copy69</styleUrl> <!-- 参照先 -->
</Pair>
<Pair> <!-- カーソルを重ねたとき -->
<key>highlight</key>
<styleUrl>#sh_sunny_copy70</styleUrl> <!-- 参照先 -->
</Pair>
</StyleMap>
<Folder> <!-- 他の Feature を階層的に配置 -->
<name>Sundial Collection</name>
<open>1</open> <!-- ドキュメントやフォルダの開閉状態 -->
<LookAt> <!-- 仮想カメラの位置設定 -->
<longitude>-26659.018612</longitude> <!-- 経度 dd -->
<latitude>-71776.660019</latitude> <!-- 緯度 dd -->
<altitude>0</altitude> <!-- 高度 m -->
<range>9958750.824018393</range> <!-- 視点位置 LookAt からの距離 m -->
<tilt>1.303827428939919e-015</tilt> <!-- 地表からの法線との角度 -->
<heading>-16.31426621668193</heading> <!-- 視点の向き 北0 +-180 -->
</LookAt>
<Style> <!-- 呼び出し可能なスタイル グループを定義 -->
<ListStyle> <!-- リスト ビューに Feature を表示する方法を指定 -->
<listItemType>check</listItemType> <!-- check:Feature の表示/非表示は、その項目のチェックボックスの設定と連動 -->
<bgColor>00ffffff</bgColor> <!-- αRGB -->
</ListStyle>
</Style>
<Folder>
<name>High Resolution</name>
<Placemark>
<name>鎌倉女子大学</name>
<description><![CDATA[<p><img src="http://localhost/openlayers/OpenLayersproj/mapsign/tatsu2.png" width="150" height="150"></p>

<p>Image source:<a href="http://localhost/openlayers/OpenLayersproj/mapsign/tatsu2.png">tatsu2.png</a></p>]]></description>
<!-- 説明バルーンに表示されるユーザー定義コンテンツ -->
<!-- CDATA: HTMLをそのまま使用できる -->
<LookAt>
<longitude>-26659.018612</longitude>
<latitude>-71776.660019</latitude>
<altitude>0</altitude>
<range>111.6162130745504</range>
<tilt>0</tilt>
<heading>0.0003913059632004609</heading>
<altitudeMode>relativeToGround</altitudeMode><!-- <coordinates> 要素内の標高コンポーネントの解釈方法 -->
<!-- relativeToGround:特定の場所の実際の高度に対して相対的に設定 -->
</LookAt>
<styleUrl>#msn_sunny_copy70</styleUrl>
<Point>
<coordinates>-26659.018612,-71776.660019</coordinates>
</Point>
</Placemark>
</Folder>
</Folder>
</Document>
</kml>

2009年7月7日火曜日

OpenLayers 19b KMLでレイヤ描画

KML Layer Example(kml-layer.html)を参考に、KMLでレイヤを描画してみます。

KMLは、Googleが開発した地理情報を表現するマークアップ言語で、現在はOGCの管理で運用されています。
OGCのサイトによると、その特徴は、Webマッピングで、モバイル地図(2次元)[Googleマップなど]と地球ブラウザ(3次元)[Googleアースなど]での地理的な注釈やデータの可視化です。

KMLについて、Google Earth の「KML のサンプル」を参考にしてみてみます。

<?xml version="1.0" encoding="UTF-8"?>

これがXML文章であるという「XML宣言」です。
<?xml バージョン 文字のエンコード ?> という内容です。


<kml xmlns="http://earth.google.com/kml/2.1">

これは「名前空間」で、KMLでは必ずこれを入力します。


<Placemark>

Google Earth の「目印」は、<Point> という「子」を持つ <Placemark>要素で表示されます。
<Placemark> には、LineString、Polygon、Model などの図形要素を1つ以上設定できるようです。


<Placemark> の子は

<name>:<Placemark> の「名前」。Google Earth では、目印のラベル。
<description>:<Placemark> の「記述(内容)」。Google Earth では、目印のバルーン。
<Point>:<Placemark> の「点」の位置。
<coordinates>:座標

になります。


地図上の表示は「Point(点)」になります。
Google マップでの KML のリファレンスが Google code にあります。
Google マップ上での動作なので、OpenLayers では動作しないものがありますので注意してください。

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Placemark>
<name>Simple placemark</name>
<description>Attached to the ground. Intelligently places itself
at the height of the underlying terrain.</description>
<Point>
<coordinates>-26659.018612,-71776.660019</coordinates>
</Point>
</Placemark>
</kml>

LineString の例

<Style id="greenLineYellowPoly"> <!-- StyleMap や Feature で参照できる、呼び出し可能なスタイル グループを定義 -->
<LineStyle> <!-- 線形状の描画スタイル(色、色モード、線の幅)を指定 -->
<color>7f00ff00</color> <!-- αRGB -->
<width>4</width> <!-- 線の幅(ピクセル単位)-->
</LineStyle>
<PolyStyle> <!-- ポリゴンの描画スタイルを指定 -->
<color>7f00ffff</color>
</PolyStyle>
</Style>
<Placemark>
<name>Absolute Extruded</name>
<description>Transparent yellow wall with green outlines</description>
<styleUrl>#greenLineYellowPoly</styleUrl> <!-- Document で定義されている <Style> または <StyleMap> の URL -->
<LineString> <!-- 連結された一連の線を定義 -->
<extrude>1</extrude> <!-- ブール値。LinearRing を地面に接続するかどうかを指定 -->
<tessellate>1</tessellate> <!-- ブール値。LinearRing を地形に合わせて表示するかどうかを指定 -->
<altitudeMode>absolute</altitudeMode> <!-- <coordinates> 要素内の標高コンポーネントの解釈方法を指定 -->
<!-- absolute: 要素の下にある地形の実際の高度に関係なく、座標の標高を海面に対して相対的に設定 -->
<coordinates> -26659.018612,-71776.660019,2357
-27159.018612,-72276.660019,2357
-27159.018612,-72776.660019,2357
</coordinates>
</LineString>
</Placemark>


Polygon の例

<Placemark>
<name>The Pentagon</name>
<styleUrl>#greenLineYellowPoly</styleUrl>
<Polygon> <!-- 外側の境界と、0 または 1 つ以上の内側の境界を指定することによって定義 -->
<extrude>1</extrude>
<altitudeMode>relativeToGround</altitudeMode>
<!-- relativeToGround: 要素の標高を、特定の場所の実際の高度に対して相対的に設定 -->
<outerBoundaryIs> <!-- 外周 -->
<LinearRing> <!-- 閉じた折れ線を定義 -->
<coordinates>
-27159.018612,-72776.660019,100
-27659.018612,-73276.660019,100
-27359.018612,-73776.660019,100
-26859.018612,-73776.660019,100
-26359.018612,-73276.660019,100
-27159.018612,-72776.660019,100
</coordinates>
</LinearRing>
</outerBoundaryIs>
<innerBoundaryIs><!-- 内周 -->
<LinearRing>
<coordinates>
-27159.018612,-72976.660019,100
-27359.018612,-73276.660019,100
-27159.018612,-73576.660019,100
-27159.018612,-73576.660019,100
-26559.018612,-73276.660019,100
-27159.018612,-72976.660019,100
</coordinates>
</LinearRing>
</innerBoundaryIs>
</Polygon>
</Placemark>

次のスクリプトを追加します。

// ここから追加
map.addLayer(new OpenLayers.Layer.GML("KML", "kml_point.kml",
{
format: OpenLayers.Format.KML,
formatOptions: {
extractStyles: true,
extractAttributes: true
}
}));
// ここまで
} // End of function init()

2009年7月6日月曜日

OpenLayers 19a GML でレイヤ描画

GML Layer Example(gml-layer.html)を参考に、GMLでレイヤを描画してみます。
最初にGMLについて。GMLとは、Wikipediaによると「Geography Markup Language (GML)はOpen Geospatial Consortium (OGC)によって開発された地理的特徴を表現する XMLベースのマークアップ言語である。」とあります。もう少し詳しくみるために

Introduction to GML Geography Markup Language
http://www.w3.org/Mobile/posdep/GMLIntroduction.html

を参考にしてみました。

まず、気になったのは、GMLはホームページのコンテンツのような利用が想定されていること。地理情報の伝達方法が主な目的で、地理情報を保存しておくには向いていないようです。
GMLの具体的な内容みるために、データベース(PostGIS)から特定のレイヤのデータをダウンロードしてみました。(マップサーバから特定のレイヤのWFSデータをダウンロードしてみました)。

次のデータの先頭部分から見ていくと:

<?xml version='1.0' encoding="utf-8" ?>

これがXML文章であるという「XML宣言」です。
<?xml バージョン 文字のエンコード ?> という内容です。


<wfs:FeatureCollection

の続きに

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

これは「名前空間」で、要素名(タグ名)がどこで決められたものかを識別するものです。
xmlns:接頭辞(プレフィックス)="URI" という内容です。この URI には何も入っていなくてもいいそうです。<ms:要素名 ...> というタグは、マップサーバの定義にしたがっているということです。

他にもここには

xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:gml="http://www.opengis.net/gml"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd
http://mapserver.gis.umn.edu/mapserver http://localhost/cgi-bin/mapserv?map=/home
/nob61/mapfile/kanagawa_mlit_pgis_school.map&SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType
&TYPENAME=university&OUTPUTFORMAT=XMLSCHEMA"

があり、これらによってこの文章が決められています。

補足 「xsi:schemaLocation=...」
xsi:XML Schema Instance
スキーマ:情報の構造を定義するための記述のこと。
インスタンス:XML Schemaなどスキーマに従って作成されたXML文章。
schemaLocation:XML スキーマ定義言語 (XSD)のXML インスタンス ドキュメントで使用する 4 つの属性の一つ。対象の名前空間を持つスキーマ ドキュメントを、インスタンス ドキュメントに関連付る。


記述されている名前空間によって、この文章(地理データ)全体を表現しているルールが決められているようです。

"FeatureCollection"の次に

<gml:boundedBy>
<gml:Box srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019 -26659.018612,-71776.660019</gml:coordinates>
</gml:Box>
</gml:boundedBy>

の内容をみてみます。

<接頭辞:要素名>
<接頭辞:要素名 属性="EPSG:2451">
<接頭辞:要素名>-26659.018612,-71776.660019 -26659.018612,-71776.660019</接頭辞:要素名>
</接頭辞:要素名>
</接頭辞:要素名>

「接頭辞」は、名前空間で指定された

xmlns:gml="http://www.opengis.net/gml"

の "xmlns:gml=..." に指定されている "gml" に対応しています。ここには、この文章全体の範囲(座標)が記述されているみたいです。要素名は、

boundedBy:境界線
Box:四角い範囲
coordinates:座標

をあらわしているようです。


<gml:featureMember> 以降は、
<ms:university fid="university.3354">
<gml:boundedBy>
<gml:Box srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019 -26659.018612,-71776.660019</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<ms:msGeometry>
<gml:Point srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019</gml:coordinates>
</gml:Point>
</ms:msGeometry>
<ms:gid>3354</ms:gid>
<ms:aac>14204</ms:aac>
<ms:ren></ms:ren>
<ms:com></ms:com>
<ms:cls></ms:cls>
<ms:pca>16</ms:pca>
<ms:pci>16007</ms:pci>
<ms:na8></ms:na8>
<ms:na0>鎌倉女子大学(家政学部)</ms:na0>
<ms:ads>大船6-1-3</ms:ads>
<ms:apf>4</ms:apf>
<ms:ad6></ms:ad6>
<ms:ys3></ms:ys3>
<ms:oy2></ms:oy2>
<ms:rcn>数値地図画像</ms:rcn>
</ms:university>
</gml:featureMember>
<gml:featureMember>
<ms:university fid="university.3355">
<gml:boundedBy>
<gml:Box srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019 -26659.018612,-71776.660019</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<ms:msGeometry>
<gml:Point srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019</gml:coordinates>
</gml:Point>
</ms:msGeometry>
<ms:gid>3355</ms:gid>
<ms:aac>14204</ms:aac>
<ms:ren></ms:ren>
<ms:com></ms:com>
<ms:cls></ms:cls>
<ms:pca>16</ms:pca>
<ms:pci>16007</ms:pci>
<ms:na8></ms:na8>
<ms:na0>鎌倉女子大学(児童学部)</ms:na0>
<ms:ads>大船6-1-3</ms:ads>
<ms:apf>4</ms:apf>
<ms:ad6></ms:ad6>
<ms:ys3></ms:ys3>
<ms:oy2></ms:oy2>
<ms:rcn>数値地図画像</ms:rcn>
</ms:university>
</gml:featureMember>
</wfs:FeatureCollection>


「<ms:...」には、マップサーバのルールに従った文章です。
「<gml:...」は、GMLのルールに従った地理空間データの文章です。
GMLでは、地図上に地理空間データで表現できる道路や川、建物などをフィーチャ(features)といいます。上記のフィーチャは、マップサーバとGMLのルールが組み合わされて表現されています。

次のコードを追加します。

---
// ここを追加
map.addLayer(new OpenLayers.Layer.GML("university", "gml_point.xml"));
// ここまで
} // End of function init()
---

gml_point.xml の内容は、「参考4」になります。



■ WFSデータの出力について
kanagawa_mlit_pgis_school.map の WFSサーバの設定部分で、"wfs_srs" は "EPSG:2451 EPSG:4612" になっています。(参考1)

OpenLayersで "units" が "meter" と "degree" のレイヤーを同時に表示するための設定ですが、"wget" コマンドでデータをダウンロードすると、"<gml:null>missing</gml:null>" と出力されてデータが取得できませんでした。(参考2)

"ogr2ogr" コマンドではデータをダウンロードできました。このとき、<gml:coordinates>は"degree"単位の数値です。(参考3)

実際に、iceweasel(DebianのFireFoxクローン)で表示し、OpenLayersのレイヤースイッチャーで表示すると、Firebugに出力データが表示されます。このとき、<gml:coordinates>は"meter"単位の数値です。(参考4)
今回はこのデータを使用しました。
また、次のようなコマンドを実行するとダウンロードできました。

wget -O university_meter.xml "http://localhost/cgi-bin/mapserv?map=/home/nob61/mapfile/kanagawa_mlit_pgis_school.map&service=WFS&version=1.0.0&request=GetFeature&bbox=-31337.715508,-77650.134635,-21796.513842,-70055.061952&typename=university"

kanagawa_mlit_pgis_school.map の WFSサーバの設定部分の "wfs_srs" を "EPSG:4612" にすると、"wget" コマンドでデータをダウンロード出きるようになりました。このとき、<gml:coordinates>は"degree"単位の数値です。(参考5)

参考1:WFSサーバの設定

WEB
IMAGEPATH "/home/nob61/ka-map/htdocs/tmp/kacache/"
IMAGEURL "/ka-map/tmp/kacache/"
METADATA
"wms_title" "Kamakura mlit School Map WMS Server"
"wms_srs" "EPSG:2451 EPSG:4612"
"wms_onlineresource" "http://localhost/cgi-bin/mapserv?map=/home/nob61/mapfile/kanagawa_mlit_pgis_school.map"
"wms_encoding" "utf-8"
"wms_feature_info_mime_type" "text/html"
"wfs_title" "Kamakura mlit School Map WFS Server"
"wfs_srs" "EPSG:2451 EPSG:4612"
# "wfs_srs" "EPSG:4612"
"wfs_onlineresource" "http://localhost/cgi-bin/mapserv?map=/home/nob61/mapfile/kanagawa_mlit_pgis_school.map"
"wfs_encoding" "utf-8"
"wfs_feature_info_mime_type" "text/html"
END
END

参考2:"wget" コマンドでのデータ
$ wget -O university.xml "http://localhost/cgi-bin/mapserv?map=/home/nob61/mapfile/kanagawa_mlit_pgis_school.map&service=WFS&version=1.0.0&request=GetFeature&typename=university"


<?xml version='1.0' encoding="utf-8" ?>
<wfs:FeatureCollection
xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:gml="http://www.opengis.net/gml"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd
http://mapserver.gis.umn.edu/mapserver http://localhost/cgi-bin/mapserv?map=/home/nob61/mapfile/kanagawa_mlit_pgis_school.map&SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=university&OUTPUTFORMAT=XMLSCHEMA">
<gml:boundedBy>
<gml:null>missing</gml:null>
</gml:boundedBy>
</wfs:FeatureCollection>

参考3:"ogr2ogr" コマンドでのデータ
$ ogr2ogr -f "GML" university.gml "PG:dbname=kanagawa_mlit" -sql "select * from publicfacilities where aac = '14204'and pci = '16007';"


<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/university.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>139.540009</gml:X><gml:Y>35.352669</gml:Y></gml:coord>
<gml:coord><gml:X>139.540009</gml:X><gml:Y>35.352669</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<ogr:sql_statement fid="F0">
<ogr:geometryProperty><gml:Point><gml:coordinates>139.540008999999998,35.352668999999999</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:gid>3354</ogr:gid>
<ogr:aac>14204</ogr:aac>
<ogr:pca>16</ogr:pca>
<ogr:pci>16007</ogr:pci>
<ogr:na0>鎌倉女子大学(家政学部)</ogr:na0>
<ogr:ads>大船6-1-3</ogr:ads>
<ogr:apf>4</ogr:apf>
<ogr:rcn>数値地図画像</ogr:rcn>
</ogr:sql_statement>
</gml:featureMember>
<gml:featureMember>
<ogr:sql_statement fid="F1">
<ogr:geometryProperty><gml:Point><gml:coordinates>139.540008999999998,35.352668999999999</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:gid>3355</ogr:gid>
<ogr:aac>14204</ogr:aac>
<ogr:pca>16</ogr:pca>
<ogr:pci>16007</ogr:pci>
<ogr:na0>鎌倉女子大学(児童学部)</ogr:na0>
<ogr:ads>大船6-1-3</ogr:ads>
<ogr:apf>4</ogr:apf>
<ogr:rcn>数値地図画像</ogr:rcn>
</ogr:sql_statement>
</gml:featureMember>
</ogr:FeatureCollection>


参考4:Firebugで表示されたWFSデータ

<?xml version='1.0' encoding="utf-8" ?>
<wfs:FeatureCollection
xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:gml="http://www.opengis.net/gml"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd

http://mapserver.gis.umn.edu/mapserver http://localhost/cgi-bin/mapserv?map=/home
/user/mapfile/kanagawa_mlit_pgis_school.map&SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType
&TYPENAME=university&OUTPUTFORMAT=XMLSCHEMA">
<gml:boundedBy>
<gml:Box srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019 -26659.018612,-71776.660019</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<ms:university fid="university.3354">
<gml:boundedBy>
<gml:Box srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019 -26659.018612,-71776.660019</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<ms:msGeometry>
<gml:Point srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019</gml:coordinates>
</gml:Point>
</ms:msGeometry>
<ms:gid>3354</ms:gid>
<ms:aac>14204</ms:aac>
<ms:ren></ms:ren>
<ms:com></ms:com>
<ms:cls></ms:cls>
<ms:pca>16</ms:pca>
<ms:pci>16007</ms:pci>
<ms:na8></ms:na8>
<ms:na0>鎌倉女子大学(家政学部)</ms:na0>
<ms:ads>大船6-1-3</ms:ads>
<ms:apf>4</ms:apf>
<ms:ad6></ms:ad6>
<ms:ys3></ms:ys3>
<ms:oy2></ms:oy2>
<ms:rcn>数値地図画像</ms:rcn>
</ms:university>
</gml:featureMember>
<gml:featureMember>
<ms:university fid="university.3355">
<gml:boundedBy>
<gml:Box srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019 -26659.018612,-71776.660019</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<ms:msGeometry>
<gml:Point srsName="EPSG:2451">
<gml:coordinates>-26659.018612,-71776.660019</gml:coordinates>
</gml:Point>
</ms:msGeometry>
<ms:gid>3355</ms:gid>
<ms:aac>14204</ms:aac>
<ms:ren></ms:ren>
<ms:com></ms:com>
<ms:cls></ms:cls>
<ms:pca>16</ms:pca>
<ms:pci>16007</ms:pci>
<ms:na8></ms:na8>
<ms:na0>鎌倉女子大学(児童学部)</ms:na0>
<ms:ads>大船6-1-3</ms:ads>
<ms:apf>4</ms:apf>
<ms:ad6></ms:ad6>
<ms:ys3></ms:ys3>
<ms:oy2></ms:oy2>
<ms:rcn>数値地図画像</ms:rcn>
</ms:university>
</gml:featureMember>
</wfs:FeatureCollection>


参考5:"wfs_srs" "EPSG:4612" のデータ(<gml:boundedBy> 以下)

<gml:boundedBy>
<gml:Box srsName="EPSG:4612">
<gml:coordinates>139.540009,35.352669 139.540009,35.352669</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<ms:university fid="university.3354">
<gml:boundedBy>
<gml:Box srsName="EPSG:4612">
<gml:coordinates>139.540009,35.352669 139.540009,35.352669</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<ms:msGeometry>
<gml:Point srsName="EPSG:4612">
<gml:coordinates>139.540009,35.352669</gml:coordinates>
</gml:Point>
</ms:msGeometry>
<ms:gid>3354</ms:gid>
<ms:aac>14204</ms:aac>
<ms:ren></ms:ren>
<ms:com></ms:com>
<ms:cls></ms:cls>
<ms:pca>16</ms:pca>
<ms:pci>16007</ms:pci>
<ms:na8></ms:na8>
<ms:na0>鎌倉女子大学(家政学部)</ms:na0>
<ms:ads>大船6-1-3</ms:ads>
<ms:apf>4</ms:apf>
<ms:ad6></ms:ad6>
<ms:ys3></ms:ys3>
<ms:oy2></ms:oy2>
<ms:rcn>数値地図画像</ms:rcn>
</ms:university>
</gml:featureMember>
<gml:featureMember>