diff --git a/examples/vector-layer.js b/examples/vector-layer.js
index 1f23f67028..c15023685a 100644
--- a/examples/vector-layer.js
+++ b/examples/vector-layer.js
@@ -42,6 +42,15 @@ var map = new ol.Map({
})
});
+map.on('mousemove', function(evt) {
+ var features = map.getFeatureInfoForPixel(evt.getPixel(), [vector]);
+ var info = [];
+ for (var i = 0, ii = features.length; i < ii; ++i) {
+ info.push(features[i].get('name'));
+ }
+ document.getElementById('map').title = info.join(', ');
+});
+
var geojson = new ol.parser.GeoJSON();
var url = 'data/countries.json';
diff --git a/src/ol/map.exports b/src/ol/map.exports
index 6fa9bba48a..048d03366d 100644
--- a/src/ol/map.exports
+++ b/src/ol/map.exports
@@ -2,6 +2,7 @@
@exportProperty ol.Map.prototype.addLayer
@exportProperty ol.Map.prototype.addPreRenderFunction
@exportProperty ol.Map.prototype.addPreRenderFunctions
+@exportProperty ol.Map.prototype.getFeatureInfoForPixel
@exportProperty ol.Map.prototype.getInteractions
@exportProperty ol.Map.prototype.getRenderer
@exportProperty ol.Map.prototype.removeLayer
diff --git a/src/ol/map.js b/src/ol/map.js
index 616ed73c0c..7da8568ae2 100644
--- a/src/ol/map.js
+++ b/src/ol/map.js
@@ -427,6 +427,34 @@ ol.Map.prototype.getCoordinateFromPixel = function(pixel) {
};
+/**
+ * Get feature information for a pixel on the map.
+ *
+ * @param {ol.Pixel} pixel Pixel coordinate relative to the map viewport.
+ * @param {Array.
|undefined} opt_layers Layers to restrict the
+ * query to. All layers will be queried if not provided.
+ * @return {Array.} Feature information. Layers that are
+ * able to return attribute data will return ol.Feature instances, other
+ * layers will return a string which can either be plain text or markup.
+ */
+ol.Map.prototype.getFeatureInfoForPixel = function(pixel, opt_layers) {
+ var renderer = this.getRenderer();
+ var layers = goog.isDefAndNotNull(opt_layers) ?
+ opt_layers : this.getLayers().getArray();
+ var layer, layerRenderer;
+ var featureInfo = [];
+ for (var i = 0, ii = layers.length; i < ii; ++i) {
+ layer = layers[i];
+ layerRenderer = renderer.getLayerRenderer(layer);
+ if (goog.isFunction(layerRenderer.getFeatureInfoForPixel)) {
+ featureInfo.push.apply(featureInfo,
+ layerRenderer.getFeatureInfoForPixel(pixel));
+ }
+ }
+ return featureInfo;
+};
+
+
/**
* @return {ol.Collection} Interactions.
*/
diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js
index 108458b198..4e7c982f26 100644
--- a/src/ol/mapbrowserevent.js
+++ b/src/ol/mapbrowserevent.js
@@ -147,6 +147,12 @@ ol.MapBrowserEventHandler = function(map) {
*/
this.downListenerKey_ = null;
+ /**
+ * @type {?number}
+ * @private
+ */
+ this.moveListenerKey_ = null;
+
/**
* @type {Array.}
* @private
@@ -172,6 +178,9 @@ ol.MapBrowserEventHandler = function(map) {
this.downListenerKey_ = goog.events.listen(element,
goog.events.EventType.MOUSEDOWN,
this.handleMouseDown_, false, this);
+ this.moveListenerKey_ = goog.events.listen(element,
+ goog.events.EventType.MOUSEMOVE,
+ this.relayMouseMove_, false, this);
// touch events
this.touchListenerKeys_ = [
goog.events.listen(element, [
@@ -281,6 +290,19 @@ ol.MapBrowserEventHandler.prototype.handleMouseMove_ = function(browserEvent) {
};
+/**
+ * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @private
+ */
+ol.MapBrowserEventHandler.prototype.relayMouseMove_ = function(browserEvent) {
+ if (goog.events.hasListener(
+ this.map_, ol.MapBrowserEvent.EventType.MOUSEMOVE)) {
+ this.dispatchEvent(new ol.MapBrowserEvent(
+ ol.MapBrowserEvent.EventType.MOUSEMOVE, this.map_, browserEvent));
+ }
+};
+
+
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @private
@@ -335,6 +357,7 @@ ol.MapBrowserEventHandler.prototype.handleTouchEnd_ = function(browserEvent) {
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
goog.events.unlistenByKey(this.clickListenerKey_);
goog.events.unlistenByKey(this.downListenerKey_);
+ goog.events.unlistenByKey(this.moveListenerKey_);
if (!goog.isNull(this.dragListenerKeys_)) {
goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
this.dragListenerKeys_ = null;
@@ -360,5 +383,6 @@ ol.MapBrowserEvent.EventType = {
DRAGEND: 'dragend',
TOUCHSTART: goog.events.EventType.TOUCHSTART,
TOUCHMOVE: goog.events.EventType.TOUCHMOVE,
- TOUCHEND: goog.events.EventType.TOUCHEND
+ TOUCHEND: goog.events.EventType.TOUCHEND,
+ MOUSEMOVE: goog.events.EventType.MOUSEMOVE
};
diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js
index b343880a36..266815fb22 100644
--- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js
+++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js
@@ -187,6 +187,26 @@ ol.renderer.canvas.VectorLayer.prototype.getTransform = function() {
};
+/**
+ * @param {ol.Pixel} pixel Pixel coordinate relative to the map viewport.
+ * @return {Array.} Features at the pixel location.
+ */
+ol.renderer.canvas.VectorLayer.prototype.getFeatureInfoForPixel =
+ function(pixel) {
+ // TODO adjust pixel tolerance for point features
+ var minPixel = new ol.Pixel(pixel.x - 1, pixel.y - 1);
+ var maxPixel = new ol.Pixel(pixel.x + 1, pixel.y + 1);
+ var map = this.getMap();
+ var minCoordinate = map.getCoordinateFromPixel(minPixel);
+ var maxCoordinate = map.getCoordinateFromPixel(maxPixel);
+ var bbox = ol.extent.boundingExtent([minCoordinate, maxCoordinate]);
+ var filter = new ol.filter.Extent(bbox);
+
+ // TODO do a real intersect against the filtered result for exact matches
+ return this.getLayer().getFeatures(filter);
+};
+
+
/**
* @param {goog.events.Event} event Layer change event.
* @private