diff options
Diffstat (limited to 'misc/openlayers/lib/OpenLayers/Layer/ArcGISCache.js')
-rw-r--r-- | misc/openlayers/lib/OpenLayers/Layer/ArcGISCache.js | 480 |
1 files changed, 0 insertions, 480 deletions
diff --git a/misc/openlayers/lib/OpenLayers/Layer/ArcGISCache.js b/misc/openlayers/lib/OpenLayers/Layer/ArcGISCache.js deleted file mode 100644 index 99f7dda..0000000 --- a/misc/openlayers/lib/OpenLayers/Layer/ArcGISCache.js +++ /dev/null @@ -1,480 +0,0 @@ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for - * full list of contributors). Published under the 2-clause BSD license. - * See license.txt in the OpenLayers distribution or repository for the - * full text of the license. */ - -/** - * @requires OpenLayers/Layer/XYZ.js - */ - -/** - * Class: OpenLayers.Layer.ArcGISCache - * Layer for accessing cached map tiles from an ArcGIS Server style mapcache. - * Tile must already be cached for this layer to access it. This does not require - * ArcGIS Server itself. - * - * A few attempts have been made at this kind of layer before. See - * http://trac.osgeo.org/openlayers/ticket/1967 - * and - * http://trac.osgeo.org/openlayers/browser/sandbox/tschaub/arcgiscache/lib/OpenLayers/Layer/ArcGISCache.js - * - * Typically the problem encountered is that the tiles seem to "jump around". - * This is due to the fact that the actual max extent for the tiles on AGS layers - * changes at each zoom level due to the way these caches are constructed. - * We have attempted to use the resolutions, tile size, and tile origin - * from the cache meta data to make the appropriate changes to the max extent - * of the tile to compensate for this behavior. This must be done as zoom levels change - * and before tiles are requested, which is why methods from base classes are overridden. - * - * For reference, you can access mapcache meta data in two ways. For accessing a - * mapcache through ArcGIS Server, you can simply go to the landing page for the - * layer. (ie. http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer) - * For accessing it directly through HTTP, there should always be a conf.xml file - * in the root directory. - * (ie. http://serverx.esri.com/arcgiscache/DG_County_roads_yesA_backgroundDark/Layers/conf.xml) - * - *Inherits from: - * - <OpenLayers.Layer.XYZ> - */ -OpenLayers.Layer.ArcGISCache = OpenLayers.Class(OpenLayers.Layer.XYZ, { - - /** - * APIProperty: url - * {String | Array} The base URL for the layer cache. You can also - * provide a list of URL strings for the layer if your cache is - * available from multiple origins. This must be set before the layer - * is drawn. - */ - url: null, - - /** - * APIProperty: tileOrigin - * {<OpenLayers.LonLat>} The location of the tile origin for the cache. - * An ArcGIS cache has it's origin at the upper-left (lowest x value - * and highest y value of the coordinate system). The units for the - * tile origin should be the same as the units for the cached data. - */ - tileOrigin: null, - - /** - * APIProperty: tileSize - * {<OpenLayers.Size>} This size of each tile. Defaults to 256 by 256 pixels. - */ - tileSize: new OpenLayers.Size(256, 256), - - /** - * APIProperty: useAGS - * {Boolean} Indicates if we are going to be accessing the ArcGIS Server (AGS) - * cache via an AGS MapServer or directly through HTTP. When accessing via - * AGS the path structure uses a standard z/y/x structure. But AGS actually - * stores the tile images on disk using a hex based folder structure that looks - * like "http://example.com/mylayer/L00/R00000000/C00000000.png". Learn more - * about this here: - * http://blogs.esri.com/Support/blogs/mappingcenter/archive/2010/08/20/Checking-Your-Local-Cache-Folders.aspx - * Defaults to true; - */ - useArcGISServer: true, - - /** - * APIProperty: type - * {String} Image type for the layer. This becomes the filename extension - * in tile requests. Default is "png" (generating a url like - * "http://example.com/mylayer/L00/R00000000/C00000000.png"). - */ - type: 'png', - - /** - * APIProperty: useScales - * {Boolean} Optional override to indicate that the layer should use 'scale' information - * returned from the server capabilities object instead of 'resolution' information. - * This can be important if your tile server uses an unusual DPI for the tiles. - */ - useScales: false, - - /** - * APIProperty: overrideDPI - * {Boolean} Optional override to change the OpenLayers.DOTS_PER_INCH setting based - * on the tile information in the server capabilities object. This can be useful - * if your server has a non-standard DPI setting on its tiles, and you're only using - * tiles with that DPI. This value is used while OpenLayers is calculating resolution - * using scales, and is not necessary if you have resolution information. (This is - * typically the case) Regardless, this setting can be useful, but is dangerous - * because it will impact other layers while calculating resolution. Only use this - * if you know what you are doing. (See OpenLayers.Util.getResolutionFromScale) - */ - overrideDPI: false, - - /** - * Constructor: OpenLayers.Layer.ArcGISCache - * Creates a new instance of this class - * - * Parameters: - * name - {String} - * url - {String} - * options - {Object} extra layer options - */ - initialize: function(name, url, options) { - OpenLayers.Layer.XYZ.prototype.initialize.apply(this, arguments); - - if (this.resolutions) { - this.serverResolutions = this.resolutions; - this.maxExtent = this.getMaxExtentForResolution(this.resolutions[0]); - } - - // this block steps through translating the values from the server layer JSON - // capabilities object into values that we can use. This is also a helpful - // reference when configuring this layer directly. - if (this.layerInfo) { - // alias the object - var info = this.layerInfo; - - // build our extents - var startingTileExtent = new OpenLayers.Bounds( - info.fullExtent.xmin, - info.fullExtent.ymin, - info.fullExtent.xmax, - info.fullExtent.ymax - ); - - // set our projection based on the given spatial reference. - // esri uses slightly different IDs, so this may not be comprehensive - this.projection = 'EPSG:' + info.spatialReference.wkid; - this.sphericalMercator = (info.spatialReference.wkid == 102100); - - // convert esri units into openlayers units (basic feet or meters only) - this.units = (info.units == "esriFeet") ? 'ft' : 'm'; - - // optional extended section based on whether or not the server returned - // specific tile information - if (!!info.tileInfo) { - // either set the tiles based on rows/columns, or specific width/height - this.tileSize = new OpenLayers.Size( - info.tileInfo.width || info.tileInfo.cols, - info.tileInfo.height || info.tileInfo.rows - ); - - // this must be set when manually configuring this layer - this.tileOrigin = new OpenLayers.LonLat( - info.tileInfo.origin.x, - info.tileInfo.origin.y - ); - - var upperLeft = new OpenLayers.Geometry.Point( - startingTileExtent.left, - startingTileExtent.top - ); - - var bottomRight = new OpenLayers.Geometry.Point( - startingTileExtent.right, - startingTileExtent.bottom - ); - - if (this.useScales) { - this.scales = []; - } else { - this.resolutions = []; - } - - this.lods = []; - for(var key in info.tileInfo.lods) { - if (info.tileInfo.lods.hasOwnProperty(key)) { - var lod = info.tileInfo.lods[key]; - if (this.useScales) { - this.scales.push(lod.scale); - } else { - this.resolutions.push(lod.resolution); - } - - var start = this.getContainingTileCoords(upperLeft, lod.resolution); - lod.startTileCol = start.x; - lod.startTileRow = start.y; - - var end = this.getContainingTileCoords(bottomRight, lod.resolution); - lod.endTileCol = end.x; - lod.endTileRow = end.y; - this.lods.push(lod); - } - } - - this.maxExtent = this.calculateMaxExtentWithLOD(this.lods[0]); - this.serverResolutions = this.resolutions; - if (this.overrideDPI && info.tileInfo.dpi) { - // see comment above for 'overrideDPI' - OpenLayers.DOTS_PER_INCH = info.tileInfo.dpi; - } - } - } - }, - - /** - * Method: getContainingTileCoords - * Calculates the x/y pixel corresponding to the position of the tile - * that contains the given point and for the for the given resolution. - * - * Parameters: - * point - {<OpenLayers.Geometry.Point>} - * res - {Float} The resolution for which to compute the extent. - * - * Returns: - * {<OpenLayers.Pixel>} The x/y pixel corresponding to the position - * of the upper left tile for the given resolution. - */ - getContainingTileCoords: function(point, res) { - return new OpenLayers.Pixel( - Math.max(Math.floor((point.x - this.tileOrigin.lon) / (this.tileSize.w * res)),0), - Math.max(Math.floor((this.tileOrigin.lat - point.y) / (this.tileSize.h * res)),0) - ); - }, - - /** - * Method: calculateMaxExtentWithLOD - * Given a Level of Detail object from the server, this function - * calculates the actual max extent - * - * Parameters: - * lod - {Object} a Level of Detail Object from the server capabilities object - representing a particular zoom level - * - * Returns: - * {<OpenLayers.Bounds>} The actual extent of the tiles for the given zoom level - */ - calculateMaxExtentWithLOD: function(lod) { - // the max extent we're provided with just overlaps some tiles - // our real extent is the bounds of all the tiles we touch - - var numTileCols = (lod.endTileCol - lod.startTileCol) + 1; - var numTileRows = (lod.endTileRow - lod.startTileRow) + 1; - - var minX = this.tileOrigin.lon + (lod.startTileCol * this.tileSize.w * lod.resolution); - var maxX = minX + (numTileCols * this.tileSize.w * lod.resolution); - - var maxY = this.tileOrigin.lat - (lod.startTileRow * this.tileSize.h * lod.resolution); - var minY = maxY - (numTileRows * this.tileSize.h * lod.resolution); - return new OpenLayers.Bounds(minX, minY, maxX, maxY); - }, - - /** - * Method: calculateMaxExtentWithExtent - * Given a 'suggested' max extent from the server, this function uses - * information about the actual tile sizes to determine the actual - * extent of the layer. - * - * Parameters: - * extent - {<OpenLayers.Bounds>} The 'suggested' extent for the layer - * res - {Float} The resolution for which to compute the extent. - * - * Returns: - * {<OpenLayers.Bounds>} The actual extent of the tiles for the given zoom level - */ - calculateMaxExtentWithExtent: function(extent, res) { - var upperLeft = new OpenLayers.Geometry.Point(extent.left, extent.top); - var bottomRight = new OpenLayers.Geometry.Point(extent.right, extent.bottom); - var start = this.getContainingTileCoords(upperLeft, res); - var end = this.getContainingTileCoords(bottomRight, res); - var lod = { - resolution: res, - startTileCol: start.x, - startTileRow: start.y, - endTileCol: end.x, - endTileRow: end.y - }; - return this.calculateMaxExtentWithLOD(lod); - }, - - /** - * Method: getUpperLeftTileCoord - * Calculates the x/y pixel corresponding to the position - * of the upper left tile for the given resolution. - * - * Parameters: - * res - {Float} The resolution for which to compute the extent. - * - * Returns: - * {<OpenLayers.Pixel>} The x/y pixel corresponding to the position - * of the upper left tile for the given resolution. - */ - getUpperLeftTileCoord: function(res) { - var upperLeft = new OpenLayers.Geometry.Point( - this.maxExtent.left, - this.maxExtent.top); - return this.getContainingTileCoords(upperLeft, res); - }, - - /** - * Method: getLowerRightTileCoord - * Calculates the x/y pixel corresponding to the position - * of the lower right tile for the given resolution. - * - * Parameters: - * res - {Float} The resolution for which to compute the extent. - * - * Returns: - * {<OpenLayers.Pixel>} The x/y pixel corresponding to the position - * of the lower right tile for the given resolution. - */ - getLowerRightTileCoord: function(res) { - var bottomRight = new OpenLayers.Geometry.Point( - this.maxExtent.right, - this.maxExtent.bottom); - return this.getContainingTileCoords(bottomRight, res); - }, - - /** - * Method: getMaxExtentForResolution - * Since the max extent of a set of tiles can change from zoom level - * to zoom level, we need to be able to calculate that max extent - * for a given resolution. - * - * Parameters: - * res - {Float} The resolution for which to compute the extent. - * - * Returns: - * {<OpenLayers.Bounds>} The extent for this resolution - */ - getMaxExtentForResolution: function(res) { - var start = this.getUpperLeftTileCoord(res); - var end = this.getLowerRightTileCoord(res); - - var numTileCols = (end.x - start.x) + 1; - var numTileRows = (end.y - start.y) + 1; - - var minX = this.tileOrigin.lon + (start.x * this.tileSize.w * res); - var maxX = minX + (numTileCols * this.tileSize.w * res); - - var maxY = this.tileOrigin.lat - (start.y * this.tileSize.h * res); - var minY = maxY - (numTileRows * this.tileSize.h * res); - return new OpenLayers.Bounds(minX, minY, maxX, maxY); - }, - - /** - * APIMethod: clone - * Returns an exact clone of this OpenLayers.Layer.ArcGISCache - * - * Parameters: - * [obj] - {Object} optional object to assign the cloned instance to. - * - * Returns: - * {<OpenLayers.Layer.ArcGISCache>} clone of this instance - */ - clone: function (obj) { - if (obj == null) { - obj = new OpenLayers.Layer.ArcGISCache(this.name, this.url, this.options); - } - return OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]); - }, - - /** - * Method: initGriddedTiles - * - * Parameters: - * bounds - {<OpenLayers.Bounds>} - */ - initGriddedTiles: function(bounds) { - delete this._tileOrigin; - OpenLayers.Layer.XYZ.prototype.initGriddedTiles.apply(this, arguments); - }, - - /** - * Method: getMaxExtent - * Get this layer's maximum extent. - * - * Returns: - * {<OpenLayers.Bounds>} - */ - getMaxExtent: function() { - var resolution = this.map.getResolution(); - return this.maxExtent = this.getMaxExtentForResolution(resolution); - }, - - /** - * Method: getTileOrigin - * Determine the origin for aligning the grid of tiles. - * The origin will be derived from the layer's <maxExtent> property. - * - * Returns: - * {<OpenLayers.LonLat>} The tile origin. - */ - getTileOrigin: function() { - if (!this._tileOrigin) { - var extent = this.getMaxExtent(); - this._tileOrigin = new OpenLayers.LonLat(extent.left, extent.bottom); - } - return this._tileOrigin; - }, - - /** - * Method: getURL - * Determine the URL for a tile given the tile bounds. This is should support - * urls that access tiles through an ArcGIS Server MapServer or directly through - * the hex folder structure using HTTP. Just be sure to set the useArcGISServer - * property appropriately! This is basically the same as - * 'OpenLayers.Layer.TMS.getURL', but with the addition of hex addressing, - * and tile rounding. - * - * Parameters: - * bounds - {<OpenLayers.Bounds>} - * - * Returns: - * {String} The URL for a tile based on given bounds. - */ - getURL: function (bounds) { - var res = this.getResolution(); - - // tile center - var originTileX = (this.tileOrigin.lon + (res * this.tileSize.w/2)); - var originTileY = (this.tileOrigin.lat - (res * this.tileSize.h/2)); - - var center = bounds.getCenterLonLat(); - var point = { x: center.lon, y: center.lat }; - var x = (Math.round(Math.abs((center.lon - originTileX) / (res * this.tileSize.w)))); - var y = (Math.round(Math.abs((originTileY - center.lat) / (res * this.tileSize.h)))); - var z = this.map.getZoom(); - - // this prevents us from getting pink tiles (non-existant tiles) - if (this.lods) { - var lod = this.lods[this.map.getZoom()]; - if ((x < lod.startTileCol || x > lod.endTileCol) - || (y < lod.startTileRow || y > lod.endTileRow)) { - return null; - } - } - else { - var start = this.getUpperLeftTileCoord(res); - var end = this.getLowerRightTileCoord(res); - if ((x < start.x || x >= end.x) - || (y < start.y || y >= end.y)) { - return null; - } - } - - // Construct the url string - var url = this.url; - var s = '' + x + y + z; - - if (OpenLayers.Util.isArray(url)) { - url = this.selectUrl(s, url); - } - - // Accessing tiles through ArcGIS Server uses a different path - // structure than direct access via the folder structure. - if (this.useArcGISServer) { - // AGS MapServers have pretty url access to tiles - url = url + '/tile/${z}/${y}/${x}'; - } else { - // The tile images are stored using hex values on disk. - x = 'C' + OpenLayers.Number.zeroPad(x, 8, 16); - y = 'R' + OpenLayers.Number.zeroPad(y, 8, 16); - z = 'L' + OpenLayers.Number.zeroPad(z, 2, 10); - url = url + '/${z}/${y}/${x}.' + this.type; - } - - // Write the values into our formatted url - url = OpenLayers.String.format(url, {'x': x, 'y': y, 'z': z}); - - return OpenLayers.Util.urlAppend( - url, OpenLayers.Util.getParameterString(this.params) - ); - }, - - CLASS_NAME: 'OpenLayers.Layer.ArcGISCache' -}); |