fix and rewrite initResolutions, see <http://trac.openlayers.org/ticket/2427#comment:18> for a detailed explanation on the changes brought by this changeset, r=ahocevar (closes #2427)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@10301 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -82,7 +82,19 @@ OpenLayers.Layer = OpenLayers.Class({
|
||||
*/
|
||||
EVENT_TYPES: ["loadstart", "loadend", "loadcancel", "visibilitychanged",
|
||||
"move", "moveend"],
|
||||
|
||||
|
||||
/**
|
||||
* Constant: RESOLUTION_PROPERTIES
|
||||
* {Array} The properties that are used for calculating resolutions
|
||||
* information.
|
||||
*/
|
||||
RESOLUTION_PROPERTIES: [
|
||||
'scales', 'resolutions',
|
||||
'maxScale', 'minScale',
|
||||
'maxResolution', 'minResolution',
|
||||
'numZoomLevels', 'maxZoomLevel'
|
||||
],
|
||||
|
||||
/**
|
||||
* APIProperty: events
|
||||
* {<OpenLayers.Events>}
|
||||
@@ -529,6 +541,7 @@ OpenLayers.Layer = OpenLayers.Class({
|
||||
// grab some essential layer data from the map if it hasn't already
|
||||
// been set
|
||||
this.maxExtent = this.maxExtent || this.map.maxExtent;
|
||||
this.minExtent = this.minExtent || this.map.minExtent;
|
||||
this.projection = this.projection || this.map.projection;
|
||||
|
||||
if (this.projection && typeof this.projection == "string") {
|
||||
@@ -734,184 +747,242 @@ OpenLayers.Layer = OpenLayers.Class({
|
||||
*/
|
||||
initResolutions: function() {
|
||||
|
||||
// These are the relevant options which are used for calculating
|
||||
// resolutions information.
|
||||
// ok we want resolutions, here's our strategy:
|
||||
//
|
||||
var props = new Array(
|
||||
'projection', 'units',
|
||||
'scales', 'resolutions',
|
||||
'maxScale', 'minScale',
|
||||
'maxResolution', 'minResolution',
|
||||
'minExtent', 'maxExtent',
|
||||
'numZoomLevels', 'maxZoomLevel'
|
||||
);
|
||||
// 1. if resolutions are defined in the layer config, use them
|
||||
// 2. else, if scales are defined in the layer config then derive
|
||||
// resolutions from these scales
|
||||
// 3. else, attempt to calculate resolutions from maxResolution,
|
||||
// minResolution, numZoomLevels, maxZoomLevel set in the
|
||||
// layer config
|
||||
// 4. if we still don't have resolutions, and if resolutions
|
||||
// are defined in the same, use them
|
||||
// 5. else, if scales are defined in the map then derive
|
||||
// resolutions from these scales
|
||||
// 6. else, attempt to calculate resolutions from maxResolution,
|
||||
// minResolution, numZoomLevels, maxZoomLevel set in the
|
||||
// map
|
||||
// 7. hope for the best!
|
||||
|
||||
//these are the properties which do *not* imply that user wishes
|
||||
// this layer to be scale-dependant
|
||||
var notScaleProps = ['projection', 'units'];
|
||||
var i, len;
|
||||
var props = {}, alwaysInRange = true;
|
||||
|
||||
//should the layer be scale-dependant? default is false -- this will
|
||||
// only be set true if we find that the user has specified a property
|
||||
// from the 'props' array that is not in 'notScaleProps'
|
||||
var useInRange = false;
|
||||
|
||||
// First we create a new object where we will store all of the
|
||||
// resolution-related properties that we find in either the layer's
|
||||
// 'options' array or from the map.
|
||||
//
|
||||
var confProps = {};
|
||||
for(var i=0, len=props.length; i<len; i++) {
|
||||
var property = props[i];
|
||||
|
||||
// If the layer had one of these properties set *and* it is
|
||||
// a scale property (is not a non-scale property), then we assume
|
||||
// the user did intend to use scale-dependant display (useInRange).
|
||||
if (this.options[property] &&
|
||||
OpenLayers.Util.indexOf(notScaleProps, property) == -1) {
|
||||
useInRange = true;
|
||||
// get resolution data from layer config
|
||||
// (we also set alwaysInRange in the layer as appropriate)
|
||||
for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) {
|
||||
var p = this.RESOLUTION_PROPERTIES[i]
|
||||
props[p] = this.options[p];
|
||||
if(alwaysInRange && this.options[p]) {
|
||||
alwaysInRange = false;
|
||||
}
|
||||
|
||||
confProps[property] = this.options[property] || this.map[property];
|
||||
}
|
||||
if(this.alwaysInRange == null) {
|
||||
this.alwaysInRange = alwaysInRange;
|
||||
}
|
||||
|
||||
//only automatically set 'alwaysInRange' if the user hasn't already
|
||||
// set it (to true or false, since the default is null). If user did
|
||||
// not intend to use scale-dependant display then we set they layer
|
||||
// as alwaysInRange. This means calculateInRange() will always return
|
||||
// true and the layer will never be turned off due to scale changes.
|
||||
//
|
||||
if (this.alwaysInRange == null) {
|
||||
this.alwaysInRange = !useInRange;
|
||||
// if we don't have resolutions then attempt to derive them from scales
|
||||
if(props.resolutions == null) {
|
||||
props.resolutions = this.resolutionsFromScales(props.scales);
|
||||
}
|
||||
|
||||
// Do not use the scales array set at the map level if
|
||||
// either minScale or maxScale or both are set at the
|
||||
// layer level
|
||||
if ((this.options.minScale != null ||
|
||||
this.options.maxScale != null) &&
|
||||
this.options.scales == null) {
|
||||
|
||||
confProps.scales = null;
|
||||
}
|
||||
// Do not use the resolutions array set at the map level if
|
||||
// either minResolution or maxResolution or both are set at the
|
||||
// layer level
|
||||
if ((this.options.minResolution != null ||
|
||||
this.options.maxResolution != null) &&
|
||||
this.options.resolutions == null) {
|
||||
|
||||
confProps.resolutions = null;
|
||||
// if we still don't have resolutions then attempt to calculate them
|
||||
if(props.resolutions == null) {
|
||||
props.resolutions = this.calculateResolutions(props);
|
||||
}
|
||||
|
||||
// If numZoomLevels hasn't been set and the maxZoomLevel *has*,
|
||||
// then use maxZoomLevel to calculate numZoomLevels
|
||||
//
|
||||
if ( (!confProps.numZoomLevels) && (confProps.maxZoomLevel) ) {
|
||||
confProps.numZoomLevels = confProps.maxZoomLevel + 1;
|
||||
}
|
||||
|
||||
// First off, we take whatever hodge-podge of values we have and
|
||||
// calculate/distill them down into a resolutions[] array
|
||||
//
|
||||
if ((confProps.scales != null) || (confProps.resolutions != null)) {
|
||||
//preset levels
|
||||
if (confProps.scales != null) {
|
||||
confProps.resolutions = [];
|
||||
for(var i=0, len=confProps.scales.length; i<len; i++) {
|
||||
var scale = confProps.scales[i];
|
||||
confProps.resolutions[i] =
|
||||
OpenLayers.Util.getResolutionFromScale(scale,
|
||||
confProps.units);
|
||||
}
|
||||
// if we couldn't calculate resolutions then we look at we have
|
||||
// in the map
|
||||
if(props.resolutions == null) {
|
||||
for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) {
|
||||
var p = this.RESOLUTION_PROPERTIES[i]
|
||||
props[p] = this.options[p] != null ?
|
||||
this.options[p] : this.map[p];
|
||||
}
|
||||
confProps.numZoomLevels = confProps.resolutions.length;
|
||||
if(props.resolutions == null) {
|
||||
props.resolutions = this.resolutionsFromScales(props.scales);
|
||||
}
|
||||
if(props.resolutions == null) {
|
||||
props.resolutions = this.calculateResolutions(props);
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we new need to set properties in the instance
|
||||
|
||||
// get maxResolution from the config if it's defined there
|
||||
var maxResolution;
|
||||
if(this.options.maxResolution &&
|
||||
this.options.maxResolution !== "auto") {
|
||||
maxResolution = this.options.maxResolution;
|
||||
}
|
||||
if(this.options.minScale) {
|
||||
maxResolution = OpenLayers.Util.getResolutionFromScale(
|
||||
this.options.minScale, this.units);
|
||||
}
|
||||
|
||||
// get minResolution from the config if it's defined there
|
||||
var minResolution;
|
||||
if(this.options.minResolution &&
|
||||
this.options.minResolution !== "auto") {
|
||||
minResolution = this.options.minResolution;
|
||||
}
|
||||
if(this.options.maxScale) {
|
||||
minResolution = OpenLayers.Util.getResolutionFromScale(
|
||||
this.options.maxScale, this.units);
|
||||
}
|
||||
|
||||
if(props.resolutions) {
|
||||
|
||||
//sort resolutions array descendingly
|
||||
props.resolutions.sort(function(a, b) {
|
||||
return (b - a);
|
||||
});
|
||||
|
||||
// if we still don't have a maxResolution get it from the
|
||||
// resolutions array
|
||||
if(!maxResolution) {
|
||||
maxResolution = props.resolutions[0];
|
||||
}
|
||||
|
||||
// if we still don't have a minResolution get it from the
|
||||
// resolutions array
|
||||
if(!minResolution) {
|
||||
var lastIdx = props.resolutions.length - 1;
|
||||
minResolution = props.resolutions[lastIdx];
|
||||
}
|
||||
}
|
||||
|
||||
this.resolutions = props.resolutions;
|
||||
if(this.resolutions) {
|
||||
len = this.resolutions.length;
|
||||
this.scales = new Array(len);
|
||||
for(i=0; i<len; i++) {
|
||||
this.scales[i] = OpenLayers.Util.getScaleFromResolution(
|
||||
this.resolutions[i], this.units);
|
||||
}
|
||||
this.numZoomLevels = len;
|
||||
}
|
||||
this.minResolution = minResolution;
|
||||
if(minResolution) {
|
||||
this.maxScale = OpenLayers.Util.getScaleFromResolution(
|
||||
minResolution, this.units);
|
||||
}
|
||||
this.maxResolution = maxResolution;
|
||||
if(maxResolution) {
|
||||
this.minScale = OpenLayers.Util.getScaleFromResolution(
|
||||
maxResolution, this.units);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: resolutionsFromScales
|
||||
* Derive resolutions from scales.
|
||||
*
|
||||
* Parameters:
|
||||
* scales - {Array(Number)} Scales
|
||||
*
|
||||
* Returns
|
||||
* {Array(Number)} Resolutions
|
||||
*/
|
||||
resolutionsFromScales: function(scales) {
|
||||
if(scales == null) {
|
||||
return;
|
||||
}
|
||||
var resolutions, i, len;
|
||||
len = scales.length;
|
||||
resolutions = new Array(len);
|
||||
for(i=0; i<len; i++) {
|
||||
resolutions[i] = OpenLayers.Util.getResolutionFromScale(
|
||||
scales[i], this.units);
|
||||
}
|
||||
return resolutions
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: calculateResolutions
|
||||
* Calculate resolutions based on the provided properties.
|
||||
*
|
||||
* Parameters:
|
||||
* props - {Object} Properties
|
||||
*
|
||||
* Return:
|
||||
* {Array({Number})} Array of resolutions.
|
||||
*/
|
||||
calculateResolutions: function(props) {
|
||||
|
||||
// determine maxResolution
|
||||
var maxResolution = props.maxResolution;
|
||||
if(props.minScale != null) {
|
||||
maxResolution =
|
||||
OpenLayers.Util.getResolutionFromScale(props.minScale,
|
||||
this.units);
|
||||
} else if(maxResolution == "auto" && this.maxExtent != null) {
|
||||
var viewSize = this.map.getSize();
|
||||
var wRes = this.maxExtent.getWidth() / viewSize.w;
|
||||
var hRes = this.maxExtent.getHeight() / viewSize.h;
|
||||
maxResolution = Math.max(wRes, hRes);
|
||||
}
|
||||
|
||||
// determine minResolution
|
||||
var minResolution = props.minResolution;
|
||||
if(props.maxScale != null) {
|
||||
minResolution =
|
||||
OpenLayers.Util.getResolutionFromScale(props.maxScale,
|
||||
this.units);
|
||||
} else if(props.minResolution == "auto" && this.minExtent != null) {
|
||||
var viewSize = this.map.getSize();
|
||||
var wRes = this.minExtent.getWidth() / viewSize.w;
|
||||
var hRes = this.minExtent.getHeight()/ viewSize.h;
|
||||
minResolution = Math.max(wRes, hRes);
|
||||
}
|
||||
|
||||
// determine numZoomLevels
|
||||
var maxZoomLevel = props.maxZoomLevel;
|
||||
var numZoomLevels = props.numZoomLevels;
|
||||
if(typeof minResolution === "number" &&
|
||||
typeof maxResolution === "number" && numZoomLevels === undefined) {
|
||||
var ratio = maxResolution / minResolution;
|
||||
numZoomLevels = Math.floor(Math.log(ratio) / Math.log(2)) + 1;
|
||||
} else if(numZoomLevels === undefined && maxZoomLevel != null) {
|
||||
numZoomLevels = maxZoomLevel + 1;
|
||||
}
|
||||
|
||||
// are we able to calculate resolutions?
|
||||
if(typeof numZoomLevels !== "number" || numZoomLevels <= 0 ||
|
||||
(typeof maxResolution !== "number" &&
|
||||
typeof minResolution !== "number")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// now we have numZoomLevels and at least one of maxResolution
|
||||
// or minResolution, we can populate the resolutions array
|
||||
|
||||
var resolutions = new Array(numZoomLevels);
|
||||
var base = 2;
|
||||
if(typeof minResolution == "number" &&
|
||||
typeof maxResolution == "number") {
|
||||
// if maxResolution and minResolution are set, we calculate
|
||||
// the base for exponential scaling that starts at
|
||||
// maxResolution and ends at minResolution in numZoomLevels
|
||||
// steps.
|
||||
base = Math.pow(
|
||||
(maxResolution / minResolution),
|
||||
(1 / (numZoomLevels - 1))
|
||||
);
|
||||
}
|
||||
|
||||
var i;
|
||||
if(typeof maxResolution === "number") {
|
||||
for(i=0; i<numZoomLevels; i++) {
|
||||
resolutions[i] = maxResolution / Math.pow(base, i);
|
||||
}
|
||||
} else {
|
||||
//maxResolution and numZoomLevels based calculation
|
||||
|
||||
// determine maxResolution
|
||||
if (confProps.minScale) {
|
||||
confProps.maxResolution =
|
||||
OpenLayers.Util.getResolutionFromScale(confProps.minScale,
|
||||
confProps.units);
|
||||
} else if (confProps.maxResolution == "auto") {
|
||||
var viewSize = this.map.getSize();
|
||||
var wRes = confProps.maxExtent.getWidth() / viewSize.w;
|
||||
var hRes = confProps.maxExtent.getHeight()/ viewSize.h;
|
||||
confProps.maxResolution = Math.max(wRes, hRes);
|
||||
}
|
||||
|
||||
// determine minResolution
|
||||
if (confProps.maxScale != null) {
|
||||
confProps.minResolution =
|
||||
OpenLayers.Util.getResolutionFromScale(confProps.maxScale,
|
||||
confProps.units);
|
||||
} else if ( (confProps.minResolution == "auto") &&
|
||||
(confProps.minExtent != null) ) {
|
||||
var viewSize = this.map.getSize();
|
||||
var wRes = confProps.minExtent.getWidth() / viewSize.w;
|
||||
var hRes = confProps.minExtent.getHeight()/ viewSize.h;
|
||||
confProps.minResolution = Math.max(wRes, hRes);
|
||||
}
|
||||
|
||||
// determine numZoomLevels if not already set on the layer
|
||||
// this gives numZoomLevels assuming approximately base 2 scaling
|
||||
if (confProps.minResolution != null &&
|
||||
this.options.numZoomLevels == undefined) {
|
||||
var ratio = confProps.maxResolution / confProps.minResolution;
|
||||
confProps.numZoomLevels =
|
||||
Math.floor(Math.log(ratio) / Math.log(2)) + 1;
|
||||
}
|
||||
|
||||
// now we have numZoomLevels and maxResolution,
|
||||
// we can populate the resolutions array
|
||||
confProps.resolutions = new Array(confProps.numZoomLevels);
|
||||
var base = 2;
|
||||
if(typeof confProps.minResolution == "number" &&
|
||||
confProps.numZoomLevels > 1) {
|
||||
/**
|
||||
* If maxResolution and minResolution are set (or related
|
||||
* scale properties), we calculate the base for exponential
|
||||
* scaling that starts at maxResolution and ends at
|
||||
* minResolution in numZoomLevels steps.
|
||||
*/
|
||||
base = Math.pow(
|
||||
(confProps.maxResolution / confProps.minResolution),
|
||||
(1 / (confProps.numZoomLevels - 1))
|
||||
);
|
||||
}
|
||||
for (var i=0; i < confProps.numZoomLevels; i++) {
|
||||
var res = confProps.maxResolution / Math.pow(base, i);
|
||||
confProps.resolutions[i] = res;
|
||||
for(i=0; i<numZoomLevels; i++) {
|
||||
resolutions[numZoomLevels - 1 - i] =
|
||||
minResolution * Math.pow(base, i);
|
||||
}
|
||||
}
|
||||
|
||||
//sort resolutions array ascendingly
|
||||
//
|
||||
confProps.resolutions.sort( function(a, b) { return(b-a); } );
|
||||
|
||||
// now set our newly calculated values back to the layer
|
||||
// Note: We specifically do *not* set them to layer.options, which we
|
||||
// will preserve as it was when we added this layer to the map.
|
||||
// this way cloned layers reset themselves to new map div
|
||||
// dimensions)
|
||||
//
|
||||
|
||||
this.resolutions = confProps.resolutions;
|
||||
this.maxResolution = confProps.resolutions[0];
|
||||
var lastIndex = confProps.resolutions.length - 1;
|
||||
this.minResolution = confProps.resolutions[lastIndex];
|
||||
|
||||
this.scales = [];
|
||||
for(var i=0, len=confProps.resolutions.length; i<len; i++) {
|
||||
this.scales[i] =
|
||||
OpenLayers.Util.getScaleFromResolution(confProps.resolutions[i],
|
||||
confProps.units);
|
||||
}
|
||||
this.minScale = this.scales[0];
|
||||
this.maxScale = this.scales[this.scales.length - 1];
|
||||
|
||||
this.numZoomLevels = confProps.numZoomLevels;
|
||||
return resolutions;
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
376
tests/Layer.html
376
tests/Layer.html
@@ -35,6 +35,7 @@
|
||||
t.ok( layer.options instanceof Object, "layer.options correctly initialized as a non-null Object" );
|
||||
}
|
||||
|
||||
|
||||
function test_Layer_clone (t) {
|
||||
t.plan( 7 );
|
||||
|
||||
@@ -144,83 +145,310 @@
|
||||
layer2.destroy();
|
||||
}
|
||||
|
||||
function test_Layer_initResolutions(t) {
|
||||
t.plan(15);
|
||||
var map = new OpenLayers.Map("map");
|
||||
var options, layer;
|
||||
|
||||
// tests for minResolution, maxResolution, and numZoomLevels
|
||||
options = {
|
||||
minResolution: 1.5,
|
||||
maxResolution: 10.5,
|
||||
numZoomLevels: 5,
|
||||
map: map
|
||||
};
|
||||
layer = new OpenLayers.Layer("test", options);
|
||||
layer.initResolutions();
|
||||
t.eq(layer.minResolution.toPrecision(6), (1.5).toPrecision(6),
|
||||
"(with numZoomLevels) layer minResolution preserved");
|
||||
t.eq(layer.maxResolution.toPrecision(6), (10.5).toPrecision(6),
|
||||
"(with numZoomLevels) layer maxResolution preserved");
|
||||
t.eq(layer.numZoomLevels, 5, "(with numZoomLevels) layer numZoomLevels preserved");
|
||||
t.eq(layer.alwaysInRange, false, "Always in range is set to false due to passed options.")
|
||||
function test_initResolutions_alwaysInRange(t) {
|
||||
t.plan(3);
|
||||
|
||||
// three tests for minResolution, and maxResolution
|
||||
options = {
|
||||
minResolution: 1.5,
|
||||
maxResolution: 10.5,
|
||||
map: map
|
||||
};
|
||||
layer = new OpenLayers.Layer("test", options);
|
||||
layer.initResolutions();
|
||||
t.eq(layer.minResolution.toPrecision(6), (1.5).toPrecision(6),
|
||||
"(without numZoomLevels) layer minResolution preserved");
|
||||
t.eq(layer.maxResolution.toPrecision(6), (10.5).toPrecision(6),
|
||||
"(without numZoomLevels) layer maxResolution preserved");
|
||||
t.eq(layer.numZoomLevels, 3, "(without numZoomLevels) layer numZoomLevels calculated");
|
||||
|
||||
// three tests for minScale, maxScale, and numZoomLevels
|
||||
options = {
|
||||
minScale: 105,
|
||||
maxScale: 15,
|
||||
numZoomLevels: 10,
|
||||
map: map
|
||||
};
|
||||
layer = new OpenLayers.Layer("test", options);
|
||||
layer.initResolutions();
|
||||
t.eq(layer.minScale.toPrecision(6), (105).toPrecision(6),
|
||||
"(with numZoomLevels) layer minScale preserved");
|
||||
t.eq(layer.maxScale.toPrecision(6), (15).toPrecision(6),
|
||||
"(with numZoomLevels) layer maxScale preserved");
|
||||
t.eq(layer.numZoomLevels, 10, "(with numZoomLevels) layer numZoomLevels preserved");
|
||||
|
||||
// three tests for minScale, and maxScale
|
||||
options = {
|
||||
minScale: 1555,
|
||||
maxScale: 155,
|
||||
map: map
|
||||
};
|
||||
layer = new OpenLayers.Layer("test", options);
|
||||
layer.initResolutions();
|
||||
t.eq(layer.minScale.toPrecision(6), (1555).toPrecision(6),
|
||||
"(without numZoomLevels) layer minScale preserved");
|
||||
t.eq(layer.maxScale.toPrecision(6), (155).toPrecision(6),
|
||||
"(without numZoomLevels) layer maxScale preserved");
|
||||
t.eq(layer.numZoomLevels, 4, "(without numZoomLevels) layer numZoomLevels calculated");
|
||||
|
||||
layer = new OpenLayers.Layer("test", {'projection': 'EPSG:4326', 'map': map});
|
||||
layer.initResolutions();
|
||||
t.eq(layer.alwaysInRange, true, "always in range true if only get projection.");
|
||||
|
||||
OpenLayers.Layer.prototype.alwaysInRange = false;
|
||||
layer = new OpenLayers.Layer("test", {'projection': 'EPSG:4326', 'map': map});
|
||||
layer.initResolutions();
|
||||
t.eq(layer.alwaysInRange, false, "always in range true if overridden on prototype.");
|
||||
OpenLayers.Layer.prototype.alwaysInRange = null;
|
||||
var map, layer;
|
||||
|
||||
map = new OpenLayers.Map("map");
|
||||
layer = new OpenLayers.Layer("test", {maxResolution: 80, minResolution: 10});
|
||||
map.addLayer(layer);
|
||||
t.eq(layer.alwaysInRange, false,
|
||||
"alwaysInRange set to false due to passed options");
|
||||
map.destroy();
|
||||
|
||||
|
||||
|
||||
map = new OpenLayers.Map("map");
|
||||
layer = new OpenLayers.Layer("test", {projection: "EPSG:4326"});
|
||||
map.addLayer(layer);
|
||||
t.eq(layer.alwaysInRange, true,
|
||||
"alwaysInRange true if only get projection.");
|
||||
map.destroy();
|
||||
|
||||
map = new OpenLayers.Map("map");
|
||||
OpenLayers.Layer.prototype.alwaysInRange = false;
|
||||
layer = new OpenLayers.Layer("test", {'projection': 'EPSG:4326'});
|
||||
map.addLayer(layer);
|
||||
t.eq(layer.alwaysInRange, false,
|
||||
"alwaysInRange true if overridden on prototype.");
|
||||
OpenLayers.Layer.prototype.alwaysInRange = null;
|
||||
map.destroy();
|
||||
}
|
||||
|
||||
function test_initResolutions_resolutions(t) {
|
||||
|
||||
function initResolutionsTest(
|
||||
id, mapOptions, layerOptions,
|
||||
expectedResolutions, expectedMinResolution, expectedMaxResolution) {
|
||||
|
||||
// setup
|
||||
var map = new OpenLayers.Map("map", mapOptions);
|
||||
var layer = new OpenLayers.Layer(null, layerOptions);
|
||||
map.addLayer(layer);
|
||||
|
||||
// make resolution assertions
|
||||
t.eq(
|
||||
layer.resolutions.length, expectedResolutions.length,
|
||||
id + ": correct resolutions length"
|
||||
);
|
||||
// allow for floating point imprecision
|
||||
var got, exp, same = true;
|
||||
for (var i=0; i<expectedResolutions.length; ++i) {
|
||||
got = layer.resolutions[i];
|
||||
exp = expectedResolutions[i];
|
||||
if (got.toFixed(10) !== exp.toFixed(10)) {
|
||||
t.fail(id + ": bad resolutions - index " + i + " got " + got + " but expected " + exp);
|
||||
same = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (same) {
|
||||
t.ok(true, id + ": correct resolutions");
|
||||
}
|
||||
t.eq(
|
||||
layer.maxResolution, expectedMaxResolution,
|
||||
id + ": maxResolution set"
|
||||
);
|
||||
t.eq(
|
||||
layer.minResolution, expectedMinResolution,
|
||||
id + ": minResolution set"
|
||||
);
|
||||
|
||||
// teardown
|
||||
map.destroy();
|
||||
}
|
||||
|
||||
// each case is an array of id, map options, layer options, expected resolutions,
|
||||
// expected min resolution, and expected max resolution
|
||||
var cases = [[
|
||||
|
||||
/*
|
||||
* Batch 1: map defaults and sensible layer options
|
||||
*/
|
||||
|
||||
"1.0", null, {resolutions: [400, 200, 100]},
|
||||
[400, 200, 100], 100, 400
|
||||
], [
|
||||
"1.1", null, {resolutions: [400, 200, 100], minResolution: 150, maxResolution: 300},
|
||||
[400, 200, 100], 150, 300
|
||||
], [
|
||||
"1.2", null, {maxResolution: 4000, numZoomLevels: 3},
|
||||
[4000, 2000, 1000], 1000, 4000
|
||||
], [
|
||||
"1.3", null, {maxResolution: 4000, maxZoomLevel: 2},
|
||||
[4000, 2000, 1000], 1000, 4000
|
||||
], [
|
||||
"1.4", null, {minResolution: 40, numZoomLevels: 3},
|
||||
[160, 80, 40], 40, 160
|
||||
], [
|
||||
"1.5", null, {minResolution: 40, maxZoomLevel: 2},
|
||||
[160, 80, 40], 40, 160
|
||||
], [
|
||||
"1.6", null, {minResolution: 10, maxResolution: 40},
|
||||
[40, 20, 10], 10, 40
|
||||
], [
|
||||
"1.7", null, {minResolution: 10, maxResolution: 40, numZoomLevels: 3},
|
||||
[40, 20, 10], 10, 40
|
||||
], [
|
||||
"1.8", null, {minResolution: 10, maxResolution: 40, maxZoomLevel: 2},
|
||||
[40, 20, 10], 10, 40
|
||||
], [
|
||||
"1.9", null, {scales: [400000, 200000, 100000]},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"1.10", null, {scales: [400000, 200000, 100000], minScale: 400000, maxScale: 100000},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"1.11", null, {minScale: 400000, numZoomLevels: 3},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"1.12", null, {minScale: 400000, maxZoomLevel: 2},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"1.13", null, {maxScale: 100000, numZoomLevels: 3},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"1.14", null, {maxScale: 100000, maxZoomLevel: 2},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"1.15", null, {maxScale: 100000, minScale: 400000},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"1.16", null, {maxScale: 100000, minScale: 400000, numZoomLevels: 3},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"1.17", null, {maxScale: 100000, minScale: 400000, maxZoomLevel: 2},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"1.18", null, {scales: [400000, 200000, 100000], units: "m"},
|
||||
[141.11103491115225, 70.55551745557612, 35.27775872778806], 35.27775872778806, 141.11103491115225
|
||||
], [
|
||||
"1.19", null, {minScale: 400000, numZoomLevels: 3, units: "m"},
|
||||
[141.11103491115225, 70.55551745557612, 35.27775872778806], 35.27775872778806, 141.11103491115225
|
||||
], [
|
||||
"1.20", null, {maxScale: 100000, numZoomLevels: 3, units: "m"},
|
||||
[141.11103491115225, 70.55551745557612, 35.27775872778806], 35.27775872778806, 141.11103491115225
|
||||
], [
|
||||
|
||||
/*
|
||||
* Batch 2: custom map options map and sensible layer options
|
||||
*/
|
||||
|
||||
/*
|
||||
* Batch 2.1: resolutions set in the layer options
|
||||
*/
|
||||
"2.1.0", {resolutions: [300, 150]}, {resolutions: [400, 200, 100]},
|
||||
[400, 200, 100], 100, 400
|
||||
], [
|
||||
"2.1.1", {numZoomLevels: 4}, {resolutions: [400, 200, 100]},
|
||||
[400, 200, 100], 100, 400
|
||||
], [
|
||||
"2.1.2", {maxResolution: 300}, {resolutions: [400, 200, 100]},
|
||||
[400, 200, 100], 100, 400
|
||||
], [
|
||||
"2.1.3", {minResolution: 300}, {resolutions: [400, 200, 100]},
|
||||
[400, 200, 100], 100, 400
|
||||
], [
|
||||
"2.1.4", {scales: [4, 2, 1]}, {resolutions: [400, 200, 100]},
|
||||
[400, 200, 100], 100, 400
|
||||
], [
|
||||
"2.1.5", {minScale: 4}, {resolutions: [400, 200, 100]},
|
||||
[400, 200, 100], 100, 400
|
||||
], [
|
||||
"2.1.6", {maxScale: 4}, {resolutions: [400, 200, 100]},
|
||||
[400, 200, 100], 100, 400
|
||||
], [
|
||||
/*
|
||||
* Batch 2.2: minResolution and maxResolution set in the layer options
|
||||
*/
|
||||
"2.2.0", {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: 0},
|
||||
[80, 40, 20, 10], 12, 48
|
||||
], [
|
||||
"2.2.1", {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: -1},
|
||||
[80, 40, 20, 10], 12, 48
|
||||
], [
|
||||
"2.2.2", {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: null},
|
||||
[80, 40, 20, 10], 12, 48
|
||||
], [
|
||||
"2.2.3", {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: undefined},
|
||||
[48, 24, 12], 12, 48
|
||||
], [
|
||||
"2.2.4", {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: 3},
|
||||
[48, 24, 12], 12, 48
|
||||
], [
|
||||
"2.2.5", {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48},
|
||||
[48, 24, 12], 12, 48
|
||||
], [
|
||||
/*
|
||||
* Batch 2.3: maxResolution set in the layer options
|
||||
*/
|
||||
"2.3.0", {resolutions: [300, 150]}, {maxResolution: 4000, numZoomLevels: 3},
|
||||
[4000, 2000, 1000], 1000, 4000
|
||||
], [
|
||||
"2.3.1", {numZoomLevels: 2}, {maxResolution: 4000, numZoomLevels: 3},
|
||||
[4000, 2000, 1000], 1000, 4000
|
||||
], [
|
||||
"2.3.2", {maxResolution: 50}, {maxResolution: 4000, numZoomLevels: 3},
|
||||
[4000, 2000, 1000], 1000, 4000
|
||||
], [
|
||||
"2.3.3", {scales: [4, 2, 1]}, {maxResolution: 4000, numZoomLevels: 3},
|
||||
[4000, 2000, 1000], 1000, 4000
|
||||
], [
|
||||
"2.3.4", {minScale: 4}, {maxResolution: 4000, numZoomLevels: 3},
|
||||
[4000, 2000, 1000], 1000, 4000
|
||||
], [
|
||||
"2.3.5", {resolutions: [300, 150]}, {maxResolution: 250},
|
||||
[300, 150], 150, 250
|
||||
], [
|
||||
/*
|
||||
* Batch 2.4: minResolution set in the layer options
|
||||
*/
|
||||
"2.4.0", {resolutions: [300, 150]}, {minResolution: 40, numZoomLevels: 3},
|
||||
[160, 80, 40], 40, 160
|
||||
], [
|
||||
"2.4.1", {numZoomLevels: 2}, {minResolution: 40, numZoomLevels: 3},
|
||||
[160, 80, 40], 40, 160
|
||||
], [
|
||||
"2.4.2", {minResolution: 50}, {minResolution: 40, numZoomLevels: 3},
|
||||
[160, 80, 40], 40, 160
|
||||
], [
|
||||
"2.4.3", {scales: [4, 2, 1]}, {minResolution: 40, numZoomLevels: 3},
|
||||
[160, 80, 40], 40, 160
|
||||
], [
|
||||
"2.4.4", {maxScale: 1}, {minResolution: 40, numZoomLevels: 3},
|
||||
[160, 80, 40], 40, 160
|
||||
], [
|
||||
"2.4.5", {resolutions: [300, 150]}, {minResolution: 250},
|
||||
[300, 150], 250, 300
|
||||
], [
|
||||
/*
|
||||
* Batch 2.5: scales set in the layer options
|
||||
*/
|
||||
"2.5.0", {resolutions: [4, 2, 1]}, {scales: [400000, 200000, 100000]},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.5.1", {numZoomLevels: 2}, {scales: [400000, 200000, 100000]},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.5.2", {maxResolution: 4}, {scales: [400000, 200000, 100000]},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.5.3", {minResolution: 1}, {scales: [400000, 200000, 100000]},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.5.4", {units: "m"}, {scales: [400000, 200000, 100000]},
|
||||
[141.11103491115225, 70.55551745557612, 35.27775872778806], 35.27775872778806, 141.11103491115225
|
||||
], [
|
||||
/*
|
||||
* Batch 2.6: minScale set in the layer options
|
||||
*/
|
||||
"2.6.0", {resolutions: [4, 2, 1]}, {minScale: 400000, numZoomLevels: 3},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.6.1", {numZoomLevels: 2}, {minScale: 400000, numZoomLevels: 3},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.6.2", {maxResolution: 4}, {minScale: 400000, numZoomLevels: 3},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.6.3", {scales: [400000, 200000, 100000]}, {minScale: 200000},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0006349563376084181
|
||||
], [
|
||||
/*
|
||||
* Batch 2.7: maxScale set in the layer options
|
||||
*/
|
||||
"2.7.0", {resolutions: [4, 2, 1]}, {maxScale: 100000, numZoomLevels: 3},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.7.1", {numZoomLevels: 2}, {maxScale: 100000, numZoomLevels: 3},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.7.2", {minResolution: 1}, {maxScale: 100000, numZoomLevels: 3},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362
|
||||
], [
|
||||
"2.7.3", {scales: [400000, 200000, 100000]}, {maxScale: 200000},
|
||||
[0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.0006349563376084181, 0.0012699126752168362
|
||||
], [
|
||||
/*
|
||||
* Batch 2.8: numZoomLevels set in the layer options
|
||||
*/
|
||||
"2.8.0", {maxResolution: 80}, {numZoomLevels: 4},
|
||||
[80, 40, 20, 10], 10, 80
|
||||
], [
|
||||
"2.8.1", {maxResolution: 80, numZoomLevels: 4}, {numZoomLevels: null},
|
||||
[80, 40, 20, 10], 10, 80
|
||||
], [
|
||||
"2.8.2", {maxResolution: 80, numZoomLevels: 4}, {numZoomLevels: undefined},
|
||||
[80, 40, 20, 10], 10, 80
|
||||
]];
|
||||
|
||||
// run all cases (4 tests each)
|
||||
var i, num = cases.length, c;
|
||||
t.plan(num * 4);
|
||||
for (i=0; i<num; ++i) {
|
||||
c = cases[i];
|
||||
initResolutionsTest(c[0], c[1], c[2], c[3], c[4], c[5]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function test_Layer_visibility(t) {
|
||||
|
||||
Reference in New Issue
Block a user