2010年3月11日木曜日

OpenLayers 52b WFS Transaction - WFS レイヤに描画フィーチャを保存

WFS Transaction Example(wfs-protocol-transaction.html)を参考に WS レイヤにフィーチャを保存するためのコントロールの使い方を試してみます。

データベース tokyo に描画用テーブル drawing を作成します。
PostGIS では保存できなかったので、Shapefile で編集可能レイヤを作成します。
gyoseikai テーブルをコピーし千代田区のデータだけのテーブルを作成します。
(gyoseikai テーブルにないデータで抽出します。)

user@debian:~$ psql tokyo
Welcome to psql 8.3.9, 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 drawing as select * from gyoseikai where aac = '13101';
SELECT
tokyo=> \dt
List of relations
Schema | Name | Type | Owner
--------+------------------+-------+-------
public | drawing | table | user
public | geometry_columns | table | user
public | gyoseikai | table | user
public | pf_tokyo | table | user
public | population | table | user
public | railroad2 | table | user
public | railroad3 | table | user
public | river_tokyo2 | table | user
public | river_tokyo3 | table | user
public | spatial_ref_sys | table | user
(10 rows)

tokyo=> select gid, prn, sun, con, cn2, aac from drawing ;
gid | prn | sun | con | cn2 | aac
------+--------+-----+----------+-----+-------
3276 | 東京都 | | 千代田区 | | 13101
(1 row)

tokyo=> \q


drawing レイヤを GeoServer に追加します。
「Layer Configration」
1 ログインした GeoServer ページの左側の欄の「Data」の「Layers」をクリックします。
2 「Add a new resource」をクリックします。
3 「New Layer chooser」の「Add a layer from」ドロップダウンから「sde:Tokyo」を選択します。
4 Tokyo store のリソース(レイヤ)のリストが表示されます。
「drawing」の「Publish」をクリックします。
5 選択したレイヤのリソースと編集した情報の設定をします。

「Basic Resource Info」を入力します。
Name: drawing (変更なし)
Title: Drawing (最初の文字を大文字に変更 任意)
Abstract: Tokyo Drawing (任意)

「Keywords」を入力します。
Current Keywords: (追加したキーワードが表示されます)
New Keyword: drawing, tokyo (1つずつ入力して「追加」ボタンをクリック)

「Metadata links」は変更しません。

「Coordinate Reference Systems」を入力します。
Native SRS: 空(変更なし)
Declared SRS: EPSG:4326 (「Find」ボタンをクリックして「4326」を検索して表示された「4326」をクリック)
SRS handling: Force declared (変更しない)

6 「Bounding Boxes」を入力します。
Native Bounding Box: (手動で入力してください。「Compute from data」をクリックした値でも大丈夫みたいです。)
Min X: 136.069
Min Y: 20.425
Max X: 153.987
Max Y: 35.898
Lat/Lon Bounding Box: (「Compute from native bounds」をクリック -以下の値が入力されました)
Min X: 136.069
Min Y: 20.425
Max X: 153.987
Max Y: 35.898

7 ページ上部の「Publishing」タブをクリックします。
8 「Default Title」の「Default Style」を「polygon」にします。
(他は変更しません。)
9 ページ下部の「Save」ボタンをクリックします。

「Layer」ページの一番最後に「drawing」が追加されます。
drawing レイヤの Shapefile を作成します。

1 GeoServer ページの左側の欄の「Layer Preview」をクリックします。
2 sde:drawing の All Formats のドロップダウンリストで 「Shapefile」を選択します。
3 「drawing.zip を開く」ダイアログで「ファイルを保存する」を選択し「OK」ボタンをクリックします。
4 「ファイル名を入れてください」ダイアログでデスクトップに保存しました。

この Shapefile を GeoServer に設定します。
1 drawing.zip を解凍します。
2 geoserver-2.0.1/data_dir/data/drawing を作成します。
3 解凍したファイルを全部 geoserver-2.0.1/data_dir/data/drawing に入れます。

user@debian:~/Desktop$ ls
drawing.zip featureserver-1.12 sld_data tilecache.csv
eclipse quicktime4linux-2.0.0 streaming tilecache2.csv
user@debian:~/Desktop$ unzip drawing.zip
Archive: drawing.zip
inflating: drawingPolygon.dbf
inflating: drawingPolygon.shx
inflating: drawingPolygon.shp
inflating: drawingPolygon.prj
inflating: drawingPolygon.cst
user@debian:~/Desktop$ ls
drawing.zip drawingPolygon.shp quicktime4linux-2.0.0 tilecache2.csv
drawingPolygon.cst drawingPolygon.shx sld_data
drawingPolygon.dbf eclipse streaming
drawingPolygon.prj featureserver-1.12 tilecache.csv
user@debian:~/Desktop$ mkdir ../geoserver-2.0.1/data_dir/data/drawing
user@debian:~/Desktop$ mv drawing* ../geoserver-2.0.1/data_dir/data/drawing/

4 GeoServer ページの左側の欄の Data -> Stores をクリックします。

5 Layers 画面の「Add new Store」をクリックします。

6 New data source の Vector Data Sources の「Shapefile」をクリックします。

7 New Vector Data Source 画面で次のように設定します。

「Basic Store Info」を入力します。
Workspace: sde
Data Source Name: Tokyo_Shapefile
Description: Tokyo MLIT Shapefile
Enable: チェック(変更なし)

「Connection Parameters」を入力します。
URL: file:data/drawing
create spatial index: チェック(変更なし)
charset: utf-8
memory mapped buffer: チェック(変更なし)

「Save」ボタンをクリックします。
New layer chooser 画面になるので、drawingPolygon の「Publish」をクリックします。

8 sde:drawingPolygon 画面で次のように設定します。

Data タブの
「Basic Rsource Info」を入力します。
Name: drawingPolygon(変更なし)
Title: DrawingPolygon
Abstract: Tokyo MLIT Gyoseikai Shapefile

「Keywords」を入力します。
New Keyword: tokyo, gyoseikai

「Metadata links」は入力しません。

「Coordinate Reference Systems」を入力します。
Native SRS: EPSG;4326(変更なし)
Declared SRS: EPSG;4326(変更なし)
SRS handling: Force declared(変更なし)

「Bounding Boxes」を入力します。
Native Bounding Box: (「Compute from data」をクリック -以下の値が入力されました)
Min X: 139.73
Min Y: 35.669
Max X: 139.783
Max Y: 35.705
Lat/Lon Bounding Box: (「Compute from native bounds」をクリック -以下の値が入力されました)
Min X: 139.73
Min Y: 35.669
Max X: 139.783
Max Y: 35.705

ページ上部の「Publishing」タブをクリックします。
「Default Title」の「Default Style」が「polygon」になっていることを確認します。
(他は変更しません。)
ページ下部の「Save」ボタンをクリックします。
「Layer」ページの一番下に「drawingPolygon」が追加されます。


HTML ファイルを新規作成します。
「openlayersTokyoproj」 を右クリックして 新規 -> HTML ファイル をクリック。
「HTML ファイル」ウィンドウの「ファイル名(任意:openlayers_wfs-prot-trans.html)」に入力して「完了」ボタンをクリック。
「charset」を「utf-8」にします。
「examples」の「wfs-protocol-transaction.html」の内容をコピーして新規作成したファイルに貼り付けます。

コードの修正とちょっと解説します。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>OpenLayers52 WFS Transaction</title>

<!-- OpenLayers ライブラリ -->
<script src="./lib/Firebug/firebug.js"></script>
<script src="./lib/OpenLayers.js"></script>

<!-- Proj4js ライブラリ -->
<script type="text/javascript" src="./lib/proj4js/lib/proj4js-compressed.js"></script>
<script type="text/javascript" src="./lib/proj4js/lib/projCode/tmerc.js"></script>
<script type="text/javascript" src="./lib/proj4js/lib/defs/EPSG2456.js"></script>

<!--
Google API キー
Google Maps API ページ
http://code.google.com/intl/ja/apis/maps/
より取得します。
実際に地図を Web ページに埋め込む作業をすると利用規約の主旨が理解できます。
-->
<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIA...(以下省略)" type="text/javascript"></script>


<!-- スタイルシート -->
<link rel="stylesheet" href="./theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="./examples/style.css" type="text/css" />

<!-- Editing Tool Bar スタイルシート -->
<style>
.customEditingToolbar {
float: right;
right: 0px;
height: 30px;
width: 200px;
}
.customEditingToolbar div {
float: right;
margin: 5px;
width: 24px;
height: 24px;
}
.olControlNavigationItemActive {
background-image: url("./theme/default/img/editing_tool_bar.png"); /* 修正 */
background-repeat: no-repeat;
background-position: -103px -23px;
}
.olControlNavigationItemInactive {
background-image: url("./theme/default/img/editing_tool_bar.png"); /* 修正 */
background-repeat: no-repeat;
background-position: -103px -0px;
}
.olControlDrawFeaturePolygonItemInactive {
background-image: url("./theme/default/img/editing_tool_bar.png"); /* 修正 */
background-repeat: no-repeat;
background-position: -26px 0px;
}
.olControlDrawFeaturePolygonItemActive {
background-image: url("./theme/default/img/editing_tool_bar.png"); /* 修正 */
background-repeat: no-repeat;
background-position: -26px -23px ;
}
.olControlModifyFeatureItemActive {
background-image: url(./theme/default/img/move_feature_on.png); /* 修正 */
background-repeat: no-repeat;
background-position: 0px 1px;
}
.olControlModifyFeatureItemInactive {
background-image: url(./theme/default/img/move_feature_off.png); /* 修正 */
background-repeat: no-repeat;
background-position: 0px 1px;
}
.olControlDeleteFeatureItemActive {
background-image: url(./theme/default/img/remove_point_on.png); /* 修正 */
background-repeat: no-repeat;
background-position: 0px 1px;
}
.olControlDeleteFeatureItemInactive {
background-image: url(./theme/default/img/remove_point_off.png); /* 修正 */
background-repeat: no-repeat;
background-position: 0px 1px;
}
</style>


<script type="text/javascript">
var map, wfs;

var DeleteFeature = OpenLayers.Class(OpenLayers.Control, {
initialize: function(layer, options) {
OpenLayers.Control.prototype.initialize.apply(this, [options]);
this.layer = layer;
this.handler = new OpenLayers.Handler.Feature(
this, layer, {click: this.clickFeature}
);
},
clickFeature: function(feature) {
// if feature doesn't have a fid, destroy it
if(feature.fid == undefined) {
this.layer.destroyFeatures([feature]);
} else {
feature.state = OpenLayers.State.DELETE;
this.layer.events.triggerEvent("afterfeaturemodified", {feature: feature});
feature.renderIntent = "select";
this.layer.drawFeature(feature);
}
},
setMap: function(map) {
this.handler.setMap(map);
OpenLayers.Control.prototype.setMap.apply(this, arguments);
},
CLASS_NAME: "OpenLayers.Control.DeleteFeature"
});


function init() {
OpenLayers.ProxyHost= "/cgi-bin/proxy.cgi?url="; // 修正
map = new OpenLayers.Map('map', {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
maxResolution: 156543.0339,
// インストールした Proj4js で計算した東京都の範囲に変更
maxExtent: new OpenLayers.Bounds(15465203, 4227761, 15579121, 4292512),
controls: [
new OpenLayers.Control.PanZoom()
]
});


/* Google Map(地形図)レイヤ
* Spherical Mercator については
* http://docs.openlayers.org/library/spherical_mercator.html
* を参照。民間企業が提供する地図の再投影法。
*/
var gphy = new OpenLayers.Layer.Google(
"Google Physical",
{type: G_PHYSICAL_MAP, sphericalMercator: true}
);

var saveStrategy = new OpenLayers.Strategy.Save();

// 変種可能レイヤに作成・修正したフィーチャのデータを保存
wfs = new OpenLayers.Layer.Vector("Editable Features", {
strategies: [new OpenLayers.Strategy.BBOX(), saveStrategy],
projection: new OpenLayers.Projection("EPSG:4326"),
protocol: new OpenLayers.Protocol.WFS({
version: "1.1.0",
srsName: "EPSG:4326",
url: "http://localhost:8080/geoserver/wfs", // 自分の GeoServer
featureNS : "http://geoserver.sf.net", // drawing がある Workspace の名前空間
featureType: "drawingPolygon", // 修正
geometryName: "the_geom",
schema: "http://localhost:8080/geoserver/wfs/DescribeFeatureType?version=1.1.0&typename=sde:drawingPolygon" // 修正
})
});

map.addLayers([gphy, wfs]);


var panel = new OpenLayers.Control.Panel(
{'displayClass': 'customEditingToolbar'} // CSS の設定
);

// 新しい Navigation Control の作成
var navigate = new OpenLayers.Control.Navigation({
title: "Pan Map",
});

// フィーチャ描画コントロール
var draw = new OpenLayers.Control.DrawFeature(
wfs, OpenLayers.Handler.Polygon,
{
title: "Draw Feature",
displayClass: "olControlDrawFeaturePolygon",
handlerOptions: {multi: true}
}
);

// フィーチャ変形コントロール
var edit = new OpenLayers.Control.ModifyFeature(wfs, {
title: "Modify Feature",
displayClass: "olControlModifyFeature",
});

// フィーチャ削除
var del = new DeleteFeature(wfs, {title: "Delete Feature"});

// フィーチャ保存
var save = new OpenLayers.Control.Button({
title: "Save Changes",
trigger: function() {
if(edit.feature) {
edit.selectControl.unselectAll();
}
saveStrategy.save();
},
displayClass: "olControlSaveFeatures"
});

panel.addControls([navigate, save, del, edit, draw]);
panel.defaultControl = navigate;
map.addControl(panel);
map.addControl(new OpenLayers.Control.LayerSwitcher()); // 追加
map.addControl(new OpenLayers.Control.MousePosition()); // 追加
map.addControl(new OpenLayers.Control.ScaleLine()); // 追加
map.zoomToMaxExtent();
}

</script>
</head>


<body onload="init()">
<h1 id="title">WFS Transaction Example</h1>
<div id="tags"></div>
<p id="shortdesc">
Shows the use of the WFS Transactions (WFS-T).
</p>
<div id="map" class="smallmap"></div>
<div id="docs">
<p>The WFS protocol allows for creation of new features and reading,
updating, or deleting of existing features.</p>
<p>Use the tools to create, modify, and delete (in order from left
to right) features. Use the save tool (picture of a disk) to
save your changes. Use the navigation tool (hand) to stop editing
and use the mouse for map navigation.</p>
</div>
</body>
</html>


「Draw Feature」ボタンをクリックして描画した後、「Save」ボタンをクリックします。

0 件のコメント: