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 分割のために描画した直線藻分割されていました。

0 件のコメント: