Files
openlayers/tests/Map.html
ahocevar abdd3a2e5b Making sure that new base layer becomes visible.
The new base layer may previously have been out of range, in which case setVisibility(true) would do nothing if the layer was visible already. So we check if it was previously out of range, and redraw it if necessary.
2012-02-02 13:53:37 +01:00

2030 lines
77 KiB
HTML

<html>
<head>
<script>
/**
* Because browsers that implement requestAnimationFrame may not execute
* animation functions while a window is not displayed (e.g. in a hidden
* iframe as in these tests), we mask the native implementations here. The
* native requestAnimationFrame functionality is tested in Util.html and
* in PanZoom.html (where a popup is opened before panning). The panTo tests
* here will test the fallback setTimeout implementation for animation.
*/
window.requestAnimationFrame =
window.webkitRequestAnimationFrame =
window.mozRequestAnimationFrame =
window.oRequestAnimationFrame =
window.msRequestAnimationFrame = null;
</script>
<script src="OLLoader.js"></script>
<script type="text/javascript">
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var map;
function test_Map_constructor (t) {
t.plan( 11 );
map = new OpenLayers.Map('map');
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
map.addLayer(baseLayer);
t.ok( OpenLayers.Element.hasClass(map.div, "olMap"), "Map div has olMap class");
t.ok( map instanceof OpenLayers.Map, "new OpenLayers.Map returns object" );
if (!isMozilla) {
t.ok( true, "skipping element test outside of Mozilla");
t.ok( true, "skipping element test outside of Mozilla");
t.ok( true, "skipping element test outside of Mozilla");
} else {
t.ok( map.div instanceof HTMLDivElement, "map.div is an HTMLDivElement" );
t.ok( map.viewPortDiv instanceof HTMLDivElement, "map.viewPortDiv is an HTMLDivElement" );
t.ok( map.layerContainerDiv instanceof HTMLDivElement, "map.layerContainerDiv is an HTMLDivElement" );
}
t.ok( map.layers instanceof Array, "map.layers is an Array" );
t.ok( map.controls instanceof Array, "map.controls is an Array" );
t.eq( map.controls.length, 4, "Default map has 4 controls." );
t.ok( map.events instanceof OpenLayers.Events, "map.events is an OpenLayers.Events" );
t.ok( map.getMaxExtent() instanceof OpenLayers.Bounds, "map.maxExtent is an OpenLayers.Bounds" );
t.ok( map.getNumZoomLevels() > 0, "map has a default numZoomLevels" );
map.destroy();
}
function test_Map_constructor_convenience(t) {
t.plan(13);
var map = new OpenLayers.Map({
maxExtent: [-170, -80, 170, 80],
restrictedExtent: [-120, -65, 120, 65],
layers: [
new OpenLayers.Layer(null, {isBaseLayer: true})
],
center: [-111, 45],
zoom: 3
});
// maxExtent from array
t.ok(map.maxExtent instanceof OpenLayers.Bounds, "maxExtent bounds");
t.eq(map.maxExtent.left, -170, "maxExtent left");
t.eq(map.maxExtent.bottom, -80, "maxExtent bottom");
t.eq(map.maxExtent.right, 170, "maxExtent right");
t.eq(map.maxExtent.top, 80, "maxExtent top");
// restrictedExtent from array
t.ok(map.restrictedExtent instanceof OpenLayers.Bounds, "restrictedExtent bounds");
t.eq(map.restrictedExtent.left, -120, "restrictedExtent left");
t.eq(map.restrictedExtent.bottom, -65, "restrictedExtent bottom");
t.eq(map.restrictedExtent.right, 120, "restrictedExtent right");
t.eq(map.restrictedExtent.top, 65, "restrictedExtent top");
var center = map.getCenter();
t.eq(center.lon, -111, "center lon");
t.eq(center.lat, 45, "center lat");
t.eq(map.getZoom(), 3, "zoom");
map.destroy();
}
function test_Map_constructor_late_rendering(t) {
t.plan( 4 );
map = new OpenLayers.Map();
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
map.addLayer(baseLayer);
t.ok(map.div != null, "Map has a div even though none was specified.");
t.ok(map.viewPortDiv.parentNode == map.div, "Map is attached to a temporary div that holds the viewPortDiv.");
var mapDiv = document.getElementById("map");
// clean up the effects of other tests
while(OpenLayers.Element.hasClass(mapDiv, "olMap")) {
OpenLayers.Element.removeClass(mapDiv, "olMap");
}
map.render(mapDiv); // Can also take a string.
t.ok(map.div == mapDiv, "Map is now rendered to the 'map' div.")
t.ok( OpenLayers.Element.hasClass(map.div, "olMap"), "Map div has olMap class");
map.destroy();
}
function test_Map_constructor_renderTo(t) {
t.plan( 1 );
map = new OpenLayers.Map({
div: "map"
});
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
map.addLayer(baseLayer);
var mapDiv = document.getElementById("map");
t.ok(map.div == mapDiv, "Map is rendered to the 'map' div.")
map.destroy();
}
function test_Map_setOptions(t) {
t.plan(2);
map = new OpenLayers.Map('map', {maxExtent: new OpenLayers.Bounds(100, 200, 300, 400)});
map.setOptions({theme: 'foo'});
t.eq(map.theme, 'foo', "theme is correctly set by setOptions");
t.ok(map.maxExtent.equals(new OpenLayers.Bounds(100, 200, 300, 400)),
"maxExtent is correct after calling setOptions");
map.destroy();
}
function test_Map_add_layers(t) {
t.plan(8);
map = new OpenLayers.Map('map');
var layer1 = new OpenLayers.Layer.WMS("Layer 1",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
var layer2 = new OpenLayers.Layer.WMS("Layer 2",
"http://wms.jpl.nasa.gov/wms.cgi", {layers: "modis,global_mosaic"});
// this uses map.addLayer internally
map.addLayers([layer1, layer2])
t.eq( map.layers.length, 2, "map has exactly two layers" );
t.ok( map.layers[0] === layer1, "1st layer is layer1" );
t.ok( map.layers[1] === layer2, "2nd layer is layer2" );
t.ok( layer1.map === map, "layer.map is map" );
t.eq( parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'],
"layer1 zIndex is set" );
t.eq( parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5,
"layer2 zIndex is set" );
map.events.register('preaddlayer', this, function(evt) {
return !(evt.layer.name === 'donotadd');
});
var layer3 = new OpenLayers.Layer.WMS("donotadd",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
map.addLayers([layer3]);
t.eq(map.layers.length, 2, "layer is not added since preaddlayer returns false");
layer3.name = 'pleaseadd';
map.addLayers([layer3]);
t.eq(map.layers.length, 3, "layer is added since preaddlayer returns true");
map.destroy();
}
function test_Map_options(t) {
t.plan(3);
map = new OpenLayers.Map('map', {numZoomLevels: 6, maxResolution: 3.14159, theme: 'foo'});
t.eq( map.numZoomLevels, 6, "map.numZoomLevels set correctly via options hashtable" );
t.eq( map.maxResolution, 3.14159, "map.maxResolution set correctly via options hashtable" );
t.eq( map.theme, 'foo', "map theme set correctly." );
map.destroy();
}
function test_eventListeners(t) {
t.plan(1);
var method = OpenLayers.Events.prototype.on;
// test that events.on is called at map construction
var options = {
eventListeners: {foo: "bar"},
controls: []
};
OpenLayers.Events.prototype.on = function(obj) {
t.eq(obj, options.eventListeners, "events.on called with eventListeners");
}
var map = new OpenLayers.Map('map', options);
OpenLayers.Events.prototype.on = method;
map.destroy();
// if events.on is called again, this will fail due to an extra test
// test map without eventListeners
OpenLayers.Events.prototype.on = function(obj) {
t.fail("events.on called without eventListeners");
}
var map2 = new OpenLayers.Map("map", {controls: []});
OpenLayers.Events.prototype.on = method;
map2.destroy();
}
function test_Map_center(t) {
t.plan(14);
var log = [];
map = new OpenLayers.Map('map', {
eventListeners: {
"movestart": function() {log.push("movestart");},
"move": function() {log.push("move");},
"moveend": function() {log.push("moveend");}
}
});
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"} );
map.addLayer(baseLayer);
var ll = new OpenLayers.LonLat(2,1);
map.setCenter(ll, 0);
t.ok( map.getCenter() instanceof OpenLayers.LonLat, "map.getCenter returns a LonLat");
t.eq( map.getZoom(), 0, "map.zoom is correct after calling setCenter");
t.ok( map.getCenter().equals(ll), "map center is correct after calling setCenter");
map.zoomIn();
t.eq( map.getZoom(), 1, "map.zoom is correct after calling setCenter,zoom in");
t.ok( map.getCenter().equals(ll), "map center is correct after calling setCenter, zoom in");
map.zoomOut();
t.eq( map.getZoom(), 0, "map.zoom is correct after calling setCenter,zoom in, zoom out");
log = [];
map.zoomTo(5);
t.eq(log[0], "movestart", "zoomTo fires movestart event");
t.eq(log[1], "move", "zoomTo fires move event");
t.eq(log[2], "moveend", "zoomTo fires moveend event");
t.eq( map.getZoom(), 5, "map.zoom is correct after calling zoomTo" );
/**
map.zoomToMaxExtent();
t.eq( map.getZoom(), 2, "map.zoom is correct after calling zoomToMaxExtent" );
var lonlat = map.getCenter();
var zero = new OpenLayers.LonLat(0, 0);
t.ok( lonlat.equals(zero), "map center is correct after calling zoomToFullExtent" );
*/
map.getCenter().lon = 10;
t.ok( map.getCenter().equals(ll), "map.getCenter returns a clone of map.center");
// allow calling setCenter with an array
map.setCenter([4, 2]);
var center = map.getCenter();
t.ok(center instanceof OpenLayers.LonLat, "(array) center is lonlat");
t.eq(center.lon, 4, "(array) center lon");
t.eq(center.lat, 2, "(array) center lat");
map.destroy();
}
function test_Map_zoomend_event (t) {
t.plan(2);
map = new OpenLayers.Map('map');
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
map.addLayer(baseLayer);
map.events.register("zoomend", {count: 0}, function() {
this.count++;
t.ok(true, "zoomend event was triggered " + this.count + " times");
});
map.setCenter(new OpenLayers.LonLat(2, 1), 0);
map.zoomIn();
map.zoomOut();
map.destroy();
}
function test_Map_add_remove_popup (t) {
t.plan(4);
map = new OpenLayers.Map('map');
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
map.addLayer(baseLayer);
var popup = new OpenLayers.Popup("chicken",
new OpenLayers.LonLat(0,0),
new OpenLayers.Size(200,200));
map.setCenter(new OpenLayers.LonLat(0, 0), 0);
map.addPopup(popup);
var pIndex = OpenLayers.Util.indexOf(map.popups, popup);
t.eq(pIndex, 0, "popup successfully added to Map's internal popups array");
var nodes = map.layerContainerDiv.childNodes;
var found = false;
for (var i=0; i < nodes.length; i++) {
if (nodes.item(i) == popup.div) {
found = true;
break;
}
}
t.ok(found, "popup.div successfully added to the map's viewPort");
map.removePopup(popup);
var pIndex = OpenLayers.Util.indexOf(map.popups, popup);
t.eq(pIndex, -1, "popup successfully removed from Map's internal popups array");
var found = false;
for (var i=0; i < nodes.length; i++) {
if (nodes.item(i) == popup.div) {
found = true;
break;
}
}
t.ok(!found, "popup.div successfully removed from the map's viewPort");
map.destroy();
}
function test_Map_add_popup_exclusive(t) {
t.plan(2);
map = new OpenLayers.Map('map');
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
map.addLayer(baseLayer);
map.setCenter(new OpenLayers.LonLat(0, 0), 0);
for (var i = 0; i < 10; i++) {
var popup = new OpenLayers.Popup("chicken",
new OpenLayers.LonLat(0,0),
new OpenLayers.Size(200,200));
map.addPopup(popup);
}
t.eq(map.popups.length, 10, "addPopup non exclusive mode works");
var popup = new OpenLayers.Popup("chicken",
new OpenLayers.LonLat(0,0),
new OpenLayers.Size(200,200));
map.addPopup(popup, true);
t.eq(map.popups.length, 1, "addPopup exclusive mode works");
map.destroy();
}
/*** THIS IS A GOOD TEST, BUT IT SHOULD BE MOVED TO WMS.
* Also, it won't work until we figure out the viewSize bug
function 08_Map_px_lonlat_translation (t) {
t.plan( 6 );
map = new OpenLayers.Map('map');
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
map.addLayer(baseLayer);
map.setCenter(new OpenLayers.LonLat(0, 0), 0);
var pixel = new OpenLayers.Pixel(50,150);
var lonlat = map.getLonLatFromViewPortPx(pixel);
t.ok( lonlat instanceof OpenLayers.LonLat, "getLonLatFromViewPortPx returns valid OpenLayers.LonLat" );
var newPixel = map.getViewPortPxFromLonLat(lonlat);
t.ok( newPixel instanceof OpenLayers.Pixel, "getViewPortPxFromLonLat returns valid OpenLayers.Pixel" );
// WARNING!!! I'm faily sure that the following test's validity
// depends highly on rounding and the resolution. For now,
// in the default case, it seems to work. This may not
// always be so.
t.ok( newPixel.equals(pixel), "Translation to pixel and back to lonlat is consistent");
lonlat = map.getLonLatFromPixel(pixel);
t.ok( lonlat instanceof OpenLayers.LonLat, "getLonLatFromPixel returns valid OpenLayers.LonLat" );
newPixel = map.getPixelFromLonLat(lonlat);
t.ok( newPixel instanceof OpenLayers.Pixel, "getPixelFromLonLat returns valid OpenLayers.Pixel" );
t.ok( newPixel.equals(pixel), "2nd translation to pixel and back to lonlat is consistent");
}
*/
function test_Map_isValidZoomLevel(t) {
t.plan(5);
var map = new OpenLayers.Map("map");
map.addLayer(new OpenLayers.Layer(null, {
isBaseLayer: true, wrapDateLine: true, numZoomLevels: 19
}));
map.zoomToMaxExtent();
var valid;
valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [-1]);
t.eq(valid, false, "-1 is not a valid zoomLevel");
valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [0]);
t.eq(valid, true, "0 is a valid zoomLevel");
valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [18]);
t.eq(valid, true, "18 is a valid zoomLevel");
valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [19]);
t.eq(valid, false, "19 is not a valid zoomLevel");
map.moveTo([16, 48], 0);
t.eq(map.getCenter().toShortString(), "0, 0", "no panning when moveTo is called with invalid zoom");
map.destroy();
}
function test_Map_isValidLonLat(t) {
t.plan( 3 );
map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS('Test Layer',
"http://octo.metacarta.com/cgi-bin/mapserv",
{map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
{maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
map.addLayer(layer);
t.ok( !map.isValidLonLat(null), "null lonlat is not valid" );
t.ok( map.isValidLonLat(new OpenLayers.LonLat(33862, 717606)), "lonlat outside max extent is valid" );
t.ok( !map.isValidLonLat(new OpenLayers.LonLat(10, 10)), "lonlat outside max extent is not valid" );
map.destroy();
}
function test_Map_getLayer(t) {
var numLayers = 3;
t.plan( numLayers + 1 );
var m = {
layers: []
};
for(var i = 0; i < numLayers; i++) {
m.layers.push( { 'id': i } );
}
for(var i = 0; i < numLayers; i++) {
var layer = OpenLayers.Map.prototype.getLayer.apply(m, [i]);
t.ok( layer == m.layers[i], "getLayer correctly returns layer " + i);
}
var gotLayer = OpenLayers.Map.prototype.getLayer.apply(m, ["chicken"]);
t.ok( gotLayer == null, "getLayer correctly returns null when layer not found");
map.destroy();
}
function test_Map_getLayersBy(t) {
var map = {
getBy: OpenLayers.Map.prototype.getBy,
getLayersBy: OpenLayers.Map.prototype.getLayersBy,
layers: [
{foo: "foo", id: Math.random()},
{foo: "bar", id: Math.random()},
{foo: "foobar", id: Math.random()},
{foo: "foo bar", id: Math.random()},
{foo: "foo", id: Math.random()}
]
};
var cases = [
{
got: map.getLayersBy("foo", "foo"),
expected: [map.layers[0], map.layers[4]],
message: "(string literal) got two layers matching foo"
}, {
got: map.getLayersBy("foo", "bar"),
expected: [map.layers[1]],
message: "(string literal) got one layer matching foo"
}, {
got: map.getLayersBy("foo", "barfoo"),
expected: [],
message: "(string literal) got empty array for no foo match"
}, {
got: map.getLayersBy("foo", /foo/),
expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],
message: "(regexp literal) got three layers containing string"
}, {
got: map.getLayersBy("foo", /foo$/),
expected: [map.layers[0], map.layers[4]],
message: "(regexp literal) got three layers ending with string"
}, {
got: map.getLayersBy("foo", /\s/),
expected: [map.layers[3]],
message: "(regexp literal) got layer containing space"
}, {
got: map.getLayersBy("foo", new RegExp("BAR", "i")),
expected: [map.layers[1], map.layers[2], map.layers[3]],
message: "(regexp object) got layers ignoring case"
}, {
got: map.getLayersBy("foo", {test: function(str) {return str.length > 3;}}),
expected: [map.layers[2], map.layers[3]],
message: "(custom object) got layers with foo length greater than 3"
}
];
t.plan(cases.length);
for(var i=0; i<cases.length; ++i) {
t.eq(cases[i].got, cases[i].expected, cases[i].message);
}
}
function test_Map_getLayersByName(t) {
var map = {
getBy: OpenLayers.Map.prototype.getBy,
getLayersBy: OpenLayers.Map.prototype.getLayersBy,
getLayersByName: OpenLayers.Map.prototype.getLayersByName,
layers: [
{name: "foo", id: Math.random()},
{name: "bar", id: Math.random()},
{name: "foobar", id: Math.random()},
{name: "foo bar", id: Math.random()},
{name: "foo", id: Math.random()}
]
};
var cases = [
{
got: map.getLayersByName("foo"),
expected: [map.layers[0], map.layers[4]],
message: "(string literal) got two layers matching name"
}, {
got: map.getLayersByName("bar"),
expected: [map.layers[1]],
message: "(string literal) got one layer matching name"
}, {
got: map.getLayersByName("barfoo"),
expected: [],
message: "(string literal) got empty array for no match"
}, {
got: map.getLayersByName(/foo/),
expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],
message: "(regexp literal) got three layers containing string"
}, {
got: map.getLayersByName(/foo$/),
expected: [map.layers[0], map.layers[4]],
message: "(regexp literal) got three layers ending with string"
}, {
got: map.getLayersByName(/\s/),
expected: [map.layers[3]],
message: "(regexp literal) got layer containing space"
}, {
got: map.getLayersByName(new RegExp("BAR", "i")),
expected: [map.layers[1], map.layers[2], map.layers[3]],
message: "(regexp object) got layers ignoring case"
}, {
got: map.getLayersByName({test: function(str) {return str.length > 3;}}),
expected: [map.layers[2], map.layers[3]],
message: "(custom object) got layers with name length greater than 3"
}
];
t.plan(cases.length);
for(var i=0; i<cases.length; ++i) {
t.eq(cases[i].got, cases[i].expected, cases[i].message);
}
}
function test_Map_getLayersByClass(t) {
var map = {
getBy: OpenLayers.Map.prototype.getBy,
getLayersBy: OpenLayers.Map.prototype.getLayersBy,
getLayersByClass: OpenLayers.Map.prototype.getLayersByClass,
layers: [
{CLASS_NAME: "foo", id: Math.random()},
{CLASS_NAME: "bar", id: Math.random()},
{CLASS_NAME: "foobar", id: Math.random()},
{CLASS_NAME: "foo bar", id: Math.random()},
{CLASS_NAME: "foo", id: Math.random()}
]
};
var cases = [
{
got: map.getLayersByClass("foo"),
expected: [map.layers[0], map.layers[4]],
message: "(string literal) got two layers matching type"
}, {
got: map.getLayersByClass("bar"),
expected: [map.layers[1]],
message: "(string literal) got one layer matching type"
}, {
got: map.getLayersByClass("barfoo"),
expected: [],
message: "(string literal) got empty array for no match"
}, {
got: map.getLayersByClass(/foo/),
expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],
message: "(regexp literal) got three layers containing string"
}, {
got: map.getLayersByClass(/foo$/),
expected: [map.layers[0], map.layers[4]],
message: "(regexp literal) got three layers ending with string"
}, {
got: map.getLayersByClass(/\s/),
expected: [map.layers[3]],
message: "(regexp literal) got layer containing space"
}, {
got: map.getLayersByClass(new RegExp("BAR", "i")),
expected: [map.layers[1], map.layers[2], map.layers[3]],
message: "(regexp object) got layers ignoring case"
}, {
got: map.getLayersByClass({test: function(str) {return str.length > 3;}}),
expected: [map.layers[2], map.layers[3]],
message: "(custom object) got layers with type length greater than 3"
}
];
t.plan(cases.length);
for(var i=0; i<cases.length; ++i) {
t.eq(cases[i].got, cases[i].expected, cases[i].message);
}
}
function test_Map_getControlsBy(t) {
var map = {
getBy: OpenLayers.Map.prototype.getBy,
getControlsBy: OpenLayers.Map.prototype.getControlsBy,
controls: [
{foo: "foo", id: Math.random()},
{foo: "bar", id: Math.random()},
{foo: "foobar", id: Math.random()},
{foo: "foo bar", id: Math.random()},
{foo: "foo", id: Math.random()}
]
};
var cases = [
{
got: map.getControlsBy("foo", "foo"),
expected: [map.controls[0], map.controls[4]],
message: "(string literal) got two controls matching foo"
}, {
got: map.getControlsBy("foo", "bar"),
expected: [map.controls[1]],
message: "(string literal) got one control matching foo"
}, {
got: map.getControlsBy("foo", "barfoo"),
expected: [],
message: "(string literal) got empty array for no foo match"
}, {
got: map.getControlsBy("foo", /foo/),
expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]],
message: "(regexp literal) got three controls containing string"
}, {
got: map.getControlsBy("foo", /foo$/),
expected: [map.controls[0], map.controls[4]],
message: "(regexp literal) got three controls ending with string"
}, {
got: map.getControlsBy("foo", /\s/),
expected: [map.controls[3]],
message: "(regexp literal) got control containing space"
}, {
got: map.getControlsBy("foo", new RegExp("BAR", "i")),
expected: [map.controls[1], map.controls[2], map.controls[3]],
message: "(regexp object) got layers ignoring case"
}, {
got: map.getControlsBy("foo", {test: function(str) {return str.length > 3;}}),
expected: [map.controls[2], map.controls[3]],
message: "(custom object) got controls with foo length greater than 3"
}
];
t.plan(cases.length);
for(var i=0; i<cases.length; ++i) {
t.eq(cases[i].got, cases[i].expected, cases[i].message);
}
}
function test_Map_getControlsByClass(t) {
var map = {
getBy: OpenLayers.Map.prototype.getBy,
getControlsBy: OpenLayers.Map.prototype.getControlsBy,
getControlsByClass: OpenLayers.Map.prototype.getControlsByClass,
controls: [
{CLASS_NAME: "foo", id: Math.random()},
{CLASS_NAME: "bar", id: Math.random()},
{CLASS_NAME: "foobar", id: Math.random()},
{CLASS_NAME: "foo bar", id: Math.random()},
{CLASS_NAME: "foo", id: Math.random()}
]
};
var cases = [
{
got: map.getControlsByClass("foo"),
expected: [map.controls[0], map.controls[4]],
message: "(string literal) got two controls matching type"
}, {
got: map.getControlsByClass("bar"),
expected: [map.controls[1]],
message: "(string literal) got one control matching type"
}, {
got: map.getControlsByClass("barfoo"),
expected: [],
message: "(string literal) got empty array for no match"
}, {
got: map.getControlsByClass(/foo/),
expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]],
message: "(regexp literal) got three controls containing string"
}, {
got: map.getControlsByClass(/foo$/),
expected: [map.controls[0], map.controls[4]],
message: "(regexp literal) got three controls ending with string"
}, {
got: map.getControlsByClass(/\s/),
expected: [map.controls[3]],
message: "(regexp literal) got control containing space"
}, {
got: map.getControlsByClass(new RegExp("BAR", "i")),
expected: [map.controls[1], map.controls[2], map.controls[3]],
message: "(regexp object) got controls ignoring case"
}, {
got: map.getControlsByClass({test: function(str) {return str.length > 3;}}),
expected: [map.controls[2], map.controls[3]],
message: "(custom object) got controls with type length greater than 3"
}
];
t.plan(cases.length);
for(var i=0; i<cases.length; ++i) {
t.eq(cases[i].got, cases[i].expected, cases[i].message);
}
}
function test_Map_double_addLayer(t) {
t.plan(2);
map = new OpenLayers.Map($('map'));
layer = new OpenLayers.Layer.WMS('Test Layer',
"http://octo.metacarta.com/cgi-bin/mapserv",
{map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}
);
var added = map.addLayer(layer);
t.ok(added === true, "Map.addLayer returns true if the layer is added to the map.");
var added = map.addLayer(layer);
t.ok(added === false, "Map.addLayer returns false if the layer is already present.");
map.destroy();
}
function test_Map_setBaseLayer(t) {
t.plan( 6 );
map = new OpenLayers.Map('map');
var wmslayer = new OpenLayers.Layer.WMS('Test Layer',
"http://octo.metacarta.com/cgi-bin/mapserv",
{map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
{maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2',
"http://octo.metacarta.com/cgi-bin/mapserv",
{map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
{maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
map.addLayers([wmslayer, wmslayer2]);
t.ok(map.baseLayer == wmslayer, "default base layer is first one added");
map.setBaseLayer(null);
t.ok(map.baseLayer == wmslayer, "setBaseLayer on null object does nothing (and does not break)");
map.setBaseLayer("chicken");
t.ok(map.baseLayer == wmslayer, "setBaseLayer on non-layer object does nothing (and does not break)");
map.setBaseLayer(wmslayer2);
t.ok(map.baseLayer == wmslayer2, "setbaselayer correctly sets 'baseLayer' property");
map.destroy();
var l1 = new OpenLayers.Layer(),
l2 = new OpenLayers.Layer(null, {maxResolution: 1.4});
map = new OpenLayers.Map({
div: 'map',
allOverlays: true,
layers: [l1, l2],
zoom: 0,
center: [0, 0]
});
t.eq(l2.div.style.display, "none", "Layer invisible because not in range");
map.raiseLayer(l1, 1);
t.eq(l2.div.style.display, "block", "Layer visible after base layer change because in range now");
map.destroy();
}
function test_Map_removeLayer(t) {
t.plan(1);
var f = function() {};
var events = {triggerEvent: f};
var layers = [
{name: "fee", removeMap: f, events: events},
{name: "fi", removeMap: f, events: events},
{name: "fo", removeMap: f, events: events},
{name: "fum", removeMap: f, events: events}
];
var map = {
layers: layers,
baseLayer: layers[0],
layerContainerDiv: {removeChild: f},
events: {triggerEvent: f},
resetLayersZIndex: function() {}
};
OpenLayers.Map.prototype.removeLayer.apply(map, [map.baseLayer, false]);
t.eq(map.baseLayer, null,
"removing the baselayer sets baseLayer to null");
}
function test_Map_removeLayer_res(t) {
t.plan(2);
map = new OpenLayers.Map('map');
var layer0 = new OpenLayers.Layer.WMS(
'Test Layer 0',
"http://octo.metacarta.com/cgi-bin/mapserv",
{map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
{resolutions: [4, 2, 1]}
);
var layer1 = new OpenLayers.Layer.WMS(
'Test Layer 1',
"http://octo.metacarta.com/cgi-bin/mapserv",
{map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
{resolutions: [4, 2]}
);
map.addLayers([layer0, layer1]);
map.zoomToMaxExtent();
map.zoomTo(2);
t.eq(map.getResolution(), layer0.resolutions[2],
"correct resolution before removal");
map.removeLayer(layer0);
t.eq(map.getResolution(), layer0.resolutions[1],
"correct resolution after removal");
map.destroy();
}
function test_Map_removeLayer_zindex(t) {
t.plan(2);
map = new OpenLayers.Map('map');
var layer0 = new OpenLayers.Layer('Test Layer 0', {isBaseLayer:true});
var layer1 = new OpenLayers.Layer('Test Layer 1', {isBaseLayer:true});
var layer2 = new OpenLayers.Layer('Test Layer 2', {isBaseLayer:false});
map.addLayers([layer0, layer1, layer2]);
map.removeLayer(layer0);
t.eq(parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'],
"correct z-index after removeLayer");
t.eq(parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['Overlay'] + 5,
"correct z-index after removeLayer");
map.destroy();
}
function test_Map_removeLayer_preremovelayer(t) {
t.plan(4);
map = new OpenLayers.Map('map');
map.addLayer(new OpenLayers.Layer());
map.removeLayer(map.layers[0]);
// one test: standard behaviour without listener
t.eq(map.layers.length, 0, "without registered preremovelayer-listener layers can be removed as usual");
var callCnt = 0;
map.events.register('preremovelayer', this, function(evt) {
callCnt++;
return !(evt.layer.name === 'donotremove');
});
var layer1 = new OpenLayers.Layer('donotremove');
var layer2 = new OpenLayers.Layer('doremove');
map.addLayers([layer1,layer2]);
// two tests: remove action can be canceled
map.removeLayer(layer1);
t.eq(map.layers.length, 2, "layer is not removed since preremovelayer returns false");
map.removeLayer(layer2);
t.eq(map.layers.length, 1, "layer is removed since preremovelayer returns true");
// one test: listener was called twice
t.eq(callCnt, 2, "preremovelayer-listener was called exactly twice");
map.destroy();
}
function test_Map_setBaseLayer_after_pan (t) {
t.plan(1);
map = new OpenLayers.Map('map');
var wmsLayer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );
var tmsLayer = new OpenLayers.Layer.TMS("TMS",
"http://labs.metacarta.com/wms-c/Basic.py/",
{'layername':'basic', 'type':'png'});
map.addLayers([wmsLayer,tmsLayer]);
map.setBaseLayer(wmsLayer);
map.zoomToMaxExtent();
map.setBaseLayer(tmsLayer);
map.zoomIn();
map.pan(0, -200, {animate:false});
map.setBaseLayer(wmsLayer);
t.eq(map.layerContainerDiv.style.top, "0px", "layerContainer is recentered after setBaseLayer");
map.destroy();
}
function test_Map_moveLayer (t) {
t.plan(10);
var ct = 0;
map = new OpenLayers.Map('map');
var wmslayer = new OpenLayers.Layer.WMS('Test Layer',
"http://octo.metacarta.com/cgi-bin/mapserv",
{map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
{maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2',
"http://octo.metacarta.com/cgi-bin/mapserv",
{map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
{maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
var wmslayer3 = new OpenLayers.Layer.WMS('Test Layer2',
"http://octo.metacarta.com/cgi-bin/mapserv",
{map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
{maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
map.addLayers([wmslayer, wmslayer2, wmslayer3]);
map.events.register("changelayer", map, function (e) { ct++; });
t.eq( map.getNumLayers(), 3, "getNumLayers returns the number of layers" );
t.eq( map.getLayerIndex(wmslayer3), 2, "getLayerIndex returns the right index" );
map.raiseLayer(wmslayer3, 1);
t.eq( map.getLayerIndex(wmslayer3), 2, "can't moveLayer up past the top of the stack" );
map.raiseLayer(wmslayer, -1);
t.eq( map.getLayerIndex(wmslayer), 0, "can't moveLayer down past the bottom of the stack" );
map.raiseLayer(wmslayer3, -1);
t.eq( map.getLayerIndex(wmslayer3), 1, "can moveLayer down from the top" );
t.eq( parseInt(wmslayer3.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5,
"layer div has the right zIndex after moving down" );
map.raiseLayer(wmslayer, 2);
t.eq( map.getLayerIndex(wmslayer), 2, "can moveLayer up from the bottom" );
t.eq( parseInt(wmslayer.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 2 * 5,
"layer div has the right zIndex after moving up" );
t.eq( map.getLayerIndex(wmslayer3), 0, "top layer is now on the bottom" );
t.eq( ct, 3, "raiseLayer triggered changelayer the right # of times" );
map.destroy();
}
function test_Map_moveTo(t) {
t.plan(2);
map = new OpenLayers.Map('map');
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"},
{maxResolution: 'auto', maxExtent: new OpenLayers.Bounds(-10,-10,10,10)});
baseLayer.events.on({
move: function() {
t.ok(true, "move listener called");
},
moveend: function(e) {
t.eq(e.zoomChanged, true, "moveend listener called with expected value");
}
});
map.addLayer(baseLayer);
var ll = new OpenLayers.LonLat(-100,-150);
map.moveTo(ll, 2);
t.ok(map.getCenter().equals(new OpenLayers.LonLat(0,0)), "safely sets out-of-bounds lonlat");
map.destroy();
}
function test_Map_defaultTheme(t) {
t.plan(5);
var links = document.getElementsByTagName('link');
map = new OpenLayers.Map('map');
var gotNodes = 0;
var themeNode = null;
for(var i=0; i<links.length; ++i) {
if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) {
gotNodes += 1;
themeNode = links.item(i);
}
}
t.eq(gotNodes, 1, "by default, a single link node is added to document");
t.ok(themeNode != null, "a link node with the theme href was added");
t.eq(themeNode.rel, "stylesheet", "node added has rel set to stylesheet");
t.eq(themeNode.type, "text/css", "node added has type set to text/css");
// reconstruct the map to prove that another link is not added
map = new OpenLayers.Map('map');
t.eq(links.length, document.getElementsByTagName('link').length,
"calling the map constructor twice with the same theme doesn't add duplicate link nodes");
map.destroy();
}
function test_Map_customTheme(t) {
t.plan(5);
var customTheme = 'foo';
var options = {theme: customTheme};
map = new OpenLayers.Map('map', options);
var links = document.getElementsByTagName('link');
var gotNodes = 0;
var themeNode = null;
for(var i=0; i<links.length; ++i) {
if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) {
gotNodes += 1;
themeNode = links.item(i);
}
}
t.eq(map.theme, customTheme, "map theme is properly set");
t.eq(gotNodes, 1, "with custom theme, a single link node is added to document");
t.ok(themeNode != null, "a link node with the theme href was added");
t.eq(themeNode.rel, "stylesheet", "node added has rel set to stylesheet");
t.eq(themeNode.type, "text/css", "node added has type set to text/css");
map.destroy();
}
function test_Map_noTheme(t) {
t.plan(1);
var head = document.getElementsByTagName('head')[0];
var nodeCount = head.childNodes.length;
var options = {theme: null};
map = new OpenLayers.Map('map', options);
t.eq(nodeCount, head.childNodes.length, "with no theme, a node is not added to document head" );
map.destroy();
}
function test_Map_addControls(t) {
t.plan(5);
var map = new OpenLayers.Map('map', {
controls: []
});
var controls = [
new OpenLayers.Control({id:'firstctrl'}),
new OpenLayers.Control({id:'secondctrl'})
];
map.addControls(controls);
t.eq(map.controls.length, 2, "two controls were added by map.addControls without a px-array");
t.eq(map.controls[0].id, 'firstctrl', "control with index 0 has id 'firstctrl'");
t.eq(map.controls[1].id, 'secondctrl', "control with index 1 has id 'secondctrl'");
var controls2 = [
new OpenLayers.Control({id:'thirdctrl'}),
new OpenLayers.Control({id:'fourthctrl'}),
new OpenLayers.Control({id:'fifthctrl'})
];
// this array is intentionally one element shorter than the above
var pixels2 = [
null,
new OpenLayers.Pixel(27,11)
];
map.addControls(controls2, pixels2);
t.eq(map.controls.length, 5, "three additional controls were added by map.addControls with a px-array");
t.eq(map.controls[3].position.toString(), pixels2[1].toString(), "control 'fourthctrl' has position set to given px");
map.destroy();
}
function test_Map_getControl(t) {
t.plan(2);
var map1 = new OpenLayers.Map('map');
var control = new OpenLayers.Control();
map1.addControl(control);
var gotControl = map1.getControl(control.id);
t.ok(gotControl == control, "got right control");
gotControl = map1.getControl("bogus id");
t.ok(gotControl == null, "getControl() for bad id returns null");
map1.destroy();
}
function test_Map_removeControl(t) {
t.plan(6);
var oldNumControls, newNumControls;
var map1 = new OpenLayers.Map('map');
oldNumControls = map1.controls.length;
var control = new OpenLayers.Control();
map1.addControl(control);
//add control
newNumControls = map1.controls.length;
t.ok( newNumControls = oldNumControls + 1, "adding a control increases control count")
var foundDiv = false;
for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) {
var childNode = map1.viewPortDiv.childNodes[i];
if (childNode == control.div) {
foundDiv = true;
}
}
t.ok(foundDiv, "new control's div correctly added to viewPort");
//remove control
map1.removeControl(control)
newNumControls = map1.controls.length;
t.ok( newNumControls == oldNumControls, "removing the control decreases control count")
var gotControl = map1.getControl(control.id);
t.ok( gotControl == null, "control no longer in map's controls array");
var foundDiv = false;
for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) {
var childNode = map1.viewPortDiv.childNodes[i];
if (childNode == control.div) {
foundDiv = true;
}
}
t.ok(!foundDiv, "control no longer child of viewPort");
//remove bogus
control = { id: "bogus id" };
map1.removeControl(control);
newNumControls = map1.controls.length;
t.ok( newNumControls == oldNumControls, "removing bad controlid doesnt crash or decrease control count")
map1.destroy();
}
function test_Map_restrictedExtent(t) {
t.plan(25);
var extent = new OpenLayers.Bounds(-180, -90, 180, 90);
var options = {
maxResolution: "auto"
};
var map = new OpenLayers.Map("map", options);
var layer = new OpenLayers.Layer.WMS(
"test",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"}
);
map.addLayer(layer);
map.zoomToMaxExtent();
var nw = new OpenLayers.LonLat(extent.left, extent.top);
var ne = new OpenLayers.LonLat(extent.right, extent.top);
var sw = new OpenLayers.LonLat(extent.left, extent.bottom);
var se = new OpenLayers.LonLat(extent.right, extent.bottom);
// try panning to northwest corner
map.setOptions({restrictedExtent: extent});
map.setCenter(nw, 0);
t.eq(map.getExtent().getCenterLonLat().toString(),
extent.getCenterLonLat().toString(),
"map extent properly restricted to northwest at zoom 0");
t.eq(map.zoom, 0, "zoom not restricted for nw, 0");
map.setCenter(nw, 5);
t.eq(map.getExtent().top, extent.top,
"map extent top properly restricted to northwest at zoom 5");
t.eq(map.getExtent().left, extent.left,
"map extent left properly restricted to northwest at zoom 5");
t.eq(map.zoom, 5, "zoom not restricted for nw, 5");
map.setOptions({restrictedExtent: null});
map.setCenter(nw, 0);
t.eq(map.getExtent().getCenterLonLat().toString(),
nw.toString(),
"map extent not restricted with null restrictedExtent for nw");
// try panning to northeast corner
map.setOptions({restrictedExtent: extent});
map.setCenter(ne, 0);
t.eq(map.getExtent().getCenterLonLat().toString(),
extent.getCenterLonLat().toString(),
"map extent properly restricted to northeast at zoom 0");
t.eq(map.zoom, 0, "zoom not restricted for ne, 0");
map.setCenter(ne, 5);
t.eq(map.getExtent().top, extent.top,
"map extent top properly restricted to northeast at zoom 5");
t.eq(map.getExtent().right, extent.right,
"map extent right properly restricted to northeast at zoom 5");
t.eq(map.zoom, 5, "zoom not restricted for ne, 5");
map.setOptions({restrictedExtent: null});
map.setCenter(ne, 0);
t.eq(map.getExtent().getCenterLonLat().toString(),
ne.toString(),
"map extent not restricted with null restrictedExtent for ne");
// try panning to southwest corner
map.setOptions({restrictedExtent: extent});
map.setCenter(sw, 0);
t.eq(map.getExtent().getCenterLonLat().toString(),
extent.getCenterLonLat().toString(),
"map extent properly restricted to southwest at zoom 0");
t.eq(map.zoom, 0, "zoom not restricted for sw, 0");
map.setCenter(sw, 5);
t.eq(map.getExtent().bottom, extent.bottom,
"map extent bottom properly restricted to southwest at zoom 5");
t.eq(map.getExtent().left, extent.left,
"map extent left properly restricted to southwest at zoom 5");
t.eq(map.zoom, 5, "zoom not restricted for sw, 5");
map.setOptions({restrictedExtent: null});
map.setCenter(sw, 0);
t.eq(map.getExtent().getCenterLonLat().toString(),
sw.toString(),
"map extent not restricted with null restrictedExtent for sw");
// try panning to southeast corner
map.setOptions({restrictedExtent: extent});
map.setCenter(se, 0);
t.eq(map.getExtent().getCenterLonLat().toString(),
extent.getCenterLonLat().toString(),
"map extent properly restricted to southeast at zoom 0");
t.eq(map.zoom, 0, "zoom not restricted for se, 0");
map.setCenter(se, 5);
t.eq(map.getExtent().bottom, extent.bottom,
"map extent bottom properly restricted to southeast at zoom 5");
t.eq(map.getExtent().right, extent.right,
"map extent right properly restricted to southeast at zoom 5");
t.eq(map.zoom, 5, "zoom not restricted for se, 5");
map.setOptions({restrictedExtent: null});
map.setCenter(se, 0);
t.eq(map.getExtent().getCenterLonLat().toString(),
se.toString(),
"map extent not restricted with null restrictedExtent for se");
map.destroy();
extent = new OpenLayers.Bounds(8, 44.5, 19, 50);
var options = {
restrictedExtent: extent
};
map = new OpenLayers.Map('map', options);
var wms = new OpenLayers.Layer.WMS(
"OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0?",
{layers: 'basic'}
);
map.addLayers([wms]);
map.zoomToExtent(extent);
map.zoomIn();
map.setOptions({restrictedExtent: null});
map.pan(-250, -250);
t.ok((map.getExtent().bottom == 48.3486328125 && map.getExtent().left == 7.45751953125), "Expected extent when toggling restrictedExtent");
map.destroy();
}
function test_Map_getResolutionForZoom(t) {
t.plan(2);
var map = new OpenLayers.Map("map");
var res = map.getResolutionForZoom();
t.eq(res, null, "getResolutionForZoom returns null for no base layer");
map.fractionalZoom = true;
var layer = new OpenLayers.Layer("test", {isBaseLayer: true});
map.addLayer(layer);
layer.getResolutionForZoom = function() {
t.ok(true, "getResolutionForZoom calls base layer getResolutionForZoom");
}
var res = map.getResolutionForZoom();
layer.destroy();
map.destroy();
}
function test_zoomTo(t) {
t.plan(8);
var map = new OpenLayers.Map("map");
map.addLayer(new OpenLayers.Layer(null, {
isBaseLayer: true
}));
map.zoomToMaxExtent();
map.zoomTo(2);
t.eq(map.getZoom(), 2, 'zoomTo(2)');
map.zoomTo(3.6);
t.eq(map.getZoom(), 4, 'zoomTo(3.6)');
map.zoomTo("4.6");
t.eq(map.getZoom(), 5, 'zoomTo("4.6")');
map.zoomTo("1.2");
t.eq(map.getZoom(), 1, 'zoomTo("1.2")');
// now allow fractional zoom
map.fractionalZoom = true;
map.zoomTo(2);
t.eq(map.getZoom(), 2, '[fractionalZoom] zoomTo(2)');
map.zoomTo(3.6);
t.eq(map.getZoom(), 3.6, '[fractionalZoom] zoomTo(3.6)');
map.zoomTo("4.6");
t.eq(map.getZoom(), 4.6, '[fractionalZoom] zoomTo("4.6")');
map.zoomTo("1.2");
t.eq(map.getZoom(), 1.2, '[fractionalZoom] zoomTo("1.2")');
map.destroy();
}
function test_Map_getUnits(t) {
t.plan(2);
var map = new OpenLayers.Map("map");
var units = map.getUnits();
t.eq(units, null, "getUnits returns null for no base layer");
var layer = new OpenLayers.Layer("test", {
isBaseLayer: true,
units: 'foo'
});
map.addLayer(layer);
var units = map.getUnits();
t.eq(units, 'foo', "getUnits returns the base layer units property");
layer.destroy();
map.destroy();
}
function test_Map_destroy (t) {
t.plan( 3 );
map = new OpenLayers.Map('map');
map.destroy();
t.eq( map.layers, null, "map.layers is null after destroy" );
t.eq( map.controls, null, "map.controls is null after destroy" );
t.eq( map.viewPortDiv, null, "map's viewportDiv nullified");
}
function test_Map_getMaxExtent(t){
t.plan(5);
var options = null;
var map = {};
//null options, no baseLayer
var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
t.eq(maxExtent, null, "null options, no baseLayer returns null");
//null options.restricted, no baseLayer
maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
t.eq(maxExtent, null, "null options.restricted, no baseLayer returns null");
//true options.restricted, null map.restrictedExtent no baseLayer
maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
t.eq(maxExtent, null, "true options.restricted, null map.restrictedExtent no baseLayer returns null");
//true options.restricted, valid map.restrictedExtent no baseLayer
options = {
'restricted': true
};
map.restrictedExtent = {};
maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
t.ok(maxExtent == map.restrictedExtent, "true options.restricted, valid map.restrictedExtent no baseLayer returns map.restrictedExtent");
//null options, valid baseLayer
options = null;
map.baseLayer = {
'maxExtent': {}
};
var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
t.ok(maxExtent == map.baseLayer.maxExtent, "null options, valid baseLayer returns map.baseLayer.maxExtent");
}
function test_Map_zoomToMaxExtent(t){
t.plan(4)
gMaxExtent = {};
var map = {
'getMaxExtent': function(options) {
gRestricted = options.restricted;
return gMaxExtent;
},
'zoomToExtent': function(extent) {
t.ok(extent == gMaxExtent, "zoomToExtent() always called on return from map.getMaxExtent()");
}
};
//options is null
var options = null;
gRestricted = null;
OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]);
t.eq(gRestricted, true, "default 'restricted' passed to map.getMaxExtent() is true");
//valid options
options = {
'restricted': {}
};
gRestricted = null;
OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]);
t.ok(gRestricted == options.restricted, "when valid options argument, 'options.restricted' passed to map.getMaxExtent()");
}
function test_Map_zoomToScale(t) {
t.plan(4);
var m = {
'baseLayer': { 'units': {} },
'size': {'w': 10, 'h': 15},
'getSize': function() { return {'w': 10, 'h': 15}; },
'getCachedCenter': function() { return {'lon': -5, 'lat': -25}; },
'zoomToExtent': function(extent, closest) {
t.ok(extent.equals(g_ExpectedExtent), "extent correctly calculated for zoomToExtent()");
t.ok(closest == g_Closest, "closest correctly passed on to zoomToExtent()");
}
}
var temp = OpenLayers.Util.getResolutionFromScale;
OpenLayers.Util.getResolutionFromScale = function(scale, units) {
t.ok(scale == g_Scale, "scale parameter correctly passed to getResolutionFromScale");
t.ok(units == m.baseLayer.units, "map's baselayer's units parameter correctly passed to getResolutionFromScale");
return 1000;
};
g_ExpectedExtent = new OpenLayers.Bounds(-5005,-7525,4995,7475);
g_Scale = {};
g_Closest = {};
var args = [g_Scale, g_Closest];
OpenLayers.Map.prototype.zoomToScale.apply(m, args);
OpenLayers.Util.getResolutionFromScale = temp;
}
function test_Map_zoomToExtent(t) {
t.plan(12);
var map = new OpenLayers.Map("map");
var layer = new OpenLayers.Layer(null, {isBaseLayer: true});
map.addLayer(layer);
var bounds = new OpenLayers.Bounds(-160, 15, -50, 69);
var center;
// default for closest
map.zoomToExtent(bounds);
center = map.getCenter();
t.eq(center.lon, -105, "a) correct x");
t.eq(center.lat, 42, "a) correct y");
t.eq(map.getZoom(), 2, "a) correct zoom");
// false for closest
map.zoomToExtent(bounds, false);
center = map.getCenter();
t.eq(center.lon, -105, "b) correct x");
t.eq(center.lat, 42, "b) correct y");
t.eq(map.getZoom(), 2, "b) correct zoom");
// true for closest
map.zoomToExtent(bounds, true);
center = map.getCenter();
t.eq(center.lon, -105, "c) correct x");
t.eq(center.lat, 42, "c) correct y");
t.eq(map.getZoom(), 3, "c) correct zoom");
// accept array
map.zoomToExtent([-160, 15, -50, 69]);
center = map.getCenter();
t.eq(center.lon, -105, "(array) correct x");
t.eq(center.lat, 42, "(array) correct y");
t.eq(map.getZoom(), 2, "(array) correct zoom");
map.destroy();
}
function test_Map_zoomToExtent_wrapped(t) {
t.plan(9);
var map = new OpenLayers.Map("map");
var layer = new OpenLayers.Layer(null, {isBaseLayer: true, wrapDateLine: true});
map.addLayer(layer);
var bounds, center;
var cases = [{
// real world
bbox: [120, -20, 140, 0],
center: [130, -10]
}, {
// one world to the right
bbox: [220, -45, 240, 45],
center: [-130, 0]
}, {
// two worlds to the right
bbox: [550, -15, 560, 5],
center: [-165, -5]
}, {
// one world to the left
bbox: [-240, -15, -220, 5],
center: [130, -5]
}, {
// two worlds to the left
bbox: [-600, -15, -580, 5],
center: [130, -5]
}];
var num = cases.length;
t.plan(num * 2);
var c, bounds, center;
for (var i=0; i<num; ++i) {
c = cases[i];
bounds = OpenLayers.Bounds.fromArray(c.bbox);
map.zoomToExtent(bounds);
center = map.getCenter();
t.eq(center.lon, c.center[0], "y: " + bounds);
t.eq(center.lat, c.center[1], "x: " + bounds);
}
map.destroy();
}
function test_allOverlays(t) {
t.plan(18);
var map = new OpenLayers.Map({
div: "map", allOverlays: true
});
var a = new OpenLayers.Layer.Vector("a", {visibility: true});
var b = new OpenLayers.Layer.Image(
"b",
"http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif",
new OpenLayers.Bounds(-180, -88.759, 180, 88.759),
new OpenLayers.Size(580, 288)
);
var c = new OpenLayers.Layer.WMS(
"c",
"http://labs.metacarta.com/wms/vmap0",
{layers: 'basic'}
);
var d = new OpenLayers.Layer.Vector("d");
map.addLayers([a, b, c, d]);
var moveCount = 0;
a.moveTo = function() {
moveCount++;
OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);
};
map.zoomToMaxExtent();
t.eq(moveCount, 1, "map.moveTo moves the base layer only once");
t.eq(map.getCenter().toString(), "lon=0,lat=0", "a map with all overlays can have a center");
a.setVisibility(false);
var moveend = 0;
a.events.on({"moveend": function() { moveend++; }});
map.zoomToMaxExtent();
t.eq(moveCount, 1, "map.moveTo does not move the base layer if it is invisible");
t.eq(moveend, 0, "map.moveTo does not trigger \"moveend\" in the layer if the layer is invisible");
a.setVisibility(true);
// a, b, c, d
t.eq(map.baseLayer.name, "a", "base layer set to first layer added");
map.removeLayer(a);
// b, c, d
t.eq(map.baseLayer.name, "b", "if base layer is removed, lowest layer becomes base");
map.addLayer(a);
// b, c, d, a
t.eq(map.baseLayer.name, "b", "adding a new layer doesn't change base layer");
map.setLayerIndex(c, 1);
// b, d, c, a
t.eq(map.baseLayer.name, "b", "changing layer order above base doesn't mess with base");
map.setLayerIndex(d, 0);
// d, b, c, a
t.eq(map.baseLayer.name, "d", "changing layer order to 0 sets base layer");
map.raiseLayer(d, 1);
// b, d, c, a
t.eq(map.baseLayer.name, "b", "raising the base layer sets a new base layer");
map.raiseLayer(d, -1);
// d, b, c, a
t.eq(map.baseLayer.name, "d", "lowering a layer to lowest index sets as base");
// all this switching of base layer didn't muck with layer visibility
t.eq(a.visibility, true, "a is visible");
t.eq(b.visibility, true, "b is visible");
t.eq(c.visibility, true, "c is visible");
t.eq(d.visibility, true, "d is visible");
// test that map can have an invisible base layer
b.setVisibility(false);
map.setLayerIndex(b, 0);
t.eq(b.visibility, false, "changing layer order doesn't change visibility");
map.destroy();
// make sure setVisibility is called when adding a single layer to the map
map = new OpenLayers.Map({
div: "map", allOverlays: true
});
var count = 0;
var layer = new OpenLayers.Layer(null, {
visibility: true,
maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
setVisibility: function() {
++count;
OpenLayers.Layer.prototype.setVisibility.apply(this, arguments);
}
});
map.addLayer(layer);
map.zoomToMaxExtent();
t.eq(count, 1, "setVisibility called when visibility is true in layer config");
t.eq(layer.div.style.display, "", "layer is visible.");
map.destroy();
}
function test_panTo(t) {
t.plan(6);
var log = [];
var map = new OpenLayers.Map("map", {
eventListeners: {
"movestart": function() {log.push("movestart");},
"move": function() {log.push("move");},
"moveend": function() {log.push("moveend");}
}
});
map.addLayer(
new OpenLayers.Layer(null, {isBaseLayer: true})
);
map.setCenter(new OpenLayers.LonLat(0, 0), 0);
t.eq(log[log.length-1], "moveend", "moveend fired when map center is set");
log = [];
map.panTo(new OpenLayers.LonLat(1, 0));
t.eq(map.panTween.playing, true, "the map pan tween is playing before destroy");
t.delay_call(2, function() {
t.eq(log[0], "movestart", "panTo starts with movestart event");
t.eq(log[1], "move", "move events fired while panning");
t.eq(log[log.length-1], "moveend", "panTo finishes with moveend event");
map.destroy();
t.ok(!map.panTween || !map.panTween.playing, "the map pan tween is not playing after destroy");
});
}
function test_pan(t) {
t.plan(4);
var map = new OpenLayers.Map("map");
map.addLayer(
new OpenLayers.Layer(null, {isBaseLayer: true})
);
map.setCenter(new OpenLayers.LonLat(0, 0), 5);
var log = [];
map.events.on({
"movestart": function() {log.push("movestart");},
"move": function() {log.push("move");},
"moveend": function() {log.push("moveend");}
});
// simulate the drag sequence of the DragPan control;
map.pan(5,5, {animate: false, dragging: true});
map.pan(1,1, {animate: false, dragging: false});
t.eq(log[0], "movestart", "pan sequence starts with movestart");
t.eq(log[1], "move", "followed by move,");
t.eq(log[log.length-2], "move", "move again before we stop panning,");
t.eq(log[log.length-1], "moveend", "and moveend when we're done.");
}
// test if we can call updateSize before document.body is ready. updateOk
// is tested in the test_updateSize function below
var earlyMap = new OpenLayers.Map();
var updateOk;
try {
earlyMap.updateSize();
updateOk = true;
} catch(e) {}
earlyMap.destroy();
function test_updateSize(t) {
t.plan(3);
// checking updateSize from outside this test function (see above)
t.ok(updateOk, "updateSize works before document.body is ready");
var map, moveToCnt, size;
map = new OpenLayers.Map({div: "map"});
map.addLayer(new OpenLayers.Layer("layer", {isBaseLayer: true}));
map.moveTo = function() {
moveToCnt++;
OpenLayers.Map.prototype.moveTo.apply(this, arguments);
};
map.getCurrentSize = function() {
return size;
};
// map has no center
// 1 test
moveToCnt = 0;
size = new OpenLayers.Size(650, 350);
map.updateSize();
t.eq(moveToCnt, 0, "updateSize doesn't move the map if it doesn't have a center");
// map has a center
// 1 test
map.zoomToMaxExtent();
moveToCnt = 0;
size = new OpenLayers.Size(600, 300);
map.updateSize();
t.eq(moveToCnt, 1, "updateSize move the map if it has a center");
map.destroy();
}
function test_invisible_map(t) {
/**
* This test confirms that initializing a map using an element that is
* not currently displayed doesn't cause any trouble.
*/
t.plan(1);
var map, msg = "initializing a map on an undisplayed element";
try {
map = new OpenLayers.Map("invisimap");
} catch (err) {
msg += ": " + err;
}
t.ok(!!map, msg);
if (map) {
map.destroy();
}
}
function test_layers_option(t) {
t.plan(3);
var map = new OpenLayers.Map({
div: "map",
layers: [
new OpenLayers.Layer()
]
});
t.eq(map.layers.length, 1, "single layer from options added");
map.destroy();
map = new OpenLayers.Map({
div: "map",
layers: [
new OpenLayers.Layer(null, {isBaseLayer: true}),
new OpenLayers.Layer(null, {isBaseLayer: false})
]
});
t.eq(map.layers.length, 2, "multiple layers added from options");
t.ok(map.baseLayer, "map has a base layer");
map.destroy();
}
function test_center_option(t) {
t.plan(7);
var map, msg;
// try setting center without layers, this has no effect
var failed = false;
try {
map = new OpenLayers.Map({
div: "map",
center: new OpenLayers.LonLat(1, 2)
});
msg = "center option without layers has no effect";
} catch (err) {
failed = true;
msg = "center option without layers throws error";
}
t.ok(!failed, msg);
if (map) {
map.destroy();
}
var log = [];
var meth = OpenLayers.Layer.prototype.moveTo;
OpenLayers.Layer.prototype.moveTo = function() {
log.push(arguments);
meth.apply(this, arguments);
};
// set center without zoom
var center = new OpenLayers.LonLat(1, 2);
map = new OpenLayers.Map({
div: "map",
layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],
center: center
});
t.ok(center.equals(map.getCenter()), "map center set without zoom");
t.eq(log.length, 1, "moveTo called once");
map.destroy();
OpenLayers.Layer.prototype.moveTo = meth;
// set center and zoom
var zoom = 3;
map = new OpenLayers.Map({
div: "map",
layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],
center: center,
zoom: zoom
});
t.ok(center.equals(map.getCenter()), "map center set with center and zoom");
t.eq(zoom, map.getZoom(), "map zoom set with center and zoom");
map.destroy();
// set center and zoom with all overlays
map = new OpenLayers.Map({
div: "map",
allOverlays: true,
layers: [new OpenLayers.Layer()],
center: center,
zoom: zoom
});
t.ok(center.equals(map.getCenter()), "map center set with all overlays");
t.eq(zoom, map.getZoom(), "map zoom set with all overlays");
map.destroy();
}
function test_pixel_lonlat(t) {
t.plan(4);
var map = new OpenLayers.Map({
div: "map",
layers: [
new OpenLayers.Layer("name", {isBaseLayer:true})
]
});
map.zoomToMaxExtent();
var px = map.getPixelFromLonLat(map.getLonLatFromPixel(new OpenLayers.Pixel(100, 100)));
t.eq(px.x, 100, "x is the same in and ot");
t.eq(px.y, 100, "y is the same in and out");
var ll = map.getLonLatFromPixel(map.getPixelFromLonLat(new OpenLayers.LonLat(100, 100)));
t.ok((ll.lon > (100 -map.getResolution()) && (ll.lon < (100 + map.getResolution()))), "lon is the same in and ot");
t.ok((ll.lat > (100 -map.getResolution()) && (ll.lat < (100 + map.getResolution()))), "lat is the same in and ot");
map.destroy();
}
function test_moveByPx(t) {
t.plan(16);
var moved;
var Layer = OpenLayers.Class(OpenLayers.Layer, {
moveByPx: function(dx, dy) {
moved[this.name] = true;
}
});
var map = new OpenLayers.Map({
div: 'map',
maxExtent: new OpenLayers.Bounds(-50, -50, 50, 50),
restrictedExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
layers: [
new Layer('base',
{isBaseLayer: true}),
new Layer('outofrange',
{isBaseLayer: false, minResolution:2})
]
});
moved = {};
map.zoomToExtent(new OpenLayers.Bounds(-1, -1, 1, 1));
// check initial state
t.eq(map.layerContainerDiv.style.left, '0px',
'[initial state] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '0px',
'[initial state] layer container top correct');
t.eq(moved['base'], undefined,
'[initial state] base layer not moved');
t.eq(moved['outofrange'], undefined,
'[initial state] out-of-range layer not moved');
// move to a valid position
moved = {};
map.moveByPx(-455, 455);
t.eq(map.layerContainerDiv.style.left, '455px',
'[valid position] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '-455px',
'[valid position] layer container top correct');
t.eq(moved['base'], true,
'[valid position] base layer moved');
t.eq(moved['outofrange'], undefined,
'[valid position] out-of-range layer not moved');
// move outside the max extent
moved = {};
map.moveByPx(-4500, 4500);
t.eq(map.layerContainerDiv.style.left, '455px',
'[outside max extent] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '-455px',
'[outside max extent] layer container top correct');
t.eq(moved['base'], undefined,
'[outside max extent] base layer not moved');
t.eq(moved['outofrange'], undefined,
'[outside max extent] out-of-range layer not moved');
// move outside the restricted extent
moved = {};
map.moveByPx(-500, 500);
t.eq(map.layerContainerDiv.style.left, '455px',
'[outside restricted extent] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '-455px',
'[outside restricted extent] layer container top correct');
t.eq(moved['base'], undefined,
'[outside restricted extent] base layer not moved');
t.eq(moved['outofrange'], undefined,
'[outside restricted extent] out-of-range layer not moved');
map.destroy();
}
// test for http://trac.osgeo.org/openlayers/ticket/3388
function test_moveByPx_restrictedExtent(t) {
t.plan(2);
var map = new OpenLayers.Map({
div: 'map',
restrictedExtent: new OpenLayers.Bounds(-22.5,-11.25,22.5,11.25),
layers: [
new OpenLayers.Layer('name', {isBaseLayer: true})
]
});
map.zoomToExtent(new OpenLayers.Bounds(-11.25, 0, 11.25, 11.25));
map.moveByPx(-10, -10);
t.eq(map.layerContainerDiv.style.left, '10px', 'layer container left correct');
t.eq(map.layerContainerDiv.style.top, '0px', 'layer container top correct');
}
function test_adjustZoom(t) {
t.plan(4);
var map = new OpenLayers.Map({
div: 'map',
layers: [
new OpenLayers.Layer('name', {
isBaseLayer: true,
wrapDateLine: true
})
]
});
map.zoomToMaxExtent();
t.ok(map.getResolution() <= map.getMaxExtent().getWidth() / map.getSize().w, "wrapDateLine map not wider than world");
t.eq(map.adjustZoom(9), 9, "valid zoom maintained");
t.eq(map.adjustZoom(1), 2, "zoom adjusted to not exceed world width");
map.moveTo([16, 48], 0);
t.eq(map.getCenter().toShortString(), "0, 0", "no panning when moveTo is called with invalid zoom");
}
</script>
</head>
<body>
<div id="map" style="width: 600px; height: 300px;"/>
<div style="display: none;"><div id="invisimap"></div></div>
</body>
</html>