Ok, i see my file was blocked so attaching it in txt format
Cheers Kris From: dev-boun...@openlayers.org [mailto:dev-boun...@openlayers.org] On Behalf Of Kris Geusebroek Sent: Thursday, February 19, 2009 2:28 PM To: dev@openlayers.org Subject: {Filename?} [OpenLayers-Dev] addition to issue #1666;Multiple layers for ModifyFeature Hi, I've been working to get the modifyfeature working with the patch provided in issue #1666. I've got it working now with the attached MultiLayers.js file. Not the nicest way to override the default classes (I just made a copy and renamed it and added my stuff), but it might be usefull to add to issue 1666 Cheers Kris Geusebroek
OpenLayers.Control.MultipleLayersSelectFeature=OpenLayers.Class(OpenLayers.Control,{ multipleKey:null, toggleKey:null, multiple:false, clickout:true, toggle:false, hover:false, box:false, onSelect:function(){}, onUnselect:function(){}, geometryTypes:null, layer:null, layers:null, callbacks:null, selectStyle:null, renderIntent:"select", handlers:null, initialize:function(layers,options){OpenLayers.Control.prototype.initialize.apply(this,[options]); if(!(layers instanceof Array)){layers=[layers];} this.layers=layers; this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,{displayInLayerSwitcher:false,display:function(){},getFeatureFromEvent:function(evt){var feature;for(var i=0;i<layers.length;i++){feature=layers[i].getFeatureFromEvent(evt);if(feature){return feature;}}}}); var callbacks={click:this.clickFeature,clickout:this.clickoutFeature}; if(this.hover){callbacks.over=this.overFeature;callbacks.out=this.outFeature;} this.callbacks=OpenLayers.Util.extend(callbacks,this.callbacks); this.handlers={feature:new OpenLayers.Handler.Feature(this,this.layer,this.callbacks,{geometryTypes:this.geometryTypes})}; if(this.box){this.handlers.box=new OpenLayers.Handler.Box(this,{done:this.selectBox},{boxDivClassName:"olHandlerBoxSelectFeature"});}}, destroy:function(){OpenLayers.Control.prototype.destroy.apply(this, arguments); this.layer.destroy();}, activate:function(){ if(!this.active){ this.collectRoots(); this.map.addLayer(this.layer); this.map.events.register("changelayer",this,this.handleChangeLayer); this.handlers.feature.activate(); if(this.box&&this.handlers.box){this.handlers.box.activate();} } return OpenLayers.Control.prototype.activate.apply(this,arguments); }, deactivate:function(){ if(this.active){ this.handlers.feature.deactivate(); if(this.handlers.box){this.handlers.box.deactivate();} this.map.events.unregister("changelayer",this,this.handleChangeLayer); this.resetRoots(); this.map.removeLayer(this.layer); } return OpenLayers.Control.prototype.deactivate.apply(this,arguments); }, unselectAll:function(options){ var layer,feature; for(var l=0;l<this.layers.length;++l){ layer=this.layers[l]; for(var i=layer.selectedFeatures.length-1;i>=0;--i){ feature=layer.selectedFeatures[i]; if(!options||options.except!=feature){ this.unselect(feature); } } } }, clickFeature:function(feature){ if(!this.hover){ var selected=(OpenLayers.Util.indexOf(feature.layer.selectedFeatures,feature)>-1); if(selected){ if(this.toggleSelect()){ this.unselect(feature); } else if(!this.multipleSelect()){ this.unselectAll({except:feature}); } } else{ if(!this.multipleSelect()){ this.unselectAll({except:feature}); } this.select(feature); } } }, multipleSelect:function(){return this.multiple||this.handlers.feature.evt[this.multipleKey];}, toggleSelect:function(){return this.toggle||this.handlers.feature.evt[this.toggleKey];}, clickoutFeature:function(feature){ if(!this.hover&&this.clickout){ this.unselectAll(); } }, overFeature:function(feature){ if(this.hover&&(OpenLayers.Util.indexOf(feature.layer.selectedFeatures,feature)==-1)){ this.select(feature); } }, outFeature:function(feature){ if(this.hover){ this.unselect(feature); } }, select:function(feature){ var layer=feature.layer; if (layer) { var cont=layer.events.triggerEvent("beforefeatureselected",{feature:feature}); if(cont!==false){ layer.selectedFeatures.push(feature); var selectStyle=this.selectStyle||this.renderIntent; layer.drawFeature(feature,selectStyle); layer.events.triggerEvent("featureselected",{feature:feature}); this.onSelect(feature); } } }, unselect:function(feature){ var layer=feature.layer; layer.drawFeature(feature,"default"); OpenLayers.Util.removeItem(layer.selectedFeatures,feature); layer.events.triggerEvent("featureunselected",{feature:feature}); this.onUnselect(feature); }, selectBox:function(position){ if(position instanceof OpenLayers.Bounds){ var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom)); var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top)); var bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat); if(!this.multipleSelect()){ this.unselectAll(); } var prevMultiple=this.multiple; this.multiple=true; var layer; for(var l=0;l<this.layers.length;++l){ layer=this.layers[l]; for(var i=0,len=layer.features.length;i<len;++i){ var feature=layer.features[i]; if(this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)>-1){ if(bounds.toGeometry().intersects(feature.geometry)){ if(OpenLayers.Util.indexOf(layer.selectedFeatures,feature)==-1){ this.select(feature); } } } } } this.multiple=prevMultiple; } }, setMap:function(map){ this.handlers.feature.setMap(map); if(this.box){this.handlers.box.setMap(map);} OpenLayers.Control.prototype.setMap.apply(this,arguments); }, collectRoots:function(){ var layer; for(var i=0;i<this.map.layers.length;++i){ layer=this.map.layers[i]; if(OpenLayers.Util.indexOf(this.layers,layer)!=-1){ layer.renderer.moveRoot(this.layer.renderer); } } }, resetRoots:function(){ var layer; for(var i=0;i<this.layers.length;++i){ layer=this.layers[i]; if(layer.renderer.getRenderLayer()==this.layer){ this.layer.renderer.moveRoot(layer.renderer); } } }, handleChangeLayer:function(evt){ var layer=evt.layer; if(evt.property=="order"&&OpenLayers.Util.indexOf(this.layers,layer)!=-1){ this.resetRoots(); this.collectRoots(); } }, CLASS_NAME:"OpenLayers.Control.MultipleLayersSelectFeature" }); OpenLayers.Control.MultipleLayersModifyFeature=OpenLayers.Class(OpenLayers.Control,{ geometryTypes:null, clickout:true, toggle:true, layer:null, feature:null, vertices:null, virtualVertices:null, selectControl:null, dragControl:null, handlers:null, deleteCodes:null, virtualStyle:null, mode:null, radiusHandle:null, dragHandle:null, onModificationStart:function(){}, onModification:function(){}, onModificationEnd:function(){}, layers:null, initialize:function(layers,options){ if(!(layers instanceof Array)) { layers=[layers]; } this.layers=layers; this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,{ displayInLayerSwitcher:false, display:function(){}, getFeatureFromEvent:function(evt) { var feature; for(var i=0;i<layers.length;i++) { feature=layers[i].getFeatureFromEvent(evt); if(feature){ return feature; } } } }); this.vertices=[]; this.virtualVertices=[]; this.virtualStyle=OpenLayers.Util.extend({},this.layers[0].style||this.layers[0].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; var selectOptions={geometryTypes:this.geometryTypes,clickout:this.clickout,toggle:this.toggle}; this.selectControl=new OpenLayers.Control.MultipleLayersSelectFeature(this.layers,selectOptions); for(var i=0;i<this.layers.length;i++) { this.layers[i].events.on({ "beforefeatureselected":this.beforeSelectFeature, "featureselected":this.selectFeature, "featureunselected":this.unselectFeature, /* Added eventhandling to prevent a feature being registered if layer is reloaded */"loadstart":this.unselectFeature, scope:this }); } var dragOptions={/* Removed geometryType Point to enable draging of other types. Was: geometryTypes:["OpenLayers.Geometry.Point"]*/geometryTypes:null, snappingOptions:this.snappingOptions, onStart:function(feature,pixel){control.dragStart.apply(control,[feature,pixel]);}, onDrag:function(feature){control.dragVertex.apply(control,[feature]);}, onComplete:function(feature){control.dragComplete.apply(control,[feature]);} }; this.dragControl=new OpenLayers.Control.MultipleLayersDragFeature(this.layers[0],dragOptions); var keyboardOptions={keydown:this.handleKeypress}; this.handlers={keyboard:new OpenLayers.Handler.Keyboard(this,keyboardOptions)}; }, destroy:function(){ for(var i=0;i<this.layers.length;i++) { this.layers[i].events.un({ "beforefeatureselected":this.beforeSelectFeature, "featureselected":this.selectFeature, "featureunselected":this.unselectFeature, /* Added eventhandling to prevent a feature being registered if layer is reloaded */"loadstart":this.unselectFeature, scope:this }); } this.layer.destroy(); this.selectControl.destroy(); this.dragControl.destroy(); OpenLayers.Control.prototype.destroy.apply(this,[]); }, activate:function(){ return(this.selectControl.activate()&&this.handlers.keyboard.activate()&&OpenLayers.Control.prototype.activate.apply(this,arguments));}, deactivate:function(){ var deactivated=false; if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){ for(var i=0;i<this.layers.length;i++) { this.layers[i].removeFeatures(this.vertices,{silent:true}); this.layers[i].removeFeatures(this.virtualVertices,{silent:true}); } this.vertices=[]; this.dragControl.deactivate(); if(this.feature&&this.feature.geometry){ this.selectControl.unselect.apply(this.selectControl,[this.feature]); } this.selectControl.deactivate(); this.handlers.keyboard.deactivate(); deactivated=true; } return deactivated; }, beforeSelectFeature:function(object){ return object.feature.layer.events.triggerEvent("beforefeaturemodified",{feature:object.feature}); }, selectFeature:function(object){ this.feature=object.feature; this.resetVertices(); this.dragControl.activate(this.feature.layer); this.onModificationStart(this.feature); }, unselectFeature:function(object){ for(var i=0;i<this.layers.length;i++) { this.layers[i].removeFeatures(this.vertices,{silent:true}); this.layers[i].destroyFeatures(this.virtualVertices,{silent:true}); } this.vertices=[]; this.virtualVertices=[]; if(this.dragHandle){ for(var i=0;i<this.layers.length;i++) { this.layers[i].destroyFeatures([this.dragHandle],{silent:true}); } delete this.dragHandle; } if(this.radiusHandle){ for(var i=0;i<this.layers.length;i++) { this.layers[i].destroyFeatures([this.radiusHandle],{silent:true}); } delete this.radiusHandle; } this.feature=null; this.dragControl.deactivate(); this.onModificationEnd(object.feature); for(var i=0;i<this.layers.length;i++) { this.layers[i].events.triggerEvent("afterfeaturemodified",{feature:object.feature}); } }, dragStart:function(feature,pixel){ if(feature!=this.feature&&!feature.geometry.parent&&feature!=this.dragHandle&&feature!=this.radiusHandle){ if(this.feature){ this.selectControl.clickFeature.apply(this.selectControl,[this.feature]); } if(this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)!=-1){ this.selectControl.clickFeature.apply(this.selectControl,[feature]); 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; } } }, dragVertex:function(vertex){ if(this.feature.geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){ if(this.feature!=vertex){ this.feature=vertex; } }else{ if(vertex._index){ vertex.geometry.parent.addComponent(vertex.geometry,vertex._index); delete vertex._index; OpenLayers.Util.removeItem(this.virtualVertices,vertex); this.vertices.push(vertex); }else if( vertex==this.dragHandle){ this.feature.layer.removeFeatures(this.vertices,{silent:true}); this.vertices=[]; if(this.radiusHandle){ this.feature.layer.destroyFeatures([this.radiusHandle],{silent:true}); this.radiusHandle=null; } } if(this.virtualVertices.length>0){ this.feature.layer.destroyFeatures(this.virtualVertices,{silent:true}); this.virtualVertices=[]; } this.feature.layer.drawFeature(this.feature,this.selectControl.renderIntent); } this.feature.layer.drawFeature(vertex); }, dragComplete:function(vertex){ this.resetVertices(); this.onModification(this.feature); this.feature.layer.events.triggerEvent("featuremodified",{feature:this.feature}); }, resetVertices:function(){ if(this.dragControl.feature){ this.dragControl.outFeature(this.dragControl.feature); } if(this.vertices.length>0){ for(var i=0;i<this.layers.length;i++) { this.layers[i].removeFeatures(this.vertices,{silent:true}); } this.vertices=[]; } if(this.virtualVertices.length>0){ for(var i=0;i<this.layers.length;i++) { this.layers[i].removeFeatures(this.virtualVertices,{silent:true}); } this.virtualVertices=[]; } if(this.dragHandle){ for(var i=0;i<this.layers.length;i++) { this.layers[i].destroyFeatures([this.dragHandle],{silent:true}); } this.dragHandle=null; } if(this.radiusHandle){ for(var i=0;i<this.layers.length;i++) { this.layers[i].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)){ this.collectVertices(); } } }, handleKeypress:function(evt){ var code=evt.keyCode; 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){ vertex.geometry.parent.removeComponent(vertex.geometry); this.feature.layer.drawFeature(this.feature,this.selectControl.renderIntent); this.resetVertices(); this.onModification(this.feature); this.feature.layer.events.triggerEvent("featuremodified",{feature:this.feature}); } } }, 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); 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); control.vertices.push(vertex); }else{ collectComponentVertices(component); } } 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); point.geometry.parent=geometry; point._index=i+1; control.virtualVertices.push(point); } } } } } collectComponentVertices.call(this,this.feature.geometry); this.feature.layer.addFeatures(this.virtualVertices,{silent:true}); this.feature.layer.addFeatures(this.vertices,{silent:true}); }, 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.feature.layer.addFeatures([this.dragHandle],{silent:true}); }, 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 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 l0=Math.sqrt((dx0*dx0)+(dy0*dy0)); var l1=Math.sqrt((dx1*dx1)+(dy1*dy1)); geometry.resize(l1/l0,originGeometry); } }; this.radiusHandle=radius; this.feature.layer.addFeatures([this.radiusHandle],{silent:true}); }, setMap:function(map){ this.selectControl.setMap(map); this.dragControl.setMap(map); OpenLayers.Control.prototype.setMap.apply(this,arguments); }, CLASS_NAME:"OpenLayers.Control.MultipleLayersModifyFeature" }); OpenLayers.Control.MultipleLayersDragFeature = OpenLayers.Class(OpenLayers.Control, { geometryTypes: null, onStart: function(feature, pixel) {}, onDrag: function(feature, pixel) {}, onComplete: function(feature, pixel) {}, layer: null, feature: null, dragCallbacks: {}, featureCallbacks: {}, lastPixel: null, initialize: function(layer, options) { OpenLayers.Control.prototype.initialize.apply(this, [options]); this.layer = layer; this.handlers = { drag: new OpenLayers.Handler.Drag( this, OpenLayers.Util.extend({ down: this.downFeature, move: this.moveFeature, up: this.upFeature, out: this.cancel, done: this.doneDragging }, this.dragCallbacks) ), feature: new OpenLayers.Handler.Feature( this, this.layer, OpenLayers.Util.extend({ over: this.overFeature, out: this.outFeature }, this.featureCallbacks), {geometryTypes: this.geometryTypes} ) }; }, destroy: function() { this.layer = null; OpenLayers.Control.prototype.destroy.apply(this, []); }, activate: function(layer) { if (layer != this.layer) { this.layer = layer; this.handlers.feature.deactivate(); delete this.handlers.feature; this.handlers.feature = new OpenLayers.Handler.Feature( this, this.layer, OpenLayers.Util.extend({ over: this.overFeature, out: this.outFeature }, this.featureCallbacks), {geometryTypes: this.geometryTypes} ); } return (this.handlers.feature.activate() && OpenLayers.Control.prototype.activate.apply(this, arguments)); }, deactivate: function() { // the return from the handlers is unimportant in this case this.handlers.drag.deactivate(); this.handlers.feature.deactivate(); this.feature = null; this.dragging = false; this.lastPixel = null; return OpenLayers.Control.prototype.deactivate.apply(this, arguments); }, overFeature: function(feature) { if(!this.handlers.drag.dragging) { this.feature = feature; this.handlers.drag.activate(); this.over = true; // TBD replace with CSS classes this.map.div.style.cursor = "move"; } else { if(this.feature.id == feature.id) { this.over = true; } else { this.over = false; } } }, downFeature: function(pixel) { this.lastPixel = pixel; this.onStart(this.feature, pixel); }, moveFeature: function(pixel) { var res = this.map.getResolution(); this.feature.geometry.move(res * (pixel.x - this.lastPixel.x), res * (this.lastPixel.y - pixel.y)); this.layer.drawFeature(this.feature); this.lastPixel = pixel; this.onDrag(this.feature, pixel); }, upFeature: function(pixel) { if(!this.over) { this.handlers.drag.deactivate(); this.feature = null; // TBD replace with CSS classes this.map.div.style.cursor = "default"; } else { // the drag handler itself resetted the cursor, so // set it back to "move" here this.map.div.style.cursor = "move"; } }, doneDragging: function(pixel) { this.onComplete(this.feature, pixel); }, outFeature: function(feature) { if(!this.handlers.drag.dragging) { this.over = false; this.handlers.drag.deactivate(); // TBD replace with CSS classes this.map.div.style.cursor = "default"; this.feature = null; } else { if(this.feature.id == feature.id) { this.over = false; } } }, cancel: function() { this.handlers.drag.deactivate(); this.over = false; }, setMap: function(map) { this.handlers.drag.setMap(map); this.handlers.feature.setMap(map); OpenLayers.Control.prototype.setMap.apply(this, arguments); }, CLASS_NAME: "OpenLayers.Control.MultipleLayersDragFeature" });
_______________________________________________ Dev mailing list Dev@openlayers.org http://openlayers.org/mailman/listinfo/dev