diff --git a/.idea/runConfigurations/apps_Collada.xml b/.idea/runConfigurations/apps_Collada.xml
index b6fe4e95..aae9e35f 100644
--- a/.idea/runConfigurations/apps_Collada.xml
+++ b/.idea/runConfigurations/apps_Collada.xml
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/examples_BasicExample.xml b/.idea/runConfigurations/examples_BasicExample.xml
deleted file mode 100644
index ce1f050d..00000000
--- a/.idea/runConfigurations/examples_BasicExample.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/examples_Pyramid.xml b/.idea/runConfigurations/examples_Pyramid.xml
new file mode 100644
index 00000000..ccc972db
--- /dev/null
+++ b/.idea/runConfigurations/examples_Pyramid.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/Pyramid.html b/examples/Pyramid.html
new file mode 100644
index 00000000..b944c73e
--- /dev/null
+++ b/examples/Pyramid.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Pyramid Example
+
+
+
+
Projection
+
+
+
+
Layers
+
+
+
+
Destination
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/Pyramid.js b/examples/Pyramid.js
new file mode 100644
index 00000000..3806249f
--- /dev/null
+++ b/examples/Pyramid.js
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2003-2006, 2009, 2017, 2020 United States Government, as represented
+ * by the Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The NASAWorldWind/WebWorldWind platform is licensed under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License
+ * at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * NASAWorldWind/WebWorldWind also contains the following 3rd party Open Source
+ * software:
+ *
+ * ES6-Promise – under MIT License
+ * libtess.js – SGI Free Software License B
+ * Proj4 – under MIT License
+ * JSZip – under MIT License
+ *
+ * A complete listing of 3rd Party software notices and licenses included in
+ * WebWorldWind can be found in the WebWorldWind 3rd-party notices and licenses
+ * PDF found in code directory.
+ */
+/**
+ * Illustrates how to build a basic WorldWind globe.
+ */
+requirejs(['./WorldWindShim',
+ './LayerManager'],
+ function (WorldWind,
+ LayerManager) {
+ "use strict";
+
+ // Tell WorldWind to log only warnings and errors.
+ WorldWind.Logger.setLoggingLevel(WorldWind.Logger.LEVEL_WARNING);
+
+ // Create the WorldWindow.
+ var wwd = new WorldWind.WorldWindow("canvasOne");
+
+ // Create and add layers to the WorldWindow.
+ var layers = [
+ // Imagery layers.
+ {layer: new WorldWind.BMNGLayer(), enabled: true},
+ // Add atmosphere layer on top of all base layers.
+ {layer: new WorldWind.AtmosphereLayer(), enabled: true},
+ // WorldWindow UI layers.
+ {layer: new WorldWind.CompassLayer(), enabled: true},
+ {layer: new WorldWind.CoordinatesDisplayLayer(wwd), enabled: true},
+ {layer: new WorldWind.ViewControlsLayer(wwd), enabled: true}
+ ];
+
+ for (var l = 0; l < layers.length; l++) {
+ layers[l].layer.enabled = layers[l].enabled;
+ wwd.addLayer(layers[l].layer);
+ }
+ const pyramidMetaData = new WorldWind.PyramidMetaData("../../standalonedata/Earth/melrose/melrose.xml");
+
+ const xmlLoaded = function (metaData) {
+ wwd.addLayer(new WorldWind.PyramidLayer("../../standalonedata/Earth/melrose", metaData));
+ wwd.redraw();
+ };
+ pyramidMetaData.load(xmlLoaded);
+
+ wwd.navigator.lookAtLocation = new Location(34.3, -103.8);
+ wwd.navigator.range = 3000;
+
+ // Create a layer manager for controlling layer visibility.
+ var layerManager = new LayerManager(wwd);
+ });
\ No newline at end of file
diff --git a/src/WorldWind.js b/src/WorldWind.js
index 46c0059a..4cac32c8 100644
--- a/src/WorldWind.js
+++ b/src/WorldWind.js
@@ -215,6 +215,8 @@ define([ // PLEASE KEEP ALL THIS IN ALPHABETICAL ORDER BY MODULE NAME (not direc
'./projections/ProjectionPolarEquidistant',
'./projections/ProjectionUPS',
'./projections/ProjectionWgs84',
+ './layer/PyramidLayer',
+ './layer/PyramidMetaData',
'./geom/Rectangle',
'./render/Renderable',
'./layer/RenderableLayer',
@@ -493,6 +495,8 @@ define([ // PLEASE KEEP ALL THIS IN ALPHABETICAL ORDER BY MODULE NAME (not direc
ProjectionPolarEquidistant,
ProjectionUPS,
ProjectionWgs84,
+ PyramidLayer,
+ PyramidMetaData,
Rectangle,
Renderable,
RenderableLayer,
@@ -1008,6 +1012,8 @@ define([ // PLEASE KEEP ALL THIS IN ALPHABETICAL ORDER BY MODULE NAME (not direc
WorldWind['ProjectionPolarEquidistant'] = ProjectionPolarEquidistant;
WorldWind['ProjectionUPS'] = ProjectionUPS;
WorldWind['ProjectionWgs84'] = ProjectionWgs84;
+ WorldWind['PyramidLayer'] = PyramidLayer;
+ WorldWind['PyramidMetaData'] = PyramidMetaData;
WorldWind['Rectangle'] = Rectangle;
WorldWind['Renderable'] = Renderable;
WorldWind['RenderableLayer'] = RenderableLayer;
diff --git a/src/globe/Tessellator.js b/src/globe/Tessellator.js
index f1020b3d..d1e9ac09 100644
--- a/src/globe/Tessellator.js
+++ b/src/globe/Tessellator.js
@@ -675,7 +675,7 @@ define(['../geom/Angle',
Tessellator.prototype.createTopLevelTiles = function (dc) {
this.topLevelTiles[dc.globeStateKey] = [];
- Tile.createTilesForLevel(this.levels.firstLevel(), this, this.topLevelTiles[dc.globeStateKey]);
+ Tile.createTilesForLevel(this.levels.firstLevel(), this, this.topLevelTiles[dc.globeStateKey], this.levels.tileOrigin);
};
Tessellator.prototype.addTileOrDescendants = function (dc, tile) {
diff --git a/src/globe/TiledElevationCoverage.js b/src/globe/TiledElevationCoverage.js
index 80f23e59..2fc4d5f1 100644
--- a/src/globe/TiledElevationCoverage.js
+++ b/src/globe/TiledElevationCoverage.js
@@ -289,8 +289,11 @@ define(['../util/AbsentResourceList',
var level = this.levels.lastLevel(),
deltaLat = level.tileDelta.latitude,
deltaLon = level.tileDelta.longitude,
- r = Tile.computeRow(deltaLat, latitude),
- c = Tile.computeColumn(deltaLon, longitude),
+ origin = this.levels.tileOrigin,
+ latOrigin = origin.latitude,
+ lonOrigin = origin.longitude,
+ r = Tile.computeRow(deltaLat, latitude, latOrigin),
+ c = Tile.computeColumn(deltaLon, longitude, lonOrigin),
tileKey,
image = null;
@@ -478,10 +481,13 @@ define(['../util/AbsentResourceList',
var deltaLat = level.tileDelta.latitude,
deltaLon = level.tileDelta.longitude,
- firstRow = Tile.computeRow(deltaLat, this.currentSector.minLatitude),
- lastRow = Tile.computeLastRow(deltaLat, this.currentSector.maxLatitude),
- firstCol = Tile.computeColumn(deltaLon, this.currentSector.minLongitude),
- lastCol = Tile.computeLastColumn(deltaLon, this.currentSector.maxLongitude);
+ origin = this.levels.tileOrigin,
+ latOrigin = origin.latitude,
+ lonOrigin = origin.longitude,
+ firstRow = Tile.computeRow(deltaLat, this.currentSector.minLatitude, latOrigin),
+ lastRow = Tile.computeRow(deltaLat, this.currentSector.maxLatitude, latOrigin),
+ firstCol = Tile.computeColumn(deltaLon, this.currentSector.minLongitude, lonOrigin),
+ lastCol = Tile.computeColumn(deltaLon, this.currentSector.maxLongitude, lonOrigin);
for (var row = firstRow; row <= lastRow; row++) {
for (var col = firstCol; col <= lastCol; col++) {
diff --git a/src/layer/PyramidLayer.js b/src/layer/PyramidLayer.js
new file mode 100644
index 00000000..cc1fd90a
--- /dev/null
+++ b/src/layer/PyramidLayer.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2003-2006, 2009, 2017, 2020 United States Government, as represented
+ * by the Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The NASAWorldWind/WebWorldWind platform is licensed under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License
+ * at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * NASAWorldWind/WebWorldWind also contains the following 3rd party Open Source
+ * software:
+ *
+ * ES6-Promise – under MIT License
+ * libtess.js – SGI Free Software License B
+ * Proj4 – under MIT License
+ * JSZip – under MIT License
+ *
+ * A complete listing of 3rd Party software notices and licenses included in
+ * WebWorldWind can be found in the WebWorldWind 3rd-party notices and licenses
+ * PDF found in code directory.
+ */
+/**
+ * @exports PyramidLayer
+ */
+define([
+ './TiledImageLayer',
+ './PyramidMetaData',
+ '../util/WWUtil',
+ '../util/LevelRowColumnUrlBuilder'
+ ],
+ function (TiledImageLayer,
+ PyramidMetaData,
+ WWUtil,
+ LevelRowColumnUrlBuilder) {
+ "use strict";
+
+ var PyramidLayer = function (pathToData, metaData) {
+ TiledImageLayer.call(this, metaData.getSector(), metaData.getLevelZeroTileDelta(), metaData.getLevelCount(),
+ metaData.getImageFormat(), WWUtil.urlPath("/" + pathToData),
+ metaData.getTileWidth(), metaData.getTileHeight(), metaData.getTileOrigin());
+ this.displayName = metaData.getDisplayName();
+ this.pickEnabled = false;
+ this.urlBuilder = new LevelRowColumnUrlBuilder(null, pathToData);
+ };
+ PyramidLayer.prototype = Object.create(TiledImageLayer.prototype);
+
+ return PyramidLayer;
+ });
diff --git a/src/layer/PyramidMetaData.js b/src/layer/PyramidMetaData.js
new file mode 100644
index 00000000..6c7be68d
--- /dev/null
+++ b/src/layer/PyramidMetaData.js
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2003-2006, 2009, 2017, 2020 United States Government, as represented
+ * by the Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The NASAWorldWind/WebWorldWind platform is licensed under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License
+ * at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * NASAWorldWind/WebWorldWind also contains the following 3rd party Open Source
+ * software:
+ *
+ * ES6-Promise – under MIT License
+ * libtess.js – SGI Free Software License B
+ * Proj4 – under MIT License
+ * JSZip – under MIT License
+ *
+ * A complete listing of 3rd Party software notices and licenses included in
+ * WebWorldWind can be found in the WebWorldWind 3rd-party notices and licenses
+ * PDF found in code directory.
+ */
+/**
+ * @exports PyramidMetaData
+ */
+define([
+ '../util/Logger',
+ '../util/XmlDocument',
+ '../geom/Location',
+ '../geom/Sector'
+ ],
+ function (Logger,
+ XmlDocument,
+ Location,
+ Sector) {
+ "use strict";
+
+ const PyramidAttrs = {
+ Text: "#text",
+ DisplayName: "DisplayName",
+ FormatSuffix: "FormatSuffix",
+ NumLevels: "NumLevels",
+ NumEmpty: "numEmpty",
+ Count: "count",
+ SectorElement: "Sector",
+ SouthWest: "SouthWest",
+ NorthEast: "NorthEast",
+ LatLon: "LatLon",
+ Units: "units",
+ Degrees: "degrees",
+ Latitude: "latitude",
+ Longitude: "longitude",
+ TileOrigin: "TileOrigin",
+ TileSize: "TileSize",
+ Dimension: "Dimension",
+ Height: "height",
+ Width: "width",
+ LevelZeroTileDelta: "LevelZeroTileDelta",
+ ImageFormat: "ImageFormat"
+ }
+
+ var PyramidMetaData = function (url) {
+ this.url = url;
+ this.levelCount = 10;
+ this.numEmptyLevels = 0;
+ this.sector = Sector.FULL_SPHERE;
+ this.tileOrigin = new Location(-90, -180);
+ this.tileWidth = 512;
+ this.tileHeight = 512;
+ this.imageFormat = "image/png";
+ };
+
+ // Location.fromRadians = function (latitudeRadians, longitudeRadians) {
+ // return new Location(latitudeRadians * Angle.RADIANS_TO_DEGREES, longitudeRadians * Angle.RADIANS_TO_DEGREES);
+ // };
+
+ PyramidMetaData.prototype.getChildValue = function (children, attr) {
+ const childNodes = Array.prototype.slice.call(children);
+ for (const childNode of childNodes) {
+ if (childNode.nodeName === attr) {
+ if (attr === PyramidAttrs.Text) {
+ return childNode.nodeValue;
+ }
+ return childNode;
+ }
+ }
+ return null;
+ };
+
+ PyramidMetaData.prototype.getLatLon = function (children) {
+ const latLon = this.getChildValue(children, PyramidAttrs.LatLon);
+ if (latLon) {
+ const latitude = latLon.attributes.getNamedItem(PyramidAttrs.Latitude);
+ const longitude = latLon.attributes.getNamedItem(PyramidAttrs.Longitude);
+ if (!latitude || !longitude) {
+ return null;
+ }
+ const units = latLon.attributes.getNamedItem(PyramidAttrs.Units);
+ if (!units || units.value === PyramidAttrs.Degrees) {
+ return new Location(parseFloat(latitude.value), parseFloat(longitude.value));
+ } else {
+ return Location.fromRadians(parseFloat(latitude.value), parseFloat(longitude.value));
+ }
+ }
+ return null;
+ };
+ PyramidMetaData.prototype.processElement = function (element) {
+ switch (element.nodeName) {
+ case PyramidAttrs.DisplayName:
+ this.displayName = this.getChildValue(element.childNodes, PyramidAttrs.Text);
+ break;
+ case PyramidAttrs.FormatSuffix:
+ this.formatSuffix = this.getChildValue(element.childNodes, PyramidAttrs.Text);
+ break;
+ case PyramidAttrs.NumLevels: {
+ let attr = element.attributes.getNamedItem(PyramidAttrs.NumEmpty);
+ if (attr) {
+ this.numEmptyLevels = parseInt(attr.value);
+ }
+ attr = element.attributes.getNamedItem(PyramidAttrs.Count);
+ if (attr) {
+ this.levelCount = parseInt(attr.value);
+ }
+ }
+ break;
+ case PyramidAttrs.SectorElement: {
+ const southWest = this.getChildValue(element.childNodes, PyramidAttrs.SouthWest);
+ let swLatLon;
+ if (southWest) {
+ swLatLon = this.getLatLon(southWest.childNodes);
+ }
+ const northEast = this.getChildValue(element.childNodes, PyramidAttrs.NorthEast);
+ let neLatLon;
+ if (northEast) {
+ neLatLon = this.getLatLon(northEast.childNodes);
+ }
+ if (swLatLon && neLatLon) {
+ this.sector = new Sector(swLatLon.latitude, neLatLon.latitude,
+ swLatLon.longitude, neLatLon.longitude);
+ }
+
+ }
+ break;
+ case PyramidAttrs.TileOrigin: {
+ const origin = this.getLatLon(element.childNodes);
+ if (origin) {
+ this.tileOrigin = origin;
+ }
+ }
+ break;
+ case PyramidAttrs.TileSize: {
+ const dimension = this.getChildValue(element.childNodes, PyramidAttrs.Dimension);
+ if (dimension) {
+ let attr = dimension.attributes.getNamedItem(PyramidAttrs.Height);
+ if (attr) {
+ this.tileHeight = parseInt(attr.value);
+ }
+ attr = dimension.attributes.getNamedItem(PyramidAttrs.Width);
+ if (attr) {
+ this.tileWidth = parseInt(attr.value);
+ }
+ }
+ }
+ break;
+ case PyramidAttrs.LevelZeroTileDelta: {
+ const delta = this.getLatLon(element.childNodes);
+ if (delta) {
+ this.levelZeroTileDelta = delta;
+ }
+ }
+ break;
+ case PyramidAttrs.ImageFormat:
+ this.imageFormat = this.getChildValue(element.childNodes, PyramidAttrs.Text);
+ break;
+ default: {
+ const childNodes = Array.prototype.slice.call(element.childNodes);
+ for (const childNode of childNodes) {
+ this.processElement(childNode);
+ }
+ }
+ break;
+ }
+ };
+
+ PyramidMetaData.prototype.parseDocument = function (xml) {
+ const document = new XmlDocument(xml).dom();
+ this.processElement(document.documentElement);
+ };
+
+ PyramidMetaData.prototype.load = function (callback) {
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
+ const self = this;
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", self.url, true);
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4 && xhr.status === 200) {
+ self.parseDocument(xhr.responseText);
+ if (callback) {
+ callback(self);
+ }
+ }
+ };
+ xhr.onerror = function () {
+ Logger.logMessage(Logger.LEVEL_WARNING, "PyramidMetaData", "load", "Document retrieval failed. " + " " + self.url);
+ };
+ xhr.ontimeout = function () {
+ Logger.logMessage(Logger.LEVEL_WARNING, "PyramidMetaData", "load", "Document retrieval timed out. " + " " + self.url);
+ };
+ xhr.send(null);
+ };
+
+ PyramidMetaData.prototype.getDisplayName = function () {
+ return this.displayName;
+ };
+
+ PyramidMetaData.prototype.getSector = function () {
+ return this.sector;
+ };
+
+ PyramidMetaData.prototype.getLevelZeroTileDelta = function () {
+ return this.levelZeroTileDelta;
+ };
+
+ PyramidMetaData.prototype.getLevelCount = function () {
+ return this.levelCount;
+ };
+
+ PyramidMetaData.prototype.getImageFormat = function () {
+ return this.imageFormat;
+ };
+
+ PyramidMetaData.prototype.getTileWidth = function () {
+ return this.tileWidth;
+ };
+
+ PyramidMetaData.prototype.getTileHeight = function () {
+ return this.tileHeight;
+ };
+
+ PyramidMetaData.prototype.getTileOrigin = function () {
+ return this.tileOrigin;
+ };
+
+ return PyramidMetaData;
+ });
\ No newline at end of file
diff --git a/src/layer/TiledImageLayer.js b/src/layer/TiledImageLayer.js
index a7202edb..3e2952a0 100644
--- a/src/layer/TiledImageLayer.js
+++ b/src/layer/TiledImageLayer.js
@@ -87,7 +87,7 @@ define([
* null or undefined, or if the specified number of levels, tile width or tile height is less than 1.
*
*/
- var TiledImageLayer = function (sector, levelZeroDelta, numLevels, imageFormat, cachePath, tileWidth, tileHeight) {
+ var TiledImageLayer = function (sector, levelZeroDelta, numLevels, imageFormat, cachePath, tileWidth, tileHeight, tileOrigin) {
if (!sector) {
throw new ArgumentError(
Logger.logMessage(Logger.LEVEL_SEVERE, "TiledImageLayer", "constructor", "missingSector"));
@@ -135,7 +135,7 @@ define([
*/
this.retrievalQueueSize = WorldWind.configuration.layerRetrievalQueueSize;
- this.levels = new LevelSet(sector, levelZeroDelta, numLevels, tileWidth, tileHeight);
+ this.levels = new LevelSet(sector, levelZeroDelta, numLevels, tileWidth, tileHeight, tileOrigin);
/**
* Controls the level of detail switching for this layer. The next highest resolution level is
@@ -353,7 +353,7 @@ define([
// Documented in superclass.
TiledImageLayer.prototype.createTopLevelTiles = function (dc) {
this.topLevelTiles = [];
- Tile.createTilesForLevel(this.levels.firstLevel(), this, this.topLevelTiles);
+ Tile.createTilesForLevel(this.levels.firstLevel(), this, this.topLevelTiles, this.levels.tileOrigin);
};
// Intentionally not documented.
diff --git a/src/render/FramebufferTileController.js b/src/render/FramebufferTileController.js
index 71370beb..c2078b53 100644
--- a/src/render/FramebufferTileController.js
+++ b/src/render/FramebufferTileController.js
@@ -220,7 +220,7 @@ define([
// Internal. Intentionally not documented.
FramebufferTileController.prototype.createTopLevelTiles = function () {
- Tile.createTilesForLevel(this.levels.firstLevel(), this, this.topLevelTiles);
+ Tile.createTilesForLevel(this.levels.firstLevel(), this, this.topLevelTiles, this.levels.tileOrigin);
};
// Internal. Intentionally not documented.
diff --git a/src/shapes/SurfaceShapeTileBuilder.js b/src/shapes/SurfaceShapeTileBuilder.js
index 19fe14e6..f9579677 100644
--- a/src/shapes/SurfaceShapeTileBuilder.js
+++ b/src/shapes/SurfaceShapeTileBuilder.js
@@ -497,7 +497,7 @@ define([
};
SurfaceShapeTileBuilder.prototype.createTopLevelTiles = function () {
- Tile.createTilesForLevel(this.levels.firstLevel(), this, this.topLevelTiles);
+ Tile.createTilesForLevel(this.levels.firstLevel(), this, this.topLevelTiles, this.levels.tileOrigin);
};
/**
diff --git a/src/util/LevelSet.js b/src/util/LevelSet.js
index a211d144..7092a5de 100644
--- a/src/util/LevelSet.js
+++ b/src/util/LevelSet.js
@@ -57,7 +57,7 @@ define([
* delta values are less than or equal to zero, or any of the number-of-levels, tile-width or tile-height
* arguments are less than 1.
*/
- var LevelSet = function (sector, levelZeroDelta, numLevels, tileWidth, tileHeight) {
+ var LevelSet = function (sector, levelZeroDelta, numLevels, tileWidth, tileHeight, tileOrigin) {
if (!sector) {
throw new ArgumentError(
Logger.logMessage(Logger.LEVEL_SEVERE, "LevelSet", "constructor", "missingSector"));
@@ -101,6 +101,13 @@ define([
*/
this.levelZeroDelta = levelZeroDelta;
+ if (tileOrigin) {
+ this.tileOrigin = tileOrigin;
+ }
+ else {
+ this.tileOrigin = new Location(-90, -180);
+ }
+
/**
* The number of levels in this level set.
* @type {Number}
diff --git a/src/util/Tile.js b/src/util/Tile.js
index 3dbf041c..84f6ea05 100644
--- a/src/util/Tile.js
+++ b/src/util/Tile.js
@@ -433,14 +433,19 @@ define([
* @param {Number} latitude The tile's minimum latitude.
* @returns {Number} The computed row number.
*/
- Tile.computeRow = function (delta, latitude) {
- var row = Math.floor((latitude + 90) / delta);
-
- // If latitude is at the end of the grid, subtract 1 from the computed row to return the last row.
- if (latitude == 90) {
- row -= 1;
+ Tile.computeRow = function (delta, latitude, origin) {
+ // var row = Math.floor((latitude + 90) / delta);
+ //
+ // // If latitude is at the end of the grid, subtract 1 from the computed row to return the last row.
+ // if (latitude == 90) {
+ // row -= 1;
+ // }
+ //
+ // return row;
+ let row = Math.floor((latitude - origin) / delta);
+ if ((latitude - origin) === 180) {
+ row = row - 1;
}
-
return row;
};
@@ -450,14 +455,23 @@ define([
* @param {Number} longitude The tile's minimum longitude.
* @returns {Number} The computed column number.
*/
- Tile.computeColumn = function (delta, longitude) {
- var col = Math.floor((longitude + 180) / delta);
-
- // If longitude is at the end of the grid, subtract 1 from the computed column to return the last column.
- if (longitude == 180) {
- col -= 1;
+ Tile.computeColumn = function (delta, longitude, origin) {
+ // var col = Math.floor((longitude + 180) / delta);
+ //
+ // // If longitude is at the end of the grid, subtract 1 from the computed column to return the last column.
+ // if (longitude == 180) {
+ // col -= 1;
+ // }
+ //
+ // return col;
+ let gridLongitude = longitude - origin;
+ if (gridLongitude < 0) {
+ gridLongitude = 360 + gridLongitude;
+ }
+ let col = Math.floor(gridLongitude / delta);
+ if ((longitude - origin) === 360) {
+ col = col - 1;
}
-
return col;
};
@@ -467,16 +481,16 @@ define([
* @param {Number} maxLatitude The tile's maximum latitude in degrees.
* @returns {Number} The computed row number.
*/
- Tile.computeLastRow = function (delta, maxLatitude) {
- var row = Math.ceil((maxLatitude + 90) / delta - 1);
-
- // If max latitude is in the first row, set the max row to 0.
- if (maxLatitude + 90 < delta) {
- row = 0;
- }
-
- return row;
- };
+ // Tile.computeLastRow = function (delta, maxLatitude) {
+ // var row = Math.ceil((maxLatitude + 90) / delta - 1);
+ //
+ // // If max latitude is in the first row, set the max row to 0.
+ // if (maxLatitude + 90 < delta) {
+ // row = 0;
+ // }
+ //
+ // return row;
+ // };
/**
* Computes the last column number for a tile within a level given the tile's maximum longitude.
@@ -484,16 +498,16 @@ define([
* @param {Number} maxLongitude The tile's maximum longitude in degrees.
* @returns {Number} The computed column number.
*/
- Tile.computeLastColumn = function (delta, maxLongitude) {
- var col = Math.ceil((maxLongitude + 180) / delta - 1);
-
- // If max longitude is in the first column, set the max column to 0.
- if (maxLongitude + 180 < delta) {
- col = 0;
- }
-
- return col;
- };
+ // Tile.computeLastColumn = function (delta, maxLongitude) {
+ // var col = Math.ceil((maxLongitude + 180) / delta - 1);
+ //
+ // // If max longitude is in the first column, set the max column to 0.
+ // if (maxLongitude + 180 < delta) {
+ // col = 0;
+ // }
+ //
+ // return col;
+ // };
/**
* Computes a sector spanned by a tile with the specified level number, row and column.
@@ -533,7 +547,7 @@ define([
* @param {Tile[]} result An array in which to return the results.
* @throws {ArgumentError} If any argument is null or undefined.
*/
- Tile.createTilesForLevel = function (level, tileFactory, result) {
+ Tile.createTilesForLevel = function (level, tileFactory, result,origin) {
if (!level) {
throw new ArgumentError(
Logger.logMessage(Logger.LEVEL_SEVERE, "Tile", "createTilesForLevel", "missingLevel"));
@@ -554,14 +568,16 @@ define([
deltaLon = level.tileDelta.longitude,
sector = level.sector,
- firstRow = Tile.computeRow(deltaLat, sector.minLatitude),
- lastRow = Tile.computeRow(deltaLat, sector.maxLatitude),
+ latOrigin = origin.latitude,
+ lonOrigin = origin.longitude,
+ firstRow = Tile.computeRow(deltaLat, sector.minLatitude, latOrigin),
+ lastRow = Tile.computeRow(deltaLat, sector.maxLatitude, latOrigin),
- firstCol = Tile.computeColumn(deltaLon, sector.minLongitude),
- lastCol = Tile.computeColumn(deltaLon, sector.maxLongitude),
+ firstCol = Tile.computeColumn(deltaLon, sector.minLongitude, lonOrigin),
+ lastCol = Tile.computeColumn(deltaLon, sector.maxLongitude, lonOrigin),
- firstRowLat = -90 + firstRow * deltaLat,
- firstRowLon = -180 + firstCol * deltaLon,
+ firstRowLat = latOrigin + firstRow * deltaLat,
+ firstRowLon = lonOrigin + firstCol * deltaLon,
minLat = firstRowLat,
minLon,