diff --git a/examples/vector-layer.js b/examples/vector-layer.js index d830d654ee..b1aa929f15 100644 --- a/examples/vector-layer.js +++ b/examples/vector-layer.js @@ -43,12 +43,17 @@ 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('info').innerHTML = info.join(', ') || ' '; + var features = map.getFeatureInfo({ + pixel: evt.getPixel(), + layers: [vector], + success: function(features) { + var info = []; + for (var i = 0, ii = features.length; i < ii; ++i) { + info.push(features[i].get('name')); + } + document.getElementById('info').innerHTML = info.join(', ') || ' '; + } + }); }); diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index d4423fa0f5..acf8dd4fb1 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -5,6 +5,20 @@ * @property {ol.ProjectionLike} projection Projection. */ +/** + * @typedef {Object} ol.GetFeatureInfoOptions + * @property {ol.Pixel} pixel Pixel coordinate relative to the map viewport. + * @property {Array.|undefined} layers Layers to restrict the + * query to. All layers will be queried if not provided. + * @property {function(Array.)} success Callback for + * successful queries. The passed argument is the resulting feature + * information. Layers that are able to provide attribute data will put + * ol.Feature instances, other layers will put a string which can either + * be plain text or markup. + * @property {function(Object)|undefined} error Callback for unsuccessful + * queries. + */ + /** * Object literal with config options for the map. * @typedef {Object} ol.MapOptions diff --git a/src/ol/map.exports b/src/ol/map.exports index 048d03366d..4bca2e1995 100644 --- a/src/ol/map.exports +++ b/src/ol/map.exports @@ -2,7 +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.getFeatureInfo @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 e144fe7e68..95af4a7fe1 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -430,17 +430,13 @@ 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.=} 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. + * @param {ol.GetFeatureInfoOptions} options Options. */ -ol.Map.prototype.getFeatureInfoForPixel = function(pixel, opt_layers) { - var layers = goog.isDefAndNotNull(opt_layers) ? - opt_layers : this.getLayers().getArray(); - return this.getRenderer().getFeatureInfoForPixel(pixel, layers); +ol.Map.prototype.getFeatureInfo = function(options) { + var layers = goog.isDefAndNotNull(options.layers) ? + options.layers : this.getLayers().getArray(); + this.getRenderer().getFeatureInfoForPixel( + options.pixel, layers, options.success, options.error); }; diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js index 83dcbdff06..c941a10898 100644 --- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js @@ -190,10 +190,14 @@ 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. + * @param {function(Array.)} success Callback for + * successful queries. The passed argument is the resulting feature + * information. Layers that are able to provide attribute data will put + * ol.Feature instances, other layers will put a string which can either + * be plain text or markup. */ ol.renderer.canvas.VectorLayer.prototype.getFeatureInfoForPixel = - function(pixel) { + function(pixel, success) { // TODO adjust pixel tolerance for applied styles var minPixel = new ol.Pixel(pixel.x - 1, pixel.y - 1); var maxPixel = new ol.Pixel(pixel.x + 1, pixel.y + 1); @@ -230,7 +234,7 @@ ol.renderer.canvas.VectorLayer.prototype.getFeatureInfoForPixel = result.push(candidate); } } - return result; + goog.global.setTimeout(function() { success(result); }, 0); }; diff --git a/src/ol/renderer/maprenderer.js b/src/ol/renderer/maprenderer.js index 3197bdbe54..badca46ca5 100644 --- a/src/ol/renderer/maprenderer.js +++ b/src/ol/renderer/maprenderer.js @@ -106,23 +106,34 @@ ol.renderer.Map.prototype.getCanvas = goog.functions.NULL; /** * @param {ol.Pixel} pixel Pixel coordinate relative to the map viewport. * @param {Array.} layers Layers to query. - * @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. + * @param {function(Array.)} success Callback for + * successful queries. The passed argument is the resulting feature + * information. Layers that are able to provide attribute data will put + * ol.Feature instances, other layers will put a string which can either + * be plain text or markup. + * @param {function(Object)=} opt_error Callback for unsuccessful + * queries. */ ol.renderer.Map.prototype.getFeatureInfoForPixel = - function(pixel, layers) { + function(pixel, layers, success, opt_error) { var layer, layerRenderer; var featureInfo = []; - for (var i = 0, ii = layers.length; i < ii; ++i) { + var numLayers = layers.length; + var callback = function(layerFeatureInfo) { + featureInfo.push.apply(featureInfo, layerFeatureInfo); + --numLayers; + if (!numLayers) { + success(featureInfo); + } + }; + + for (var i = 0; i < numLayers; ++i) { layer = layers[i]; layerRenderer = this.getLayerRenderer(layer); if (goog.isFunction(layerRenderer.getFeatureInfoForPixel)) { - featureInfo.push.apply(featureInfo, - layerRenderer.getFeatureInfoForPixel(pixel)); + layerRenderer.getFeatureInfoForPixel(pixel, callback, opt_error); } } - return featureInfo; };