diff options
author | Chris Schlaeger <chris@linux.com> | 2014-08-12 21:56:44 +0200 |
---|---|---|
committer | Chris Schlaeger <chris@linux.com> | 2014-08-12 21:56:44 +0200 |
commit | ea346a785dc1b3f7c156f6fc33da634e1f1a627b (patch) | |
tree | af67530553d20b6e82ad60fd79593e9c4abf5565 /misc/openlayers/tests/Layer | |
parent | 59741cd535c47f25971bf8c32b25da25ceadc6d5 (diff) | |
download | postrunner-ea346a785dc1b3f7c156f6fc33da634e1f1a627b.zip |
Adding jquery, flot and openlayers to be included with the GEM.v0.0.4
Diffstat (limited to 'misc/openlayers/tests/Layer')
36 files changed, 10457 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Layer/ArcGIS93Rest.html b/misc/openlayers/tests/Layer/ArcGIS93Rest.html new file mode 100644 index 0000000..ddca6ac --- /dev/null +++ b/misc/openlayers/tests/Layer/ArcGIS93Rest.html @@ -0,0 +1,324 @@ +<html> +<head> + <script type="text/javascript">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script> + <script type="text/javascript">window.alert = oldAlert;</script> +<script src="../OLLoader.js"></script> + <script type="text/javascript"> + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var layer; + + var name = 'Test Layer'; + var url = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/export"; + var params = {layers: "show:0,2"}; + + function test_Layer_AGS93_constructor (t) { + var params = {layers: "show:0,2"}; + t.plan( 14 ); + + var trans_format = "png"; + if (OpenLayers.Util.alphaHack()) { trans_format = "gif"; } + + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + t.ok( layer instanceof OpenLayers.Layer.ArcGIS93Rest, "new OpenLayers.Layer.ArcGIS93Rest returns object" ); + t.eq( layer.url, url, "layer.url is correct (HTTPRequest inited)" ); + t.eq( layer.params.LAYERS, "show:0,2", "params passed in correctly uppercased" ); + + t.eq( layer.params.FORMAT, "png", "default params correclty uppercased and copied"); + + t.eq(layer.isBaseLayer, true, "no transparency setting, wms is baselayer"); + + params.format = 'jpg'; + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + t.eq( layer.params.FORMAT, "jpg", "default params correclty uppercased and overridden"); + + params.TRANSPARENT = "true"; + var layer2 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + t.eq(layer2.isBaseLayer, false, "transparency == 'true', wms is not baselayer"); + + params.TRANSPARENT = "TRUE"; + var layer3 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + t.eq(layer3.isBaseLayer, false, "transparency == 'TRUE', wms is not baselayer"); + t.eq(layer3.params.FORMAT, trans_format, "transparent = TRUE causes non-image/jpeg format"); + + params.TRANSPARENT = "TRuE"; + var layer4 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + t.eq(layer4.isBaseLayer, false, "transparency == 'TRuE', wms is not baselayer"); + t.eq(layer4.params.FORMAT, trans_format, "transparent = TRuE causes non-image/jpeg format"); + + params.TRANSPARENT = true; + var layer5 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + t.eq(layer5.isBaseLayer, false, "transparency == true, wms is not baselayer"); + t.eq(layer5.params.FORMAT, trans_format, "transparent = true causes non-image/jpeg format"); + + params.TRANSPARENT = false; + var layer6 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + t.eq(layer6.isBaseLayer, true, "transparency == false, wms is baselayer"); + } + + function test_Layer_AGS93_addtile (t) { + var params = {layers: "show:0,2"}; + t.plan( 6 ); + + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + var map = new OpenLayers.Map('map', {tileManager: null}); + map.addLayer(layer); + var pixel = new OpenLayers.Pixel(5,6); + var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel); + tile.draw(); + + var img = tile.imgDiv; + var tParams = OpenLayers.Util.extend({}, + OpenLayers.Util.upperCaseObject(params)); + tParams = OpenLayers.Util.extend(tParams, { + FORMAT: "png", BBOX: "1,2,3,4", SIZE: "256,256", F: "image", BBOXSR: "4326", IMAGESR: "4326" + }); + t.eq( tile.url, + url + "?" + OpenLayers.Util.getParameterString(tParams), + "image src is created correctly via addtile" ); + t.eq( tile.getTile().style.top, "6px", "image top is set correctly via addtile" ); + t.eq( tile.getTile().style.left, "5px", "image top is set correctly via addtile" ); + + var firstChild = layer.div.firstChild; + t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" ); + t.ok( firstChild == img, "div first child is correct image object" ); + t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." ); + map.destroy(); + } + + function test_Layer_AGS93_inittiles (t) { + var params = {layers: "show:0,2"}; + t.plan( 2 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params, {buffer: 2}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),5); + t.eq( layer.grid.length, 8, "Grid rows is correct." ); + t.eq( layer.grid[0].length, 7, "Grid cols is correct." ); + map.destroy(); + } + + + function test_Layer_AGS93_clone (t) { + var params = {layers: "show:0,2"}; + t.plan(4); + + var options = {tileSize: new OpenLayers.Size(500,50)}; + var map = new OpenLayers.Map('map', options); + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + map.addLayer(layer); + + layer.grid = [ [6, 7], + [8, 9]]; + + var clone = layer.clone(); + + t.ok( clone.grid != layer.grid, "clone does not copy grid"); + + t.ok( clone.tileSize.equals(layer.tileSize), "tileSize correctly cloned"); + + layer.tileSize.w += 40; + + t.eq( clone.tileSize.w, 500, "changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference"); + + t.eq( clone.alpha, layer.alpha, "alpha copied correctly"); + + layer.grid = null; + map.destroy(); + } + + function test_Layer_AGS93_isBaseLayer(t) { + var params = {layers: "show:0,2"}; + t.plan(3); + + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + t.ok( layer.isBaseLayer, "baselayer is true by default"); + + var newParams = OpenLayers.Util.extend({}, params); + newParams.transparent = "true"; + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, newParams); + t.ok( !layer.isBaseLayer, "baselayer is false when transparent is set to true"); + + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params, {isBaseLayer: false}); + t.ok( !layer.isBaseLayer, "baselayer is false when option is set to false" ); + } + + function test_Layer_AGS93_mergeNewParams (t) { + var params = {layers: "show:0,2"}; + t.plan( 4 ); + + var map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + + var newParams = { layers: 'sooper', + chickpeas: 'png'}; + + map.addLayer(layer); + map.zoomToMaxExtent(); + + layer.redraw = function() { + t.ok(true, "layer is redrawn after new params merged"); + } + + layer.mergeNewParams(newParams); + + t.eq( layer.params.LAYERS, "sooper", "mergeNewParams() overwrites well"); + t.eq( layer.params.CHICKPEAS, "png", "mergeNewParams() adds well"); + + newParams.CHICKPEAS = 151; + + t.eq( layer.params.CHICKPEAS, "png", "mergeNewParams() makes clean copy of hashtable"); + map.destroy(); + } + + function test_Layer_AGS93_getFullRequestString (t) { + var params = {layers: "show:0,2"}; + t.plan( 1 ); + var map = new OpenLayers.Map('map'); + map.projection = "xx"; + tParams = { layers: 'show:0,2', + format: 'png'}; + var tLayer = new OpenLayers.Layer.ArcGIS93Rest(name, url, tParams); + map.addLayer(tLayer); + str = tLayer.getFullRequestString(); + var tParams = { + LAYERS: "show:0,2", FORMAT: "png" + }; + t.eq(str, + url + "?" + OpenLayers.Util.getParameterString(tParams), + "getFullRequestString() adds SRS value"); + map.destroy(); + + } + + function test_Layer_AGS93_noGutters (t) { + t.plan(2); + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.ArcGIS93Rest("no gutter layer", url, params, {gutter: 0}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + var tile = layer.grid[0][0]; + var request = layer.getURL(tile.bounds); + var args = OpenLayers.Util.getParameters(request); + t.eq(parseInt(args['SIZE'][0]), + tile.size.w, + "layer without gutter requests images that are as wide as the tile"); + t.eq(parseInt(args['SIZE'][1]), + tile.size.h, + "layer without gutter requests images that are as tall as the tile"); + + layer.destroy(); + map.destroy(); + } + + function test_Layer_AGS93_gutters (t) { + var params = {layers: "show:0,2"}; + t.plan(2); + var gutter = 15; + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.ArcGIS93Rest("gutter layer", url, params, {gutter: gutter}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + var tile = layer.grid[0][0]; + var request = layer.getURL(tile.bounds); + var args = OpenLayers.Util.getParameters(request); + t.eq(parseInt(args['SIZE'][0]), + tile.size.w + (2 * gutter), + "layer with gutter requests images that are wider by twice the gutter"); + t.eq(parseInt(args['SIZE'][1]), + tile.size.h + (2 * gutter), + "layer with gutter requests images that are taller by twice the gutter"); + + layer.destroy(); + map.destroy(); + + } + + function test_Layer_AGS93_destroy (t) { + + t.plan( 1 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0), 5); + + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.destroy(); + + // checks to make sure superclass (grid) destroy() was called + + t.ok( layer.grid == null, "grid set to null"); + } + + function test_Layer_ADG93_Filter(t) { + var params = {layers: "show:0,2"}; + t.plan( 9 ); + + layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params); + var map = new OpenLayers.Map('map', {tileManager: null}); + map.addLayer(layer); + var pixel = new OpenLayers.Pixel(5,6); + var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel); + // Set up basic params. + var tParams = OpenLayers.Util.extend({}, OpenLayers.Util.upperCaseObject(params)); + tParams = OpenLayers.Util.extend(tParams, { + FORMAT: "png", BBOX: "1,2,3,4", SIZE: "256,256", F: "image", BBOXSR: "4326", IMAGESR: "4326" + }); + + // We need to actually set the "correct" url on a dom element, because doing so encodes things not encoded by getParameterString. + var encodingHack = document.createElement("img"); + + tile.draw(); + t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src no filter" ); + + layer.setLayerFilter('1', "MR_TOAD = 'FLYING'"); + tParams["LAYERDEFS"] = "1:MR_TOAD = 'FLYING';"; + tile.draw(); + t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src one filter" ); + + layer.setLayerFilter('1', "MR_TOAD = 'NOT FLYING'"); + tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';"; + tile.draw(); + t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src change one filter" ); + + layer.setLayerFilter('2', "true = false"); + tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';2:true = false;"; + tile.draw(); + t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src two filters" ); + + layer.setLayerFilter('99', "some_col > 5"); + tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';2:true = false;99:some_col > 5;"; + tile.draw(); + t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src three filters" ); + + layer.clearLayerFilter('2'); + tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';99:some_col > 5;"; + tile.draw(); + t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src removed middle filter" ); + + layer.clearLayerFilter('2'); + tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';99:some_col > 5;"; + tile.draw(); + t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src removed missing filter (no change)" ); + + layer.clearLayerFilter(); + delete tParams["LAYERDEFS"]; + tile.draw(); + t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src removed all filters" ); + + layer.clearLayerFilter(); + tile.draw(); + t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src removed all (no) filters" ); + } + + + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/ArcGISCache.html b/misc/openlayers/tests/Layer/ArcGISCache.html new file mode 100644 index 0000000..b5ed5d5 --- /dev/null +++ b/misc/openlayers/tests/Layer/ArcGISCache.html @@ -0,0 +1,256 @@ +<html> +<head> + <script src="../../lib/OpenLayers.js"></script> + <script src="../../lib/OpenLayers/Layer/ArcGISCache.js" type="text/javascript"></script> + <script src="ArcGISCache.json" type="text/javascript"></script> + <script type="text/javascript"> + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var layer; + + var name = 'Test Layer'; + var url = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"; + var options = { }; + + function test_Layer_ARCGISCACHE_constructor (t) { + t.plan( 1 ); + + var layer = new OpenLayers.Layer.ArcGISCache(name, url, options); + t.ok( layer instanceof OpenLayers.Layer.ArcGISCache, "returns OpenLayers.Layer.ArcGISCache object" ); + } + + function test_Layer_ARCGISCACHE_autoConfigure (t) { + t.plan( 5 ); + var layerInfo = capabilitiesObject; + + //initialize the layer using the JSON object from an arcgis server + //SEE: ArcGISCache.json + var layer = new OpenLayers.Layer.ArcGISCache(name, url, { + layerInfo: layerInfo + }); + t.ok( layer instanceof OpenLayers.Layer.ArcGISCache, "returns OpenLayers.Layer.ArcGISCache object" ); + t.ok( layer.projection = 'EPSG:' + layerInfo.spatialReference.wkid, "projection is set correctly"); + t.ok( layer.units = 'm', "map units are set correctly"); + t.ok( layer.resolutions && layer.resolutions.length == 20, "resolutions are initialized from LOD objects properly"); + + if (layerInfo.tileInfo) { + if (layerInfo.tileInfo.width && layerInfo.tileInfo.height) { + var tileSize = new OpenLayers.Size(layerInfo.tileInfo.width, layerInfo.tileInfo.height); + t.ok((layer.tileSize.width == tileSize.width) && (layer.tileSize.height == tileSize.height), "tile size is set properly"); + } + else { + var tileSize = new OpenLayers.Size(layerInfo.tileInfo.cols, layerInfo.tileInfo.rows); + t.ok((layer.tileSize.width == tileSize.width) && (layer.tileSize.height == tileSize.height), "tile size is set properly"); + } + } + } + + /** + * lets make sure we're getting the correct urls back with a basic auto-configure setup + */ + function test_Layer_ARCGISCACHE_autoConfigure_URLS(t) { + var layerInfo = capabilitiesObject; + + //initialize the layer using the JSON object from an arcgis server + //SEE: ArcGISCache.json + var layer = new OpenLayers.Layer.ArcGISCache(name, url, { + layerInfo: layerInfo, + params: {foo: "bar"} + }); + var map = new OpenLayers.Map('map', { + maxExtent: layer.maxExtent, + units: layer.units, + resolutions: layer.resolutions, + numZoomLevels: layer.numZoomLevels, + tileSize: layer.tileSize, + projection: layer.displayProjection, + StartBounds: layer.initialExtent + }); + map.addLayers([layer]); + + //this set represents a few edge cases, and some more specific cases, it is by no means exhaustive, + var urlSets = [ + { + bounds: new OpenLayers.Bounds(-36787612.973083,-22463925.368666, 43362420.398053,17611091.316902), + url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/0/0/0" + }, + { + bounds: new OpenLayers.Bounds(-31793889.951914,4589319.785415, 8281126.733654,24626828.128199), + url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/1/0/0" + }, + { + bounds: new OpenLayers.Bounds(-24639873.181971,12676071.933457, -4602364.839187,22694826.104849), + url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/2/0/0" + }, + { + bounds: new OpenLayers.Bounds(-15521241.455665,11580270.695961, 4516266.887119,21599024.867353), + url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/2/0/1" + }, + { + bounds: new OpenLayers.Bounds(-9265879.5435993,2870892.9335638, -8639707.4078873,3183979.0014198) , + url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/7/54/35" + }, + { + bounds: new OpenLayers.Bounds(-10741909.131798,4684560.1640365, -10585366.09787,4762831.6810005), + url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/9/195/119" + }, + { + bounds: new OpenLayers.Bounds(-13668958.106938,4456961.2611504, -13512415.07301,4535232.7781144), + url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/9/198/82" + } + ]; + + t.plan( urlSets.length ); + for(var i=0;i<urlSets.length;i++) + { + var o = urlSets[i]; + map.zoomToExtent(o.bounds, true); + + var resultUrl = layer.getURL(o.bounds); + t.ok( resultUrl == o.url + "?foo=bar", "correct tile returned for " + o.bounds); + } + } + + /** + * Test the formatting for the 'direct' urls, especially when not auto-configuring the layer + */ + function test_Layer_ARCGISCACHE_direct(t) { + var roadsUrl = 'http://serverx.esri.com/arcgiscache/DG_County_roads_yesA_backgroundDark/Layers/_alllayers'; + var urlSets = [ + { + bounds: new OpenLayers.Bounds(289244.67443386,4317153.7421985, 306178.04163392,4325620.4257985), + url: roadsUrl + "/L00/R0000029e/C0000027f.png" + }, + { + bounds: new OpenLayers.Bounds(308658.51534463,4303230.0164352, 325591.88254469,4311696.7000352), + url: roadsUrl + "/L00/R000002a0/C00000282.png" + }, + { + bounds: new OpenLayers.Bounds(311136.39626998,4318933.8711555, 311678.26402038,4319204.8050307) , + url: roadsUrl + "/L05/R000051e0/C00004e52.png" + } + ]; + t.plan( urlSets.length ); + + + //perform the exact setup from the arcgiscache_direct example + + // First 4 variables extracted from conf.xml file + // Tile layers & map MUST have same projection + var proj='EPSG:26915'; + + // Layer can also accept serverResolutions array + // to deal with situation in which layer resolution array & map resolution + // array are out of sync + var mapResolutions = [33.0729828126323,16.9333672000677,8.46668360003387,4.23334180001693,2.11667090000847,1.05833545000423]; + + // For this example this next line is not really needed, 256x256 is default. + // However, you would need to change this if your layer had different tile sizes + var tileSize = new OpenLayers.Size(256,256); + + // Tile Origin is required unless it is the same as the implicit map origin + // which can be effected by several variables including maxExtent for map or base layer + var agsTileOrigin = new OpenLayers.LonLat(-5120900,9998100); + + // This can really be any valid bounds that the map would reasonably be within + var mapExtent = new OpenLayers.Bounds(289310.8204,4300021.937,314710.8712,4325421.988); + + + var map = new OpenLayers.Map('map', { + maxExtent:mapExtent, + controls: [ + new OpenLayers.Control.Navigation(), + new OpenLayers.Control.LayerSwitcher(), + new OpenLayers.Control.PanZoomBar(), + new OpenLayers.Control.MousePosition()] + }); + + var layer = new OpenLayers.Layer.ArcGISCache('Roads', roadsUrl, { + tileOrigin: agsTileOrigin, + resolutions: mapResolutions, + sphericalMercator: true, + maxExtent: mapExtent, + useArcGISServer: false, + isBaseLayer: true, + projection: proj + }); + + map.addLayers([layer]); + map.zoomToExtent(new OpenLayers.Bounds(-8341644, 4711236, -8339198, 4712459)); + + for(var i=0;i<urlSets.length;i++) + { + var o = urlSets[i]; + map.zoomToExtent(o.bounds, true); + var resultUrl = layer.getURL(o.bounds); + t.ok( resultUrl == o.url, "correct tile returned for " + o.bounds); + } + } + + /** + * Check the utility function for generating tile indexes against a file cache + * This is already tested in BaseTypes test, but these are specific, + * common conversions that this class will rely on, so the tests are retained + */ + function test_Layer_ARCGISCACHE_zeroPad(t) { + t.plan(4); + + var layer = new OpenLayers.Layer.ArcGISCache('test', null, { }); + + //some tile examples + t.ok('00000001' == OpenLayers.Number.zeroPad(1, 8, 16), 'zeroPad should generate tile indexes properly '); + t.ok('00000020' == OpenLayers.Number.zeroPad(32, 8, 16), 'zeroPad should generate tile indexes properly '); + t.ok('00000100' == OpenLayers.Number.zeroPad(256, 8, 16), 'zeroPad should generate tile indexes properly '); + t.ok('00001000' == OpenLayers.Number.zeroPad(4096, 8, 16), 'zeroPad should generate tile indexes properly '); + } + + /** + * Check to ensure our LOD calculation will correctly avoid returning tile indexes less than zero + * (see http://trac.osgeo.org/openlayers/ticket/3169) + */ + function test_Layer_ARCGISCACHE_tileBounds(t) { + t.plan(1); + + var layer = new OpenLayers.Layer.ArcGISCache('test', null, { }); + var res = 264.583862501058; + layer.tileOrigin = new OpenLayers.LonLat(0.0, 650000.0); + layer.tileSize = new OpenLayers.Size(512, 512); + + // pick a point off the left of our tile origin (would be a negative tile index) + var point = new OpenLayers.Geometry.Point(-123308.94829, 393128.85817); + + var tile = layer.getContainingTileCoords(point, res); + t.ok((tile.x >= 0 && tile.y >= 0), 'layer should not generate negative tile ranges for level of detail'); + } + + /* + * Test that messing up the Array.prototype does not mess up the lods of the layer. + * This messes up zooming when resolutions are very small/scales are very large/zoomed way in. + */ + function test_Layer_ARCGISCACHE_lods (t) { + t.plan( 2 ); + var layerInfo = capabilitiesObject; + + lods = layerInfo.tileInfo.lods.length; + + // mess up the Array prototype + Array.prototype.foo = function() { }; + + t.ok( lods == layerInfo.tileInfo.lods.length, 'proper number of "Levels of Detail" before initialization' ); + + // initialize the layer using the JSON object from an arcgis server + // see: ArcGISCache.json + var layer = new OpenLayers.Layer.ArcGISCache(name, url, { + layerInfo: layerInfo + }); + + t.ok( lods == layer.lods.length, 'proper number of "Levels of Detail" after initialization.' ); + // restore the Array prototype + delete Array.prototype.foo; + } + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px;"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/ArcGISCache.json b/misc/openlayers/tests/Layer/ArcGISCache.json new file mode 100644 index 0000000..79dffa8 --- /dev/null +++ b/misc/openlayers/tests/Layer/ArcGISCache.json @@ -0,0 +1,334 @@ +var capabilitiesObject = { + "currentVersion" : 10.01, + "serviceDescription" : "This map is designed to be used as a base map by GIS professionals and as a reference map by anyone. The base map includes administrative boundaries, cities, water features, physiographic features, parks, landmarks, highways, roads, railways, airports, and buildings overlaid on land cover and shaded relief imagery for added context. The map was compiled from a variety of best available sources from several data providers, including the U.S. Geological Survey, Food and Agriculture Organization of the United Nations, National Park Service, Tele Atlas, AND, and ESRI. The base map currently provides coverage for the world down to a scale of ~1:1m and coverage for the continental United States and Hawaii to a scale of ~1:20k. The base map also includes detailed maps for selected cities in the United States including Portland, Oregon and Philadephia, Pennsylvania. The base map was designed and developed by ESRI based on the topographic map templates that are available through the ArcGIS Resource Centers. For more information on this map, visit us \u003ca href=\"http://goto.arcgisonline.com/maps/World_Topo_Map \" target=\"_new\"\u003eonline\u003c/a\u003e.", + "mapName" : "Layers", + "description" : "This map is designed to be used as a base map by GIS professionals and as a reference map by anyone. The base map includes administrative boundaries, cities, water features, physiographic features, parks, landmarks, highways, roads, railways, airports, and buildings overlaid on land cover and shaded relief imagery for added context. The map was compiled from a variety of best available sources from several data providers, including the U.S. Geological Survey, Food and Agriculture Organization of the United Nations, National Park Service, Tele Atlas, AND, and ESRI. The base map currently provides coverage for the world down to a scale of ~1:1m and coverage for the continental United States and Hawaii to a scale of ~1:20k. The base map also includes detailed maps for selected cities in the United States including Portland, Oregon and Philadephia, Pennsylvania. The base map was designed and developed by ESRI based on the topographic map templates that are available through the ArcGIS Resource Centers. For more information on this map, visit us online at http://goto.arcgisonline.com/maps/World_Topo_Map", + "copyrightText" : "Sources: USGS, FAO, NPS, EPA, ESRI, DeLorme, TANA, other suppliers", + "layers" : [ + { + "id" : 0, + "name" : "Topographic Info", + "parentLayerId" : -1, + "defaultVisibility" : true, + "subLayerIds" : [1, 2, 3, 4], + "minScale" : 0, + "maxScale" : 0 + }, + { + "id" : 1, + "name" : "Elevation (m)", + "parentLayerId" : 0, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 0, + "maxScale" : 0 + }, + { + "id" : 2, + "name" : "Elevation (ft)", + "parentLayerId" : 0, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 0, + "maxScale" : 0 + }, + { + "id" : 3, + "name" : "Slope", + "parentLayerId" : 0, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 0, + "maxScale" : 0 + }, + { + "id" : 4, + "name" : "Aspect", + "parentLayerId" : 0, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 0, + "maxScale" : 0 + }, + { + "id" : 5, + "name" : "Places Info", + "parentLayerId" : -1, + "defaultVisibility" : true, + "subLayerIds" : [6, 7, 8, 9], + "minScale" : 0, + "maxScale" : 0 + }, + { + "id" : 6, + "name" : "Place Names (Country Level)", + "parentLayerId" : 5, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 0, + "maxScale" : 80000000 + }, + { + "id" : 7, + "name" : "Place Names (State Level)", + "parentLayerId" : 5, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 80000001, + "maxScale" : 1500000 + }, + { + "id" : 8, + "name" : "Place Names (County Level)", + "parentLayerId" : 5, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 1500001, + "maxScale" : 400000 + }, + { + "id" : 9, + "name" : "Place Names (City Level)", + "parentLayerId" : 5, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 399999, + "maxScale" : 0 + }, + { + "id" : 10, + "name" : "Scale Descriptions", + "parentLayerId" : -1, + "defaultVisibility" : true, + "subLayerIds" : [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26], + "minScale" : 0, + "maxScale" : 0 + }, + { + "id" : 11, + "name" : "Level 15 ~1:18K", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 25000, + "maxScale" : 15001 + }, + { + "id" : 12, + "name" : "Level 14 ~1:36K", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 50000, + "maxScale" : 25001 + }, + { + "id" : 13, + "name" : "Level 13 ~1:72K", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 100000, + "maxScale" : 50001 + }, + { + "id" : 14, + "name" : "Level 12 ~1:144K", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 288000, + "maxScale" : 100000 + }, + { + "id" : 15, + "name" : "Level 11 ~1:288K", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 575000, + "maxScale" : 288000 + }, + { + "id" : 16, + "name" : "Level 10 ~1:577K", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 1150000, + "maxScale" : 575000 + }, + { + "id" : 17, + "name" : "Level 9 ~1:1.15M", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 2200000, + "maxScale" : 1150000 + }, + { + "id" : 18, + "name" : "Level 8 ~1:2.3M", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 4500000, + "maxScale" : 2200000 + }, + { + "id" : 19, + "name" : "Level 7 ~1:4.5M", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 9000000, + "maxScale" : 4500000 + }, + { + "id" : 20, + "name" : "Level 6 ~1:9.2M", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 18000000, + "maxScale" : 9000000 + }, + { + "id" : 21, + "name" : "Level 5 ~1:18M ", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 36000000, + "maxScale" : 18000000 + }, + { + "id" : 22, + "name" : "Level 4 ~1:36M", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 72000000, + "maxScale" : 36000000 + }, + { + "id" : 23, + "name" : "Level 3 ~1:72M", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 75500000, + "maxScale" : 70000000 + }, + { + "id" : 24, + "name" : "Level 2 ~1:147M", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 290000000, + "maxScale" : 147000000 + }, + { + "id" : 25, + "name" : "Level 1 ~1:292M", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 295000000, + "maxScale" : 150000000 + }, + { + "id" : 26, + "name" : "Level 0 ~1:584M", + "parentLayerId" : 10, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 0, + "maxScale" : 295000000 + }, + { + "id" : 27, + "name" : "Citations", + "parentLayerId" : -1, + "defaultVisibility" : true, + "subLayerIds" : null, + "minScale" : 0, + "maxScale" : 0 + } + ], + "tables" : [ + + ], + "spatialReference" : { + "wkid" : 102100 + }, + "singleFusedMapCache" : true, + "tileInfo" : { + "rows" : 256, + "cols" : 256, + "dpi" : 96, + "format" : "JPEG", + "compressionQuality" : 90, + "origin" : { + "x" : -20037508.342787, + "y" : 20037508.342787 + }, + "spatialReference" : { + "wkid" : 102100 + }, + "lods" : [ + {"level" : 0, "resolution" : 156543.033928, "scale" : 591657527.591555}, + {"level" : 1, "resolution" : 78271.5169639999, "scale" : 295828763.795777}, + {"level" : 2, "resolution" : 39135.7584820001, "scale" : 147914381.897889}, + {"level" : 3, "resolution" : 19567.8792409999, "scale" : 73957190.948944}, + {"level" : 4, "resolution" : 9783.93962049996, "scale" : 36978595.474472}, + {"level" : 5, "resolution" : 4891.96981024998, "scale" : 18489297.737236}, + {"level" : 6, "resolution" : 2445.98490512499, "scale" : 9244648.868618}, + {"level" : 7, "resolution" : 1222.99245256249, "scale" : 4622324.434309}, + {"level" : 8, "resolution" : 611.49622628138, "scale" : 2311162.217155}, + {"level" : 9, "resolution" : 305.748113140558, "scale" : 1155581.108577}, + {"level" : 10, "resolution" : 152.874056570411, "scale" : 577790.554289}, + {"level" : 11, "resolution" : 76.4370282850732, "scale" : 288895.277144}, + {"level" : 12, "resolution" : 38.2185141425366, "scale" : 144447.638572}, + {"level" : 13, "resolution" : 19.1092570712683, "scale" : 72223.819286}, + {"level" : 14, "resolution" : 9.55462853563415, "scale" : 36111.909643}, + {"level" : 15, "resolution" : 4.77731426794937, "scale" : 18055.954822}, + {"level" : 16, "resolution" : 2.38865713397468, "scale" : 9027.977411}, + {"level" : 17, "resolution" : 1.19432856685505, "scale" : 4513.988705}, + {"level" : 18, "resolution" : 0.597164283559817, "scale" : 2256.994353}, + {"level" : 19, "resolution" : 0.298582141647617, "scale" : 1128.497176} + ] + }, + "initialExtent" : { + "xmin" : -45223792.233066, + "ymin" : -22882589.2065154, + "xmax" : 45223792.233066, + "ymax" : 22882589.2065155, + "spatialReference" : { + "wkid" : 102100 + } + }, + "fullExtent" : { + "xmin" : -20037507.0671618, + "ymin" : -19971868.8804086, + "xmax" : 20037507.0671618, + "ymax" : 19971868.8804086, + "spatialReference" : { + "wkid" : 102100 + } + }, + "units" : "esriMeters", + "supportedImageFormatTypes" : "PNG24,PNG,JPG,DIB,TIFF,EMF,PS,PDF,GIF,SVG,SVGZ,AI,BMP", + "documentInfo" : { + "Title" : "World Topo Map", + "Author" : "ESRI", + "Comments" : "", + "Subject" : "", + "Category" : "", + "Keywords" : "", + "Credits" : "" + }, + "capabilities" : "Map,Query,Data" +};
\ No newline at end of file diff --git a/misc/openlayers/tests/Layer/ArcIMS.html b/misc/openlayers/tests/Layer/ArcIMS.html new file mode 100644 index 0000000..4f86227 --- /dev/null +++ b/misc/openlayers/tests/Layer/ArcIMS.html @@ -0,0 +1,123 @@ +<html> + <head> + <script type="text/javascript" src="../OLLoader.js"></script> + <script type="text/javascript"> + + // use an arcims map service against Avencia Inc.'s global sample map services + var serviceName = "OpenLayers_Sample"; + var layerName = "Global Sample Map"; + var imsUrl = "http://sample.avencia.com/servlet/com.esri.esrimap.Esrimap"; + + // + // create an arcims layer + // + function test_Layer_ArcIMS_constructor( t ) { + t.plan(11); + + var options = { + serviceName: serviceName, + async: false, + displayOutsideMaxExtent: true + }; + + var layer = new OpenLayers.Layer.ArcIMS( layerName, imsUrl, options ); + + // check layer & properties + t.ok( layer instanceof OpenLayers.Layer.ArcIMS, "new OpenLayers.Layer.ArcIMS returns object" ); + t.eq( layer.url, imsUrl, "layer.url is correct (HTTPRequest inited)" ); + t.eq( layer.name, layerName, "layer.name is correct" ); + t.eq( layer.displayOutsideMaxExtent, options.displayOutsideMaxExtent, + "displayOutsideMaxExtent property set correctly from options" ); + + // check request parameters + t.eq( layer.params.ServiceName, serviceName, "ServiceName set properly" ); + t.eq( layer.params.ClientVersion, "9.2", "ClientVersion set properly" ); + + // check request options + t.eq( layer.options.async, options.async, "async property set correctly from options" ); + t.eq( layer.options.serviceName, serviceName, "serviceName property set correctly from options" ); + t.eq( layer.options.layers.length, 0, "layers option is the correct length" ); + t.eq( layer.options.tileSize.w, 512, "default tile width set correctly" ); + t.eq( layer.options.tileSize.h, 512, "default tile height set correctly" ); + } + + + + /* + * how to test getURL, getURLasync, and getFeatureInfo without a proxy? + * + */ + + + // + // Create an arcims layer, and verify that the query changes properly + // + function test_Layer_ArcIMS_setLayerQuery(t) { + t.plan(9); + + var options = { serviceName: serviceName }; + var layer = new OpenLayers.Layer.ArcIMS( layerName, imsUrl, options ); + var querydef = { + where: "FIPS_CNTRY = 'US'" + }; + + t.eq( layer.options.layers.length, 0, "layer definitions are empty" ); + + layer.setLayerQuery( "layerID", querydef ); + + t.eq( layer.options.layers.length, 1, "layers definitions contain one layerdef" ); + t.ok( layer.options.layers[0].query !== null, "layer query exists" ); + t.eq( typeof layer.options.layers[0].query.where, "string", "where query is a string" ); + t.eq( layer.options.layers[0].query.where, querydef.where, "where query matches" ); + + // change the definition + querydef = { + where: "FIPS_CNTRY = 'UV'", + spatialfilter:true + } + + layer.setLayerQuery( "layerID", querydef ); + + t.eq( layer.options.layers.length, 1, "layers definitions contain one layerdef" ); + t.ok( layer.options.layers[0].query !== null, "layer query exists" ); + t.eq( typeof layer.options.layers[0].query.where, "string", "where query is a string" ); + t.eq( layer.options.layers[0].query.where, querydef.where, "where query matches" ); + } + function test_Layer_ArcIMS_clone (t) { + t.plan(5); + + var url = imsUrl; + var options = { + serviceName: serviceName, + async: false, + displayOutsideMaxExtent: true + }; + var map = new OpenLayers.Map('map', {controls: []}); + var layer = new OpenLayers.Layer.ArcIMS(name, url, options); + map.addLayer(layer); + + layer.grid = [ [6, 7], + [8, 9]]; + + var clone = layer.clone(); + + t.ok( clone.grid != layer.grid, "clone does not copy grid"); + + t.ok( clone.tileSize.equals(layer.tileSize), "tileSize correctly cloned"); + + t.eq( clone.params.serviceName, layer.params.serviceName, "serviceName copied correctly"); + + t.eq( clone.async, layer.async, "async copied correctly"); + + t.eq( clone.url, layer.url, "url copied correctly"); + + layer.grid = null; + map.destroy(); + } + + </script> + </head> + <body> + <div id="map" style="width:500px;height:550px"></div> + </body> +</html> diff --git a/misc/openlayers/tests/Layer/Bing.html b/misc/openlayers/tests/Layer/Bing.html new file mode 100644 index 0000000..89bbba7 --- /dev/null +++ b/misc/openlayers/tests/Layer/Bing.html @@ -0,0 +1,200 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var map, layer; + + var layerType = 'Aerial'; + var key = "AqTGBsziZHIJYYxgivLBf0hVdrAk9mWO5cQcb8Yux8sW5M8c8opEC2lZqKR1ZZXf"; + + var options = { + type: layerType, + key: key + }; + + function test_constructor(t) { + t.plan(3); + + var origProcessMetadata = OpenLayers.Layer.Bing.processMetadata; + var log = []; + OpenLayers.Layer.Bing.processMetadata = function(metadata) { + var script = document.getElementById(this._callbackId); + log.push(script.src); + origProcessMetadata.apply(this, arguments); + }; + layer = new OpenLayers.Layer.Bing(OpenLayers.Util.extend({ + metadataParams: {foo: "bar"} + }, options)); + t.ok(layer instanceof OpenLayers.Layer.Bing, "returns OpenLayers.Layer.Bing object" ); + t.delay_call(5, function() { + t.eq(log.length, 1, "processMetadata called"); + t.eq(OpenLayers.Util.getParameters(log[0]).foo, "bar", "metadataParams passed to url correctly."); + OpenLayers.Layer.Bing.processMetadata = origProcessMetadata; + layer.destroy(); + }); + } + + function test_initLayer(t) { + t.plan(2); + + var meta = []; + var origProcessMetadata = OpenLayers.Layer.Bing.processMetadata; + OpenLayers.Layer.Bing.processMetadata = function(metadata) { + meta.push(metadata); + }; + map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.Bing(options); + var extent; + map.addLayers([layer, new OpenLayers.Layer(null, { + moveTo: function(bounds, changed) { + extent = bounds; + } + })]); + map.zoomToMaxExtent(); + + var map2 = new OpenLayers.Map("map"); + var layer2 = new OpenLayers.Layer.Bing(OpenLayers.Util.extend({ + initLayer: function() { + // pretend we have a zoomMin of 2 + this.metadata.resourceSets[0].resources[0].zoomMin = 2; + OpenLayers.Layer.Bing.prototype.initLayer.apply(this, arguments); + } + }, options)); + var extent2; + map2.addLayers([layer2, new OpenLayers.Layer(null, { + moveTo: function(bounds, changed) { + extent2 = bounds; + } + })]); + map2.zoomToMaxExtent(); + + t.delay_call(5, function() { + origProcessMetadata.call(layer, meta[0]); + t.eq(extent.toBBOX(), map.getExtent().toBBOX(), "layer extent correct for base layer with zoomMin == 1."); + map.destroy(); + }); + + t.delay_call(6, function() { + origProcessMetadata.call(layer2, meta[1]); + t.eq(extent2.toBBOX(), map2.getExtent().toBBOX(), "layer extent correct for base layer with zoomMin == 2."); + map2.destroy(); + OpenLayers.Layer.Bing.processMetadata = origProcessMetadata; + }); + } + + function test_initLayer_notempty(t) { + t.plan(1); + + map = new OpenLayers.Map("map", { + projection: "EPSG:3857", + layers: [new OpenLayers.Layer("dummy", {isBaseLayer: true})] + }); + map.zoomToExtent([-14768652, 4492113, -12263964, 5744457]); + var layer = new OpenLayers.Layer.Bing(OpenLayers.Util.extend({ + isBaseLayer: false + }, options)); + map.addLayer(layer); + + t.delay_call(5, function() { + t.ok(layer.grid[0][0].url, "Tile not empty"); + map.destroy(); + }); + } + + function test_attribution(t) { + t.plan(3); + + var log = []; + var map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.Bing(options); + map.addLayer(layer); + map.zoomToMaxExtent(); + + t.delay_call(2, function() { + t.ok(OpenLayers.Util.indexOf(layer.attribution, 'olBingAttribution aerial') !== -1, "Attribution has the correct css class"); + t.ok(OpenLayers.Util.indexOf(layer.attribution, '<img src="">') == -1, "Attribution contains a logo"); + t.ok(OpenLayers.Util.indexOf(layer.attribution, '</img></div></a><a style=') == -1 , "Attribution contains a copyright"); + map.destroy(); + }); + } + + function test_attribution_notempty(t) { + t.plan(1); + + var log = []; + var map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.Bing(OpenLayers.Util.applyDefaults({type: 'Road'}, options)); + map.addLayer(layer); + var format = OpenLayers.String.format; + OpenLayers.String.format = function(tpl, options) { + log.push(options.copyrights); + } + map.zoomToExtent(new OpenLayers.Bounds(-14768652, 4492113, -12263964, 5744457)); + t.delay_call(2, function() { + t.ok(log.join("") !== "", "Copyright not empty"); + OpenLayers.String.format = format; + map.destroy(); + }); + } + + function test_getXYZ(t) { + t.plan(1); + + var map = new OpenLayers.Map("map", {allOverlays: true}); + var osm = new OpenLayers.Layer.OSM(); + map.addLayer(osm); + map.zoomToExtent(new OpenLayers.Bounds(11373579,-2445208,13628777,680760)); + layer = new OpenLayers.Layer.Bing(options); + map.addLayer(layer); + + t.delay_call(2, function() { + var xyz = layer.getXYZ(layer.getTileBounds(new OpenLayers.Pixel(1,1))); + t.eq(xyz.z, OpenLayers.Util.indexOf(layer.serverResolutions, map.getResolution()), "zoom level correct"); + }); + } + + function test_clone(t) { + t.plan(1); + + var clone; + + layer = new OpenLayers.Layer.Bing(options); + clone = layer.clone(); + t.ok(clone instanceof OpenLayers.Layer.Bing, "clone is a Layer.Bing instance"); + } + + function test_protocol(t) + { + t.plan(5); + + var map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.Bing(options); + map.addLayer(layer); + map.zoomToMaxExtent(); + + t.delay_call(5, function() { + t.ok(OpenLayers.Util.indexOf(layer.attribution, '<img src="//') != -1, "Attribution contains a logo with protocol //"); + t.ok(OpenLayers.Util.indexOf(layer.attribution, '<img src="http://') == -1, "Attribution logo does not have http:// protocol"); + t.ok(layer.grid[1][1].url.indexOf('http:') == -1, "Tile url does not contain http:"); + + map.destroy(); + }); + + var map2 = new OpenLayers.Map("map"); + layer_https = new OpenLayers.Layer.Bing(OpenLayers.Util.applyDefaults({protocol: 'https:'}, options)); + map2.addLayer(layer_https); + map2.zoomToMaxExtent(); + + t.delay_call(5, function() { + t.ok(OpenLayers.Util.indexOf(layer_https.attribution, '<img src="https://') != -1, "Attribution logo has https:// protocol"); + t.ok(layer_https.grid[1][1].url.indexOf('https:') == 0, "Tile url contains https:"); + map2.destroy(); + }); + } + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/EventPane.html b/misc/openlayers/tests/Layer/EventPane.html new file mode 100644 index 0000000..8d8e180 --- /dev/null +++ b/misc/openlayers/tests/Layer/EventPane.html @@ -0,0 +1,172 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var isOpera = (navigator.userAgent.indexOf("Opera") != -1); + var layer; + + function test_Layer_EventPane_constructor (t) { + t.plan( 5 ); + + var layer = new OpenLayers.Layer.EventPane('Test Layer'); + + t.ok( layer instanceof OpenLayers.Layer.EventPane, "new OpenLayers.Layer.EventPane returns object" ); + t.eq( layer.CLASS_NAME, "OpenLayers.Layer.EventPane", "CLASS_NAME variable set correctly"); + t.eq( layer.name, "Test Layer", "layer.name is correct" ); + t.eq( layer.isBaseLayer, true, "EventPane layer is always base layer" ); + if (!isMozilla) { + t.ok( true, "skipping element test outside of Mozilla"); + } else { + t.ok( layer.pane instanceof HTMLDivElement, "layer.pane is an HTMLDivElement" ); + } + } + + function test_Layer_EventPane_clone (t) { + t.plan( 1 ); + t.ok( true, "need to actually write some tests here" ); + return; + + /// FIX ME FIX ME: fix this later + + var map = new OpenLayers.Map('map'); + var options = { chicken: 151, foo: "bar" }; + var layer = new OpenLayers.Layer('Test Layer', options); + map.addLayer(layer); + + // randomly assigned property + layer.chocolate = 5; + + var clone = layer.clone(); + + t.ok( clone instanceof OpenLayers.Layer, "new OpenLayers.Layer returns object" ); + t.eq( clone.name, "Test Layer", "default clone.name is correct" ); + t.ok( ((clone.options["chicken"] == 151) && (clone.options["foo"] == "bar")), "clone.options correctly set" ); + t.eq(clone.chocolate, 5, "correctly copied randomly assigned property"); + + layer.addOptions({chicken:152}); + t.eq(clone.options["chicken"], 151, "made a clean copy of options"); + + + t.ok( clone.map == null, "cloned layer has map property set to null") + + } + + function test_Layer_EventPane_setMap (t) { + +// MOUSEMOVE test does not seem to work... +// t.plan( 2 ); + + if (OpenLayers.BROWSER_NAME != "firefox" && OpenLayers.BROWSER_NAME != "mozilla") { + t.plan(4); + } else { + t.plan(0); + t.debug_print("Firefox gives different results for different browsers on setMap on EventPane, so just don't run it for now.") + return; + } + var map = new OpenLayers.Map('map'); + + layer = new OpenLayers.Layer.EventPane('Test Layer'); + + //give dummy function so test wont bomb on layer.setMap() + layer.loadMapObject = function() { }; + layer.getWarningHTML = function() { this.warning = true; return ""; }; + map.addLayer(layer); + t.eq( parseInt(layer.pane.style.zIndex) - parseInt(layer.div.style.zIndex), + 1, "layer pane is 1 z-level above its div" ); + + t.ok( layer.warning, "warning correctly registered on no mapObject load" ); + + layer2 = new OpenLayers.Layer.EventPane('Test Layer'); + + //give dummy function so test wont bomb on layer.setMap() + layer2.loadMapObject = function() { this.mapObject = {}; }; + layer2.getWarningHTML = function() { this.warning = true; return ""; } + + map.addLayer(layer2); + t.ok(!layer2.warning, "warning not registered on mapObject load"); + + var log = []; + map.events.register("mousemove", map, function(event) { + log.push(event); + }); + + if (document.createEvent) { // Mozilla + var evObj = document.createEvent('MouseEvents'); + evObj.initEvent('mousemove', true, false); + map.viewPortDiv.dispatchEvent(evObj); + } else if(document.createEventObject) { // IE + map.viewPortDiv.fireEvent('onmousemove'); + } + + t.eq(log.length, 1, "got one event"); + + } + + function test_Layer_EventPane_setVisibility (t) { + t.plan( 2 ); + layer = new OpenLayers.Layer.EventPane('Test Layer'); + layer.setVisibility(false); + t.eq(layer.visibility, false, "layer pane is now invisible"); + layer.setVisibility(true); + t.eq(layer.visibility, true, "layer pane is now visible"); + } + + + function test_Layer_EventPane_removeLayer(t) { + t.plan(1); + var map = new OpenLayers.Map('map'); + + layer = new OpenLayers.Layer.EventPane('Test Layer'); + layer.loadMapObject = function() { }; + layer.getWarningHTML = function() { this.warning = true; return ""; }; + map.addLayer(layer); + map.removeLayer(layer); + var parent = layer.pane.parentNode; + // IE creates a DOCUMENT_FRAGMENT_NODE for the parent + t.ok(!parent || parent.nodeType == 11, "Layer.pane removed from dom."); + } + + function test_repeat_add(t) { + + t.plan(1); + var map = new OpenLayers.Map("map"); + + layer = new OpenLayers.Layer.EventPane(); + layer.loadMapObject = function() {}; + layer.getWarningHTML = function() {this.warning = true; return "";}; + + map.addLayer(layer); + map.removeLayer(layer); + + // try adding the layer a second time + var msg = "layer successfully added after being removed"; + var pass = true; + try { + map.addLayer(layer); + } catch (err) { + msg = "couldn't add layer after removing: " + err; + pass = false; + } + t.ok(pass, msg); + + } + + function test_destroy(t) { + + t.plan(2); + layer = new OpenLayers.Layer.EventPane(); + t.ok(layer.pane, "pane created on initialize"); + + layer.destroy(); + t.ok(!layer.pane, "pane deleted on destroy"); + + } + + + </script> +</head> +<body> + <div id="map" style="height:500px;width:500px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/FixedZoomLevels.html b/misc/openlayers/tests/Layer/FixedZoomLevels.html new file mode 100644 index 0000000..133571b --- /dev/null +++ b/misc/openlayers/tests/Layer/FixedZoomLevels.html @@ -0,0 +1,137 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var layer; + + function test_Layer_FixedZoomLevels (t) { + t.plan( 39 ); + + var layer = { 'MIN_ZOOM_LEVEL': 5, + 'MAX_ZOOM_LEVEL': 10 }; + + + //defaults + + layer = p_createLayer(layer); + p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, "nothing specified"); + + + //layer.options + + // min,num + layer = p_createLayer(layer, {}, { minZoomLevel: 3, numZoomLevels: 12}); + p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, "min too low num too high(layer.options)"); + + layer = p_createLayer(layer, {}, { minZoomLevel: 6, numZoomLevels: 3 }); + p_minMaxNum(t, layer, 6, 8, "valid min,num(layer.options)"); + + + // max + layer = p_createLayer(layer, {}, { maxZoomLevel: 9 }); + p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, 9, "valid max(layer.options)"); + + layer = p_createLayer(layer, {}, { maxZoomLevel: 12 }); + p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, "invalid max(layer.options)"); + + + + //map + + // min,num + layer = p_createLayer(layer, { minZoomLevel: 3, numZoomLevels: 12}); + p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, "min too low num too high(map)"); + + layer = p_createLayer(layer, { minZoomLevel: 6, numZoomLevels: 3 }); + p_minMaxNum(t, layer, 6, 8, "valid min,num(map)"); + + + // max + layer = p_createLayer(layer, { maxZoomLevel: 9 }); + p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, 9, "valid max(map)"); + + layer = p_createLayer(layer, { maxZoomLevel: 12 }); + p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, "invalid max(map)"); + + //map vs. options + + layer = p_createLayer(layer, {minZoomLevel: 6, numZoomLevels: 2}, { minZoomLevel: 7, numZoomLevels: 3}); + p_minMaxNum(t, layer, 7, 9, "min,num(layer.options) wins over (map)"); + + layer = p_createLayer(layer, {minZoomLevel: 6, maxZoomLevel: 8}, { minZoomLevel: 7, maxZoomLevel: 9}); + p_minMaxNum(t, layer, 7, 9, "min,max(layer.options) wins over (map)"); + + + // numZoomLevels vs. maxZoomLevel + + layer = p_createLayer(layer, {maxZoomLevel: 8, numZoomLevels: 6}); + p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, 10, "min,max(layer.options) wins over (map)"); + + // resolutions array + + var resolutions = Array(20); + for (var i = 0; i < 20; i++) { + resolutions[i] = Math.random(); + } + OpenLayers.Util.extend(layer, {RESOLUTIONS:resolutions}); + var minZoomLevel = 6; + var numZoomLevels = 2; + layer = p_createLayer(layer, {}, {minZoomLevel: minZoomLevel, numZoomLevels: numZoomLevels}); + t.eq( layer.resolutions.length, numZoomLevels, "length of resolutions array ok"); + for (var i = 0; i < numZoomLevels; i++) { + t.eq( layer.resolutions[i], resolutions[i + minZoomLevel], "resolutions array at index " + i + " ok"); + } + } + + function test_getMapObjectZoomFromOLZoom(t) { + t.plan(4); + + var map = new OpenLayers.Map("map", {allOverlays: true}); + var xyz = new OpenLayers.Layer.XYZ("xyz", "${x}${y}${z}", { + sphericalMercator: true, + resolutions: [39135.7584765625, 19567.87923828125, 9783.939619140625] + }); + var fixed = new (OpenLayers.Class(OpenLayers.Layer, OpenLayers.Layer.FixedZoomLevels, { + initialize: function() { + OpenLayers.Layer.prototype.initialize.apply(this, arguments); + } + }))("fixed", { + resolutions: [156543.03390625, 78271.516953125, 39135.7584765625, 19567.87923828125, 9783.939619140625], + minZoomLevel: 1 + }); + map.addLayers([xyz, fixed]); + map.setCenter(new OpenLayers.LonLat(0, 0), 2); + // map.getZoom() returns 2 + t.eq(fixed.getMapObjectZoomFromOLZoom(map.getZoom()), 4, "correct return value from getMapObjectZoomFromOLZoom"); + t.eq(fixed.getOLZoomFromMapObjectZoom(4), map.getZoom() - fixed.minZoomLevel, "correct return value from getOLZoomFromMapObjectZoom"); + + map.setBaseLayer(fixed); + // map.getZoom() returns 4 now + t.eq(fixed.getMapObjectZoomFromOLZoom(map.getZoom()), 5, "correct return value from getMapObjectZoomFromOLZoom"); + t.eq(fixed.getOLZoomFromMapObjectZoom(5), map.getZoom(), "correct return value from getOLZoomFromMapObjectZoom"); + } + + function p_createLayer(layer, mapOptions, layerOptions) { + + layer.map = mapOptions || {}; + layer.options = layerOptions || {}; + OpenLayers.Layer.FixedZoomLevels.prototype.initResolutions.apply(layer); + + return layer; + } + + function p_minMaxNum(t, layer, min, max, msg) { + + t.eq( layer.minZoomLevel, min, "min zoom level inherited from layer constant: " + msg); + t.eq( layer.maxZoomLevel, max, "max zoom level inherited from layer constant: " + msg); + t.eq( layer.numZoomLevels, max - min + 1, "num zoom levels correctly calcuated: " + msg); + + } + + + </script> +</head> +<body> + <div id="map" style="width:256px;height:256px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/GeoRSS.html b/misc/openlayers/tests/Layer/GeoRSS.html new file mode 100644 index 0000000..a942e83 --- /dev/null +++ b/misc/openlayers/tests/Layer/GeoRSS.html @@ -0,0 +1,210 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var isMSIE = (navigator.userAgent.indexOf("MSIE") > -1); + var layer; + + var georss_txt = "./georss.txt"; + var atom_xml = "./atom-1.0.xml"; + + // if this test is running online, different rules apply + if (isMSIE) { + georss_txt = "." + georss_txt; + atom_xml = "." + atom_xml; + } + + function test_Layer_GeoRSS_constructor (t) { + t.plan( 7 ); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt ); + t.ok( layer instanceof OpenLayers.Layer.GeoRSS, "new OpenLayers.Layer.GeoRSS returns object" ); + t.eq( layer.location, georss_txt, "layer.location is correct" ); + var markers; + layer.loadRSS(); + t.delay_call( 1, function() { + t.eq( layer.markers.length, 40, "marker length is correct" ); + var ll = new OpenLayers.LonLat(-71.142197, 42.405696); + var theTitle = "Knitting Room"; + var theDescription = 'This little shop is jammed full. Yarn, yarn everywhere. They make the most of every possible nook and cranny. I like this place also because they have a lot of different kinds of knitting needles in all different sizes. Also, the people who work here are younger and hipper than in the other stores I go to. I reccomend buying supplies here and then knitting your way through a good documentary at the Capitol Theater across the street.<br/>Address: 2 lake St, Arlington, MA <br/>Tags: knitting, yarn, pins and needles, handspun, hand dyed, novelty yarn, fancy, simple, young, hip, friendly, needles, addy, cute hats<br /><br /><a href="http://platial.com/place/90306">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/90306">Grab this on Platial</a> '; + t.ok( layer.markers[0].lonlat.equals(ll), "lonlat on first marker is correct" ); + t.eq( layer.name, "Crschmidt's Places At Platial", "Layer name is correct." ); + t.eq( layer.features[0].data.title, theTitle); + t.eq( layer.features[0].data.description, theDescription); + } ); + } + + function test_Layer_GeoRSS_dontUseFeedTitle (t) { + t.plan( 1 ); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt, {'useFeedTitle': false} ); + t.delay_call( 1, function() { + t.eq( layer.name, "Test Layer", "Layer name is correct when not used from feed." ); + } ); + } + + function test_Layer_GeoRSS_AtomParsing (t) { + t.plan( 6 ); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', atom_xml ); + t.ok( layer instanceof OpenLayers.Layer.GeoRSS, "new OpenLayers.Layer.GeoRSS returns object" ); + t.eq( layer.location, atom_xml, "layer.location is correct" ); + var markers; + layer.loadRSS(); + t.delay_call( 1, function() { + t.eq( layer.markers.length, 2, "marker length is correct" ); + var ll = new OpenLayers.LonLat(29.9805, 36.7702); + t.ok( layer.markers[0].lonlat.equals(ll), "lonlat on first marker is correct" ); + t.like( layer.features[0].data['popupContentHTML'], '<a class="link" href="http://pleiades.stoa.org/places/638896" target="_blank">Unnamed Tumulus</a>', "Link is correct."); + t.eq( layer.name, "tumulus", "Layer name is correct." ); + } ); + } + + function test_Layer_GeoRSS_draw (t) { +// t.plan(5); + t.plan( 2 ); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt); + t.ok( layer instanceof OpenLayers.Layer.GeoRSS, "new OpenLayers.Layer.GeoRSS returns object" ); + var 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.addLayer(layer); + t.delay_call( 1, function() { + map.setCenter(new OpenLayers.LonLat(0,0),0); + t.eq( map.layers[1].name, layer.name, "Layer name is correct" ); + + });; + } + function test_Layer_GeoRSS_load_events (t) { + t.plan( 1 ); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt); + var 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.addLayer(layer); + layer.events.register("loadstart", t, function() { this.ok(true, "loadstart event triggered once (#1580)") }); + map.setCenter(new OpenLayers.LonLat(0,0),0); + } + function test_Layer_GeoRSS_events (t) { + t.plan( 4 ); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt); + var 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.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),0); + var event = {}; + t.delay_call( 2, function() { + t.ok(layer.markers[0].events, "First marker has an events object"); + t.eq(layer.markers[0].events.listeners['click'].length, 1, "Marker events has one object"); + layer.markers[0].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "Popup opened correctly"); + layer.markers[1].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "1st popup gone, 2nd Popup opened correctly"); + }); + } + function test_Layer_GeoRSS_popups (t) { + t.plan( 4 ); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt); + var 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.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),0); + var event = {}; + t.delay_call( 1, function() { + t.ok(layer.markers[0].events, "First marker has an events object"); + t.eq(layer.markers[0].events.listeners['click'].length, 1, "Marker events has one object"); + layer.markers[0].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "Popup opened correctly"); + layer.markers[1].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "1st popup gone, 2nd Popup opened correctly"); + }); + + } + function test_Layer_GeoRSS_resizedPopups(t) { + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt, {'popupSize': new OpenLayers.Size(200,100)}); + t.plan( 4 ); + var 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.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),0); + var event = {}; + t.delay_call( 1, function() { + t.ok(layer.markers[0].events, "First marker has an events object"); + t.eq(layer.markers[0].events.listeners['click'].length, 1, "Marker events has one object"); + layer.markers[0].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "Popup opened correctly"); + map.popups[0].size.w=300; + layer.markers[1].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "1st popup gone, 2nd Popup opened correctly"); + }); + } + + function test_Layer_GeoRSS_icon(t) { + t.plan( 3 ); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt); + var the_icon = new OpenLayers.Icon('http://boston.openguides.org/markers/AQUA.png'); + var otherLayer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt,{icon:the_icon}); + var 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.addLayers([layer,otherLayer]); + map.setCenter(new OpenLayers.LonLat(0,0),0); + var defaultIcon = OpenLayers.Marker.defaultIcon(); + layer.loadRSS(); + otherLayer.loadRSS(); + t.delay_call( 2, function() { + t.ok(layer.markers[0].icon, "The layer has a icon"); + t.eq(layer.markers[0].icon.url, defaultIcon.url, "The layer without icon has the default icon."); + t.eq(otherLayer.markers[0].icon.url, the_icon.url,"The layer with an icon has that icon."); + }); + } + function test_Layer_GeoRSS_loadend_Event(t) { + var browserCode = OpenLayers.BROWSER_NAME; + if (browserCode == "msie") { + t.plan(1); + t.ok(true, "IE fails the GeoRSS test. This could probably be fixed by someone with enough energy to fix it."); + } else { + t.plan(2); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt); + t.delay_call(2, function() { + layer.events.register('loadend', layer, function() { + t.ok(true, "Loadend event fired"); + }); + layer.parseData({ + 'responseText': '<xml xmlns="http://example.com"><title> </title></xml>' + }); + t.ok(true, "Parsing data didn't fail"); + }); + } + } + + function test_Layer_GeoRSS_destroy (t) { + t.plan( 1 ); + layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + t.delay_call( 1, function() { + layer.destroy(); + t.eq( layer.map, null, "layer.map is null after destroy" ); + }); + } + + </script> +</head> +<body> + <div id="map" style="width:500px; height:500px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/Google.html b/misc/openlayers/tests/Layer/Google.html new file mode 100644 index 0000000..84f17c9 --- /dev/null +++ b/misc/openlayers/tests/Layer/Google.html @@ -0,0 +1,369 @@ +<html> +<head> + <script type="text/javascript">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script> + <!-- this gmaps key generated for http://openlayers.org/dev/ --> + <script src='http://maps.google.com/maps?file=api&v=2&key=ABQIAAAA9XNhd8q0UdwNC7YSO4YZghSPUCi5aRYVveCcVYxzezM4iaj_gxQ9t-UajFL70jfcpquH5l1IJ-Zyyw'></script> + <script type="text/javascript">window.alert = oldAlert;</script> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var layer; + var validkey = (window.location.protocol == "file:") || + (window.location.host == "localhost") || + (window.location.host == "openlayers.org"); + + function test_Layer_Google_message(t) { + t.plan(0); + if(gMess) { + t.debug_print(gMess); + } + } + + function test_Layer_Google_constructor (t) { + if(validkey) { + t.plan( 4 ); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.Google('Goog Layer'); + map.addLayer(layer); + + + t.ok( layer instanceof OpenLayers.Layer.Google, "new OpenLayers.Layer.Google returns object" ); + t.eq( layer.CLASS_NAME, "OpenLayers.Layer.Google", "CLASS_NAME variable set correctly"); + + t.eq( layer.name, "Goog Layer", "layer.name is correct" ); + + t.ok ( layer.mapObject != null, "GMap2 Object correctly loaded"); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_clone(t) { + if (validkey) { + t.plan(2); + var layer, clone; + + // test default layer + layer = new OpenLayers.Layer.Google(); + clone = layer.clone(); + t.ok(clone instanceof OpenLayers.Layer.Google, "[default] good instance"); + + layer.destroy(); + clone.destroy(); + + // test with alt type + layer = new OpenLayers.Layer.Google(null, {type: G_SATELLITE_MAP}); + clone = layer.clone(); + t.ok(clone.type === G_SATELLITE_MAP, "[sat] correct type"); + + layer.destroy(); + clone.destroy(); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_Layer_Google_isBaseLayer (t) { + if(validkey) { + t.plan(1); + + var layer = new OpenLayers.Layer.Google('Goog Layer'); + + t.ok(layer.isBaseLayer, "a default load of google layer responds as a base layer"); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_Layer_Google_Translation_lonlat (t) { + + if(validkey) { + t.plan( 4 ); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.Google('Goog Layer'); + map.addLayer(layer); + + // these two lines specify an appropriate translation. + // the code afterwards works by itself to test that translation + // works correctly both ways. + var gLatLng = new GLatLng(50,100); + var correspondingOLLonLat = new OpenLayers.LonLat(100,50); + + + olLonLat = layer.getOLLonLatFromMapObjectLonLat(gLatLng); + t.ok(olLonLat.equals(correspondingOLLonLat), "Translation from GLatLng to OpenLayers.LonLat works"); + + var transGLatLng = layer.getMapObjectLonLatFromOLLonLat(olLonLat); + t.ok( transGLatLng.equals(gLatLng), "Translation from OpenLayers.LonLat to GLatLng works"); + + t.ok( layer.getMapObjectLonLatFromOLLonLat(null) == null, "getGLatLngFromOLLonLat(null) returns null"); + t.ok( layer.getOLLonLatFromMapObjectLonLat(null) == null, "getOLLonLatFromGLatLng(null) returns null"); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_Layer_Google_Translation_pixel (t) { + if(validkey) { + t.plan( 4 ); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.Google('Goog Layer'); + map.addLayer(layer); + + // these two lines specify an appropriate translation. + // the code afterwards works by itself to test that translation + // works correctly both ways. + var gPoint = new GPoint(50,100); + var correspondingOLPixel = new OpenLayers.Pixel(50, 100); + + + olPixel = layer.getOLPixelFromMapObjectPixel(gPoint); + t.ok( olPixel.equals(correspondingOLPixel), "Translation from GPoint to OpenLayers.Pixel works"); + + var transGPoint = layer.getMapObjectPixelFromOLPixel(olPixel); + t.ok( transGPoint.equals(gPoint), "Translation from OpenLayers.Pixel to GPoint works"); + + t.ok( layer.getMapObjectPixelFromOLPixel(null) == null, "getGPointFromOLPixel(null) returns null"); + t.ok( layer.getOLPixelFromMapObjectPixel(null) == null, "getOLPixelFromGPoint(null) returns null"); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_Layer_destroy (t) { + if(validkey) { + t.plan( 5 ); + + var map = new OpenLayers.Map('map'); + + layer = new OpenLayers.Layer.Google('Test Layer'); + map.addLayer(layer); + + layer.destroy(); + + t.eq( layer.name, null, "layer.name is null after destroy" ); + t.eq( layer.div, null, "layer.div is null after destroy" ); + t.eq( layer.map, null, "layer.map is null after destroy" ); + t.eq( layer.options, null, "layer.options is null after destroy" ); + t.eq( layer.gmap, null, "layer.gmap is null after destroy" ); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_Layer_Goole_forwardMercator(t){ + if(validkey) { + t.plan(2); + //Just test that the fowardMercator function still exists. + var layer = new OpenLayers.Layer.Google('Test Layer', {'sphericalMercator': true}); + layer.forwardMercator = function(evt) { + t.ok(true, + "GoogleMercator.forwardMercator was called and executed." ); + return; + } + layer.forwardMercator(); + //Now test the fowardMercator returns the expected LonLat object + var layer = new OpenLayers.Layer.Google('Test Layer', {'sphericalMercator': true}); + var lonlat2 = new OpenLayers.LonLat(Math.random(),Math.random()); + var result = layer.forwardMercator(lonlat2.lon, lonlat2.lat); + t.ok(result instanceof OpenLayers.LonLat, "OpenLayers.Google.fowardMercator returns LonLat object" ); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_Layer_Google_overlay(t) { + // Test for #849. + if(validkey) { + t.plan(1); + var map = new OpenLayers.Map( 'map' , + { controls: [] , 'numZoomLevels':20}); + + var satellite = new OpenLayers.Layer.Google( "Google Satellite" , {type: G_SATELLITE_MAP, 'maxZoomLevel':18} ); + var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", {layers: 'basic', 'transparent':true}, + {isBaseLayer: false, singleTile: true} ); + + map.addLayers([satellite, layer]); + map.setCenter(new OpenLayers.LonLat(10.205188,48.857593), 5); + map.zoomIn(); + var size = map.getSize(); + var px = new OpenLayers.Pixel(size.w, size.h); + var br = map.getLonLatFromPixel(px); + t.ok(layer.grid[0][0].bounds.containsLonLat(br), "Bottom right pixel is covered by untiled WMS layer"); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + function test_Layer_Google_isBaseLayer (t) { + if(validkey) { + t.plan(3); + var map = new OpenLayers.Map( 'map' , + { controls: [] , 'numZoomLevels':20}); + + var satellite = new OpenLayers.Layer.Google( "Google Satellite" , {type: G_SATELLITE_MAP, 'maxZoomLevel':18} ); + map.addLayers([satellite]); + map.zoomToMaxExtent(); + + t.eq(satellite.div.style.display, "", "Satellite layer is visible."); + satellite.setVisibility(false); + t.eq(satellite.div.style.display, "none", "Satellite layer is not visible."); + satellite.setVisibility(true); + t.eq(satellite.div.style.display, "block", "Satellite layer is visible."); + + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_setOpacity(t) { + if(validkey) { + t.plan(6); + + var map = new OpenLayers.Map("map"); + var gmap = new OpenLayers.Layer.Google( + "Google Streets", // the default + {numZoomLevels: 20} + ); + var ghyb = new OpenLayers.Layer.Google( + "Google Hybrid", + {type: G_HYBRID_MAP, numZoomLevels: 20} + ); + var gsat = new OpenLayers.Layer.Google( + "Google Satellite", + {type: G_SATELLITE_MAP, numZoomLevels: 22} + ); + map.addLayers([gmap, ghyb, gsat]); + map.zoomToMaxExtent(); + + var container = map.baseLayer.mapObject.getContainer(); + var opacityCheck = function(opacity) { + var style = container.style; + var current = style.opacity === "" ? 1 : parseFloat(style.opacity); + if (style.filter && !style.opacity) { + current = Number(style.filter.replace(/alpha\(opacity=(.+?)\)/, "$1")); + } + return (current === opacity); + }; + + gmap.setOpacity(0.5); + t.ok(opacityCheck(0.5), "container opacity set for visible layer"); + + ghyb.setOpacity(0.75); + t.ok(opacityCheck(0.5), "container opacity not changed if layer not visible"); + map.setBaseLayer(ghyb); + t.ok(opacityCheck(0.75), "container opacity changed to 0.75 when layer becomes visible"); + + map.setBaseLayer(gsat); + t.ok(opacityCheck(1), "container opacity set to 1 by default"); + gsat.setOpacity(0.25); + t.ok(opacityCheck(0.25), "container opacity changed to 0.25 for visible layer"); + + map.setBaseLayer(gmap); + t.ok(opacityCheck(0.5), "container opacity set to layer opacity"); + + map.destroy(); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_Layer_Google_setGMapVisibility(t) { + if(validkey) { + t.plan(4); + + var map1 = new OpenLayers.Map('map'); + var gmap1 = new OpenLayers.Layer.Google("Google Streets"); + var dummy1 = new OpenLayers.Layer("Dummy", {isBaseLayer: true}); + map1.addLayers([dummy1, gmap1]); + map1.zoomToMaxExtent(); + + t.delay_call(2, function() { + t.ok(gmap1.termsOfUse.style.display == "none" || gmap1.termsOfUse.style.left == "-9999px", "termsOfUse is not visible"); + t.eq(gmap1.poweredBy.style.display, "none", "poweredBy is not visible"); + map1.destroy(); + }); + + var map2 = new OpenLayers.Map('map', {allOverlays: true}); + var gmap2 = new OpenLayers.Layer.Google("Google Streets", {visibility: false}); + var dummy2 = new OpenLayers.Layer("Dummy"); + map2.addLayers([gmap2, dummy2]); + map2.zoomToMaxExtent(); + + t.delay_call(2, function() { + t.ok(gmap2.termsOfUse.style.display == "none" || gmap2.termsOfUse.style.left == "-9999px", "allOverlays:true - termsOfUse is not visible"); + t.eq(gmap2.poweredBy.style.display, "none", "allOverlays:true - poweredBy is not visible"); + map2.destroy(); + }); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + function test_sphericalMercator(t) { + + if (validkey) { + t.plan(4); + var map, layer; + + map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.Google(); + map.addLayer(layer); + t.ok(!layer.sphericalMercator, "sphericalMercator false by default"); + t.eq(map.getProjection(), "EPSG:4326", "4326 by default without sphericalMercator"); + map.destroy(); + + map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.Google(null, { + sphericalMercator: true + }); + map.addLayer(layer); + t.eq(map.getProjection(), "EPSG:900913", "900913 by default with sphericalMercator"); + map.destroy(); + + map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.Google(null, { + sphericalMercator: true, + projection: "EPSG:102113" + }); + map.addLayer(layer); + t.eq(map.getProjection(), "EPSG:102113", "custom code respected with sphericalMercator"); + map.destroy(); + } else { + t.plan(0); + t.debug_print("Google tests can't be run from " + + window.location.host); + } + } + + + </script> +</head> +<body> + <div id="map" style="width:500px; height: 500px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/Google/v3.html b/misc/openlayers/tests/Layer/Google/v3.html new file mode 100644 index 0000000..5f14b48 --- /dev/null +++ b/misc/openlayers/tests/Layer/Google/v3.html @@ -0,0 +1,337 @@ +<html> +<head> + <script src="http://maps.google.com/maps/api/js?sensor=false&v=3.6"></script> + <script src="../../OLLoader.js"></script> + <script type="text/javascript"> + + var layer; + + function test_Layer_Google_constructor (t) { + t.plan( 5 ); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.Google('Goog Layer'); + map.addLayer(layer); + + + t.ok( layer instanceof OpenLayers.Layer.Google, "new OpenLayers.Layer.Google returns object" ); + t.eq( layer.CLASS_NAME, "OpenLayers.Layer.Google", "CLASS_NAME variable set correctly"); + + t.eq( layer.name, "Goog Layer", "layer.name is correct" ); + + t.ok ( layer.mapObject != null, "GMap Object correctly loaded"); + + t.eq(layer.version, "3", "API version 3 detected."); + } + + function test_clone(t) { + t.plan(2); + var layer, clone; + + // test default layer + layer = new OpenLayers.Layer.Google(); + clone = layer.clone(); + t.ok(clone instanceof OpenLayers.Layer.Google, "[default] good instance"); + + layer.destroy(); + clone.destroy(); + + // test with alt type + layer = new OpenLayers.Layer.Google(null, {type: google.maps.MapTypeId.SATELLITE}); + clone = layer.clone(); + t.ok(clone.type === google.maps.MapTypeId.SATELLITE, "[sat] correct type"); + + layer.destroy(); + clone.destroy(); + } + + function test_Layer_Google_isBaseLayer (t) { + t.plan(1); + + var layer = new OpenLayers.Layer.Google('Goog Layer'); + + t.ok(layer.isBaseLayer, "a default load of google layer responds as a base layer"); + } + + function test_Layer_Google_Translation_lonlat (t) { + t.plan( 4 ); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.Google('Goog Layer'); + map.addLayer(layer); + + // these two lines specify an appropriate translation. + // the code afterwards works by itself to test that translation + // works correctly both ways. + var gLatLng = new google.maps.LatLng(50,100); + // v3 uses sphericalMercator by default + var correspondingOLLonLat = layer.forwardMercator(100, 50); + + olLonLat = layer.getOLLonLatFromMapObjectLonLat(gLatLng); + t.ok(olLonLat.equals(correspondingOLLonLat), "Translation from GLatLng to OpenLayers.LonLat works"); + + var transGLatLng = layer.getMapObjectLonLatFromOLLonLat(olLonLat); + t.ok( transGLatLng.equals(gLatLng), "Translation from OpenLayers.LonLat to GLatLng works"); + + t.ok( layer.getMapObjectLonLatFromOLLonLat(null) == null, "getGLatLngFromOLLonLat(null) returns null"); + t.ok( layer.getOLLonLatFromMapObjectLonLat(null) == null, "getOLLonLatFromGLatLng(null) returns null"); + } + + function test_Layer_Google_Translation_pixel (t) { + t.plan( 4 ); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.Google('Goog Layer'); + map.addLayer(layer); + + // these two lines specify an appropriate translation. + // the code afterwards works by itself to test that translation + // works correctly both ways. + var gPoint = new google.maps.Point(50,100); + var correspondingOLPixel = new OpenLayers.Pixel(50, 100); + + + olPixel = layer.getOLPixelFromMapObjectPixel(gPoint); + t.ok( olPixel.equals(correspondingOLPixel), "Translation from GPoint to OpenLayers.Pixel works"); + + var transGPoint = layer.getMapObjectPixelFromOLPixel(olPixel); + t.ok( transGPoint.equals(gPoint), "Translation from OpenLayers.Pixel to GPoint works"); + + t.ok( layer.getMapObjectPixelFromOLPixel(null) == null, "getGPointFromOLPixel(null) returns null"); + t.ok( layer.getOLPixelFromMapObjectPixel(null) == null, "getOLPixelFromGPoint(null) returns null"); + } + + function test_Layer_destroy (t) { + t.plan( 5 ); + + var map = new OpenLayers.Map('map'); + + layer = new OpenLayers.Layer.Google('Test Layer'); + map.addLayer(layer); + + layer.destroy(); + + t.eq( layer.name, null, "layer.name is null after destroy" ); + t.eq( layer.div, null, "layer.div is null after destroy" ); + t.eq( layer.map, null, "layer.map is null after destroy" ); + t.eq( layer.options, null, "layer.options is null after destroy" ); + t.eq( layer.gmap, null, "layer.gmap is null after destroy" ); + } + + function test_Layer_Goole_forwardMercator(t){ + t.plan(2); + //Just test that the fowardMercator function still exists. + var layer = new OpenLayers.Layer.Google('Test Layer', {'sphericalMercator': true}); + layer.forwardMercator = function(evt) { + t.ok(true, + "GoogleMercator.forwardMercator was called and executed." ); + return; + } + layer.forwardMercator(); + //Now test the fowardMercator returns the expected LonLat object + var layer = new OpenLayers.Layer.Google('Test Layer', {'sphericalMercator': true}); + var lonlat2 = new OpenLayers.LonLat(Math.random(),Math.random()); + var result = layer.forwardMercator(lonlat2.lon, lonlat2.lat); + t.ok(result instanceof OpenLayers.LonLat, "OpenLayers.Google.fowardMercator returns LonLat object" ); + } + + function test_Layer_Google_overlay(t) { + // Test for #849. + t.plan(1); + var map = new OpenLayers.Map( 'map' , + { controls: [] , 'numZoomLevels':20}); + + var satellite = new OpenLayers.Layer.Google( "Google Satellite" , {type: google.maps.MapTypeId.SATELLITE, 'maxZoomLevel':18} ); + var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", {layers: 'basic', 'transparent':true}, + {isBaseLayer: false, singleTile: true, displayOutsideMaxExtent: true} ); + + map.addLayers([satellite, layer]); + map.setCenter(new OpenLayers.LonLat(10.205188,48.857593), 5); + map.zoomIn(); + var size = map.getSize(); + var px = new OpenLayers.Pixel(size.w, size.h); + var br = map.getLonLatFromPixel(px); + t.ok(layer.grid[0][0].bounds.containsLonLat(br), "Bottom right pixel is covered by untiled WMS layer"); + } + function test_Layer_Google_isBaseLayer (t) { + t.plan(3); + var map = new OpenLayers.Map( 'map' , + { controls: [] , 'numZoomLevels':20}); + + var satellite = new OpenLayers.Layer.Google( "Google Satellite" , {type: google.maps.MapTypeId.SATELLITE, 'maxZoomLevel':18} ); + map.addLayers([satellite]); + map.zoomToMaxExtent(); + + t.eq(satellite.div.style.display, "", "Satellite layer is visible."); + satellite.setVisibility(false); + t.eq(satellite.div.style.display, "none", "Satellite layer is not visible."); + satellite.setVisibility(true); + t.eq(satellite.div.style.display, "block", "Satellite layer is visible."); + } + + function test_allOverlays_invisible(t) { + + t.plan(1); + + var map = new OpenLayers.Map('map', {allOverlays: true}); + + var osm = new OpenLayers.Layer.OSM(); + var gmap = new OpenLayers.Layer.Google("Google Streets", {visibility: false}); + + // keep track of last argument to setGMapVisibility + var visible; + var original = gmap.setGMapVisibility; + gmap.setGMapVisibility = function(vis) { + visible = vis; + original.apply(gmap, arguments); + } + + map.addLayers([osm, gmap]); + map.zoomToMaxExtent(); + + t.ok(visible === false, "setGMapVisibility last called with false"); + + map.destroy(); + + } + + function test_allOverlays_pan(t) { + + t.plan(8); + + var origPrecision = OpenLayers.Util.DEFAULT_PRECISION; + // GMaps v3 seems to use a default precision of 13, which is lower + // than what we use in OpenLayers. + // See http://trac.osgeo.org/openlayers/ticket/3059 + OpenLayers.Util.DEFAULT_PRECISION = 13; + + var map = new OpenLayers.Map('map', {allOverlays: true}); + + var gmap = new OpenLayers.Layer.Google("Google Streets"); + var osm = new OpenLayers.Layer.OSM(); + map.addLayers([gmap, osm]); + + var origin = new OpenLayers.LonLat(1000000, 6000000); + map.setCenter(origin, 4); + var resolution = map.getResolution(); + + var dx, dy, center, expected; + + // confirm that panning works with Google visible + dx = 100, dy = -100; + map.pan(dx, dy, {animate: false}); + center = map.getCenter(); + expected = new OpenLayers.LonLat( + origin.lon + (resolution * dx), + origin.lat - (resolution * dy) + ); + t.eq(center.lon, expected.lon, "x panning with Google visible " + dx + ", " + dy); + t.eq(center.lat, expected.lat, "y panning with Google visible " + dx + ", " + dy); + map.pan(-dx, -dy, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, origin.lon, "x panning with Google visible " + (-dx) + ", " + (-dy)); + t.eq(center.lat, origin.lat, "y panning with Google visible " + (-dx) + ", " + (-dy)); + + // confirm that panning works with Google invisible + gmap.setVisibility(false); + dx = 100, dy = -100; + map.pan(dx, dy, {animate: false}); + center = map.getCenter(); + expected = new OpenLayers.LonLat( + origin.lon + (resolution * dx), + origin.lat - (resolution * dy) + ); + t.eq(center.lon, expected.lon, "x panning with Google invisible " + dx + ", " + dy); + t.eq(center.lat, expected.lat, "y panning with Google invisible " + dx + ", " + dy); + map.pan(-dx, -dy, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, origin.lon, "x panning with Google invisible " + (-dx) + ", " + (-dy)); + t.eq(center.lat, origin.lat, "y panning with Google invisible " + (-dx) + ", " + (-dy)); + + map.destroy(); + OpenLayers.Util.DEFAULT_PRECISION = origPrecision; + } + + function test_wrapDateLine(t) { + t.plan(2); + + var origPrecision = OpenLayers.Util.DEFAULT_PRECISION; + // Our default precision is very high - millimeters should be enough. + // See http://trac.osgeo.org/openlayers/ticket/3059 + OpenLayers.Util.DEFAULT_PRECISION = 12; + + var map = new OpenLayers.Map("map"); + + var gmap = new OpenLayers.Layer.Google("Google Streets"); + map.addLayer(gmap); + map.setCenter(new OpenLayers.LonLat(0, 0), 1); + + var center; + + // pan to the edge of the world + map.pan(256, 0, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, 20037508.34, "edge of the world"); + // pan off the edge of the world + map.pan(100, 0, {animate: false}); + center = map.getCenter(); + var expect = OpenLayers.Util.toFloat(100 * map.getResolution() - 20037508.34); + t.eq(center.lon, expect, "magically back in the western hemisphere"); + + map.destroy(); + OpenLayers.Util.DEFAULT_PRECISION = origPrecision; + } + + function test_respectDateLine(t) { + t.plan(2); + + var map = new OpenLayers.Map("map"); + + var gmap = new OpenLayers.Layer.Google("Google Streets", {wrapDateLine: false}); + map.addLayer(gmap); + map.setCenter(new OpenLayers.LonLat(0, 0), 1); + + var center; + + // pan to the edge of the world + map.pan(256, 0, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, 20037508.34, "edge of the world"); + // pan off the edge of the world + map.pan(100, 0, {animate: false}); + center = map.getCenter(); + t.eq(center.lon, 20037508.34, "whew, still on the edge"); + + map.destroy(); + + } + + function test_moveViewportDiv(t) { + t.plan(2); + + var map = new OpenLayers.Map('map', { + projection: 'EPSG:3857', + center: [0, 0], + zoom: 1 + }); + var gmap = new OpenLayers.Layer.Google(); + map.addLayer(gmap); + + t.delay_call(4, function() { + t.ok(map.viewPortDiv.parentNode !== map.div, 'viewport moved inside GMaps'); + + var osm = new OpenLayers.Layer.OSM(); + map.addLayer(osm); + map.setBaseLayer(osm); + + t.ok(map.viewPortDiv.parentNode === map.div, 'viewport moved back'); + }); + } + + </script> +</head> +<body> + <div id="map" style="width:500px; height: 500px"></div> +</body> +</html>
\ No newline at end of file diff --git a/misc/openlayers/tests/Layer/Grid.html b/misc/openlayers/tests/Layer/Grid.html new file mode 100644 index 0000000..495a9ab --- /dev/null +++ b/misc/openlayers/tests/Layer/Grid.html @@ -0,0 +1,1593 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var layer; + + var name = 'Test Layer'; + var url = "http://vmap0.tiles.osgeo.org/wms/vmap0"; + var params = {layers: 'basic', format: 'image/png'}; + + /** + * NOTE TO READER: + * + * Some of the tests on the Grid class actually use the WMS class. + * This is because WMS is a subclass of Grid and it implements the + * core functions which are necessary to test the tile-generation + * mechanism. + * + */ + + + function test_constructor (t) { + t.plan( 7 ); + + layer = new OpenLayers.Layer.Grid(name, url, params, null); + t.ok( layer instanceof OpenLayers.Layer.Grid, "returns OpenLayers.Layer.Grid object" ); + t.eq( layer.buffer, 0, "buffer default is 0"); + t.eq( layer.ratio, 1.5, "ratio default is 1.5"); + t.eq( layer.numLoadingTiles, 0, "numLoadingTiles starts at 0"); + t.ok( layer.tileClass === OpenLayers.Tile.Image, "tileClass default is OpenLayers.Tile.Image"); + t.eq( layer.className, 'olLayerGrid', "className default is olLayerGrid"); + + var obj = {}; + var func = function() {}; + layer.events.register('tileloaded', obj, func); + + t.ok( layer.events.listeners['tileloaded'].length == 1, "one listener for tileloaded after register"); + } + + function test_constructor_singleTile(t) { + t.plan(2); + layer = new OpenLayers.Layer.Grid(name, url, params, {singleTile: true}); + t.eq( layer.className, 'olLayerGridSingleTile', "className default is olLayerGridSingleTile"); + t.eq( layer.removeBackBufferDelay, 0, "removeBackBufferDelay default is 0"); + } + + function test_setMap(t) { + t.plan(1); + var map = new OpenLayers.Map('map', {tileManager: null}); + layer = new OpenLayers.Layer.Grid(name, url, params, null); + map.addLayer(layer); + t.ok(OpenLayers.Element.hasClass(layer.div, "olLayerGrid"), + "olLayerGrid class assigned to layer div"); + map.destroy(); + } + + function test_setMap_singleTile(t) { + t.plan(1); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.Grid(name, url, params, {singleTile: true}); + map.addLayer(layer); + t.ok(OpenLayers.Element.hasClass(layer.div, "olLayerGridSingleTile"), + "olLayerGridSingleTile class assigned to layer div"); + map.destroy(); + } + + function test_Layer_Grid_inittiles (t) { + t.plan( 2 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params, {buffer:2}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),5); + t.eq( layer.grid.length, 8, "Grid rows is correct." ); + t.eq( layer.grid[0].length, 7, "Grid cols is correct." ); + + } + + function test_Layer_Grid_tileClass(t) { + t.plan(2); + + var myTileClass = OpenLayers.Class(OpenLayers.Tile, {}); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params, { + tileClass: myTileClass + }); + map.addLayer(layer); + + t.ok(layer.tileClass === myTileClass, "tileClass is set"); + var instance = layer.addTile(new OpenLayers.Bounds(-10, 10, 50, 100), + new OpenLayers.Pixel(10, 12)); + + t.ok(instance instanceof myTileClass, "addTile returns type is correct"); + + map.destroy(); + } + + function test_Layer_Grid_clearTiles (t) { + t.plan(4); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0)); + + var numTiles = layer.grid.length * layer.grid[0].length; + + //our count of how many times tile.destroy() is called + tilesDeleted = 0; + + //this will get set to false if we try to destroy a tile that has + // not been unhookedv + allTilesUnhooked = true; + + OpenLayers.Tile.Image.prototype._destroy = + OpenLayers.Tile.Image.prototype.destroy; + + OpenLayers.Tile.Image.prototype.destroy = function() { + if (!this.unhooked) { + allTilesUnhooked = false; + } + tilesDeleted++; + } + + layer.removeTileMonitoringHooks = function(tile) { + tile.unhooked = true; + } + + layer.clearGrid(); + + t.ok( layer.grid != null, "layer.grid does not get nullified" ); + t.eq(tilesDeleted, numTiles, "all tiles destroy()ed properly"); + t.ok(allTilesUnhooked, "all tiles unhooked before being destroyed"); + t.eq(layer.gridResolution, null, "gridResolution set to null"); + + OpenLayers.Tile.Image.prototype.destroy = + OpenLayers.Tile.Image.prototype._destroy; + + } + + + function test_Layer_Grid_getTilesBounds(t) { + t.plan(4); + + layer = new OpenLayers.Layer.WMS(name, url, params); + + + //normal grid + var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)}; + var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)}; + layer.grid = [ [6, tr], + [bl, 7]]; + + var bounds = layer.getTilesBounds(); + var testBounds = new OpenLayers.Bounds(1,2,3,4); + + t.ok( bounds.equals(testBounds), "getTilesBounds() returns correct bounds"); + + //no tiles + layer.grid = []; + bounds = layer.getTilesBounds(); + + t.ok(bounds == null, "getTilesBounds() on a tile-less grid returns null"); + + + //singleTile + var singleTile = { bounds: new OpenLayers.Bounds(1,2,3,4)}; + layer.grid = [ [ singleTile ] ]; + bounds = layer.getTilesBounds(); + + t.ok( bounds.equals(testBounds), "getTilesBounds() returns correct bounds"); + + //world wrapped around the dateline + var bl = { bounds: new OpenLayers.Bounds(0,-90,180,90)}; + var tr = { bounds: new OpenLayers.Bounds(-180,-90,0,90)}; + layer.grid = [[bl, tr]]; + + var bounds = layer.getTilesBounds(); + var testBounds = new OpenLayers.Bounds(0,-90,360,90); + + t.ok( bounds.equals(testBounds), "getTilesBounds() returns correct bounds"); + + } + + function test_Layer_Grid_getResolution(t) { + t.plan( 1 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params); + map.addLayer(layer); + + map.zoom = 5; + + t.eq( layer.getResolution(), 0.0439453125, "getResolution() returns correct value"); + } + + function test_Layer_Grid_getZoomForExtent(t) { + t.plan( 2 ); + var bounds, zoom; + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params); + map.addLayer(layer); + + bounds = new OpenLayers.Bounds(10,10,12,12); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 8, "getZoomForExtent() returns correct value"); + + bounds = new OpenLayers.Bounds(10,10,100,100); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 2, "getZoomForExtent() returns correct value"); + } + + function test_moveGriddedTiles(t) { + t.plan(1); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params, {buffer: 2}); + map.addLayer(layer); + map.setCenter([0, 0], 5); + var count = 0; + layer.shiftColumn = function(prepend) { + ++count; + OpenLayers.Layer.WMS.prototype.shiftColumn.apply(this, arguments); + } + map.moveTo([15, 0]); + t.delay_call(.5, function() { + t.eq(count, 1, "column shifted once"); + }); + } + + function test_Layer_Grid_moveTo(t) { + + t.plan(13); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params); + layer.destroy = function() {}; //we're going to do funky things with the grid + layer.applyBackBuffer = function() {}; // backbuffering isn't under test here + map.addLayer(layer); + map.setCenter([-10, 0], 5); + + var log = []; + + //make sure null bounds doesnt cause script error. + // no test necessary, just action + map.getExtent = function() { return null; } + layer.singleTile = false; + layer.moveTo(); //checks to make sure null bounds doesnt break us + + + //observing globals + layer.initSingleTile = function(bounds) { + g_WhichFunc = "InitSingle"; + g_Bounds = bounds; + }; + layer.initGriddedTiles = function(bounds) { + g_WhichFunc = "InitGridded"; + g_Bounds = bounds; + }; + layer.moveGriddedTiles = function() { + g_WhichFunc = "MoveGridded"; + g_Bounds = layer.map.getExtent(); + }; + var clearTestBounds = function() { + g_WhichFunc = null; + g_Bounds = null; + }; + + //default map extent (tested every time below) + b = new OpenLayers.Bounds(0,0,100,100); + map.getExtent = function() { + return b; + }; + var tilesBounds = null; + layer.getTilesBounds = function() { + return tilesBounds; + } + + +//FORCE + + //empty grid + layer.grid = []; + //grid + clearTestBounds(); + layer.singleTile = false; + layer.moveTo() + t.ok(g_Bounds.equals(b), "if grid is empty, initGridded called"); + + //singletile + clearTestBounds(); + layer.singleTile = true; + layer.moveTo() + t.ok(g_Bounds.equals(b), "if grid is empty, initSingleTile called"); + + //zoomChanged + zoomChanged = true; + layer.grid = [ [ {} ] ]; + + //grid + clearTestBounds(); + layer.singleTile = false; + layer.moveTo(null, zoomChanged); + t.ok(g_Bounds.equals(b), "if layer has grid but zoomChanged is called, initGridded called"); + + //singletile + clearTestBounds(); + layer.singleTile = true; + layer.moveTo(null, zoomChanged); + t.ok(g_Bounds.equals(b), "if layer has grid but zoomChanged is called, initSingleTile called"); + + +//NO FORCE + zoomChanged = false; + layer.grid = [ [ {} ] ]; + + //single tile + layer.singleTile = true; + + //DRAGGING + var dragging = true; + + //in bounds + clearTestBounds(); + tilesBounds = new OpenLayers.Bounds(-10,-10,110,110); + layer.moveTo(null, zoomChanged, dragging); + t.ok(g_Bounds == null, "if dragging and tile in bounds, no init()"); + + //out bounds + clearTestBounds(); + tilesBounds = new OpenLayers.Bounds(10,10,120,120); + layer.moveTo(null, zoomChanged, dragging); + t.ok(g_Bounds == null, "if dragging and tile out of bounds, no init()"); + + //NOT DRAGGING + dragging = false; + + //in bounds + clearTestBounds(); + tilesBounds = new OpenLayers.Bounds(-10,-10,110,110); + layer.moveTo(null, zoomChanged, dragging); + t.ok(g_Bounds == null, "if dragging and tile in bounds, no init()"); + + //out bounds + clearTestBounds(); + tilesBounds = new OpenLayers.Bounds(10,10,120,120); + layer.moveTo(null, zoomChanged, dragging); + t.ok(g_WhichFunc == "InitSingle", "if not dragging and tile out of bounds, we call initSingleTile()"); + t.ok(g_Bounds.equals(b), "if not dragging and tile out of bounds, we call initSingleTile() with correct bounds"); + + + //gridded + layer.grid = [ [ {position: new OpenLayers.Pixel(0,0)} ] ]; + layer.singleTile = false; + + //regular move + clearTestBounds(); + tilesBounds = new OpenLayers.Bounds(10,10,120,120); + g_WhichFunc = null; + layer.moveTo(null, zoomChanged); + t.eq(g_WhichFunc, "MoveGridded", "if tiles not drastically out of bounds, we call moveGriddedTile()"); + t.ok(g_Bounds.equals(b), "if tiles not drastically out of bounds, we call moveGriddedTile() with correct bounds"); + + // drastic pan + clearTestBounds(); + tilesBounds = new OpenLayers.Bounds(-150,-150,-120,-120); + layer.moveTo(null, zoomChanged); + t.ok(g_WhichFunc == "InitGridded", "if tiles drastically out of bounds, we call initGriddedTile()"); + t.ok(g_Bounds.equals(b), "if tiles drastically out of bounds, we call initGriddedTile() with correct bounds"); + } + + /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR + * + * -insertColumn + * -insertRow + * + + function 08_Layer_Grid_insertColumn(t) { + } + + function 09_Layer_Grid_insertRow(t) { + } + + * + */ + + function test_Layer_Grid_clone(t) { + t.plan(7); + + var options = {tileSize: new OpenLayers.Size(500,50)}; + var map = new OpenLayers.Map('map', options); + layer = new OpenLayers.Layer.Grid(name, url, params); + map.addLayer(layer); + + layer.grid = [ [6, 7], + [8, 9]]; + + // if we clone when tiles are still loading, this should not influence the clone + layer.numLoadingTiles = 1; + var clone = layer.clone(); + t.eq( clone.numLoadingTiles, 0, "numLoadingTiles should be reset"); + t.ok( clone.grid != layer.grid, "clone does not copy grid"); + t.ok( clone.grid.length == 0, "clone creates a new array instead"); + + t.eq(clone.backBuffer, null, "no backbuffer from original"); + + t.ok( clone.tileSize.equals(layer.tileSize), "tileSize correctly cloned"); + + layer.tileSize.w += 40; + + t.eq( clone.tileSize.w, 500, "changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference"); + + t.eq( clone.alpha, layer.alpha, "alpha copied correctly"); + + layer.grid = null; + } + + function test_Layer_Grid_setTileSize(t) { + t.plan(1); + + OpenLayers.Layer.HTTPRequest.prototype._setTileSize = + OpenLayers.Layer.HTTPRequest.prototype.setTileSize; + + OpenLayers.Layer.HTTPRequest.prototype.setTileSize = function(size) { + g_Size = size; + }; + + + layer = new OpenLayers.Layer.Grid(name, url, params, { + singleTile: true + }); + mapSize = new OpenLayers.Size(100,1000); + layer.map = { + getSize: function() { return mapSize; } + } + + g_Size = null; + layer.setTileSize(); + + var idealSize = new OpenLayers.Size(150,1500); + t.ok( g_Size && g_Size.equals(idealSize), "correctly calculated tile size passed to superclass setTileSize() function"); + + OpenLayers.Layer.HTTPRequest.prototype.setTileSize = + OpenLayers.Layer.HTTPRequest.prototype._setTileSize; + } + + function test_Layer_Grid_initSingleTile(t) { + t.plan( 11 ); + + layer = new OpenLayers.Layer.Grid(name, url, params, { + singleTile: true, + ratio: 2 + }); + + var bounds = new OpenLayers.Bounds(-10,10,50,100); + + var desiredTileBounds = new OpenLayers.Bounds(-40,-35,80,145); + var desiredUL = new OpenLayers.LonLat(-40,145); + + translatedPX = {}; + layer.map = { + getLayerPxFromLonLat: function(ul) { + t.ok(ul.lon === desiredUL.lon && ul.lat === desiredUL.lat, "correct ul passed to translation"); + return translatedPX; + }, + getResolution: function() { + } + } + + var newTile = { + draw: function() { + t.ok(true, "newly created tile has been drawn"); + } + }; + layer.addTile = function(tileBounds, px) { + t.ok(tileBounds.equals(desiredTileBounds), "correct tile bounds passed to addTile to create new tile"); + t.ok(px == translatedPX, "correct tile px passed to addTile to create new tile"); + return newTile; + }; + layer.addTileMonitoringHooks = function(tile) { + t.ok(tile == newTile, "adding monitoring hooks to the newly added tile"); + }; + layer.removeExcessTiles = function(x,y) { + t.ok(x == 1 && y == 1, "removeExcessTiles called") + }; + + + layer.grid = []; + layer.initSingleTile(bounds); + + t.ok(layer.grid[0][0] == newTile, "grid's 0,0 is set to the newly created tile"); + + var tile = { + moveTo: function(tileBounds, px) { + t.ok(tileBounds.equals(desiredTileBounds), "correct tile bounds passed to tile.moveTo()"); + t.ok(px == translatedPX, "correct tile px passed to tile.moveTo()"); + } + }; + layer.grid = [[ tile ]]; + layer.initSingleTile(bounds); + + } + + function test_Layer_Grid_addTileMonitoringHooks(t) { + t.plan(18); + + layer = new OpenLayers.Layer.Grid(); + layer.events = { + 'triggerEvent': function(str, evt) { + g_events.push([str, evt]); + } + } + + var tile = { + events: { + register: function(name, obj, func) { + g_registered[name] = [obj, func]; + }, + on: function(obj) { + for (var o in obj) { + if (obj.hasOwnProperty(o)) { + tile.events.register(o, obj.scope, obj[o]); + } + } + } + }, + imgDiv: {className: ''} + } + + g_registered = {}; + g_events = []; + + layer.addTileMonitoringHooks(tile); + + //loadstart + t.ok(tile.onLoadStart != null, "onLoadStart function created and added to tile"); + entry = g_registered["loadstart"]; + t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadStart, "loadstart correctly registered"); + + layer.numLoadingTiles = 0; + g_events = []; + tile.onLoadStart.apply(layer); + + t.eq(g_events[0][0], "loadstart", "loadstart event triggered when numLoadingTiles is 0"); + t.eq(layer.numLoadingTiles, 1, "numLoadingTiles incremented"); + t.eq(g_events[1][0], "tileloadstart", "tileloadstart event triggered"); + + g_events = []; + tile.onLoadStart.apply(layer); + t.eq(g_events.length, 1, "tileloadstart, but not loadstart triggered when numLoadingTiles is not 0"); + t.eq(layer.numLoadingTiles, 2, "numLoadingTiles incremented"); + + + //loadend + t.ok(tile.onLoadEnd != null, "onLoadEnd function created and added to tile"); + entry = g_registered["loadend"]; + t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadEnd, "loadend correctly registered"); + + g_events = []; + tile.onLoadError.apply(layer); + t.eq(g_events[0][0], "tileerror", "tileerror triggered"); + t.ok(g_events[0][1].tile === tile, "tile passed as tile property to event object"); + + layer.numLoadingTiles = 2; + g_events = []; + tile.onLoadEnd.apply(layer, [{}]); + t.eq(g_events[0][0], "tileloaded", "tileloaded triggered when numLoadingTiles is > 0"); + t.ok(g_events[0][1].tile === tile, "tile passed as tile property to event object"); + t.eq(g_events.length, 1, "loadend event not triggered when numLoadingTiles is > 0"); + t.eq(layer.numLoadingTiles, 1, "numLoadingTiles decremented"); + + + g_events = []; + layer.grid = [[{}]]; // to prevent error in updateBackBuffer + tile.onLoadEnd.apply(layer, [{}]); + t.eq(g_events[0][0], "tileloaded", "tileloaded triggered when numLoadingTiles is 0"); + t.eq(g_events[1][0], "loadend", "loadend event triggered when numLoadingTiles is 0"); + t.eq(layer.numLoadingTiles, 0, "numLoadingTiles decremented"); + } + + function test_Layer_Grid_removeTileMonitoringHooks(t) { + t.plan(2); + + layer = new OpenLayers.Layer.Grid(); + + var tile = { + onLoadStart: {}, + onLoadEnd: {}, + unload: function() {}, + events: { + unregister: function(name, obj, func) { + g_unregistered[name] = [obj, func]; + }, + un: OpenLayers.Events.prototype.un + } + } + + g_unregistered = {}; + + layer.removeTileMonitoringHooks(tile); + + entry = g_unregistered["loadstart"]; + t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadStart, "loadstart correctly unregistered"); + + entry = g_unregistered["loadend"]; + t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadEnd, "loadend correctly unregistered"); + } + + function test_Layer_Grid_tileSizeIsInteger(t) { + t.plan(1); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.Grid(name, url, params, { + singleTile: true, + ratio: 1.5 + }); + map.addLayers([layer]); + + width = layer.tileSize.w; + height = layer.tileSize.h; + t.ok(width == parseInt(width) && height == parseInt(height), "calculated tileSize width/height are integer values"); + } + function test_Layer_Grid_getTileBounds(t) { + t.plan(2); + var map = new OpenLayers.Map("map2", {zoomMethod: null}); + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.WMS(name, url, params); + + var newParams = { layers: 'sooper', + chickpeas: 'image/png'}; + + map.addLayer(layer); + map.zoomToMaxExtent(); + map.zoomIn(); + var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200)); + t.eq(bounds.toBBOX(), "-180,-90,0,90", "get tile bounds returns correct bounds"); + map.pan(200,0, {animate:false}); + var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200)); + t.eq(bounds.toBBOX(), "0,-90,180,90", "get tile bounds returns correct bounds after pan"); + } + + function test_Layer_Grid_moveTo_buffer_calculation (t) { + t.plan(6); + + var map = new OpenLayers.Map( 'map3' ); // odd map size + var layer0 = new OpenLayers.Layer.WMS( "0 buffer: OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", + {layers: 'basic'}, {'buffer':0} ); + map.addLayer(layer0); + + var layer1 = new OpenLayers.Layer.WMS( "1 buffer: OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", + {layers: 'basic'}, {'buffer':1} ); + map.addLayer(layer1); + + var layer2 = new OpenLayers.Layer.WMS( "2 buffer: OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", + {layers: 'basic'}, {'buffer':2} ); + map.addLayer(layer2); + + map.setCenter(new OpenLayers.LonLat(0, 0), 4); + t.eq( layer0.grid.length, 3, "Grid rows with buffer:0" ); + map.setBaseLayer(layer1); + t.eq( layer1.grid.length, 5, "Grid rows with buffer:1" ); + map.setBaseLayer(layer2); + t.eq( layer2.grid.length, 7, "Grid rows with buffer:2" ); + + // zooming in on Greenland exercises the bug from pre-r4313 + map.setCenter(new OpenLayers.LonLat(0, 90), 4); + t.eq( layer0.grid.length, 3, "Grid rows with buffer:0" ); + map.setBaseLayer(layer1); + t.eq( layer1.grid.length, 5, "Grid rows with buffer:1" ); + map.setBaseLayer(layer2); + t.eq( layer2.grid.length, 7, "Grid rows with buffer:2" ); + } + + function test_Layer_Grid_destroy (t) { + + t.plan( 9 ); + + var map = new OpenLayers.Map('map', {tileManager: null}); + layer = new OpenLayers.Layer.Grid(name, url, params); + map.addLayer(layer); + layer.destroy(); + t.eq( layer.grid, null, "layer.grid is null after destroy" ); + t.eq( layer.tileSize, null, "layer.tileSize is null after destroy" ); + + + //test with tile creation + layer = new OpenLayers.Layer.WMS(name, url, params); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0), 10); + map.setCenter(new OpenLayers.LonLat(1,1)); + + //grab a reference to one of the tiles + var tile = layer.grid[1][1]; + t.eq( tile.imgDiv.className, "olTileImage", "Tile has an image" ); + + var removeBackBufferCalled = false; + layer.removeBackBuffer = function() { + removeBackBufferCalled = true; + }; + + layer.destroy(); + t.eq( tile.imgDiv, null, "Tile destroyed" ); + t.eq( layer.timerId, null, "Tile loading timeout cleared"); + t.ok( layer.grid == null, "tiles appropriately destroyed") + t.ok( removeBackBufferCalled, "destroy calls removeBackBuffer"); + + // destroy after remove from map + layer = new OpenLayers.Layer.WMS(name, url, params); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 10); + map.removeLayer(layer); + layer.destroy(); + t.eq( layer.grid, null, "layer.grid is null after destroy" ); + t.eq( layer.tileSize, null, "layer.tileSize is null after destroy" ); + } + + function test_setOpacity(t) { + t.plan(5); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.WMS('', '', {}, { + isBaseLayer: true, + opacity: '0.6' + }); + map.addLayer(layer); + // setCenter adds tiles to the layer's grid + map.setCenter(new OpenLayers.LonLat(0, 0), 5); + + var tile = layer.grid[0][0], tileImg = tile.imgDiv; + + tile.onImageLoad(); // simulate an image load event + t.eq(layer.opacity, '0.6', 'layer opacity value is correct'); + t.eq(parseFloat(tileImg.style.opacity), 0.6, 'tile opacity is correct'); + + layer.setOpacity('0.2'); + t.eq(layer.opacity, '0.2', 'layer opacity value is correct'); + t.eq(parseFloat(tileImg.style.opacity), 0.2, 'tile opacity is correct'); + + tile = layer.addTile(new OpenLayers.Bounds(1, 2, 3, 4), + new OpenLayers.Pixel(5, 6)); + tile.draw(); // add tile to the grid + tile.onImageLoad(); // simulate an image load event + t.eq(parseFloat(tile.imgDiv.style.opacity), 0.2, "tile opacity is correc"); + + map.destroy(); + } + + function test_getServerResolution(t) { + + t.plan(4); + + var layer = new OpenLayers.Layer.Grid('', '', {}, {}); + var res; + + res = layer.getServerResolution(1); + t.eq(res, 1, '[1] getServerResolution return value is correct'); + + layer.serverResolutions = [2, 1]; + res = layer.getServerResolution(1); + t.eq(res, 1, '[2] getServerResolution return value is correct'); + + layer.serverResolutions = [2]; + res = layer.getServerResolution(1); + t.eq(res, 2, '[3] getServerResolution return value is correct'); + + var exc; + layer.serverResolutions = [0.5]; + res = layer.getServerResolution(1); + t.eq(res, 0.5, '[4] getServerResolution return value is correct'); + } + + function test_getServerZoom(t) { + + t.plan(5); + + var resolution, zoom; + var map = new OpenLayers.Map('map', { + resolutions: [8, 4, 2, 1, 0.5], + getResolution: function() { + return resolution; + } + }); + var layer = new OpenLayers.Layer.WMS('', '', {}, {isBaseLayer: true}); + map.addLayer(layer); + + resolution = 8; + zoom = layer.getServerZoom(); + t.eq(zoom, 0, '[1] getServerZoom return value is correct'); + + resolution = 4; + zoom = layer.getServerZoom(); + t.eq(zoom, 1, '[2] getServerZoom return value is correct'); + + layer.serverResolutions = [2, 1]; + resolution = 1; + zoom = layer.getServerZoom(); + t.eq(zoom, 1, '[3] getServerZoom return value is correct'); + + layer.serverResolutions = [2]; + resolution = 0.5; + zoom = layer.getServerZoom(); + t.eq(zoom, 0, '[4] getServerZoom return value is correct'); + + var exc; + layer.serverResolutions = [0.5]; + resolution = 1; + zoom = layer.getServerZoom(); + t.eq(zoom, 0, '[4] getServerZoom return value is correct'); + + map.destroy(); + } + + function test_moveTo_scale(t) { + + t.plan(11); + + var map = new OpenLayers.Map('map', { + resolutions: [32, 16, 8, 4, 2, 1], + zoomMethod: null + }); + var layer = new OpenLayers.Layer.WMS('', '', {}, { + isBaseLayer: true, + serverResolutions: [32, 16, 8] + }); + map.addLayer(layer); + + // initial resolution is 8 + map.setCenter(new OpenLayers.LonLat(0, 0), 2); + + // test initial conditions + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, 'layer div scale is 1'); + + // change from resolution 8 to 4 + map.zoomTo(3); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 2, '[8->4] layer div scale is 2'); + + // change from resolution 8 to 2 + map.zoomTo(2); map.zoomTo(4); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[8->2] layer div scale is 4'); + + // change from resolution 8 to 1 + map.zoomTo(2); map.zoomTo(5); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[8->1] layer div scale is 8'); + + // change from resolution 4 to 2 + map.zoomTo(3); map.zoomTo(4); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[4->2] layer div scale is 4'); + + // change from resolution 4 to 1 + map.zoomTo(3); map.zoomTo(5); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[4->1] layer div scale is 8'); + + // change from resolution 2 to 1 + map.zoomTo(4); map.zoomTo(5); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[2->1] layer div scale is 8'); + + // change from resolution 1 to 2 + map.zoomTo(5); map.zoomTo(4); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[1->2] layer div scale is 4'); + + // change from resolution 1 to 4 + map.zoomTo(5); map.zoomTo(3); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 2, '[1->4] layer div scale is 2'); + + // change from resolution 1 to 8 + map.zoomTo(5); map.zoomTo(2); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, '[1->8] layer div scale is 1'); + + // change from resolution 1 to 16 + map.zoomTo(5); map.zoomTo(1); + t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, '[1->16] layer div scale is 1'); + + map.destroy(); + } + + function test_moveTo_backbuffer_singletile(t) { + t.plan(4); + + var map = new OpenLayers.Map('map', { + resolutions: [1, 0.5, 0.025], + zoomMethod: null + }); + var resolution; + var layer = new OpenLayers.Layer.WMS('', '', {}, { + singleTile: true, + isBaseLayer: true, + transitionEffect: 'resize', + applyBackBuffer: function(res) { + resolution = res; + } + }); + map.addLayer(layer); + + // initial resolution is 0.025 + resolution = undefined; + map.setCenter(new OpenLayers.LonLat(0, 0), 2); + t.eq(resolution, 0.025, + 'applyBackBuffer not called on first moveTo'); + + // move to (-90, 45) + resolution = undefined; + map.setCenter(new OpenLayers.LonLat(-90, 45)); + t.eq(resolution, 0.025, + 'applyBackBuffer called when map is moved'); + + // change to resolution 1 + resolution = undefined; + map.zoomTo(0); + t.eq(resolution, 1, + 'applyBackBuffer called when map is zoomed out'); + + // change to resolution 0.5 + resolution = undefined; + map.zoomTo(1); + t.eq(resolution, 0.5, + 'applyBackBuffer called when map is zoomed out'); + + map.destroy(); + } + + function test_moveTo_backbuffer(t) { + t.plan(4); + + var map = new OpenLayers.Map('map', { + resolutions: [1, 0.5, 0.025], + zoomMethod: null + }); + var resolution; + var layer = new OpenLayers.Layer.WMS('', '', {}, { + isBaseLayer: true, + transitionEffect: 'resize', + applyBackBuffer: function(res) { + resolution = res; + } + }); + map.addLayer(layer); + + // initial resolution is 0.025 + resolution = undefined; + map.setCenter(new OpenLayers.LonLat(0, 0), 2); + t.eq(resolution, 0.025, + 'applyBackBuffer not called on first moveTo'); + + // move to (-90, 45) + resolution = undefined; + map.setCenter(new OpenLayers.LonLat(-90, 45)); + t.eq(resolution, undefined, + 'applyBackBuffer not called when map is moved'); + + // change to resolution 1 + resolution = undefined; + map.zoomTo(0); + t.eq(resolution, 1, + 'applyBackBuffer called when map is zoomed out'); + + // change to resolution 0.5 + map.zoomTo(1); + t.eq(resolution, 0.5, + 'applyBackBuffer called when map is zoomed out'); + + map.destroy(); + } + + function test_applyBackBuffer(t) { + t.plan(12); + + var map = new OpenLayers.Map('map2'); + var layer = new OpenLayers.Layer.WMS('', '', {}, { + isBaseLayer: true + }); + map.addLayer(layer); + map.zoomToMaxExtent(); + + var backBuffer; + + // test #1 + layer.createBackBuffer = function() { + return; + }; + layer.applyBackBuffer(2); + t.eq(layer.backBuffer, undefined, + 'back buffer not created if createBackBuffer returns undefined'); + + // test #2 + layer.createBackBuffer = function() { + backBuffer = document.createElement('div'); + return backBuffer; + }; + layer.gridResolution = 32; + layer.backBufferResolution = 2; + layer.grid[0][0].bounds = new OpenLayers.Bounds(0, 1, 1, 0); + layer.applyBackBuffer(2); + t.ok(layer.backBuffer === backBuffer, + 'back buffer set in layer'); + t.ok(map.layerContainerDiv.firstChild === backBuffer, + 'back buffer inserted as first child'); + t.eq(layer.backBuffer.style.left, '250px', + 'back buffer has correct left'); + t.eq(layer.backBuffer.style.top, '275px', + 'back buffer has correct top'); + + // test #3 + layer.createBackBuffer = function() { + backBuffer = document.createElement('div'); + return backBuffer; + }; + layer.gridResolution = 32; + layer.backBufferResolution = 2; + layer.grid[0][0].bounds = new OpenLayers.Bounds(0, 1, 1, 0); + map.layerContainerOriginPx.x = 20; + map.layerContainerOriginPx.y = -20; + layer.applyBackBuffer(2); + t.ok(layer.backBuffer === backBuffer, + 'back buffer set in layer'); + t.ok(map.layerContainerDiv.firstChild === backBuffer, + 'back buffer inserted as first child'); + t.eq(layer.backBuffer.style.left, '230px', + 'back buffer has correct left'); + t.eq(layer.backBuffer.style.top, '295px', + 'back buffer has correct top'); + + // test #4 + // and a back buffer in the layer and do as if back buffer removal + // has been scheduled, and test that applyBackBuffer removes the + // back buffer and clears the timer + layer.createBackBuffer = function() { + return; + }; + backBuffer = document.createElement('div'); + map.layerContainerDiv.insertBefore(backBuffer, map.baseLayer.div); + layer.backBuffer = backBuffer; + layer.backBufferTimerId = 'fake'; + layer.applyBackBuffer(2); + t.ok(backBuffer !== map.layerContainerDiv.firstChild, + 'back buffer is not first child of layer container div'); + t.eq(layer.backBuffer, null, + 'back buffer not set in layer'); + t.eq(layer.backBufferTimerId, null, + 'back buffer timer cleared'); + map.destroy(); + } + + function test_createBackBuffer(t) { + t.plan(9); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.WMS('', '', {}, { + isBaseLayer: true + }); + map.addLayer(layer); + map.zoomToMaxExtent(); + + var createBackBuffer = OpenLayers.Tile.Image.prototype.createBackBuffer; + + var backBuffer; + + OpenLayers.Tile.Image.prototype.createBackBuffer = function() { + return; + }; + backBuffer = layer.createBackBuffer(); + t.ok(backBuffer != undefined, + 'createBackBuffer returns a back buffer'); + t.eq(backBuffer.childNodes.length, 0, + 'returned back buffer has no child nodes'); + + OpenLayers.Tile.Image.prototype.createBackBuffer = function() { + return document.createElement('div'); + }; + + layer.transitionEffect = 'map-resize'; + backBuffer = layer.createBackBuffer(); + t.ok(backBuffer.style.zIndex == 99, 'z-index of backbuffer correct for "map-resize".'); + layer.removeBackBuffer(); + + layer.transitionEffect = 'resize'; + backBuffer = layer.createBackBuffer(); + t.ok(backBuffer.style.zIndex == layer.getZIndex() - 1, 'z-index of backbuffer correct for "resize",'); + + layer.backBufferResolution = 1; + layer.gridResolution = 1; + layer.backBuffer = backBuffer; + layer.div.appendChild(backBuffer); + layer.backBufferLonLat = {lon: 0, lat: 0}; + layer.applyBackBuffer(1); + t.ok(backBuffer != undefined, + 'createBackBuffer returns a back buffer'); + t.eq(backBuffer.childNodes[0].style.left, '0px', + 'first tile has correct left'); + t.eq(backBuffer.childNodes[0].style.top, '0px', + 'first tile has correct top'); + t.eq(backBuffer.childNodes[1].style.left, '256px', + 'second tile has correct left'); + t.eq(backBuffer.childNodes[1].style.top, '0px', + 'second tile has correct top'); + + map.destroy(); + OpenLayers.Tile.Image.prototype.createBackBuffer = createBackBuffer; + } + + function test_removeBackBuffer(t) { + t.plan(3); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.WMS('', '', {}, {isBaseLayer: true}); + map.addLayer(layer); + + // add a fake back buffer + var backBuffer = document.createElement('div'); + layer.backBuffer = backBuffer; + layer.div.appendChild(backBuffer); + layer.backBufferResolution = 32; + + layer.removeBackBuffer(); + t.eq(layer.backBuffer, null, 'backBuffer set to null in layer'); + t.eq(layer.backBufferResolution, null, + 'backBufferResolution set to null in layer'); + t.ok(backBuffer.parentNode !== layer.div, + 'back buffer removed from layer'); + + map.destroy(); + } + + function test_backbuffer_replace(t) { + t.plan(6); + var map = new OpenLayers.Map('map', {tileManager: null}); + var layer = new OpenLayers.Layer.WMS('', '../../img/blank.gif'); + map.addLayer(layer); + map.zoomToMaxExtent(); + + layer.grid[1][1].onImageLoad(); + layer.mergeNewParams({foo: 'bar'}); + var tile = layer.grid[1][1]; + t.ok(OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile is marked for being replaced'); + t.ok(document.getElementById(tile.id + '_bb'), 'backbuffer created for tile'); + // simulate a css declaration where '.olTileReplacing' sets display + // to none. + tile.imgDiv.style.display = 'none'; + tile.onImageLoad(); + t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile replaced, no longer marked'); + t.ok(!document.getElementById(tile.id + '_bb'), 'backbuffer removed for tile'); + + layer.mergeNewParams({foo: 'baz'}); + tile = layer.grid[1][1]; + // simulate a css declaration where '.olTileReplacing' does not set + // display to none. + tile.imgDiv.style.display = 'block'; + tile.onImageLoad(); + t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile replaced, no longer marked'); + t.ok(document.getElementById(tile.id + '_bb'), 'backbuffer not removed for visible tile'); + } + + function test_backbuffer_replace_singleTile(t) { + t.plan(1); + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.WMS('', '../../img/blank.gif', null, { + singleTile: true, + transitionEffect: 'resize' + }); + map.addLayer(layer); + map.zoomToMaxExtent(); + + t.delay_call(1, function() { + map.zoomIn(); + var tile = layer.grid[0][0]; + t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile is not marked for being replaced for singleTile layers'); + }); + } + + function test_singleTile_move_and_zoom(t) { + + // + // In single tile mode with no transition effect, we insert a non-scaled + // backbuffer when the layer is moved. But if a zoom occurs right after + // a move, i.e. before the new image is received, we need to remove the + // backbuffer, or an ill-positioned image will be visible during the + // zoom transition. + // + + t.plan(4); + + var map = new OpenLayers.Map('map', {zoomMethod: null}); + var layer = new OpenLayers.Layer.WMS('', '', {}, { + isBaseLayer: true, + transitionEffect: null, + singleTile: true, + ratio: 1.1 + }); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), 0); + + // move + map.setCenter(new OpenLayers.LonLat(50, 50)); + t.ok(layer.backBuffer && layer.backBuffer.parentNode === layer.div, + 'backbuffer inserted after map move'); + t.eq(layer.backBuffer.style.left, '-25px'); + t.eq(layer.backBuffer.style.top, '-28px'); + // zoom + map.zoomTo(1); + t.eq(layer.backBuffer, null, + 'back buffer removed when zooming'); + + map.destroy(); + } + + function test_backbuffer_scaled_layer(t) { + t.plan(12); + + // + // set up + // + + var map = new OpenLayers.Map('map', { + resolutions: [32, 16, 8, 4, 2, 1], + zoomMethod: null, + tileManager: null + }); + var layer = new OpenLayers.Layer.WMS( + "WMS", + window.location.href + "#", + null, + {transitionEffect: "resize"} + ); + + layer.serverResolutions = [32, 16, 8]; + + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), 2); + + var origCreateBackBuffer = OpenLayers.Tile.Image.prototype.createBackBuffer; + OpenLayers.Tile.Image.prototype.createBackBuffer = function() { + return document.createElement('div'); + }; + + // we want to control when the back buffer is removed + var removeBackBuffer = OpenLayers.Function.bind( + layer.removeBackBuffer, layer); + layer.removeBackBuffer = function() {}; + + // + // test + // + + // change resolution from 8 to 4 + map.zoomTo(3); + t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1, + '[8->4] back buffer not scaled'); + removeBackBuffer(); + + // change resolution from 8 to 2 + map.zoomTo(2); removeBackBuffer(); map.zoomTo(4); + t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1, + '[8->2] back buffer not scaled'); + removeBackBuffer(); + + // change resolution from 16 to 4 + map.zoomTo(1); removeBackBuffer(); map.zoomTo(3); + t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 2, + '[16->4] back buffer width is as expected'); + t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 2, + '[16->4] back buffer height is as expected'); + removeBackBuffer(); + + // change resolution from 32 to 1 + map.zoomTo(0); removeBackBuffer(); map.zoomTo(5); + t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 4, + '[32->1] back buffer width is as expected'); + t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 4, + '[32->1] back buffer height is as expected'); + removeBackBuffer(); + + // change resolution from 4 to 2 + map.zoomTo(3); removeBackBuffer(); map.zoomTo(4); + t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1, + '[4->2] back buffer not scaled'); + removeBackBuffer(); + + // change resolution from 4 to 1 + map.zoomTo(3); removeBackBuffer(); map.zoomTo(5); + t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1, + '[4->1] back buffer not scaled'); + removeBackBuffer(); + + // change resolution from 1 to 4 + map.zoomTo(5); removeBackBuffer(); map.zoomTo(3); + t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1, + '[1->4] back buffer not scaled'); + removeBackBuffer(); + + // change resolution from 4 to 8 + map.zoomTo(3); removeBackBuffer(); map.zoomTo(2); + t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1, + '[4->8] back buffer not scaled'); + removeBackBuffer(); + + // change resolution from 4 to 16 + map.zoomTo(3); removeBackBuffer(); map.zoomTo(1); + t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 0.5, + '[4->16] back buffer width is as expected'); + t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 0.5, + '[4->16] back buffer height is as expected'); + removeBackBuffer(); + + // + // tear down + // + + map.destroy(); + OpenLayers.Tile.Image.prototype.createBackBuffer = origCreateBackBuffer + } + + + function test_delayed_back_buffer_removal(t) { + // + // Test that the delaying of the back buffer removal behaves + // as expected. + // + + t.plan(5); + + // set up + + var map = new OpenLayers.Map('map', { + resolutions: [32, 16, 8, 4, 2, 1], + zoomMethod: null + }); + var layer = new OpenLayers.Layer.WMS('', '', {}, { + isBaseLayer: true, + transitionEffect: 'resize' + }); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), 0); + + map.zoomTo(1); + + t.ok(layer.backBuffer === map.layerContainerDiv.firstChild, + '[a] back buffer is first child of layer container div'); + + // Mark one tile loaded and add an element to the backbuffer, to see if + // backbuffer removal gets scheduled. + layer.backBuffer.appendChild(document.createElement('img')); + layer.grid[1][1].onImageLoad(); + + t.ok(layer.backBufferTimerId !== null, + '[a] back buffer scheduled for removal'); + + var backBuffer = layer.backBuffer; + + map.zoomTo(2); + + t.ok(layer.backBuffer !== backBuffer, + '[b] a new back buffer was created'); + t.ok(layer.backBuffer === map.layerContainerDiv.firstChild, + '[b] back buffer is first child of layer container div'); + t.ok(layer.backBufferTimerId === null, + '[b] back buffer no longer scheduled for removal'); + + // tear down + + map.destroy(); + } + + function test_getGridData(t) { + t.plan(12); + + var layer = new OpenLayers.Layer.Grid(null, null, null, { + isBaseLayer: true, getURL: function() { + return "/bogus/path/to/tile"; + } + }); + var map = new OpenLayers.Map({ + div: "map", + layers: [layer], + controls: [], + center: [0, 0], + zoom: 1 + }); + + // get tile data for [0, 0] + var data = layer.getTileData({lon: 0, lat: 0}); + t.ok(data && data.tile, "[0, 0]: got tile data"); + t.eq(data.i, 0, "[0, 0]: i"); + t.eq(data.j, 128, "[0, 0]: j"); + t.ok( + data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}), + "[0, 0]: tile bounds " + data.tile.bounds.toString() + ); + + // get tile data for [-110, 45] + data = layer.getTileData({lon: -110, lat: 45}); + t.ok(data && data.tile, "[-110, 45]: got tile data"); + t.eq(data.i, 99, "[-110, 45]: i"); + t.eq(data.j, 64, "[-110, 45]: j"); + t.ok( + data.tile.bounds.equals({left: -180, bottom: -90, right: 0, top: 90}), + "[-110, 45]: tile bounds " + data.tile.bounds.toString() + ); + + // get tile data for [0, 300] (north of grid) + data = layer.getTileData({lon: 0, lat: 300}) + t.eq(data, null, "[0, 300]: north of grid"); + + // get tile data for [400, 0] (east of grid) + data = layer.getTileData({lon: 400, lat: 0}) + t.eq(data, null, "[400, 0]: east of grid"); + + // get tile data for [0, -500] (south of grid) + data = layer.getTileData({lon: 0, lat: -500}) + t.eq(data, null, "[0, -500]: south of grid"); + + // get tile data for [-200, 0] (west of grid) + data = layer.getTileData({lon: -200, lat: 0}) + t.eq(data, null, "[-200, 0]: west of grid"); + + map.destroy(); + + } + + function test_getGridData_wrapped(t) { + t.plan(18); + + var layer = new OpenLayers.Layer.Grid(null, null, null, { + isBaseLayer: true, getURL: function() { + return "/bogus/path/to/tile"; + }, + wrapDateLine: true + }); + var map = new OpenLayers.Map({ + div: "map", + layers: [layer], + controls: [], + center: [-50, 0], + zoom: 1 + }); + + // get tile data for [0, 0] + var data = layer.getTileData({lon: 0, lat: 0}); + t.ok(data && data.tile, "[0, 0]: got tile data"); + t.eq(data.i, 0, "[0, 0]: i"); + t.eq(data.j, 128, "[0, 0]: j"); + t.ok( + data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}), + "[0, 0]: tile bounds " + data.tile.bounds.toString() + ); + + // get tile data for [-110, 45] + data = layer.getTileData({lon: -110, lat: 45}); + t.ok(data && data.tile, "[-110, 45]: got tile data"); + t.eq(data.i, 99, "[-110, 45]: i"); + t.eq(data.j, 64, "[-110, 45]: j"); + t.ok( + data.tile.bounds.equals({left: -180, bottom: -90, right: 0, top: 90}), + "[-110, 45]: tile bounds " + data.tile.bounds.toString() + ); + + // get tile data for [0, 300] (north of grid) + data = layer.getTileData({lon: 0, lat: 300}) + t.eq(data, null, "[0, 300]: north of grid"); + + // get tile data for [400, 0] (equivalent to [40, 0] and visible on map) + data = layer.getTileData({lon: 400, lat: 0}) + t.ok(data && data.tile, "[400, 0]: got tile data"); + t.eq(data.i, 56, "[400, 0]: i"); + t.eq(data.j, 128, "[400, 0]: j"); + t.ok( + data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}), + "[400, 0]: tile bounds " + data.tile.bounds.toString() + ); + + // get tile data for [0, -500] (south of grid) + data = layer.getTileData({lon: 0, lat: -500}) + t.eq(data, null, "[0, -500]: south of grid"); + + // get tile data for [-200, 0] (equivalent to [160, 0] and wrapped to west side map) + data = layer.getTileData({lon: -200, lat: 0}) + t.ok(data && data.tile, "[-200, 0]: got tile data"); + t.eq(data.i, 227, "[-200, 0]: i"); + t.eq(data.j, 128, "[-200, 0]: j"); + t.ok( + data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}), + "[-200, 0]: tile bounds " + data.tile.bounds.toString() + ); + + map.destroy(); + + } + + function test_removeExcessTiles(t) { + t.plan(15); + + /* + * Set up + */ + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.Grid('name', '/url', + {}, {isBaseLayer: true}); + map.addLayer(layer); + + function newTile(id) { + var t = new OpenLayers.Tile(layer, + new OpenLayers.Pixel(1, 1), + new OpenLayers.Bounds(1, 1, 1, 1)); + t._id = id; + return t; + } + + layer.grid = [ + [newTile(1), newTile(2), newTile(3)], + [newTile(4), newTile(5)], + [newTile(6), newTile(7), newTile(8)] + ]; + + // create a clone to be able to test whether + // tiles have been destroyed or not + var grid = [ + layer.grid[0].slice(), + layer.grid[1].slice(), + layer.grid[2].slice() + ]; + + /* + * Test + */ + + layer.removeExcessTiles(2, 2); + + t.eq(layer.grid.length, 2, 'grid has two rows'); + t.eq(layer.grid[0].length, 2, 'row #1 has two columns'); + t.eq(layer.grid[0][0]._id, 1, 'row #1 col #1 includes expected tile'); + t.eq(layer.grid[0][1]._id, 2, 'row #1 col #2 includes expected tile'); + t.eq(layer.grid[1].length, 2, 'row #2 has two columns'); + t.eq(layer.grid[1][0]._id, 4, 'row #2 col #1 includes expected tile'); + t.eq(layer.grid[1][1]._id, 5, 'row #2 col #2 includes expected tile'); + + t.ok(grid[0][0].events != null, 'tile 0,0 not destroyed'); + t.ok(grid[0][1].events != null, 'tile 0,1 not destroyed'); + t.ok(grid[0][2].events == null, 'tile 0,2 destroyed'); + t.ok(grid[1][0].events != null, 'tile 1,0 not destroyed'); + t.ok(grid[1][1].events != null, 'tile 1,1 not destroyed'); + t.ok(grid[2][0].events == null, 'tile 2,0 destroyed'); + t.ok(grid[2][1].events == null, 'tile 2,1 destroyed'); + t.ok(grid[2][2].events == null, 'tile 2,2 destroyed'); + + /* + * Tear down + */ + + map.destroy(); + } + + function test_addOptions(t) { + t.plan(15); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params, {buffer:2}); + map.addLayer(layer); + t.eq(layer.tileSize, map.getTileSize(), "layer's tile size is equal to the map's tile size"); + t.ok(layer.removeBackBufferDelay !== 0, "removeBackBufferDelay should not be 0 since we are not singleTile"); + t.eq(layer.className, "olLayerGrid", "className correct for gridded mode"); + map.setCenter(new OpenLayers.LonLat(0,0),5); + t.eq(layer.grid.length, 8, "Grid rows is correct."); + t.eq(layer.grid[0].length, 7, "Grid cols is correct."); + t.eq(layer.singleTile, false, "singleTile is false by default"); + layer.addOptions({singleTile: true}); + t.eq(layer.removeBackBufferDelay, 0, "removeBackBufferDelay set to 0 since singleTile is true"); + t.eq(layer.singleTile, true, "singleTile set to true"); + t.eq(layer.className, "olLayerGridSingleTile", "className correct for singleTile mode"); + t.eq(layer.grid.length, 1, "Grid rows is correct."); + t.eq(layer.grid[0].length, 1, "Grid cols is correct."); + t.eq(layer.tileSize, new OpenLayers.Size(748, 823), "tile size changed"); + layer.addOptions({singleTile: false}); + t.eq(layer.grid.length, 8, "Grid rows is correct."); + t.eq(layer.grid[0].length, 7, "Grid cols is correct."); + t.eq(layer.tileSize, map.getTileSize(), "layer's tile size is equal to the map's tile size"); + map.destroy(); + } + + </script> +</head> +<body> +<div id="map" style="width:499px;height:549px;display:none"></div> +<div id="map2" style="width:500px;height:550px;display:none"></div> +<div id="map3" style="width:594px;height:464px;display:none"></div> +<div id="map4" style="width:768px;height:512px;display:none"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/HTTPRequest.html b/misc/openlayers/tests/Layer/HTTPRequest.html new file mode 100644 index 0000000..dcb6e23 --- /dev/null +++ b/misc/openlayers/tests/Layer/HTTPRequest.html @@ -0,0 +1,229 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var layer; + + var name = "Test Layer"; + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + var params = { map: '/mapdata/vmap_wms.map', + layers: 'basic', + format: 'image/png'}; + var options = { chicken: 151, foo: "bar" }; + + function test_Layer_HTTPRequest_constructor (t) { + t.plan( 6 ); + + layer = new OpenLayers.Layer.HTTPRequest(name, url, params, options); + + t.ok( layer instanceof OpenLayers.Layer.HTTPRequest, "new OpenLayers.Layer.HTTPRequest returns correctly typed object" ); + + // correct bubbling up to Layer.initialize() + t.eq( layer.name, name, "layer.name is correct" ); + t.ok( ((layer.options["chicken"] == 151) && (layer.options["foo"] == "bar")), "layer.options correctly set" ); + + // HTTPRequest-specific properties + t.eq( layer.url, url, "layer.name is correct" ); + t.ok( ((layer.params["map"] == '/mapdata/vmap_wms.map') && + (layer.params["layers"] == "basic") && + (layer.params["format"] == "image/png")), "layer.params correctly set" ); + + layer = new OpenLayers.Layer.HTTPRequest(name, url, null, {params: params}); + t.ok( ((layer.params["map"] == '/mapdata/vmap_wms.map') && + (layer.params["layers"] == "basic") && + (layer.params["format"] == "image/png")), "layer.params correctly set from options" ); + } + + function test_Layer_HTTPRequest_clone (t) { + t.plan( 6 ); + + var toClone = new OpenLayers.Layer.HTTPRequest(name, url, params, options); + toClone.chocolate = 5; + + var layer = toClone.clone(); + + t.eq(layer.chocolate, 5, "correctly copied randomly assigned property"); + + t.ok( layer instanceof OpenLayers.Layer.HTTPRequest, "new OpenLayers.Layer.HTTPRequest returns correctly typed object" ); + + // correct bubbling up to Layer.initialize() + t.eq( layer.name, name, "layer.name is correct" ); + t.eq( layer.options, options, "layer.options correctly set" ); + + // HTTPRequest-specific properties + t.eq( layer.url, url, "layer.name is correct" ); + t.ok( ((layer.params["map"] == '/mapdata/vmap_wms.map') && + (layer.params["layers"] == "basic") && + (layer.params["format"] == "image/png")), "layer.params correctly set" ); + + } + + function test_Layer_HTTPRequest_setUrl (t) { + t.plan( 1 ); + + layer = new OpenLayers.Layer.HTTPRequest(name, url, params, options); + + layer.setUrl("foo"); + t.eq( layer.url, "foo", "setUrl() works"); + } + + function test_Layer_HTTPRequest_mergeNewParams (t) { + t.plan( 8 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.HTTPRequest(name, url, params, options); + map.addLayer(layer); + + var scope = {some: "scope"}, log = []; + map.events.on({ + changelayer: function(e) { + log.push({layer: e.layer, property: e.property, scope: this}); + }, + scope: scope + }); + + var newParams = { layers: 'sooper', + chickpeas: 'image/png'}; + + layer.mergeNewParams(newParams); + + t.eq( layer.params.layers, "sooper", "mergeNewParams() overwrites well"); + t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() adds well"); + t.eq( log.length, 1, "mergeNewParams() triggers changelayer once"); + t.ok( log[0].layer == layer, "mergeNewParams() passes changelayer listener the expected layer"); + t.ok( log[0].property == "params", "mergeNewParams() passes changelayer listener the property \"params\""); + t.eq( log[0].scope, scope, "mergeNewParams() executes changelayer listener with expected scope"); + + newParams.chickpeas = 151; + + t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() makes clean copy of hash"); + + layer.redraw = function() { + t.ok(true, "layer.mergeNewParams calls layer.redraw"); + } + layer.mergeNewParams(); + } + + function test_Layer_HTTPRequest_getFullRequestString (t) { + + tParams = { layers: 'basic', + format: 'image/png'}; + + t.plan( 12 ); + + // without ? + tUrl = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null); + str = layer.getFullRequestString(); + t.eq(str, tUrl + '?' + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for url sans ?"); + + + // with ? + tUrl = "http://octo.metacarta.com/cgi-bin/mapserv?"; + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null); + str = layer.getFullRequestString(); + t.eq(str, tUrl + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for url with ?"); + + // with ?param1=5 + tUrl = "http://octo.metacarta.com/cgi-bin/mapserv?param1=5"; + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null); + str = layer.getFullRequestString(); + t.eq(str, tUrl + '&' + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for url with ?param1=5"); + + // with ?param1=5& + tUrl = "http://octo.metacarta.com/cgi-bin/mapserv?param1=5&format=image/jpeg"; + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null); + str = layer.getFullRequestString(); + t.eq(str, tUrl + '&' + OpenLayers.Util.getParameterString({'layers':'basic'}), "getFullRequestString() doesn't override already-existing params in URL"); + + + // with ?param1=5& + tUrl = "http://octo.metacarta.com/cgi-bin/mapserv?param1=5&"; + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null); + str = layer.getFullRequestString(); + t.eq(str, tUrl + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for url with ?param1=5&"); + + + + // passing in new params + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null); + str = layer.getFullRequestString( { chicken: 6, + layers:"road" } ); + t.eq(str, tUrl + OpenLayers.Util.getParameterString({layers: 'road', format: "image/png", chicken: 6}), "getFullRequestString() works for passing in new params"); + + // layer with null params + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, null, null); + str = layer.getFullRequestString(); + t.eq(str, tUrl + OpenLayers.Util.getParameterString({}), "getFullRequestString() works for layer with null params"); + + // layer with null params passing in new params + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, null, null); + str = layer.getFullRequestString( { chicken: 6, + layers:"road" } ); + t.eq(str, tUrl + OpenLayers.Util.getParameterString({chicken: 6, layers: "road"}), "getFullRequestString() works for layer with null params passing in new params"); + + // with specified altUrl parameter + tUrl = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.HTTPRequest(name, "chicken", tParams, null); + str = layer.getFullRequestString(null, tUrl); + t.eq(str, tUrl + '?' + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works with specified altUrl parameter"); + + // single url object + tUrl = ["http://octo.metacarta.com/cgi-bin/mapserv"]; + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null); + str = layer.getFullRequestString(); + t.eq(str, tUrl[0] + '?' + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for list of one url"); + + // two url object + tUrl = ["http://octo.metacarta.com/cgi-bin/mapserv","http://labs.metacarta.com/cgi-bin/mapserv"]; + layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null); + str = layer.getFullRequestString(); + t.eq(str, tUrl[1] + '?' + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for list of two urls"); + str = layer.getFullRequestString({'a':'b'}); + t.eq(str, tUrl[0] + '?' + OpenLayers.Util.getParameterString(OpenLayers.Util.extend(tParams,{'a':'b'})), "getFullRequestString() works for list of two urls and is deterministic"); + + } + + function test_Layer_HTTPRequest_selectUrl (t) { + t.plan( 4 ); + + layer = new OpenLayers.Layer.HTTPRequest(name, url, params, options); + + urls = ["wms1", "wms2", "wms3", "wms4"]; + t.eq( layer.selectUrl("bbox=-180,0,0,90", urls), "wms3", "selectUrl(-90,-180) returns 4" ); + t.eq( layer.selectUrl("bbox=-180,-90,0,0", urls), "wms1", "selectUrl(90,-180) returns 3" ); + t.eq( layer.selectUrl("bbox=0,90,180,0", urls), "wms1", "selectUrl(-90,180) returns 1" ); + t.eq( layer.selectUrl("bbox=0,0,180,90", urls), "wms4", "selectUrl(90,180) returns 2" ); + } + + function test_Layer_HTTPRequest_destroy (t) { + t.plan( 6 ); + + var map = new OpenLayers.Map('map'); + + layer = new OpenLayers.Layer.HTTPRequest("Test Layer", + "http://www.openlayers.org", + { foo: 2, bar: 3}, + { opt1: 8, opt2: 9}); + + map.addLayer(layer); + layer.destroy(); + + // Ensure Layer.destroy() is called + t.eq( layer.name, null, "layer.name is null after destroy" ); + t.eq( layer.div, null, "layer.div is null after destroy" ); + t.eq( layer.map, null, "layer.map is null after destroy" ); + t.eq( layer.options, null, "layer.options is null after destroy" ); + + + // Specific to HTTPRequest + t.eq( layer.url, null, "layer.url is null after destroy" ); + t.eq( layer.params, null, "layer.params is null after destroy" ); + } + + </script> +</head> +<body> + <div id="map"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/Image.html b/misc/openlayers/tests/Layer/Image.html new file mode 100644 index 0000000..05ab5c3 --- /dev/null +++ b/misc/openlayers/tests/Layer/Image.html @@ -0,0 +1,164 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var layer; + + function test_Layer_Image_constructor (t) { + t.plan( 13 ); + + var options = { chicken: 151, foo: "bar", projection: "EPSG:4326" }; + var layer = new OpenLayers.Layer.Image('Test Layer', + '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), options); + + t.ok( layer instanceof OpenLayers.Layer.Image, "new OpenLayers.Layer.Image returns object" ); + t.eq( layer.CLASS_NAME, "OpenLayers.Layer.Image", "CLASS_NAME variable set correctly"); + + t.eq( layer.name, "Test Layer", "layer.name is correct" ); + t.ok( layer.id != null, "Layer is given an id"); + t.eq( layer.projection.getCode(), "EPSG:4326", "default layer projection correctly set"); + t.ok( ((layer.chicken == 151) && (layer.foo == "bar")), "layer.options correctly set to Layer Object" ); + t.ok( ((layer.options["chicken"] == 151) && (layer.options["foo"] == "bar")), "layer.options correctly backed up" ); + + options.chicken = 552; + + t.eq( layer.options["chicken"], 151 , "layer.options correctly made fresh copy" ); + + t.eq( layer.isBaseLayer, true, "Default img layer is base layer" ); + + layer = new OpenLayers.Layer.Image('Test Layer', + '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)); + t.ok( layer instanceof OpenLayers.Layer.Image, "new OpenLayers.Layer.Image returns object" ); + t.eq( layer.name, "Test Layer", "layer.name is correct" ); + t.ok( layer.projection == null, "default layer projection correctly set"); + t.ok( layer.options instanceof Object, "layer.options correctly initialized as a non-null Object" ); + } + + function test_maxExtent(t) { + t.plan(2); + var layer; + + // test that the image extent is set as the default maxExtent + var extent = new OpenLayers.Bounds(1, 2, 3, 4); + var size = new OpenLayers.Size(2, 2); + layer = new OpenLayers.Layer.Image("Test", "foo", extent, size); + t.eq(layer.maxExtent.toString(), extent.toString(), "extent set as default maxExtent"); + + // test that the maxExtent can be set explicitly + var maxExtent = new OpenLayers.Bounds(10, 20, 30, 40); + layer = new OpenLayers.Layer.Image("Test", "foo", extent, size, {maxExtent: maxExtent}); + t.eq(layer.maxExtent.toString(), maxExtent.toString(), "maxExtent can be set explicitly"); + + } + + function test_Layer_Image_tileTests (t) { + t.plan(7); + var map = new OpenLayers.Map('map'); + + layer = new OpenLayers.Layer.Image('Test Layer', + '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)); + + map.addLayer(layer); + map.zoomToMaxExtent(); + + // no resolution info was sent, so maxResolution should be calculated + // by aspectRatio*extent/size (this is the pixel aspect ratio) + var aspectRatio = (layer.extent.getHeight() / layer.size.h) / + (layer.extent.getWidth() / layer.size.w); + t.eq(aspectRatio, layer.aspectRatio, "aspectRatio is properly set"); + var maxExtent = aspectRatio * layer.extent.getWidth() / layer.size.w; + t.eq(maxExtent, layer.maxResolution, "maxResolution is properly set"); + + t.eq(layer.tile.position.x,-42, "Tile x positioned correctly at maxextent"); + t.eq(layer.tile.position.y,106, "Tile y positioned correctly at maxextent"); + t.eq(layer.tile.url, "http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif", "URL is correct"); + map.zoomIn(); + t.eq(layer.tile.url, "http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif", "URL is correct"); + layer.setUrl('http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256'); + t.eq(layer.tile.url, "http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256", "URL is correct after setURL"); + } +/****** + * + * + * HERE IS WHERE SOME TESTS SHOULD BE PUT TO CHECK ON THE LONLAT-PX TRANSLATION + * FUNCTIONS AND RESOLUTION AND GETEXTENT GETZOOMLEVEL, ETC + * + * + */ + + + function test_Layer_Image_destroy_before_use (t) { + t.plan(1); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.Image('Test', '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)); + map.addLayer(layer); + map.removeLayer(layer); + layer.destroy(); + t.ok(true, "destroy() didn't throw an error"); + } + + function test_Layer_Image_destroy (t) { + t.plan( 4 ); + + var map = new OpenLayers.Map('map'); + + layer = new OpenLayers.Layer.Image('Test Layer', + '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)); + + map.addLayer(layer); + map.zoomToMaxExtent(); + + layer.destroy(); + + t.eq( layer.name, null, "layer.name is null after destroy" ); + t.eq( layer.div, null, "layer.div is null after destroy" ); + t.eq( layer.map, null, "layer.map is null after destroy" ); + t.eq( layer.options, null, "layer.options is null after destroy" ); + + } + + function test_loadEvents(t) { + t.plan(3); + + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.Image( + 'Test', '../../img/blank.gif', + new OpenLayers.Bounds(-180, -88.759, 180, 88.759), + new OpenLayers.Size(580, 288) + ); + + map.addLayer(layer); + + layer.events.register('loadstart', null, function(obj) { + t.ok(obj.object.tile.isLoading, "loadstart triggered while tile is loading"); + }); + + var delay = false; + layer.events.register('loadend', null, function(obj) { + delay = true; + }); + + t.delay_call(5, function() { + t.eq(delay, true, "registered for loadend"); + t.eq(layer.tile.isLoading, false, "loadend triggered after tile is loaded"); + map.destroy(); //tear down + return delay; + }); + map.zoomToMaxExtent(); + } + + </script> +</head> +<body> + <div id="map" style="width:500px;height:500px"></div> + <div id="map2" style="width:100px;height:100px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/KaMap.html b/misc/openlayers/tests/Layer/KaMap.html new file mode 100644 index 0000000..a41e4eb --- /dev/null +++ b/misc/openlayers/tests/Layer/KaMap.html @@ -0,0 +1,287 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var layer; + + var name = 'Test Layer'; + var url = "http://boston.freemap.in/tile.php?"; + var params = { + 'map':'boston-new', + 'g':'border,water,roads,openspace', + 'i':'JPEG' + }; + var units = "meters"; + + + + function test_Layer_KaMap_constructor (t) { + t.plan( 1 ); + + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + t.ok( layer instanceof OpenLayers.Layer.KaMap, "returns OpenLayers.Layer.KaMap object" ); + } + + function test_Layer_Grid_moveTo_buffer_calculation (t) { + t.plan(6); + + var map = new OpenLayers.Map( 'map3' ); // odd map size + var layer0 = new OpenLayers.Layer.KaMap( "0 buffer: OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", + {layers: 'basic'}, {'buffer':0} ); + map.addLayer(layer0); + + var layer1 = new OpenLayers.Layer.KaMap( "1 buffer: OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", + {layers: 'basic'}, {'buffer':1} ); + map.addLayer(layer1); + + var layer2 = new OpenLayers.Layer.KaMap( "2 buffer: OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", + {layers: 'basic'}, {'buffer':2} ); + map.addLayer(layer2); + + map.setCenter(new OpenLayers.LonLat(0, 0), 4); + t.eq( layer0.grid.length, 3, "Grid rows with buffer:0" ); + map.setBaseLayer(layer1); + t.eq( layer1.grid.length, 5, "Grid rows with buffer:1" ); + map.setBaseLayer(layer2); + t.eq( layer2.grid.length, 7, "Grid rows with buffer:2" ); + + // zooming in on Greenland exercises the bug from pre-r4313 + map.setCenter(new OpenLayers.LonLat(0, 90), 4); + t.eq( layer0.grid.length, 3, "Grid rows with buffer:0" ); + map.setBaseLayer(layer1); + t.eq( layer1.grid.length, 5, "Grid rows with buffer:1" ); + map.setBaseLayer(layer2); + t.eq( layer2.grid.length, 7, "Grid rows with buffer:2" ); + map.destroy(); + } + + function test_Layer_KaMap_inittiles (t) { + t.plan( 2 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),5); + t.eq( layer.grid.length, 4, "KaMap rows is correct." ); + t.eq( layer.grid[0].length, 3, "KaMap cols is correct." ); + map.destroy(); + + } + + function test_Layer_KaMap_clearTiles (t) { + t.plan( 1 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0)); + + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.clearGrid(); + + t.ok( layer.grid != null, "layer.grid does not get nullified" ); + map.destroy(); + } + + + function test_Layer_KaMap_getKaMapBounds(t) { + t.plan( 1 ); + + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + + var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)}; + var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)}; + layer.grid = [ [6, tr], + [bl, 7]]; + + var bounds = layer.getTilesBounds(); + + var testBounds = new OpenLayers.Bounds(1,2,3,4); + + t.ok( bounds.equals(testBounds), "getKaMapBounds() returns correct bounds") + + layer.grid = null; + } + + function test_Layer_KaMap_getResolution(t) { + t.plan( 1 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + map.addLayer(layer); + + map.zoom = 5; + + t.eq( layer.getResolution(), 0.0439453125, "getResolution() returns correct value"); + map.destroy(); + } + + function test_Layer_KaMap_getZoomForExtent(t) { + t.plan( 2 ); + var bounds, zoom; + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + map.addLayer(layer); + + bounds = new OpenLayers.Bounds(10,10,12,12); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 8, "getZoomForExtent() returns correct value"); + + bounds = new OpenLayers.Bounds(10,10,100,100); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 2, "getZoomForExtent() returns correct value"); + map.destroy(); + } + + function test_Layer_kaMap_mergeNewParams (t) { + t.plan( 4 ); + + var map = new OpenLayers.Map("map"); + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.KaMap(name, url, params); + + var newParams = { layers: 'sooper', + chickpeas: 'image/png'}; + + map.addLayer(layer); + map.zoomToMaxExtent(); + layer.redraw = function() { + t.ok(true, "layer is redrawn after new params merged"); + } + + layer.mergeNewParams(newParams); + + t.eq( layer.params.layers, "sooper", "mergeNewParams() overwrites well"); + t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() adds well"); + + newParams.chickpeas = 151; + + t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() makes clean copy of hashtable"); + map.destroy(); + } + + + /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR + * + * -moveTo + * -insertColumn + * -insertRow + + function 07_Layer_KaMap_moveTo(t) { + } + + function 08_Layer_KaMap_insertColumn(t) { + } + + function 09_Layer_KaMap_insertRow(t) { + } + + * + */ + + function test_Layer_KaMap_clone(t) { + t.plan(5); + + var options = {tileSize: new OpenLayers.Size(500,50)}; + var map = new OpenLayers.Map('map', options); + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + map.addLayer(layer); + + layer.grid = [ [6, 7], + [8, 9]]; + + var clone = layer.clone(); + + t.ok( clone.grid != layer.grid, "clone does not copy grid"); + + t.ok( clone.tileSize.equals(layer.tileSize), "tileSize correctly cloned"); + + layer.tileSize.w += 40; + + t.eq( clone.tileSize.w, 500, "changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference"); + + t.eq( clone.alpha, layer.alpha, "alpha copied correctly"); + + t.eq( clone.CLASS_NAME, "OpenLayers.Layer.KaMap", "Clone is a ka-map layer"); + + layer.grid = null; + map.destroy(); + } + + function test_Layer_KaMap_setMap(t) { + + t.plan(2); + + var options = {tileSize: new OpenLayers.Size(500,50)}; + var map = new OpenLayers.Map('map', options); + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + + + layer.setMap(map); + + t.ok( layer.tileSize != null, "tileSize has been set"); + t.ok( (layer.tileSize.h == 50) && (layer.tileSize.w == 500), "tileSize has been set correctly"); + map.destroy(); + } + function test_Layer_KaMap_getTileBounds(t) { + t.plan(2); + var map = new OpenLayers.Map("map", {zoomMethod: null}); + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.KaMap(name, url, params); + + var newParams = { layers: 'sooper', + chickpeas: 'image/png'}; + + map.addLayer(layer); + map.zoomToMaxExtent(); + map.zoomIn(); + var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200)); + t.eq(bounds.toBBOX(), "-180,0,0,180", "get tile bounds returns correct bounds"); + map.pan(200,0,{animate:false}); + var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200)); + t.eq(bounds.toBBOX(), "0,0,180,180", "get tile bounds returns correct bounds after pan"); + map.destroy(); + } + + function test_Layer_KaMap_destroy (t) { + + t.plan( 3 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + map.addLayer(layer); + layer.destroy(); + t.eq( layer.grid, null, "layer.grid is null after destroy" ); + t.eq( layer.tileSize, null, "layer.tileSize is null after destroy" ); + + + //test with tile creation + layer = new OpenLayers.Layer.KaMap(name, url, params, units); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.destroy(); + + t.ok( layer.grid == null, "tiles appropriately destroyed"); + map.destroy(); + } + + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px;display:none"></div> +<div id="map2" style="width:500px;height:550px;display:none"></div> +<div id="map3" style="width:594px;height:464px;display:none"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/MapGuide.html b/misc/openlayers/tests/Layer/MapGuide.html new file mode 100644 index 0000000..b1eb386 --- /dev/null +++ b/misc/openlayers/tests/Layer/MapGuide.html @@ -0,0 +1,177 @@ +<html> +<head> + <script type="text/javascript">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script> + <script src='http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAjpkAC9ePGem0lIq5XcMiuhR_wWLPFku8Ix9i2SXYRVK3e45q1BQUd_beF8dtzKET_EteAjPdGDwqpQ'></script> + <script type="text/javascript">window.alert = oldAlert;</script> +<script src="../OLLoader.js"></script> + <script type="text/javascript"> + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var layer; + + var name = 'MapGuide Test Layer'; + var url = "http://data.mapguide.com/mapguide/mapagent/mapagent.fcgi?USERNAME=Anonymous&"; + var paramsTiled = { + mapdefinition: 'Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition', + basemaplayergroupname: "Base Layer Group" + } + var paramsUntiled = { + mapdefinition: 'Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition' + }; + + function test_Layer_MapGuide_untiled_constructor (t) { + t.plan( 8 ); + + var trans_format = "image/png"; + var options = {singleTile:true}; + if (OpenLayers.Util.alphaHack()) { trans_format = "image/gif"; } + + layer = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options); + t.ok( layer instanceof OpenLayers.Layer.MapGuide, "new OpenLayers.Layer.MapGuide returns object" ); + t.eq( layer.url, "http://data.mapguide.com/mapguide/mapagent/mapagent.fcgi?USERNAME=Anonymous&", "layer.url is correct (HTTPRequest inited)" ); + t.eq( layer.params.mapdefinition, "Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition", "params passed in correctly" ); + + t.eq( layer.params.operation, "GETMAPIMAGE", "default params set correctly and copied"); + + t.eq(layer.isBaseLayer, true, "no transparency setting, layer is baselayer"); + + options.transparent = "true"; + var layer2 = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options); + t.eq(layer2.isBaseLayer, false, "transparency == 'true', layer is not baselayer"); + + options.transparent = true; + var layer5 = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options); + t.eq(layer5.isBaseLayer, false, "transparency == true, layer is not baselayer"); + + options.transparent = false; + var layer6 = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options); + t.eq(layer6.isBaseLayer, true, "transparency == false, layer is baselayer"); + } + + function test_Layer_MapGuide_tiled_constructor (t) { + t.plan( 5 ); + + var trans_format = "image/png"; + var options = {singleTile:false}; + if (OpenLayers.Util.alphaHack()) { trans_format = "image/gif"; } + + layer = new OpenLayers.Layer.MapGuide(name, url, paramsTiled, options); + t.ok( layer instanceof OpenLayers.Layer.MapGuide, "new OpenLayers.Layer.MapGuide returns object" ); + t.eq( layer.url, "http://data.mapguide.com/mapguide/mapagent/mapagent.fcgi?USERNAME=Anonymous&", "layer.url is correct (HTTPRequest inited)" ); + t.eq( layer.params.basemaplayergroupname, "Base Layer Group", "params passed in correctly" ); + + t.eq( layer.params.operation, "GETTILEIMAGE", "default params correctly uppercased and copied"); + t.eq( layer.params.version, "1.2.0", "version params set correctly set"); + } + + function test_Layer_MapGuide_inittiles (t) { + t.plan( 1 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.MapGuide(name, url, paramsTiled); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,400000),5); + t.eq( layer.grid.length, 3, "Grid rows is correct." ); + // t.eq( layer.grid[0].length, 6, "Grid cols is correct." ); + map.destroy(); + } + + + function test_Layer_MapGuide_clone (t) { + t.plan(4); + + var options = {tileSize: new OpenLayers.Size(500,50)}; + var map = new OpenLayers.Map('map', options); + layer = new OpenLayers.Layer.MapGuide(name, url, paramsTiled); + map.addLayer(layer); + + layer.grid = [ [6, 7], + [8, 9]]; + + var clone = layer.clone(); + + t.eq( layer.tileSize.w, 300, "layer.tileSize fixed to 300x300"); + t.ok( clone.grid != layer.grid, "clone does not copy grid"); + + t.ok( clone.tileSize.equals(layer.tileSize), "tileSize correctly cloned"); + + layer.tileSize.w += 40; + + t.eq( clone.alpha, layer.alpha, "alpha copied correctly"); + + layer.grid = null; + map.destroy(); + } + + function test_Layer_MapGuide_isBaseLayer(t) { + t.plan(3); + + var options = {singleTile:true}; + layer = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options); + t.ok( layer.isBaseLayer, "baselayer is true by default"); + + var newParams = OpenLayers.Util.extend({}, paramsUntiled); + options.transparent = "true"; + layer = new OpenLayers.Layer.MapGuide(name, url, newParams, options); + t.ok( !layer.isBaseLayer, "baselayer is false when transparent is set to true"); + + newParams = OpenLayers.Util.extend({}, paramsUntiled); + options.isBaseLayer = false; + layer = new OpenLayers.Layer.MapGuide(name, url, newParams, options); + t.ok( !layer.isBaseLayer, "baselayer is false when option is set to false" ); + } + + function test_Layer_MapGuide_mergeNewParams (t) { + t.plan( 4 ); + + var options = {singleTile:true}; + var map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options); + + var newParams = { mapDefinition: 'Library://Samples/Gmap/Maps/gmap.MapDefinition', + chickpeas: 'image/png'}; + + map.addLayer(layer); + map.zoomToMaxExtent(); + + layer.redraw = function() { + t.ok(true, "layer is redrawn after new params merged"); + } + + layer.mergeNewParams(newParams); + + t.eq( layer.params.mapDefinition, "Library://Samples/Gmap/Maps/gmap.MapDefinition", "mergeNewParams() overwrites well"); + t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() adds well"); + + newParams.chickpeas = 151; + + t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() makes clean copy of hashtable"); + map.destroy(); + } + + function test_Layer_MapGuide_destroy (t) { + + t.plan( 1 ); + + var options = {singleTile:true}; + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0), 5); + + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.destroy(); + + // checks to make sure superclass (grid) destroy() was called + + t.ok( layer.grid == null, "grid set to null"); + } + + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/MapServer.html b/misc/openlayers/tests/Layer/MapServer.html new file mode 100644 index 0000000..9ae8d01 --- /dev/null +++ b/misc/openlayers/tests/Layer/MapServer.html @@ -0,0 +1,238 @@ +<html> +<head> + <script type="text/javascript">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script> + <script type="text/javascript">window.alert = oldAlert;</script> + + +<script src="../OLLoader.js"></script> + <script type="text/javascript"> + // turn off animation frame handling, so we can check img urls in tests + delete OpenLayers.Layer.Grid.prototype.queueTileDraw; + + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var layer; + + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/cgi-bin/mapserv"; + var params = { map: '/mapdata/vmap_wms.map', + layers: 'basic'}; + + function test_Layer_MapServer_constructor (t) { + t.plan( 4 ); + + var url = "http://labs.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.MapServer(name, url, params); + t.ok( layer instanceof OpenLayers.Layer.MapServer, "new OpenLayers.Layer.MapServer returns object" ); + t.eq( layer.url, "http://labs.metacarta.com/cgi-bin/mapserv", "layer.url is correct (HTTPRequest inited)" ); + + t.eq( layer.params.mode, "map", "default mode param correctly copied"); + t.eq( layer.params.map_imagetype, "png", "default imagetype correctly copied"); + + + } + + function test_Layer_MapServer_addtile (t) { + t.plan( 6 ); + + var url = "http://labs.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.MapServer(name, url, params); + var map = new OpenLayers.Map('map', {tileManager: null}); + map.addLayer(layer); + var pixel = new OpenLayers.Pixel(5,6); + var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel); + tile.draw(); + + var img = tile.imgDiv; + var tParams = OpenLayers.Util.extend({},params); + tParams = OpenLayers.Util.extend(tParams, { + layers: 'basic', + mode: 'map', + map_imagetype: 'png', + mapext:[1,2,3,4], + imgext:[1,2,3,4], + map_size:[256, 256], + imgx:128, + imgy:128, + imgxy:[256,256] + }); + t.eq( tile.url, + url + "?" + OpenLayers.Util.getParameterString(tParams).replace(/,/g, "+"), + "image src is created correctly via addtile" ); + t.eq( tile.getTile().style.top, "6px", "image top is set correctly via addtile" ); + t.eq( tile.getTile().style.left, "5px", "image top is set correctly via addtile" ); + + var firstChild = layer.div.firstChild; + t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" ); + t.ok( firstChild == img, "div first child is correct image object" ); + t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." ); + map.destroy(); + } + + function test_Layer_MapServer_inittiles (t) { + t.plan( 2 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.MapServer(name, url, params, {buffer: 0}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),5); + t.eq( layer.grid.length, 4, "Grid rows is correct." ); + t.eq( layer.grid[0].length, 3, "Grid cols is correct." ); + map.destroy(); + + } + + + function test_Layer_MapServer_clone (t) { + t.plan(4); + + var url = "http://labs.metacarta.com/cgi-bin/mapserv"; + var options = {tileSize: new OpenLayers.Size(500,50)}; + var map = new OpenLayers.Map('map', options); + layer = new OpenLayers.Layer.MapServer(name, url, params); + map.addLayer(layer); + + layer.grid = [ [6, 7], + [8, 9]]; + + var clone = layer.clone(); + + t.ok( clone.grid != layer.grid, "clone does not copy grid"); + + t.ok( clone.tileSize.equals(layer.tileSize), "tileSize correctly cloned"); + + layer.tileSize.w += 40; + + t.eq( clone.tileSize.w, 500, "changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference"); + + t.eq( clone.alpha, layer.alpha, "alpha copied correctly"); + + layer.grid = null; + map.destroy(); + } + + function test_Layer_MapServer_isBaseLayer(t) { + t.plan(3); + + var url = "http://labs.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.MapServer(name, url, params); + t.ok( layer.isBaseLayer, "baselayer is true by default"); + + var newParams = OpenLayers.Util.extend({}, params); + newParams.transparent = "true"; + layer = new OpenLayers.Layer.MapServer(name, url, newParams); + t.ok( !layer.isBaseLayer, "baselayer is false when transparent is set to true"); + + layer = new OpenLayers.Layer.MapServer(name, url, params, {isBaseLayer: false}); + t.ok( !layer.isBaseLayer, "baselayer is false when option is set to false" ); + } + + function test_Layer_MapServer_mergeNewParams (t) { + t.plan( 4 ); + + var map = new OpenLayers.Map("map"); + var url = "http://labs.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.MapServer(name, url, params); + + var newParams = { layers: 'sooper', + chickpeas: 'image/png'}; + + map.addLayer(layer); + map.zoomToMaxExtent(); + + layer.redraw = function() { + t.ok(true, "layer is redrawn after new params merged"); + } + layer.mergeNewParams(newParams); + + t.eq( layer.params.layers, "sooper", "mergeNewParams() overwrites well"); + t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() adds well"); + + newParams.chickpeas = 151; + + t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() makes clean copy of hashtable"); + map.destroy(); + } + + function test_Layer_MapServer_getFullRequestString (t) { + t.plan( 3 ); + var map = new OpenLayers.Map('map'); + tUrl = "http://labs.metacarta.com/cgi-bin/mapserv"; + tParams = { layers: 'basic', + format: 'png'}; + var tLayer = new OpenLayers.Layer.MapServer(name, tUrl, tParams); + map.addLayer(tLayer); + str = tLayer.getFullRequestString(); + var tParams = { + layers: 'basic', + format: 'png', + mode: 'map', + map_imagetype: 'png' + }; + + var sStr = tUrl + "?" + OpenLayers.Util.getParameterString(tParams); + sStr = sStr.replace(/,/g, "+"); + + t.eq(str, sStr , "getFullRequestString() works"); + map.destroy(); + + tUrl = ["http://octo.metacarta.com/cgi-bin/mapserv","http://labs.metacarta.com/cgi-bin/mapserv"]; + layer = new OpenLayers.Layer.MapServer(name, tUrl, tParams, null); + str = layer.getFullRequestString({'c':'d'}); + t.eq(str, tUrl[1] + '?' + OpenLayers.Util.getParameterString(OpenLayers.Util.extend(tParams,{'c':'d'})), "getFullRequestString() works for list of two urls and is deterministic"); + layer.destroy(); + var tParams = { + layers: 'basic', + format: 'png', + mode: 'map', + map_imagetype: 'png' + }; + tUrl = ["http://octo.metacarta.com/cgi-bin/mapserv","http://labs.metacarta.com/cgi-bin/mapserv"]; + layer = new OpenLayers.Layer.MapServer(name, tUrl, tParams, null); + str = layer.getFullRequestString({'a':'b'}); + t.eq(str, tUrl[0] + '?' + OpenLayers.Util.getParameterString(OpenLayers.Util.extend(tParams,{'a':'b'})), "getFullRequestString() works for list of two urls and is deterministic"); + layer.destroy(); + + } + + function test_Layer_MapServer_singleTile (t) { + t.plan( 5 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.MapServer(name, url, params, {singleTile: true}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),5); + t.eq( layer.singleTile, true, "layer has singleTile property, great!" ); + t.eq( layer.grid.length, 1, "Grid has only a single row, good enough!" ); + t.eq( layer.grid[0].length, 1, "Grid has only a single column, good enough!" ); + t.eq( layer.tileSize.w, 750, "Image width is correct" ); + t.eq( layer.tileSize.h, 825, "Image height is correct" ); + map.destroy(); + } + + + + function test_Layer_MapServer_destroy (t) { + + t.plan( 1 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.MapServer(name, url, params); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0), 5); + + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.destroy(); + + // checks to make sure superclass (grid) destroy() was called + + t.ok( layer.grid == null, "grid set to null"); + map.destroy(); + } + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/Markers.html b/misc/openlayers/tests/Layer/Markers.html new file mode 100644 index 0000000..07f699f --- /dev/null +++ b/misc/openlayers/tests/Layer/Markers.html @@ -0,0 +1,156 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var layer; + + function test_initialize(t) { + t.plan( 2 ); + + layer = new OpenLayers.Layer.Markers('Test Layer'); + t.ok( layer instanceof OpenLayers.Layer.Markers, "new OpenLayers.Layer.Markers returns object" ); + t.eq( layer.name, "Test Layer", "layer.name is correct" ); + } + function test_addlayer (t) { + t.plan( 3 ); + + layer = new OpenLayers.Layer.Markers('Test Layer'); + t.ok( layer instanceof OpenLayers.Layer.Markers, "new OpenLayers.Layer.Markers returns object" ); + t.eq( layer.name, "Test Layer", "layer.name is correct" ); + layer.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0), + new OpenLayers.Icon()) + ); + t.eq( layer.markers.length, 1, "addLayer adds marker to layer." ); + } + function test_addMarker_removeMarker (t) { + t.plan( 6 ); + + var 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.zoomToMaxExtent(); + layer = new OpenLayers.Layer.Markers('Test Layer'); + map.addLayer(layer); + var marker = new OpenLayers.Marker(new OpenLayers.LonLat(5,40)); + layer.addMarker(marker); + t.ok( marker.icon.imageDiv.parentNode == layer.div, "addMarker adds marker image node into layer node." ); + layer.removeMarker(marker); + t.ok( marker.icon.imageDiv.parentNode != layer.div, "removeMarker removes marker image node from layer node." ); + layer.removeMarker(marker); + t.ok(true, "Removing marker twice does not fail."); + layer.addMarker(marker); + t.ok( marker.icon.imageDiv.parentNode == layer.div, "addMarker adds marker image node into layer node." ); + + layer.markers = null; + layer.removeMarker(marker); + t.ok(true, "removing marker when no markers present does not script error"); + + var l = new OpenLayers.Layer.Markers(); + var marker = new OpenLayers.Marker(new OpenLayers.LonLat(5,40)); + l.addMarker(marker); + l.removeMarker(marker); + t.ok(true, "Removing marker when layer not added to map does not fail."); + + } + + function test_markerMovement(t) { + + t.plan(6); + + var map = new OpenLayers.Map("map", {zoomMethod: null}); + var layer = new OpenLayers.Layer.Markers("Base", {isBaseLayer: true}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), 1); + + var size = new OpenLayers.Size(10, 10); + var offset = new OpenLayers.Pixel(-(size.w/2), -size.h); + var icon = new OpenLayers.Icon("foo", size, offset); + var marker = new OpenLayers.Marker(new OpenLayers.LonLat(10, -10), icon) + layer.addMarker(marker); + + t.eq(marker.icon.px.x, 554, "marker icon is placed at 554 px on x-axis"); + t.eq(marker.icon.px.y, 314, "marker icon is placed at 314 px on y-axis"); + + map.zoomTo(2); + + t.eq(marker.icon.px.x, 568, "marker icon moved to 568 px on x-axis"); + t.eq(marker.icon.px.y, 328, "marker icon moved to 328 px on y-axis"); + + map.zoomTo(1); + + t.eq(marker.icon.px.x, 554, "marker icon moved back to 554 px on x-axis"); + t.eq(marker.icon.px.y, 314, "marker icon moved back to 314 px on y-axis"); + + } + + function test_destroy (t) { + t.plan( 1 ); + layer = new OpenLayers.Layer.Markers('Test Layer'); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + layer.destroy(); + t.eq( layer.map, null, "layer.map is null after destroy" ); + } + + function test_getDataExtent(t) { + t.plan( 4 ); + + var layer = {}; + var ret = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(layer, []); + t.eq(ret, null, "does not crash, returns null on layer with null 'this.markers'"); + + layer.markers = []; + ret = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(layer, []); + t.eq(ret, null, "returns null on layer with empty 'this.markers'"); + + layer.markers.push({ + 'lonlat': new OpenLayers.LonLat(4,5) + }); + var expectedBounds = new OpenLayers.Bounds(4,5,4,5); + ret = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(layer, []); + t.ok(ret.equals(expectedBounds), "returns expected bounds with only one marker"); + + layer.markers.push({ + 'lonlat': new OpenLayers.LonLat(1,2) + }); + var expectedBounds = new OpenLayers.Bounds(1,2,4,5); + ret = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(layer, []); + t.ok(ret.equals(expectedBounds), "returns expected bounds with multiple markers"); + + } + + function test_setOpacity(t) { + t.plan(1); + + layer = new OpenLayers.Layer.Markers('Test Layer'); + + var opacity = 0.1234; + + for (var i = 0; i < 12; i++) { + layer.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0), new OpenLayers.Icon())); + } + + layer.setOpacity(opacity); + + for (var i = 0; i < 4; i++) { + layer.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0), new OpenLayers.Icon())); + } + + var itWorks = false; + for (var i = 0; i < layer.markers.length; i++) { + itWorks = parseFloat(layer.markers[i].icon.imageDiv.style.opacity) == opacity; + if (!itWorks) { + break; + } + } + t.ok(itWorks, "setOpacity change markers opacity"); + } + + </script> +</head> +<body> + <div id="map" style="width: 1080px; height: 600px;"/> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/OSM.html b/misc/openlayers/tests/Layer/OSM.html new file mode 100644 index 0000000..fac471c --- /dev/null +++ b/misc/openlayers/tests/Layer/OSM.html @@ -0,0 +1,16 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + function test_clone(t) { + t.plan(1); + var layer = new OpenLayers.Layer.OSM(); + var clone = layer.clone(); + t.ok(clone instanceof OpenLayers.Layer.OSM, "clone is a Layer.OSM instance"); + } + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/PointGrid.html b/misc/openlayers/tests/Layer/PointGrid.html new file mode 100644 index 0000000..6fb6ae2 --- /dev/null +++ b/misc/openlayers/tests/Layer/PointGrid.html @@ -0,0 +1,232 @@ +<!DOCTYPE html> +<html> +<head> +<script src="../OLLoader.js"></script> +<script type="text/javascript"> + + function test_initialize(t) { + t.plan(1); + var layer = new OpenLayers.Layer.PointGrid(); + t.ok(layer instanceof OpenLayers.Layer.PointGrid, "instance created"); + layer.destroy(); + } + + function test_name(t) { + t.plan(1); + var layer = new OpenLayers.Layer.PointGrid({name: "foo"}); + t.eq(layer.name, "foo", "name set like every other property"); + layer.destroy(); + } + + function test_spacing(t) { + t.plan(7); + + var layer = new OpenLayers.Layer.PointGrid({ + isBaseLayer: true, + resolutions: [1], + maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50), + dx: 10, + dy: 10, + ratio: 1 + }); + + var map = new OpenLayers.Map({ + div: "map", + layers: [layer], + center: new OpenLayers.LonLat(0, 0), + zoom: 0 + }); + + t.eq(layer.features.length, 200, "200 features"); + + // set dx/dy together + layer.setSpacing(20); + t.eq(layer.dx, 20, "dx 20"); + t.eq(layer.dy, 20, "dy 20"); + t.eq(layer.features.length, 50, "50 features"); + + // set dx/dy independently + layer.setSpacing(50, 25); + t.eq(layer.dx, 50, "dx 50"); + t.eq(layer.dy, 25, "dy 25"); + t.eq(layer.features.length, 16, "16 features"); + + map.destroy(); + } + + function test_ratio(t) { + t.plan(3); + + var layer = new OpenLayers.Layer.PointGrid({ + isBaseLayer: true, + resolutions: [1], + maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50), + dx: 25, + dy: 25, + ratio: 1 + }); + + var map = new OpenLayers.Map({ + div: "map", + layers: [layer], + center: new OpenLayers.LonLat(0, 0), + zoom: 0 + }); + + t.eq(layer.features.length, 32, "32 features"); + + // increase ratio (1.5 -> 300 x 150) + layer.setRatio(1.5); + t.eq(layer.ratio, 1.5, "ratio 1.5"); + t.eq(layer.features.length, 72, "72 features"); + + map.destroy(); + } + + function test_maxFeatures(t) { + t.plan(3); + + var layer = new OpenLayers.Layer.PointGrid({ + isBaseLayer: true, + resolutions: [1], + maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50), + dx: 10, + dy: 10, + ratio: 1 + }); + + var map = new OpenLayers.Map({ + div: "map", + layers: [layer], + center: new OpenLayers.LonLat(0, 0), + zoom: 0 + }); + + t.eq(layer.features.length, 200, "200 features"); + + // limit maxFeatures + layer.setMaxFeatures(150); + t.eq(layer.maxFeatures, 150, "maxFeatures 150"); + t.ok(layer.features.length <= 150, "<= 150 features"); + + map.destroy(); + } + + function test_rotation(t) { + t.plan(6); + + var layer = new OpenLayers.Layer.PointGrid({ + isBaseLayer: true, + resolutions: [1], + maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50), + dx: 10, + dy: 10, + ratio: 1 + }); + + var map = new OpenLayers.Map({ + div: "map", + layers: [layer], + center: new OpenLayers.LonLat(0, 0), + zoom: 0 + }); + + function getRotation(layer) { + // grid starts at bottom left and goes up + var g0 = layer.features[0].geometry; + var g1 = layer.features[1].geometry; + // subtract 90 to get rotation of grid + return Math.atan2(g1.y - g0.y, g1.x - g0.x) * (180 / Math.PI) - 90; + } + + t.eq(layer.rotation, 0, "0 rotation"); + t.eq(getRotation(layer).toFixed(3), (0).toFixed(3), "0 grid") + + // rotate grid 25 degrees counter-clockwise + layer.setRotation(25); + t.eq(layer.rotation, 25, "25 rotation"); + t.eq(getRotation(layer).toFixed(3), (25).toFixed(3), "25 grid"); + + // rotate grid 45 degrees clockwise + layer.setRotation(-45); + t.eq(layer.rotation, -45, "-45 rotation"); + t.eq(getRotation(layer).toFixed(3), (-45).toFixed(3), "-45 grid"); + + map.destroy(); + } + + function test_origin(t) { + t.plan(7); + + var layer = new OpenLayers.Layer.PointGrid({ + isBaseLayer: true, + resolutions: [1], + maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50), + dx: 10, + dy: 10, + ratio: 1 + }); + + var map = new OpenLayers.Map({ + div: "map", + layers: [layer], + center: new OpenLayers.LonLat(0, 0), + zoom: 0 + }); + + var origin = layer.getOrigin(); + t.ok(map.getExtent().getCenterLonLat().equals(origin), "default is center of map extent"); + + var g0 = layer.features[0].geometry; + + t.eq((g0.x - origin.lon) % layer.dx, 0, "a) lattice aligned with origin x"); + t.eq((g0.y - origin.lat) % layer.dy, 0, "a) lattice aligned with origin y"); + + // set origin + layer.setOrigin(new OpenLayers.LonLat(-5, 12)); + origin = layer.getOrigin(); + t.eq(origin.lon, -5, "-5 origin x"); + t.eq(origin.lat, 12, "12 origin y"); + + g0 = layer.features[0].geometry; + t.eq((g0.x - origin.lon) % layer.dx, 0, "b) lattice aligned with origin x"); + t.eq((g0.y - origin.lat) % layer.dy, 0, "b) lattice aligned with origin y"); + + map.destroy(); + } + + function test_zoom(t) { + t.plan(2); + + var layer = new OpenLayers.Layer.PointGrid({ + isBaseLayer: true, + resolutions: [2, 1], + maxExtent: new OpenLayers.Bounds(-200, -100, 200, 100), + dx: 20, + dy: 20, + ratio: 1 + }); + + var map = new OpenLayers.Map({ + div: "map", + layers: [layer], + center: new OpenLayers.LonLat(0, 0), + zoom: 1, + zoomMethod: null + }); + + t.eq(layer.features.length, 50, "50 features at zoom 1"); + + map.zoomTo(0); + t.eq(layer.features.length, 200, "200 features at zoom 0") + + map.destroy(); + } + + +</script> +</head> +<body> +<div id="map" style="width:200px;height:100px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/PointTrack.html b/misc/openlayers/tests/Layer/PointTrack.html new file mode 100644 index 0000000..95b8ced --- /dev/null +++ b/misc/openlayers/tests/Layer/PointTrack.html @@ -0,0 +1,79 @@ +<html> +<head> +<script src="../OLLoader.js"></script> + <script type="text/javascript"> + + var name = "PointTrack Layer"; + + function test_Layer_PointTrack_constructor(t) { + t.plan(2); + + var layer = new OpenLayers.Layer.PointTrack(name); + t.ok(layer instanceof OpenLayers.Layer.PointTrack, "new OpenLayers.Layer.PointTrack returns correct object" ); + t.ok(layer.addNodes, "layer has an addNodes method"); + + } + + function test_Layer_PointTrack_addNodes(t) { + t.plan(11); + + var layer = new OpenLayers.Layer.PointTrack(name, + {dataFrom: OpenLayers.Layer.PointTrack.dataFrom.TARGET_NODE}); + + var point1 = new OpenLayers.Geometry.Point(-111.04, 45.68); + var sourceNode = new OpenLayers.Feature.Vector(point1); + var point2 = new OpenLayers.Geometry.Point(-112.34, 45.67); + var targetNode = new OpenLayers.Feature.Vector(point2, {foo: "bar"}); + layer.addNodes([sourceNode, targetNode]); + + t.eq(layer.features.length, 1, "OpenLayers.Layer.PointTrack.addNodes creates one feature from two vector point features"); + t.eq(layer.features[0].geometry.CLASS_NAME, "OpenLayers.Geometry.LineString", "The created feature has a LineString geometry"); + var geometry = layer.features[0].geometry; + t.eq(geometry.components[0].x, -111.04, "The x of the first point of the line equals the x of the first point added to the layer"); + t.eq(geometry.components[1].y, 45.67, "The y of the second point of the line equals the y of the second point added to the layer"); + t.eq(layer.features[0].attributes.foo, "bar", "OpenLayers.Layer.PointTrack.addNodes assigns the attributes of the target node correctly"); + + layer.dataFrom = OpenLayers.Layer.PointTrack.dataFrom.SOURCE_NODE; + + point1 = new OpenLayers.Geometry.Point(-123.54, 45.67); + sourceNode = new OpenLayers.Feature.Vector(point1, {foo: "bar"}); + point2 = new OpenLayers.Geometry.Point(-123.21, 45.32); + targetNode = new OpenLayers.Feature.Vector(point2); + layer.addNodes([sourceNode, targetNode]); + + t.eq(layer.features.length, 2, "added another two points, so the layer now has two features"); + t.eq(layer.features[1].attributes.foo, "bar", "OpenLayers.Layer.PointTrack.addNodes assigns the attributes of the source node correctly"); + + point1 = new OpenLayers.LonLat(-123.58, 45.69); + sourceNode = new OpenLayers.Feature(null, point1); + point2 = new OpenLayers.LonLat(-123.25, 45.37); + targetNode = new OpenLayers.Feature(null, point2); + sourceNode.data = {foo: "bar"}; + layer.addNodes([sourceNode, targetNode]); + + t.eq(layer.features.length, 3, "added another two points, this time from features, so the layer now has two features"); + t.eq(layer.features[2].geometry.components[0].x, -123.58, "The x of the first point of the line equals the x of the first point added to the layer"); + t.eq(layer.features[2].geometry.components[1].y, 45.37, "The y of the second point of the line equals the x of the second point added to the layer"); + t.eq(layer.features[2].data, sourceNode.data, "OpenLayers.Layer.PointTrack.addNodes assigns the data of the source node correctly"); + + } + + function test_Layer_PointTrack_destroy (t) { + t.plan(3); + layer = new OpenLayers.Layer.PointTrack(name); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + t.eq(layer.map.layers.length, 1, "layer added to the map successfully"); + layer.destroy(); + t.eq(layer.map, null, "layer.map is null after destroy"); + t.ok(!layer.renderer, "layer.renderer is falsey after destroy"); + } + + + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/SphericalMercator.html b/misc/openlayers/tests/Layer/SphericalMercator.html new file mode 100644 index 0000000..be94735 --- /dev/null +++ b/misc/openlayers/tests/Layer/SphericalMercator.html @@ -0,0 +1,126 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + function test_SphericalMercator_forwardMercator(t) { + t.plan(12); + var arctic = OpenLayers.Layer.SphericalMercator.forwardMercator(0, 85); + var antarctic = OpenLayers.Layer.SphericalMercator.forwardMercator(0, -85); + var hawaii = OpenLayers.Layer.SphericalMercator.forwardMercator(-180, 0); + var phillipines = OpenLayers.Layer.SphericalMercator.forwardMercator(180, 0); + var ne = OpenLayers.Layer.SphericalMercator.forwardMercator(180, 90); + var sw = OpenLayers.Layer.SphericalMercator.forwardMercator(-180, -90); + + t.eq(arctic.lon, 0, "Arctic longitude is correct"); + t.eq(Math.round(arctic.lat), 19971869, "Arctic latitude is correct"); + + t.eq(antarctic.lon, 0, "Antarctic longitude is correct"); + t.eq(Math.round(antarctic.lat), -19971869, "Antarctic latitude is correct"); + + t.eq(Math.round(hawaii.lat), 0, "Hawaiian lat is correct"); + t.eq(hawaii.lon, -20037508.34, "Hawaiian lon is correct"); + + t.eq(Math.round(phillipines.lat), 0, "Phillipines lat is correct"); + t.eq(phillipines.lon, 20037508.340, "Phillipines lon is correct"); + + // be kind and stay within the world instead of having +/- infinity lat + t.ok(ne.lat, 20037508.34, "NE lat is correct"); + t.eq(ne.lon, 20037508.34, "NE lon is correct"); + + t.eq(sw.lat, -20037508.34, "SW lat is correct"); + t.eq(sw.lon, -20037508.34, "SW lon is correct"); + } + + function test_sphericalMercator_inverseMercator(t) { + t.plan(4); + var sw = OpenLayers.Layer.SphericalMercator.inverseMercator(-20037508.34, -20037508.34); + var ne = OpenLayers.Layer.SphericalMercator.inverseMercator(20037508.34, 20037508.34); + t.eq(sw.lon, -180, "Southwest lon correct"); + t.eq(ne.lon, 180, "Northeast lon correct"); + + t.eq(sw.lat.toFixed(10), "-85.0511287798", "Southwest lat correct"); + t.eq(ne.lat.toFixed(10), "85.0511287798", "Northeast lat correct"); + } + + function strToFixed(str, dig) { + if(dig == undefined) { + dig = 5; + } + return str.replace(/(\d+\.\d+)/g, function(match) { + return parseFloat(match).toFixed(dig); + }); + } + + function test_SphericalMercator_to4326(t) { + t.plan(1); + var point = new OpenLayers.Geometry.Point(1113195, 2273031); + point.transform("EPSG:900913", "EPSG:4326"); + + t.eq(strToFixed(point.toString()), + strToFixed("POINT(10.000000828446318 20.000000618997227)"), + "point transforms from Spherical Mercator to EPSG:4326"); + } + + function test_SphericalMercator_addTransform(t) { + // this class should add two methods to the + // OpenLayers.Projection.transforms object + t.plan(4); + var wgs84 = OpenLayers.Projection.transforms["EPSG:4326"]; + t.ok(wgs84 instanceof Object, "EPSG:4326 exists in table"); + + var smerc = OpenLayers.Projection.transforms["EPSG:900913"]; + t.ok(smerc instanceof Object, "EPSG:900913 exists in table"); + + t.ok(typeof(wgs84["EPSG:900913"]) === "function", + "from EPSG:4326 to EPSG:900913 correctly defined"); + t.ok(typeof(smerc["EPSG:4326"]) === "function", + "from EPSG:900913 to EPSG:4326 correctly defined"); + } + + function test_equivalence(t) { + + // list of equivalent codes for web mercator + var codes = ["EPSG:900913", "EPSG:3857", "EPSG:102113", "EPSG:102100"]; + var len = codes.length; + + t.plan(len + (len * len)); + + var ggPoint = new OpenLayers.Geometry.Point(10, 20); + var smPoint = new OpenLayers.Geometry.Point(1113195, 2273031); + + var gg = new OpenLayers.Projection("EPSG:4326"); + + var i, proj, forward, inverse, other, j, equiv; + for (i=0, len=codes.length; i<len; ++i) { + proj = new OpenLayers.Projection(codes[i]); + + // confirm that forward/inverse work + forward = ggPoint.clone().transform(gg, proj); + t.eq( + strToFixed(forward.toString()), + strToFixed("POINT(1113194.9077777779 2273030.9266712805)"), + "transforms from EPSG:4326 to " + proj + ); + inverse = smPoint.clone().transform(proj, gg); + t.eq( + strToFixed(inverse.toString()), + strToFixed("POINT(10.000000828446318 20.000000618997227)"), + "transforms from " + proj + " to EPSG:4326" + ); + + // confirm that null transform works + for (j=i+1; j<len; ++j) { + other = new OpenLayers.Projection(codes[j]); + equiv = ggPoint.clone().transform(proj, other); + t.ok(proj.equals(other), proj + " and " + other + " are equivalent"); + t.ok(ggPoint.equals(equiv), "transform from " + proj + " to " + other + " preserves geometry"); + } + } + + } + + </script> +</head> +<body> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/TMS.html b/misc/openlayers/tests/Layer/TMS.html new file mode 100644 index 0000000..4ac629f --- /dev/null +++ b/misc/openlayers/tests/Layer/TMS.html @@ -0,0 +1,262 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var layer; + + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/"; + var options = {'layername':'basic', 'type':'png'}; + + + function test_Layer_TMS_constructor (t) { + t.plan( 1 ); + + layer = new OpenLayers.Layer.TMS(name, url, options); + t.ok( layer instanceof OpenLayers.Layer.TMS, "returns OpenLayers.Layer.TMS object" ); + } + + + + function test_Layer_TMS_clearTiles (t) { + t.plan( 1 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.TMS(name, url, options); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0)); + + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.clearGrid(); + + t.ok( layer.grid != null, "layer.grid does not get nullified" ); + map.destroy(); + } + + + function test_Layer_TMS_getTMSBounds(t) { + t.plan( 1 ); + + layer = new OpenLayers.Layer.TMS(name, url, options); + + var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)}; + var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)}; + layer.grid = [ [6, tr], + [bl, 7]]; + + var bounds = layer.getTilesBounds(); + + var testBounds = new OpenLayers.Bounds(1,2,3,4); + + t.ok( bounds.equals(testBounds), "getTMSBounds() returns correct bounds"); + + layer.grid = null; + } + + function test_Layer_TMS_getResolution(t) { + t.plan( 1 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.TMS(name, url, options); + map.addLayer(layer); + + map.zoom = 5; + + t.eq( layer.getResolution(), 0.0439453125, "getResolution() returns correct value"); + map.destroy(); + } + + function test_Layer_TMS_getZoomForExtent(t) { + t.plan( 2 ); + var bounds, zoom; + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.TMS(name, url, options); + map.addLayer(layer); + + bounds = new OpenLayers.Bounds(10,10,12,12); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 8, "getZoomForExtent() returns correct value"); + + bounds = new OpenLayers.Bounds(10,10,100,100); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 2, "getZoomForExtent() returns correct value"); + map.destroy(); + } + + + /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR + * + * -moveTo + * -insertColumn + * -insertRow + + function 07_Layer_TMS_moveTo(t) { + } + + function 08_Layer_TMS_insertColumn(t) { + } + + function 09_Layer_TMS_insertRow(t) { + } + + * + */ + function test_Layer_TMS_getURL(t) { + + t.plan(3); + + var map = new OpenLayers.Map('map', options); + var options = {'layername':'basic', 'type':'png'}; + layer = new OpenLayers.Layer.TMS(name, url, options); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 9); + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/192.png", "Tile URL is correct"); + + var layer2 = layer.clone(); + layer2.serviceVersion = "1.2.3"; + map.addLayer(layer2); + tileurl = layer2.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.2.3/basic/9/261/192.png", "TMS serviceVersion is correct"); + + layer.url = ["http://tilecache1/", "http://tilecache2/", "http://tilecache3/"]; + tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://tilecache1/1.0.0/basic/9/261/192.png", "Tile URL is deterministic"); + map.destroy(); + } + function test_Layer_TMS_Rounding(t) { + t.plan(1); + m = new OpenLayers.Map("map", {'maxExtent':new OpenLayers.Bounds(-122.6579,37.4901,-122.0738,37.8795)}); + layer = new OpenLayers.Layer.TMS( "TMS", + "http://labs.metacarta.com/wms-c/Basic.py/", {layername: 'basic', type:'png', resolutions:[0.000634956337608418], buffer: 2} ); + m.addLayer(layer); + m.zoomToMaxExtent(); + t.eq(layer.getURL(layer.grid[3][3].bounds), "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/0/1/1.png", "TMS tiles around rounded properly."); + m.destroy(); + } + + function test_Layer_TMS_serverResolutions(t) { + t.plan(2); + + var map = new OpenLayers.Map('map', { + resolutions: [13,11] + }); + + var layer = new OpenLayers.Layer.TMS('tc layer', '', options); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 1); + + var tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0)); + var level = parseInt(tileurl.split('/')[2]); + t.eq(map.getZoom(), level, "Tile zoom level is correct without serverResolutions"); + + layer.serverResolutions = [14,13,12,11,10]; + tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0)); + level = parseInt(tileurl.split('/')[2]); + var res = map.getResolution(); + var gotLevel = OpenLayers.Util.indexOf(layer.serverResolutions, res); + t.eq(gotLevel, level, "Tile zoom level is correct with serverResolutions"); + + map.destroy(); + } + + function test_zoomOffset(t) { + + t.plan(2); + + var offset, zoom; + + // test offset of 2 + offset = 2; + zoom = 3; + + var map = new OpenLayers.Map({ + div: "map" + }); + var layer = new OpenLayers.Layer.TMS("TMS", "", { + layername: "basic", + type: "png", + zoomOffset: offset + }); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), zoom); + + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(parseInt(tileurl.split("/")[2]), zoom + offset, "correct level for offset 2"); + + map.destroy(); + + // test offset of -1 + offset = -1; + zoom = 3; + + var map = new OpenLayers.Map({ + div: "map" + }); + var layer = new OpenLayers.Layer.TMS("TMS", "", { + layername: "basic", + type: "png", + zoomOffset: offset + }); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), zoom); + + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(parseInt(tileurl.split("/")[2]), zoom + offset, "correct level for offset -1"); + + map.destroy(); + } + + function test_Layer_TMS_setMap(t) { + + t.plan(3); + + var map = new OpenLayers.Map('map', options); + layer = new OpenLayers.Layer.TMS(name, url, options); + + t.eq(layer.tileOrigin, null, "Tile origin starts out null"); + layer.setMap(map); + + t.eq(layer.tileOrigin.lat, -90, "lat is -90"); + t.eq(layer.tileOrigin.lon, -180, "lon is -180"); + map.destroy(); + } + + function test_Layer_TMS_destroy (t) { + + t.plan( 3 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.TMS(name, url, options); + map.addLayer(layer); + layer.destroy(); + t.eq( layer.grid, null, "layer.grid is null after destroy" ); + t.eq( layer.tileSize, null, "layer.tileSize is null after destroy" ); + + + //test with tile creation + layer = new OpenLayers.Layer.TMS(name, url, options); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.destroy(); + + t.ok( layer.grid == null, "tiles appropriately destroyed"); + map.destroy(); + } + + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px;"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/Text.html b/misc/openlayers/tests/Layer/Text.html new file mode 100644 index 0000000..3bffe4c --- /dev/null +++ b/misc/openlayers/tests/Layer/Text.html @@ -0,0 +1,211 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var isMSIE = (navigator.userAgent.indexOf("MSIE") > -1); + var layer; + + var datafile = "./data_Layer_Text_textfile.txt"; + var datafile2 = "./data_Layer_Text_textfile_2.txt"; + var datafile_overflow = "./data_Layer_Text_textfile_overflow.txt"; + + // if this test is running in IE, different rules apply + if (isMSIE) { + datafile = "." + datafile; + datafile2 = "." + datafile2; + datafile_overflow = "." + datafile_overflow; + } + + function test_Layer_Text_constructor (t) { + t.plan( 5 ); + + layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile }); + layer.loadText(); + t.ok( layer instanceof OpenLayers.Layer.Text, "new OpenLayers.Layer.Text returns object" ); + t.eq( layer.location, datafile, "layer.location is correct" ); + var markers; + t.delay_call( 1, function() { + t.eq( layer.markers.length, 2, "marker length is correct" ); + var ll = new OpenLayers.LonLat(20, 10); + t.ok( layer.markers[0].lonlat.equals(ll), "first marker is correct" ); + t.eq( layer.markers[0].icon.url, 'http://boston.openguides.org/markers/ORANGE.png', "icon" ); + } ); + } + function test_Layer_Text_draw (t) { +// t.plan(5); + t.plan( 2 ); + layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile }); + t.ok( layer instanceof OpenLayers.Layer.Text, "new OpenLayers.Layer.Text returns object" ); + var 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.addLayer(layer); + t.eq( map.layers[1].name, layer.name, "Layer added to map okay" ); + t.delay_call( 1, function() { + map.setCenter(new OpenLayers.LonLat(0,0),0); + +/* + if (!isMozilla) + t.ok( true, "skipping element test outside of Mozilla"); + else + t.ok( map.layers[0].div.firstChild instanceof HTMLImageElement, "Marker added to div" ) + + t.eq( map.layers[0].div.firstChild.style.top, "219px", "Marker top set correctly" ) + t.eq( map.layers[0].div.firstChild.style.left, "273px", "Marker left set correctly" ) +*/ + });; + } + + function test_Layer_Text_moveTo(t) { + t.plan(16); + + temp = OpenLayers.Layer.Markers.prototype.moveTo; + + g_Bounds = {}; + g_ZoomChanged = {}; + g_Minor = {}; + var args = [g_Bounds, g_ZoomChanged, g_Minor]; + + OpenLayers.Layer.Markers.prototype.moveTo = + function(bounds, zoomChanged, minor) { + t.ok(bounds == g_Bounds, "correct bounds passed to Markers superclass"); + t.ok(zoomChanged == g_ZoomChanged, "correct zoomChanged passed to Markers superclass"); + t.ok(minor == g_Minor, "correct minor passed to Markers superclass"); + } + + var layer = { + 'loadText': function() { g_TextLoaded = true; } + }; + + //visibility true, loaded true + layer.visibility = true; + layer.loaded = true; + g_TextLoaded = false; + OpenLayers.Layer.Text.prototype.moveTo.apply(layer, args); + t.ok(g_TextLoaded == false, "text not loaded when visibility true, loaded true"); + + //visibility true, loaded false + layer.visibility = true; + layer.loaded = false; + g_TextLoaded = false; + OpenLayers.Layer.Text.prototype.moveTo.apply(layer, args); + t.ok(g_TextLoaded == true, "text is loaded when visibility true, loaded false"); + + //visibility false, loaded true + layer.visibility = false; + layer.loaded = true; + g_TextLoaded = false; + OpenLayers.Layer.Text.prototype.moveTo.apply(layer, args); + t.ok(g_TextLoaded == false, "text not loaded when visibility false, loaded true"); + + //visibility false, loaded false + layer.visibility = false; + layer.loaded = false; + g_TextLoaded = false; + OpenLayers.Layer.Text.prototype.moveTo.apply(layer, args); + t.ok(g_TextLoaded == false, "text not loaded when visibility false, loaded false"); + + OpenLayers.Layer.Markers.prototype.moveTo = temp; + } + + + + function test_Layer_Text_events (t) { + t.plan( 5 ); + layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile2 }); + var 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.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),0); + var event = {}; + t.delay_call( 1, function() { + t.ok(layer.markers[0].events, "First marker has an events object"); + t.eq(layer.markers[0].events.listeners['click'].length, 1, "Marker events has one object"); + layer.markers[0].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "Popup opened correctly"); + layer.markers[1].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "1st popup gone, 2nd Popup opened correctly"); + //Safari 3 separates style overflow into overflow-x and overflow-y + var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow'; + t.eq(map.popups[0].contentDiv.style[prop],"auto", "default Popup overflow correct"); + }); + } + function test_Layer_Text_overflow (t) { + t.plan( 4 ); + layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile_overflow }); + var 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.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),0); + var event = {}; + t.delay_call( 1, function() { + layer.markers[0].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "Popup opened correctly"); + //Safari 3 separates style overflow into overflow-x and overflow-y + var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow'; + t.eq(map.popups[0].contentDiv.style[prop],"auto", "Popup overflow read from file"); + layer.markers[1].events.triggerEvent('click', event); + t.eq(map.popups.length, 1, "1st popup gone, 2nd Popup opened correctly"); + //Safari 3 separates style overflow into overflow-x and overflow-y + var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow'; + t.eq(map.popups[0].contentDiv.style[prop],"hidden", "Popup overflow read from file"); + }); + } + function test_Layer_Text_events_nopopups (t) { + t.plan( 4 ); + layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile }); + var 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.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),0); + var event = {}; + t.delay_call( 1, function() { + t.ok(layer.markers[0].events, "First marker has an events object"); + t.eq(layer.markers[0].events.listeners['click'], undefined, "Marker events has no object"); + layer.markers[0].events.triggerEvent('click', event); + t.eq(map.popups.length, 0, "no popup on first marker"); + layer.markers[1].events.triggerEvent('click', event); + t.eq(map.popups.length, 0, "no popup on second marker"); + }); + } + function test_Layer_Text_loadend_Event(t) { + t.plan(2); + layer = new OpenLayers.Layer.Text('Test Layer', {location:datafile}); + t.delay_call(2, function() { + layer.events.register('loadend', layer, function() { + t.ok(true, "Loadend event fired"); + }); + layer.parseData({ + 'responseText':'' + }); + t.ok(true, "Parsing data didn't fail"); + }); + } + + function test_Layer_Text_destroy (t) { + t.plan( 1 ); + layer = new OpenLayers.Layer.Text('Test Layer'); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + layer.destroy(); + t.eq( layer.map, null, "layer.map is null after destroy" ); + } + + </script> +</head> +<body> + <div id="map" style="width:500px; height:500px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/TileCache.html b/misc/openlayers/tests/Layer/TileCache.html new file mode 100644 index 0000000..2bb88f5 --- /dev/null +++ b/misc/openlayers/tests/Layer/TileCache.html @@ -0,0 +1,203 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + + + + function test_Layer_TileCache_constructor (t) { + t.plan( 1 ); + + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/"; + var layername = "basic"; + var options = {'type':'png'}; + + var layer = new OpenLayers.Layer.TileCache(name, url, layername, options); + t.ok( layer instanceof OpenLayers.Layer.TileCache, "returns OpenLayers.Layer.TileCache object" ); + layer.destroy(); + } + + function test_Layer_TileCache_clone(t) { + t.plan(3); + + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/"; + var layername = "basic"; + var options = {'type':'png'}; + var layer = new OpenLayers.Layer.TileCache(name, url, layername, options); + + var clone = layer.clone(); + t.eq(layer.name, clone.name, "clone() correctly copy the 'name' property"); + t.eq(layer.url, clone.url, "clone() correctly copy the 'url' property"); + t.eq(layer.layername, clone.layername, "clone() correctly copy the 'layername' property"); + clone.destroy(); + layer.destroy(); + } + + function test_Layer_TileCache_clearTiles (t) { + t.plan( 1 ); + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/"; + var layername = "basic"; + var options = {'type':'png'}; + var layer = new OpenLayers.Layer.TileCache(name, url, layername, options); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0)); + + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.clearGrid(); + + t.ok( layer.grid != null, "layer.grid does not get nullified" ); + map.destroy(); + } + + + function test_Layer_TileCache_getTileCacheBounds(t) { + t.plan( 1 ); + + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/"; + var layername = "basic"; + var options = {'type':'png'}; + var layer = new OpenLayers.Layer.TileCache(name, url, layername, options); + + var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)}; + var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)}; + layer.grid = [ [6, tr], + [bl, 7]]; + + var bounds = layer.getTilesBounds(); + + var testBounds = new OpenLayers.Bounds(1,2,3,4); + + t.ok( bounds.equals(testBounds), "getTileCacheBounds() returns correct bounds") + + } + + function test_Layer_TileCache_getResolution(t) { + t.plan( 1 ); + + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/"; + var layername = "basic"; + var options = {'type':'png', maxResolution: 180/256}; + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.TileCache(name, url, layername, options); + map.addLayer(layer); + + map.zoom = 5; + + t.eq( layer.getResolution(), 0.02197265625, "getResolution() returns correct value"); + map.destroy(); + } + + function test_Layer_TileCache_getZoomForExtent(t) { + t.plan( 2 ); + var bounds, zoom; + + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/"; + var layername = "basic"; + var options = {'type':'png', maxResolution: 180/256}; + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.TileCache(name, url, layername, options); + map.addLayer(layer); + + bounds = new OpenLayers.Bounds(10,10,12,12); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 7, "getZoomForExtent() returns correct value"); + + bounds = new OpenLayers.Bounds(10,10,100,100); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 1, "getZoomForExtent() returns correct value"); + map.destroy(); + } + + function test_Layer_TileCache_getURL(t) { + + t.plan(2); + + var map = new OpenLayers.Map('map'); + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/"; + var layername = "basic"; + var options = {'layername':'basic', 'format':'image/jpg', maxResolution: 180/256}; + var layer = new OpenLayers.Layer.TileCache(name, url, layername, options); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 9); + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/basic/09/000/000/522/000/000/384.jpeg", "Tile URL is correct"); + + layer.url = ["http://tilecache1/", "http://tilecache2/", "http://tilecache3/"]; + tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://tilecache2/basic/09/000/000/522/000/000/384.jpeg", "Tile URL is deterministic"); + map.destroy(); + } + + function test_Layer_TileCache_serverResolutions(t) { + t.plan(2); + + var map = new OpenLayers.Map('map', { + resolutions: [13,11] + }); + + var layer = new OpenLayers.Layer.TileCache('tc layer', '', 'basic'); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 1); + + var tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0)); + var level = parseInt(tileurl.split('/')[2]); + t.eq(map.getZoom(), level, "Tile zoom level is correct without serverResolutions"); + + layer.serverResolutions = [14,13,12,11,10]; + tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0)); + level = parseInt(tileurl.split('/')[2]); + var gotLevel = OpenLayers.Util.indexOf(layer.serverResolutions, map.getResolution()); + t.eq(gotLevel, level, "Tile zoom level is correct with serverResolutions"); + + map.destroy(); + } + + function test_Layer_TileCache_destroy (t) { + + t.plan( 3 ); + + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/"; + var layername = "basic"; + var options = {'layername':'basic', 'format':'image/jpg', maxResolution: 180/256}; + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.TileCache(name, url, layername, options); + map.addLayer(layer); + layer.destroy(); + t.eq( layer.grid, null, "layer.grid is null after destroy" ); + t.eq( layer.tileSize, null, "layer.tileSize is null after destroy" ); + + + //test with tile creation + layer = new OpenLayers.Layer.TileCache(name, url, options); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.destroy(); + + t.ok( layer.grid == null, "tiles appropriately destroyed"); + map.destroy(); + } + + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/UTFGrid.html b/misc/openlayers/tests/Layer/UTFGrid.html new file mode 100644 index 0000000..872d796 --- /dev/null +++ b/misc/openlayers/tests/Layer/UTFGrid.html @@ -0,0 +1,131 @@ +<!DOCTYPE html> +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <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 map, layer; + function setUp() { + layer = new OpenLayers.Layer.UTFGrid({ + url: "../data/utfgrid/world_utfgrid/${z}/${x}/${y}.json", + isBaseLayer: true, + utfgridResolution: 4 + }); + map = new OpenLayers.Map({ + div: "map", + projection: "EPSG:900913", + layers: [layer], + center: [0, 0], + zoom: 1, + tileManager: null + }); + } + + function tearDown() { + map.destroy(); + map = null; + layer = null; + } + + function test_constructor(t) { + t.plan(4); + + var layer = new OpenLayers.Layer.UTFGrid({ + name: "foo", + url: "path/to/tiles/${z}/${x}/${y}", + utfgridResolution: 8 + }); + t.ok(layer instanceof OpenLayers.Layer.UTFGrid, "utfgrid instance"); + t.eq(layer.name, "foo", "layer name"); + t.eq(layer.url, "path/to/tiles/${z}/${x}/${y}", "layer url"); + t.eq(layer.utfgridResolution, 8, "layer utfgridResolution"); + + layer.destroy(); + + } + + function test_createBackBuffer(t) { + t.plan(1); + setUp(); + + var got; + try { + got = layer.createBackBuffer(); + } catch (e) { + got = e; + } finally { + tearDown(); + } + t.eq(got, undefined, "createBackBuffer returns undefined"); + } + + function test_clone(t) { + t.plan(3); + setUp(); + + var clone = layer.clone(); + t.ok(layer instanceof OpenLayers.Layer.UTFGrid, "utfgrid instance"); + t.eq(layer.url, "../data/utfgrid/world_utfgrid/${z}/${x}/${y}.json", "layer url"); + t.eq(layer.utfgridResolution, 4, "layer utfgridResolution"); + clone.destroy(); + + tearDown(); + } + + function test_getFeatureInfo(t) { + t.plan(2); + setUp(); + + // wait for tile loading to finish + t.delay_call(0.5, function() { + var loc = new OpenLayers.LonLat(-110, 45).transform("EPSG:4326", "EPSG:900913"); + var info = layer.getFeatureInfo(loc); + + t.eq(info.id, "207", "feature id"); + t.eq(info.data, {POP2005: 299846449, NAME: "United States"}, "feature data"); + + tearDown(); + }); + + } + + function test_getFeatureId(t) { + t.plan(2); + setUp(); + + // wait for tile loading to finish + t.delay_call(0.5, function() { + var ca = new OpenLayers.LonLat(-110, 55).transform("EPSG:4326", "EPSG:900913"); + var ru = new OpenLayers.LonLat(90, 75).transform("EPSG:4326", "EPSG:900913"); + + t.eq(layer.getFeatureId(ca), "24", "feature id for ca"); + t.eq(layer.getFeatureId(ru), "245", "feature id for ru"); + + tearDown(); + }); + + } + + </script> +</head> +<body> +<div id="map" style="height: 256px; width: 512px"></div> +</body> +</html> + diff --git a/misc/openlayers/tests/Layer/Vector.html b/misc/openlayers/tests/Layer/Vector.html new file mode 100644 index 0000000..aa3e2f8 --- /dev/null +++ b/misc/openlayers/tests/Layer/Vector.html @@ -0,0 +1,879 @@ +<html> +<head> +<script src="../OLLoader.js"></script> + <script type="text/javascript"> + + var name = "Vector Layer"; + + function test_Layer_Vector_constructor(t) { + t.plan(5); + + var options = {protocol: new OpenLayers.Protocol(), + strategies: [new OpenLayers.Strategy(), new OpenLayers.Strategy()]} + var layer = new OpenLayers.Layer.Vector(name, options); + + t.ok(layer instanceof OpenLayers.Layer.Vector, "new OpenLayers.Layer.Vector returns correct object" ); + t.eq(layer.name, name, "layer name is correctly set"); + t.ok(layer.renderer.CLASS_NAME, "layer has a renderer"); + + t.ok((layer.name == layer.strategies[0].layer.name) && + (layer.strategies[0].layer.name == layer.strategies[1].layer.name), + "setLayer was called on strategies"); + + options.renderers = [OpenLayers.Renderer.SVG, OpenLayers.Renderer.VML, OpenLayers.Renderer.Canvas]; + layer.destroy(); + layer = new OpenLayers.Layer.Vector(name, options); + t.ok(layer.renderer.CLASS_NAME, "layer has a renderer when providing a function"); + layer.destroy(); + } + + function test_Layer_Vector_assignRenderer(t) { + t.plan(2); + + // create a dummy class in the global name space + My = { + Custom: { + Renderer: { + Supported: OpenLayers.Class(OpenLayers.Renderer, { + supported: OpenLayers.Function.True, + CLASS_NAME: 'My.Custom.Renderer.Supported' + }), + NotSupported: OpenLayers.Class(OpenLayers.Renderer, { + supported: OpenLayers.Function.False, + CLASS_NAME: 'My.Custom.Renderer.NotSupported' + }) + } + } + }; + var layer = new OpenLayers.Layer.Vector('vector', { + renderers: [My.Custom.Renderer.NotSupported, + My.Custom.Renderer.Supported, + OpenLayers.Renderer.Canvas] + }); + t.eq(layer.renderer.CLASS_NAME, 'My.Custom.Renderer.Supported', + 'layer has a valid renderer'); + + var layer = new OpenLayers.Layer.Vector('vector', { + renderers: ['SVG', 'VML', 'Canvas', My.Custom.Renderer.Supported] + }); + t.ok(layer.renderer.CLASS_NAME != 'My.Custom.Renderer.Supported', + 'renderers can be strings as well'); + } + + function test_Layer_Vector_refresh(t) { + t.plan(4); + + var obj = {"an": "object"}; + + var log; + var layer = new OpenLayers.Layer.Vector(name, { + eventListeners: { + refresh: function(o) { + log.obj = o; + } + } + }); + inRange = false; + layer.calculateInRange = function() { + return inRange; + }; + + log = {}; + inRange = false; + layer.visibility = false; + layer.refresh(obj); + t.eq(log.obj, undefined, "[false, false] refresh not triggered"); + + log = {}; + inRange = true; + layer.visibility = false; + layer.refresh(obj); + t.eq(log.obj, undefined, "[true, false] refresh not triggered"); + + log = {}; + inRange = false; + layer.visibility = true; + layer.refresh(obj); + t.eq(log.obj, undefined, "[false, true] refresh not triggered"); + + log = {}; + inRange = true; + layer.visibility = true; + layer.refresh(obj); + t.ok(log.obj === obj, "[true, true] refresh triggered with correct arg"); + } + + function test_Layer_Vector_addFeatures(t) { + t.plan(8); + + var layer = new OpenLayers.Layer.Vector(name); + + var point = new OpenLayers.Geometry.Point(-111.04, 45.68); + var pointFeature = new OpenLayers.Feature.Vector(point); + + layer.preFeatureInsert = function(feature) { + t.ok(feature == pointFeature, "OpenLayers.Layer.Vector.addFeatures calls preFeatureInsert with the right arg"); + }; + layer.onFeatureInsert = function(feature) { + t.ok(feature == pointFeature, "OpenLayers.Layer.Vector.addFeatures calls onFeatureInsert with the right arg"); + }; + layer.events.register('beforefeatureadded', null, function(obj) { + t.ok(pointFeature == obj.feature, "OpenLayers.Layer.Vector.addFeatures triggers beforefeatureadded with correct feature passed to callback"); + }); + layer.events.register('featureadded', null, function(obj) { + t.ok(pointFeature == obj.feature, "OpenLayers.Layer.Vector.addFeatures triggers featureadded with correct feature passed to callback"); + }); + layer.events.register('featuresadded', null, function(obj) { + t.ok(pointFeature == obj.features[0], "OpenLayers.Layer.Vector.addFeatures triggers featuresadded with correct features passed to callback"); + }); + + layer.addFeatures([pointFeature]); + + t.eq(layer.features.length, 1, "OpenLayers.Layer.Vector.addFeatures adds something to the array"); + t.ok(layer.features[0] == pointFeature, "OpenLayers.Layer.Vector.addFeatures returns an array of features"); + + layer.preFeatureInsert = function(feature) { + t.fail("OpenLayers.Layer.Vector.addFeatures calls preFeatureInsert while it must not"); + }; + layer.onFeatureInsert = function(feature) { + t.fail("OpenLayers.Layer.Vector.addFeatures calls onFeatureInsert while it must not"); + }; + layer.events.register('beforefeatureadded', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.addFeatures triggers beforefeatureadded while it must not"); + }); + layer.events.register('featureadded', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.addFeatures triggers featureadded while it must not"); + }); + layer.events.register('featuresadded', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.addFeatures triggers featuresadded while it must not"); + }); + + layer.addFeatures([pointFeature], {silent: true}); + + var extent = layer.getDataExtent(); + t.eq(extent.toBBOX(), "-111.04,45.68,-111.04,45.68", "extent from getDataExtent is correct"); + } + + function test_Layer_Vector_getFeature(t) { + t.plan(13); + + var layer = new OpenLayers.Layer.Vector(name); + var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-111.04, 45.68)); + + t.ok(layer.getFeatureById(feature.id) == null, + "OpenLayers.Layer.Vector.getFeatureById returns null while the layer is empty"); + t.ok(layer.getFeatureByFid('my_fid') == null, + "OpenLayers.Layer.Vector.getFeatureByFid returns null while the layer is empty"); + + layer.addFeatures([feature]); + + t.ok(layer.getFeatureByFid('my_fid') == null, + "OpenLayers.Layer.Vector.getFeatureByFid returns null on unset feature fid"); + + feature.fid = 'my_fid'; + + t.ok(layer.getFeatureById(feature.id) == feature, + "OpenLayers.Layer.Vector.getFeatureById returns the correct feature"); + t.ok(layer.getFeatureByFid(feature.fid) == feature, + "OpenLayers.Layer.Vector.getFeatureByFid returns the correct feature"); + t.ok(layer.getFeatureById('some_id_that_does_not_exist') == null, + "OpenLayers.Layer.Vector.getFeatureById returns null on non-existing feature id"); + t.ok(layer.getFeatureByFid('some_fid_that_does_not_exist') == null, + "OpenLayers.Layer.Vector.getFeatureByFid returns null on non-existing feature fid"); + t.ok(layer.getFeatureById(feature.fid) == null, + "OpenLayers.Layer.Vector.getFeatureById ignores the feature fid"); + t.ok(layer.getFeatureByFid(feature.id) == null, + "OpenLayers.Layer.Vector.getFeatureByFid ignores the feature id"); + + t.ok(layer.getFeatureBy('id', feature.id) == feature, + "OpenLayers.Layer.Vector.getFeatureBy('id', ...) works like getFeatureById on existing feature id"); + t.ok(layer.getFeatureBy('id', 'some_id_that_does_not_exist') == null, + "OpenLayers.Layer.Vector.getFeatureBy('id', ...) works like getFeatureById on non-existing feature id"); + t.ok(layer.getFeatureBy('fid', feature.fid) == feature, + "OpenLayers.Layer.Vector.getFeatureBy('fid', ...) works like getFeatureByFid on existing feature fid"); + t.ok(layer.getFeatureBy('fid', 'some_fid_that_does_not_exist') == null, + "OpenLayers.Layer.Vector.getFeatureBy('fid', ...) works like getFeatureByFid on non-existing feature fid"); + } + + function test_Layer_Vector_getFeaturesByAttribute(t) { + t.plan( 9 ); + // setup layer + var layer = new OpenLayers.Layer.Vector(name); + + // feature_1 + var geometry_1 = new OpenLayers.Geometry.Point(-28.63, 153.64); + var attributes_1 = { + humpty: 'dumpty', + clazz: 1 + }; + var feature_1 = new OpenLayers.Feature.Vector(geometry_1, attributes_1); + feature_1.fid = 'f_01'; // to identify later + + // feature_2 + var geometry_2 = new OpenLayers.Geometry.Point(-27.48, 153.05); + var attributes_2 = { + // this feature has attribute humpty === undefined + clazz: '1' + }; + var feature_2 = new OpenLayers.Feature.Vector(geometry_2, attributes_2); + feature_2.fid = 'f_02'; // to identify later + + // feature_3 + var geometry_3 = new OpenLayers.Geometry.Point(-33.74, 150.3); + var attributes_3 = { + humpty: 'foobar', + clazz: 1 + }; + var feature_3 = new OpenLayers.Feature.Vector(geometry_3, attributes_3); + feature_3.fid = 'f_03'; // to identify later + + // Tests + + // don't find anything... no features added + // 1 test + t.ok(layer.getFeaturesByAttribute('humpty', 'dumpty').length === 0, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns an empty array while the layer is empty"); + + layer.addFeatures([feature_1, feature_2, feature_3]); + + // simple use case: find 1 feature with an attribute and matching value + // 2 tests + var dumptyResults = layer.getFeaturesByAttribute('humpty', 'dumpty'); + t.ok(dumptyResults.length === 1, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with one feature for attribute 'humpty' with value 'dumpty'"); + t.ok(dumptyResults[0].fid === 'f_01', + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct feature with attribute 'humpty' set to 'dumpty'"); + + // simple use case: find 1 feature with an attribute and matching value + // and respect data types + // 2 tests + var strOneResults = layer.getFeaturesByAttribute('clazz', '1'); + t.ok(strOneResults.length === 1, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with one feature for attribute 'clazz' with value '1' (a string)"); + t.ok(strOneResults[0].fid === 'f_02', + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct feature with attribute 'clazz' set to the string '1'"); + + // simple use case: find 2 features with an attribute and matching value + // and respect data types + // 2 tests + var numOneResults = layer.getFeaturesByAttribute('clazz', 1); + t.ok(numOneResults.length === 2, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with two features for attribute 'clazz' with value 1 (a number)"); + var bothFound = !!((numOneResults[0].fid === 'f_01' && numOneResults[1].fid === 'f_03') || (numOneResults[0].fid === 'f_03' && numOneResults[1].fid === 'f_01')); + t.ok(bothFound, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct features with attribute 'clazz' set to the number 1"); + + // advanced use case: find the 1 feature, that has an attribute not set + var undefined; + var humptyNotSet = layer.getFeaturesByAttribute('humpty', undefined); + t.ok(humptyNotSet.length === 1, + "OpenLayers.Layer.Vector.getFeaturesByAttribute can be used to find features that have certain attributes not set"); + t.ok(humptyNotSet[0].fid === 'f_02', + "OpenLayers.Layer.Vector.getFeaturesByAttribute found the correct featuren that has a certain attribute not set"); + } + + function test_Layer_Vector_getDataExtent(t) { + t.plan(1); + var layer = new OpenLayers.Layer.Vector(name); + + var point = new OpenLayers.Geometry.Point(-111.04, 45.68); + var pointFeature = new OpenLayers.Feature.Vector(point); + layer.addFeatures([pointFeature]); + var point = new OpenLayers.Geometry.Point(-111.04, 5.68); + var pointFeature = new OpenLayers.Feature.Vector(point); + layer.addFeatures([pointFeature]); + var extent = layer.getDataExtent(); + t.ok(extent.toBBOX() != layer.features[0].geometry.getBounds().toBBOX(), "extent from getDataExtent doesn't clobber first feature"); + } + + function test_Layer_Vector_getDataExtentEmpty(t) { + t.plan(1); + var layer = new OpenLayers.Layer.Vector(name); + layer.addFeatures([new OpenLayers.Feature.Vector(null), new OpenLayers.Feature.Vector(null)]); + var extent = layer.getDataExtent(); + t.eq(extent, null, "We expect null to be returned if there are no features with a geometry"); + } + + function test_Layer_Vector_removeFeatures(t) { + t.plan(17); + + var layer = new OpenLayers.Layer.Vector(name); + var features, log; + + var point1 = new OpenLayers.Geometry.Point(-111.04, 45.68); + var pointFeature1 = new OpenLayers.Feature.Vector(point1); + var point2 = new OpenLayers.Geometry.Point(-111.14, 45.78); + var pointFeature2 = new OpenLayers.Feature.Vector(point2); + + // 1 test + layer.addFeatures([pointFeature1, pointFeature2]); + features = layer.removeFeatures([pointFeature1]); + t.ok(layer.features.length == 1, "OpenLayers.Layer.Vector.removeFeatures removes a feature from the features array"); + + // 1 test + layer.addFeatures([pointFeature1.clone(), pointFeature2.clone()]); + layer.selectedFeatures.push(layer.features[0]); + layer.removeFeatures(layer.features[0]); + t.eq(layer.selectedFeatures, [], "Remove features removes selected features"); + + // 1 test + features = layer.removeFeatures(layer.features); + t.ok(layer.features.length == 0, + "OpenLayers.Layer.Vector.removeFeatures(layer.features) removes all feature from the features array"); + + // 4 tests + log = []; + layer.addFeatures([pointFeature1, pointFeature2]); + layer.events.register("featuresremoved", null, function(obj) { + log.push(obj); + }); + layer.removeFeatures(layer.features); + t.eq(log.length, 1, + "\"featuresremoved\" triggered once [0]"); + t.eq(log[0].features.length, 2, + "\"featuresremoved\" listener is passed two features [0]"); + t.ok(log[0].features[0] == pointFeature1, + "\"featuresremoved\" listener is passed the correct feature at index 0 [0]"); + t.ok(log[0].features[1] == pointFeature2, + "\"featuresremoved\" listener is passed the correct feature at index 1 [0]"); + layer.events.remove("featuresremoved"); + + // 4 tests + log = []; + layer.addFeatures([ + pointFeature1, pointFeature2, + pointFeature1.clone(), pointFeature2.clone() + ]); + layer.selectedFeatures.push(pointFeature1); + layer.selectedFeatures.push(pointFeature2); + layer.events.register("featuresremoved", null, function(obj) { + log.push(obj); + }); + layer.removeFeatures(layer.selectedFeatures); + t.eq(log.length, 1, + "\"featuresremoved\" triggered once [1]"); + t.eq(log[0].features.length, 2, + "\"featuresremoved\" listener is passed two features [1]"); + t.ok(log[0].features[0] == pointFeature1, + "\"featuresremoved\" listener is passed the correct feature at index 0 [1]"); + t.ok(log[0].features[1] == pointFeature2, + "\"featuresremoved\" listener is passed the correct feature at index 1 [1]"); + layer.events.remove("featuresremoved"); + layer.removeFeatures(layer.features); + + // 6 tests + layer.events.register('beforefeatureremoved', null, function(obj) { + t.ok(pointFeature1 == obj.feature, + "OpenLayers.Layer.Vector.removeFeatures triggers beforefeatureremoved with correct feature passed to callback"); + }); + layer.events.register('featureremoved', null, function(obj) { + t.ok(pointFeature1 == obj.feature, + "OpenLayers.Layer.Vector.removeFeatures triggers featureremoved with correct feature passed to callback"); + }); + layer.events.register('featuresremoved', null, function(obj) { + t.ok(pointFeature1 == obj.features[0], + "OpenLayers.Layer.Vector.removeFeatures triggers featuresremoved with correct features passed to callback"); + }); + layer.addFeatures([pointFeature1]); + layer.removeFeatures([pointFeature1]); + layer.addFeatures([pointFeature1]); + layer.removeFeatures(layer.features); + + // 0 test + layer.events.register('beforefeatureremoved', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.removeFeatures triggers beforefeatureremoved while it must not"); + }); + layer.events.register('featureremoved', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.removeFeatures triggers featureremoved while it must not"); + }); + layer.events.register('featuresremoved', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.removeFeatures triggers featuresremoved while it must not"); + }); + layer.addFeatures([pointFeature1]); + layer.removeFeatures([pointFeature1], {silent: true}); + } + + function test_Layer_Vector_drawFeature(t) { + t.plan(7); + var layer = new OpenLayers.Layer.Vector("Test Layer", {isBaseLayer: true}); + var map = new OpenLayers.Map('map', { + maxExtent: new OpenLayers.Bounds(-100, -100, 100, 100) + }); + map.addLayer(layer); + var geometry = new OpenLayers.Geometry.Point(10, 10); + var feature = new OpenLayers.Feature.Vector(geometry); + + var f, s; + + // Bogus layer renderer needs some methods + // for functional tests. + layer.drawn = true; + layer.renderer = { + drawFeature: function(feature, style) { + f = feature; + s = style; + }, + root: document.createElement("div"), + destroy: function() { }, + eraseFeatures: function() {}, + setExtent: function() {} + }; + + + layer.drawFeature(feature); + t.ok(geometry.equals(f.geometry), + "calls layer.renderer.drawFeature() with feature.geometry"); + + feature.style = {foo: "bar"}; + layer.drawFeature(feature); + t.eq(feature.style, s, + "calls layer.renderer.drawFeature() with feature.style"); + + feature.style = null; + layer.style = {foo: "bar"}; + layer.drawFeature(feature); + t.eq(layer.style.foo, s.foo, + "given null feature style, uses layer style"); + + feature.style = {foo1: "bar1"}; + layer.style = {foo2: "bar2"}; + var customStyle = {foo: "bar"}; + layer.drawFeature(feature, customStyle); + t.eq(customStyle.foo, s.foo, + "given a custom style, renders with that"); + + // the real renderer's drawFeature method is tested in Renderer.html + layer.renderer.drawFeature = function(feature) { + return(feature.geometry.getBounds().intersectsBounds(map.getExtent())); + } + // reset the drawn to null as if the layer had never been rendered + layer.drawn = null; + + layer.drawFeature(feature); + t.ok(true, "Trying to draw a feature on an not drawn layer doesn't throw any error."); + + layer.addFeatures([feature]); + + map.setCenter(new OpenLayers.Bounds(0, 0, 0, 0), 6); + t.ok(layer.unrenderedFeatures[feature.id], "Did not render feature outside the viewport."); + map.panTo(new OpenLayers.LonLat(10, 10)); + t.ok(!layer.unrenderedFeatures[feature.id], "Rendered feature inside the viewport."); + + layer.features = []; + } + + function test_deleted_state(t) { + t.plan(9); + + var map = new OpenLayers.Map("map"); + var layer = new OpenLayers.Layer.Vector(); + map.addLayer(layer); + var feature = new OpenLayers.Feature.Vector( + new OpenLayers.Geometry.Point(10, 10) + ); + var log; + layer.renderer = { + drawFeature: function(f, s) { + log = { + feature: f, + style: s + }; + }, + destroy: function() {} + }; + + // draw feature with no state + layer.drawn = true; + layer.drawFeature(feature); + t.ok(log.feature === feature, "[no state] drawFeature called with correct feature"); + t.ok(log.style.display !== "none", "[no state] drawFeature called with style display not none"); + + // draw feature with delete style + feature.state = OpenLayers.State.DELETE; + layer.drawFeature(feature); + t.ok(log.feature === feature, "[delete] drawFeature called with correct feature"); + t.eq(log.style.display, "none", "[delete] drawFeature called with style display none"); + + // undelete the feature and redraw + delete feature.state; + delete feature.renderIntent; + layer.drawFeature(feature); + t.ok(log.feature === feature, "[undelete] drawFeature called with correct feature"); + t.ok(log.style.display !== "none", "[undelete] drawFeature called with style display not none"); + + // change deleted style + layer.styleMap.styles["delete"] = new OpenLayers.Style({fillOpacity: 0.1}); + + // draw feature with delete style + feature.state = OpenLayers.State.DELETE; + layer.drawFeature(feature); + t.ok(log.feature === feature, "[draw deleted] drawFeature called with correct feature"); + t.ok(log.style.display !== "none", "[draw deleted] drawFeature called with style display not none"); + t.eq(log.style.fillOpacity, 0.1,"[draw deleted] drawFeature called with correct fill opacity"); + + + } + + function test_Layer_Vector_eraseFeatures(t) { + t.plan(2); + var layer = new OpenLayers.Layer.Vector("Test Layer"); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + var geometry = new OpenLayers.Geometry.Point(10, 10); + var feature = new OpenLayers.Feature.Vector(geometry); + + var f; + layer.renderer = { + eraseFeatures: function(features) { + f = features[0]; + }, + destroy: function() { } + }; + + layer.eraseFeatures([feature]); + t.ok(f, "calls layer.renderer.eraseFeatures"); + t.ok(geometry.equals(f.geometry), + "calls layer.renderer.eraseFeatures() given an array of features"); + } + + function test_Layer_Vector_destroyFeatures (t) { + t.plan(8); + var layer = new OpenLayers.Layer.Vector(name); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + var features = [], i; + for (i = 0; i < 5; i++) { + features.push(new OpenLayers.Feature.Vector( + new OpenLayers.Geometry.Point(0,0))); + } + layer.addFeatures(features); + t.eq(layer.features.length, 5, "addFeatures adds 5 features"); + layer.selectedFeatures.push(features[0]); + layer.destroyFeatures(); + t.eq(layer.features.length, 0, "destroyFeatures triggers removal"); + t.eq(layer.selectedFeatures, [], "Destroy features removes selected features"); + var allDestroyed = true; + for (i = 0; i < 5; i++) { + if(features[i].geometry) { + allDestroyed = false; + } + } + t.ok(allDestroyed, "destroyFeatures actually destroys features"); + features = []; + for (i = 0; i < 5; i++) { + features.push(new OpenLayers.Feature.Vector( + new OpenLayers.Geometry.Point(0,0))); + } + layer.addFeatures(features); + layer.selectedFeatures.push(features[0]); + layer.selectedFeatures.push(features[1]); + layer.destroyFeatures([features[0], features[1]]); + t.eq(layer.features.length, 3, "destroyFeatures removes appropriate features"); + t.eq(layer.selectedFeatures, [], "destroyFeatures removes appropriate selected features"); + t.eq(features[0].geometry, null, "destroyFeatures destroys feature 0"); + t.eq(features[1].geometry, null, "destroyFeatures destroys feature 1"); + } + + function test_Layer_Vector_destroy (t) { + t.plan(6); + + var options = {protocol: new OpenLayers.Protocol(), + strategies: [new OpenLayers.Strategy(), new OpenLayers.Strategy()]} + var layer = new OpenLayers.Layer.Vector(name, options); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + layer.destroy(); + t.eq(layer.map, null, "layer.map is null after destroy"); + t.ok(!layer.renderer, "layer.renderer is falsey"); + var err; + try { + layer.getFeatureFromEvent({target: "map"}); + } catch (ex) { + err = ex; + } + t.ok(err, "Error thrown when calling getFeatureFromEvent on destroyed layer"); + + t.eq(layer.protocol, null, "layer.protocol is null after destroy"); + t.eq(layer.strategies, null, "layer.strategies is null after destroy"); + + // test that we can call layer.destroy a second time without trouble + try { + layer.destroy(); + layer.destroy(); + t.ok(true, "layer.destroy called twice without any issues"); + } catch(err) { + t.fail("calling layer.destroy twice triggers exception: " + err + " in " + err.fileName + " line " + err.lineNumber); + } + + } + + function test_Layer_Vector_clone(t) { + t.plan(5); + var original = new OpenLayers.Layer.Vector(name, {dummyOption: "foo"}); + original.addFeatures([new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2), {foo: "bar"})]); + var clone = original.clone(); + t.ok(clone instanceof OpenLayers.Layer.Vector, "clone is an instance of OpenLayers.Layer.Vector"); + t.ok(clone.name, original.name, "clone has the same name as the original"); + t.ok(clone.features[0] != original.features[0], "clone's feature does not equal the original's feature"); + t.eq(clone.features[0].attributes.foo, original.features[0].attributes.foo, "clone's feature has the same attributes as the original's feature"); + t.eq(clone.dummyOption, original.dummyOption, "clone's dummyOption equals the original's dummy option"); + } + + function test_Layer_Vector_externalGraphic(t) { + t.plan(11); + var layer = new OpenLayers.Layer.Vector("Test Layer", {isBaseLayer: true}); + var renderer = layer.renderer; + var map = new OpenLayers.Map('map'); + map.addLayers([layer]); + + var geometryX = 10; + var geometryY = 10; + var geometry = new OpenLayers.Geometry.Point(geometryX, geometryY); + var feature = new OpenLayers.Feature.Vector(geometry); + + map.zoomToMaxExtent(); + + var customStyle1 = new Object({ + externalGraphic: 'test.png', + pointRadius: 10 + }); + var customStyle2 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 12 + }); + var customStyle3 = new Object({ + externalGraphic: 'test.png', + graphicHeight: 14 + }); + var customStyle4 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 24, + graphicHeight: 16 + }); + var customStyle5 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 24, + graphicOpacity: 1 + }); + var customStyle6 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 24, + graphicHeight: 16, + graphicXOffset: -24, + graphicYOffset: -16 + }); + + var root = renderer.vectorRoot; + if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.SVG') { + feature.style = customStyle1; + layer.drawFeature(feature); + t.eq(root.firstChild.getAttributeNS(null, 'width'), + (2*customStyle1.pointRadius).toString(), + "given a pointRadius, width equals 2*pointRadius"); + t.eq(root.firstChild.getAttributeNS(null, 'height'), + (2*customStyle1.pointRadius).toString(), + "given a pointRadius, height equals 2*pointRadius"); + feature.style = customStyle2; + layer.drawFeature(feature); + t.eq(root.firstChild.getAttributeNS(null, 'width'), + root.firstChild.getAttributeNS(null, 'height'), + "given a graphicWidth, width equals height"); + t.eq(root.firstChild.getAttributeNS(null, 'width'), + customStyle2.graphicWidth.toString(), + "width is set correctly"); + feature.style = customStyle3; + layer.drawFeature(feature); + t.eq(root.firstChild.getAttributeNS(null, 'height'), + root.firstChild.getAttributeNS(null, 'width'), + "given a graphicHeight, height equals width"); + t.eq(root.firstChild.getAttributeNS(null, 'height'), + customStyle3.graphicHeight.toString(), + "height is set correctly"); + feature.style = customStyle4; + layer.drawFeature(feature); + t.eq(root.firstChild.getAttributeNS(null, 'height'), + customStyle4.graphicHeight.toString(), + "given graphicHeight and graphicWidth, both are set: height"); + t.eq(root.firstChild.getAttributeNS(null, 'width'), + customStyle4.graphicWidth.toString(), + "given graphicHeight and graphicWidth, both are set: width"); + feature.style = customStyle5; + layer.drawFeature(feature); + // we use startsWith here as some browsers (at least Safari 3 and FireFox 4) + // do not append a semi-colon to the opacity string + t.ok(OpenLayers.String.startsWith( + root.firstChild.getAttributeNS(null, 'style'), + "opacity: " + customStyle5.graphicOpacity.toString()), + "graphicOpacity correctly set"); + feature.style = customStyle6; + layer.drawFeature(feature); + var x = geometryX / renderer.getResolution() + renderer.left; + var y = geometryY / renderer.getResolution() - renderer.top; + // SVG setStyle() gets x and y using getAttributeNS(), which returns + // a value with only 3 decimal digits. To mimic this we use toFixed(3) here + x = x.toFixed(3); + y = y.toFixed(3); + // toFixed() returns a string + x = parseFloat(x); + y = parseFloat(y); + t.eq(root.firstChild.getAttributeNS(null, 'x'), + (x + customStyle6.graphicXOffset).toFixed().toString(), + "graphicXOffset correctly set"); + t.eq(root.firstChild.getAttributeNS(null, 'y'), + (-y + customStyle6.graphicYOffset).toFixed().toString(), + "graphicYOffset correctly set"); + } + if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.VML') { + feature.style = customStyle1; + layer.drawFeature(feature); + t.eq(root.firstChild.style.width, + (2*customStyle1.pointRadius).toString()+'px', + "given a pointRadius, width equals 2*pointRadius"); + t.eq(root.firstChild.style.height, + (2*customStyle1.pointRadius).toString()+'px', + "given a pointRadius, height equals 2*pointRadius"); + feature.style = customStyle2; + layer.drawFeature(feature); + t.eq(root.firstChild.style.width, + root.firstChild.style.height, + "given a graphicWidth, width equals height"); + t.eq(root.firstChild.style.width, + customStyle2.graphicWidth.toString()+'px', + "width is set correctly"); + feature.style = customStyle3; + layer.drawFeature(feature); + t.eq(root.firstChild.style.height, + root.firstChild.style.width, + "given a graphicHeight, height equals width"); + t.eq(root.firstChild.style.height, + customStyle3.graphicHeight.toString()+'px', + "height is set correctly"); + feature.style = customStyle4; + layer.drawFeature(feature); + var left = parseInt(root.firstChild.style.left); + var top = parseInt(root.firstChild.style.top); + t.eq(root.firstChild.style.height, + customStyle4.graphicHeight.toString()+'px', + "given graphicHeight and graphicWidth, both are set: height"); + t.eq(root.firstChild.style.width, + customStyle4.graphicWidth.toString()+'px', + "given graphicHeight and graphicWidth, both are set: width"); + feature.style = customStyle5; + layer.renderer.clear(); + layer.drawFeature(feature); + var fill = root.firstChild.getElementsByTagName("v:fill")[0]; + var opacity; + if(fill) { + opacity = fill.getAttribute('opacity'); + } + if(opacity === undefined) { + fill = root.firstChild.getElementsByTagName("fill")[0]; + opacity = fill.getAttribute('opacity'); + } + t.eq(opacity, + customStyle5.graphicOpacity, + "graphicOpacity correctly set"); + feature.style = customStyle6; + layer.drawFeature(feature); + var offsetLeft = parseInt(root.firstChild.style.left); + var offsetTop = parseInt(root.firstChild.style.top); + t.eq((offsetLeft-left)*2, customStyle6.graphicXOffset, "graphicXOffset correctly set"); + t.eq((top-offsetTop)*2, customStyle6.graphicYOffset, "graphicYOffset correctly set"); + + } + } + + function test_removeLayer_drawFeature(t) { + // test behaviour when features are redrawn while + // the layer has been removed from the map + + t.plan(1); + + // set up + + var map, layer, feature; + + map = new OpenLayers.Map("map"); + map.addLayer(new OpenLayers.Layer("base", {isBaseLayer: true})); + + layer = new OpenLayers.Layer.Vector("vector"); + map.addLayer(layer); + + map.zoomToMaxExtent(); + + feature = new OpenLayers.Feature.Vector( + new OpenLayers.Geometry.Point(1.0, 1.0)); + layer.addFeatures(feature); + + // test + + map.removeLayer(layer); + layer.drawFeature(feature); + layer.drawFeature(feature); + map.addLayer(layer); + + var count = 0, node; + while(node = document.getElementById(feature.geometry.id)) { + node.parentNode.removeChild(node); + count++; + } + + t.eq(count, 1, "one geometry added, one geometry removed"); + + // tear down + + map.destroy(); + } + + function test_vectorBeforeFeatureAddedVeto(t) { + t.plan( 4 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.Vector(""); + map.addLayer(layer); + var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0)); + layer.addFeatures([feature]); + + var addedFeatures = []; + var beforefeatureadded_veto = function(evt) { return false; }; + layer.events.register("beforefeatureadded", layer, beforefeatureadded_veto); + layer.events.register("featuresadded", layer, function(evt) { + if (evt.features) { + for (var i = 0; i < evt.features.length; i++) { + addedFeatures.push(evt.features[i]); + } + } + }); + + var blankFeatures = [ + new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0)), + new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0))]; + layer.addFeatures(blankFeatures); + + t.eq(layer.features.length, 1, + "features not added to layer after beforefeatureadded veto"); + t.eq(addedFeatures.length, 0, + "no features sent to featuresadded on feature veto"); + + addedFeatures = []; + + layer.events.unregister("beforefeatureadded", layer, beforefeatureadded_veto); + beforefeatureadded_veto = function(evt) { return true; }; + layer.events.register("beforefeatureadded", layer, beforefeatureadded_veto); + + layer.addFeatures(blankFeatures); + + t.eq(layer.features.length, 3, + "features added to layer as expected"); + t.eq(addedFeatures.length, 2, + "featuresadded event received expected number of features"); + } + + + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/Vector/RootContainer.html b/misc/openlayers/tests/Layer/Vector/RootContainer.html new file mode 100644 index 0000000..aa92923 --- /dev/null +++ b/misc/openlayers/tests/Layer/Vector/RootContainer.html @@ -0,0 +1,63 @@ +<html> +<head> + <script src="../../OLLoader.js"></script> + <script type="text/javascript"> + var layer, map; + + function test_RootContainer_collectResetRoots(t) { + + map = new OpenLayers.Map("map"); + var layer1 = new OpenLayers.Layer.Vector("layer1"); + var layer2 = new OpenLayers.Layer.Vector("layer2"); + layer = new OpenLayers.Layer.Vector.RootContainer("layer_1_2", { + layers: [layer1, layer2] + }); + + // we cannot test this with a renderer that does not hava a rendererRoot + var plan = layer.renderer.rendererRoot ? 4 : 0; + t.plan(plan); + if(plan == 0) { + return; + } + + var numRoots = layer.renderer.rendererRoot.childNodes.length; + + // addLayers will call setMap() for layer, which will call collectRoots() + map.addLayers([layer1, layer2, layer]); + t.eq(layer.renderer.rendererRoot.childNodes.length, numRoots * 3, "layer has correct number of renderer roots"); + t.eq(layer1.renderer.rendererRoot.childNodes.length, 0, "layer1 has no own renderer root"); + + layer.resetRoots(); + t.eq(layer.renderer.rendererRoot.childNodes.length, numRoots, "roots removed from container"); + t.eq(layer1.renderer.rendererRoot.childNodes.length, numRoots, "root re-added to original layer"); + } + + function test_RootContainer_getFeatureFromEvent(t) { + t.plan(2); + var map = new OpenLayers.Map("map"); + var layer1 = new OpenLayers.Layer.Vector("layer1"); + var layer2 = new OpenLayers.Layer.Vector("layer2"); + layer = new OpenLayers.Layer.Vector.RootContainer("layer_1_2", { + layers: [layer1, layer2] + }); + map.addLayers([layer1, layer2, layer]); + var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,1)); + var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,0)); + layer1.addFeatures(feature1); + layer2.addFeatures(feature2); + t.eq(layer.getFeatureFromEvent({ + srcElement: { + _featureId: feature1.id + } + }).id, feature1.id, "feature from layer1 found"); + t.eq(layer.getFeatureFromEvent({srcElement: { + _featureId: feature2.id + }}).id, feature2.id, "feature from layer2 found"); + } + + </script> +</head> +<body> + <div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/WMS.html b/misc/openlayers/tests/Layer/WMS.html new file mode 100644 index 0000000..b990f07 --- /dev/null +++ b/misc/openlayers/tests/Layer/WMS.html @@ -0,0 +1,583 @@ +<html> +<head> + <script type="text/javascript">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script> + <script src='http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAjpkAC9ePGem0lIq5XcMiuhR_wWLPFku8Ix9i2SXYRVK3e45q1BQUd_beF8dtzKET_EteAjPdGDwqpQ'></script> + <script type="text/javascript">window.alert = oldAlert;</script> +<script src="../OLLoader.js"></script> + <script type="text/javascript"> + // turn off animation frame handling, so we can check img urls in tests + delete OpenLayers.Layer.Grid.prototype.queueTileDraw; + + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var layer; + + var name = 'Test Layer'; + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + var params = { map: '/mapdata/vmap_wms.map', + layers: 'basic', + format: 'image/jpeg'}; + + function test_Layer_WMS_constructor (t) { + t.plan( 15 ); + + var trans_format = "image/png"; + if (OpenLayers.Util.alphaHack()) { trans_format = "image/gif"; } + + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.WMS(name, url, params); + t.ok( layer instanceof OpenLayers.Layer.WMS, "new OpenLayers.Layer.WMS returns object" ); + t.eq( layer.url, "http://octo.metacarta.com/cgi-bin/mapserv", "layer.url is correct (HTTPRequest inited)" ); + t.eq( layer.params.MAP, "/mapdata/vmap_wms.map", "params passed in correctly uppercased" ); + + t.eq( layer.params.SERVICE, "WMS", "default params correclty uppercased and copied"); + + t.eq(layer.isBaseLayer, true, "no transparency setting, wms is baselayer"); + + params.TRANSPARENT = "true"; + var layer2 = new OpenLayers.Layer.WMS(name, url, params); + t.eq(layer2.isBaseLayer, false, "transparency == 'true', wms is not baselayer"); + + params.TRANSPARENT = "TRUE"; + var layer3 = new OpenLayers.Layer.WMS(name, url, params); + t.eq(layer3.isBaseLayer, false, "transparency == 'TRUE', wms is not baselayer"); + t.eq(layer3.params.FORMAT, trans_format, "transparent = TRUE causes non-image/jpeg format"); + + params.TRANSPARENT = "TRuE"; + var layer4 = new OpenLayers.Layer.WMS(name, url, params); + t.eq(layer4.isBaseLayer, false, "transparency == 'TRuE', wms is not baselayer"); + t.eq(layer4.params.FORMAT, trans_format, "transparent = TRuE causes non-image/jpeg format"); + + params.TRANSPARENT = true; + var layer5 = new OpenLayers.Layer.WMS(name, url, params); + t.eq(layer5.isBaseLayer, false, "transparency == true, wms is not baselayer"); + t.eq(layer5.params.FORMAT, trans_format, "transparent = true causes non-image/jpeg format"); + + params.TRANSPARENT = false; + var layer6 = new OpenLayers.Layer.WMS(name, url, params); + t.eq(layer6.isBaseLayer, true, "transparency == false, wms is baselayer"); + + params.TRANSPARENT = true; + var layer7 = new OpenLayers.Layer.WMS(name, url, params, {noMagic: true}); + t.eq(layer7.params.FORMAT, "image/jpeg", "When using noMagic true image/jpeg will not be automagically switched to image/png or image/gif if transparent"); + + params.TRANSPARENT = true; + var layer8 = new OpenLayers.Layer.WMS(name, url, params, {noMagic: true}); + t.eq(layer8.isBaseLayer, true, "When using noMagic then transparent means the wms layer is not automagically changed to not being a baselayer"); + + params.TRANSPARENT = false; + + } + + function test_Layer_WMS_addtile (t) { + t.plan( 6 ); + + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.WMS(name, url, params); + var map = new OpenLayers.Map('map', {tileManager: null}); + map.addLayer(layer); + var pixel = new OpenLayers.Pixel(5,6); + var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel); + tile.draw(); + + var img = tile.imgDiv; + var tParams = OpenLayers.Util.extend({}, + OpenLayers.Util.upperCaseObject(params)); + tParams = OpenLayers.Util.extend(tParams, { + BBOX: [1,2,3,4], + WIDTH: "256", HEIGHT: "256" + }); + t.eq( tile.url, + layer.getFullRequestString(tParams), + "image src is created correctly via addtile" ); + t.eq( tile.getTile().style.top, "6px", "image top is set correctly via addtile" ); + t.eq( tile.getTile().style.left, "5px", "image top is set correctly via addtile" ); + + var firstChild = layer.div.firstChild; + t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" ); + t.ok( firstChild == img, "div first child is correct image object" ); + t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." ); + map.destroy(); + } + + function test_Layer_WMS_bboxEncoding (t) { + t.plan( 6 ); + + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.WMS(name, url, params, {encodeBBOX:true}); + var map = new OpenLayers.Map('map', {tileManager: null}); + map.addLayer(layer); + var pixel = new OpenLayers.Pixel(5,6); + var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel); + tile.draw(); + + var img = tile.imgDiv; + var tParams = OpenLayers.Util.extend({}, + OpenLayers.Util.upperCaseObject(params)); + tParams = OpenLayers.Util.extend(tParams, { + BBOX: "1,2,3,4", + WIDTH: "256", HEIGHT: "256" + }); + t.eq( tile.url, + layer.getFullRequestString(tParams), + "image src is created correctly via addtile" ); + t.eq( tile.getTile().style.top, "6px", "image top is set correctly via addtile" ); + t.eq( tile.getTile().style.left, "5px", "image top is set correctly via addtile" ); + + var firstChild = layer.div.firstChild; + t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" ); + t.ok( firstChild, img, "div first child is correct image object" ); + t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." ); + map.destroy(); + } + + function test_Layer_WMS_inittiles (t) { + t.plan( 2 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params, {buffer:2}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0),5); + t.eq( layer.grid.length, 8, "Grid rows is correct." ); + t.eq( layer.grid[0].length, 7, "Grid cols is correct." ); + map.destroy(); + } + + function test_Layer_WMS_clone (t) { + t.plan(4); + + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + var options = {tileSize: new OpenLayers.Size(500,50)}; + var map = new OpenLayers.Map('map', options); + layer = new OpenLayers.Layer.WMS(name, url, params); + map.addLayer(layer); + + layer.grid = [ [6, 7], + [8, 9]]; + + var clone = layer.clone(); + + t.ok( clone.grid != layer.grid, "clone does not copy grid"); + + t.ok( clone.tileSize.equals(layer.tileSize), "tileSize correctly cloned"); + + layer.tileSize.w += 40; + + t.eq( clone.tileSize.w, 500, "changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference"); + + t.eq( clone.alpha, layer.alpha, "alpha copied correctly"); + + layer.grid = null; + map.destroy(); + } + + function test_Layer_WMS_isBaseLayer(t) { + t.plan(3); + + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.WMS(name, url, params); + t.ok( layer.isBaseLayer, "baselayer is true by default"); + + var newParams = OpenLayers.Util.extend({}, params); + newParams.transparent = "true"; + layer = new OpenLayers.Layer.WMS(name, url, newParams); + t.ok( !layer.isBaseLayer, "baselayer is false when transparent is set to true"); + + layer = new OpenLayers.Layer.WMS(name, url, params, {isBaseLayer: false}); + t.ok( !layer.isBaseLayer, "baselayer is false when option is set to false" ); + } + + function test_Layer_WMS_mergeNewParams (t) { + t.plan( 4 ); + + var map = new OpenLayers.Map("map"); + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.WMS(name, url, params); + + var newParams = { layers: 'sooper', + chickpeas: 'image/png'}; + + map.addLayer(layer); + map.zoomToMaxExtent(); + + layer.redraw = function() { + t.ok(true, "layer is redrawn after new params merged"); + } + + layer.mergeNewParams(newParams); + + t.eq( layer.params.LAYERS, "sooper", "mergeNewParams() overwrites well"); + t.eq( layer.params.CHICKPEAS, "image/png", "mergeNewParams() adds well"); + + newParams.CHICKPEAS = 151; + + t.eq( layer.params.CHICKPEAS, "image/png", "mergeNewParams() makes clean copy of hashtable"); + map.destroy(); + } + + function test_Layer_WMS_getFullRequestString (t) { + + + t.plan( 4 ); + var map = new OpenLayers.Map('map'); + map.projection = "xx"; + var tUrl = "http://octo.metacarta.com/cgi-bin/mapserv"; + var tParams = { layers: 'basic', + format: 'image/png'}; + var tLayer = new OpenLayers.Layer.WMS(name, tUrl, tParams); + map.addLayer(tLayer); + var str = tLayer.getFullRequestString(); + var tParams = { + LAYERS: "basic", FORMAT: "image/png", SERVICE: "WMS", + VERSION: "1.1.1", REQUEST: "GetMap", STYLES: "", + SRS: "xx" + }; + t.eq(str, + tUrl + "?" + OpenLayers.Util.getParameterString(tParams), + "getFullRequestString() adds SRS value"); + + map.removeLayer(tLayer); + tLayer.projection = "none"; + map.addLayer(tLayer); + str = tLayer.getFullRequestString(); + delete tParams['SRS']; + t.eq(str, + tUrl + "?" + OpenLayers.Util.getParameterString(tParams), + "getFullRequestString() by default does *not* add SRS value if projection is 'none'"); + map.destroy(); + + map = new OpenLayers.Map("map", {projection: "EPSG:4326"}); + var layerProj = new OpenLayers.Projection("FOO", { + equals: function() {return true}, + getCode: function() {return "FOO"} + }); + tLayer = new OpenLayers.Layer.WMS(name, tUrl, tParams, {projection: layerProj}); + map.addLayer(tLayer); + str = tLayer.getFullRequestString(); + tParams.SRS = "FOO"; + t.eq(str, + tUrl + "?" + OpenLayers.Util.getParameterString(tParams), + "getFullRequestString() uses the layer projection if it equals the map projection"); + map.destroy(); + + map = new OpenLayers.Map("map", {projection: "EPSG:4326"}); + map.addLayer(new OpenLayers.Layer(null, {isBaseLayer: true})); + tLayer = new OpenLayers.Layer.WMS(name, tUrl); + tLayer.map = map; + var error; + try { + tLayer.getFullRequestString(); + error = false; + } catch(err) { + error = true; + } + t.ok(!error, "no error on getFullRequestString if layer has no projection"); + map.destroy(); + + } + + function test_setOpacity(t) { + t.plan(1); + + var layer = new OpenLayers.Layer.WMS( + null, "/bogus/wms", {layers: "mylayer"} + ); + var map = new OpenLayers.Map("map"); + map.addLayer(layer); + + map.zoomToMaxExtent(); + + layer.setOpacity(0.5); + t.delay_call(1, function() { + t.eq(parseFloat(layer.div.firstChild.style.opacity), 0.5, "opacity set"); + map.destroy(); + }); + } + + + function test_Layer_WMS_noGutters (t) { + t.plan(2); + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.WMS("no gutter layer", url, params, {gutter: 0}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + var tile = layer.grid[0][0]; + var request = layer.getURL(tile.bounds); + var args = OpenLayers.Util.getParameters(request); + t.eq(parseInt(args['WIDTH']), + tile.size.w, + "layer without gutter requests images that are as wide as the tile"); + t.eq(parseInt(args['HEIGHT']), + tile.size.h, + "layer without gutter requests images that are as tall as the tile"); + + layer.destroy(); + map.destroy(); + } + + function test_Layer_WMS_gutters (t) { + t.plan(2); + var gutter = 15; + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer.WMS("gutter layer", url, params, {gutter: gutter}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + var tile = layer.grid[0][0]; + var request = layer.getURL(tile.bounds); + var args = OpenLayers.Util.getParameters(request); + t.eq(parseInt(args['WIDTH']), + tile.size.w + (2 * gutter), + "layer with gutter requests images that are wider by twice the gutter"); + t.eq(parseInt(args['HEIGHT']), + tile.size.h + (2 * gutter), + "layer with gutter requests images that are taller by twice the gutter"); + + layer.destroy(); + map.destroy(); + + } + + function test_maxExtent(t) { + t.plan(5); + + var layer = new OpenLayers.Layer.WMS( + null, "http://example.com/wms", + {layers: "foo"}, + {maxExtent: [-180, 0, 0, 90]} + ); + + t.ok(layer.maxExtent instanceof OpenLayers.Bounds, "(array) bounds instance"); + t.eq(layer.maxExtent.left, -180, "(array) bounds left"); + t.eq(layer.maxExtent.bottom, 0, "(array) bounds left"); + t.eq(layer.maxExtent.right, 0, "(array) bounds right"); + t.eq(layer.maxExtent.top, 90, "(array) bounds top"); + + layer.destroy(); + } + + function test_minExtent(t) { + t.plan(5); + + var layer = new OpenLayers.Layer.WMS( + null, "http://example.com/wms", + {layers: "foo"}, + {minExtent: [-180, 0, 0, 90]} + ); + + t.ok(layer.minExtent instanceof OpenLayers.Bounds, "(array) bounds instance"); + t.eq(layer.minExtent.left, -180, "(array) bounds left"); + t.eq(layer.minExtent.bottom, 0, "(array) bounds left"); + t.eq(layer.minExtent.right, 0, "(array) bounds right"); + t.eq(layer.minExtent.top, 90, "(array) bounds top"); + + layer.destroy(); + } + + function test_tileOrigin(t) { + t.plan(4); + + var dummy = new OpenLayers.Layer(null, {isBaseLayer: true}); + var unconstrained = new OpenLayers.Layer.WMS( + null, "http://example.com/wms", + {layers: "unconstrained"}, + {isBaseLayer: false, buffer: 0} + ); + var constrained = new OpenLayers.Layer.WMS( + null, "http://example.com/wms-c", + {layers: "constrained"}, + {buffer: 0, isBaseLayer: false, tileOrigin: new OpenLayers.LonLat(-180, -90)} + ); + var map = new OpenLayers.Map({ + div: "map", + maxExtent: new OpenLayers.Bounds(-185, -95, 185, 95), + maxResolution: 1.40625, + layers: [dummy, unconstrained, constrained], + center: new OpenLayers.LonLat(0, 0), + zoom: 1 + }); + + t.eq(unconstrained.grid[1][0].bounds.bottom, -95, "unconstrained bottom correct"); + t.eq(unconstrained.grid[1][0].bounds.left, -185, "unconstrained left correct"); + t.eq(constrained.grid[1][0].bounds.bottom, -90, "constrained bottom correct"); + t.eq(constrained.grid[1][0].bounds.left, -180, "constrained left correct"); + + map.destroy(); + + } + + function test_Layer_WMS_destroy (t) { + + t.plan( 1 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0), 5); + + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.destroy(); + + // checks to make sure superclass (grid) destroy() was called + + t.ok( layer.grid == null, "grid set to null"); + } + + function test_customProjection(t) { + t.plan(1); + var map = new OpenLayers.Map('map', { + units: 'm', + projection: new OpenLayers.Projection('EPSG:28992'), + maxExtent: new OpenLayers.Bounds(0, 300000, 300000, 6250000) + }); + var layer = new OpenLayers.Layer.WMS(null, url, {layers: 'mylayer', version: '1.3.0'}); + map.addLayer(layer); + var error = false; + try { + map.setCenter(new OpenLayers.LonLat(100000,300000), 5); + } catch(err) { + error = true; + } + t.ok(!error, "no error on getURL if layer has a custom projection and no defaults defined"); + layer.destroy(); + map.destroy(); + } + + function test_Layer_WMS_v13(t) { + + t.plan(6); + + var lon = 5; + var lat = 40; + var zoom = 5; + var map = new OpenLayers.Map( 'map' ); + var layer = new OpenLayers.Layer.WMS( + "OpenLayers WMS", + "http://myserver.org/wms?", + {layers: 'mylayer', version: '1.3.0'}, + {singleTile: true} + ); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(lon, lat), zoom); + + var url = layer.getURL(map.getExtent()); + var params = url.split("&"); + var bbox; + for (var i=0, len=params.length; i<len; i++) { + var param = params[i]; + var a = param.split('='); + if (a[0] === 'BBOX') { + bbox = a[1]; + break; + } + } + + t.eq(layer.params.CRS, "EPSG:4326", "In WMS 1.3 SRS is now CRS"); + t.eq(bbox, "27.9150390625,-5.986328125,52.0849609375,15.986328125", "Axis sequence is lat lon for EPSG:4326 in WMS 1.3.0"); + + var layer2 = new OpenLayers.Layer.WMS( + "OpenLayers WMS", + "http://myserver.org/wms?", + {layers: 'mylayer', version: '1.1.1'}, + {singleTile: true} + ); + map.addLayer(layer2); + + var url = layer2.getURL(map.getExtent()); + var params = url.split("&"); + var bbox; + for (var i=0, len=params.length; i<len; i++) { + var param = params[i]; + var a = param.split('='); + if (a[0] === 'BBOX') { + bbox = a[1]; + break; + } + } + + t.eq(layer2.params.SRS, "EPSG:4326", "In WMS 1.1.1 parameter is called SRS"); + t.eq(bbox, "-5.986328125,27.9150390625,15.986328125,52.0849609375", "Axis sequence is lon lat for EPSG:4326 in WMS 1.1.1"); + + map.destroy(); + + // CRS:84 has normal axis sequence (lon lat) + var map = new OpenLayers.Map( 'map', {projection: 'CRS:84'} ); + var layer = new OpenLayers.Layer.WMS( + "OpenLayers WMS", + "http://myserver.org/wms?", + {layers: 'mylayer', version: '1.3.0'}, + {singleTile: true} + ); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(lon, lat), zoom); + + var url = layer.getURL(map.getExtent()); + var params = url.split("&"); + var bbox, exceptions; + for (var i=0, len=params.length; i<len; i++) { + var param = params[i]; + var a = param.split('='); + if (a[0] === 'EXCEPTIONS') { + exceptions = a[1]; + } + if (a[0] === 'BBOX') { + bbox = a[1]; + } + } + + t.eq(exceptions, "INIMAGE", "If not set, EXCEPTIONS should be INIMAGE for WMS 1.3"); + t.eq(bbox, "-5.986328125,27.9150390625,15.986328125,52.0849609375", "Axis sequence for CRS:84 is lon lat"); + + map.destroy(); + + } + + function test_transparent(t) { + t.plan(5); + var map = new OpenLayers.Map("map", {allOverlays: true}); + var layer = new OpenLayers.Layer.WMS( + "OpenLayers WMS", + "http://myserver.org/wms?", + {layers: 'mylayer', transparent: true} + ); + map.addLayer(layer); + + t.eq(typeof layer.params.TRANSPARENT, "boolean", "transparent param is boolean"); + t.ok(layer.getFullRequestString({}).indexOf("TRANSPARENT=TRUE") != -1, "Boolean transparent param value is uppercase TRUE"); + layer.mergeNewParams({transparent: false}); + t.ok(layer.getFullRequestString({}).indexOf("TRANSPARENT=FALSE") != -1, "Boolean transparent param value is uppercase FALSE"); + + layer.mergeNewParams({transparent: "true"}); + t.eq(typeof layer.params.TRANSPARENT, "string", "transparent param is string"); + t.ok(layer.getFullRequestString({}).indexOf("TRANSPARENT=true") != -1, "transparent param value passed as provided if String"); + + map.destroy(); + } + + function test_tileBounds(t) { + t.plan(3); + + var map = new OpenLayers.Map("map", {projection: "EPSG:3857", zoomMethod: null}); + var layer = new OpenLayers.Layer.WMS("wms", "../../img/blank.gif"); + map.addLayer(layer); + map.setCenter([0, 0], 1); + map.pan(2, -100); + map.zoomIn(); + t.eq(layer.grid[1][0].bounds, new OpenLayers.Bounds(-10018754.17, 0, 0, 10018754.17), "no floating point errors after zooming"); + map.setCenter([0, 0], 14); + var bounds = layer.grid[0][0].bounds.clone(); + map.pan(260, 520); + map.pan(-260, -520); + t.eq(layer.grid[0][0].bounds, bounds, "no floating point errors after dragging back and forth"); + t.eq(bounds.right, 0, "0 is 0, and not some super small number"); + + map.destroy(); + } + + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/WMTS.html b/misc/openlayers/tests/Layer/WMTS.html new file mode 100644 index 0000000..c6dcd4c --- /dev/null +++ b/misc/openlayers/tests/Layer/WMTS.html @@ -0,0 +1,1491 @@ +<html> + <head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + + function test_constructor(t) { + t.plan(6); + var xml = document.getElementById("capabilities").firstChild.nodeValue; + var doc = new OpenLayers.Format.XML().read(xml); + var obj = new OpenLayers.Format.WMTSCapabilities().read(doc); + + var layer0 = new OpenLayers.Layer.WMTS({ + name: "GeoWebCache USA WMTS", + url: "http://example.com/geowebcache-1.2.2/service/wmts/", + layer: "arcgis-online-wms", + style: "", + matrixSet: "arcgis-online-wgs84", + format: "image/png", + isBaseLayer: false, + requestEncoding: "KVP", + maxResolution: 0.3521969032857032, + numZoomLevels: 7, + matrixIds: obj.contents.tileMatrixSets["arcgis-online-wgs84"].matrixIds + }); + + t.ok(layer0 instanceof OpenLayers.Layer.WMTS, "constructor returns instance of OpenLayers.Layer.WMTS"); + t.eq(layer0.formatSuffix, "png", "formatSuffix is set correct based on 'format' parameter"); + + var layer1 = new OpenLayers.Layer.WMTS({ + name: "Blue Marble WMTS", + url: "http://example.com/wmts/", + layer: "world", + style: "blue_marble", + matrixSet: "arcgis_online", + tileSize: new OpenLayers.Size(512, 512), + requestEncoding: "REST" + }); + + t.ok(layer1 instanceof OpenLayers.Layer.WMTS, "constructor returns instance of OpenLayers.Layer.WMTS"); + t.eq(layer1.formatSuffix, "jpg", "formatSuffix is set correct based on default format"); + t.eq(layer1.tileSize.w, 512.0, "tileSize w is set correctly"); + t.eq(layer1.tileSize.h, 512.0, "tileSize h is set correctly"); + } + + function test_moveTo(t) { + t.plan(9); + var xml = document.getElementById("capabilities").firstChild.nodeValue; + var doc = new OpenLayers.Format.XML().read(xml); + var obj = new OpenLayers.Format.WMTSCapabilities().read(doc); + + var layer0 = new OpenLayers.Layer.WMTS({ + name: "GeoWebCache USA WMTS", + url: "http://example.com/geowebcache-1.2.2/service/wmts/", + layer: "arcgis-online-wms", + style: "foo", + matrixSet: "arcgis-online-wgs84", + format: "image/png", + requestEncoding: "KVP", + maxResolution: 0.3521969032857032, + numZoomLevels: 7, + matrixIds: obj.contents.tileMatrixSets["arcgis-online-wgs84"].matrixIds + }); + + var map = new OpenLayers.Map('map'); + map.addLayer(layer0); + + map.setCenter(new OpenLayers.LonLat(-97, 38), 1); + + t.ok((layer0.tileOrigin instanceof OpenLayers.LonLat), "tileOrigin is an instance of OpenLayers.LonLat"); + t.ok((layer0.tileOrigin.lon == -180 && layer0.tileOrigin.lat == 90), "tileOrigin is set correctly"); + t.ok((layer0.tileSize instanceof OpenLayers.Size), "tileSize is an instance of OpenLayers.Size"); + t.eq(layer0.tileSize.w, 256.0, "tileSize w is set correctly"); + t.eq(layer0.tileSize.h, 256.0, "tileSize h is set correctly"); + + map.setCenter(new OpenLayers.LonLat(-97.0, 38.0), 6); + + t.eq(layer0.tileOrigin.lon, -175, "tileOrigin.lat updated correctly when zoom changed"); + t.eq(layer0.tileOrigin.lat, 85, "tileOrigin.lat updated correctly when zoom changed"); + t.eq(layer0.tileSize.w, 512.0, "tileSize w updated correctly when zoom changed"); + t.eq(layer0.tileSize.h, 512.0, "tileSize h updated correctly when zoom changed"); + + map.destroy(); + } + + function test_clearTiles (t) { + t.plan(1); + var map = new OpenLayers.Map('map'); + + var layer1 = new OpenLayers.Layer.WMTS({ + name: "Blue Marble WMTS", + url: "http://example.com/wmts/", + layer: "world", + style: "blue_marble", + matrixSet: "arcgis_online", + tileSize: new OpenLayers.Size(512, 512), + requestEncoding: "REST" + }); + + map.addLayer(layer1); + map.setCenter(new OpenLayers.LonLat(0,0)); + + //grab a reference to one of the tiles + var tile = layer1.grid[0][0]; + + layer1.clearGrid(); + + t.ok( layer1.grid != null, "layer.grid does not get nullified" ); + map.destroy(); + } + + function test_getTilesBounds(t) { + t.plan(1); + var layer1 = new OpenLayers.Layer.WMTS({ + name: "Blue Marble WMTS", + url: "http://example.com/wmts/", + layer: "world", + style: "blue_marble", + matrixSet: "arcgis_online", + tileSize: new OpenLayers.Size(512, 512), + requestEncoding: "REST" + }); + var bl = {bounds: new OpenLayers.Bounds(1,2,2,3)}; + var tr = {bounds: new OpenLayers.Bounds(2,3,3,4)}; + layer1.grid = [[6, tr],[bl, 7]]; + var bounds = layer1.getTilesBounds(); + var testBounds = new OpenLayers.Bounds(1,2,3,4); + t.ok(bounds.equals(testBounds), "correct bounds"); + } + + function test_getResolution(t) { + t.plan(1); + var map = new OpenLayers.Map('map'); + var layer1 = new OpenLayers.Layer.WMTS({ + name: "Blue Marble WMTS", + url: "http://example.com/wmts/", + layer: "world", + style: "blue_marble", + matrixSet: "arcgis_online", + tileSize: new OpenLayers.Size(512, 512), + maxResolution: 1.40625, + requestEncoding: "REST" + }); + map.addLayer(layer1); + map.zoom = 5; + t.eq(layer1.getResolution(), 0.0439453125, "getResolution() returns correct value"); + map.destroy(); + } + + function test_getZoomForExtent(t) { + t.plan(2); + var bounds, zoom; + + var map = new OpenLayers.Map('map'); + var layer1 = new OpenLayers.Layer.WMTS({ + name: "Blue Marble WMTS", + url: "http://example.com/wmts/", + layer: "world", + style: "blue_marble", + matrixSet: "arcgis_online", + tileSize: new OpenLayers.Size(512, 512), + maxResolution: 1.40625, + requestEncoding: "REST" + }); + map.addLayer(layer1); + bounds = new OpenLayers.Bounds(10,10,12,12); + zoom = layer1.getZoomForExtent(bounds); + t.eq(zoom, 8, "correct value for (10,10,12,12)"); + bounds = new OpenLayers.Bounds(10,10,100,100); + zoom = layer1.getZoomForExtent(bounds); + t.eq(zoom, 3, "correct value (10,10,100,100)"); + map.destroy(); + } + + function test_getURL(t) { + t.plan(2); + var xml = document.getElementById("capabilities").firstChild.nodeValue; + var doc = new OpenLayers.Format.XML().read(xml); + var obj = new OpenLayers.Format.WMTSCapabilities().read(doc); + + var layer0 = new OpenLayers.Layer.WMTS({ + name: "GeoWebCache USA WMTS", + url: "http://example.com/geowebcache-1.2.2/service/wmts/", + layer: "arcgis-online-wms", + style: "foo", + matrixSet: "arcgis-online-wgs84", + format: "image/png", + requestEncoding: "KVP", + maxResolution: 0.3521969032857032, + numZoomLevels: 7, + matrixIds: obj.contents.tileMatrixSets["arcgis-online-wgs84"].matrixIds + }); + + var layer1 = new OpenLayers.Layer.WMTS({ + name: "Blue Marble WMTS", + url: "http://example.com/wmts/", + layer: "world", + style: "blue_marble", + matrixSet: "arcgis_online", + format: "image/jpeg", + tileSize: new OpenLayers.Size(512, 512), + requestEncoding: "REST", + isBaseLayer: false + }); + + var options = { + controls: [ + new OpenLayers.Control.LayerSwitcher(), + new OpenLayers.Control.Navigation(), + new OpenLayers.Control.PanZoom() + ], + projection: "EPSG:4326", + maxResolution: 0.3515625, + maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90) + }; + var map = new OpenLayers.Map('map', options); + map.addLayers([layer0,layer1]); + map.setCenter(new OpenLayers.LonLat(-97.0, 38.0), 1); + var tileurl0 = layer0.getURL(new OpenLayers.Bounds(-135.0, 0.0, -90.0, 45.0)); + t.ok(OpenLayers.Util.isEquivalentUrl(tileurl0, "http://example.com/geowebcache-1.2.2/service/wmts/?LAYER=arcgis-online-wms&STYLE=foo&TILEMATRIXSET=arcgis-online-wgs84&FORMAT=image%2Fpng&SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&TILEMATRIX=arcgis-online-wgs84%3A1&TILEROW=1&TILECOL=1"), "layer0 getURL returns correct url"); + + var tileurl1 = layer1.getURL(new OpenLayers.Bounds(-180.0, 0.0, -90.0, 90.0)); + t.eq(tileurl1, "http://example.com/wmts/1.0.0/world/blue_marble/arcgis_online/1/0/0.jpg", "layer1 getURL returns correct url"); + map.destroy(); + } + + function test_getURL_resourceUrl(t) { + t.plan(2); + + var xml = document.getElementById("capabilities").firstChild.nodeValue; + var doc = new OpenLayers.Format.XML().read(xml); + var obj = new OpenLayers.Format.WMTSCapabilities().read(doc); + + var template = "http://www.example.com/{style}/{Time}/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"; + var layer = new OpenLayers.Layer.WMTS({ + requestEncoding: "REST", + url: template, + layer: "GeoWebCache_USA_WMTS", + style: "foo", + matrixSet: "arcgis-online", + params: {Time: "2011"}, + dimensions: ["Time"] + }); + + var map = new OpenLayers.Map("map", { + layers: [layer], + projection: "EPSG:4326", + maxResolution: 0.3515625, + maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90), + zoomMethod: null + }); + map.setCenter(new OpenLayers.LonLat(-97.0, 38.0), 1); + t.eq(layer.getURL(new OpenLayers.Bounds(-135.0, 0.0, -90.0, 45.0)), + "http://www.example.com/foo/2011/foo/arcgis-online/1/1/1.png", "getURL returns correct url"); + map.zoomIn(); + t.eq(layer.getURL(new OpenLayers.Bounds(-180.0, 0.0, -90.0, 90.0)), + "http://www.example.com/foo/2011/foo/arcgis-online/2/2/2.png", "getURL returns correct url"); + map.destroy(); + } + + function test_destroy (t) { + t.plan(3); + var map = new OpenLayers.Map('map'); + var layer1 = new OpenLayers.Layer.WMTS({ + name: "Blue Marble WMTS", + url: "http://example.com/wmts/", + layer: "world", + style: "blue_marble", + matrixSet: "arcgis_online", + tileSize: new OpenLayers.Size(512, 512), + requestEncoding: "REST" + }); + map.addLayer(layer1); + layer1.destroy(); + t.eq( layer1.grid, null, "layer.grid is null after destroy" ); + t.eq( layer1.tileSize, null, "layer.tileSize is null after destroy" ); + + //test with tile creation + var layer2 = new OpenLayers.Layer.WMTS({ + name: "Blue Marble WMTS", + url: "http://example.com/wmts/", + layer: "world", + style: "blue_marble", + matrixSet: "arcgis_online", + tileSize: new OpenLayers.Size(512, 512), + requestEncoding: "REST" + }); + map.addLayer(layer2); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + //grab a reference to one of the tiles + var tile = layer2.grid[0][0]; + + layer2.destroy(); + + t.ok( layer2.grid == null, "tiles appropriately destroyed"); + map.destroy(); + } + + function test_getIdentifier(t) { + t.plan(2); + + var map = new OpenLayers.Map('map'); + var layer, identifier; + + layer = new OpenLayers.Layer.WMTS({ + name: "Blue Marble WMTS", + url: "http://example.com/wmts/", + layer: "world", + style: "blue_marble", + matrixSet: "arcgis_online", + tileSize: new OpenLayers.Size(512, 512), + requestEncoding: "REST" + }); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + + layer.zoomOffset = 2; + identifier = layer.getIdentifier(); + t.eq(identifier, 7, '[zoomOffset] getIdentifier return value is correct'); + + layer.serverResolutions = ['offset', 1.40625, 0.703125, 0.3515625, 0.17578125, + 0.087890625, 0.0439453125]; + identifier = layer.getIdentifier(); + t.eq(identifier, 6, '[serverResolutions] getIdentifier return value is correct'); + + map.destroy(); + } + + </script> + </head> + <body> + <div id="map" style="width:1024px;height:512px;"></div> + <div id="capabilities"><!-- +<Capabilities xmlns="http://www.opengis.net/wmts/1.0" +xmlns:ows="http://www.opengis.net/ows/1.1" +xmlns:xlink="http://www.w3.org/1999/xlink" +xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://geowebcache.org/schema/opengis/wmts/1.0.0/wmtsGetCapabilities_response.xsd" +version="1.0.0"> +<ows:ServiceIdentification> + <ows:Title>Web Map Tile Service - GeoWebCache</ows:Title> + <ows:ServiceType>OGC WMTS</ows:ServiceType> + <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion> +</ows:ServiceIdentification> +<ows:ServiceProvider> + <ows:ProviderName>http://example.com/geowebcache-1.2.2/service/wmts</ows:ProviderName> + <ows:ProviderSite xlink:href="http://example.com/geowebcache-1.2.2/service/wmts" /> + <ows:ServiceContact> + <ows:IndividualName>GeoWebCache User</ows:IndividualName> + </ows:ServiceContact> +</ows:ServiceProvider> +<ows:OperationsMetadata> + <ows:Operation name="GetCapabilities"> + <ows:DCP> + <ows:HTTP> + <ows:Get xlink:href="http://example.com/geowebcache-1.2.2/service/wmts?"> + <ows:Constraint name="GetEncoding"> + <ows:AllowedValues> + <ows:Value>KVP</ows:Value> + </ows:AllowedValues> + </ows:Constraint> + </ows:Get> + </ows:HTTP> + </ows:DCP> + </ows:Operation> + <ows:Operation name="GetTile"> + <ows:DCP> + <ows:HTTP> + <ows:Get xlink:href="http://example.com/geowebcache-1.2.2/service/wmts?"> + <ows:Constraint name="GetEncoding"> + <ows:AllowedValues> + <ows:Value>KVP</ows:Value> + </ows:AllowedValues> + </ows:Constraint> + </ows:Get> + </ows:HTTP> + </ows:DCP> + </ows:Operation> + <ows:Operation name="GetFeatureInfo"> + <ows:DCP> + <ows:HTTP> + <ows:Get xlink:href="http://example.com/geowebcache-1.2.2/service/wmts?"> + <ows:Constraint name="GetEncoding"> + <ows:AllowedValues> + <ows:Value>KVP</ows:Value> + </ows:AllowedValues> + </ows:Constraint> + </ows:Get> + </ows:HTTP> + </ows:DCP> + </ows:Operation> +</ows:OperationsMetadata> +<Contents> + <Layer> + <ows:Title>arcgis-online-wms</ows:Title> + <ows:Abstract>arcgis-online-wms</ows:Abstract> + <ows:WGS84BoundingBox> + <ows:LowerCorner>-180.0 -90.0</ows:LowerCorner> + <ows:UpperCorner>180.0 90.0</ows:UpperCorner> + </ows:WGS84BoundingBox> + <ows:Identifier>arcgis-online-wms</ows:Identifier> + <Style isDefault="true"> + <ows:Identifier>_null</ows:Identifier> + </Style> + <Format>image/png</Format> + <Format>image/jpeg</Format> + <TileMatrixSetLink> <TileMatrixSet>arcgis-online-wgs84</TileMatrixSet> + </TileMatrixSetLink> </Layer> + <TileMatrixSet> + <ows:Identifier>EPSG:4326</ows:Identifier> + <ows:SupportedCRS>urn:ogc:def:crs:EPSG::4326</ows:SupportedCRS> + <TileMatrix> + <ows:Identifier>EPSG:4326:0</ows:Identifier> + <ScaleDenominator>2.795411320143589E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2</MatrixWidth> + <MatrixHeight>1</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:1</ows:Identifier> + <ScaleDenominator>1.3977056600717944E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>4</MatrixWidth> + <MatrixHeight>2</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:2</ows:Identifier> + <ScaleDenominator>6.988528300358972E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>8</MatrixWidth> + <MatrixHeight>4</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:3</ows:Identifier> + <ScaleDenominator>3.494264150179486E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>16</MatrixWidth> + <MatrixHeight>8</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:4</ows:Identifier> + <ScaleDenominator>1.747132075089743E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>32</MatrixWidth> + <MatrixHeight>16</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:5</ows:Identifier> + <ScaleDenominator>8735660.375448715</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>64</MatrixWidth> + <MatrixHeight>32</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:6</ows:Identifier> + <ScaleDenominator>4367830.1877243575</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>128</MatrixWidth> + <MatrixHeight>64</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:7</ows:Identifier> + <ScaleDenominator>2183915.0938621787</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>256</MatrixWidth> + <MatrixHeight>128</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:8</ows:Identifier> + <ScaleDenominator>1091957.5469310894</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>512</MatrixWidth> + <MatrixHeight>256</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:9</ows:Identifier> + <ScaleDenominator>545978.7734655447</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1024</MatrixWidth> + <MatrixHeight>512</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:10</ows:Identifier> + <ScaleDenominator>272989.38673277234</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2048</MatrixWidth> + <MatrixHeight>1024</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:11</ows:Identifier> + <ScaleDenominator>136494.69336638617</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>4096</MatrixWidth> + <MatrixHeight>2048</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:12</ows:Identifier> + <ScaleDenominator>68247.34668319309</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>8192</MatrixWidth> + <MatrixHeight>4096</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:13</ows:Identifier> + <ScaleDenominator>34123.67334159654</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>16384</MatrixWidth> + <MatrixHeight>8192</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:14</ows:Identifier> + <ScaleDenominator>17061.83667079827</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>32768</MatrixWidth> + <MatrixHeight>16384</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:15</ows:Identifier> + <ScaleDenominator>8530.918335399136</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>65536</MatrixWidth> + <MatrixHeight>32768</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:16</ows:Identifier> + <ScaleDenominator>4265.459167699568</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>131072</MatrixWidth> + <MatrixHeight>65536</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:17</ows:Identifier> + <ScaleDenominator>2132.729583849784</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>262144</MatrixWidth> + <MatrixHeight>131072</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:18</ows:Identifier> + <ScaleDenominator>1066.364791924892</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>524288</MatrixWidth> + <MatrixHeight>262144</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:19</ows:Identifier> + <ScaleDenominator>533.182395962446</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1048576</MatrixWidth> + <MatrixHeight>524288</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:20</ows:Identifier> + <ScaleDenominator>266.591197981223</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2097152</MatrixWidth> + <MatrixHeight>1048576</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:21</ows:Identifier> + <ScaleDenominator>133.2955989906115</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>4194304</MatrixWidth> + <MatrixHeight>2097152</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:22</ows:Identifier> + <ScaleDenominator>66.64779949530575</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>8388608</MatrixWidth> + <MatrixHeight>4194304</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:23</ows:Identifier> + <ScaleDenominator>33.323899747652874</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>16777216</MatrixWidth> + <MatrixHeight>8388608</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:24</ows:Identifier> + <ScaleDenominator>16.661949873826437</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>33554432</MatrixWidth> + <MatrixHeight>16777216</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:25</ows:Identifier> + <ScaleDenominator>8.330974936913218</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>67108864</MatrixWidth> + <MatrixHeight>33554432</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:26</ows:Identifier> + <ScaleDenominator>4.165487468456609</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>134217728</MatrixWidth> + <MatrixHeight>67108864</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:27</ows:Identifier> + <ScaleDenominator>2.0827437342283046</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>268435456</MatrixWidth> + <MatrixHeight>134217728</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:28</ows:Identifier> + <ScaleDenominator>1.0413718671141523</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>536870912</MatrixWidth> + <MatrixHeight>268435456</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:29</ows:Identifier> + <ScaleDenominator>0.5206859335570762</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1073741824</MatrixWidth> + <MatrixHeight>536870912</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:4326:30</ows:Identifier> + <ScaleDenominator>0.2603429667785381</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2147483648</MatrixWidth> + <MatrixHeight>1073741824</MatrixHeight> + </TileMatrix> + </TileMatrixSet> + <TileMatrixSet> + <ows:Identifier>arcgis-online-epsg102113</ows:Identifier> + <ows:SupportedCRS>urn:ogc:def:crs:EPSG::102113</ows:SupportedCRS> + <TileMatrix> + <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract> <ows:Identifier>arcgis-online-epsg102113:0</ows:Identifier> + <ScaleDenominator>5.590822639285715E8</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1</MatrixWidth> + <MatrixHeight>1</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract> <ows:Identifier>arcgis-online-epsg102113:1</ows:Identifier> + <ScaleDenominator>2.7954113196428573E8</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2</MatrixWidth> + <MatrixHeight>2</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract> <ows:Identifier>arcgis-online-epsg102113:2</ows:Identifier> + <ScaleDenominator>1.3977056598214287E8</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>4</MatrixWidth> + <MatrixHeight>4</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract> <ows:Identifier>arcgis-online-epsg102113:3</ows:Identifier> + <ScaleDenominator>6.988528299107143E7</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>8</MatrixWidth> + <MatrixHeight>8</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract> <ows:Identifier>arcgis-online-epsg102113:4</ows:Identifier> + <ScaleDenominator>3.494264149553572E7</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>16</MatrixWidth> + <MatrixHeight>16</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract> <ows:Identifier>arcgis-online-epsg102113:5</ows:Identifier> + <ScaleDenominator>1.747132074776786E7</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>32</MatrixWidth> + <MatrixHeight>32</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract> <ows:Identifier>arcgis-online-epsg102113:6</ows:Identifier> + <ScaleDenominator>8735660.37388393</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>64</MatrixWidth> + <MatrixHeight>64</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract> <ows:Identifier>arcgis-online-epsg102113:7</ows:Identifier> + <ScaleDenominator>4367830.186941965</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>128</MatrixWidth> + <MatrixHeight>128</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract> <ows:Identifier>arcgis-online-epsg102113:8</ows:Identifier> + <ScaleDenominator>2183915.0934709823</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>256</MatrixWidth> + <MatrixHeight>256</MatrixHeight> + </TileMatrix> + </TileMatrixSet> + <TileMatrixSet> + <ows:Identifier>GlobalCRS84Scale</ows:Identifier> + <ows:SupportedCRS>urn:ogc:def:crs:EPSG::4326</ows:SupportedCRS> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:0</ows:Identifier> + <ScaleDenominator>5.0000000000000006E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2</MatrixWidth> + <MatrixHeight>1</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:1</ows:Identifier> + <ScaleDenominator>2.5000000000000003E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>3</MatrixWidth> + <MatrixHeight>2</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:2</ows:Identifier> + <ScaleDenominator>1.0000000000000001E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>6</MatrixWidth> + <MatrixHeight>3</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:3</ows:Identifier> + <ScaleDenominator>5.000000000000001E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>12</MatrixWidth> + <MatrixHeight>6</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:4</ows:Identifier> + <ScaleDenominator>2.5000000000000004E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>23</MatrixWidth> + <MatrixHeight>12</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:5</ows:Identifier> + <ScaleDenominator>1.0E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>56</MatrixWidth> + <MatrixHeight>28</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:6</ows:Identifier> + <ScaleDenominator>5000000.0</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>112</MatrixWidth> + <MatrixHeight>56</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:7</ows:Identifier> + <ScaleDenominator>2500000.0</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>224</MatrixWidth> + <MatrixHeight>112</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:8</ows:Identifier> + <ScaleDenominator>1000000.0000000001</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>560</MatrixWidth> + <MatrixHeight>280</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:9</ows:Identifier> + <ScaleDenominator>500000.00000000006</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1119</MatrixWidth> + <MatrixHeight>560</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:10</ows:Identifier> + <ScaleDenominator>250000.00000000003</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2237</MatrixWidth> + <MatrixHeight>1119</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:11</ows:Identifier> + <ScaleDenominator>100000.00000000001</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>5591</MatrixWidth> + <MatrixHeight>2796</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:12</ows:Identifier> + <ScaleDenominator>50000.00000000001</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>11182</MatrixWidth> + <MatrixHeight>5591</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:13</ows:Identifier> + <ScaleDenominator>25000.000000000004</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>22364</MatrixWidth> + <MatrixHeight>11182</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:14</ows:Identifier> + <ScaleDenominator>10000.000000000002</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>55909</MatrixWidth> + <MatrixHeight>27955</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:15</ows:Identifier> + <ScaleDenominator>5000.000000000001</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>111817</MatrixWidth> + <MatrixHeight>55909</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:16</ows:Identifier> + <ScaleDenominator>2500.0000000000005</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>223633</MatrixWidth> + <MatrixHeight>111817</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:17</ows:Identifier> + <ScaleDenominator>1000.0000000000002</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>559083</MatrixWidth> + <MatrixHeight>279542</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:18</ows:Identifier> + <ScaleDenominator>500.0000000000001</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1118165</MatrixWidth> + <MatrixHeight>559083</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:19</ows:Identifier> + <ScaleDenominator>250.00000000000006</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2236330</MatrixWidth> + <MatrixHeight>1118165</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Scale:20</ows:Identifier> + <ScaleDenominator>100.00000000000003</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>5590823</MatrixWidth> + <MatrixHeight>2795412</MatrixHeight> + </TileMatrix> + </TileMatrixSet> + <TileMatrixSet> + <ows:Identifier>EPSG:900913</ows:Identifier> + <ows:SupportedCRS>urn:ogc:def:crs:EPSG::900913</ows:SupportedCRS> + <TileMatrix> + <ows:Identifier>EPSG:900913:0</ows:Identifier> + <ScaleDenominator>5.590822639508929E8</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1</MatrixWidth> + <MatrixHeight>1</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:1</ows:Identifier> + <ScaleDenominator>2.7954113197544646E8</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2</MatrixWidth> + <MatrixHeight>2</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:2</ows:Identifier> + <ScaleDenominator>1.3977056598772323E8</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>4</MatrixWidth> + <MatrixHeight>4</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:3</ows:Identifier> + <ScaleDenominator>6.988528299386162E7</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>8</MatrixWidth> + <MatrixHeight>8</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:4</ows:Identifier> + <ScaleDenominator>3.494264149693081E7</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>16</MatrixWidth> + <MatrixHeight>16</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:5</ows:Identifier> + <ScaleDenominator>1.7471320748465404E7</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>32</MatrixWidth> + <MatrixHeight>32</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:6</ows:Identifier> + <ScaleDenominator>8735660.374232702</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>64</MatrixWidth> + <MatrixHeight>64</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:7</ows:Identifier> + <ScaleDenominator>4367830.187116351</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>128</MatrixWidth> + <MatrixHeight>128</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:8</ows:Identifier> + <ScaleDenominator>2183915.0935581755</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>256</MatrixWidth> + <MatrixHeight>256</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:9</ows:Identifier> + <ScaleDenominator>1091957.5467790877</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>512</MatrixWidth> + <MatrixHeight>512</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:10</ows:Identifier> + <ScaleDenominator>545978.7733895439</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1024</MatrixWidth> + <MatrixHeight>1024</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:11</ows:Identifier> + <ScaleDenominator>272989.38669477194</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2048</MatrixWidth> + <MatrixHeight>2048</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:12</ows:Identifier> + <ScaleDenominator>136494.69334738597</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>4096</MatrixWidth> + <MatrixHeight>4096</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:13</ows:Identifier> + <ScaleDenominator>68247.34667369298</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>8192</MatrixWidth> + <MatrixHeight>8192</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:14</ows:Identifier> + <ScaleDenominator>34123.67333684649</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>16384</MatrixWidth> + <MatrixHeight>16384</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:15</ows:Identifier> + <ScaleDenominator>17061.836668423246</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>32768</MatrixWidth> + <MatrixHeight>32768</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:16</ows:Identifier> + <ScaleDenominator>8530.918334211623</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>65536</MatrixWidth> + <MatrixHeight>65536</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:17</ows:Identifier> + <ScaleDenominator>4265.4591671058115</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>131072</MatrixWidth> + <MatrixHeight>131072</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:18</ows:Identifier> + <ScaleDenominator>2132.7295835529058</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>262144</MatrixWidth> + <MatrixHeight>262144</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:19</ows:Identifier> + <ScaleDenominator>1066.3647917764529</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>524288</MatrixWidth> + <MatrixHeight>524288</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:20</ows:Identifier> + <ScaleDenominator>533.1823958882264</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1048576</MatrixWidth> + <MatrixHeight>1048576</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:21</ows:Identifier> + <ScaleDenominator>266.5911979441132</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2097152</MatrixWidth> + <MatrixHeight>2097152</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:22</ows:Identifier> + <ScaleDenominator>133.2955989720566</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>4194304</MatrixWidth> + <MatrixHeight>4194304</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:23</ows:Identifier> + <ScaleDenominator>66.6477994860283</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>8388608</MatrixWidth> + <MatrixHeight>8388608</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:24</ows:Identifier> + <ScaleDenominator>33.32389974301415</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>16777216</MatrixWidth> + <MatrixHeight>16777216</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:25</ows:Identifier> + <ScaleDenominator>16.661949871507076</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>33554432</MatrixWidth> + <MatrixHeight>33554432</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:26</ows:Identifier> + <ScaleDenominator>8.330974935753538</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>67108864</MatrixWidth> + <MatrixHeight>67108864</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:27</ows:Identifier> + <ScaleDenominator>4.165487467876769</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>134217728</MatrixWidth> + <MatrixHeight>134217728</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:28</ows:Identifier> + <ScaleDenominator>2.0827437339383845</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>268435456</MatrixWidth> + <MatrixHeight>268435456</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:29</ows:Identifier> + <ScaleDenominator>1.0413718669691923</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>536870912</MatrixWidth> + <MatrixHeight>536870912</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>EPSG:900913:30</ows:Identifier> + <ScaleDenominator>0.5206859334845961</ScaleDenominator> + <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1073741824</MatrixWidth> + <MatrixHeight>1073741824</MatrixHeight> + </TileMatrix> + </TileMatrixSet> + <TileMatrixSet> + <ows:Identifier>arcgis-online-wgs84</ows:Identifier> + <ows:SupportedCRS>urn:ogc:def:crs:EPSG::4326</ows:SupportedCRS> + <TileMatrix> + <ows:Identifier>arcgis-online-wgs84:0</ows:Identifier> + <ScaleDenominator>1.3977056600717944E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>4</MatrixWidth> + <MatrixHeight>2</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>arcgis-online-wgs84:1</ows:Identifier> + <ScaleDenominator>6.988528300358972E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>8</MatrixWidth> + <MatrixHeight>4</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>arcgis-online-wgs84:2</ows:Identifier> + <ScaleDenominator>3.494264150179486E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>16</MatrixWidth> + <MatrixHeight>8</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>arcgis-online-wgs84:3</ows:Identifier> + <ScaleDenominator>1.747132075089743E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>32</MatrixWidth> + <MatrixHeight>16</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>arcgis-online-wgs84:4</ows:Identifier> + <ScaleDenominator>8735660.375448715</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>64</MatrixWidth> + <MatrixHeight>32</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>arcgis-online-wgs84:5</ows:Identifier> + <ScaleDenominator>4367830.1877243575</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>128</MatrixWidth> + <MatrixHeight>64</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>arcgis-online-wgs84:6</ows:Identifier> + <ScaleDenominator>2183915.0938621787</ScaleDenominator> + <TopLeftCorner>85 -175</TopLeftCorner> + <TileWidth>512</TileWidth> + <TileHeight>512</TileHeight> + <MatrixWidth>256</MatrixWidth> + <MatrixHeight>128</MatrixHeight> + </TileMatrix> + </TileMatrixSet> + <TileMatrixSet> + <ows:Identifier>GlobalCRS84Pixel</ows:Identifier> + <ows:SupportedCRS>urn:ogc:def:crs:EPSG::4326</ows:SupportedCRS> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:0</ows:Identifier> + <ScaleDenominator>7.951392199519542E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1</MatrixWidth> + <MatrixHeight>1</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:1</ows:Identifier> + <ScaleDenominator>3.975696099759771E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>2</MatrixWidth> + <MatrixHeight>1</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:2</ows:Identifier> + <ScaleDenominator>1.9878480498798856E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>3</MatrixWidth> + <MatrixHeight>2</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:3</ows:Identifier> + <ScaleDenominator>1.325232033253257E8</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>5</MatrixWidth> + <MatrixHeight>3</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:4</ows:Identifier> + <ScaleDenominator>6.626160166266285E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>9</MatrixWidth> + <MatrixHeight>5</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:5</ows:Identifier> + <ScaleDenominator>3.3130800831331424E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>17</MatrixWidth> + <MatrixHeight>9</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:6</ows:Identifier> + <ScaleDenominator>1.325232033253257E7</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>43</MatrixWidth> + <MatrixHeight>22</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:7</ows:Identifier> + <ScaleDenominator>6626160.166266285</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>85</MatrixWidth> + <MatrixHeight>43</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:8</ows:Identifier> + <ScaleDenominator>3313080.0831331424</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>169</MatrixWidth> + <MatrixHeight>85</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:9</ows:Identifier> + <ScaleDenominator>1656540.0415665712</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>338</MatrixWidth> + <MatrixHeight>169</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:10</ows:Identifier> + <ScaleDenominator>552180.0138555238</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1013</MatrixWidth> + <MatrixHeight>507</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:11</ows:Identifier> + <ScaleDenominator>331308.00831331423</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>1688</MatrixWidth> + <MatrixHeight>844</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:12</ows:Identifier> + <ScaleDenominator>110436.00277110476</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>5063</MatrixWidth> + <MatrixHeight>2532</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:13</ows:Identifier> + <ScaleDenominator>55218.00138555238</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>10125</MatrixWidth> + <MatrixHeight>5063</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:14</ows:Identifier> + <ScaleDenominator>33130.80083133143</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>16875</MatrixWidth> + <MatrixHeight>8438</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:15</ows:Identifier> + <ScaleDenominator>11043.600277110474</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>50625</MatrixWidth> + <MatrixHeight>25313</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:16</ows:Identifier> + <ScaleDenominator>3313.080083133142</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>168750</MatrixWidth> + <MatrixHeight>84375</MatrixHeight> + </TileMatrix> + <TileMatrix> + <ows:Identifier>GlobalCRS84Pixel:17</ows:Identifier> + <ScaleDenominator>1104.3600277110472</ScaleDenominator> + <TopLeftCorner>90.0 -180.0</TopLeftCorner> + <TileWidth>256</TileWidth> + <TileHeight>256</TileHeight> + <MatrixWidth>506250</MatrixWidth> + <MatrixHeight>253125</MatrixHeight> + </TileMatrix> + </TileMatrixSet> +</Contents> +<ServiceMetadataURL xlink:href="http://example.com/geowebcache-1.2.2/service/wmts?REQUEST=getcapabilities&VERSION=1.0.0"/> +</Capabilities> + --> + </div> + </body> +</html> diff --git a/misc/openlayers/tests/Layer/WrapDateLine.html b/misc/openlayers/tests/Layer/WrapDateLine.html new file mode 100644 index 0000000..efe8903 --- /dev/null +++ b/misc/openlayers/tests/Layer/WrapDateLine.html @@ -0,0 +1,188 @@ +<html> +<head> +<script src="../OLLoader.js"></script> + <script type="text/javascript"> + // turn off animation frame handling, so we can check img urls in tests + delete OpenLayers.Layer.Grid.prototype.queueTileDraw; + + var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var layer; + + var name = 'Test Layer'; + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + var params = { map: '/mapdata/vmap_wms.map', + layers: 'basic', + format: 'image/png'}; + + + function test_Layer_WrapDateLine_adjustBounds(t) { + t.plan(10); + + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true}); + map.addLayer(layer); + map.zoomToMaxExtent(); + var bounds = layer.adjustBounds(new OpenLayers.Bounds(-270,-90,-180,0)); + t.ok( bounds.equals(new OpenLayers.Bounds(90,-90,180,0)), "-270,-90,-180,0 wraps to 90,-90,180,0"); + bounds = layer.adjustBounds(new OpenLayers.Bounds(180,-90,270,0)); + t.ok( bounds.equals(new OpenLayers.Bounds(-180,-90,-90,0)), "180,-90,270,0 wraps to -180,-90,-90,0"); + bounds = layer.adjustBounds(new OpenLayers.Bounds(-180,-90,0,0)); + t.ok( bounds.equals(new OpenLayers.Bounds(-180,-90,0,0)), "-180,-90,0,0 doesn't wrap"); + bounds = layer.adjustBounds(new OpenLayers.Bounds(-181,-90,-179,0)); + t.ok( bounds.equals(new OpenLayers.Bounds(-181,-90,-179,0)), "-181,-90,-179,0 doesn't wrap, because it straddles the dateline"); + bounds = layer.adjustBounds(new OpenLayers.Bounds(-180,-180,-90,-90)); + t.ok( bounds.equals(new OpenLayers.Bounds(-180,-180,-90,-90)), "-180,-180,-90,-90 doesn't wrap, because we don't wrap lats."); + layer = new OpenLayers.Layer.WMS(name, url, params); + map.addLayer(layer); + var testBounds = null; + var outBounds = null; + var testList = [ + new OpenLayers.Bounds(-270,-90,-180,0), + new OpenLayers.Bounds(180,-90,270,0), + new OpenLayers.Bounds(-180,-90,0,0), + new OpenLayers.Bounds(-181,-90,-179,0), + new OpenLayers.Bounds(-180,-180,-90,-90) + ]; + for (var i = 0; i < testList.length; i++) { + outBounds = layer.adjustBounds(testList[i]); + t.ok( outBounds.equals(testList[i]), testList[i]+" doesn't wrap in non-wrapping layer."); + } + map.destroy(); + } + function test_Layer_WrapDateLine_getLonLat(t) { + t.plan(12); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true}); + map.addLayer(layer); + map.zoomToMaxExtent(); + var testLonLats = [ + new OpenLayers.LonLat(-185,5), + new OpenLayers.LonLat(-180,-95), + new OpenLayers.LonLat(-180,95), + new OpenLayers.LonLat(180,-95), + new OpenLayers.LonLat(180,95), + new OpenLayers.LonLat(185,5) + ]; + var outLonLats = [ + new OpenLayers.LonLat(175,5), + new OpenLayers.LonLat(-180,-95), + new OpenLayers.LonLat(-180,95), + new OpenLayers.LonLat(180,-95), + new OpenLayers.LonLat(180,95), + new OpenLayers.LonLat(-175,5) + ]; + + for (var i = 0; i < testLonLats.length; i++) { + var pixel = layer.getViewPortPxFromLonLat(testLonLats[i]); + var lonlat = layer.getLonLatFromViewPortPx(pixel); + lonlat.lon = Math.round(lonlat.lon); + lonlat.lat = Math.round(lonlat.lat); + t.ok(outLonLats[i].equals(lonlat), testLonLats[i] + " wraps to " + outLonLats[i]+ " (what happened: " + lonlat + ")"); + } + + layer = new OpenLayers.Layer.WMS(name, url, params); + map.addLayer(layer); + var outLonLats = [ + new OpenLayers.LonLat(-185,5), + new OpenLayers.LonLat(-180,-95), + new OpenLayers.LonLat(-180,95), + new OpenLayers.LonLat(180,-95), + new OpenLayers.LonLat(180,95), + new OpenLayers.LonLat(185,5) + ]; + for (var i = 0; i < testLonLats.length; i++) { + var pixel = layer.getViewPortPxFromLonLat(testLonLats[i]); + var lonlat = layer.getLonLatFromViewPortPx(pixel); + lonlat.lon = Math.round(lonlat.lon); + lonlat.lat = Math.round(lonlat.lat); + t.ok(outLonLats[i].equals(lonlat), testLonLats[i] + " wraps to " + outLonLats[i]+ " (what happened: " + lonlat + ")"); + } + map.destroy(); + + } + function test_Layer_WrapDateLine_ZoomToExtent (t) { + t.plan( 4 ); + + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true}); + var m = new OpenLayers.Map('map'); + m.addLayer(layer); + m.setCenter = function(myCenter) { this.center = myCenter; } + var testBounds = [ + new OpenLayers.Bounds(-185,-90,-175,-85), + new OpenLayers.Bounds(0,-90,-170,-85), + new OpenLayers.Bounds(-270,-90,-180,-85), + new OpenLayers.Bounds(0,0,45,45) + ]; + var outCenters = [ + new OpenLayers.LonLat(-180,-87.5), + new OpenLayers.LonLat(95,-87.5), + new OpenLayers.LonLat(135,-87.5), + new OpenLayers.LonLat(22.5,22.5) + ]; + for (var i = 0; i < testBounds.length; i++) { + m.zoomToExtent(testBounds[i]); + t.ok(m.center.equals(outCenters[i]), "Map center from bounds " + testBounds[i] + " should be " + outCenters[i] + ", got " + m.center); + } + m.destroy(); + + + } + function test_Layer_WrapDateLine_WMS (t) { + t.plan( 4 ); + + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true,encodeBBOX:true, buffer: 2}); + var m = new OpenLayers.Map('map', {tileManager: null, adjustZoom: function(z) {return z;}}); + m.addLayer(layer); + m.zoomToMaxExtent(); + t.eq(layer.grid[3][0].url, "http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256", "cell [3][0] is wrapped around the world."); + t.eq(layer.grid[3][1].url, "http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180%2C-90%2C0%2C90&WIDTH=256&HEIGHT=256", "cell [3][1] is wrapped around the world."); + t.eq(layer.grid[3][2].url, "http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256", "cell [3][2] is not wrapped at all."); + t.ok(layer.grid[0][2].url == null, "no latitudinal wrapping - tile not loaded if outside maxExtent"); + m.destroy(); + + } + function test_Layer_WrapDateLine_KaMap (t) { + t.plan( 4 ); + + var layer = new OpenLayers.Layer.KaMap( "Blue Marble NG", + "http://www.openlayers.org/world/index.php", + {g: "satellite", map: "world"}, + {wrapDateLine: true, buffer: 2} ); + var m = new OpenLayers.Map('map', {tileManager: null, adjustZoom: function(z) {return z;}}); + m.addLayer(layer); + m.zoomToMaxExtent(); + t.eq(layer.grid[4][7].url, "http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=0&l=-256&s=221471921.25", "grid[5][7] kamap is okay"); + t.eq(layer.grid[4][6].url, "http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=0&l=0&s=221471921.25", "grid[5][6] kamap is okay"); + t.eq(layer.grid[4][5].url, "http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=0&l=-256&s=221471921.25", "grid[5][5] is okay"); + t.ok(layer.grid[7][6].url == null, "no latitudinal wrapping - tile not loaded if outside maxExtent"); + m.destroy(); + } + function test_Layer_WrapDateLine_WMS_Overlay (t) { + t.plan( 4 ); + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + baselayer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true, buffer: 2}); + var layer = new OpenLayers.Layer.WMS( "DM Solutions Demo", + "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap", + {layers: "bathymetry,land_fn,park,drain_fn,drainage," + + "prov_bound,fedlimit,rail,road,popplace", + transparent: "true", format: "image/png"}, + {wrapDateLine: true, encodeBBOX:true, buffer:2}); + var m = new OpenLayers.Map('map', {tileManager: null, adjustZoom: function(z) {return z;}}); + m.addLayers([baselayer,layer]); + m.zoomToMaxExtent(); + t.eq(layer.grid[3][0].url, "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256", "grid[0][0] wms overlay is okay"); + t.eq(layer.grid[3][1].url, "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180%2C-90%2C0%2C90&WIDTH=256&HEIGHT=256", "grid[0][3] wms overlay is okay"); + t.eq(layer.grid[3][2].url, "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256", "grid[3][0] wms overlay okay"); + t.ok(layer.grid[0][2].url == null, "no latitudinal wrapping - tile not loaded if outside maxExtent"); + m.destroy(); + } + + </script> +</head> +<body> +<div id="map" style="width:1000px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/XYZ.html b/misc/openlayers/tests/Layer/XYZ.html new file mode 100644 index 0000000..bd6d26e --- /dev/null +++ b/misc/openlayers/tests/Layer/XYZ.html @@ -0,0 +1,266 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var layer; + + var name = 'Test Layer'; + var url = "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/${z}/${x}/${y}.png"; + var options = {'layername':'basic', 'type':'png'}; + + + function test_Layer_XYZ_constructor (t) { + t.plan( 1 ); + + layer = new OpenLayers.Layer.XYZ(name, url, options); + t.ok( layer instanceof OpenLayers.Layer.XYZ, "returns OpenLayers.Layer.XYZ object" ); + } + + + + function test_Layer_XYZ_clearTiles (t) { + t.plan( 1 ); + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.XYZ(name, url, options); + map.addLayer(layer); + + map.setCenter(new OpenLayers.LonLat(0,0)); + + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.clearGrid(); + + t.ok( layer.grid != null, "layer.grid does not get nullified" ); + map.destroy(); + } + + + function test_Layer_XYZ_getXYZBounds(t) { + t.plan( 1 ); + + layer = new OpenLayers.Layer.XYZ(name, url, options); + + var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)}; + var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)}; + layer.grid = [ [6, tr], + [bl, 7]]; + + var bounds = layer.getTilesBounds(); + + var testBounds = new OpenLayers.Bounds(1,2,3,4); + + t.ok( bounds.equals(testBounds), "getXYZBounds() returns correct bounds") + + layer.grid = null; + } + + function test_Layer_XYZ_getResolution(t) { + t.plan( 1 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.XYZ(name, url, options); + map.addLayer(layer); + + map.zoom = 5; + + t.eq( layer.getResolution(), 0.0439453125, "getResolution() returns correct value"); + map.destroy(); + } + + function test_Layer_XYZ_getZoomForExtent(t) { + t.plan( 2 ); + var bounds, zoom; + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.XYZ(name, url, options); + map.addLayer(layer); + + bounds = new OpenLayers.Bounds(10,10,12,12); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 8, "getZoomForExtent() returns correct value"); + + bounds = new OpenLayers.Bounds(10,10,100,100); + zoom = layer.getZoomForExtent(bounds); + + t.eq( zoom, 2, "getZoomForExtent() returns correct value"); + map.destroy(); + } + + + /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR + * + * -moveTo + * -insertColumn + * -insertRow + + function 07_Layer_XYZ_moveTo(t) { + } + + function 08_Layer_XYZ_insertColumn(t) { + } + + function 09_Layer_XYZ_insertRow(t) { + } + + * + */ + function test_Layer_XYZ_getURL(t) { + + t.plan(6); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.XYZ(name, url); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 9); + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/63.png", "Tile URL is correct"); + + layer.url = ["http://tilecache1/", "http://tilecache2/", "http://tilecache3/"]; + tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://tilecache1/", "Tile URL is deterministic"); + + layer.url = url; + tileurl = layer.getURL(new OpenLayers.Bounds(180.515625,45,181.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/513/63.png", "Tile URL is correct"); + tileurl = layer.getURL(new OpenLayers.Bounds(-181.515625,45,-180.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/-2/63.png", "Tile URL is correct"); + layer.wrapDateLine = true; + tileurl = layer.getURL(new OpenLayers.Bounds(180.515625,45,181.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/1/63.png", "Tile URL is correct"); + tileurl = layer.getURL(new OpenLayers.Bounds(-181.515625,45,-180.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/510/63.png", "Tile URL is correct"); + map.destroy(); + } + function test_Layer_XYZ_Rounding(t) { + t.plan(1); + m = new OpenLayers.Map("map", {'maxExtent':new OpenLayers.Bounds(-122.6579,37.4901,-122.0738,37.8795)}); + layer = new OpenLayers.Layer.XYZ( "XYZ", + url, {layername: 'basic', type:'png', resolutions:[0.000634956337608418], buffer: 2} ); + m.addLayer(layer); + m.zoomToMaxExtent() + t.eq(layer.getURL(layer.grid[3][3].bounds), "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/0/1/0.png", "XYZ tiles around rounded properly."); + m.destroy(); + } + + function test_Layer_XYZ_setMap(t) { + + t.plan(3); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.XYZ(name, url); + + t.eq(layer.tileOrigin, null, "Tile origin starts out null"); + layer.setMap(map); + + t.eq(layer.tileOrigin.lat, -90, "lat is -90"); + t.eq(layer.tileOrigin.lon, -180, "lon is -180"); + map.destroy(); + } + + function test_Layer_XYZ_serverResolutions(t) { + t.plan(2); + + var map = new OpenLayers.Map('map', { + resolutions: [13,11] + }); + + var layer = new OpenLayers.Layer.XYZ(name, url, options); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 1); + + var tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0)); + var level = parseInt(tileurl.split('/')[7]); + t.eq(map.getZoom(), level, "Tile zoom level is correct without serverResolutions"); + + layer.serverResolutions = [14,13,12,11,10]; + tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0)); + level = parseInt(tileurl.split('/')[7]); + var res = map.getResolution(); + var gotLevel = OpenLayers.Util.indexOf(layer.serverResolutions, res); + t.eq(gotLevel, level, "Tile zoom level is correct with serverResolutions"); + + map.destroy(); + } + + function test_zoomOffset(t) { + + t.plan(2); + + var offset; + + // test offset of 2 + offset = 2; + + var map = new OpenLayers.Map({ + div: "map", + maxResolution: 1.40625 / Math.pow(2, offset) + }); + var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 7); + + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/63.png", "correct URL for offset of 2"); + + map.destroy(); + + // test offset of -1 + offset = -1; + + var map = new OpenLayers.Map({ + div: "map", + maxResolution: 1.40625 / Math.pow(2, offset) + }); + var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 10); + + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/63.png", "correct URL for offset of -1"); + + map.destroy(); + + + } + + function test_Layer_XYZ_destroy (t) { + + t.plan( 3 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.XYZ(name, url, options); + map.addLayer(layer); + layer.destroy(); + t.eq( layer.grid, null, "layer.grid is null after destroy" ); + t.eq( layer.tileSize, null, "layer.tileSize is null after destroy" ); + + + //test with tile creation + layer = new OpenLayers.Layer.XYZ(name, url, options); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 5); + //grab a reference to one of the tiles + var tile = layer.grid[0][0]; + + layer.destroy(); + + t.ok( layer.grid == null, "tiles appropriately destroyed"); + map.destroy(); + } + + function test_clone(t) { + t.plan(1); + + layer = new OpenLayers.Layer.XYZ(name, url, options); + var clone = layer.clone(); + t.ok(clone instanceof OpenLayers.Layer.XYZ, "clone is a Layer.XYZ instance"); + } + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> diff --git a/misc/openlayers/tests/Layer/atom-1.0.xml b/misc/openlayers/tests/Layer/atom-1.0.xml new file mode 100644 index 0000000..f0d5d6f --- /dev/null +++ b/misc/openlayers/tests/Layer/atom-1.0.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<feed xmlns="http://www.w3.org/2005/Atom" + xmlns:georss="http://www.georss.org/georss"> + + <title>tumulus</title> + <link rel="self" + href="http://pleiades.stoa.org/places/tumulus"/> + <updated/> + <author/> + <id>http://pleiades.stoa.org/places/tumulus</id> + + <entry> + <title>Unnamed Tumulus</title> + <link rel="alternate" + href="http://pleiades.stoa.org/places/638896" + /> + <id>http://pleiades.stoa.org/places/638896</id> + <updated/> + <summary>An ancient tumulus, attested during the Classical period (modern location: Karaburun). Its ancient name is not known.</summary> + <georss:point>36.7702 29.9805</georss:point> + </entry> + <entry> + <title>Unnamed Tumulus</title> + <link rel="alternate" + href="http://pleiades.stoa.org/places/638924" + /> + <id>http://pleiades.stoa.org/places/638924</id> + <updated/> + <summary>An ancient tumulus, attested during the Classical period (modern location: Kızılbel). Its ancient name is not known.</summary> + <georss:point>36.7263 29.8619</georss:point> + </entry> + +</feed> + diff --git a/misc/openlayers/tests/Layer/data_Layer_Text_textfile.txt b/misc/openlayers/tests/Layer/data_Layer_Text_textfile.txt new file mode 100644 index 0000000..8250988 --- /dev/null +++ b/misc/openlayers/tests/Layer/data_Layer_Text_textfile.txt @@ -0,0 +1,3 @@ +point image +10,20 http://boston.openguides.org/markers/ORANGE.png +15,25 http://boston.openguides.org/markers/ORANGE.png diff --git a/misc/openlayers/tests/Layer/data_Layer_Text_textfile_2.txt b/misc/openlayers/tests/Layer/data_Layer_Text_textfile_2.txt new file mode 100644 index 0000000..91a8093 --- /dev/null +++ b/misc/openlayers/tests/Layer/data_Layer_Text_textfile_2.txt @@ -0,0 +1,3 @@ +point title description image +10,20 a b http://boston.openguides.org/markers/ORANGE.png +15,25 c d http://boston.openguides.org/markers/ORANGE.png diff --git a/misc/openlayers/tests/Layer/data_Layer_Text_textfile_overflow.txt b/misc/openlayers/tests/Layer/data_Layer_Text_textfile_overflow.txt new file mode 100644 index 0000000..bb4768e --- /dev/null +++ b/misc/openlayers/tests/Layer/data_Layer_Text_textfile_overflow.txt @@ -0,0 +1,3 @@ +overflow point title description image +auto 10,20 a b http://boston.openguides.org/markers/ORANGE.png +hidden 15,25 c d http://boston.openguides.org/markers/ORANGE.png diff --git a/misc/openlayers/tests/Layer/georss.txt b/misc/openlayers/tests/Layer/georss.txt new file mode 100644 index 0000000..053749b --- /dev/null +++ b/misc/openlayers/tests/Layer/georss.txt @@ -0,0 +1,378 @@ +<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/css" href="/css/rss.css" ?> + +<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://purl.org/rss/1.0/" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:georss="http://www.georss.org/georss"> +<docs>This is an RSS file. Copy the URL into your aggregator of choice. If you don't know what this means and want to learn more, please see: <span>http://platial.typepad.com/news/2006/04/really_simple_t.html</span> for more info.</docs><channel rdf:about="http://platial.com"> +<link>http://platial.com</link> +<title>Crschmidt's Places At Platial</title> +<description></description> +<items> +<rdf:Seq> +<rdf:li resource="http://platial.com/place/90306"/> +<rdf:li resource="http://platial.com/place/67230"/> +<rdf:li resource="http://platial.com/place/65645"/> +<rdf:li resource="http://platial.com/place/62200"/> +<rdf:li resource="http://platial.com/place/28232"/> +<rdf:li resource="http://platial.com/place/43666"/> +<rdf:li resource="http://platial.com/place/28394"/> +<rdf:li resource="http://platial.com/place/28251"/> +<rdf:li resource="http://platial.com/place/28392"/> +<rdf:li resource="http://platial.com/place/28391"/> +<rdf:li resource="http://platial.com/place/28231"/> +<rdf:li resource="http://platial.com/place/28393"/> +<rdf:li resource="http://platial.com/place/31685"/> +<rdf:li resource="http://platial.com/place/28596"/> +<rdf:li resource="http://platial.com/place/28595"/> +<rdf:li resource="http://platial.com/place/28594"/> +<rdf:li resource="http://platial.com/place/28593"/> +<rdf:li resource="http://platial.com/place/28592"/> +<rdf:li resource="http://platial.com/place/28591"/> +<rdf:li resource="http://platial.com/place/28590"/> +<rdf:li resource="http://platial.com/place/28589"/> +<rdf:li resource="http://platial.com/place/28588"/> +<rdf:li resource="http://platial.com/place/28587"/> +<rdf:li resource="http://platial.com/place/28586"/> +<rdf:li resource="http://platial.com/place/28585"/> +<rdf:li resource="http://platial.com/place/28584"/> +<rdf:li resource="http://platial.com/place/28583"/> +<rdf:li resource="http://platial.com/place/28582"/> +<rdf:li resource="http://platial.com/place/28581"/> +<rdf:li resource="http://platial.com/place/28580"/> +<rdf:li resource="http://platial.com/place/28579"/> +<rdf:li resource="http://platial.com/place/28578"/> +<rdf:li resource="http://platial.com/place/28577"/> +<rdf:li resource="http://platial.com/place/28576"/> +<rdf:li resource="http://platial.com/place/28575"/> +<rdf:li resource="http://platial.com/place/28574"/> +<rdf:li resource="http://platial.com/place/28573"/> +<rdf:li resource="http://platial.com/place/28572"/> +<rdf:li resource="http://platial.com/place/28571"/> +<rdf:li resource="http://platial.com/place/28570"/> +</rdf:Seq> +</items> +</channel> +<item rdf:about="http://platial.com/place/90306"> +<link>http://platial.com/place/90306</link> +<title>Knitting Room</title> +<description><![CDATA[This little shop is jammed full. Yarn, yarn everywhere. They make the most of every possible nook and cranny. I like this place also because they have a lot of different kinds of knitting needles in all different sizes. Also, the people who work here are younger and hipper than in the other stores I go to. I reccomend buying supplies here and then knitting your way through a good documentary at the Capitol Theater across the street.<br/>Address: 2 lake St, Arlington, MA <br/>Tags: knitting, yarn, pins and needles, handspun, hand dyed, novelty yarn, fancy, simple, young, hip, friendly, needles, addy, cute hats<br /><br /><a href="http://platial.com/place/90306">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/90306">Grab this on Platial</a> ]]></description> +<georss:point>42.405696 -71.142197</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-06-08T17:35:01.942452+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/67230"> +<link>http://platial.com/place/67230</link> +<title>Knitting Room</title> +<description><![CDATA[This little shop is jammed full. Yarn, yarn everywhere. They make the most of every possible nook and cranny. I like this place also because they have a lot of different kinds of knitting needles in all different sizes. Also, the people who work here are younger and hipper than in the other stores I go to. I reccomend buying supplies here and then knitting your way through a good documentary at the Capitol Theater across the street.<br/>Address: 2 lake St, Arlington, MA <br/>Tags: knitting, yarn, pins and needles, handspun, hand dyed, novelty yarn, fancy, simple, young, hip, friendly, needles, addy, cute hats<br /><br /><a href="http://platial.com/place/67230">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/67230">Grab this on Platial</a> ]]></description> +<georss:point>42.405524 -71.142273</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-04-24T11:35:26.733857+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/65645"> +<link>http://platial.com/place/65645</link> +<title>â ¢¢â¢Â£ËøÅ</title> +<description><![CDATA[ijeª£âµËËî<br/>Address: 151 Erie St., Cambridge, MA<br/>Tags: platial graffiti<br /><br /><a href="http://platial.com/place/65645">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/65645">Grab this on Platial</a> ]]></description> +<georss:point>42.352455 -71.110210</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-04-20T08:56:12.696224+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/62200"> +<link>http://platial.com/place/62200</link> +<title>Allen Hall</title> +<description><![CDATA[My dorm at UIUC.<br/>Address: 1301 W Gregory Dr, Urbana, IL<br/>Tags: dorm, uiuc, college<br/><a href="http://platial.com/place/62200"><img src="http://platial.comhttp://static.flickr.com/4/8576450_0d59cc2531_s.jpg"/></a><br/><br /><br /><a href="http://platial.com/place/62200">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/62200">Grab this on Platial</a> ]]></description> +<georss:point>40.104172 -88.220623</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-04-14T08:01:01.872873+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28232"> +<link>http://platial.com/place/28232</link> +<title>Bagby Hot Springs, OR</title> +<description><![CDATA[Hot spring, temperature: 136 degress F, 58 degress C. However, the area around the springs are not exactly well looked upon by people who know the place. + +<br/>Tags: 20s, rosalie, romance, childhood, hike, camping, soak, relax, beautiful, hot springs, bathhouse, favorite, popular, crowded, organized, honeymoon tub, plumbing made from hollowed out trees, hot springs, mt hood, notorious car break in spot, rash, bacteria<br /><br /><a href="http://platial.com/place/28232">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28232">Grab this on Platial</a> ]]></description> +<georss:point>44.936000 -122.173000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:10:18.553063+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/43666"> +<link>http://platial.com/place/43666</link> +<title>Shooting Location for "The Field of Dreams" Film</title> +<description><![CDATA[1989's Field of Dreams was a Best Picture Academy Award nominee, and the baseball field in the cornfield still stands today, and has become quite a tourist destination. Games are occasionally played at the field, re-enacting professional baseball at the turn of the 20th Century.<br/>Address: Dyersville, Iowa<br/>Tags: iowa, baseball, movie locations, field of dreams, kevin costner, costner, dyersville, kinsella, james earl jones, chicago black sox, shoeless joe, joe jackson, famous farms, film, movie, cinema, shooting location<br /><br /><a href="http://platial.com/place/43666">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/43666">Grab this on Platial</a> ]]></description> +<georss:point>42.481213 -91.111679</georss:point> +<dc:creator>echinodermata</dc:creator> +<dc:date>2006-03-23T11:40:17.654061+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28394"> +<link>http://platial.com/place/28394</link> +<title>Moffetts (Bonneville) Hot Springs, WA</title> +<description><![CDATA[Hot spring, temperature: 97 degress F, 36 degress C<br/>Tags: soak, hot springs, relax, nature<br /><br /><a href="http://platial.com/place/28394">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28394">Grab this on Platial</a> ]]></description> +<georss:point>45.658000 -121.962000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:16:27.329816+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28251"> +<link>http://platial.com/place/28251</link> +<title>Austin Hot Springs, OR</title> +<description><![CDATA[Hot spring, temperature: 186 degress F, 86 degress C<br/>Tags: soak, hot springs, relax, nature, popular, crowded<br /><br /><a href="http://platial.com/place/28251">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28251">Grab this on Platial</a> ]]></description> +<georss:point>45.021000 -122.009000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:11:04.489886+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28392"> +<link>http://platial.com/place/28392</link> +<title>Rock Creek Hot Springs, WA</title> +<description><![CDATA[Hot spring, temperature: Hot degress F, Hot degress C<br/>Tags: soak, hot springs, relax, nature<br /><br /><a href="http://platial.com/place/28392">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28392">Grab this on Platial</a> ]]></description> +<georss:point>45.723000 -121.927000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:16:22.636855+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28391"> +<link>http://platial.com/place/28391</link> +<title>St. Martins (Wind River) Hot Springs, WA</title> +<description><![CDATA[Hot spring, temperature: 120 degress F, 49 degress C<br/>Tags: hot springs, soak, relax, nature, wonderful<br /><br /><a href="http://platial.com/place/28391">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28391">Grab this on Platial</a> ]]></description> +<georss:point>45.728000 -121.800000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:16:20.383244+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28231"> +<link>http://platial.com/place/28231</link> +<title>Breitenbush Hot Springs, OR</title> +<description><![CDATA[Hot spring, temperature: 198 degress F, 92 degress C<br/>Tags: hot springs, resort, relax, nature, beautiful, http:www.breitenbush.com, soaking<br /><br /><a href="http://platial.com/place/28231">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28231">Grab this on Platial</a> ]]></description> +<georss:point>44.782000 -121.975000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:10:16.529195+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28393"> +<link>http://platial.com/place/28393</link> +<title>Collins Hot Springs, WA</title> +<description><![CDATA[Hot spring, temperature: 122 degress F, 50 degress C<br/>Tags: portland, nice, hot springs, soak<br /><br /><a href="http://platial.com/place/28393">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28393">Grab this on Platial</a> ]]></description> +<georss:point>45.701000 -121.728000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:16:24.648745+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/31685"> +<link>http://platial.com/place/31685</link> +<title>Darwin's Ltd.</title> +<description><![CDATA[Nice little coffee shop/cafe, free Wifi, close enough to walk from Harvard Square.<br/>Address: 148 Mount Auburn St, Cambridge, MA<br/>Tags: coffee, beer, sandwiches, freewifi<br/><a href="http://platial.com/place/31685"><img src="http://platial.comhttp://static.flickr.com/38/84885937_74fd3d1025_s.jpg"/></a><br/><br /><br /><a href="http://platial.com/place/31685">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/31685">Grab this on Platial</a> ]]></description> +<georss:point>42.373974 -71.125053</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-10T09:24:08.152985+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28596"> +<link>http://platial.com/place/28596</link> +<title>Huckleberry Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: Boiling degress F, Boiling degress C<br /><br /><a href="http://platial.com/place/28596">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28596">Grab this on Platial</a> ]]></description> +<georss:point>44.115000 -110.684000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:32.283094+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28595"> +<link>http://platial.com/place/28595</link> +<title>South Entrance Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: 156 degress F, 69 degress C<br/><a href="http://platial.com/place/28595"><img src="http://platial.comhttp://static.flickr.com/52/130989872_f1457f68b5_s.jpg"/></a><br/><br /><br /><a href="http://platial.com/place/28595">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28595">Grab this on Platial</a> ]]></description> +<georss:point>44.142000 -110.656000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:30.279497+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28594"> +<link>http://platial.com/place/28594</link> +<title>Crawfish Creek Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: 136 degress F, 58 degress C<br/><a href="http://platial.com/place/28594"><img src="http://platial.comhttp://static.flickr.com/52/128312256_d6a879924c_s.jpg"/></a><br/><br /><br /><a href="http://platial.com/place/28594">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28594">Grab this on Platial</a> ]]></description> +<georss:point>44.157000 -110.699000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:28.280271+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28593"> +<link>http://platial.com/place/28593</link> +<title>Crawfish Creek Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: 138 degress F, 59 degress C<br /><br /><a href="http://platial.com/place/28593">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28593">Grab this on Platial</a> ]]></description> +<georss:point>44.165000 -110.723000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:20.364077+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28592"> +<link>http://platial.com/place/28592</link> +<title>Snake Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: 136 degress F, 58 degress C<br /><br /><a href="http://platial.com/place/28592">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28592">Grab this on Platial</a> ]]></description> +<georss:point>44.169000 -110.583000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:12.234974+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28591"> +<link>http://platial.com/place/28591</link> +<title>Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: 142 degress F, 61 degress C<br /><br /><a href="http://platial.com/place/28591">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28591">Grab this on Platial</a> ]]></description> +<georss:point>44.187000 -110.726000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:10.027857+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28590"> +<link>http://platial.com/place/28590</link> +<title>Hot Springs on Upper Snake River, WY</title> +<description><![CDATA[Hot spring, temperature: 167 degress F, 75 degress C<br /><br /><a href="http://platial.com/place/28590">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28590">Grab this on Platial</a> ]]></description> +<georss:point>44.204000 -110.486000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:07.79658+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28589"> +<link>http://platial.com/place/28589</link> +<title>Hot Springs on lewis Lake, WY</title> +<description><![CDATA[Hot spring, temperature: 154 degress F, 68 degress C<br /><br /><a href="http://platial.com/place/28589">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28589">Grab this on Platial</a> ]]></description> +<georss:point>44.276000 -110.636000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:05.683418+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28588"> +<link>http://platial.com/place/28588</link> +<title>Rustic Geyser, WY</title> +<description><![CDATA[Hot spring, temperature: 199 degress F, 93 degress C<br /><br /><a href="http://platial.com/place/28588">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28588">Grab this on Platial</a> ]]></description> +<georss:point>44.282000 -110.506000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:03.66329+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28587"> +<link>http://platial.com/place/28587</link> +<title>Bechler River Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: 194 degress F, 90 degress C<br /><br /><a href="http://platial.com/place/28587">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28587">Grab this on Platial</a> ]]></description> +<georss:point>44.285000 -110.900000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:24:01.611442+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28586"> +<link>http://platial.com/place/28586</link> +<title>Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: Boiling degress F, 201 degress C<br /><br /><a href="http://platial.com/place/28586">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28586">Grab this on Platial</a> ]]></description> +<georss:point>44.290000 -110.504000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:59.658699+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28585"> +<link>http://platial.com/place/28585</link> +<title>Heart Lake Geyser Basin, WY</title> +<description><![CDATA[Hot spring, temperature: Middle Group degress F, 174 degress C<br /><br /><a href="http://platial.com/place/28585">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28585">Grab this on Platial</a> ]]></description> +<georss:point>44.299000 -110.517000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:57.181801+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28584"> +<link>http://platial.com/place/28584</link> +<title>Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: Boiling degress F, 201 degress C<br /><br /><a href="http://platial.com/place/28584">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28584">Grab this on Platial</a> ]]></description> +<georss:point>44.307000 -110.526000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:55.240485+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28583"> +<link>http://platial.com/place/28583</link> +<title>Hot Springs on lewis Lake, WY</title> +<description><![CDATA[Hot spring, temperature: 199 degress F, 93 degress C<br /><br /><a href="http://platial.com/place/28583">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28583">Grab this on Platial</a> ]]></description> +<georss:point>44.309000 -110.654000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:53.22295+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28582"> +<link>http://platial.com/place/28582</link> +<title>Shoshone Geyser Basin, WY</title> +<description><![CDATA[Hot spring, temperature: 203 degress F, 95 degress C<br /><br /><a href="http://platial.com/place/28582">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28582">Grab this on Platial</a> ]]></description> +<georss:point>44.354000 -110.800000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:51.179049+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28581"> +<link>http://platial.com/place/28581</link> +<title>Hot Springs on Continental Divide, WY</title> +<description><![CDATA[Hot spring, temperature: 189 degress F, 87 degress C<br /><br /><a href="http://platial.com/place/28581">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28581">Grab this on Platial</a> ]]></description> +<georss:point>44.401000 -110.936000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:49.077176+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28580"> +<link>http://platial.com/place/28580</link> +<title>Hot Springs on Upper Firehole River, WY</title> +<description><![CDATA[Hot spring, temperature: Hot degress F, Hot degress C<br /><br /><a href="http://platial.com/place/28580">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28580">Grab this on Platial</a> ]]></description> +<georss:point>44.404000 -110.824000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:47.054664+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28579"> +<link>http://platial.com/place/28579</link> +<title>Summit Lake Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: 162 degress F, 72 degress C<br /><br /><a href="http://platial.com/place/28579">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28579">Grab this on Platial</a> ]]></description> +<georss:point>44.410000 -110.953000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:45.039394+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28578"> +<link>http://platial.com/place/28578</link> +<title>Lone Star Geyser Basin, WY</title> +<description><![CDATA[Hot spring, temperature: Footbridge degress F, 183 degress C<br /><br /><a href="http://platial.com/place/28578">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28578">Grab this on Platial</a> ]]></description> +<georss:point>44.414000 -110.817000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:42.938808+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28577"> +<link>http://platial.com/place/28577</link> +<title>West. Thumb Geyser Basin, WY</title> +<description><![CDATA[Hot spring, temperature: 203 degress F, 95 degress C<br /><br /><a href="http://platial.com/place/28577">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28577">Grab this on Platial</a> ]]></description> +<georss:point>44.417000 -110.570000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:40.90238+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28576"> +<link>http://platial.com/place/28576</link> +<title>Lone Star Geyser, WY</title> +<description><![CDATA[Hot spring, temperature: 199 degress F, 93 degress C<br /><br /><a href="http://platial.com/place/28576">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28576">Grab this on Platial</a> ]]></description> +<georss:point>44.418000 -110.805000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:38.844625+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28575"> +<link>http://platial.com/place/28575</link> +<title>Smoke Jumper Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: 198 degress F, 92 degress C<br /><br /><a href="http://platial.com/place/28575">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28575">Grab this on Platial</a> ]]></description> +<georss:point>44.421000 -110.952000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:36.818513+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28574"> +<link>http://platial.com/place/28574</link> +<title>West. Thumb Geyser Basin, WY</title> +<description><![CDATA[Hot spring, temperature: 196 degress F, 91 degress C<br /><br /><a href="http://platial.com/place/28574">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28574">Grab this on Platial</a> ]]></description> +<georss:point>44.422000 -110.574000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:34.767729+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28573"> +<link>http://platial.com/place/28573</link> +<title>Potts Hot Spring Basin, WY</title> +<description><![CDATA[Hot spring, temperature: 203 degress F, 95 degress C<br /><br /><a href="http://platial.com/place/28573">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28573">Grab this on Platial</a> ]]></description> +<georss:point>44.433000 -110.581000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:32.749915+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28572"> +<link>http://platial.com/place/28572</link> +<title>Hot Springs, WY</title> +<description><![CDATA[Hot spring, temperature: Hot degress F, Hot degress C<br /><br /><a href="http://platial.com/place/28572">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28572">Grab this on Platial</a> ]]></description> +<georss:point>44.433000 -110.813000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:30.829745+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28571"> +<link>http://platial.com/place/28571</link> +<title>Hot Springs on Continental Divide, WY</title> +<description><![CDATA[Hot spring, temperature: Hot degress F, Hot degress C<br /><br /><a href="http://platial.com/place/28571">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28571">Grab this on Platial</a> ]]></description> +<georss:point>44.438000 -110.977000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:28.730401+00:00</dc:date> +</item> +<item rdf:about="http://platial.com/place/28570"> +<link>http://platial.com/place/28570</link> +<title>SouthEastern Group, WY</title> +<description><![CDATA[Hot spring, temperature: 198 degress F, 92 degress C<br /><br /><a href="http://platial.com/place/28570">Map this on Platial</a><br /> <a href="http://platial.com/place_grab/28570">Grab this on Platial</a> ]]></description> +<georss:point>44.459000 -110.817000</georss:point> +<dc:creator>crschmidt</dc:creator> +<dc:date>2006-01-03T23:23:26.706763+00:00</dc:date> +</item> +</rdf:RDF>
\ No newline at end of file |