summaryrefslogtreecommitdiff
path: root/misc/openlayers/tests/Map.html
diff options
context:
space:
mode:
Diffstat (limited to 'misc/openlayers/tests/Map.html')
-rw-r--r--misc/openlayers/tests/Map.html2255
1 files changed, 2255 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Map.html b/misc/openlayers/tests/Map.html
new file mode 100644
index 0000000..9693fb1
--- /dev/null
+++ b/misc/openlayers/tests/Map.html
@@ -0,0 +1,2255 @@
+<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"},
+ tileManager: null,
+ 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", {tileManager: null, controls: []});
+ OpenLayers.Events.prototype.on = method;
+ map2.destroy();
+ }
+
+ function test_Map_center(t) {
+ t.plan(14);
+ var log = [];
+ map = new OpenLayers.Map('map', {
+ zoomMethod: null,
+ 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', {zoomMethod: null});
+ 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});
+ var log = [];
+ map.applyTransform = function(x, y, scale) {
+ log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]);
+ OpenLayers.Map.prototype.applyTransform.apply(this, arguments);
+ };
+ map.setBaseLayer(wmsLayer);
+ t.eq(log[0][0], 0, "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");
+ },
+ movestart: function(e) {
+ t.eq(e.zoomChanged, true, "movestart listener called with expected value");
+ }
+ });
+ baseLayer.events.on({
+ 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,
+ zoomMethod: null
+ };
+ 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", {zoomMethod: null});
+ 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_zoomTo_animated(t) {
+ t.plan(2);
+
+ var map = new OpenLayers.Map("map");
+ map.addLayer(new OpenLayers.Layer(null, {
+ isBaseLayer: true
+ }));
+
+ map.zoomToMaxExtent();
+
+ map.zoomTo(2);
+ map.zoomIn();
+ map.zoomOut();
+ map.zoomIn();
+ t.delay_call(2, function() {
+ t.eq(map.getZoom(), 3, '[fractionalZoom: false] zoomTo(2) - zoomIn() - zoomOut() - zoomIn()');
+
+ // now allow fractional zoom
+ map.fractionalZoom = true;
+
+ map.zoomTo(2.6);
+ map.zoomIn();
+ map.zoomOut();
+ map.zoomIn();
+ });
+ t.delay_call(4, function() {
+ t.eq(map.getZoom(), 3.6, '[fractionalZoom: true] zoomTo(2) - zoomIn() - zoomOut() - zoomIn()');
+ 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.");
+ }
+
+ function test_pan_no_anim_event_sequence(t) {
+ t.plan(4);
+
+ var log = [];
+ var map = new OpenLayers.Map("map");
+ map.addLayer(
+ new OpenLayers.Layer(null, {isBaseLayer: true})
+ );
+ map.setCenter(new OpenLayers.LonLat(0, 0), 5);
+ map.events.on({
+ "movestart": function() {
+ log.push("movestart");
+ },
+ "move": function() {
+ log.push("move");
+ },
+ "moveend": function() {
+ log.push("moveend");
+ }
+ });
+
+ map.pan(5,5, {animate: false});
+ t.eq(log.length, 3, "no more than 3 events happen.");
+ t.eq(log[0], "movestart", "pan sequence starts with movestart");
+ t.eq(log[1], "move", "followed by move,");
+ t.eq(log[2], "moveend", "and moveend when we're done.");
+
+ map.destroy();
+ }
+
+ // 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(14);
+
+ 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})
+ ]
+ });
+ var log = [];
+ map.applyTransform = function(x, y, scale) {
+ log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]);
+ OpenLayers.Map.prototype.applyTransform.apply(this, arguments);
+ };
+
+ moved = {};
+ map.zoomToExtent(new OpenLayers.Bounds(-1, -1, 1, 1));
+
+ // check initial state
+ t.eq(log[0][0], 0,
+ '[initial state] layer container left correct');
+ t.eq(log[0][1], 0,
+ '[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(log[1][0], 455,
+ '[valid position] layer container left correct');
+ t.eq(log[1][1], -455,
+ '[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(log.length, 2,
+ '[outside max extent] layer container offset unchanged');
+ 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(log.length, 2,
+ '[outside restricted extent] layer container offset unchanged');
+ 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));
+
+ var log = [];
+ map.applyTransform = function(x, y, scale) {
+ log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]);
+ OpenLayers.Map.prototype.applyTransform.apply(this, arguments);
+ };
+
+ map.moveByPx(-10, -10);
+ t.eq(log[0][0], 10, 'layer container left correct');
+ t.eq(log[0][1], 0, 'layer container top correct');
+ }
+
+ function test_applyTransform(t) {
+ t.plan(10);
+ var origStylePrefix = OpenLayers.Util.vendorPrefix.style;
+ OpenLayers.Util.vendorPrefix.style =
+ OpenLayers.Util.vendorPrefix.css =
+ function(key) { return 'transform'; };
+
+ var map = new OpenLayers.Map('map');
+ map.layerContainerDiv = {style: {}};
+ delete map.applyTransform.transform;
+ delete map.applyTransform.template;
+ var origGetStyle = OpenLayers.Element.getStyle;
+ OpenLayers.Element.getStyle = function() { return 'foo'; }
+ map.applyTransform(1, 2, 3);
+ OpenLayers.Element.getStyle = origGetStyle;
+ t.eq(map.layerContainerDiv.style.transform, 'translate3d(1px,2px,0) scale3d(3,3,1)', '3d transform and scale used when available');
+
+ delete map.applyTransform.transform;
+ delete map.applyTransform.template;
+ var origIndexOf = String.prototype.indexOf;
+ String.prototype.indexOf = function() { return -1; };
+ map.layerContainerOriginPx = {x: -3, y: 2};
+ map.applyTransform(1, 2, 3);
+ String.prototype.indexOf = origIndexOf;
+ t.eq(map.layerContainerDiv.style.transform, 'translate(4px,0px) scale(3,3)', '2d translate and scale correct');
+ t.eq(map.layerContainerDiv.style.left, '-3px', 'container origin x set as style.left');
+ t.eq(map.layerContainerDiv.style.top, '2px', 'container origin y set as style.top');
+ map.applyTransform(1, 2);
+ t.ok(!map.layerContainerDiv.style.transform, 'no transform set when no transform needed');
+ t.eq(map.layerContainerDiv.style.left, '1px', 'style.left correct when no transform needed');
+ t.eq(map.layerContainerDiv.style.top, '2px', 'style.top correct when no transform needed');
+
+ map.applyTransform.transform = null;
+ map.applyTransform(4, 5, 6);
+ t.eq(map.layerContainerDiv.style.left, '4px', 'style.left set when transform not available')
+ t.eq(map.layerContainerDiv.style.top, '5px', 'style.top set when transform not available')
+ t.ok(!map.layerContainerDiv.style.transform, 'no transform set, because not supported');
+
+ map.destroy();
+ delete map.applyTransform.transform;
+ delete map.applyTransform.template;
+ OpenLayers.Util.vendorPrefix.style = origStylePrefix;
+ }
+
+ function test_options(t) {
+ t.plan(2);
+
+ var map = new OpenLayers.Map('map');
+ t.eq(map.options, {}, 'map.options is empty with no options');
+ map.destroy();
+
+ var options = {
+ resolutions: [1,2,3,5],
+ projection: "EPSG:4326",
+ units: 'm'
+ };
+ var map = new OpenLayers.Map('map', options);
+ t.eq(map.options, options, 'map.options is a copy of the constructor option');
+ map.destroy();
+ }
+
+ function test_adjustZoom(t) {
+ t.plan(5);
+ 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.fractionalZoom = true;
+ t.eq(map.adjustZoom(1).toPrecision(3), "1.29", "zoom adjusted to match world width");
+
+ map.moveTo([16, 48], 0);
+ t.eq(map.getCenter().toShortString(), "0, 0", "no panning when moveTo is called with invalid zoom");
+ }
+
+ function test_correctCenterAtZoomLevel0(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map({
+ div: 'map',
+ maxExtent: new OpenLayers.Bounds(-30, 48.00, 3.50, 64.00),
+ restrictedExtent: new OpenLayers.Bounds(-30, 48.00, 3.50, 64.00),
+ projection: "EPSG:4258",
+ units: "degrees",
+ layers: [
+ new OpenLayers.Layer('name', {
+ isBaseLayer: true
+ })
+ ]
+ });
+ map.setCenter(new OpenLayers.LonLat(-1.3, 50.8), 4);
+ map.moveTo(null, 0);
+ var center = map.getCenter();
+ t.ok(center.equals(new OpenLayers.LonLat(-13.25, 56)), "Center is correct and not equal to maxExtent's center");
+ }
+
+ function test_getZoomTargetCenter(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map({
+ div: 'map',
+ layers: [
+ new OpenLayers.Layer('', {isBaseLayer: true})
+ ],
+ center: [0, 0],
+ zoom: 1
+ });
+
+ var ll = map.getZoomTargetCenter({x: 44, y: 22}, map.getMaxResolution());
+
+ t.eq(ll.toShortString(), "180, -90", "getZoomTargetCenter works.");
+
+ map.destroy();
+ }
+
+ function test_autoUpdateSize(t) {
+ t.plan(1);
+ OpenLayers.Event.unloadCache();
+ var resizeListener = false;
+ var map = new OpenLayers.Map({
+ autoUpdateSize: false,
+ div: 'map',
+ layers: [
+ new OpenLayers.Layer('name', {
+ isBaseLayer: true,
+ wrapDateLine: true
+ })
+ ]
+ });
+ map.setCenter(new OpenLayers.LonLat(-1.3, 50.8), 4);
+ for (var key in OpenLayers.Event.observers) {
+ var obj = OpenLayers.Event.observers[key];
+ for (var i=0, ii=obj.length; i<ii; ++i) {
+ var listener = obj[i];
+ if (listener.name === 'resize' && listener.element === window) {
+ resizeListener = true;
+ }
+ }
+ }
+ t.eq(resizeListener, map.autoUpdateSize, "resize listener not registered when autoUpdateSize is false");
+ map.destroy();
+ }
+
+ function test_tileManager(t) {
+ t.plan(3);
+ var map = new OpenLayers.Map('map');
+ t.ok(map.tileManager instanceof OpenLayers.TileManager, "Default tileManager created");
+ map.destroy();
+ map = new OpenLayers.Map('map', {tileManager: null});
+ t.ok(map.tileManager === null, "No tileManager created");
+ map.destroy();
+ var options = {cacheSize: 512};
+ map = new OpenLayers.Map('map', {tileManager: options});
+ t.eq(map.tileManager.cacheSize, 512, "cacheSize taken from options");
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 600px; height: 300px;"/>
+ <div style="display: none;"><div id="invisimap"></div></div>
+</body>
+</html>