drag, rotate, resize, and reshape with the ModifyFeature control - thanks pvalsecc and elemoine for the inspiration, tests, and code - good partenering with you guys (closes #1150).
git-svn-id: http://svn.openlayers.org/trunk/openlayers@5301 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -86,7 +86,37 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
* {<OpenLayers.Feature.Vector.Style>}
|
||||
*/
|
||||
virtualStyle: null,
|
||||
|
||||
/**
|
||||
* APIProperty: rotate
|
||||
* {Boolean} Allow rotation of feature instead of vertex modification.
|
||||
*/
|
||||
rotate: false,
|
||||
|
||||
/**
|
||||
* APIProperty: resize
|
||||
* {Boolean} Allow resizing of feature instead of vertex modification.
|
||||
*/
|
||||
resize: false,
|
||||
|
||||
/**
|
||||
* Property: radiusHandle
|
||||
* {<OpenLayers.Feature.Vector>} A handle for rotating/resizing a feature.
|
||||
*/
|
||||
radiusHandle: null,
|
||||
|
||||
/**
|
||||
* APIProperty: drag
|
||||
* {Boolean} Allow dragging of feature with a drag handle.
|
||||
*/
|
||||
drag: false,
|
||||
|
||||
/**
|
||||
* Property: dragHandle
|
||||
* {<OpenLayers.Feature.Vector>} A handle for dragging a feature.
|
||||
*/
|
||||
dragHandle: null,
|
||||
|
||||
/**
|
||||
* APIProperty: onModificationStart
|
||||
* {Function} Optional function to be called when a feature is selected
|
||||
@@ -250,9 +280,17 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
unselectFeature: function(feature) {
|
||||
this.layer.removeFeatures(this.vertices);
|
||||
this.layer.removeFeatures(this.virtualVertices);
|
||||
this.vertices = [];
|
||||
this.layer.destroyFeatures(this.virtualVertices);
|
||||
this.virtualVertices = [];
|
||||
if(this.dragHandle) {
|
||||
this.layer.destroyFeatures([this.dragHandle]);
|
||||
delete this.dragHandle;
|
||||
}
|
||||
if(this.radiusHandle) {
|
||||
this.layer.destroyFeatures([this.radiusHandle]);
|
||||
delete this.radiusHandle;
|
||||
}
|
||||
this.feature = null;
|
||||
this.dragControl.deactivate();
|
||||
this.onModificationEnd(feature);
|
||||
@@ -274,9 +312,8 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
dragStart: function(feature, pixel) {
|
||||
// only change behavior if the feature is not in the vertices array
|
||||
if(feature != this.feature &&
|
||||
OpenLayers.Util.indexOf(this.vertices, feature) == -1 &&
|
||||
OpenLayers.Util.indexOf(this.virtualVertices, feature) == -1) {
|
||||
if(feature != this.feature && !feature.geometry.parent &&
|
||||
feature != this.dragHandle && feature != this.radiusHandle) {
|
||||
if(this.feature) {
|
||||
// unselect the currently selected feature
|
||||
this.selectControl.clickFeature.apply(this.selectControl,
|
||||
@@ -315,21 +352,41 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
* vertex - {<OpenLayers.Feature.Vector>} The vertex being dragged.
|
||||
*/
|
||||
dragVertex: function(vertex) {
|
||||
/**
|
||||
* Five cases:
|
||||
* 1) dragging a simple point
|
||||
* 2) dragging a virtual vertex
|
||||
* 3) dragging a drag handle
|
||||
* 4) dragging a radius handle
|
||||
* 5) dragging a real vertex
|
||||
*/
|
||||
if(this.feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
|
||||
// dragging a simple point
|
||||
if(this.feature != vertex) {
|
||||
this.feature = vertex;
|
||||
}
|
||||
} else {
|
||||
if(OpenLayers.Util.indexOf(this.virtualVertices, vertex) != -1) {
|
||||
if(vertex._index) {
|
||||
// dragging a virtual vertex
|
||||
vertex.geometry.parent.addComponent(vertex.geometry,
|
||||
vertex._index);
|
||||
delete vertex._index;
|
||||
OpenLayers.Util.removeItem(this.virtualVertices, vertex);
|
||||
this.layer.removeFeatures(vertex);
|
||||
} else if(vertex == this.dragHandle) {
|
||||
// dragging a drag handle
|
||||
this.layer.removeFeatures(this.vertices);
|
||||
this.vertices = [];
|
||||
if(this.radiusHandle) {
|
||||
this.layer.destroyFeatures([this.radiusHandle]);
|
||||
this.radiusHandle = null;
|
||||
}
|
||||
}
|
||||
// dragging a radius handle - no special treatment
|
||||
// dragging a real vertex - no special treatment
|
||||
this.layer.destroyFeatures(this.virtualVertices);
|
||||
this.virtualVertices = [];
|
||||
this.layer.drawFeature(this.feature, this.selectControl.selectStyle);
|
||||
}
|
||||
this.layer.drawFeature(this.feature, this.selectControl.selectStyle);
|
||||
this.layer.removeFeatures(this.virtualVertices);
|
||||
// keep the vertex on top so it gets the mouseout after dragging
|
||||
// this should be removed in favor of an option to draw under or
|
||||
// maintain node z-index
|
||||
@@ -360,11 +417,24 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
this.layer.removeFeatures(this.virtualVertices);
|
||||
this.virtualVertices = [];
|
||||
}
|
||||
if(this.dragHandle) {
|
||||
this.layer.destroyFeatures([this.dragHandle]);
|
||||
this.dragHandle = null;
|
||||
}
|
||||
if(this.radiusHandle) {
|
||||
this.layer.destroyFeatures([this.radiusHandle]);
|
||||
this.radiusHandle = null;
|
||||
}
|
||||
if(this.feature &&
|
||||
this.feature.geometry.CLASS_NAME != "OpenLayers.Geometry.Point") {
|
||||
this.collectVertices(this.feature.geometry);
|
||||
this.layer.addFeatures(this.vertices);
|
||||
this.layer.addFeatures(this.virtualVertices);
|
||||
if(this.drag) {
|
||||
this.collectDragHandle();
|
||||
}
|
||||
if(this.rotate || this.resize) {
|
||||
this.collectRadiusHandle();
|
||||
} else {
|
||||
this.collectVertices();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -385,7 +455,8 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
var vertex = this.dragControl.feature;
|
||||
if(vertex &&
|
||||
OpenLayers.Util.indexOf(this.vertices, vertex) != -1 &&
|
||||
!this.dragControl.dragHandler.dragging) {
|
||||
!this.dragControl.dragHandler.dragging &&
|
||||
vertex.geometry.parent) {
|
||||
// remove the vertex
|
||||
vertex.geometry.parent.removeComponent(vertex.geometry);
|
||||
this.layer.drawFeature(this.feature,
|
||||
@@ -442,8 +513,69 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
collectComponentVertices(this.feature.geometry);
|
||||
}
|
||||
collectComponentVertices.call(this, this.feature.geometry);
|
||||
this.layer.addFeatures(this.vertices);
|
||||
this.layer.addFeatures(this.virtualVertices);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: collectDragHandle
|
||||
* Collect the drag handle for the selected geometry.
|
||||
*/
|
||||
collectDragHandle: function() {
|
||||
var geometry = this.feature.geometry;
|
||||
var center = geometry.getBounds().getCenterLonLat();
|
||||
var originGeometry = new OpenLayers.Geometry.Point(
|
||||
center.lon, center.lat
|
||||
);
|
||||
var origin = new OpenLayers.Feature.Vector(originGeometry);
|
||||
originGeometry.move = function(x, y) {
|
||||
OpenLayers.Geometry.Point.prototype.move.call(this, x, y);
|
||||
geometry.move(x, y);
|
||||
}
|
||||
this.dragHandle = origin;
|
||||
this.layer.addFeatures([this.dragHandle]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: collectRadiusHandle
|
||||
* Collect the radius handle for the selected geometry.
|
||||
*/
|
||||
collectRadiusHandle: function() {
|
||||
var geometry = this.feature.geometry;
|
||||
var bounds = geometry.getBounds();
|
||||
var center = bounds.getCenterLonLat();
|
||||
var originGeometry = new OpenLayers.Geometry.Point(
|
||||
center.lon, center.lat
|
||||
);
|
||||
var radiusGeometry = new OpenLayers.Geometry.Point(
|
||||
bounds.right, bounds.bottom
|
||||
);
|
||||
var radius = new OpenLayers.Feature.Vector(radiusGeometry);
|
||||
var resize = this.resize;
|
||||
var rotate = this.rotate;
|
||||
radiusGeometry.move = function(x, y) {
|
||||
OpenLayers.Geometry.Point.prototype.move.call(this, x, y);
|
||||
var dx1 = this.x - originGeometry.x;
|
||||
var dy1 = this.y - originGeometry.y;
|
||||
var dx0 = dx1 - x;
|
||||
var dy0 = dy1 - y;
|
||||
if(rotate) {
|
||||
var a0 = Math.atan2(dy0, dx0);
|
||||
var a1 = Math.atan2(dy1, dx1);
|
||||
var angle = a1 - a0;
|
||||
angle *= 180 / Math.PI;
|
||||
geometry.rotate(angle, originGeometry);
|
||||
}
|
||||
if(resize) {
|
||||
var l0 = Math.sqrt((dx0 * dx0) + (dy0 * dy0));
|
||||
var l1 = Math.sqrt((dx1 * dx1) + (dy1 * dy1));
|
||||
geometry.resize(l1 / l0, originGeometry);
|
||||
}
|
||||
}
|
||||
this.radiusHandle = radius;
|
||||
this.layer.addFeatures([this.radiusHandle]);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user