Created a TransformFeature control and added a documentDrag option to the DragFeature control. r=elemoine (closes #2433)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@9999 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
ahocevar
2010-01-31 14:08:36 +00:00
parent 7a78237bdd
commit cb0dffc045
6 changed files with 779 additions and 1 deletions

View File

@@ -0,0 +1,105 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>OpenLayers: Transformation Box</title>
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="style.css" type="text/css" />
<script src="../lib/OpenLayers.js" type="text/javascript"></script>
<script type="text/javascript">
var map, control;
function init(){
map = new OpenLayers.Map('map', {allOverlays: true});
// context for appropriate scale/resize cursors
var cursors = ["sw-resize", "s-resize", "se-resize",
"e-resize", "ne-resize", "n-resize", "nw-resize", "w-resize"];
var context = {
getCursor: function(feature){
var i = OpenLayers.Util.indexOf(control.handles, feature);
var cursor = "inherit";
if(i !== -1) {
i = (i + 8 + Math.round(control.rotation / 90) * 2) % 8;
cursor = cursors[i];
}
return cursor;
}
};
// a nice style for the transformation box
var style = new OpenLayers.Style({
cursor: "${getCursor}",
pointRadius: 5,
fillColor: "white",
fillOpacity: 1,
strokeColor: "black"
}, {context: context});
// the layer that we want to transform features on
var vectorLayer = new OpenLayers.Layer.Vector("Simple Geometry", {
styleMap: new OpenLayers.StyleMap({
"transform": style
})
});
// create the TransformFeature control, using the renderIntent
// from above
control = new OpenLayers.Control.TransformFeature(vectorLayer, {
renderIntent: "transform"
});
map.addControl(control);
// create a polygon feature from a linear ring of points
var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
var pointList = [];
for(var p=0; p<6; ++p) {
var a = p * (2 * Math.PI) / 7;
var r = Math.random(1) + 2;
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);
var polygonFeature = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Polygon([linearRing]));
map.addLayer(vectorLayer);
map.setCenter(new OpenLayers.LonLat(point.x, point.y), 5);
var anotherFeature = polygonFeature.clone();
polygonFeature.geometry.move(-3, 0);
anotherFeature.geometry.move(3, 0);
vectorLayer.addFeatures([polygonFeature, anotherFeature]);
// start with the transformation box on polygonFeature
control.setFeature(polygonFeature, {rotation: 45, scale: 0.5, ratio: 1.5});
}
</script>
</head>
<body onload="init()">
<h1 id="title">Vector Feature Transformation Box Example</h1>
<div id="tags">
</div>
<p id="shortdesc">
Shows the use of the TransformFeature control.
</p>
<div style="text-align: right">
<div dir="rtl" id="map" class="smallmap"></div>
</div>
<div id="docs">
<p>This example shows transformation of vector features with a
tranformation box. Grab one of the handles to resize the feature.
Holding the SHIFT key will preserve the aspect ratio. Position the
mouse right outside one of the corner handles to rotate the feature,
and hold the SHIFT key to only rotate in 45<34> increments.</p>
<p>In this example, the transformation box has been set on the left
feature, with a rotation preset of 45<34>. Clicking on the right feature
will set it for transformation, starting with an unrotated box.
Dragging a feature or the box edges will move it around.</p>
</div>
</body>
</html>

View File

@@ -178,6 +178,7 @@
"OpenLayers/Control/Measure.js",
"OpenLayers/Control/WMSGetFeatureInfo.js",
"OpenLayers/Control/Graticule.js",
"OpenLayers/Control/TransformFeature.js",
"OpenLayers/Geometry.js",
"OpenLayers/Geometry/Rectangle.js",
"OpenLayers/Geometry/Collection.js",

View File

@@ -64,6 +64,13 @@ OpenLayers.Control.DragFeature = OpenLayers.Class(OpenLayers.Control, {
*/
onComplete: function(feature, pixel) {},
/**
* APIProperty: documentDrag
* {Boolean} If set to true, mouse dragging will continue even if the
* mouse cursor leaves the map viewport. Default is false.
*/
documentDrag: false,
/**
* Property: layer
* {<OpenLayers.Layer.Vector>}
@@ -115,7 +122,9 @@ OpenLayers.Control.DragFeature = OpenLayers.Class(OpenLayers.Control, {
up: this.upFeature,
out: this.cancel,
done: this.doneDragging
}, this.dragCallbacks)
}, this.dragCallbacks), {
documentDrag: this.documentDrag
}
),
feature: new OpenLayers.Handler.Feature(
this, this.layer, OpenLayers.Util.extend({

View File

@@ -0,0 +1,579 @@
/* Copyright (c) 2009 MetaCarta, Inc., 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.js
* @requires OpenLayers/Control/DragFeature.js
* @requires OpenLayers/Feature/Vector.js
* @requires OpenLayers/Geometry/LineString.js
* @requires OpenLayers/Geometry/Point.js
*/
/**
* Class: OpenLayers.Control.TransformFeature
* Control to transform features with a standard transformation box.
*
* Inherits From:
* - <OpenLayers.Control>
*/
OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, {
/**
* Constant: EVENT_TYPES
*
* Supported event types:
* - *beforesetfeature* Triggered before a feature is set for
* tranformation. The feature will not be set if a listener returns
* false. Listeners receive a *feature* property, with the feature
* that will be set for transformation. Listeners are allowed to
* set the control's *scale*, *ratio* and *rotation* properties,
* which will set the initial scale, ratio and rotation of the
* feature, like the <setFeature> method's initialParams argument.
* - *setfeature* Triggered when a feature is set for tranformation.
* Listeners receive a *feature* property, with the feature that
* is now set for transformation.
* - *beforetransform* Triggered while dragging, before a feature is
* transformed. The feature will not be transformed if a listener
* returns false (but the box still will). Listeners receive one or
* more of *center*, *scale*, *ratio* and *rotation*. The *center*
* property is an <OpenLayers.Geometry.Point> object with the new
* center of the transformed feature, the others are Floats with the
* scale, ratio or rotation change since the last transformation.
* - *transform* Triggered while dragging, when a feature is transformed.
* Listeners receive an event object with one or more of *center*,
* *scale*, *ratio* and *rotation*. The *center* property is an
* <OpenLayers.Geometry.Point> object with the new center of the
* transformed feature, the others are Floats with the scale, ratio
* or rotation change of the feature since the last transformation.
* - *transformcomplete" Triggered after dragging. Listeners receive
* an event object with the transformed *feature*.
*/
EVENT_TYPES: ["beforesetfeature", "setfeature", "beforetransform",
"transform", "transformcomplete"],
/**
* APIProperty: geometryTypes
* {Array(String)} To restrict transformation to a limited set of geometry
* types, send a list of strings corresponding to the geometry class
* names.
*/
geometryTypes: null,
/**
* Property: layer
* {<OpenLayers.Layer.Vector>}
*/
layer: null,
/**
* APIProperty: preserveAspectRatio
* {Boolean} set to true to not change the feature's aspect ratio.
*/
preserveAspectRatio: false,
/**
* APIProperty: rotate
* {Boolean} set to false if rotation should be disabled. Default is true.
* To be passed with the constructor or set when the control is not
* active.
*/
rotate: true,
/**
* APIProperty: feature
* {<OpenLayers.Feature.Vector>} Feature currently available for
* transformation. Read-only, use <setFeature> to set it manually.
*/
feature: null,
/**
* APIProperty: renderIntent
* {String|Object} Render intent for the transformation box and
* handles. A symbolizer object can also be provided here.
*/
renderIntent: "temporary",
/**
* APIProperty: rotationHandleSymbolizer
* {Object|String} Optional. A custom symbolizer for the rotation handles.
* A render intent can also be provided here. Defaults to
* (code)
* {
* stroke: false,
* pointRadius: 10,
* fillOpacity: 0,
* cursor: "pointer"
* }
* (end)
*/
rotationHandleSymbolizer: null,
/**
* APIProperty: box
* {<OpenLayers.Feature.Vector>} The transformation box rectangle.
* Read-only.
*/
box: null,
/**
* APIProperty: center
* {<OpenLayers.Geometry.Point>} The center of the feature bounds.
* Read-only.
*/
center: null,
/**
* APIProperty: scale
* {Float} The scale of the feature, relative to the scale the time the
* feature was set. Read-only, except for *beforesetfeature*
* listeners.
*/
scale: 1,
/**
* APIProperty: ratio
* {Float} The ratio of the feature relative to the ratio the time the
* feature was set. Read-only, except for *beforesetfeature*
* listeners.
*/
ratio: 1,
/**
* Property: rotation
* {Integer} the current rotation angle of the box. Read-only, except for
* *beforesetfeature* listeners.
*/
rotation: 0,
/**
* APIProperty: handles
* {Array(<OpenLayers.Feature.Vector>)} The 8 handles currently available
* for scaling/resizing. Numbered counterclockwise, starting from the
* southwest corner. Read-only.
*/
handles: null,
/**
* APIProperty: rotationHandles
* {Array(<OpenLayers.Feature.Vector>)} The 4 rotation handles currently
* available for rotating. Numbered counterclockwise, starting from
* the southwest corner. Read-only.
*/
rotationHandles: null,
/**
* Property: dragControl
* {<OpenLayers.Control.DragFeature>}
*/
dragControl: null,
/**
* Constructor: OpenLayers.Control.TransformFeature
* Create a new transform feature control.
*
* Parameters:
* layer - {<OpenLayers.Layer.Vector>} Layer that contains features that
* will be transformed.
* options - {Object} Optional object whose properties will be set on the
* control.
*/
initialize: function(layer, options) {
// concatenate events specific to this control with those from the base
this.EVENT_TYPES =
OpenLayers.Control.TransformFeature.prototype.EVENT_TYPES.concat(
OpenLayers.Control.prototype.EVENT_TYPES
);
OpenLayers.Control.prototype.initialize.apply(this, [options]);
this.layer = layer;
if(!this.rotationHandleSymbolizer) {
this.rotationHandleSymbolizer = {
stroke: false,
pointRadius: 10,
fillOpacity: 0,
cursor: "pointer"
};
}
this.createBox();
this.createControl();
},
/**
* APIMethod: activate
* Activates the control.
*/
activate: function() {
var activated = false;
if(OpenLayers.Control.prototype.activate.apply(this, arguments)) {
this.dragControl.activate();
this.layer.addFeatures([this.box]);
this.rotate && this.layer.addFeatures(this.rotationHandles);
this.layer.addFeatures(this.handles);
activated = true;
}
return activated;
},
/**
* APIMethod: deactivate
* Deactivates the control.
*/
deactivate: function() {
var deactivated = false;
if(OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
this.layer.removeFeatures(this.handles);
this.rotate && this.layer.removeFeatures(this.rotationHandles);
this.layer.removeFeatures([this.box]);
this.dragControl.deactivate();
deactivated = true;
}
return deactivated;
},
/**
* Method: setMap
*
* Parameters:
* map - {<OpenLayers.Map>}
*/
setMap: function(map) {
this.dragControl.setMap(map);
OpenLayers.Control.prototype.setMap.apply(this, arguments);
},
/**
* APIMethod: setFeature
* Place the transformation box on a feature and start transforming it.
* If the control is not active, it will be activated.
*
* Parameters:
* feature - {<OpenLayers.Feature.Vector>}
* initialParams - {Object} Initial values for rotation, scale or ratio.
* Setting a rotation value here will cause the transformation box to
* start rotated. Setting a scale or ratio will not affect the
* transormation box, but applications may use this to keep track of
* scale and ratio of a feature across multiple transforms.
*/
setFeature: function(feature, initialParams) {
initialParams = OpenLayers.Util.applyDefaults(initialParams, {
rotation: 0,
scale: 1,
ratio: 1
});
var evt = {feature: feature};
var oldRotation = this.rotation;
var oldCenter = this.center;
OpenLayers.Util.extend(this, initialParams);
if(this.events.triggerEvent("beforesetfeature", evt) === false) {
return;
}
this.feature = feature;
this.activate();
this._setfeature = true;
var featureBounds = this.feature.geometry.getBounds();
this.box.move(featureBounds.getCenterLonLat());
this.box.geometry.rotate(-oldRotation, oldCenter);
this._angle = 0;
var ll;
if(this.rotation) {
var geom = feature.geometry.clone();
geom.rotate(-this.rotation, this.center);
var box = new OpenLayers.Feature.Vector(
geom.getBounds().toGeometry());
box.geometry.rotate(this.rotation, this.center);
this.box.geometry.rotate(this.rotation, this.center);
this.box.move(box.geometry.getBounds().getCenterLonLat());
var llGeom = box.geometry.components[0].components[0];
ll = llGeom.getBounds().getCenterLonLat();
} else {
ll = new OpenLayers.LonLat(featureBounds.left, featureBounds.bottom);
}
this.handles[0].move(ll);
delete this._setfeature;
this.events.triggerEvent("setfeature", evt);
},
/**
* Method: createBox
* Creates the box with all handles and transformation handles.
*/
createBox: function() {
var control = this;
this.center = new OpenLayers.Geometry.Point(0, 0);
var box = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.LineString([
new OpenLayers.Geometry.Point(-1, -1),
new OpenLayers.Geometry.Point(0, -1),
new OpenLayers.Geometry.Point(1, -1),
new OpenLayers.Geometry.Point(1, 0),
new OpenLayers.Geometry.Point(1, 1),
new OpenLayers.Geometry.Point(0, 1),
new OpenLayers.Geometry.Point(-1, 1),
new OpenLayers.Geometry.Point(-1, 0),
new OpenLayers.Geometry.Point(-1, -1)
]), null,
typeof this.renderIntent == "string" ? null : this.renderIntent
);
// Override for box move - make sure that the center gets updated
box.geometry.move = function(x, y) {
control._moving = true;
OpenLayers.Geometry.LineString.prototype.move.apply(this, arguments);
control.center.move(x, y);
delete control._moving;
};
// Overrides for vertex move, resize and rotate - make sure that
// handle and rotationHandle geometries are also moved, resized and
// rotated.
var vertexMoveFn = function(x, y) {
OpenLayers.Geometry.Point.prototype.move.apply(this, arguments);
this._rotationHandle && this._rotationHandle.geometry.move(x, y);
this._handle.geometry.move(x, y);
};
var vertexResizeFn = function(scale, center, ratio) {
OpenLayers.Geometry.Point.prototype.resize.apply(this, arguments);
this._rotationHandle && this._rotationHandle.geometry.resize(
scale, center, ratio);
this._handle.geometry.resize(scale, center, ratio);
};
var vertexRotateFn = function(angle, center) {
OpenLayers.Geometry.Point.prototype.rotate.apply(this, arguments);
this._rotationHandle && this._rotationHandle.geometry.rotate(
angle, center);
this._handle.geometry.rotate(angle, center);
};
// Override for handle move - make sure that the box and other handles
// are updated, and finally transform the feature.
var handleMoveFn = function(x, y) {
var oldX = this.x, oldY = this.y;
OpenLayers.Geometry.Point.prototype.move.call(this, x, y);
if(control._moving) {
return;
}
var evt = control.dragControl.handlers.drag.evt;
var preserveAspectRatio = !control._setfeature &&
control.preserveAspectRatio;
var reshape = !preserveAspectRatio && !(evt && evt.shiftKey);
var oldGeom = new OpenLayers.Geometry.Point(oldX, oldY);
var centerGeometry = control.center;
this.rotate(-control.rotation, centerGeometry);
oldGeom.rotate(-control.rotation, centerGeometry);
var dx1 = this.x - centerGeometry.x;
var dy1 = this.y - centerGeometry.y;
var dx0 = dx1 - (this.x - oldGeom.x);
var dy0 = dy1 - (this.y - oldGeom.y);
this.x = oldX;
this.y = oldY;
var scale, ratio = 1;
if (reshape) {
scale = Math.abs(dy0) < 0.00001 ? 1 : dy1 / dy0;
ratio = (Math.abs(dx0) < 0.00001 ? 1 : (dx1 / dx0)) / scale;
} else {
var l0 = Math.sqrt((dx0 * dx0) + (dy0 * dy0));
var l1 = Math.sqrt((dx1 * dx1) + (dy1 * dy1));
scale = l1 / l0;
}
// rotate the box to 0 before resizing - saves us some
// calculations and is inexpensive because we don't drawFeature.
control._moving = true;
control.box.geometry.rotate(-control.rotation, centerGeometry);
delete control._moving;
control.box.geometry.resize(scale, centerGeometry, ratio);
control.box.geometry.rotate(control.rotation, centerGeometry);
control.transformFeature({scale: scale, ratio: ratio});
};
// Override for rotation handle move - make sure that the box and
// other handles are updated, and finally transform the feature.
var rotationHandleMoveFn = function(x, y){
var oldX = this.x, oldY = this.y;
OpenLayers.Geometry.Point.prototype.move.call(this, x, y);
if(control._moving) {
return;
}
var evt = control.dragControl.handlers.drag.evt;
var constrain = (evt && evt.shiftKey) ? 45 : 1;
var centerGeometry = control.center;
var dx1 = this.x - centerGeometry.x;
var dy1 = this.y - centerGeometry.y;
var dx0 = dx1 - x;
var dy0 = dy1 - y;
this.x = oldX;
this.y = oldY;
var a0 = Math.atan2(dy0, dx0);
var a1 = Math.atan2(dy1, dx1);
var angle = a1 - a0;
angle *= 180 / Math.PI;
control._angle = (control._angle + angle) % 360;
var diff = control.rotation % constrain;
if(Math.abs(control._angle) >= constrain || diff !== 0) {
angle = Math.round(control._angle / constrain) * constrain -
diff;
control._angle = 0;
control.box.geometry.rotate(angle, centerGeometry);
control.transformFeature({rotation: angle});
}
};
var handles = new Array(8);
var rotationHandles = new Array(4);
var geom, handle, rotationHandle;
for(var i=0; i<8; ++i) {
geom = box.geometry.components[i];
handle = new OpenLayers.Feature.Vector(geom.clone(), null,
typeof this.renderIntent == "string" ? null :
this.renderIntent);
if(i % 2 == 0) {
rotationHandle = new OpenLayers.Feature.Vector(geom.clone(),
null, typeof this.rotationHandleSymbolizer == "string" ?
null : this.rotationHandleSymbolizer);
rotationHandle.geometry.move = rotationHandleMoveFn;
geom._rotationHandle = rotationHandle;
rotationHandles[i/2] = rotationHandle;
}
geom.move = vertexMoveFn;
geom.resize = vertexResizeFn;
geom.rotate = vertexRotateFn;
handle.geometry.move = handleMoveFn;
geom._handle = handle;
handles[i] = handle;
}
this.box = box;
this.rotationHandles = rotationHandles;
this.handles = handles;
},
/**
* Method: createControl
* Creates a DragFeature control for this control.
*/
createControl: function() {
var control = this;
this.dragControl = new OpenLayers.Control.DragFeature(this.layer, {
documentDrag: true,
// avoid moving the feature itself - move the box instead
moveFeature: function(pixel) {
if(this.feature === control.feature) {
this.feature = control.box;
}
OpenLayers.Control.DragFeature.prototype.moveFeature.apply(this,
arguments);
},
// transform while dragging
onDrag: function(feature, pixel) {
var geom = feature.geometry;
if(feature === control.box) {
control.transformFeature({center: control.center});
control.drawHandles();
}
},
// set a new feature
onStart: function(feature, pixel) {
var eligible = !control.geometryTypes ||
OpenLayers.Util.indexOf(control.geometryTypes,
feature.geometry.CLASS_NAME) !== -1;
var i = OpenLayers.Util.indexOf(control.handles, feature);
i += OpenLayers.Util.indexOf(control.rotationHandles,
feature);
if(feature !== control.feature && feature !== control.box &&
i == -2 && eligible) {
control.setFeature(feature);
}
},
onComplete: function(feature, pixel) {
control.events.triggerEvent("transformcomplete",
{feature: feature});
}
});
},
/**
* Method: drawHandles
* Draws the handles to match the box.
*/
drawHandles: function() {
var layer = this.layer;
for(var i=0; i<8; ++i) {
if(this.rotate && i % 2 === 0) {
layer.drawFeature(this.rotationHandles[i/2],
this.rotationHandleSymbolizer);
}
layer.drawFeature(this.handles[i], this.renderIntent);
}
},
/**
* Method: transformFeature
* Transforms the feature.
*
* Parameters:
* mods - {Object} An object with optional scale, ratio, rotation and
* center properties.
*/
transformFeature: function(mods) {
if(!this._setfeature) {
this.scale *= (mods.scale || 1);
this.ratio *= (mods.ratio || 1);
var oldRotation = this.rotation;
this.rotation = (this.rotation + (mods.rotation || 0)) % 360;
if(this.events.triggerEvent("beforetransform", mods) !== false) {
var feature = this.feature;
var geom = feature.geometry;
var center = this.center;
geom.rotate(-oldRotation, center);
if(mods.scale || mods.ratio) {
geom.resize(mods.scale, center, mods.ratio);
} else if(mods.center) {
feature.move(mods.center.getBounds().getCenterLonLat());
}
geom.rotate(this.rotation, center);
this.layer.drawFeature(feature);
feature.toState(OpenLayers.State.UPDATE);
this.events.triggerEvent("transform", mods);
}
}
this.layer.drawFeature(this.box, this.renderIntent);
this.drawHandles();
},
/**
* APIMethod: destroy
* Take care of things that are not handled in superclass.
*/
destroy: function() {
var geom;
for(var i=0; i<8; ++i) {
geom = this.box.geometry.components[i];
geom._handle.destroy();
geom._handle = null;
geom._rotationHandle && geom._rotationHandle.destroy();
geom._rotationHandle = null;
};
this.box.destroy();
this.box = null;
this.layer = null;
this.dragControl.destroy();
OpenLayers.Control.prototype.destroy.apply(this, arguments);
},
CLASS_NAME: "OpenLayers.Control.TransformFeature"
});

View File

@@ -0,0 +1,83 @@
<html>
<head>
<script src="../../lib/OpenLayers.js"></script>
<script type="text/javascript">
function test_initialize(t) {
t.plan(6);
var layer = "foo";
var control = new OpenLayers.Control.TransformFeature(layer);
t.ok(control.layer == layer,
"constructor sets layer correctly");
t.ok(control.dragControl instanceof OpenLayers.Control.DragFeature,
"constructor sets the drag control correctly");
t.ok(control.box instanceof OpenLayers.Feature.Vector,
"box feature created");
t.eq(control.handles.length, 8, "8 handles created");
t.eq(control.rotationHandles.length, 4, "4 rotation handles created")
t.eq(typeof control.rotationHandleSymbolizer, "object",
"rotationHandleSymbolizer initialized");
control.destroy();
}
function test_destroy(t) {
t.plan(1);
var map = new OpenLayers.Map("map");
var layer = new OpenLayers.Layer.Vector();
map.addLayer(layer);
var control = new OpenLayers.Control.TransformFeature(layer);
control.dragControl.destroy = function() {
t.ok(true,
"control.destroy calls destroy on drag control");
};
control.destroy();
map.destroy();
}
function test_activate(t) {
t.plan(3);
var map = new OpenLayers.Map("map");
var layer = new OpenLayers.Layer.Vector();
map.addLayer(layer);
var control = new OpenLayers.Control.TransformFeature(layer);
map.addControl(control);
t.ok(!control.dragControl.active,
"drag control is not active prior to activating control");
control.activate();
t.ok(control.dragControl.active,
"drag control is active after activating control");
t.ok(control.box.layer === layer, "box added to layer");
map.destroy();
}
function test_setFeature(t) {
t.plan(4);
var map = new OpenLayers.Map("map", {allOverlays: true});
var layer = new OpenLayers.Layer.Vector();
var feature = new OpenLayers.Feature.Vector(
OpenLayers.Geometry.fromWKT("POLYGON((-1 -1, 1 -1, 1 1, -1 1))"));
layer.addFeatures([feature]);
map.addLayer(layer);
map.setCenter(new OpenLayers.LonLat(0, 0), 18);
var control = new OpenLayers.Control.TransformFeature(layer);
map.addControl(control);
control.setFeature(feature);
t.ok(control.active, "control activated on setFeature");
t.ok(feature.geometry.getBounds().equals(control.box.geometry.getBounds()), "box positioned correctly");
t.geom_eq(control.handles[0].geometry, control.box.geometry.components[0], "handle positioned with box");
var center = new OpenLayers.LonLat(1, 1);
control.box.move(center);
t.geom_eq(control.handles[0].geometry, control.box.geometry.components[0], "handle moved with box");
}
</script>
</head>
<body>
<div id="map" style="width: 400px; height: 250px;"/>
</body>
</html>

View File

@@ -35,6 +35,7 @@
<li>Control/SelectFeature.html</li>
<li>Control/Snapping.html</li>
<li>Control/Split.html</li>
<li>Control/TransformFeature.html</li>
<li>Control/WMSGetFeatureInfo.html</li>
<li>Control/PanPanel.html</li>
<li>Events.html</li>