3 <script src="../lib/OpenLayers.js"></script>
4 <script type="text/javascript">
6 var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
9 function test_Map_constructor (t) {
12 map = new OpenLayers.Map('map');
13 var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
14 "http://octo.metacarta.com/cgi-bin/mapserv?",
15 {map: "/mapdata/vmap_wms.map", layers: "basic"});
16 map.addLayer(baseLayer);
18 t.ok( OpenLayers.Element.hasClass(map.div, "olMap"), "Map div has olMap class");
20 t.ok( map instanceof OpenLayers.Map, "new OpenLayers.Map returns object" );
22 t.ok( true, "skipping element test outside of Mozilla");
23 t.ok( true, "skipping element test outside of Mozilla");
24 t.ok( true, "skipping element test outside of Mozilla");
26 t.ok( map.div instanceof HTMLDivElement, "map.div is an HTMLDivElement" );
27 t.ok( map.viewPortDiv instanceof HTMLDivElement, "map.viewPortDiv is an HTMLDivElement" );
28 t.ok( map.layerContainerDiv instanceof HTMLDivElement, "map.layerContainerDiv is an HTMLDivElement" );
30 t.ok( map.layers instanceof Array, "map.layers is an Array" );
31 t.ok( map.controls instanceof Array, "map.controls is an Array" );
32 t.eq( map.controls.length, 4, "Default map has 4 controls." );
33 t.ok( map.events instanceof OpenLayers.Events, "map.events is an OpenLayers.Events" );
34 t.ok( map.getMaxExtent() instanceof OpenLayers.Bounds, "map.maxExtent is an OpenLayers.Bounds" );
35 t.ok( map.getNumZoomLevels() > 0, "map has a default numZoomLevels" );
38 function test_Map_constructor_late_rendering(t) {
41 map = new OpenLayers.Map();
42 var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
43 "http://octo.metacarta.com/cgi-bin/mapserv?",
44 {map: "/mapdata/vmap_wms.map", layers: "basic"});
45 map.addLayer(baseLayer);
47 t.ok(map.div != null, "Map has a div even though none was specified.");
48 t.ok(map.viewPortDiv.parentNode == map.div, "Map is attached to a temporary div that holds the viewPortDiv.");
50 var mapDiv = document.getElementById("map");
51 // clean up the effects of other tests
52 while(OpenLayers.Element.hasClass(mapDiv, "olMap")) {
53 OpenLayers.Element.removeClass(mapDiv, "olMap");
55 map.render(mapDiv); // Can also take a string.
57 t.ok(map.div == mapDiv, "Map is now rendered to the 'map' div.")
58 t.ok( OpenLayers.Element.hasClass(map.div, "olMap"), "Map div has olMap class");
61 function test_Map_constructor_renderTo(t) {
64 map = new OpenLayers.Map({
67 var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
68 "http://octo.metacarta.com/cgi-bin/mapserv?",
69 {map: "/mapdata/vmap_wms.map", layers: "basic"});
70 map.addLayer(baseLayer);
72 var mapDiv = document.getElementById("map");
73 t.ok(map.div == mapDiv, "Map is rendered to the 'map' div.")
76 function test_Map_setOptions(t) {
78 map = new OpenLayers.Map('map', {maxExtent: new OpenLayers.Bounds(100, 200, 300, 400)});
79 map.setOptions({theme: 'foo'});
81 t.eq(map.theme, 'foo', "theme is correctly set by setOptions");
82 t.ok(map.maxExtent.equals(new OpenLayers.Bounds(100, 200, 300, 400)),
83 "maxExtent is correct after calling setOptions");
86 function test_Map_add_layers(t) {
88 map = new OpenLayers.Map('map');
89 var layer1 = new OpenLayers.Layer.WMS("Layer 1",
90 "http://octo.metacarta.com/cgi-bin/mapserv?",
91 {map: "/mapdata/vmap_wms.map", layers: "basic"});
92 var layer2 = new OpenLayers.Layer.WMS("Layer 2",
93 "http://wms.jpl.nasa.gov/wms.cgi", {layers: "modis,global_mosaic"});
94 // this uses map.addLayer internally
95 map.addLayers([layer1, layer2])
96 t.eq( map.layers.length, 2, "map has exactly two layers" );
97 t.ok( map.layers[0] === layer1, "1st layer is layer1" );
98 t.ok( map.layers[1] === layer2, "2nd layer is layer2" );
99 t.ok( layer1.map === map, "layer.map is map" );
100 t.eq( parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'],
101 "layer1 zIndex is set" );
102 t.eq( parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5,
103 "layer2 zIndex is set" );
106 function test_Map_options(t) {
108 map = new OpenLayers.Map('map', {numZoomLevels: 6, maxResolution: 3.14159, theme: 'foo'});
109 t.eq( map.numZoomLevels, 6, "map.numZoomLevels set correctly via options hashtable" );
110 t.eq( map.maxResolution, 3.14159, "map.maxResolution set correctly via options hashtable" );
111 t.eq( map.theme, 'foo', "map theme set correctly." );
114 function test_eventListeners(t) {
117 var method = OpenLayers.Events.prototype.on;
118 // test that events.on is called at map construction
120 eventListeners: {foo: "bar"},
123 OpenLayers.Events.prototype.on = function(obj) {
124 t.eq(obj, options.eventListeners, "events.on called with eventListeners");
126 var map = new OpenLayers.Map('map', options);
127 OpenLayers.Events.prototype.on = method;
130 // if events.on is called again, this will fail due to an extra test
131 // test map without eventListeners
132 OpenLayers.Events.prototype.on = function(obj) {
133 t.fail("events.on called without eventListeners");
135 var map2 = new OpenLayers.Map("map", {controls: []});
136 OpenLayers.Events.prototype.on = method;
140 function test_Map_center(t) {
142 map = new OpenLayers.Map('map');
143 var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
144 "http://octo.metacarta.com/cgi-bin/mapserv?",
145 {map: "/mapdata/vmap_wms.map", layers: "basic"} );
146 map.addLayer(baseLayer);
147 var ll = new OpenLayers.LonLat(2,1);
148 map.setCenter(ll, 0);
149 t.ok( map.getCenter() instanceof OpenLayers.LonLat, "map.getCenter returns a LonLat");
150 t.eq( map.getZoom(), 0, "map.zoom is correct after calling setCenter");
151 t.ok( map.getCenter().equals(ll), "map center is correct after calling setCenter");
153 t.eq( map.getZoom(), 1, "map.zoom is correct after calling setCenter,zoom in");
154 t.ok( map.getCenter().equals(ll), "map center is correct after calling setCenter, zoom in");
156 t.eq( map.getZoom(), 0, "map.zoom is correct after calling setCenter,zoom in, zoom out");
159 t.eq( map.getZoom(), 5, "map.zoom is correct after calling zoomTo" );
162 map.zoomToMaxExtent();
163 t.eq( map.getZoom(), 2, "map.zoom is correct after calling zoomToMaxExtent" );
164 var lonlat = map.getCenter();
165 var zero = new OpenLayers.LonLat(0, 0);
166 t.ok( lonlat.equals(zero), "map center is correct after calling zoomToFullExtent" );
169 map.getCenter().lon = 10;
170 t.ok( map.getCenter().equals(ll), "map.getCenter returns a clone of map.center");
173 function test_Map_zoomend_event (t) {
176 map = new OpenLayers.Map('map');
177 var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
178 "http://octo.metacarta.com/cgi-bin/mapserv?",
179 {map: "/mapdata/vmap_wms.map", layers: "basic"});
180 map.addLayer(baseLayer);
181 map.events.register("zoomend", {count: 0}, function() {
183 t.ok(true, "zoomend event was triggered " + this.count + " times");
185 map.setCenter(new OpenLayers.LonLat(2, 1), 0);
190 function test_Map_add_remove_popup (t) {
193 map = new OpenLayers.Map('map');
194 var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
195 "http://octo.metacarta.com/cgi-bin/mapserv?",
196 {map: "/mapdata/vmap_wms.map", layers: "basic"});
197 map.addLayer(baseLayer);
199 var popup = new OpenLayers.Popup("chicken",
200 new OpenLayers.LonLat(0,0),
201 new OpenLayers.Size(200,200));
202 map.setCenter(new OpenLayers.LonLat(0, 0), 0);
205 var pIndex = OpenLayers.Util.indexOf(map.popups, popup);
206 t.eq(pIndex, 0, "popup successfully added to Map's internal popups array");
208 var nodes = map.layerContainerDiv.childNodes;
211 for (var i=0; i < nodes.length; i++) {
212 if (nodes.item(i) == popup.div) {
217 t.ok(found, "popup.div successfully added to the map's viewPort");
220 map.removePopup(popup);
221 var pIndex = OpenLayers.Util.indexOf(map.popups, popup);
222 t.eq(pIndex, -1, "popup successfully removed from Map's internal popups array");
225 for (var i=0; i < nodes.length; i++) {
226 if (nodes.item(i) == popup.div) {
231 t.ok(!found, "popup.div successfully removed from the map's viewPort");
234 function test_Map_add_popup_exclusive(t) {
237 map = new OpenLayers.Map('map');
238 var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
239 "http://octo.metacarta.com/cgi-bin/mapserv?",
240 {map: "/mapdata/vmap_wms.map", layers: "basic"});
241 map.addLayer(baseLayer);
243 map.setCenter(new OpenLayers.LonLat(0, 0), 0);
245 for (var i = 0; i < 10; i++) {
246 var popup = new OpenLayers.Popup("chicken",
247 new OpenLayers.LonLat(0,0),
248 new OpenLayers.Size(200,200));
251 t.eq(map.popups.length, 10, "addPopup non exclusive mode works");
253 var popup = new OpenLayers.Popup("chicken",
254 new OpenLayers.LonLat(0,0),
255 new OpenLayers.Size(200,200));
256 map.addPopup(popup, true);
257 t.eq(map.popups.length, 1, "addPopup exclusive mode works");
261 /*** THIS IS A GOOD TEST, BUT IT SHOULD BE MOVED TO WMS.
262 * Also, it won't work until we figure out the viewSize bug
264 function 08_Map_px_lonlat_translation (t) {
266 map = new OpenLayers.Map('map');
267 var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
268 "http://octo.metacarta.com/cgi-bin/mapserv?",
269 {map: "/mapdata/vmap_wms.map", layers: "basic"});
270 map.addLayer(baseLayer);
271 map.setCenter(new OpenLayers.LonLat(0, 0), 0);
273 var pixel = new OpenLayers.Pixel(50,150);
274 var lonlat = map.getLonLatFromViewPortPx(pixel);
275 t.ok( lonlat instanceof OpenLayers.LonLat, "getLonLatFromViewPortPx returns valid OpenLayers.LonLat" );
277 var newPixel = map.getViewPortPxFromLonLat(lonlat);
278 t.ok( newPixel instanceof OpenLayers.Pixel, "getViewPortPxFromLonLat returns valid OpenLayers.Pixel" );
280 // WARNING!!! I'm faily sure that the following test's validity
281 // depends highly on rounding and the resolution. For now,
282 // in the default case, it seems to work. This may not
284 t.ok( newPixel.equals(pixel), "Translation to pixel and back to lonlat is consistent");
286 lonlat = map.getLonLatFromPixel(pixel);
287 t.ok( lonlat instanceof OpenLayers.LonLat, "getLonLatFromPixel returns valid OpenLayers.LonLat" );
289 newPixel = map.getPixelFromLonLat(lonlat);
290 t.ok( newPixel instanceof OpenLayers.Pixel, "getPixelFromLonLat returns valid OpenLayers.Pixel" );
292 t.ok( newPixel.equals(pixel), "2nd translation to pixel and back to lonlat is consistent");
296 function test_Map_isValidLonLat(t) {
299 map = new OpenLayers.Map('map');
300 layer = new OpenLayers.Layer.WMS('Test Layer',
301 "http://octo.metacarta.com/cgi-bin/mapserv",
302 {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
303 {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
306 t.ok( !map.isValidLonLat(null), "null lonlat is not valid" );
307 t.ok( map.isValidLonLat(new OpenLayers.LonLat(33862, 717606)), "lonlat outside max extent is valid" );
308 t.ok( !map.isValidLonLat(new OpenLayers.LonLat(10, 10)), "lonlat outside max extent is not valid" );
311 function test_Map_getLayer(t) {
313 t.plan( numLayers + 1 );
319 for(var i = 0; i < numLayers; i++) {
320 m.layers.push( { 'id': i } );
323 for(var i = 0; i < numLayers; i++) {
324 var layer = OpenLayers.Map.prototype.getLayer.apply(m, [i]);
325 t.ok( layer == m.layers[i], "getLayer correctly returns layer " + i);
328 var gotLayer = OpenLayers.Map.prototype.getLayer.apply(m, ["chicken"]);
329 t.ok( gotLayer == null, "getLayer correctly returns null when layer not found");
332 function test_Map_getLayersBy(t) {
335 getBy: OpenLayers.Map.prototype.getBy,
336 getLayersBy: OpenLayers.Map.prototype.getLayersBy,
338 {foo: "foo", id: Math.random()},
339 {foo: "bar", id: Math.random()},
340 {foo: "foobar", id: Math.random()},
341 {foo: "foo bar", id: Math.random()},
342 {foo: "foo", id: Math.random()}
348 got: map.getLayersBy("foo", "foo"),
349 expected: [map.layers[0], map.layers[4]],
350 message: "(string literal) got two layers matching foo"
352 got: map.getLayersBy("foo", "bar"),
353 expected: [map.layers[1]],
354 message: "(string literal) got one layer matching foo"
356 got: map.getLayersBy("foo", "barfoo"),
358 message: "(string literal) got empty array for no foo match"
360 got: map.getLayersBy("foo", /foo/),
361 expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],
362 message: "(regexp literal) got three layers containing string"
364 got: map.getLayersBy("foo", /foo$/),
365 expected: [map.layers[0], map.layers[4]],
366 message: "(regexp literal) got three layers ending with string"
368 got: map.getLayersBy("foo", /\s/),
369 expected: [map.layers[3]],
370 message: "(regexp literal) got layer containing space"
372 got: map.getLayersBy("foo", new RegExp("BAR", "i")),
373 expected: [map.layers[1], map.layers[2], map.layers[3]],
374 message: "(regexp object) got layers ignoring case"
376 got: map.getLayersBy("foo", {test: function(str) {return str.length > 3;}}),
377 expected: [map.layers[2], map.layers[3]],
378 message: "(custom object) got layers with foo length greater than 3"
381 t.plan(cases.length);
382 for(var i=0; i<cases.length; ++i) {
383 t.eq(cases[i].got, cases[i].expected, cases[i].message);
388 function test_Map_getLayersByName(t) {
391 getBy: OpenLayers.Map.prototype.getBy,
392 getLayersBy: OpenLayers.Map.prototype.getLayersBy,
393 getLayersByName: OpenLayers.Map.prototype.getLayersByName,
395 {name: "foo", id: Math.random()},
396 {name: "bar", id: Math.random()},
397 {name: "foobar", id: Math.random()},
398 {name: "foo bar", id: Math.random()},
399 {name: "foo", id: Math.random()}
405 got: map.getLayersByName("foo"),
406 expected: [map.layers[0], map.layers[4]],
407 message: "(string literal) got two layers matching name"
409 got: map.getLayersByName("bar"),
410 expected: [map.layers[1]],
411 message: "(string literal) got one layer matching name"
413 got: map.getLayersByName("barfoo"),
415 message: "(string literal) got empty array for no match"
417 got: map.getLayersByName(/foo/),
418 expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],
419 message: "(regexp literal) got three layers containing string"
421 got: map.getLayersByName(/foo$/),
422 expected: [map.layers[0], map.layers[4]],
423 message: "(regexp literal) got three layers ending with string"
425 got: map.getLayersByName(/\s/),
426 expected: [map.layers[3]],
427 message: "(regexp literal) got layer containing space"
429 got: map.getLayersByName(new RegExp("BAR", "i")),
430 expected: [map.layers[1], map.layers[2], map.layers[3]],
431 message: "(regexp object) got layers ignoring case"
433 got: map.getLayersByName({test: function(str) {return str.length > 3;}}),
434 expected: [map.layers[2], map.layers[3]],
435 message: "(custom object) got layers with name length greater than 3"
438 t.plan(cases.length);
439 for(var i=0; i<cases.length; ++i) {
440 t.eq(cases[i].got, cases[i].expected, cases[i].message);
445 function test_Map_getLayersByClass(t) {
448 getBy: OpenLayers.Map.prototype.getBy,
449 getLayersBy: OpenLayers.Map.prototype.getLayersBy,
450 getLayersByClass: OpenLayers.Map.prototype.getLayersByClass,
452 {CLASS_NAME: "foo", id: Math.random()},
453 {CLASS_NAME: "bar", id: Math.random()},
454 {CLASS_NAME: "foobar", id: Math.random()},
455 {CLASS_NAME: "foo bar", id: Math.random()},
456 {CLASS_NAME: "foo", id: Math.random()}
462 got: map.getLayersByClass("foo"),
463 expected: [map.layers[0], map.layers[4]],
464 message: "(string literal) got two layers matching type"
466 got: map.getLayersByClass("bar"),
467 expected: [map.layers[1]],
468 message: "(string literal) got one layer matching type"
470 got: map.getLayersByClass("barfoo"),
472 message: "(string literal) got empty array for no match"
474 got: map.getLayersByClass(/foo/),
475 expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],
476 message: "(regexp literal) got three layers containing string"
478 got: map.getLayersByClass(/foo$/),
479 expected: [map.layers[0], map.layers[4]],
480 message: "(regexp literal) got three layers ending with string"
482 got: map.getLayersByClass(/\s/),
483 expected: [map.layers[3]],
484 message: "(regexp literal) got layer containing space"
486 got: map.getLayersByClass(new RegExp("BAR", "i")),
487 expected: [map.layers[1], map.layers[2], map.layers[3]],
488 message: "(regexp object) got layers ignoring case"
490 got: map.getLayersByClass({test: function(str) {return str.length > 3;}}),
491 expected: [map.layers[2], map.layers[3]],
492 message: "(custom object) got layers with type length greater than 3"
495 t.plan(cases.length);
496 for(var i=0; i<cases.length; ++i) {
497 t.eq(cases[i].got, cases[i].expected, cases[i].message);
502 function test_Map_getControlsBy(t) {
505 getBy: OpenLayers.Map.prototype.getBy,
506 getControlsBy: OpenLayers.Map.prototype.getControlsBy,
508 {foo: "foo", id: Math.random()},
509 {foo: "bar", id: Math.random()},
510 {foo: "foobar", id: Math.random()},
511 {foo: "foo bar", id: Math.random()},
512 {foo: "foo", id: Math.random()}
518 got: map.getControlsBy("foo", "foo"),
519 expected: [map.controls[0], map.controls[4]],
520 message: "(string literal) got two controls matching foo"
522 got: map.getControlsBy("foo", "bar"),
523 expected: [map.controls[1]],
524 message: "(string literal) got one control matching foo"
526 got: map.getControlsBy("foo", "barfoo"),
528 message: "(string literal) got empty array for no foo match"
530 got: map.getControlsBy("foo", /foo/),
531 expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]],
532 message: "(regexp literal) got three controls containing string"
534 got: map.getControlsBy("foo", /foo$/),
535 expected: [map.controls[0], map.controls[4]],
536 message: "(regexp literal) got three controls ending with string"
538 got: map.getControlsBy("foo", /\s/),
539 expected: [map.controls[3]],
540 message: "(regexp literal) got control containing space"
542 got: map.getControlsBy("foo", new RegExp("BAR", "i")),
543 expected: [map.controls[1], map.controls[2], map.controls[3]],
544 message: "(regexp object) got layers ignoring case"
546 got: map.getControlsBy("foo", {test: function(str) {return str.length > 3;}}),
547 expected: [map.controls[2], map.controls[3]],
548 message: "(custom object) got controls with foo length greater than 3"
551 t.plan(cases.length);
552 for(var i=0; i<cases.length; ++i) {
553 t.eq(cases[i].got, cases[i].expected, cases[i].message);
558 function test_Map_getControlsByClass(t) {
561 getBy: OpenLayers.Map.prototype.getBy,
562 getControlsBy: OpenLayers.Map.prototype.getControlsBy,
563 getControlsByClass: OpenLayers.Map.prototype.getControlsByClass,
565 {CLASS_NAME: "foo", id: Math.random()},
566 {CLASS_NAME: "bar", id: Math.random()},
567 {CLASS_NAME: "foobar", id: Math.random()},
568 {CLASS_NAME: "foo bar", id: Math.random()},
569 {CLASS_NAME: "foo", id: Math.random()}
575 got: map.getControlsByClass("foo"),
576 expected: [map.controls[0], map.controls[4]],
577 message: "(string literal) got two controls matching type"
579 got: map.getControlsByClass("bar"),
580 expected: [map.controls[1]],
581 message: "(string literal) got one control matching type"
583 got: map.getControlsByClass("barfoo"),
585 message: "(string literal) got empty array for no match"
587 got: map.getControlsByClass(/foo/),
588 expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]],
589 message: "(regexp literal) got three controls containing string"
591 got: map.getControlsByClass(/foo$/),
592 expected: [map.controls[0], map.controls[4]],
593 message: "(regexp literal) got three controls ending with string"
595 got: map.getControlsByClass(/\s/),
596 expected: [map.controls[3]],
597 message: "(regexp literal) got control containing space"
599 got: map.getControlsByClass(new RegExp("BAR", "i")),
600 expected: [map.controls[1], map.controls[2], map.controls[3]],
601 message: "(regexp object) got controls ignoring case"
603 got: map.getControlsByClass({test: function(str) {return str.length > 3;}}),
604 expected: [map.controls[2], map.controls[3]],
605 message: "(custom object) got controls with type length greater than 3"
608 t.plan(cases.length);
609 for(var i=0; i<cases.length; ++i) {
610 t.eq(cases[i].got, cases[i].expected, cases[i].message);
615 function test_Map_double_addLayer(t) {
618 map = new OpenLayers.Map($('map'));
619 layer = new OpenLayers.Layer.WMS('Test Layer',
620 "http://octo.metacarta.com/cgi-bin/mapserv",
621 {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}
624 map.addLayers([layer,layer]);
626 t.eq( map.layers.length, 1, "Map does not allow double adding of layers." );
630 function test_Map_setBaseLayer(t) {
633 map = new OpenLayers.Map('map');
635 var wmslayer = new OpenLayers.Layer.WMS('Test Layer',
636 "http://octo.metacarta.com/cgi-bin/mapserv",
637 {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
638 {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
640 var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2',
641 "http://octo.metacarta.com/cgi-bin/mapserv",
642 {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
643 {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
645 map.addLayers([wmslayer, wmslayer2]);
647 t.ok(map.baseLayer == wmslayer, "default base layer is first one added");
649 map.setBaseLayer(null);
650 t.ok(map.baseLayer == wmslayer, "setBaseLayer on null object does nothing (and does not break)");
652 map.setBaseLayer("chicken");
653 t.ok(map.baseLayer == wmslayer, "setBaseLayer on non-layer object does nothing (and does not break)");
655 map.setBaseLayer(wmslayer2);
656 t.ok(map.baseLayer == wmslayer2, "setbaselayer correctly sets 'baseLayer' property");
659 function test_Map_removeLayer(t) {
661 var f = function() {};
663 {name: "fee", removeMap: f},
664 {name: "fi", removeMap: f},
665 {name: "fo", removeMap: f},
666 {name: "fum", removeMap: f}
670 baseLayer: layers[0],
671 layerContainerDiv: {removeChild: f},
672 events: {triggerEvent: f},
673 resetLayersZIndex: function() {}
675 OpenLayers.Map.prototype.removeLayer.apply(map, [map.baseLayer, false]);
676 t.eq(map.baseLayer, null,
677 "removing the baselayer sets baseLayer to null");
680 function test_Map_removeLayer_res(t) {
683 map = new OpenLayers.Map('map');
685 var layer0 = new OpenLayers.Layer.WMS(
687 "http://octo.metacarta.com/cgi-bin/mapserv",
688 {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
689 {resolutions: [4, 2, 1]}
692 var layer1 = new OpenLayers.Layer.WMS(
694 "http://octo.metacarta.com/cgi-bin/mapserv",
695 {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
696 {resolutions: [4, 2]}
699 map.addLayers([layer0, layer1]);
700 map.zoomToMaxExtent();
702 t.eq(map.getResolution(), layer0.resolutions[2],
703 "correct resolution before removal");
704 map.removeLayer(layer0);
705 t.eq(map.getResolution(), layer0.resolutions[1],
706 "correct resolution after removal");
709 function test_Map_removeLayer_zindex(t) {
712 map = new OpenLayers.Map('map');
714 var layer0 = new OpenLayers.Layer('Test Layer 0', {isBaseLayer:true});
715 var layer1 = new OpenLayers.Layer('Test Layer 1', {isBaseLayer:true});
716 var layer2 = new OpenLayers.Layer('Test Layer 2', {isBaseLayer:false});
718 map.addLayers([layer0, layer1, layer2]);
719 map.removeLayer(layer0);
721 t.eq(parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'],
722 "correct z-index after removeLayer");
723 t.eq(parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['Overlay'] + 5,
724 "correct z-index after removeLayer");
727 function test_Map_setBaseLayer_after_pan (t) {
730 map = new OpenLayers.Map('map');
731 var wmsLayer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
732 "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );
733 var tmsLayer = new OpenLayers.Layer.TMS("TMS",
734 "http://labs.metacarta.com/wms-c/Basic.py/",
735 {'layername':'basic', 'type':'png'});
736 map.addLayers([wmsLayer,tmsLayer]);
737 map.setBaseLayer(wmsLayer);
738 map.zoomToMaxExtent();
739 map.setBaseLayer(tmsLayer);
741 map.pan(0, -200, {animate:false});
742 map.setBaseLayer(wmsLayer);
743 t.eq(map.layerContainerDiv.style.top, "0px", "layerContainer is recentered after setBaseLayer");
746 function test_Map_moveLayer (t) {
750 map = new OpenLayers.Map('map');
751 var wmslayer = new OpenLayers.Layer.WMS('Test Layer',
752 "http://octo.metacarta.com/cgi-bin/mapserv",
753 {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
754 {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
756 var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2',
757 "http://octo.metacarta.com/cgi-bin/mapserv",
758 {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
759 {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
761 var wmslayer3 = new OpenLayers.Layer.WMS('Test Layer2',
762 "http://octo.metacarta.com/cgi-bin/mapserv",
763 {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'},
764 {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
766 map.addLayers([wmslayer, wmslayer2, wmslayer3]);
767 map.events.register("changelayer", map, function (e) { ct++; });
768 t.eq( map.getNumLayers(), 3, "getNumLayers returns the number of layers" );
769 t.eq( map.getLayerIndex(wmslayer3), 2, "getLayerIndex returns the right index" );
770 map.raiseLayer(wmslayer3, 1);
771 t.eq( map.getLayerIndex(wmslayer3), 2, "can't moveLayer up past the top of the stack" );
772 map.raiseLayer(wmslayer, -1);
773 t.eq( map.getLayerIndex(wmslayer), 0, "can't moveLayer down past the bottom of the stack" );
774 map.raiseLayer(wmslayer3, -1);
775 t.eq( map.getLayerIndex(wmslayer3), 1, "can moveLayer down from the top" );
776 t.eq( parseInt(wmslayer3.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5,
777 "layer div has the right zIndex after moving down" );
778 map.raiseLayer(wmslayer, 2);
779 t.eq( map.getLayerIndex(wmslayer), 2, "can moveLayer up from the bottom" );
780 t.eq( parseInt(wmslayer.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 2 * 5,
781 "layer div has the right zIndex after moving up" );
782 t.eq( map.getLayerIndex(wmslayer3), 0, "top layer is now on the bottom" );
783 t.eq( ct, 3, "raiseLayer triggered changelayer the right # of times" );
786 function test_Map_moveTo(t) {
789 map = new OpenLayers.Map('map');
790 var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
791 "http://octo.metacarta.com/cgi-bin/mapserv?",
792 {map: "/mapdata/vmap_wms.map", layers: "basic"},
793 {maxResolution: 'auto', maxExtent: new OpenLayers.Bounds(-10,-10,10,10)});
794 baseLayer.events.on({
796 t.ok(true, "move listener called");
798 moveend: function(e) {
799 t.eq(e.zoomChanged, true, "moveend listener called with expected value");
802 map.addLayer(baseLayer);
803 var ll = new OpenLayers.LonLat(-100,-150);
805 t.ok(map.getCenter().equals(new OpenLayers.LonLat(0,0)), "safely sets out-of-bounds lonlat");
808 function test_Map_defaultTheme(t) {
811 var links = document.getElementsByTagName('link');
812 map = new OpenLayers.Map('map');
814 var themeNode = null;
815 for(var i=0; i<links.length; ++i) {
816 if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) {
818 themeNode = links.item(i);
821 t.eq(gotNodes, 1, "by default, a single link node is added to document");
822 t.ok(themeNode != null, "a link node with the theme href was added");
823 t.eq(themeNode.rel, "stylesheet", "node added has rel set to stylesheet");
824 t.eq(themeNode.type, "text/css", "node added has type set to text/css");
826 // reconstruct the map to prove that another link is not added
827 map = new OpenLayers.Map('map');
828 t.eq(links.length, document.getElementsByTagName('link').length,
829 "calling the map constructor twice with the same theme doesn't add duplicate link nodes");
832 function test_Map_customTheme(t) {
835 var customTheme = 'foo';
836 var options = {theme: customTheme};
837 map = new OpenLayers.Map('map', options);
839 var links = document.getElementsByTagName('link');
841 var themeNode = null;
842 for(var i=0; i<links.length; ++i) {
843 if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) {
845 themeNode = links.item(i);
849 t.eq(map.theme, customTheme, "map theme is properly set");
850 t.eq(gotNodes, 1, "with custom theme, a single link node is added to document");
851 t.ok(themeNode != null, "a link node with the theme href was added");
852 t.eq(themeNode.rel, "stylesheet", "node added has rel set to stylesheet");
853 t.eq(themeNode.type, "text/css", "node added has type set to text/css");
856 function test_Map_noTheme(t) {
859 var head = document.getElementsByTagName('head')[0];
860 var nodeCount = head.childNodes.length;
862 var options = {theme: null};
863 map = new OpenLayers.Map('map', options);
865 t.eq(nodeCount, head.childNodes.length, "with no theme, a node is not added to document head" );
868 function test_Map_getControl(t) {
871 var map1 = new OpenLayers.Map('map');
873 var control = new OpenLayers.Control();
874 map1.addControl(control);
876 var gotControl = map1.getControl(control.id);
877 t.ok(gotControl == control, "got right control");
879 gotControl = map1.getControl("bogus id");
880 t.ok(gotControl == null, "getControl() for bad id returns null");
883 function test_Map_removeControl(t) {
886 var oldNumControls, newNumControls;
888 var map1 = new OpenLayers.Map('map');
889 oldNumControls = map1.controls.length;
891 var control = new OpenLayers.Control();
892 map1.addControl(control);
895 newNumControls = map1.controls.length;
896 t.ok( newNumControls = oldNumControls + 1, "adding a control increases control count")
898 var foundDiv = false;
899 for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) {
900 var childNode = map1.viewPortDiv.childNodes[i];
901 if (childNode == control.div) {
905 t.ok(foundDiv, "new control's div correctly added to viewPort");
908 map1.removeControl(control)
909 newNumControls = map1.controls.length;
910 t.ok( newNumControls == oldNumControls, "removing the control decreases control count")
912 var gotControl = map1.getControl(control.id);
913 t.ok( gotControl == null, "control no longer in map's controls array");
915 var foundDiv = false;
916 for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) {
917 var childNode = map1.viewPortDiv.childNodes[i];
918 if (childNode == control.div) {
922 t.ok(!foundDiv, "control no longer child of viewPort");
925 control = { id: "bogus id" };
926 map1.removeControl(control);
927 newNumControls = map1.controls.length;
928 t.ok( newNumControls == oldNumControls, "removing bad controlid doesnt crash or decrease control count")
931 function test_Map_restrictedExtent(t) {
933 var extent = new OpenLayers.Bounds(-180, -90, 180, 90);
935 maxResolution: "auto"
937 var map = new OpenLayers.Map("map", options);
938 var layer = new OpenLayers.Layer.WMS(
940 "http://octo.metacarta.com/cgi-bin/mapserv?",
941 {map: "/mapdata/vmap_wms.map", layers: "basic"}
944 map.zoomToMaxExtent();
945 var nw = new OpenLayers.LonLat(extent.left, extent.top);
946 var ne = new OpenLayers.LonLat(extent.right, extent.top);
947 var sw = new OpenLayers.LonLat(extent.left, extent.bottom);
948 var se = new OpenLayers.LonLat(extent.right, extent.bottom);
950 // try panning to northwest corner
951 map.setOptions({restrictedExtent: extent});
952 map.setCenter(nw, 0);
953 t.eq(map.getExtent().getCenterLonLat().toString(),
954 extent.getCenterLonLat().toString(),
955 "map extent properly restricted to northwest at zoom 0");
956 t.eq(map.zoom, 0, "zoom not restricted for nw, 0");
957 map.setCenter(nw, 5);
958 t.eq(map.getExtent().top, extent.top,
959 "map extent top properly restricted to northwest at zoom 5");
960 t.eq(map.getExtent().left, extent.left,
961 "map extent left properly restricted to northwest at zoom 5");
962 t.eq(map.zoom, 5, "zoom not restricted for nw, 5");
963 map.setOptions({restrictedExtent: null});
964 map.setCenter(nw, 0);
965 t.eq(map.getExtent().getCenterLonLat().toString(),
967 "map extent not restricted with null restrictedExtent for nw");
969 // try panning to northeast corner
970 map.setOptions({restrictedExtent: extent});
971 map.setCenter(ne, 0);
972 t.eq(map.getExtent().getCenterLonLat().toString(),
973 extent.getCenterLonLat().toString(),
974 "map extent properly restricted to northeast at zoom 0");
975 t.eq(map.zoom, 0, "zoom not restricted for ne, 0");
976 map.setCenter(ne, 5);
977 t.eq(map.getExtent().top, extent.top,
978 "map extent top properly restricted to northeast at zoom 5");
979 t.eq(map.getExtent().right, extent.right,
980 "map extent right properly restricted to northeast at zoom 5");
981 t.eq(map.zoom, 5, "zoom not restricted for ne, 5");
982 map.setOptions({restrictedExtent: null});
983 map.setCenter(ne, 0);
984 t.eq(map.getExtent().getCenterLonLat().toString(),
986 "map extent not restricted with null restrictedExtent for ne");
988 // try panning to southwest corner
989 map.setOptions({restrictedExtent: extent});
990 map.setCenter(sw, 0);
991 t.eq(map.getExtent().getCenterLonLat().toString(),
992 extent.getCenterLonLat().toString(),
993 "map extent properly restricted to southwest at zoom 0");
994 t.eq(map.zoom, 0, "zoom not restricted for sw, 0");
995 map.setCenter(sw, 5);
996 t.eq(map.getExtent().bottom, extent.bottom,
997 "map extent bottom properly restricted to southwest at zoom 5");
998 t.eq(map.getExtent().left, extent.left,
999 "map extent left properly restricted to southwest at zoom 5");
1000 t.eq(map.zoom, 5, "zoom not restricted for sw, 5");
1001 map.setOptions({restrictedExtent: null});
1002 map.setCenter(sw, 0);
1003 t.eq(map.getExtent().getCenterLonLat().toString(),
1005 "map extent not restricted with null restrictedExtent for sw");
1007 // try panning to southeast corner
1008 map.setOptions({restrictedExtent: extent});
1009 map.setCenter(se, 0);
1010 t.eq(map.getExtent().getCenterLonLat().toString(),
1011 extent.getCenterLonLat().toString(),
1012 "map extent properly restricted to southeast at zoom 0");
1013 t.eq(map.zoom, 0, "zoom not restricted for se, 0");
1014 map.setCenter(se, 5);
1015 t.eq(map.getExtent().bottom, extent.bottom,
1016 "map extent bottom properly restricted to southeast at zoom 5");
1017 t.eq(map.getExtent().right, extent.right,
1018 "map extent right properly restricted to southeast at zoom 5");
1019 t.eq(map.zoom, 5, "zoom not restricted for se, 5");
1020 map.setOptions({restrictedExtent: null});
1021 map.setCenter(se, 0);
1022 t.eq(map.getExtent().getCenterLonLat().toString(),
1024 "map extent not restricted with null restrictedExtent for se");
1027 function test_Map_getResolutionForZoom(t) {
1029 var map = new OpenLayers.Map("map");
1030 var res = map.getResolutionForZoom();
1031 t.eq(res, null, "getResolutionForZoom returns null for no base layer");
1032 map.fractionalZoom = true;
1033 var layer = new OpenLayers.Layer("test", {isBaseLayer: true});
1034 layer.getResolutionForZoom = function() {
1035 t.ok(true, "getResolutionForZoom calls base layer getResolutionForZoom");
1037 map.addLayer(layer);
1038 var res = map.getResolutionForZoom();
1043 function test_Map_getUnits(t) {
1045 var map = new OpenLayers.Map("map");
1046 var units = map.getUnits();
1047 t.eq(units, null, "getUnits returns null for no base layer");
1049 var layer = new OpenLayers.Layer("test", {
1053 map.addLayer(layer);
1054 var units = map.getUnits();
1055 t.eq(units, 'foo', "getUnits returns the base layer units property");
1060 function test_Map_destroy (t) {
1062 map = new OpenLayers.Map('map');
1064 t.eq( map.layers, null, "map.layers is null after destroy" );
1065 t.eq( map.controls, null, "map.controls is null after destroy" );
1066 t.eq( map.viewPortDiv, null, "map's viewportDiv nullified");
1069 function test_Map_getMaxExtent(t){
1075 //null options, no baseLayer
1076 var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1077 t.eq(maxExtent, null, "null options, no baseLayer returns null");
1079 //null options.restricted, no baseLayer
1080 maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1081 t.eq(maxExtent, null, "null options.restricted, no baseLayer returns null");
1083 //true options.restricted, null map.restrictedExtent no baseLayer
1084 maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1085 t.eq(maxExtent, null, "true options.restricted, null map.restrictedExtent no baseLayer returns null");
1087 //true options.restricted, valid map.restrictedExtent no baseLayer
1091 map.restrictedExtent = {};
1092 maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1093 t.ok(maxExtent == map.restrictedExtent, "true options.restricted, valid map.restrictedExtent no baseLayer returns map.restrictedExtent");
1095 //null options, valid baseLayer
1100 var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1101 t.ok(maxExtent == map.baseLayer.maxExtent, "null options, valid baseLayer returns map.baseLayer.maxExtent");
1104 function test_Map_zoomToMaxExtent(t){
1110 'getMaxExtent': function(options) {
1111 gRestricted = options.restricted;
1114 'zoomToExtent': function(extent) {
1115 t.ok(extent == gMaxExtent, "zoomToExtent() always called on return from map.getMaxExtent()");
1122 OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]);
1123 t.eq(gRestricted, true, "default 'restricted' passed to map.getMaxExtent() is true");
1130 OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]);
1131 t.ok(gRestricted == options.restricted, "when valid options argument, 'options.restricted' passed to map.getMaxExtent()");
1134 function test_Map_zoomToScale(t) {
1138 'baseLayer': { 'units': {} },
1139 'getSize': function() { return {'w': 10, 'h': 15}; },
1140 'getCenter': function() { return {'lon': -5, 'lat': -25}; },
1141 'zoomToExtent': function(extent, closest) {
1142 t.ok(extent.equals(g_ExpectedExtent), "extent correctly calculated for zoomToExtent()");
1143 t.ok(closest == g_Closest, "closest correctly passed on to zoomToExtent()");
1147 var temp = OpenLayers.Util.getResolutionFromScale;
1148 OpenLayers.Util.getResolutionFromScale = function(scale, units) {
1149 t.ok(scale == g_Scale, "scale parameter correctly passed to getResolutionFromScale");
1150 t.ok(units == m.baseLayer.units, "map's baselayer's units parameter correctly passed to getResolutionFromScale");
1154 g_ExpectedExtent = new OpenLayers.Bounds(-5005,-7525,4995,7475);
1157 var args = [g_Scale, g_Closest];
1158 OpenLayers.Map.prototype.zoomToScale.apply(m, args);
1160 OpenLayers.Util.getResolutionFromScale = temp;
1163 function test_Map_zoomToExtent(t) {
1169 'wrapDateLine': false
1171 'setCenter': function(center, zoomLevel) {
1173 g_ZoomLevel = zoomLevel;
1175 'getZoomForExtent': function(bounds, closest) {
1176 t.ok(bounds.equals(g_ToCenterBounds), "bounds correctly passed into getZoomForExtent()");
1177 t.ok(closest == g_Closest, "closest correctly passed along to getZoomForExtent()");
1178 return g_ZoomLevelReturn;
1183 g_ZoomLevelReturn = {};
1184 g_Bounds = new OpenLayers.Bounds(-20,-15,0,5);
1185 g_ExpectedCenter = new OpenLayers.LonLat(-10,-5);
1187 g_ToCenterBounds = g_Bounds;
1188 var args = [g_Bounds, g_Closest];
1189 OpenLayers.Map.prototype.zoomToExtent.apply(m, args);
1191 t.ok(g_Center.equals(g_ExpectedCenter), "setCenter called on correct center");
1192 t.ok(g_ZoomLevel == g_ZoomLevelReturn, "correctly passes along zoom level as returned from getZoomForExtent()");
1196 m.baseLayer.wrapDateLine = true;
1197 m.getMaxExtent = function() { return new OpenLayers.Bounds(-200,-200,200,200); };
1199 g_ZoomLevelReturn = {};
1200 g_BoundsCenter = {};
1201 g_Bounds = new OpenLayers.Bounds(160,-60,-60,60);
1202 g_ExpectedCenter = new OpenLayers.LonLat(-150,0);
1204 g_ToCenterBounds = new OpenLayers.Bounds(160,-60,340,60);
1205 var args = [g_Bounds, g_Closest];
1206 OpenLayers.Map.prototype.zoomToExtent.apply(m, args);
1207 t.ok(g_Center.equals(g_ExpectedCenter), "setCenter called on correct center");
1208 t.ok(g_ZoomLevel == g_ZoomLevelReturn, "correctly passes along zoom level as returned from getZoomForExtent()");
1213 function test_allOverlays(t) {
1217 var map = new OpenLayers.Map({
1218 div: "map", allOverlays: true
1221 var a = new OpenLayers.Layer.Vector("a", {visibility: true});
1223 var b = new OpenLayers.Layer.Image(
1225 "http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif",
1226 new OpenLayers.Bounds(-180, -88.759, 180, 88.759),
1227 new OpenLayers.Size(580, 288)
1230 var c = new OpenLayers.Layer.WMS(
1232 "http://labs.metacarta.com/wms/vmap0",
1236 var d = new OpenLayers.Layer.Vector("d");
1238 map.addLayers([a, b, c, d]);
1241 a.moveTo = function() {
1243 OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);
1246 map.zoomToMaxExtent();
1247 t.eq(moveCount, 1, "map.moveTo moves the base layer only once");
1248 t.eq(map.getCenter().toString(), "lon=0,lat=0", "a map with all overlays can have a center");
1250 a.setVisibility(false);
1252 a.events.on({"moveend": function() { moveend++; }});
1253 map.zoomToMaxExtent();
1254 t.eq(moveCount, 1, "map.moveTo does not move the base layer if it is invisible");
1255 t.eq(moveend, 0, "map.moveTo does not trigger \"moveend\" in the layer if the layer is invisible");
1256 a.setVisibility(true);
1259 t.eq(map.baseLayer.name, "a", "base layer set to first layer added");
1263 t.eq(map.baseLayer.name, "b", "if base layer is removed, lowest layer becomes base");
1267 t.eq(map.baseLayer.name, "b", "adding a new layer doesn't change base layer");
1269 map.setLayerIndex(c, 1);
1271 t.eq(map.baseLayer.name, "b", "changing layer order above base doesn't mess with base");
1273 map.setLayerIndex(d, 0);
1275 t.eq(map.baseLayer.name, "d", "changing layer order to 0 sets base layer");
1277 map.raiseLayer(d, 1);
1279 t.eq(map.baseLayer.name, "b", "raising the base layer sets a new base layer");
1281 map.raiseLayer(d, -1);
1283 t.eq(map.baseLayer.name, "d", "lowering a layer to lowest index sets as base");
1285 // all this switching of base layer didn't muck with layer visibility
1286 t.eq(a.visibility, true, "a is visible");
1287 t.eq(b.visibility, true, "b is visible");
1288 t.eq(c.visibility, true, "c is visible");
1289 t.eq(d.visibility, true, "d is visible");
1291 // test that map can have an invisible base layer
1292 b.setVisibility(false);
1293 map.setLayerIndex(b, 0);
1294 t.eq(b.visibility, false, "changing layer order doesn't change visibility");
1304 <div id="map" style="width: 600px; height: 300px;"/>