ラベル Snapping の投稿を表示しています。 すべての投稿を表示
ラベル Snapping の投稿を表示しています。 すべての投稿を表示

2010年6月8日火曜日

OpenLayers 56b Snap/Split and Persist via WFS - Snap と Split を WFS で保存 2

HTML ファイルの作成

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

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

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>OpenLayers56 Snap/Split and Persist via WFS</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>

<!-- スタイルシート -->
<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;
}
.olControlDrawFeaturePointItemInactive {
background-image: url("./theme/default/img/editing_tool_bar.png"); /* 修正 */
background-repeat: no-repeat;
background-position: -77px 0px;
}
.olControlDrawFeaturePointItemActive {
background-image: url("./theme/default/img/editing_tool_bar.png"); /* 修正 */
background-repeat: no-repeat;
background-position: -77px -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', {
maxResolution: 156543.03390625,
restrictedExtent: new OpenLayers.Bounds(15518513, 4258113, 15518513, 4265113),// 表示範囲 東京駅周辺に変更
maxExtent: new OpenLayers.Bounds(-2.003750834E7,-2.003750834E7,2.003750834E7,2.003750834E7),// 世界全図
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"), // 追加
controls: [
new OpenLayers.Control.PanZoom()
]
});


// Open Street Map レイヤ
var wms = new OpenLayers.Layer.WMS("Base Layer",
"http://demo.opengeo.org/geoserver_openstreetmap/gwc/service/wms",
{
layers: 'openstreetmap',
format: 'image/png'
});

// 描画したフィーチャのスタイル
var styles = new OpenLayers.StyleMap({
"default": new OpenLayers.Style(null, {
rules: [
new OpenLayers.Rule({
symbolizer: {
"Point": {
pointRadius: 5,
graphicName: "square",
fillColor: "white",
fillOpacity: 0.25,
strokeWidth: 1,
strokeOpacity: 1,
strokeColor: "#333333"
},
"Line": {
strokeWidth: 3,
strokeOpacity: 1,
strokeColor: "#666666"
}
}
})
]
}),
"select": new OpenLayers.Style({
strokeColor: "#00ccff",
strokeWidth: 4
}),
"temporary": new OpenLayers.Style(null, {
rules: [
new OpenLayers.Rule({
symbolizer: {
"Point": {
pointRadius: 5,
graphicName: "square",
fillColor: "white",
fillOpacity: 0.25,
strokeWidth: 1,
strokeOpacity: 1,
strokeColor: "#333333"
},
"Line": {
strokeWidth: 3,
strokeOpacity: 1,
strokeColor: "#00ccff"
}
}
})
]
})
});


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"),
styleMap: styles,
protocol: new OpenLayers.Protocol.WFS({
version: "1.1.0",
srsName: "EPSG:4326",
url: "http://localhost:8080/geoserver/wfs", // 自分の GeoServer
featureNS : "http://geoserver.sf.net", // drawinglineLine がある Workspace の名前空間
featureType: "drawinglineLine", // 修正
geometryName: "the_geom",
schema: "http://localhost:8080/geoserver/wfs/DescribeFeatureType?version=1.1.0&typename=sde:drawinglineLine" // 修正
})
});

map.addLayers([wms, wfs]);


  // configure the snapping agent
var snap = new OpenLayers.Control.Snapping({layer: wfs});
map.addControl(snap);
snap.activate();

// configure split agent
var split = new OpenLayers.Control.Split({
layer: wfs,
source: wfs,
tolerance: 0.0001,
deferDelete: true,
eventListeners: {
aftersplit: function(event) {
var msg = "Split resulted in " + event.features.length + " features.";
flashFeatures(event.features);
}
}
});
map.addControl(split);
split.activate();


// add some editing tools to a panel
var panel = new OpenLayers.Control.Panel(
{displayClass: 'customEditingToolbar'}
);
var draw = new OpenLayers.Control.DrawFeature(
wfs, OpenLayers.Handler.Path,
{
title: "Draw Feature",
displayClass: "olControlDrawFeaturePoint",
handlerOptions: {multi: true}
}
);
modify = new OpenLayers.Control.ModifyFeature(
wfs, {displayClass: "olControlModifyFeature"}
);
var del = new DeleteFeature(wfs, {title: "Delete Feature"});

var save = new OpenLayers.Control.Button({
title: "Save Changes",
trigger: function() {
if(modify.feature) {
modify.selectControl.unselectAll();
}
saveStrategy.save();
},
displayClass: "olControlSaveFeatures"
});

panel.addControls([
new OpenLayers.Control.Navigation(),
save, del, modify, draw
]);

panel.defaultControl = panel.controls[0];
map.addControl(panel);
map.addControl(new OpenLayers.Control.LayerSwitcher()); // 追加
map.addControl(new OpenLayers.Control.MousePosition()); // 追加
map.addControl(new OpenLayers.Control.ScaleLine()); // 追加
map.zoomTo(14);
}


function flashFeatures(features, index) {
if(!index) {
index = 0;
}
var current = features[index];
if(current && current.layer === wfs) {
wfs.drawFeature(features[index], "select");
}
var prev = features[index-1];
if(prev && prev.layer === wfs) {
wfs.drawFeature(prev, "default");
}
++index;
if(index <= features.length) {
window.setTimeout(function() {flashFeatures(features, index)}, 100);
}
}

</script>
</head>
<body onload="init()">

<h1 id="title">Snap/Split and Persist via WFS</h1>
<div id="tags"></div>
<p id="shortdesc">
Shows snapping, splitting, and 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>



OpenLayers 56a Snap/Split and Persist via WFS - Snap と Split を WFS で保存 1

Snap/Split and Persist via WFS(wfs-snap-split.html)を参考に WFS レイヤに Snap and Split の結果の保存を試してみます。

シェイプファイルと GeoServer の設定

データベース tokyo に描画用テーブル drawingline を作成します。
PostGIS では保存できなかったので、Shapefile で編集可能レイヤを作成します。
river2_tokyo テーブルをコピーし1つのデータだけのテーブルを作成します。

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 drawingline as select * from river_tokyo2 where gid = '1';
SELECT
tokyo=> \dt
List of relations
Schema | Name | Type | Owner
--------+------------------+-------+-------
public | drawing | table | user
public | drawingline | table | user
public | drawingpoint | 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
(12 rows)

tokyo=> select gid, ric, cpu, wsc, eps, dus, slb, cop, rin, sos, eos, odc, dfd, sor, eor from drawingline ;
gid | ric | cpu | wsc | eps | dus | slb | cop | rin | sos | eos | odc | dfd | sor | eor
-----+------------+-----+--------+-----+-----+-----+-----+--------+-----+-----+-----+-----+-----+-----
1 | 8303050000 | | 830305 | | | | 0 | 小川谷 | | | 3 | 1 | |
(1 row)

tokyo=> \q

drawingline レイヤを 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 のリソース(レイヤ)のリストが表示されます。
「drawingline」の「Publish」をクリックします。
5 選択したレイヤのリソースと編集した情報の設定をします。

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

「Keywords」を入力します。
Current Keywords: (追加したキーワードが表示されます)
New Keyword: drawing, line, 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: 139.018
Min Y: 35.89
Max X: 139.018
Max Y: 35.89
Lat/Lon Bounding Box: (「Compute from native bounds」をクリック -以下の値が入力されました)
Min X: 139.018
Min Y: 35.89
Max X: 139.018
Max Y: 35.89

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

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

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

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

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

4 GeoServer ページの左側の欄の Data -> layers をクリックします。
5 Layers 画面の Add a new resource をクリックします。
6 New layer chooser 画面の Add layer from で sde:Tokyo_Shapefile を選択します。7 drawinglineLine の「Publish」をクリックします。

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

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

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

「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」をクリック -以下の値が入力されました)
Native Bounding Box: ()
Min X: 139.018
Min Y: 35.89
Max X: 139.018
Max Y: 35.89
Lat/Lon Bounding Box: (手動で入力してください。)
Min X: 139.018
Min Y: 35.89
Max X: 139.018
Max Y: 35.89

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

2009年11月19日木曜日

OpenLayers 29 ベクトル図の変形と分割 - Snapping & Splitting

Snapping & Splitting Example(snap-split.html)を参考に GeoJson データでベクトル図の変形と分割をします。

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

コードの修正とちょっと解説します。
(Snapping の "node", "vertex", "edge" の設定がよく分からないので、この部分を省略したコードです。)
データを OpenLayers27 Split Feature の ol27_line.json を使用します。
分割したことの確認は、青くフラッシュすること以外に、snapping のために選択すると分かります。
Snapping したフィーチャと交差または接触したフィーチャも分割されます。


<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>OpenLayers29 Snapping & Splitting</title>
<link rel="stylesheet" href="./theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="./examples/style.css" type="text/css" />
<style type="text/css">
// 編集ボタンのスタイル
.olControlEditingToolbar .olControlModifyFeatureItemInactive {
background-position: -1px 0px ;
}
.olControlEditingToolbar .olControlModifyFeatureItemActive {
background-position: -1px -23px ;
}
label.head {
font-weight: bold;
padding: 1em 0 0.1em 0;
border-bottom: 1px solid grey;
}
// テーブル(表)のスタイル
td {
padding: 0.25em 1em;
}
tr.head td {
text-align: center;
font-weight: bold;
}
</style>
<!-- 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>

<!-- Snapping & Splitting のスクリプト -->

<script type="text/javascript">
OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2';

function init() {
initMap();
initUI();
}

var map, draw, modify, snap, split, vectors;
function initMap() {
// map = new OpenLayers.Map('map');
// 東京都用 map の設定
map = new OpenLayers.Map('map', {
projection: new OpenLayers.Projection("EPSG:2456"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
maxResolution: 'auto',
units: 'meters',
maxExtent: new OpenLayers.Bounds(-279000,1054000,-185000,1104000)
});

// ここまで
// スタイル(通常、選択、編集中)の設定

var styles = new OpenLayers.StyleMap({
"default": new OpenLayers.Style(null, {
rules: [
new OpenLayers.Rule({
symbolizer: {
"Point": {
pointRadius: 5,
graphicName: "square",
fillColor: "white",
fillOpacity: 0.25,
strokeWidth: 1,
srokeOpacity: 1,
strokeColor: "#333333"
},
"Line": {
strokeWidth: 3,
strokeOpacity: 1,
strokeColor: "#666666"
}
}
})
]
}),
"select": new OpenLayers.Style({
strokeColor: "#00ccff",
strokeWidth: 4
}),
"temporary": new OpenLayers.Style(null, {
rules: [
new OpenLayers.Rule({
symbolizer: {
"Point": {
pointRadius: 5,
graphicName: "square",
fillColor: "white",
fillOpacity: 0.25,
strokeWidth: 1,
strokeOpacity: 1,
strokeColor: "#333333"
},
"Line": {
strokeWidth: 3,
strokeOpacity: 1,
strokeColor: "#00ccff"
}
}
})
]
})
});

// create three vector layers

vectors = new OpenLayers.Layer.Vector("Lines", {
isBaseLayer: true,
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "ol27_line2.json",
format: new OpenLayers.Format.GeoJSON({
internalProjection: new OpenLayers.Projection("EPSG:2456"),
externalProjection: new OpenLayers.Projection("EPSG:4326")
})
}),
styleMap: styles,
});
map.addLayer(vectors);

// configure the snapping agent

snap = new OpenLayers.Control.Snapping({layer: vectors});
map.addControl(snap);
snap.activate();

// configure split agent

/*
*source
*新しく作成されたフィーチャまたは変形されたフィーチャが提供された場合、
*ターゲットレイヤ上でフィーチャを分割するために使用されます。
*提供されない場合は、一時的なスケッチレイヤが線を描画するために作成されます。
*tolerance
*頂点で発生する分割下のソースの頂点と計算された交差点間の距離のオプションの値。
*/
split = new OpenLayers.Control.Split({
layer: vectors,
source: vectors,
tolerance: 0.0001,
eventListeners: {
aftersplit: function(event) {
flashFeatures(event.features);
}
}
});
map.addControl(split);
split.activate();

// add some editing tools to a panel

var panel = new OpenLayers.Control.Panel({
displayClass: "olControlEditingToolbar"
});
draw = new OpenLayers.Control.DrawFeature(
vectors, OpenLayers.Handler.Path,{
displayClass: "olControlDrawFeaturePoint",
title: "Draw Features"
}
);
modify = new OpenLayers.Control.ModifyFeature(
vectors, {
displayClass: "olControlModifyFeature",
title: "Modify Features"
}
);
panel.addControls([
new OpenLayers.Control.Navigation({title: "Navigate"}),
draw, modify
]);
map.addControl(panel);

map.addControl(new OpenLayers.Control.MousePosition());
map.addControl(new OpenLayers.Control.LayerSwitcher()); // 追加
map.addControl(new OpenLayers.Control.ScaleLine()); // 追加

map.zoomToMaxExtent();
} // End of initMap()

// 分割後のフラッシュ

function flashFeatures(features, index) {
if(!index) {
index = 0;
}
var current = features[index];
if(current && current.layer === vectors) {
vectors.drawFeature(features[index], "select");
}
var prev = features[index-1];
if(prev && prev.layer === vectors) {
vectors.drawFeature(prev, "default");
}
++index;
if(index <= features.length) {
window.setTimeout(function() {flashFeatures(features, index)}, 1000); // 1000ミリ秒に修正
}
}

// Snapping と Splitting をチェックしたときの動作

/**
* Add behavior to page elements. This basically lets us set snapping
* target properties with the checkboxes and text inputs. The checkboxes
* toggle the target node, vertex, or edge (boolean) values. The
* text inputs set the nodeTolerance, vertexTolerance, or edgeTolerance
* property values.
*/
function initUI() {
// add behavior to snap elements
var snapCheck = $("snap_toggle");
snapCheck.checked = true;
snapCheck.onclick = function() {
if(snapCheck.checked) {
snap.activate();
$("snap_options").style.display = "block";
} else {
snap.deactivate();
$("snap_options").style.display = "none";
}
};
// add behavior to split elements
var splitCheck = $("split_toggle");
splitCheck.checked = true;
splitCheck.onclick = function() {
if(splitCheck.checked) {
split.activate();
$("split_options").style.display = "block";
} else {
split.deactivate();
$("split_options").style.display = "none";
}
};
var edgeCheck = $("edge_toggle");
edgeCheck.checked = split.edge;
edgeCheck.onclick = function() {
split.edge = edgeCheck.checked;
};
// フィーチャ消去
$("clear").onclick = function() {
modify.deactivate();
vectors.destroyFeatures();
};

}

</script>
</head>

<!-- body 部分 -->

<body onload="init()">
<h1 id="title">Snapping & Splitting Example</h1>
<div id="shortdesc">A demonstration snapping and splitting while editing vector features.</div>
<div id="map" class="smallmap"></div>
<br/>
<input type="checkbox" id="snap_toggle" />
<label for="snap_toggle" class="head">Enable Snapping</label>
<br />
<input type="checkbox" id="split_toggle" />
<label for="split_toggle" class="head">Enable Splitting</label>
<table id="split_options">
<tbody>
<tr>
<td><label for="edge_toggle">edges split</label></td>
<td><input type="checkbox" id="edge_toggle" /></td>
</tr>
</tbody>
</table>
<br />
<button id="clear">clear</button> Clear all features.
</body>
</html>



Split 分割のために描画した直線が残って表示されています。



Snap 分割のために描画した直線藻分割されていました。

2009年11月15日日曜日

OpenLayers 27a ベクトル図の変形 - Snapping

OpenLayers Select and Highlight Feature Example(highlight-feature.html) を参考に GeoJson データでベクトル図を変形します。

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

コードの修正とちょっと解説します。
(Snapping の "node", "vertex", "edge" の設定がよく分からないので、この部分を省略したコードです。)

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>OpenLayers27 Snapping</title>
<link rel="stylesheet" href="./theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="./examples/style.css" type="text/css" />

<!-- 編集ボタンのスタイル -->
<style type="text/css">
.olControlEditingToolbar .olControlModifyFeatureItemInactive {
background-position: -1px 0px;
}
.olControlEditingToolbar .olControlModifyFeatureItemActive {
background-position: -1px -23px;
}
</style>

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

<!-- Snapping コード -->

<script type="text/javascript">
OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2';

function init() {
initMap();
initUI();
}

var map, draw, modify, snap, point, line, poly;
function initMap() {

// map = new OpenLayers.Map('map');
// 東京都用 map の設定
map = new OpenLayers.Map('map', {
projection: new OpenLayers.Projection("EPSG:2456"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
maxResolution: 'auto',
units: 'meters',
maxExtent: new OpenLayers.Bounds(-279000,1054000,-185000,1104000)
});

// スタイル(通常、選択、編集中)の設定

var styles = new OpenLayers.StyleMap({
"default": new OpenLayers.Style(null, {
rules: [
new OpenLayers.Rule({
symbolizer: {
"Point": {
pointRadius: 5,
graphicName: "square",
fillColor: "white",
fillOpacity: 0.25,
strokeWidth: 1,
strokeOpacity: 1,
strokeColor: "#3333aa"
},
"Line": {
strokeWidth: 3,
strokeOpacity: 1,
strokeColor: "#6666aa"
},
"Polygon": {
strokeWidth: 1,
strokeOpacity: 1,
fillColor: "#9999aa",
strokeColor: "#6666aa"
}
}
})
]
}),
"select": new OpenLayers.Style(null, {
rules: [
new OpenLayers.Rule({
symbolizer: {
"Point": {
pointRadius: 5,
graphicName: "square",
fillColor: "white",
fillOpacity: 0.25,
strokeWidth: 2,
strokeOpacity: 1,
strokeColor: "#0000ff"
},
"Line": {
strokeWidth: 3,
strokeOpacity: 1,
strokeColor: "#0000ff"
},
"Polygon": {
strokeWidth: 2,
strokeOpacity: 1,
fillColor: "#0000ff",
strokeColor: "#0000ff"
}
}
})
]
}),
"temporary": new OpenLayers.Style(null, {
rules: [
new OpenLayers.Rule({
symbolizer: {
"Point": {
graphicName: "square",
pointRadius: 5,
fillColor: "white",
fillOpacity: 0.25,
strokeWidth: 2,
strokeColor: "#0000ff"
},
"Line": {
strokeWidth: 3,
strokeOpacity: 1,
strokeColor: "#0000ff"
},
"Polygon": {
strokeWidth: 2,
strokeOpacity: 1,
strokeColor: "#0000ff",
fillColor: "#0000ff"
}
}
})
]
})
});

// create three vector layers

poly = new OpenLayers.Layer.Vector("polygons", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "ol27_polygon.json", // 修正した東京都の範囲のデータ
format: new OpenLayers.Format.GeoJSON({ // map の設定に合わせて修正
internalProjection: new OpenLayers.Projection("EPSG:2456"),
externalProjection: new OpenLayers.Projection("EPSG:4326")
}),
}),
isBaseLayer: true,
styleMap: styles
});
line = new OpenLayers.Layer.Vector("lines", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "ol27_line.json",
format: new OpenLayers.Format.GeoJSON({
internalProjection: new OpenLayers.Projection("EPSG:2456"),
externalProjection: new OpenLayers.Projection("EPSG:4326")
}),
}),
styleMap: styles
});
point = new OpenLayers.Layer.Vector("points", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "ol27_point.json",
format: new OpenLayers.Format.GeoJSON({
internalProjection: new OpenLayers.Projection("EPSG:2456"),
externalProjection: new OpenLayers.Projection("EPSG:4326")
}),
}),
styleMap: styles
});
map.addLayers([poly, line, point]);

// configure the snapping agent

snap = new OpenLayers.Control.Snapping({
layer: poly,
targets: [point, line, poly],
greedy: false
});
snap.activate();

// add some editing tools to a panel
var panel = new OpenLayers.Control.Panel({
displayClass: "olControlEditingToolbar"
});
draw = new OpenLayers.Control.DrawFeature(
poly, OpenLayers.Handler.Polygon, {displayClass: "olControlDrawFeaturePoint", title: "Draw Features"}
);
modify = new OpenLayers.Control.ModifyFeature(
poly, {displayClass: "olControlModifyFeature", title: "Modify Features"}
);
panel.addControls([
new OpenLayers.Control.Navigation({title: "Navigate"}),
draw, modify
]);
map.addControl(panel);
// レイヤスイッチャ、マウスポジション、スケールラインのコントロール設置
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
map.addControl(new OpenLayers.Control.ScaleLine());

// give the map a location
// map.setCenter(new OpenLayers.LonLat(0, 0), 1);
if (!map.getCenter()) {
map.zoomToMaxExtent()
};
}

/**
* Add behavior to page elements. This basically lets us set snapping
* target properties with the checkboxes and text inputs. The checkboxes
* toggle the target node, vertex, or edge (boolean) values. The
* text inputs set the nodeTolerance, vertexTolerance, or edgeTolerance
* property values.
*/

function initUI() {
var check = $("snapping");
check.checked = true;
check.onclick = function() {
if(check.checked) {
snap.activate();
} else {
snap.deactivate();
}
};

var sel = $("editable");
sel.value = "poly";
sel.onchange = function() {
updateEditable(sel.value);
}

}

// this function allows the editable layer to be changed
// for the snapping control, this amounts to calling setLayer

function updateEditable(name) {
layer = window[name];

// update the editable layer for the snapping control (nice)

snap.setLayer(layer);

// update the editable layer for the modify control (ugly)

var modActive = modify.active;
if(modActive) {
modify.deactivate();
}
modify.layer = layer;
modify.selectControl.layer = layer;
modify.selectControl.handlers.feature.layer = layer;
modify.dragControl.layer = layer;
modify.dragControl.handlers.drag.layer = layer;
modify.dragControl.handlers.feature.layer = layer;
if(modActive) {
modify.activate();
}

// update the editable layer for the draw control (very ugly)
var drawActive = draw.active;
if(drawActive) {
draw.deactivate();
}
draw.layer = layer;
var handler = ({
point: OpenLayers.Handler.Point,
line: OpenLayers.Handler.Path,
poly: OpenLayers.Handler.Polygon
})[name];
draw.handler = new handler(draw, draw.callbacks, draw.handlerOptions);
if(drawActive) {
draw.activate();
}

}
</script>
</head>

<!-- body 部分 -->

<body onload="init()">
<h1 id="title">Snapping Example</h1>
<div id="shortdesc">A demonstration snapping while editing vector features.</div>
<div id="map" class="smallmap"></div>
<br/>
<label for="editable">Editable Layer:</label>
<select id="editable" name="editable">
<option value="poly">polygons</option>
<option value="line">lines</option>
<option value="point">points</option>
</select>
<label for="snapping">Enable Snapping</label>
<input type="checkbox" name="snapping" id="snapping" checked="checked" />

<p>Though all snapping types are shown here for all target layers, not all are sensible.
Points don't have edges, for example.</p>
</body>
</html>