| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814 |
- /* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
- * full list of contributors). Published under the Clear BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
- * full text of the license. */
- /**
- * @requires OpenLayers/Control/DragFeature.js
- * @requires OpenLayers/Control/SelectFeature.js
- * @requires OpenLayers/Handler/Keyboard.js
- */
- /**
- * Class: OpenLayers.Control.ModifyFeature
- * Control to modify features. When activated, a click renders the vertices
- * of a feature - these vertices can then be dragged. By default, the
- * delete key will delete the vertex under the mouse. New features are
- * added by dragging "virtual vertices" between vertices. Create a new
- * control with the <OpenLayers.Control.ModifyFeature> constructor.
- *
- * Inherits From:
- * - <OpenLayers.Control>
- */
- OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
- /**
- * APIProperty: geometryTypes
- * {Array(String)} To restrict modification to a limited set of geometry
- * types, send a list of strings corresponding to the geometry class
- * names.
- */
- geometryTypes: null,
- /**
- * APIProperty: clickout
- * {Boolean} Unselect features when clicking outside any feature.
- * Default is true.
- */
- clickout: true,
- /**
- * APIProperty: toggle
- * {Boolean} Unselect a selected feature on click.
- * Default is true.
- */
- toggle: true,
-
- /**
- * APIProperty: standalone
- * {Boolean} Set to true to create a control without SelectFeature
- * capabilities. Default is false. If standalone is true, to modify
- * a feature, call the <selectFeature> method with the target feature.
- * Note that you must call the <unselectFeature> method to finish
- * feature modification in standalone mode (before starting to modify
- * another feature).
- */
- standalone: false,
- /**
- * Property: layer
- * {<OpenLayers.Layer.Vector>}
- */
- layer: null,
-
- /**
- * Property: feature
- * {<OpenLayers.Feature.Vector>} Feature currently available for modification.
- */
- feature: null,
-
- /**
- * Property: vertices
- * {Array(<OpenLayers.Feature.Vector>)} Verticies currently available
- * for dragging.
- */
- vertices: null,
-
- /**
- * Property: virtualVertices
- * {Array(<OpenLayers.Feature.Vector>)} Virtual vertices in the middle
- * of each edge.
- */
- virtualVertices: null,
- /**
- * Property: selectControl
- * {<OpenLayers.Control.SelectFeature>}
- */
- selectControl: null,
-
- /**
- * Property: dragControl
- * {<OpenLayers.Control.DragFeature>}
- */
- dragControl: null,
-
- /**
- * Property: handlers
- * {Object}
- */
- handlers: null,
-
- /**
- * APIProperty: deleteCodes
- * {Array(Integer)} Keycodes for deleting verticies. Set to null to disable
- * vertex deltion by keypress. If non-null, keypresses with codes
- * in this array will delete vertices under the mouse. Default
- * is 46 and 68, the 'delete' and lowercase 'd' keys.
- */
- deleteCodes: null,
- /**
- * APIProperty: virtualStyle
- * {Object} A symbolizer to be used for virtual vertices.
- */
- virtualStyle: null,
-
- /**
- * APIProperty: vertexRenderIntent
- * {String} The renderIntent to use for vertices. If no <virtualStyle> is
- * provided, this renderIntent will also be used for virtual vertices, with
- * a fillOpacity and strokeOpacity of 0.3. Default is null, which means
- * that the layer's default style will be used for vertices.
- */
- vertexRenderIntent: null,
- /**
- * APIProperty: mode
- * {Integer} Bitfields specifying the modification mode. Defaults to
- * OpenLayers.Control.ModifyFeature.RESHAPE. To set the mode to a
- * combination of options, use the | operator. For example, to allow
- * the control to both resize and rotate features, use the following
- * syntax
- * (code)
- * control.mode = OpenLayers.Control.ModifyFeature.RESIZE |
- * OpenLayers.Control.ModifyFeature.ROTATE;
- * (end)
- */
- mode: null,
- /**
- * Property: modified
- * {Boolean} The currently selected feature has been modified.
- */
- modified: false,
- /**
- * Property: radiusHandle
- * {<OpenLayers.Feature.Vector>} A handle for rotating/resizing a feature.
- */
- radiusHandle: null,
- /**
- * Property: dragHandle
- * {<OpenLayers.Feature.Vector>} A handle for dragging a feature.
- */
- dragHandle: null,
- /**
- * APIProperty: onModificationStart
- * {Function} *Deprecated*. Register for "beforefeaturemodified" instead.
- * The "beforefeaturemodified" event is triggered on the layer before
- * any modification begins.
- *
- * Optional function to be called when a feature is selected
- * to be modified. The function should expect to be called with a
- * feature. This could be used for example to allow to lock the
- * feature on server-side.
- */
- onModificationStart: function() {},
- /**
- * APIProperty: onModification
- * {Function} *Deprecated*. Register for "featuremodified" instead.
- * The "featuremodified" event is triggered on the layer with each
- * feature modification.
- *
- * Optional function to be called when a feature has been
- * modified. The function should expect to be called with a feature.
- */
- onModification: function() {},
- /**
- * APIProperty: onModificationEnd
- * {Function} *Deprecated*. Register for "afterfeaturemodified" instead.
- * The "afterfeaturemodified" event is triggered on the layer after
- * a feature has been modified.
- *
- * Optional function to be called when a feature is finished
- * being modified. The function should expect to be called with a
- * feature.
- */
- onModificationEnd: function() {},
- /**
- * Constructor: OpenLayers.Control.ModifyFeature
- * Create a new modify feature control.
- *
- * Parameters:
- * layer - {<OpenLayers.Layer.Vector>} Layer that contains features that
- * will be modified.
- * options - {Object} Optional object whose properties will be set on the
- * control.
- */
- initialize: function(layer, options) {
- options = options || {};
- this.layer = layer;
- this.vertices = [];
- this.virtualVertices = [];
- this.virtualStyle = OpenLayers.Util.extend({},
- this.layer.style ||
- this.layer.styleMap.createSymbolizer(null, options.vertexRenderIntent)
- );
- this.virtualStyle.fillOpacity = 0.3;
- this.virtualStyle.strokeOpacity = 0.3;
- this.deleteCodes = [46, 68];
- this.mode = OpenLayers.Control.ModifyFeature.RESHAPE;
- OpenLayers.Control.prototype.initialize.apply(this, [options]);
- if(!(OpenLayers.Util.isArray(this.deleteCodes))) {
- this.deleteCodes = [this.deleteCodes];
- }
- var control = this;
- // configure the select control
- var selectOptions = {
- geometryTypes: this.geometryTypes,
- clickout: this.clickout,
- toggle: this.toggle,
- onBeforeSelect: this.beforeSelectFeature,
- onSelect: this.selectFeature,
- onUnselect: this.unselectFeature,
- scope: this
- };
- if(this.standalone === false) {
- this.selectControl = new OpenLayers.Control.SelectFeature(
- layer, selectOptions
- );
- }
- // configure the drag control
- var dragOptions = {
- geometryTypes: ["OpenLayers.Geometry.Point"],
- snappingOptions: this.snappingOptions,
- onStart: function(feature, pixel) {
- control.dragStart.apply(control, [feature, pixel]);
- },
- onDrag: function(feature, pixel) {
- control.dragVertex.apply(control, [feature, pixel]);
- },
- onComplete: function(feature) {
- control.dragComplete.apply(control, [feature]);
- },
- featureCallbacks: {
- over: function(feature) {
- /**
- * In normal mode, the feature handler is set up to allow
- * dragging of all points. In standalone mode, we only
- * want to allow dragging of sketch vertices and virtual
- * vertices - or, in the case of a modifiable point, the
- * point itself.
- */
- if(control.standalone !== true || feature._sketch ||
- control.feature === feature) {
- control.dragControl.overFeature.apply(
- control.dragControl, [feature]);
- }
- }
- }
- };
- this.dragControl = new OpenLayers.Control.DragFeature(
- layer, dragOptions
- );
- // configure the keyboard handler
- var keyboardOptions = {
- keydown: this.handleKeypress
- };
- this.handlers = {
- keyboard: new OpenLayers.Handler.Keyboard(this, keyboardOptions)
- };
- },
- /**
- * APIMethod: destroy
- * Take care of things that are not handled in superclass.
- */
- destroy: function() {
- this.layer = null;
- this.standalone || this.selectControl.destroy();
- this.dragControl.destroy();
- OpenLayers.Control.prototype.destroy.apply(this, []);
- },
- /**
- * APIMethod: activate
- * Activate the control.
- *
- * Returns:
- * {Boolean} Successfully activated the control.
- */
- activate: function() {
- return ((this.standalone || this.selectControl.activate()) &&
- this.handlers.keyboard.activate() &&
- OpenLayers.Control.prototype.activate.apply(this, arguments));
- },
- /**
- * APIMethod: deactivate
- * Deactivate the control.
- *
- * Returns:
- * {Boolean} Successfully deactivated the control.
- */
- deactivate: function() {
- var deactivated = false;
- // the return from the controls is unimportant in this case
- if(OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
- this.layer.removeFeatures(this.vertices, {silent: true});
- this.layer.removeFeatures(this.virtualVertices, {silent: true});
- this.vertices = [];
- this.dragControl.deactivate();
- var feature = this.feature;
- var valid = feature && feature.geometry && feature.layer;
- if(this.standalone === false) {
- if(valid) {
- this.selectControl.unselect.apply(this.selectControl,
- [feature]);
- }
- this.selectControl.deactivate();
- } else {
- if(valid) {
- this.unselectFeature(feature);
- }
- }
- this.handlers.keyboard.deactivate();
- deactivated = true;
- }
- return deactivated;
- },
-
- /**
- * Method: beforeSelectFeature
- * Called before a feature is selected.
- *
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>} The feature about to be selected.
- */
- beforeSelectFeature: function(feature) {
- return this.layer.events.triggerEvent(
- "beforefeaturemodified", {feature: feature}
- );
- },
- /**
- * APIMethod: selectFeature
- * Select a feature for modification in standalone mode. In non-standalone
- * mode, this method is called when the select feature control selects a
- * feature. Register a listener to the beforefeaturemodified event and
- * return false to prevent feature modification.
- *
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>} the selected feature.
- */
- selectFeature: function(feature) {
- if (!this.standalone || this.beforeSelectFeature(feature) !== false) {
- this.feature = feature;
- this.modified = false;
- this.resetVertices();
- this.dragControl.activate();
- this.onModificationStart(this.feature);
- }
- // keep track of geometry modifications
- var modified = feature.modified;
- if (feature.geometry && !(modified && modified.geometry)) {
- this._originalGeometry = feature.geometry.clone();
- }
- },
- /**
- * Method: unselectFeature
- * Called when the select feature control unselects a feature.
- *
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>} The unselected feature.
- */
- unselectFeature: function(feature) {
- this.layer.removeFeatures(this.vertices, {silent: true});
- this.vertices = [];
- this.layer.destroyFeatures(this.virtualVertices, {silent: true});
- this.virtualVertices = [];
- if(this.dragHandle) {
- this.layer.destroyFeatures([this.dragHandle], {silent: true});
- delete this.dragHandle;
- }
- if(this.radiusHandle) {
- this.layer.destroyFeatures([this.radiusHandle], {silent: true});
- delete this.radiusHandle;
- }
- this.feature = null;
- this.dragControl.deactivate();
- this.onModificationEnd(feature);
- this.layer.events.triggerEvent("afterfeaturemodified", {
- feature: feature,
- modified: this.modified
- });
- this.modified = false;
- },
- /**
- * Method: dragStart
- * Called by the drag feature control with before a feature is dragged.
- * This method is used to differentiate between points and vertices
- * of higher order geometries. This respects the <geometryTypes>
- * property and forces a select of points when the drag control is
- * already active (and stops events from propagating to the select
- * control).
- *
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>} The point or vertex about to be
- * dragged.
- * pixel - {<OpenLayers.Pixel>} Pixel location of the mouse event.
- */
- dragStart: function(feature, pixel) {
- // only change behavior if the feature is not in the vertices array
- if(feature != this.feature && !feature.geometry.parent &&
- feature != this.dragHandle && feature != this.radiusHandle) {
- if(this.standalone === false && this.feature) {
- // unselect the currently selected feature
- this.selectControl.clickFeature.apply(this.selectControl,
- [this.feature]);
- }
- // check any constraints on the geometry type
- if(this.geometryTypes == null ||
- OpenLayers.Util.indexOf(this.geometryTypes,
- feature.geometry.CLASS_NAME) != -1) {
- // select the point
- this.standalone || this.selectControl.clickFeature.apply(
- this.selectControl, [feature]);
- /**
- * TBD: These lines improve workflow by letting the user
- * immediately start dragging after the mouse down.
- * However, it is very ugly to be messing with controls
- * and their handlers in this way. I'd like a better
- * solution if the workflow change is necessary.
- */
- // prepare the point for dragging
- this.dragControl.overFeature.apply(this.dragControl,
- [feature]);
- this.dragControl.lastPixel = pixel;
- this.dragControl.handlers.drag.started = true;
- this.dragControl.handlers.drag.start = pixel;
- this.dragControl.handlers.drag.last = pixel;
- }
- }
- },
-
- /**
- * Method: dragVertex
- * Called by the drag feature control with each drag move of a vertex.
- *
- * Parameters:
- * vertex - {<OpenLayers.Feature.Vector>} The vertex being dragged.
- * pixel - {<OpenLayers.Pixel>} Pixel location of the mouse event.
- */
- dragVertex: function(vertex, pixel) {
- this.modified = true;
- /**
- * Five cases:
- * 1) dragging a simple point
- * 2) dragging a virtual vertex
- * 3) dragging a drag handle
- * 4) dragging a real vertex
- * 5) dragging a radius handle
- */
- if(this.feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
- // dragging a simple point
- if(this.feature != vertex) {
- this.feature = vertex;
- }
- this.layer.events.triggerEvent("vertexmodified", {
- vertex: vertex.geometry,
- feature: this.feature,
- pixel: pixel
- });
- } else {
- if(vertex._index) {
- // dragging a virtual vertex
- vertex.geometry.parent.addComponent(vertex.geometry,
- vertex._index);
- // move from virtual to real vertex
- delete vertex._index;
- OpenLayers.Util.removeItem(this.virtualVertices, vertex);
- this.vertices.push(vertex);
- } else if(vertex == this.dragHandle) {
- // dragging a drag handle
- this.layer.removeFeatures(this.vertices, {silent: true});
- this.vertices = [];
- if(this.radiusHandle) {
- this.layer.destroyFeatures([this.radiusHandle], {silent: true});
- this.radiusHandle = null;
- }
- } else if(vertex !== this.radiusHandle) {
- // dragging a real vertex
- this.layer.events.triggerEvent("vertexmodified", {
- vertex: vertex.geometry,
- feature: this.feature,
- pixel: pixel
- });
- }
- // dragging a radius handle - no special treatment
- if(this.virtualVertices.length > 0) {
- this.layer.destroyFeatures(this.virtualVertices, {silent: true});
- this.virtualVertices = [];
- }
- this.layer.drawFeature(this.feature, this.standalone ? undefined :
- this.selectControl.renderIntent);
- }
- // 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
- this.layer.drawFeature(vertex);
- },
-
- /**
- * Method: dragComplete
- * Called by the drag feature control when the feature dragging is complete.
- *
- * Parameters:
- * vertex - {<OpenLayers.Feature.Vector>} The vertex being dragged.
- */
- dragComplete: function(vertex) {
- this.resetVertices();
- this.setFeatureState();
- this.onModification(this.feature);
- this.layer.events.triggerEvent("featuremodified",
- {feature: this.feature});
- },
-
- /**
- * Method: setFeatureState
- * Called when the feature is modified. If the current state is not
- * INSERT or DELETE, the state is set to UPDATE.
- */
- setFeatureState: function() {
- if(this.feature.state != OpenLayers.State.INSERT &&
- this.feature.state != OpenLayers.State.DELETE) {
- this.feature.state = OpenLayers.State.UPDATE;
- if (this.modified && this._originalGeometry) {
- var feature = this.feature;
- feature.modified = OpenLayers.Util.extend(feature.modified, {
- geometry: this._originalGeometry
- });
- delete this._originalGeometry;
- }
- }
- },
-
- /**
- * Method: resetVertices
- */
- resetVertices: function() {
- // if coming from a drag complete we're about to destroy the vertex
- // that was just dragged. For that reason, the drag feature control
- // will never detect a mouse-out on that vertex, meaning that the drag
- // handler won't be deactivated. This can cause errors because the drag
- // feature control still has a feature to drag but that feature is
- // destroyed. To prevent this, we call outFeature on the drag feature
- // control if the control actually has a feature to drag.
- if(this.dragControl.feature) {
- this.dragControl.outFeature(this.dragControl.feature);
- }
- if(this.vertices.length > 0) {
- this.layer.removeFeatures(this.vertices, {silent: true});
- this.vertices = [];
- }
- if(this.virtualVertices.length > 0) {
- this.layer.removeFeatures(this.virtualVertices, {silent: true});
- this.virtualVertices = [];
- }
- if(this.dragHandle) {
- this.layer.destroyFeatures([this.dragHandle], {silent: true});
- this.dragHandle = null;
- }
- if(this.radiusHandle) {
- this.layer.destroyFeatures([this.radiusHandle], {silent: true});
- this.radiusHandle = null;
- }
- if(this.feature &&
- this.feature.geometry.CLASS_NAME != "OpenLayers.Geometry.Point") {
- if((this.mode & OpenLayers.Control.ModifyFeature.DRAG)) {
- this.collectDragHandle();
- }
- if((this.mode & (OpenLayers.Control.ModifyFeature.ROTATE |
- OpenLayers.Control.ModifyFeature.RESIZE))) {
- this.collectRadiusHandle();
- }
- if(this.mode & OpenLayers.Control.ModifyFeature.RESHAPE){
- // Don't collect vertices when we're resizing
- if (!(this.mode & OpenLayers.Control.ModifyFeature.RESIZE)){
- this.collectVertices();
- }
- }
- }
- },
-
- /**
- * Method: handleKeypress
- * Called by the feature handler on keypress. This is used to delete
- * vertices. If the <deleteCode> property is set, vertices will
- * be deleted when a feature is selected for modification and
- * the mouse is over a vertex.
- *
- * Parameters:
- * {Integer} Key code corresponding to the keypress event.
- */
- handleKeypress: function(evt) {
- var code = evt.keyCode;
-
- // check for delete key
- if(this.feature &&
- OpenLayers.Util.indexOf(this.deleteCodes, code) != -1) {
- var vertex = this.dragControl.feature;
- if(vertex &&
- OpenLayers.Util.indexOf(this.vertices, vertex) != -1 &&
- !this.dragControl.handlers.drag.dragging &&
- vertex.geometry.parent) {
- // remove the vertex
- vertex.geometry.parent.removeComponent(vertex.geometry);
- this.layer.events.triggerEvent("vertexremoved", {
- vertex: vertex.geometry,
- feature: this.feature,
- pixel: evt.xy
- });
- this.layer.drawFeature(this.feature, this.standalone ?
- undefined :
- this.selectControl.renderIntent);
- this.modified = true;
- this.resetVertices();
- this.setFeatureState();
- this.onModification(this.feature);
- this.layer.events.triggerEvent("featuremodified",
- {feature: this.feature});
- }
- }
- },
- /**
- * Method: collectVertices
- * Collect the vertices from the modifiable feature's geometry and push
- * them on to the control's vertices array.
- */
- collectVertices: function() {
- this.vertices = [];
- this.virtualVertices = [];
- var control = this;
- function collectComponentVertices(geometry) {
- var i, vertex, component, len;
- if(geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
- vertex = new OpenLayers.Feature.Vector(geometry);
- vertex._sketch = true;
- vertex.renderIntent = control.vertexRenderIntent;
- control.vertices.push(vertex);
- } else {
- var numVert = geometry.components.length;
- if(geometry.CLASS_NAME == "OpenLayers.Geometry.LinearRing") {
- numVert -= 1;
- }
- for(i=0; i<numVert; ++i) {
- component = geometry.components[i];
- if(component.CLASS_NAME == "OpenLayers.Geometry.Point") {
- vertex = new OpenLayers.Feature.Vector(component);
- vertex._sketch = true;
- vertex.renderIntent = control.vertexRenderIntent;
- control.vertices.push(vertex);
- } else {
- collectComponentVertices(component);
- }
- }
-
- // add virtual vertices in the middle of each edge
- if(geometry.CLASS_NAME != "OpenLayers.Geometry.MultiPoint") {
- for(i=0, len=geometry.components.length; i<len-1; ++i) {
- var prevVertex = geometry.components[i];
- var nextVertex = geometry.components[i + 1];
- if(prevVertex.CLASS_NAME == "OpenLayers.Geometry.Point" &&
- nextVertex.CLASS_NAME == "OpenLayers.Geometry.Point") {
- var x = (prevVertex.x + nextVertex.x) / 2;
- var y = (prevVertex.y + nextVertex.y) / 2;
- var point = new OpenLayers.Feature.Vector(
- new OpenLayers.Geometry.Point(x, y),
- null, control.virtualStyle
- );
- // set the virtual parent and intended index
- point.geometry.parent = geometry;
- point._index = i + 1;
- point._sketch = true;
- control.virtualVertices.push(point);
- }
- }
- }
- }
- }
- collectComponentVertices.call(this, this.feature.geometry);
- this.layer.addFeatures(this.virtualVertices, {silent: true});
- this.layer.addFeatures(this.vertices, {silent: true});
- },
- /**
- * 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);
- };
- origin._sketch = true;
- this.dragHandle = origin;
- this.layer.addFeatures([this.dragHandle], {silent: true});
- },
- /**
- * 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.mode & OpenLayers.Control.ModifyFeature.RESIZE);
- var reshape = (this.mode & OpenLayers.Control.ModifyFeature.RESHAPE);
- var rotate = (this.mode & OpenLayers.Control.ModifyFeature.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 scale, ratio;
- // 'resize' together with 'reshape' implies that the aspect
- // ratio of the geometry will not be preserved whilst resizing
- if (reshape) {
- scale = dy1 / dy0;
- ratio = (dx1 / dx0) / scale;
- } else {
- var l0 = Math.sqrt((dx0 * dx0) + (dy0 * dy0));
- var l1 = Math.sqrt((dx1 * dx1) + (dy1 * dy1));
- scale = l1 / l0;
- }
- geometry.resize(scale, originGeometry, ratio);
- }
- };
- radius._sketch = true;
- this.radiusHandle = radius;
- this.layer.addFeatures([this.radiusHandle], {silent: true});
- },
- /**
- * Method: setMap
- * Set the map property for the control and all handlers.
- *
- * Parameters:
- * map - {<OpenLayers.Map>} The control's map.
- */
- setMap: function(map) {
- this.standalone || this.selectControl.setMap(map);
- this.dragControl.setMap(map);
- OpenLayers.Control.prototype.setMap.apply(this, arguments);
- },
- CLASS_NAME: "OpenLayers.Control.ModifyFeature"
- });
- /**
- * Constant: RESHAPE
- * {Integer} Constant used to make the control work in reshape mode
- */
- OpenLayers.Control.ModifyFeature.RESHAPE = 1;
- /**
- * Constant: RESIZE
- * {Integer} Constant used to make the control work in resize mode
- */
- OpenLayers.Control.ModifyFeature.RESIZE = 2;
- /**
- * Constant: ROTATE
- * {Integer} Constant used to make the control work in rotate mode
- */
- OpenLayers.Control.ModifyFeature.ROTATE = 4;
- /**
- * Constant: DRAG
- * {Integer} Constant used to make the control work in drag mode
- */
- OpenLayers.Control.ModifyFeature.DRAG = 8;
|