Software: Apache. PHP/5.5.15 uname -a: Windows NT SVR-DMZ 6.1 build 7600 (Windows Server 2008 R2 Enterprise Edition) i586 SYSTEM Safe-mode: OFF (not secure) C:\dmz\phpMyAdmin\js\openlayers\src\openlayers\lib\OpenLayers\Control\ drwxrwxrwx |
Viewing file: ModifyFeature.js (28.49 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) | /* Copyright (c) 2006-2010 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: 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) { this.layer = layer; this.vertices = []; this.virtualVertices = []; this.virtualStyle = OpenLayers.Util.extend({}, this.layer.style || this.layer.styleMap.createSymbolizer()); 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(!(this.deleteCodes instanceof Array)) { 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} ); }, /** * Method: selectFeature * Called when the select feature control selects a feature. * * Parameters: * feature - {<OpenLayers.Feature.Vector>} the selected feature. */ selectFeature: function(feature) { this.feature = feature; this.modified = false; this.resetVertices(); this.dragControl.activate(); this.onModificationStart(this.feature); }, /** * 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; } }, /** * 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.drawFeature(this.feature, this.standalone ? undefined : this.selectControl.renderIntent); 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; 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; 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; |
:: Command execute :: | |
--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0312 ]-- |