diff --git a/examples/regular-polygons.html b/examples/regular-polygons.html index c27e9d064b..9bf2fc40f2 100644 --- a/examples/regular-polygons.html +++ b/examples/regular-polygons.html @@ -66,6 +66,7 @@ map.setCenter(new OpenLayers.LonLat(0, 0), 3); document.getElementById('noneToggle').checked = true; + document.getElementById('irregularToggle').checked = false; } function setOptions(options) { polygonControl.handler.setOptions(options); @@ -146,6 +147,16 @@ + + + irregular + + + + + @@ -156,5 +167,7 @@ the snap angle is non-null) and you hold down the Shift key, you will toggle to non-snapping mode.

+

+ The irregular option allows drawing of irregular polygons. With this option, the fixed radius option is ignored. diff --git a/lib/OpenLayers/Geometry/Collection.js b/lib/OpenLayers/Geometry/Collection.js index c4d63e998c..2a7f85eb40 100644 --- a/lib/OpenLayers/Geometry/Collection.js +++ b/lib/OpenLayers/Geometry/Collection.js @@ -269,10 +269,11 @@ OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, { * (lines, for example, will be twice as long, and polygons * will have four times the area). * origin - {} Point of origin for resizing + * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1. */ - resize: function(scale, origin) { + resize: function(scale, origin, ratio) { for(var i=0; i} Point of origin for resizing + * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1. */ - resize: function(scale, origin) { + resize: function(scale, origin, ratio) { for(var i=0; i} Point of origin for resizing + * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1. */ - resize: function(scale, origin) { - this.x = origin.x + (scale * (this.x - origin.x)); - + resize: function(scale, origin, ratio) { + ratio = (ratio == undefined) ? 1 : ratio; + this.x = origin.x + (scale * ratio * (this.x - origin.x)); this.y = origin.y + (scale * (this.y - origin.y)); this.clearBounds(); }, diff --git a/lib/OpenLayers/Handler/RegularPolygon.js b/lib/OpenLayers/Handler/RegularPolygon.js index c5164d5931..f90b214ae5 100644 --- a/lib/OpenLayers/Handler/RegularPolygon.js +++ b/lib/OpenLayers/Handler/RegularPolygon.js @@ -62,6 +62,18 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, { */ persist: false, + /** + * APIProperty: irregular + * {Boolean} Draw an irregular polygon instead of a regular polygon. + * Default is false. If true, the initial mouse down will represent + * one corner of the polygon bounds and with each mouse movement, the + * polygon will be stretched so the opposite corner of its bounds + * follows the mouse position. This property takes precedence over + * the radius property. If set to true, the radius property will + * be ignored. + */ + irregular: false, + /** * Property: angle * {Float} The angle from the origin (mouse down) to the current mouse @@ -194,7 +206,7 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, { var maploc = this.map.getLonLatFromPixel(evt.xy); this.origin = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat); // create the new polygon - if(!this.fixedRadius) { + if(!this.fixedRadius || this.irregular) { // smallest radius should not be less one pixel in map units // VML doesn't behave well with smaller this.radius = this.map.getResolution(); @@ -218,7 +230,10 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, { move: function(evt) { var maploc = this.map.getLonLatFromPixel(evt.xy); var point = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat); - if(this.fixedRadius) { + if(this.irregular) { + var ry = Math.sqrt(2) * Math.abs(point.y - this.origin.y) / 2; + this.radius = Math.max(this.map.getResolution() / 2, ry); + } else if(this.fixedRadius) { this.origin = point; } else { this.calculateAngle(point, evt); @@ -226,6 +241,18 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, { point.distanceTo(this.origin)); } this.modifyGeometry(); + if(this.irregular) { + var dx = point.x - this.origin.x; + var dy = point.y - this.origin.y; + var ratio; + if(dy == 0) { + ratio = dx / (this.radius * Math.sqrt(2)); + } else { + ratio = dx / dy; + } + this.feature.geometry.resize(1, this.origin, ratio); + this.feature.geometry.move(dx / 2, dy / 2); + } this.layer.drawFeature(this.feature, this.style); }, @@ -277,6 +304,7 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, { // if the number of sides ever changes, create a new geometry if(ring.components.length != (this.sides + 1)) { this.createGeometry(); + ring = this.feature.geometry.components[0]; } for(var i=0; i