Giving the map a getFeatureInfoForPixel method
This method is an entry point for getting feature information. Renderers can use a hit canvas or defer to a layer (source) to get matching features for a pixel. For now this is only implemented for vector layers, and it uses a bbox query because we cannot refine the result because of missing geometry intersection functions yet.
This commit is contained in:
@@ -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 geojson = new ol.parser.GeoJSON();
|
||||||
var url = 'data/countries.json';
|
var url = 'data/countries.json';
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
@exportProperty ol.Map.prototype.addLayer
|
@exportProperty ol.Map.prototype.addLayer
|
||||||
@exportProperty ol.Map.prototype.addPreRenderFunction
|
@exportProperty ol.Map.prototype.addPreRenderFunction
|
||||||
@exportProperty ol.Map.prototype.addPreRenderFunctions
|
@exportProperty ol.Map.prototype.addPreRenderFunctions
|
||||||
|
@exportProperty ol.Map.prototype.getFeatureInfoForPixel
|
||||||
@exportProperty ol.Map.prototype.getInteractions
|
@exportProperty ol.Map.prototype.getInteractions
|
||||||
@exportProperty ol.Map.prototype.getRenderer
|
@exportProperty ol.Map.prototype.getRenderer
|
||||||
@exportProperty ol.Map.prototype.removeLayer
|
@exportProperty ol.Map.prototype.removeLayer
|
||||||
|
|||||||
@@ -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.<ol.layer.Layer>|undefined} opt_layers Layers to restrict the
|
||||||
|
* query to. All layers will be queried if not provided.
|
||||||
|
* @return {Array.<ol.Feature|string>} 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.
|
* @return {ol.Collection} Interactions.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -147,6 +147,12 @@ ol.MapBrowserEventHandler = function(map) {
|
|||||||
*/
|
*/
|
||||||
this.downListenerKey_ = null;
|
this.downListenerKey_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {?number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.moveListenerKey_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Array.<number>}
|
* @type {Array.<number>}
|
||||||
* @private
|
* @private
|
||||||
@@ -172,6 +178,9 @@ ol.MapBrowserEventHandler = function(map) {
|
|||||||
this.downListenerKey_ = goog.events.listen(element,
|
this.downListenerKey_ = goog.events.listen(element,
|
||||||
goog.events.EventType.MOUSEDOWN,
|
goog.events.EventType.MOUSEDOWN,
|
||||||
this.handleMouseDown_, false, this);
|
this.handleMouseDown_, false, this);
|
||||||
|
this.moveListenerKey_ = goog.events.listen(element,
|
||||||
|
goog.events.EventType.MOUSEMOVE,
|
||||||
|
this.relayMouseMove_, false, this);
|
||||||
// touch events
|
// touch events
|
||||||
this.touchListenerKeys_ = [
|
this.touchListenerKeys_ = [
|
||||||
goog.events.listen(element, [
|
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.
|
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||||
* @private
|
* @private
|
||||||
@@ -335,6 +357,7 @@ ol.MapBrowserEventHandler.prototype.handleTouchEnd_ = function(browserEvent) {
|
|||||||
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
|
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
|
||||||
goog.events.unlistenByKey(this.clickListenerKey_);
|
goog.events.unlistenByKey(this.clickListenerKey_);
|
||||||
goog.events.unlistenByKey(this.downListenerKey_);
|
goog.events.unlistenByKey(this.downListenerKey_);
|
||||||
|
goog.events.unlistenByKey(this.moveListenerKey_);
|
||||||
if (!goog.isNull(this.dragListenerKeys_)) {
|
if (!goog.isNull(this.dragListenerKeys_)) {
|
||||||
goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
|
goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
|
||||||
this.dragListenerKeys_ = null;
|
this.dragListenerKeys_ = null;
|
||||||
@@ -360,5 +383,6 @@ ol.MapBrowserEvent.EventType = {
|
|||||||
DRAGEND: 'dragend',
|
DRAGEND: 'dragend',
|
||||||
TOUCHSTART: goog.events.EventType.TOUCHSTART,
|
TOUCHSTART: goog.events.EventType.TOUCHSTART,
|
||||||
TOUCHMOVE: goog.events.EventType.TOUCHMOVE,
|
TOUCHMOVE: goog.events.EventType.TOUCHMOVE,
|
||||||
TOUCHEND: goog.events.EventType.TOUCHEND
|
TOUCHEND: goog.events.EventType.TOUCHEND,
|
||||||
|
MOUSEMOVE: goog.events.EventType.MOUSEMOVE
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -187,6 +187,26 @@ ol.renderer.canvas.VectorLayer.prototype.getTransform = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.Pixel} pixel Pixel coordinate relative to the map viewport.
|
||||||
|
* @return {Array.<ol.Feature>} 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.
|
* @param {goog.events.Event} event Layer change event.
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
Reference in New Issue
Block a user