Adding a snapping agent for snapping geometry components to existing components while editing. r=ahocevar (closes #954)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@8951 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Tim Schaub
2009-03-05 23:04:07 +00:00
parent 930adf45c0
commit 9b6894644b
8 changed files with 1111 additions and 0 deletions

10
examples/data/line.json Normal file
View File

@@ -0,0 +1,10 @@
{
"type": "FeatureCollection",
"features": [
{"type":"Feature", "id":"OpenLayers.Feature.Vector_458", "properties":{}, "geometry":{"type":"LineString", "coordinates":[[-121.640625, 24.2578125], [-78.046875, 27.7734375], [-45.703125, 24.9609375], [-13.359375, 16.5234375], [12.65625, 6.6796875], [39.375, 1.0546875], [76.640625, 1.0546875], [108.28125, 1.7578125], [156.09375, 15.8203125]]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}},
{"type":"Feature", "id":"OpenLayers.Feature.Vector_1111", "properties":{}, "geometry":{"type":"LineString", "coordinates":[[-122.34375, -35.5078125], [-48.515625, -33.3984375], [-5.625, -37.6171875], [20.390625, -32.6953125], [69.609375, -34.1015625], [121.640625, -38.3203125], [150.46875, -33.3984375]]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}},
{"type":"Feature", "id":"OpenLayers.Feature.Vector_634", "properties":{}, "geometry":{"type":"LineString", "coordinates":[[-54.84375, 69.9609375], [-56.953125, 31.9921875], [-56.953125, 5.2734375], [-65.390625, -34.8046875], [-66.09375, -61.5234375]]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}},
{"type":"Feature", "id":"OpenLayers.Feature.Vector_820", "properties":{}, "geometry":{"type":"LineString", "coordinates":[[39.375, 58.0078125], [42.890625, 25.6640625], [42.1875, -1.0546875], [37.96875, -50.2734375], [37.265625, -64.3359375]]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}},
{"type":"Feature", "id":"OpenLayers.Feature.Vector_1280", "properties":{}, "geometry":{"type":"LineString", "coordinates":[[101.25, 42.5390625], [106.875, 13.7109375], [106.171875, -17.9296875], [104.765625, -49.5703125], [102.65625, -67.1484375]]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}}
]
}

8
examples/data/point.json Normal file
View File

@@ -0,0 +1,8 @@
{
"type": "FeatureCollection",
"features": [
{"type":"Feature", "id":"OpenLayers.Feature.Vector_1721", "properties":{}, "geometry":{"type":"Point", "coordinates":[-89.296875, -14.4140625]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}},
{"type":"Feature", "id":"OpenLayers.Feature.Vector_1715", "properties":{}, "geometry":{"type":"Point", "coordinates":[-25.3125, -54.4921875]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}},
{"type":"Feature", "id":"OpenLayers.Feature.Vector_1709", "properties":{}, "geometry":{"type":"Point", "coordinates":[73.828125, -23.5546875]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}}
]
}

9
examples/data/poly.json Normal file
View File

@@ -0,0 +1,9 @@
{
"type": "FeatureCollection",
"features": [
{"type":"Feature", "id":"OpenLayers.Feature.Vector_1489", "properties":{}, "geometry":{"type":"Polygon", "coordinates":[[[-109.6875, 63.6328125], [-112.5, 35.5078125], [-85.078125, 34.8046875], [-68.90625, 39.7265625], [-68.203125, 67.1484375], [-109.6875, 63.6328125]]]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}},
{"type":"Feature", "id":"OpenLayers.Feature.Vector_1668", "properties":{}, "geometry":{"type":"Polygon", "coordinates":[[[-40.78125, 65.0390625], [-40.078125, 34.8046875], [-12.65625, 25.6640625], [21.09375, 17.2265625], [22.5, 58.0078125], [-40.78125, 65.0390625]]]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}}
]
}

226
examples/snapping.html Normal file
View File

@@ -0,0 +1,226 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Snapping</title>
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
.olControlEditingToolbar .olControlModifyFeatureItemInactive {
background-position: -1px 0px ;
}
.olControlEditingToolbar .olControlModifyFeatureItemActive {
background-position: -1px -23px ;
}
table {
padding: 1em 0 1em;
}
td {
padding: 0.5em 1em;
border: 1px solid #ddd;
}
tr.head td {
text-align: center;
font-weight: bold;
}
</style>
<script src="../lib/Firebug/firebug.js"></script>
<script src="../lib/OpenLayers.js"></script>
<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');
// create three vector layers
poly = new OpenLayers.Layer.Vector("polygons", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "data/poly.json",
format: new OpenLayers.Format.GeoJSON()
}),
isBaseLayer: true
});
line = new OpenLayers.Layer.Vector("lines", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "data/line.json",
format: new OpenLayers.Format.GeoJSON()
})
});
point = new OpenLayers.Layer.Vector("points", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "data/point.json",
format: new OpenLayers.Format.GeoJSON()
})
});
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"}
);
modify = new OpenLayers.Control.ModifyFeature(
poly, {displayClass: "olControlModifyFeature"}
);
panel.addControls([
new OpenLayers.Control.Navigation(),
draw, modify
]);
map.addControl(panel);
// give the map a location
map.setCenter(new OpenLayers.LonLat(0, 0), 1);
}
/**
* 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);
}
var target, type, tog, tol;
var types = ["node", "vertex", "edge"];
for(var i=0; i<snap.targets.length; ++i) {
target = snap.targets[i];
for(var j=0; j<types.length; ++j) {
type = types[j];
tog = $(i + "_" + type);
tog.checked = target[type];
tog.onclick = (function(tog, type, target) {
return function() {target[type] = tog.checked;}
})(tog, type, target);
tol = $(i + "_" + type + "Tolerance");
tol.value = target[type + "Tolerance"];
tol.onchange = (function(tol, type, target) {
return function() {
target[type + "Tolerance"] = Number(tol.value) || 0;
}
})(tol, type, target);
}
}
}
// 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 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" />
<table>
<tbody>
<tr class="head">
<td>targets</td><td>node</td><td>vertex</td><td>edge</td>
</tr>
<tr>
<td>points</td>
<td><input type="checkbox" id="0_node" /><input id="0_nodeTolerance" type="text" size="3" /></td>
<td><input type="checkbox" id="0_vertex" /><input id="0_vertexTolerance" type="text" size="3" /></td>
<td><input type="checkbox" id="0_edge" /><input id="0_edgeTolerance" type="text" size="3" /></td>
</tr>
<tr>
<td>lines</td>
<td><input type="checkbox" id="1_node" /><input id="1_nodeTolerance" type="text" size="3" /></td>
<td><input type="checkbox" id="1_vertex" /><input id="1_vertexTolerance" type="text" size="3" /></td>
<td><input type="checkbox" id="1_edge" /><input id="1_edgeTolerance" type="text" size="3" /></td>
</tr>
<tr>
<td>polygons</td>
<td><input type="checkbox" id="2_node" /><input id="2_nodeTolerance" type="text" size="3" /></td>
<td><input type="checkbox" id="2_vertex" /><input id="2_vertexTolerance" type="text" size="3" /></td>
<td><input type="checkbox" id="2_edge" /><input id="2_edgeTolerance" type="text" size="3" /></td>
</tr>
</tbody>
</table>
<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>