Merge pull request #2109 from elemoine/visibleandinrange

Hit detection respects min and maxResolution
This commit is contained in:
Éric Lemoine
2014-05-25 14:43:44 +02:00
5 changed files with 72 additions and 9 deletions

View File

@@ -37,6 +37,20 @@ ol.layer.Layer = function(options) {
goog.inherits(ol.layer.Layer, ol.layer.Base); goog.inherits(ol.layer.Layer, ol.layer.Base);
/**
* Return `true` if the layer is visible, and if the passed resolution is
* between the layer's minResolution and maxResolution. The comparison is
* inclusive for `minResolution` and exclusive for `maxResolution`.
* @param {ol.layer.LayerState} layerState Layer state.
* @param {number} resolution Resolution.
* @return {boolean} The layer is visible at the given resolution.
*/
ol.layer.Layer.visibleAtResolution = function(layerState, resolution) {
return layerState.visible && resolution >= layerState.minResolution &&
resolution < layerState.maxResolution;
};
/** /**
* @inheritDoc * @inheritDoc
*/ */

View File

@@ -10,6 +10,7 @@ goog.require('ol');
goog.require('ol.css'); goog.require('ol.css');
goog.require('ol.dom'); goog.require('ol.dom');
goog.require('ol.layer.Image'); goog.require('ol.layer.Image');
goog.require('ol.layer.Layer');
goog.require('ol.layer.Tile'); goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector'); goog.require('ol.layer.Vector');
goog.require('ol.render.Event'); goog.require('ol.render.Event');
@@ -160,10 +161,8 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
layer = layerState.layer; layer = layerState.layer;
layerRenderer = this.getLayerRenderer(layer); layerRenderer = this.getLayerRenderer(layer);
goog.asserts.assertInstanceof(layerRenderer, ol.renderer.canvas.Layer); goog.asserts.assertInstanceof(layerRenderer, ol.renderer.canvas.Layer);
if (!layerState.visible || if (!ol.layer.Layer.visibleAtResolution(layerState, viewResolution) ||
layerState.sourceState != ol.source.State.READY || layerState.sourceState != ol.source.State.READY) {
viewResolution >= layerState.maxResolution ||
viewResolution < layerState.minResolution) {
continue; continue;
} }
layerRenderer.prepareFrame(frameState, layerState); layerRenderer.prepareFrame(frameState, layerState);

View File

@@ -99,11 +99,13 @@ ol.renderer.Map.prototype.forEachFeatureAtPixel =
layerFilter, thisArg2) { layerFilter, thisArg2) {
var layerStates = this.map_.getLayerGroup().getLayerStatesArray(); var layerStates = this.map_.getLayerGroup().getLayerStatesArray();
var numLayers = layerStates.length; var numLayers = layerStates.length;
var viewResolution = frameState.view2DState.resolution;
var i; var i;
for (i = numLayers - 1; i >= 0; --i) { for (i = numLayers - 1; i >= 0; --i) {
var layerState = layerStates[i]; var layerState = layerStates[i];
var layer = layerState.layer; var layer = layerState.layer;
if (layerState.visible && layerFilter.call(thisArg2, layer)) { if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) &&
layerFilter.call(thisArg2, layer)) {
var layerRenderer = this.getLayerRenderer(layer); var layerRenderer = this.getLayerRenderer(layer);
var result = layerRenderer.forEachFeatureAtPixel( var result = layerRenderer.forEachFeatureAtPixel(
coordinate, frameState, callback, thisArg); coordinate, frameState, callback, thisArg);

View File

@@ -17,6 +17,7 @@ goog.require('ol.Tile');
goog.require('ol.css'); goog.require('ol.css');
goog.require('ol.dom'); goog.require('ol.dom');
goog.require('ol.layer.Image'); goog.require('ol.layer.Image');
goog.require('ol.layer.Layer');
goog.require('ol.layer.Tile'); goog.require('ol.layer.Tile');
goog.require('ol.render.Event'); goog.require('ol.render.Event');
goog.require('ol.render.EventType'); goog.require('ol.render.EventType');
@@ -442,10 +443,8 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
var i, ii, layerState; var i, ii, layerState;
for (i = 0, ii = layerStatesArray.length; i < ii; ++i) { for (i = 0, ii = layerStatesArray.length; i < ii; ++i) {
layerState = layerStatesArray[i]; layerState = layerStatesArray[i];
if (layerState.visible && if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) &&
layerState.sourceState == ol.source.State.READY && layerState.sourceState == ol.source.State.READY) {
viewResolution < layerState.maxResolution &&
viewResolution >= layerState.minResolution) {
layerStatesToDraw.push(layerState); layerStatesToDraw.push(layerState);
} }
} }

View File

@@ -108,6 +108,55 @@ describe('ol.layer.Layer', function() {
}); });
describe('visibleAtResolution', function() {
var layer;
beforeEach(function() {
layer = new ol.layer.Layer({
source: new ol.source.Source({
projection: ol.proj.get('EPSG:4326')
})
});
});
afterEach(function() {
goog.dispose(layer);
});
it('returns false if layer is not visible', function() {
layer.setVisible(false);
layer.setMinResolution(3);
layer.setMaxResolution(5);
var layerState = layer.getLayerState();
expect(ol.layer.Layer.visibleAtResolution(layerState, 4)).to.be(false);
});
it('returns false if resolution lower than minResolution', function() {
layer.setVisible(true);
layer.setMinResolution(3);
layer.setMaxResolution(5);
var layerState = layer.getLayerState();
expect(ol.layer.Layer.visibleAtResolution(layerState, 2)).to.be(false);
});
it('returns false if resolution greater than maxResolution', function() {
layer.setVisible(true);
layer.setMinResolution(3);
layer.setMaxResolution(5);
var layerState = layer.getLayerState();
expect(ol.layer.Layer.visibleAtResolution(layerState, 6)).to.be(false);
});
it('returns true otherwise', function() {
layer.setVisible(true);
layer.setMinResolution(3);
layer.setMaxResolution(5);
var layerState = layer.getLayerState();
expect(ol.layer.Layer.visibleAtResolution(layerState, 4)).to.be(true);
});
});
describe('#getLayerState', function() { describe('#getLayerState', function() {
var layer; var layer;