Merge pull request #1032 from bbinet/minmax_resolution

Add support for layer min/maxResolution
This commit is contained in:
Bruno Binet
2013-09-19 09:11:16 -07:00
9 changed files with 254 additions and 21 deletions

View File

@@ -0,0 +1,65 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="../css/ol.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
<title>Min/max resolution example</title>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="./">OpenLayers 3 Examples</a>
<ul class="nav pull-right">
<li><iframe class="github-watch-button" src="http://ghbtns.com/github-btn.html?user=openlayers&repo=ol3&type=watch&count=true"
allowtransparency="true" frameborder="0" scrolling="0" height="20" width="90"></iframe></li>
<li><a href="https://twitter.com/share" class="twitter-share-button" data-count="none" data-hashtags="openlayers">&nbsp;</a></li>
<li><div class="g-plusone-wrapper"><div class="g-plusone" data-size="medium" data-annotation="none"></div></div></li>
</ul>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<h4 id="title">Min/max resolution example</h4>
<p id="shortdesc">Show/hide layers depending on current view resolution.</p>
<div id="docs">
<p>
Zoom in twice: the MapBox layer should hide whereas the OSM layer should be shown.
</p>
<p>
If you continue to zoom in, you'll see the OSM layer also disappear.
</p>
<p>
The rendering of the layers are here controlled using minResolution and maxResolution options.
</p>
<p>See the <a href="min-max-resolution.js" target="_blank">min-max-resolution.js source</a> to see how this is done.</p>
</div>
<div id="tags">minResolution, maxResolution, resolution</div>
</div>
</div>
</div>
<script src="loader.js?id=min-max-resolution" type="text/javascript"></script>
<script src="../resources/social-links.js" type="text/javascript"></script>
</body>
</html>

View File

@@ -0,0 +1,33 @@
goog.require('ol.Map');
goog.require('ol.View2D');
goog.require('ol.layer.Tile');
goog.require('ol.source.OSM');
goog.require('ol.source.TileJSON');
/**
* Create the map.
*/
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
minResolution: 200,
maxResolution: 2000
}),
new ol.layer.Tile({
source: new ol.source.TileJSON({
url: 'http://api.tiles.mapbox.com/v3/' +
'mapbox.natural-earth-hypso-bathy.jsonp',
crossOrigin: 'anonymous'
}),
minResolution: 2000,
maxResolution: 20000
})
],
target: 'map',
view: new ol.View2D({
center: [653600, 5723680],
zoom: 5
})
});

View File

@@ -337,6 +337,10 @@
* @property {number|undefined} opacity Opacity.
* @property {number|undefined} saturation Saturation.
* @property {boolean|undefined} visible Visibility.
* @property {number|undefined} minResolution The minimum resolution
* (inclusive) at which this layer will be visible.
* @property {number|undefined} maxResolution The maximum resolution
* (exclusive) below which this layer will be visible.
*/
/**
@@ -348,6 +352,10 @@
* @property {number|undefined} saturation Saturation.
* @property {ol.source.Source} source Source for this layer.
* @property {boolean|undefined} visible Visibility. Default is true (visible).
* @property {number|undefined} minResolution The minimum resolution
* (inclusive) at which this layer will be visible.
* @property {number|undefined} maxResolution The maximum resolution
* (exclusive) below which this layer will be visible.
*/
/**
@@ -358,6 +366,10 @@
* @property {number|undefined} opacity Opacity.
* @property {number|undefined} saturation Saturation.
* @property {boolean|undefined} visible Visibility.
* @property {number|undefined} minResolution The minimum resolution
* (inclusive) at which this layer will be visible.
* @property {number|undefined} maxResolution The maximum resolution
* (exclusive) below which this layer will be visible.
* @property {Array.<ol.layer.Base>|ol.Collection|undefined} layers Child layers.
*/
@@ -371,6 +383,10 @@
* @property {number|undefined} saturation Saturation.
* @property {ol.source.Source} source Source for this layer.
* @property {boolean|undefined} visible Visibility. Default is true (visible).
* @property {number|undefined} minResolution The minimum resolution
* (inclusive) at which this layer will be visible.
* @property {number|undefined} maxResolution The maximum resolution
* (exclusive) below which this layer will be visible.
*/
/**
@@ -383,6 +399,10 @@
* @property {ol.source.Source} source Source for this layer.
* @property {ol.style.Style|undefined} style Style.
* @property {boolean|undefined} visible Visibility. Default is true (visible).
* @property {number|undefined} minResolution The minimum resolution
* (inclusive) at which this layer will be visible.
* @property {number|undefined} maxResolution The maximum resolution
* (exclusive) below which this layer will be visible.
*/
/**

View File

@@ -18,7 +18,9 @@ ol.layer.LayerProperty = {
HUE: 'hue',
OPACITY: 'opacity',
SATURATION: 'saturation',
VISIBLE: 'visible'
VISIBLE: 'visible',
MAX_RESOLUTION: 'maxResolution',
MIN_RESOLUTION: 'minResolution'
};
@@ -29,7 +31,9 @@ ol.layer.LayerProperty = {
* opacity: number,
* ready: boolean,
* saturation: number,
* visible: boolean}}
* visible: boolean,
* maxResolution: number,
* minResolution: number}}
*/
ol.layer.LayerState;
@@ -58,6 +62,12 @@ ol.layer.Base = function(options) {
values.saturation = goog.isDef(values.saturation) ? values.saturation : 1;
/** @type {boolean} */
values.visible = goog.isDef(values.visible) ? values.visible : true;
/** @type {number} */
values.maxResolution = goog.isDef(values.maxResolution) ?
values.maxResolution : Infinity;
/** @type {number} */
values.minResolution = goog.isDef(values.minResolution) ?
values.minResolution : 0;
this.setValues(values);
@@ -67,6 +77,8 @@ ol.layer.Base = function(options) {
ol.Object.getChangeEventType(ol.layer.LayerProperty.HUE),
ol.Object.getChangeEventType(ol.layer.LayerProperty.OPACITY),
ol.Object.getChangeEventType(ol.layer.LayerProperty.SATURATION),
ol.Object.getChangeEventType(ol.layer.LayerProperty.MAX_RESOLUTION),
ol.Object.getChangeEventType(ol.layer.LayerProperty.MIN_RESOLUTION),
goog.events.EventType.LOAD
],
this.handleLayerChange, false, this);
@@ -134,6 +146,8 @@ ol.layer.Base.prototype.getLayerState = function() {
var ready = this.isReady();
var saturation = this.getSaturation();
var visible = this.getVisible();
var maxResolution = this.getMaxResolution();
var minResolution = this.getMinResolution();
return {
brightness: goog.isDef(brightness) ? goog.math.clamp(brightness, -1, 1) : 0,
contrast: goog.isDef(contrast) ? Math.max(contrast, 0) : 1,
@@ -141,7 +155,9 @@ ol.layer.Base.prototype.getLayerState = function() {
opacity: goog.isDef(opacity) ? goog.math.clamp(opacity, 0, 1) : 1,
ready: ready,
saturation: goog.isDef(saturation) ? Math.max(saturation, 0) : 1,
visible: goog.isDef(visible) ? !!visible : true
visible: goog.isDef(visible) ? !!visible : true,
maxResolution: goog.isDef(maxResolution) ? maxResolution : Infinity,
minResolution: goog.isDef(minResolution) ? Math.max(minResolution, 0) : 0
};
};
@@ -167,6 +183,32 @@ ol.layer.Base.prototype.getLayersArray = goog.abstractMethod;
ol.layer.Base.prototype.getLayerStatesArray = goog.abstractMethod;
/**
* @return {number} MaxResolution.
*/
ol.layer.Base.prototype.getMaxResolution = function() {
return /** @type {number} */ (
this.get(ol.layer.LayerProperty.MAX_RESOLUTION));
};
goog.exportProperty(
ol.layer.Base.prototype,
'getMaxResolution',
ol.layer.Base.prototype.getMaxResolution);
/**
* @return {number} MinResolution.
*/
ol.layer.Base.prototype.getMinResolution = function() {
return /** @type {number} */ (
this.get(ol.layer.LayerProperty.MIN_RESOLUTION));
};
goog.exportProperty(
ol.layer.Base.prototype,
'getMinResolution',
ol.layer.Base.prototype.getMinResolution);
/**
* @return {number} Opacity.
*/
@@ -288,6 +330,30 @@ goog.exportProperty(
ol.layer.Base.prototype.setHue);
/**
* @param {number} maxResolution MaxResolution.
*/
ol.layer.Base.prototype.setMaxResolution = function(maxResolution) {
this.set(ol.layer.LayerProperty.MAX_RESOLUTION, maxResolution);
};
goog.exportProperty(
ol.layer.Base.prototype,
'setMaxResolution',
ol.layer.Base.prototype.setMaxResolution);
/**
* @param {number} minResolution MinResolution.
*/
ol.layer.Base.prototype.setMinResolution = function(minResolution) {
this.set(ol.layer.LayerProperty.MIN_RESOLUTION, minResolution);
};
goog.exportProperty(
ol.layer.Base.prototype,
'setMinResolution',
ol.layer.Base.prototype.setMinResolution);
/**
* @param {number} opacity Opacity.
*/

View File

@@ -206,6 +206,10 @@ ol.layer.Group.prototype.getLayerStatesArray = function(opt_obj) {
layerState.opacity *= ownLayerState.opacity;
layerState.saturation *= ownLayerState.saturation;
layerState.visible = layerState.visible && ownLayerState.visible;
layerState.maxResolution = Math.min(
layerState.maxResolution, ownLayerState.maxResolution);
layerState.minResolution = Math.max(
layerState.minResolution, ownLayerState.minResolution);
}
return obj;

View File

@@ -114,13 +114,16 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
var layerStates = frameState.layerStates;
var layersArray = frameState.layersArray;
var viewResolution = frameState.view2DState.resolution;
var i, ii, image, layer, layerRenderer, layerState, transform;
for (i = 0, ii = layersArray.length; i < ii; ++i) {
layer = layersArray[i];
layerRenderer = this.getLayerRenderer(layer);
layerState = layerStates[goog.getUid(layer)];
if (!layerState.visible || !layerState.ready) {
if (!layerState.visible || !layerState.ready ||
viewResolution >= layerState.maxResolution ||
viewResolution < layerState.minResolution) {
continue;
}
layerRenderer.renderFrame(frameState, layerState);

View File

@@ -551,12 +551,15 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
++this.textureCacheFrameMarkerCount_;
var layersArray = frameState.layersArray;
var viewResolution = frameState.view2DState.resolution;
var i, ii, layer, layerRenderer, layerState;
for (i = 0, ii = layersArray.length; i < ii; ++i) {
layer = layersArray[i];
layerRenderer = this.getLayerRenderer(layer);
layerState = frameState.layerStates[goog.getUid(layer)];
if (layerState.visible && layerState.ready) {
if (layerState.visible && layerState.ready &&
viewResolution < layerState.maxResolution &&
viewResolution >= layerState.minResolution) {
layerRenderer.renderFrame(frameState, layerState);
}
}
@@ -580,10 +583,11 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
var currentProgram = null;
var locations;
for (i = 0, ii = layersArray.length; i < ii; ++i) {
layer = layersArray[i];
layerState = frameState.layerStates[goog.getUid(layer)];
if (!layerState.visible || !layerState.ready) {
if (!layerState.visible || !layerState.ready ||
viewResolution >= layerState.maxResolution ||
viewResolution < layerState.minResolution) {
continue;
}
var useColor =

View File

@@ -54,7 +54,9 @@ describe('ol.layer.Layer', function() {
opacity: 1,
saturation: 1,
visible: true,
ready: true
ready: true,
maxResolution: Infinity,
minResolution: 0
});
});
@@ -73,6 +75,8 @@ describe('ol.layer.Layer', function() {
opacity: 0.5,
saturation: 5,
visible: false,
maxResolution: 500,
minResolution: 0.25,
foo: 42
});
@@ -82,6 +86,8 @@ describe('ol.layer.Layer', function() {
expect(layer.getOpacity()).to.be(0.5);
expect(layer.getSaturation()).to.be(5);
expect(layer.getVisible()).to.be(false);
expect(layer.getMaxResolution()).to.be(500);
expect(layer.getMinResolution()).to.be(0.25);
expect(layer.get('foo')).to.be(42);
expect(layer.getLayerState()).to.eql({
brightness: 0.5,
@@ -90,7 +96,9 @@ describe('ol.layer.Layer', function() {
opacity: 0.5,
saturation: 5,
visible: false,
ready: true
ready: true,
maxResolution: 500,
minResolution: 0.25
});
goog.dispose(layer);
@@ -121,6 +129,8 @@ describe('ol.layer.Layer', function() {
layer.setOpacity(0.3);
layer.setSaturation(0.3);
layer.setVisible(false);
layer.setMaxResolution(500);
layer.setMinResolution(0.25);
expect(layer.getLayerState()).to.eql({
brightness: -0.7,
contrast: 0.3,
@@ -128,7 +138,9 @@ describe('ol.layer.Layer', function() {
opacity: 0.3,
saturation: 0.3,
visible: false,
ready: true
ready: true,
maxResolution: 500,
minResolution: 0.25
});
});
@@ -146,7 +158,9 @@ describe('ol.layer.Layer', function() {
opacity: 0,
saturation: 0,
visible: false,
ready: true
ready: true,
maxResolution: Infinity,
minResolution: 0
});
layer.setBrightness(-3);
@@ -162,7 +176,9 @@ describe('ol.layer.Layer', function() {
opacity: 1,
saturation: 42,
visible: true,
ready: true
ready: true,
maxResolution: Infinity,
minResolution: 0
});
});

View File

@@ -50,7 +50,9 @@ describe('ol.layer.Group', function() {
opacity: 1,
saturation: 1,
visible: true,
ready: true
ready: true,
maxResolution: Infinity,
minResolution: 0
});
});
@@ -76,7 +78,9 @@ describe('ol.layer.Group', function() {
hue: 180,
opacity: 0.5,
saturation: 5,
visible: false
visible: false,
maxResolution: 500,
minResolution: 0.25
});
expect(layerGroup.getBrightness()).to.be(0.5);
@@ -85,6 +89,8 @@ describe('ol.layer.Group', function() {
expect(layerGroup.getOpacity()).to.be(0.5);
expect(layerGroup.getSaturation()).to.be(5);
expect(layerGroup.getVisible()).to.be(false);
expect(layerGroup.getMaxResolution()).to.be(500);
expect(layerGroup.getMinResolution()).to.be(0.25);
expect(layerGroup.getLayerState()).to.eql({
brightness: 0.5,
contrast: 10,
@@ -92,7 +98,9 @@ describe('ol.layer.Group', function() {
opacity: 0.5,
saturation: 5,
visible: false,
ready: true
ready: true,
maxResolution: 500,
minResolution: 0.25
});
expect(layerGroup.getLayers()).to.be.a(ol.Collection);
expect(layerGroup.getLayers().getLength()).to.be(1);
@@ -123,6 +131,8 @@ describe('ol.layer.Group', function() {
layerGroup.setOpacity(0.3);
layerGroup.setSaturation(0.3);
layerGroup.setVisible(false);
layerGroup.setMaxResolution(500);
layerGroup.setMinResolution(0.25);
expect(layerGroup.getLayerState()).to.eql({
brightness: -0.7,
contrast: 0.3,
@@ -130,7 +140,9 @@ describe('ol.layer.Group', function() {
opacity: 0.3,
saturation: 0.3,
visible: false,
ready: true
ready: true,
maxResolution: 500,
minResolution: 0.25
});
});
@@ -148,7 +160,9 @@ describe('ol.layer.Group', function() {
opacity: 0,
saturation: 0,
visible: false,
ready: true
ready: true,
maxResolution: Infinity,
minResolution: 0
});
layerGroup.setBrightness(-3);
@@ -164,7 +178,9 @@ describe('ol.layer.Group', function() {
opacity: 1,
saturation: 42,
visible: true,
ready: true
ready: true,
maxResolution: Infinity,
minResolution: 0
});
});
@@ -231,7 +247,9 @@ describe('ol.layer.Group', function() {
hue: 180,
opacity: 0.5,
saturation: 5,
visible: false
visible: false,
maxResolution: 500,
minResolution: 0.25
});
it('does not transform layerStates by default', function() {
@@ -263,7 +281,9 @@ describe('ol.layer.Group', function() {
hue: 180,
opacity: 0.5,
saturation: 5,
visible: false
visible: false,
maxResolution: 150,
minResolution: 0.2
});
obj = layerGroup.getLayerStatesArray();
@@ -277,7 +297,9 @@ describe('ol.layer.Group', function() {
opacity: 0.25,
saturation: 25,
visible: false,
ready: true
ready: true,
maxResolution: 150,
minResolution: 0.25
});
goog.dispose(layerGroup);