Skip to content

Commit

Permalink
Methods for programmatically manipulating sketches while digitizing f…
Browse files Browse the repository at this point in the history
…eatures. r=bartvde (closes #3343)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@12103 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
  • Loading branch information
tschaub committed Jun 17, 2011
1 parent abdb336 commit 2cf3f62
Show file tree
Hide file tree
Showing 12 changed files with 842 additions and 5 deletions.
38 changes: 38 additions & 0 deletions examples/draw-undo-redo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<title>OpenLayers Undo/Redo Drawing Methods</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0;">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
<link rel="stylesheet" href="style.css" type="text/css">
<script src="../lib/OpenLayers.js"></script>
</head>
<body>
<h1 id="title">Undo/Redo Drawing</h1>
<p id="shortdesc">
Demonstrates the use of undo &amp; redo methods while drawing.
</p>
<div id="map" class="smallmap"></div>

<div id="docs">
<p>
Use <code>Ctrl-Z</code> or <code>⌘-Z</code> to undo while drawing.
Use <code>Ctrl-Y</code> or <code>⌘-Y</code> to redo what you have
undone. Use <code>Esc</code> to cancel the current sketch.
<p>
The <code>control.undo</code> method works on the current
sketch, removing the most recently added point.
The <code>control.redo</code> method adds back items that were
removed from an undo. To fully erase a sketch, call the
<code>control.cancel</code> method.
</p><p>
View the <a href="draw-undo-redo.js" target="_blank">draw-undo-redo.js</a>
source to see how this is done.
</p>
</div>

<script src="draw-undo-redo.js"></script>
</body>
</html>
56 changes: 56 additions & 0 deletions examples/draw-undo-redo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
var map = new OpenLayers.Map({
div: "map",
layers: [
new OpenLayers.Layer.WMS(
"Global Imagery",
"http://maps.opengeo.org/geowebcache/service/wms",
{layers: "bluemarble"},
{tileOrigin: new OpenLayers.LonLat(-180, -90)}
),
new OpenLayers.Layer.Vector()
],
center: new OpenLayers.LonLat(0, 0),
zoom: 1
});

var draw = new OpenLayers.Control.DrawFeature(
map.layers[1], OpenLayers.Handler.Path
);
map.addControl(draw);
draw.activate();

OpenLayers.Event.observe(document, "keydown", function(evt) {
var code = evt.keyCode;
var handled = false;
if (code === 90) {
// z
if ("metaKey" in evt) {
if (evt.metaKey) {
draw.undo();
handled = true;
}
} else if (evt.ctrlKey) {
draw.undo();
handled = true;
}
}
if (code === 89) {
// y
if ("metaKey" in evt) {
if (evt.metaKey) {
draw.redo();
handled = true;
}
} else if (evt.ctrlKey) {
draw.redo();
handled = true;
}
}
if (handled) {
OpenLayers.Event.stop(evt);
}
if (code === 27) {
// esc
draw.cancel();
}
});
58 changes: 58 additions & 0 deletions examples/editing-methods.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<title>OpenLayers Editing Methods</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0;">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
<link rel="stylesheet" href="style.css" type="text/css">
<script src="../lib/OpenLayers.js"></script>
</head>
<body>
<h1 id="title">Editing Methods</h1>
<p id="shortdesc">
Demonstrates the use of editing methods for manipulating geometries
while drawing.
</p>
<div id="map" class="smallmap"></div>
<ul id="methods">
<li><a href="#" id="insertXY">insert x,y</a></li>
<li><a href="#" id="insertDeltaXY">insert dx,dy</a></li>
<li><a href="#" id="insertDirectionLength">insert direction/length</a></li>
<li><a href="#" id="insertDeflectionLength">insert deflection/length</a></li>
<li><a href="#" id="finishSketch">finish sketch</a></li>
<li><a href="#" id="cancel">cancel sketch</a></li>
</ul>

<div id="docs">
<p>
The <code>control.insertXY</code> method inserts a point at the given
map coordinates (x, y) immediately prior to the most recent point
(under the mouse).
The <code>control.insertDeltaXY</code> method inserts a point at
the given offset values (dx, dy) from the previously added point.
The <code>control.insertDirectionLength</code> method inserts a
point at offset direction and length from the previously added point.
Direction is measured counter-clockwise from the positive x-axis.
The <code>control.insertDeflectionLength</code> method inserts a
point at offset deflection and length from the previously added point.
Deflection is measured counter-clockwise from the previous line
segment.
The <code>control.finishSketch</code> method completes the current
sketch without adding the point under the user's mouse. This
allows a sketch to be finished without a double-click.
The <code>control.cancel</code> method discards the current
sketch and leaves the control active.
The <code>control.insertXY</code> method may be called before
any points are digitized manually. The other methods have no
effect until at least one point has been added to the sketch.
</p><p>
View the <a href="editing-methods.js" target="_blank">editing-methods.js</a>
source to see how this is done.
</p>
</div>

<script src="editing-methods.js"></script>
</body>
</html>
83 changes: 83 additions & 0 deletions examples/editing-methods.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
var map = new OpenLayers.Map({
div: "map",
layers: [
new OpenLayers.Layer.WMS(
"Global Imagery",
"http://maps.opengeo.org/geowebcache/service/wms",
{layers: "bluemarble"},
{tileOrigin: new OpenLayers.LonLat(-180, -90)}
),
new OpenLayers.Layer.Vector()
],
center: new OpenLayers.LonLat(0, 0),
zoom: 1
});

var draw = new OpenLayers.Control.DrawFeature(
map.layers[1], OpenLayers.Handler.Path
);
map.addControl(draw);
draw.activate();

// handle clicks on method links
$("insertXY").onclick = function() {
var values = parseInput(
window.prompt(
"Enter map coordinates for new point (e.g. '-111, 46')", "x, y"
)
);
if (values != null) {
draw.insertXY(values[0], values[1]);
}
}
$("insertDeltaXY").onclick = function() {
var values = parseInput(
window.prompt(
"Enter offset values for new point (e.g. '15, -10')", "dx, dy"
)
);
if (values != null) {
draw.insertDeltaXY(values[0], values[1]);
}
}
$("insertDirectionLength").onclick = function() {
var values = parseInput(
window.prompt(
"Enter direction and length offset values for new point (e.g. '-45, 10')", "direction, length"
)
);
if (values != null) {
draw.insertDirectionLength(values[0], values[1]);
}
}
$("insertDeflectionLength").onclick = function() {
var values = parseInput(
window.prompt(
"Enter deflection and length offset values for new point (e.g. '15, 20')", "deflection, length"
)
);
if (values != null) {
draw.insertDeflectionLength(values[0], values[1]);
}
}
$("cancel").onclick = function() {
draw.cancel();
}
$("finishSketch").onclick = function() {
draw.finishSketch();
}

function parseInput(text) {
var values = text.split(",");
if (values.length !== 2) {
values = null;
} else {
values[0] = parseFloat(values[0]);
values[1] = parseFloat(values[1]);
if (isNaN(values[0]) || isNaN(values[1])) {
window.alert("The two values must be numeric.");
values = null;
}
}
return values;
}
100 changes: 100 additions & 0 deletions lib/OpenLayers/Control/DrawFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,106 @@ OpenLayers.Control.DrawFeature = OpenLayers.Class(OpenLayers.Control, {
this.events.triggerEvent("featureadded",{feature : feature});
}
},

/**
* APIMethod: insertXY
* Insert a point in the current sketch given x & y coordinates.
*
* Parameters:
* x - {Number} The x-coordinate of the point.
* y - {Number} The y-coordinate of the point.
*/
insertXY: function(x, y) {
if (this.handler && this.handler.line) {
this.handler.insertXY(x, y);
}
},

/**
* APIMethod: insertDeltaXY
* Insert a point given offsets from the previously inserted point.
*
* Parameters:
* dx - {Number} The x-coordinate offset of the point.
* dy - {Number} The y-coordinate offset of the point.
*/
insertDeltaXY: function(dx, dy) {
if (this.handler && this.handler.line) {
this.handler.insertDeltaXY(dx, dy);
}
},

/**
* APIMethod: insertDirectionLength
* Insert a point in the current sketch given a direction and a length.
*
* Parameters:
* direction - {Number} Degrees clockwise from the positive x-axis.
* length - {Number} Distance from the previously drawn point.
*/
insertDirectionLength: function(direction, length) {
if (this.handler && this.handler.line) {
this.handler.insertDirectionLength(direction, length);
}
},

/**
* APIMethod: insertDeflectionLength
* Insert a point in the current sketch given a deflection and a length.
* The deflection should be degrees clockwise from the previously
* digitized segment.
*
* Parameters:
* deflection - {Number} Degrees clockwise from the previous segment.
* length - {Number} Distance from the previously drawn point.
*/
insertDeflectionLength: function(deflection, length) {
if (this.handler && this.handler.line) {
this.handler.insertDeflectionLength(deflection, length);
}
},

/**
* APIMethod: undo
* Remove the most recently added point in the current sketch geometry.
*
* Returns:
* {Boolean} An edit was undone.
*/
undo: function() {
return this.handler.undo && this.handler.undo();
},

/**
* APIMethod: redo
* Reinsert the most recently removed point resulting from an <undo> call.
* The undo stack is deleted whenever a point is added by other means.
*
* Returns:
* {Boolean} An edit was redone.
*/
redo: function() {
return this.handler.redo && this.handler.redo();
},

/**
* APIMethod: finishSketch
* Finishes the sketch without including the currently drawn point.
* This method can be called to terminate drawing programmatically
* instead of waiting for the user to end the sketch.
*/
finishSketch: function() {
this.handler.finishGeometry();
},

/**
* APIMethod: cancel
* Cancel the current sketch. This removes the current sketch and keeps
* the drawing control active.
*/
cancel: function() {
this.handler.cancel();
},

CLASS_NAME: "OpenLayers.Control.DrawFeature"
});
12 changes: 11 additions & 1 deletion lib/OpenLayers/Geometry/Collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,20 @@ OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {
*
* Parameters:
* components - {Array(<OpenLayers.Geometry>)} The components to be removed
*
* Returns:
* {Boolean} A component was removed.
*/
removeComponents: function(components) {
var removed = false;

if(!(OpenLayers.Util.isArray(components))) {
components = [components];
}
for(var i=components.length-1; i>=0; --i) {
this.removeComponent(components[i]);
removed = this.removeComponent(components[i]) || removed;
}
return removed;
},

/**
Expand All @@ -199,6 +205,9 @@ OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {
*
* Parameters:
* component - {<OpenLayers.Geometry>}
*
* Returns:
* {Boolean} The component was removed.
*/
removeComponent: function(component) {

Expand All @@ -207,6 +216,7 @@ OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {
// clearBounds() so that it gets recalculated on the next call
// to this.getBounds();
this.clearBounds();
return true;
},

/**
Expand Down
Loading

0 comments on commit 2cf3f62

Please sign in to comment.