adding irregular option to regular polygon control - now, go draw rectangles, and more - thanks for the review elem (closes #1098).
git-svn-id: http://svn.openlayers.org/trunk/openlayers@5200 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -66,6 +66,7 @@
|
|||||||
map.setCenter(new OpenLayers.LonLat(0, 0), 3);
|
map.setCenter(new OpenLayers.LonLat(0, 0), 3);
|
||||||
|
|
||||||
document.getElementById('noneToggle').checked = true;
|
document.getElementById('noneToggle').checked = true;
|
||||||
|
document.getElementById('irregularToggle').checked = false;
|
||||||
}
|
}
|
||||||
function setOptions(options) {
|
function setOptions(options) {
|
||||||
polygonControl.handler.setOptions(options);
|
polygonControl.handler.setOptions(options);
|
||||||
@@ -146,6 +147,16 @@
|
|||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
irregular
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="irregularToggle" name="irregular"
|
||||||
|
type="checkbox"
|
||||||
|
onchange="setOptions({irregular: this.checked})") />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -156,5 +167,7 @@
|
|||||||
the snap angle is non-null) and you hold down the <b>Shift</b> key, you
|
the snap angle is non-null) and you hold down the <b>Shift</b> key, you
|
||||||
will toggle to non-snapping mode.
|
will toggle to non-snapping mode.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
The <i>irregular</i> option allows drawing of irregular polygons. With this option, the fixed radius option is ignored.
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -269,10 +269,11 @@ OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {
|
|||||||
* (lines, for example, will be twice as long, and polygons
|
* (lines, for example, will be twice as long, and polygons
|
||||||
* will have four times the area).
|
* will have four times the area).
|
||||||
* origin - {<OpenLayers.Geometry.Point>} Point of origin for resizing
|
* origin - {<OpenLayers.Geometry.Point>} 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<this.components.length; ++i) {
|
for(var i=0; i<this.components.length; ++i) {
|
||||||
this.components[i].resize(scale, origin);
|
this.components[i].resize(scale, origin, ratio);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -145,10 +145,11 @@ OpenLayers.Geometry.LinearRing = OpenLayers.Class(
|
|||||||
* (lines, for example, will be twice as long, and polygons
|
* (lines, for example, will be twice as long, and polygons
|
||||||
* will have four times the area).
|
* will have four times the area).
|
||||||
* origin - {<OpenLayers.Geometry.Point>} Point of origin for resizing
|
* origin - {<OpenLayers.Geometry.Point>} 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<this.components.length - 1; ++i) {
|
for(var i=0; i<this.components.length - 1; ++i) {
|
||||||
this.components[i].resize(scale, origin);
|
this.components[i].resize(scale, origin, ratio);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -160,10 +160,11 @@ OpenLayers.Geometry.Point = OpenLayers.Class(OpenLayers.Geometry, {
|
|||||||
* distance from the origin. A scale of 2 doubles the
|
* distance from the origin. A scale of 2 doubles the
|
||||||
* distance between the point and origin.
|
* distance between the point and origin.
|
||||||
* origin - {<OpenLayers.Geometry.Point>} Point of origin for resizing
|
* origin - {<OpenLayers.Geometry.Point>} 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) {
|
||||||
this.x = origin.x + (scale * (this.x - origin.x));
|
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.y = origin.y + (scale * (this.y - origin.y));
|
||||||
this.clearBounds();
|
this.clearBounds();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -62,6 +62,18 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, {
|
|||||||
*/
|
*/
|
||||||
persist: false,
|
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
|
* Property: angle
|
||||||
* {Float} The angle from the origin (mouse down) to the current mouse
|
* {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);
|
var maploc = this.map.getLonLatFromPixel(evt.xy);
|
||||||
this.origin = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);
|
this.origin = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);
|
||||||
// create the new polygon
|
// create the new polygon
|
||||||
if(!this.fixedRadius) {
|
if(!this.fixedRadius || this.irregular) {
|
||||||
// smallest radius should not be less one pixel in map units
|
// smallest radius should not be less one pixel in map units
|
||||||
// VML doesn't behave well with smaller
|
// VML doesn't behave well with smaller
|
||||||
this.radius = this.map.getResolution();
|
this.radius = this.map.getResolution();
|
||||||
@@ -218,7 +230,10 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, {
|
|||||||
move: function(evt) {
|
move: function(evt) {
|
||||||
var maploc = this.map.getLonLatFromPixel(evt.xy);
|
var maploc = this.map.getLonLatFromPixel(evt.xy);
|
||||||
var point = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);
|
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;
|
this.origin = point;
|
||||||
} else {
|
} else {
|
||||||
this.calculateAngle(point, evt);
|
this.calculateAngle(point, evt);
|
||||||
@@ -226,6 +241,18 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, {
|
|||||||
point.distanceTo(this.origin));
|
point.distanceTo(this.origin));
|
||||||
}
|
}
|
||||||
this.modifyGeometry();
|
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);
|
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 the number of sides ever changes, create a new geometry
|
||||||
if(ring.components.length != (this.sides + 1)) {
|
if(ring.components.length != (this.sides + 1)) {
|
||||||
this.createGeometry();
|
this.createGeometry();
|
||||||
|
ring = this.feature.geometry.components[0];
|
||||||
}
|
}
|
||||||
for(var i=0; i<this.sides; ++i) {
|
for(var i=0; i<this.sides; ++i) {
|
||||||
point = ring.components[i];
|
point = ring.components[i];
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_Point_resize(t) {
|
function test_Point_resize(t) {
|
||||||
t.plan(3);
|
t.plan(5);
|
||||||
|
|
||||||
var tolerance = 1e-10;
|
var tolerance = 1e-10;
|
||||||
var x = 100 * Math.random();
|
var x = 100 * Math.random();
|
||||||
@@ -134,6 +134,13 @@
|
|||||||
|
|
||||||
t.ok(point.bounds == null, "bounds is correctly cleared after a resize()");
|
t.ok(point.bounds == null, "bounds is correctly cleared after a resize()");
|
||||||
|
|
||||||
|
// resize with non uniform scaling (ratio != 1)
|
||||||
|
point = new OpenLayers.Geometry.Point(10, 10);
|
||||||
|
origin = new OpenLayers.Geometry.Point(0, 0);
|
||||||
|
point.resize(2, origin, 4);
|
||||||
|
t.eq(point.x, 80, "non-uniform scaling correctly applied in x dim");
|
||||||
|
t.eq(point.y, 20, "non-uniform scaling correctly applied in y dim");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_Point_equals(t) {
|
function test_Point_equals(t) {
|
||||||
|
|||||||
@@ -142,6 +142,46 @@
|
|||||||
"bounds with manual radius setting and mousemove");
|
"bounds with manual radius setting and mousemove");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_Handler_RegularPolygon_irregular(t) {
|
||||||
|
t.plan(4);
|
||||||
|
var map = {
|
||||||
|
getLonLatFromPixel: function(px) {
|
||||||
|
return {lon: px.x, lat: px.y};
|
||||||
|
},
|
||||||
|
getResolution: function() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var layer = {
|
||||||
|
addFeatures: function() {},
|
||||||
|
drawFeature: function(feature, style) {
|
||||||
|
var ring = feature.geometry.components[0];
|
||||||
|
t.eq(ring.components[0].x, 20, "correct right");
|
||||||
|
t.eq(ring.components[0].y, 10, "correct bottom");
|
||||||
|
t.eq(ring.components[2].x, 10, "correct left");
|
||||||
|
t.eq(ring.components[2].y, 15, "correct top");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var control = {};
|
||||||
|
var options = {
|
||||||
|
sides: 4,
|
||||||
|
irregular: true,
|
||||||
|
layer: layer,
|
||||||
|
map: map
|
||||||
|
};
|
||||||
|
var handler = new OpenLayers.Handler.RegularPolygon(
|
||||||
|
control, null, options
|
||||||
|
);
|
||||||
|
handler.origin = new OpenLayers.Geometry.Point(10, 10);
|
||||||
|
handler.feature = new OpenLayers.Feature.Vector(
|
||||||
|
new OpenLayers.Geometry.Polygon(
|
||||||
|
[new OpenLayers.Geometry.LinearRing()]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// should result in a 10 x 5 rectangle
|
||||||
|
handler.move({xy: {x: 20, y: 15}});
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Reference in New Issue
Block a user