#805 - all geometries now know how to rotate - see the examples/rotate-features.html for geometry.rotate in action

git-svn-id: http://svn.openlayers.org/trunk/openlayers@3602 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Tim Schaub
2007-07-05 22:03:27 +00:00
parent debca7c477
commit dcffa03e7d
6 changed files with 207 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#map {
width: 500px;
height: 350px;
border: 1px solid #ccc;
}
p {
width: 500px;
}
</style>
<script src="../lib/OpenLayers.js"></script>
<script type="text/javascript">
<!--
var map, pointFeature, lineFeature, polygonFeature;
function init(){
map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );
map.addLayer(layer);
var style_blue = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
style_blue.strokeColor = "blue";
style_blue.fillColor = "blue";
var style_green = {
strokeColor: "#339933",
strokeOpacity: 1,
strokeWidth: 3,
pointRadius: 6,
pointerEvents: "visiblePainted"
};
var vectorLayer = new OpenLayers.Layer.Vector("Simple Geometry");
// create a point feature
var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
pointFeature = new OpenLayers.Feature.Vector(point, null, style_blue);
// create a line feature from a list of points
var pointList = [];
var newPoint = point;
for(var p=0; p<5; ++p) {
newPoint = new OpenLayers.Geometry.Point(newPoint.x + Math.random(1),
newPoint.y + Math.random(1));
pointList.push(newPoint);
}
lineFeature = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.LineString(pointList),null,style_green);
// create a polygon feature from a linear ring of points
var pointList = [];
for(var p=0; p<6; ++p) {
var a = p * (2 * Math.PI) / 7;
var r = Math.random(1) + 1;
var newPoint = new OpenLayers.Geometry.Point(point.x + (r * Math.cos(a)),
point.y + (r * Math.sin(a)));
pointList.push(newPoint);
}
pointList.push(pointList[0]);
var linearRing = new OpenLayers.Geometry.LinearRing(pointList);
polygonFeature = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Polygon([linearRing]));
map.addLayer(vectorLayer);
map.setCenter(new OpenLayers.LonLat(point.x, point.y), 5);
vectorLayer.addFeatures([pointFeature, lineFeature, polygonFeature]);
// start rotating
var origin = new OpenLayers.Geometry.Point(-110, 45);
window.setInterval(rotateFeature, 100,
pointFeature, Math.PI / 10, origin);
window.setInterval(rotateFeature, 100,
lineFeature, Math.PI / 20, origin);
window.setInterval(rotateFeature, 100,
polygonFeature, -1 * Math.PI / 10, origin);
}
function rotateFeature(feature, angle, origin) {
feature.geometry.rotate(angle, origin);
feature.layer.drawFeature(feature);
}
// -->
</script>
</head>
<body onload="init()">
<div id="map"></div>
<p>This example shows a few features rotating. There is not yet a control
built that provides a tool for rotating, but the geometry.rotate method
can be accessed to rotate programmatically.</p>
</body>
</html>

View File

@@ -245,6 +245,21 @@ OpenLayers.Geometry.Collection.prototype =
} }
}, },
/**
* APIMethod: rotate
* Rotate a geometry around some origin
*
* Parameters:
* angle - {Float} Rotation angle in radians (measured counterclockwise
* from the positive x-axis)
* origin - {OpenLayers.Geometry.Point} Center point for the rotation
*/
rotate: function(angle, origin) {
for(var i=0; i<this.components.length; ++i) {
this.components[i].rotate(angle, origin);
}
},
/** /**
* APIMethod: equals * APIMethod: equals
* Tests for equivalent geometries * Tests for equivalent geometries

View File

@@ -132,6 +132,22 @@ OpenLayers.Geometry.Point.prototype =
this.y = this.y + y; this.y = this.y + y;
}, },
/**
* APIMethod: rotate
* Rotate a point around another
*
* Parameters:
* angle - {Float} Rotation angle in radians (measured counterclockwise
* from the positive x-axis)
* origin - {OpenLayers.Geometry.Point} Center point for the rotation
*/
rotate: function(angle, origin) {
var radius = this.distanceTo(origin);
var theta = angle + Math.atan2(this.y - origin.y, this.x - origin.x);
this.x = origin.x + (radius * Math.cos(theta));
this.y = origin.y + (radius * Math.sin(theta));
},
/** @final @type String */ /** @final @type String */
CLASS_NAME: "OpenLayers.Geometry.Point" CLASS_NAME: "OpenLayers.Geometry.Point"
}); });

View File

@@ -77,6 +77,35 @@
t.eq(line.components[1].y, y1 + dy, "move() correctly modifies second y"); t.eq(line.components[1].y, y1 + dy, "move() correctly modifies second y");
} }
function test_LineString_rotate(t) {
t.plan(6);
var components = [new OpenLayers.Geometry.Point(10,15),
new OpenLayers.Geometry.Point(0,0)];
var geometry = new OpenLayers.Geometry.LineString(components);
var originals = [];
var comp;
var angle = 2 * Math.PI * Math.random();
var origin = new OpenLayers.Geometry.Point(10 * Math.random(),
10 * Math.random());
for(var i=0; i<geometry.components.length; ++i) {
comp = geometry.components[i];
originals[i] = comp.rotate;
comp.rotate = function(a, o) {
t.ok(true, "rotate called for component " + i);
t.ok(a == angle, "rotate called with correct angle");
t.ok(o == origin, "rotate called with correct origin");
}
}
geometry.rotate(angle, origin);
// restore the original rotate defs
for(var i=0; i<geometry.components.length; ++i) {
comp.rotate = originals[i];
}
}
function test_LineString_equals(t) { function test_LineString_equals(t) {
t.plan(3); t.plan(3);

View File

@@ -79,6 +79,30 @@
t.eq(point.y, y + dy, "move() correctly modifies y"); t.eq(point.y, y + dy, "move() correctly modifies y");
} }
function test_Point_rotate(t) {
t.plan(4);
var tolerance = 1e-10;
var x = 10;
var y = 20;
var point = new OpenLayers.Geometry.Point(x, y);
var origin = new OpenLayers.Geometry.Point(5, 10);
// rotate a full revolution
point.rotate(2 * Math.PI, origin);
t.ok(((point.x - x) / x) < tolerance,
"rotate by 2 * Math.PI returns to the same y");
t.ok(((point.y - y) / y) < tolerance,
"rotate by 2 * Math.PI returns to the same y")
// rotate an 1/8 turn
point.rotate(Math.PI / 4, origin);
t.ok(((point.x - 1.4644660940672636) / 1.4644660940672636) < tolerance,
"rotate 1/8 turn correctly");
t.ok(((point.y - 20.606601717798213) / 20.606601717798213) < tolerance,
"rotate 1/8 turn correctly")
}
function test_Point_equals(t) { function test_Point_equals(t) {
t.plan(3); t.plan(3);

View File

@@ -106,6 +106,33 @@
t.eq(polygon.components[1].components[0].y, y2 + dy, "move() correctly modifies second y"); t.eq(polygon.components[1].components[0].y, y2 + dy, "move() correctly modifies second y");
} }
function test_Polygon_rotate(t) {
t.plan(6);
var geometry = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);
var originals = [];
var comp;
var angle = 2 * Math.PI * Math.random();
var origin = new OpenLayers.Geometry.Point(10 * Math.random(),
10 * Math.random());
for(var i=0; i<geometry.components.length; ++i) {
comp = geometry.components[i];
originals[i] = comp.rotate;
comp.rotate = function(a, o) {
t.ok(true, "rotate called for component " + i);
t.ok(a == angle, "rotate called with correct angle");
t.ok(o == origin, "rotate called with correct origin");
}
}
geometry.rotate(angle, origin);
// restore the original rotate defs
for(var i=0; i<geometry.components.length; ++i) {
comp.rotate = originals[i];
}
}
function test_Polygon_equals(t) { function test_Polygon_equals(t) {
t.plan(3); t.plan(3);