Added GetFeature control to get features based on spatial filters
created by clicking or dragging boxes on the map. Thanks tschaub for the review and the final patch with valuable improvements. r=tschaub (closes #1936) git-svn-id: http://svn.openlayers.org/trunk/openlayers@9003 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
80
examples/getfeature-wfs.html
Normal file
80
examples/getfeature-wfs.html
Normal file
@@ -0,0 +1,80 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<title>WFS: GetFeature Example (GeoServer)</title>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
var map, layer, select, hover, control;
|
||||
|
||||
function init(){
|
||||
OpenLayers.ProxyHost= "proxy.cgi?url=";
|
||||
map = new OpenLayers.Map('map', {
|
||||
controls: [
|
||||
new OpenLayers.Control.PanZoom(),
|
||||
new OpenLayers.Control.Permalink(),
|
||||
new OpenLayers.Control.Navigation()
|
||||
]
|
||||
});
|
||||
layer = new OpenLayers.Layer.WMS(
|
||||
"States WMS/WFS",
|
||||
"http://demo.opengeo.org/geoserver/ows",
|
||||
{layers: 'topp:states', format: 'image/gif'}
|
||||
);
|
||||
select = new OpenLayers.Layer.Vector("Selection", {styleMap:
|
||||
new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"])
|
||||
});
|
||||
hover = new OpenLayers.Layer.Vector("Hover");
|
||||
map.addLayers([layer, hover, select]);
|
||||
|
||||
control = new OpenLayers.Control.GetFeature({
|
||||
protocol: OpenLayers.Protocol.WFS.fromWMSLayer(layer),
|
||||
box: true,
|
||||
hover: true,
|
||||
multipleKey: "shiftKey",
|
||||
toggleKey: "ctrlKey"
|
||||
});
|
||||
control.events.register("featureselected", this, function(e) {
|
||||
select.addFeatures([e.feature]);
|
||||
});
|
||||
control.events.register("featureunselected", this, function(e) {
|
||||
select.removeFeatures([e.feature]);
|
||||
});
|
||||
control.events.register("hoverfeature", this, function(e) {
|
||||
hover.addFeatures([e.feature]);
|
||||
});
|
||||
control.events.register("outfeature", this, function(e) {
|
||||
hover.removeFeatures([e.feature]);
|
||||
});
|
||||
map.addControl(control);
|
||||
control.activate();
|
||||
|
||||
map.setCenter(new OpenLayers.Bounds(-140.444336,25.115234,-44.438477,50.580078).getCenterLonLat(), 3);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">WFS GetFeature Example (GeoServer)</h1>
|
||||
|
||||
<div id="tags">
|
||||
</div>
|
||||
|
||||
<p id="shortdesc">
|
||||
Shows how to use the GetFeature control to select features from a
|
||||
WMS layer. Click or drag a box to select features, use the Shift key to
|
||||
add features to the selection, use the Ctrl key to toggle a feature's
|
||||
selected status. Note that this control also has a hover option, which is
|
||||
enabled in this example. This gives you a visual feedback by loading the
|
||||
feature underneath the mouse pointer from the WFS, but causes a lot of
|
||||
GetFeature requests to be issued.
|
||||
</p>
|
||||
|
||||
<div id="map" class="smallmap"></div>
|
||||
|
||||
<div id="docs"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
@@ -245,6 +245,7 @@
|
||||
"OpenLayers/Format/WMC/v1_1_0.js",
|
||||
"OpenLayers/Format/WMSGetFeatureInfo.js",
|
||||
"OpenLayers/Layer/WFS.js",
|
||||
"OpenLayers/Control/GetFeature.js",
|
||||
"OpenLayers/Control/MouseToolbar.js",
|
||||
"OpenLayers/Control/NavToolbar.js",
|
||||
"OpenLayers/Control/PanPanel.js",
|
||||
|
||||
557
lib/OpenLayers/Control/GetFeature.js
Normal file
557
lib/OpenLayers/Control/GetFeature.js
Normal file
@@ -0,0 +1,557 @@
|
||||
/* Copyright (c) 2006-2008 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/Handler/Click.js
|
||||
* @requires OpenLayers/Handler/Box.js
|
||||
* @requires OpenLayers/Handler/Hover.js
|
||||
* @requires OpenLayers/Filter/Spatial.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Control.GetFeature
|
||||
* Gets vector features for locations underneath the mouse cursor. Can be
|
||||
* configured to act on click, hover or dragged boxes. Uses an
|
||||
* <OpenLayers.Protocol> that supports spatial filters (BBOX) to retrieve
|
||||
* features from a server and fires events that notify applications of the
|
||||
* selected features.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Control>
|
||||
*/
|
||||
OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: protocol
|
||||
* {<OpenLayers.Protocol>} Required. The protocol used for fetching
|
||||
* features.
|
||||
*/
|
||||
protocol: null,
|
||||
|
||||
/**
|
||||
* APIProperty: multipleKey
|
||||
* {String} An event modifier ('altKey' or 'shiftKey') that temporarily sets
|
||||
* the <multiple> property to true. Default is null.
|
||||
*/
|
||||
multipleKey: null,
|
||||
|
||||
/**
|
||||
* APIProperty: toggleKey
|
||||
* {String} An event modifier ('altKey' or 'shiftKey') that temporarily sets
|
||||
* the <toggle> property to true. Default is null.
|
||||
*/
|
||||
toggleKey: null,
|
||||
|
||||
/**
|
||||
* Property: modifiers
|
||||
* {Object} The event modifiers to use, according to the current event
|
||||
* being handled by this control's handlers
|
||||
*/
|
||||
modifiers: null,
|
||||
|
||||
/**
|
||||
* APIProperty: multiple
|
||||
* {Boolean} Allow selection of multiple geometries. Default is false.
|
||||
*/
|
||||
multiple: false,
|
||||
|
||||
/**
|
||||
* APIProperty: click
|
||||
* {Boolean} Use a click handler for selecting/unselecting features.
|
||||
* Default is true.
|
||||
*/
|
||||
click: true,
|
||||
|
||||
/**
|
||||
* APIProperty: clickout
|
||||
* {Boolean} Unselect features when clicking outside any feature.
|
||||
* Applies only if <click> is true. Default is true.
|
||||
*/
|
||||
clickout: true,
|
||||
|
||||
/**
|
||||
* APIProperty: toggle
|
||||
* {Boolean} Unselect a selected feature on click. Applies only if
|
||||
* <click> is true. Default is false.
|
||||
*/
|
||||
toggle: false,
|
||||
|
||||
/**
|
||||
* APIProperty: clickTolerance
|
||||
* {Integer} Tolerance for the BBOX query in pixels. This has the
|
||||
* same effect as the tolerance parameter on WMS GetFeatureInfo
|
||||
* requests. Will be ignored for box selections. Applies only if
|
||||
* <click> is true. Default is 5.
|
||||
*/
|
||||
clickTolerance: 5,
|
||||
|
||||
/**
|
||||
* APIProperty: hover
|
||||
* {Boolean} Send feature requests on mouse moves. Default is false.
|
||||
*/
|
||||
hover: false,
|
||||
|
||||
/**
|
||||
* APIProperty: box
|
||||
* {Boolean} Allow feature selection by drawing a box.
|
||||
*/
|
||||
box: false,
|
||||
|
||||
/**
|
||||
* APIProperty: maxFeatures
|
||||
* {Integer} Maximum number of features to return from a query, if
|
||||
* supported by the <protocol>. Default is 10.
|
||||
*/
|
||||
maxFeatures: 10,
|
||||
|
||||
/**
|
||||
* Property: features
|
||||
* {Object} Hash of {<OpenLayers.Feature.Vector>}, keyed by fid, holding
|
||||
* the currently selected features
|
||||
*/
|
||||
features: null,
|
||||
|
||||
/**
|
||||
* Proeprty: hoverFeature
|
||||
* {<OpenLayers.Feature.Vector>} The feature currently selected by the
|
||||
* hover handler
|
||||
*/
|
||||
hoverFeature: null,
|
||||
|
||||
/**
|
||||
* APIProperty: handlerOptions
|
||||
* {Object} Additional options for the handlers used by this control. This
|
||||
* is a hash with the keys "click", "box" and "hover".
|
||||
*/
|
||||
handlerOptions: null,
|
||||
|
||||
/**
|
||||
* Property: handlers
|
||||
* {Object} Object with references to multiple <OpenLayers.Handler>
|
||||
* instances.
|
||||
*/
|
||||
handlers: null,
|
||||
|
||||
/**
|
||||
* Property: hoverRequest
|
||||
* {<OpenLayers.Request>} contains the currently running hover request
|
||||
* (if any).
|
||||
*/
|
||||
hoverRequest: null,
|
||||
|
||||
/**
|
||||
* Constant: EVENT_TYPES
|
||||
*
|
||||
* Supported event types:
|
||||
* beforefeatureselected - Triggered when <click> is true before a
|
||||
* feature is selected. The event object has a feature property with
|
||||
* the feature about to select
|
||||
* featureselected - Triggered when <click> is true and a feature is
|
||||
* selected. The event object has a feature property with the
|
||||
* selected feature
|
||||
* featureunselected - Triggered when <click> is true and a feature is
|
||||
* unselected. The event object has a feature property with the
|
||||
* unselected feature
|
||||
* clickout - Triggered when when <click> is true and no feature was
|
||||
* selected.
|
||||
* hoverfeature - Triggered when <hover> is true and the mouse has
|
||||
* stopped over a feature
|
||||
* outfeature - Triggered when <hover> is true and the mouse moves
|
||||
* moved away from a hover-selected feature
|
||||
*/
|
||||
EVENT_TYPES: ["featureselected", "featureunselected", "clickout",
|
||||
"beforefeatureselected", "hoverfeature", "outfeature"],
|
||||
|
||||
/**
|
||||
* Constructor: <OpenLayers.Control.SelectFeature>
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} A configuration object which at least has to contain
|
||||
* a <protocol> property
|
||||
*/
|
||||
initialize: function(options) {
|
||||
// concatenate events specific to vector with those from the base
|
||||
this.EVENT_TYPES =
|
||||
OpenLayers.Control.GetFeature.prototype.EVENT_TYPES.concat(
|
||||
OpenLayers.Control.prototype.EVENT_TYPES
|
||||
);
|
||||
|
||||
options.handlerOptions = options.handlerOptions || {};
|
||||
|
||||
OpenLayers.Control.prototype.initialize.apply(this, [options]);
|
||||
|
||||
this.features = {};
|
||||
|
||||
this.handlers = {};
|
||||
|
||||
if(this.click) {
|
||||
this.handlers.click = new OpenLayers.Handler.Click(this,
|
||||
{click: this.selectSingle}, this.handlerOptions.click || {})
|
||||
};
|
||||
|
||||
if(this.box) {
|
||||
this.handlers.box = new OpenLayers.Handler.Box(
|
||||
this, {done: this.selectBox},
|
||||
OpenLayers.Util.extend(this.handlerOptions.box, {
|
||||
boxDivClassName: "olHandlerBoxSelectFeature"
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if(this.hover) {
|
||||
this.handlers.hover = new OpenLayers.Handler.Hover(
|
||||
this, {'move': this.cancelHover, 'pause': this.selectHover},
|
||||
OpenLayers.Util.extend(this.handlerOptions.hover, {
|
||||
'delay': 250
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: activate
|
||||
* Activates the control.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The control was effectively activated.
|
||||
*/
|
||||
activate: function () {
|
||||
if (!this.active) {
|
||||
for(var i in this.handlers) {
|
||||
this.handlers[i].activate();
|
||||
}
|
||||
}
|
||||
return OpenLayers.Control.prototype.activate.apply(
|
||||
this, arguments
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: deactivate
|
||||
* Deactivates the control.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The control was effectively deactivated.
|
||||
*/
|
||||
deactivate: function () {
|
||||
if (this.active) {
|
||||
for(var i in this.handlers) {
|
||||
this.handlers[i].deactivate();
|
||||
}
|
||||
}
|
||||
return OpenLayers.Control.prototype.deactivate.apply(
|
||||
this, arguments
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: unselectAll
|
||||
* Unselect all selected features. To unselect all except for a single
|
||||
* feature, set the options.except property to the feature.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} Optional configuration object.
|
||||
*/
|
||||
unselectAll: function(options) {
|
||||
// we'll want an option to supress notification here
|
||||
var feature;
|
||||
for(var i=this.features.length-1; i>=0; --i) {
|
||||
feature = this.features[i];
|
||||
if(!options || options.except != feature) {
|
||||
this.unselect(feature);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: selectSingle
|
||||
* Called on click
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {<OpenLayers.Event>}
|
||||
*/
|
||||
selectSingle: function(evt) {
|
||||
// Set the cursor to "wait" to tell the user we're working on their click.
|
||||
OpenLayers.Element.addClass(this.map.div, "olCursorWait");
|
||||
|
||||
var bounds = this.pixelToBounds(evt.xy);
|
||||
|
||||
this.setModifiers(evt);
|
||||
this.request(bounds, {single: true});
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: selectBox
|
||||
* Callback from the handlers.box set up when <box> selection is on
|
||||
*
|
||||
* Parameters:
|
||||
* position - {<OpenLayers.Bounds>}
|
||||
*/
|
||||
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
|
||||
);
|
||||
|
||||
this.setModifiers(this.handlers.box.dragHandler.evt);
|
||||
this.request(bounds);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method selectHover
|
||||
* Callback from the handlers.hover set up when <hover> selection is on
|
||||
*
|
||||
* Parameters:
|
||||
* evt {Object} - event object with an xy property
|
||||
*/
|
||||
selectHover: function(evt) {
|
||||
var bounds = this.pixelToBounds(evt.xy);
|
||||
this.request(bounds, {single: true, hover: true});
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: cancelHover
|
||||
* Callback from the handlers.hover set up when <hover> selection is on
|
||||
*/
|
||||
cancelHover: function() {
|
||||
if (this.hoverRequest) {
|
||||
this.hoverRequest.abort();
|
||||
this.hoverRequest = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: request
|
||||
* Sends a GetFeature request to the WFS
|
||||
*
|
||||
* Parameters:
|
||||
* bounds - {<OpenLayers.Bounds>} bounds for the request's BBOX filter
|
||||
* options - {Object} additional options for this method.
|
||||
*
|
||||
* Supported options include:
|
||||
* single - {Boolean} A single feature should be returned.
|
||||
* Note that this will be ignored if the protocol does not
|
||||
* return the geometries of the features.
|
||||
* hover - {Boolean} Do the request for the hover handler.
|
||||
*/
|
||||
request: function(bounds, options) {
|
||||
options = options || {};
|
||||
var filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.BBOX,
|
||||
value: bounds
|
||||
});
|
||||
|
||||
var response = this.protocol.read({
|
||||
maxFeatures: options.single == true ? this.maxFeatures : undefined,
|
||||
filter: filter,
|
||||
callback: function(result) {
|
||||
if(result.code == 1) {
|
||||
if(result.features.length) {
|
||||
if(options.single == true) {
|
||||
this.selectBestFeature(result.features,
|
||||
bounds.getCenterLonLat(), options);
|
||||
} else {
|
||||
this.select(result.features);
|
||||
}
|
||||
} else if(options.hover) {
|
||||
this.hoverSelect();
|
||||
} else {
|
||||
this.events.triggerEvent("clickout");
|
||||
if(this.clickout) {
|
||||
this.unselectAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reset the cursor.
|
||||
OpenLayers.Element.removeClass(this.map.div, "olCursorWait");
|
||||
},
|
||||
scope: this
|
||||
});
|
||||
if(options.hover == true) {
|
||||
this.hoverRequest = response.priv;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: selectBestFeature
|
||||
* Selects the feature from an array of features that is the best match
|
||||
* for the click position.
|
||||
*
|
||||
* Parameters:
|
||||
* features - {Array(<OpenLayers.Feature.Vector>)}
|
||||
* clickPosition - {<OpenLayers.LonLat>}
|
||||
* options - {Object} additional options for this method
|
||||
*
|
||||
* Supported options include:
|
||||
* hover - {Boolean} Do the selection for the hover handler.
|
||||
*/
|
||||
selectBestFeature: function(features, clickPosition, options) {
|
||||
options = options || {};
|
||||
if(features.length) {
|
||||
var point = new OpenLayers.Geometry.Point(clickPosition.lon,
|
||||
clickPosition.lat);
|
||||
var feature, resultFeature, dist;
|
||||
var minDist = Number.MAX_VALUE;
|
||||
for(var i=0; i<features.length; ++i) {
|
||||
feature = features[i];
|
||||
if(feature.geometry) {
|
||||
dist = point.distanceTo(feature.geometry, {edge: false});
|
||||
if(dist < minDist) {
|
||||
minDist = dist;
|
||||
resultFeature = feature;
|
||||
if(minDist == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(options.hover == true) {
|
||||
this.hoverSelect(resultFeature);
|
||||
} else {
|
||||
this.select(resultFeature || features);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setModifiers
|
||||
* Sets the multiple and toggle modifiers according to the current event
|
||||
*
|
||||
* Parameters:
|
||||
* evt {<OpenLayers.Event>}
|
||||
*/
|
||||
setModifiers: function(evt) {
|
||||
this.modifiers = {
|
||||
multiple: this.multiple || (this.multipleKey && evt[this.multipleKey]),
|
||||
toggle: this.toggle || (this.toggleKey && evt[this.toggleKey])
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: select
|
||||
* Add feature to the hash of selected features and trigger the
|
||||
* featureselected event.
|
||||
*
|
||||
* Parameters:
|
||||
* features - {<OpenLayers.Feature.Vector>} or an array of features
|
||||
*/
|
||||
select: function(features) {
|
||||
if(!this.modifiers.multiple && !this.modifiers.toggle) {
|
||||
this.unselectAll();
|
||||
}
|
||||
if(!(features instanceof Array)) {
|
||||
features = [features];
|
||||
}
|
||||
|
||||
var feature;
|
||||
for(var i=0, len=features.length; i<len; ++i) {
|
||||
feature = features[i];
|
||||
if(this.features[feature.fid || feature.id]) {
|
||||
if(this.modifiers.toggle) {
|
||||
this.unselect(this.features[feature.fid || feature.id]);
|
||||
}
|
||||
} else {
|
||||
cont = this.events.triggerEvent("beforefeatureselected", {
|
||||
feature: feature
|
||||
});
|
||||
if(cont !== false) {
|
||||
this.features[feature.fid || feature.id] = feature;
|
||||
|
||||
this.events.triggerEvent("featureselected",
|
||||
{feature: feature});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: hoverSelect
|
||||
* Sets/unsets the <hoverFeature>
|
||||
*
|
||||
* Parameters:
|
||||
* feature - {<OpenLayers.Feature.Vector>} the feature to hover-select.
|
||||
* If none is provided, the current <hoverFeature> will be nulled and
|
||||
* the outfeature event will be triggered.
|
||||
*/
|
||||
hoverSelect: function(feature) {
|
||||
var fid = feature ? feature.fid || feature.id : null;
|
||||
var hfid = this.hoverFeature ?
|
||||
this.hoverFeature.fid || this.hoverFeature.id : null;
|
||||
|
||||
if(hfid && hfid != fid) {
|
||||
this.events.triggerEvent("outfeature",
|
||||
{feature: this.hoverFeature});
|
||||
this.hoverFeature = null;
|
||||
}
|
||||
if(fid && fid != hfid) {
|
||||
this.events.triggerEvent("hoverfeature", {feature: feature});
|
||||
this.hoverFeature = feature;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: unselect
|
||||
* Remove feature from the hash of selected features and trigger the
|
||||
* featureunselected event.
|
||||
*
|
||||
* Parameters:
|
||||
* feature - {<OpenLayers.Feature.Vector>}
|
||||
*/
|
||||
unselect: function(feature) {
|
||||
delete this.features[feature.fid || feature.id];
|
||||
this.events.triggerEvent("featureunselected", {feature: feature});
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: unselectAll
|
||||
* Unselect all selected features.
|
||||
*/
|
||||
unselectAll: function() {
|
||||
// we'll want an option to supress notification here
|
||||
for(var fid in this.features) {
|
||||
this.unselect(this.features[fid]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setMap
|
||||
* Set the map property for the control.
|
||||
*
|
||||
* Parameters:
|
||||
* map - {<OpenLayers.Map>}
|
||||
*/
|
||||
setMap: function(map) {
|
||||
for(var i in this.handlers) {
|
||||
this.handlers[i].setMap(map);
|
||||
}
|
||||
OpenLayers.Control.prototype.setMap.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: pixelToBounds
|
||||
* Takes a pixel as argument and creates bounds after adding the
|
||||
* <clickTolerance>.
|
||||
*
|
||||
* Parameters:
|
||||
* pixel - {<OpenLayers.Pixel>}
|
||||
*/
|
||||
pixelToBounds: function(pixel) {
|
||||
var llPx = pixel.add(-this.clickTolerance/2, this.clickTolerance/2);
|
||||
var urPx = pixel.add(this.clickTolerance/2, -this.clickTolerance/2);
|
||||
var ll = this.map.getLonLatFromPixel(llPx);
|
||||
var ur = this.map.getLonLatFromPixel(urPx);
|
||||
return new OpenLayers.Bounds(ll.lon, ll.lat, ur.lon, ur.lat);
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Control.GetFeature"
|
||||
});
|
||||
104
tests/Control/GetFeature.html
Normal file
104
tests/Control/GetFeature.html
Normal file
@@ -0,0 +1,104 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
function test_Control_GetFeature_constructor(t) {
|
||||
t.plan(2);
|
||||
var protocol = "foo";
|
||||
var control = new OpenLayers.Control.GetFeature({
|
||||
protocol: protocol
|
||||
});
|
||||
t.ok(control instanceof OpenLayers.Control.GetFeature,
|
||||
"new OpenLayers.Control.SelectFeature returns an instance");
|
||||
t.eq(control.protocol, "foo",
|
||||
"constructor sets protocol correctly");
|
||||
}
|
||||
|
||||
function test_Control_GetFeature_select(t) {
|
||||
t.plan(3);
|
||||
var map = new OpenLayers.Map("map");
|
||||
var layer = new OpenLayers.Layer.WMS("foo", "wms", {
|
||||
layers: "foo"
|
||||
});
|
||||
map.addLayer(layer);
|
||||
map.setCenter(new OpenLayers.LonLat(1,2));
|
||||
var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));
|
||||
var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(2,3));
|
||||
var control = new OpenLayers.Control.GetFeature({
|
||||
protocol: new OpenLayers.Protocol({
|
||||
read: function(obj) {
|
||||
obj.callback.call(obj.scope, {
|
||||
features: [feature1, feature2],
|
||||
code: 1
|
||||
});
|
||||
}
|
||||
}),
|
||||
box: true
|
||||
});
|
||||
map.addControl(control);
|
||||
|
||||
var singleTest = function(evt) {
|
||||
t.eq(evt.feature.id, feature1.id, "featureselected callback called with closest feature");
|
||||
}
|
||||
control.events.register("featureselected", this, singleTest);
|
||||
control.selectSingle({xy: new OpenLayers.Pixel(200, 125)});
|
||||
control.events.unregister("featureselected", this, singleTest);
|
||||
|
||||
var features = []
|
||||
var boxTest = function(evt) {
|
||||
features.push(evt.feature);
|
||||
}
|
||||
control.events.register("featureselected", this, boxTest);
|
||||
control.selectBox(new OpenLayers.Bounds(0,0,4,4));
|
||||
control.events.unregister("featureselected", this, boxTest);
|
||||
t.eq(features.length, 2, "2 features inside box selected");
|
||||
t.eq(features[1].id, feature2.id, "featureselected callback called with multiple features");
|
||||
}
|
||||
|
||||
function test_Control_GetFeature_hover(t) {
|
||||
t.plan(3);
|
||||
var map = new OpenLayers.Map("map");
|
||||
var layer = new OpenLayers.Layer.WMS("foo", "wms", {
|
||||
layers: "foo"
|
||||
});
|
||||
map.addLayer(layer);
|
||||
map.setCenter(new OpenLayers.LonLat(1,2));
|
||||
var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));
|
||||
var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(2,3));
|
||||
var control = new OpenLayers.Control.GetFeature({
|
||||
protocol: new OpenLayers.Protocol({
|
||||
read: function(obj){
|
||||
obj.callback.call(obj.scope, {
|
||||
features: [feature1, feature2],
|
||||
code: 1
|
||||
});
|
||||
return {priv: {}};
|
||||
}
|
||||
}),
|
||||
hover: true
|
||||
});
|
||||
map.addControl(control);
|
||||
|
||||
var hoverFeature;
|
||||
var hoverTest = function(evt) {
|
||||
t.eq(evt.feature.id, hoverFeature.id, "hoverfeature callback called with closest feature");
|
||||
}
|
||||
var outTest = function(evt) {
|
||||
t.eq(evt.feature.id, feature1.id, "outfeature callback called with previously hovered feature");
|
||||
}
|
||||
control.events.register("hoverfeature", this, hoverTest);
|
||||
control.events.register("outfeature", this, outTest);
|
||||
hoverFeature = feature1;
|
||||
control.selectHover({xy: new OpenLayers.Pixel(200, 125)});
|
||||
hoverFeature = feature2;
|
||||
control.selectHover({xy: new OpenLayers.Pixel(400, 0)});
|
||||
control.events.unregister("hoverfeature", this, hoverTest);
|
||||
control.events.unregister("outfeature", this, outTest);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" style="width: 400px; height: 250px;"/>
|
||||
</body>
|
||||
</html>
|
||||
@@ -14,6 +14,7 @@
|
||||
<li>Control/DragFeature.html</li>
|
||||
<li>Control/DragPan.html</li>
|
||||
<li>Control/DrawFeature.html</li>
|
||||
<li>Control/GetFeature.html</li>
|
||||
<li>Control/KeyboardDefaults.html</li>
|
||||
<li>Control/LayerSwitcher.html</li>
|
||||
<li>Control/ModifyFeature.html</li>
|
||||
|
||||
@@ -321,3 +321,10 @@ div.olControlMousePosition {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cursor styles
|
||||
*/
|
||||
|
||||
.olCursorWait {
|
||||
cursor: wait;
|
||||
}
|
||||
Reference in New Issue
Block a user