Skip to content

Commit fba5af4

Browse files
committed
Separate first level delta in Level Set for latitude and longitude.
1 parent c17e8b0 commit fba5af4

File tree

10 files changed

+55
-52
lines changed

10 files changed

+55
-52
lines changed

worldwind/src/main/java/gov/nasa/worldwind/globe/BasicTessellator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
public class BasicTessellator implements Tessellator, TileFactory {
3434

3535
// ~0.6 meter resolution
36-
protected LevelSet levelSet = new LevelSet(new Sector().setFullSphere(), new Location(-90, -180), 90, 20, 32, 32);
36+
protected LevelSet levelSet = new LevelSet(new Sector().setFullSphere(), new Location(-90, -180), new Location(90, 90), 20, 32, 32);
3737

3838
protected double detailControl = 80;
3939

worldwind/src/main/java/gov/nasa/worldwind/layer/BlueMarbleLandsatLayer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public BlueMarbleLandsatLayer(String serviceAddress) {
8585

8686
@Override
8787
public Tile createTile(Sector sector, Level level, int row, int column) {
88-
double radiansPerPixel = Math.toRadians(level.tileDelta) / level.tileHeight;
88+
double radiansPerPixel = Math.toRadians(level.tileDelta.latitude) / level.tileHeight;
8989
double metersPerPixel = radiansPerPixel * WorldWind.WGS84_SEMI_MAJOR_AXIS;
9090

9191
if (metersPerPixel < 2.0e3) { // switch to Landsat at 2km resolution

worldwind/src/main/java/gov/nasa/worldwind/layer/LayerFactory.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,10 @@ protected void createFromGeoPackageAsync(String pathName, Layer layer, Callback
280280
tileMatrixSet.getMaxY() - tileMatrixSet.getMinY(),
281281
tileMatrixSet.getMaxX() - tileMatrixSet.getMinX());
282282
config.tileOrigin.set(tileMatrixSet.getMinY(), tileMatrixSet.getMinX());
283-
config.firstLevelDelta = (tileMatrixSet.getMaxY() - tileMatrixSet.getMinY()) / tileMatrix.valueAt(0).getMatrixHeight();
283+
config.firstLevelDelta.set(
284+
(tileMatrixSet.getMaxY() - tileMatrixSet.getMinY()) / tileMatrix.valueAt(0).getMatrixHeight(),
285+
(tileMatrixSet.getMaxX() - tileMatrixSet.getMinX()) / tileMatrix.valueAt(0).getMatrixWidth()
286+
);
284287
config.numLevels = tileMatrix.keyAt(tileMatrix.size() - 1) - tileMatrix.keyAt(0) + 1;
285288

286289
TiledSurfaceImage surfaceImage = new TiledSurfaceImage();
@@ -681,7 +684,7 @@ protected LevelSet createWmtsLevelSet(WmtsLayer wmtsLayer, CompatibleTileMatrixS
681684
}
682685
int imageSize = tileMatrixSet.getTileMatrices().get(0).getTileHeight();
683686

684-
return new LevelSet(boundingBox, new Location(-90, -180), 90, compatibleTileMatrixSet.tileMatrices.size(), imageSize, imageSize);
687+
return new LevelSet(boundingBox, new Location(-90, -180), new Location(90, 90), compatibleTileMatrixSet.tileMatrices.size(), imageSize, imageSize);
685688
}
686689

687690
protected String buildWmtsKvpTemplate(String kvpServiceAddress, String layer, String format, String styleIdentifier, String tileMatrixSet) {

worldwind/src/main/java/gov/nasa/worldwind/layer/mercator/MercatorImageTile.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ static void assembleMercatorTilesForLevel(Level level, TileFactory tileFactory,
5353
// NOTE LevelSet.sector is final Sector attribute and thus can not be cast to MercatorSector!
5454
MercatorSector sector = MercatorSector.fromSector(level.parent.sector);
5555
Location tileOrigin = level.parent.tileOrigin;
56-
double dLat = level.tileDelta / 2;
57-
double dLon = level.tileDelta;
56+
double dLat = level.tileDelta.latitude;
57+
double dLon = level.tileDelta.longitude;
5858

5959
int firstRow = Tile.computeRow(dLat, sector.minLatitude(), tileOrigin.latitude);
6060
int lastRow = Tile.computeLastRow(dLat, sector.maxLatitude(), tileOrigin.latitude);

worldwind/src/main/java/gov/nasa/worldwind/layer/mercator/MercatorTiledImageLayer.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ public MercatorTiledImageLayer(String name, int numLevels, int firstLevelOffset,
2222
this.setPickEnabled(false);
2323
this.firstLevelOffset = firstLevelOffset;
2424

25+
MercatorSector sector = MercatorSector.fromDegrees(-1.0, 1.0, - FULL_SPHERE / 2, FULL_SPHERE / 2);
26+
Location tileOrigin = new Location(sector.minLatitude(), sector.minLongitude());
27+
int n = 1 << firstLevelOffset;
28+
Location firstLevelDelta = new Location(sector.deltaLatitude() / n, sector.deltaLongitude() / n);
2529
MercatorTiledSurfaceImage surfaceImage = new MercatorTiledSurfaceImage();
26-
surfaceImage.setLevelSet(new LevelSet(
27-
MercatorSector.fromDegrees(-1.0, 1.0, - FULL_SPHERE / 2, FULL_SPHERE / 2), new Location(-90, -180),
28-
FULL_SPHERE / (1 << firstLevelOffset), numLevels - firstLevelOffset, tileSize, tileSize));
30+
surfaceImage.setLevelSet(new LevelSet(sector, tileOrigin, firstLevelDelta, numLevels - firstLevelOffset, tileSize, tileSize));
2931
surfaceImage.setTileFactory(this);
3032
if(!overlay) {
3133
surfaceImage.setImageOptions(new ImageOptions(WorldWind.RGB_565)); // reduce memory usage by using a 16-bit configuration with no alpha

worldwind/src/main/java/gov/nasa/worldwind/util/Level.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
package gov.nasa.worldwind.util;
77

8+
import gov.nasa.worldwind.geom.Location;
9+
810
/**
911
* Represents a level of a specific resolution in a {@link LevelSet}.
1012
*/
@@ -35,7 +37,7 @@ public class Level {
3537
/**
3638
* The geographic width and height in degrees of tiles within this level.
3739
*/
38-
public final double tileDelta;
40+
public final Location tileDelta;
3941

4042
/**
4143
* The parent LevelSet's tileWidth.
@@ -54,21 +56,21 @@ public class Level {
5456
* @param levelNumber the level's ordinal within its parent level set
5557
* @param tileDelta the geographic width and height in degrees of tiles within this level
5658
*/
57-
public Level(LevelSet parent, int levelNumber, double tileDelta) {
59+
public Level(LevelSet parent, int levelNumber, Location tileDelta) {
5860
if (parent == null) {
5961
throw new IllegalArgumentException(
6062
Logger.logMessage(Logger.ERROR, "Level", "constructor", "The parent level set is null"));
6163
}
6264

63-
if (tileDelta <= 0) {
65+
if (tileDelta == null || tileDelta.latitude <= 0 || tileDelta.longitude <= 0) {
6466
throw new IllegalArgumentException(
6567
Logger.logMessage(Logger.ERROR, "Level", "constructor", "The tile delta is zero"));
6668
}
6769

6870
this.parent = parent;
6971
this.levelNumber = levelNumber;
70-
this.levelWidth = (int) Math.round(parent.tileWidth * parent.sector.deltaLongitude() / tileDelta);
71-
this.levelHeight = (int) Math.round(parent.tileHeight * parent.sector.deltaLatitude() / tileDelta);
72+
this.levelWidth = (int) Math.round(parent.tileWidth * parent.sector.deltaLongitude() / tileDelta.longitude);
73+
this.levelHeight = (int) Math.round(parent.tileHeight * parent.sector.deltaLatitude() / tileDelta.latitude);
7274
this.tileDelta = tileDelta;
7375
this.tileWidth = parent.tileWidth;
7476
this.tileHeight = parent.tileHeight;

worldwind/src/main/java/gov/nasa/worldwind/util/LevelSet.java

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ public class LevelSet {
2525
public final Location tileOrigin = new Location();
2626

2727
/**
28-
* The geographic width and height in degrees of tiles in the first level (lowest resolution) of this level set.
28+
* The geographic width and height in degrees of tiles in the first level (the lowest resolution) of this level set.
2929
*/
30-
public final double firstLevelDelta;
30+
public final Location firstLevelDelta = new Location();
3131

3232
/**
3333
* The width in pixels of images associated with tiles in this level set, or the number of sample points in the
@@ -51,7 +51,6 @@ public class LevelSet {
5151
* <code>firstLevel</code> and <code>lastLevel</code> always return null.
5252
*/
5353
public LevelSet() {
54-
this.firstLevelDelta = 0;
5554
this.tileWidth = 0;
5655
this.tileHeight = 0;
5756
this.levels = new Level[0];
@@ -74,7 +73,7 @@ public LevelSet() {
7473
*
7574
* @throws IllegalArgumentException If any argument is null, or if any dimension is zero
7675
*/
77-
public LevelSet(Sector sector, Location tileOrigin, double firstLevelDelta, int numLevels, int tileWidth, int tileHeight) {
76+
public LevelSet(Sector sector, Location tileOrigin, Location firstLevelDelta, int numLevels, int tileWidth, int tileHeight) {
7877
if (sector == null) {
7978
throw new IllegalArgumentException(
8079
Logger.logMessage(Logger.ERROR, "LevelSet", "constructor", "missingSector"));
@@ -85,7 +84,7 @@ public LevelSet(Sector sector, Location tileOrigin, double firstLevelDelta, int
8584
Logger.logMessage(Logger.ERROR, "LevelSet", "constructor", "missingTileOrigin"));
8685
}
8786

88-
if (firstLevelDelta <= 0) {
87+
if (firstLevelDelta == null || firstLevelDelta.latitude <= 0 || firstLevelDelta.longitude <= 0) {
8988
throw new IllegalArgumentException(
9089
Logger.logMessage(Logger.ERROR, "LevelSet", "constructor", "invalidTileDelta"));
9190
}
@@ -102,7 +101,7 @@ public LevelSet(Sector sector, Location tileOrigin, double firstLevelDelta, int
102101

103102
this.sector.set(sector);
104103
this.tileOrigin.set(tileOrigin);
105-
this.firstLevelDelta = firstLevelDelta;
104+
this.firstLevelDelta.set(firstLevelDelta);
106105
this.tileWidth = tileWidth;
107106
this.tileHeight = tileHeight;
108107
this.levels = new Level[numLevels];
@@ -129,12 +128,7 @@ public LevelSet(LevelSetConfig config) {
129128
Logger.logMessage(Logger.ERROR, "LevelSet", "constructor", "missingSector"));
130129
}
131130

132-
if (config.tileOrigin == null) {
133-
throw new IllegalArgumentException(
134-
Logger.logMessage(Logger.ERROR, "LevelSet", "constructor", "missingTileOrigin"));
135-
}
136-
137-
if (config.firstLevelDelta <= 0) {
131+
if (config.firstLevelDelta.latitude <= 0 || config.firstLevelDelta.longitude <= 0) {
138132
throw new IllegalArgumentException(
139133
Logger.logMessage(Logger.ERROR, "LevelSet", "constructor", "invalidTileDelta"));
140134
}
@@ -151,7 +145,7 @@ public LevelSet(LevelSetConfig config) {
151145

152146
this.sector.set(config.sector);
153147
this.tileOrigin.set(config.tileOrigin);
154-
this.firstLevelDelta = config.firstLevelDelta;
148+
this.firstLevelDelta.set(config.firstLevelDelta);
155149
this.tileWidth = config.tileWidth;
156150
this.tileHeight = config.tileHeight;
157151
this.levels = new Level[config.numLevels];
@@ -160,7 +154,8 @@ public LevelSet(LevelSetConfig config) {
160154

161155
protected void assembleLevels() {
162156
for (int i = 0, len = this.levels.length; i < len; i++) {
163-
double delta = firstLevelDelta / (1 << i);
157+
int n = 1 << i;
158+
Location delta = new Location(firstLevelDelta.latitude / n, firstLevelDelta.longitude / n);
164159
this.levels[i] = new Level(this, i, delta);
165160
}
166161
}
@@ -209,7 +204,7 @@ public Level levelForResolution(double radiansPerPixel) {
209204
}
210205

211206
double degreesPerPixel = Math.toDegrees(radiansPerPixel);
212-
double firstLevelDegreesPerPixel = this.firstLevelDelta / Math.min(this.tileWidth, this.tileHeight);
207+
double firstLevelDegreesPerPixel = Math.max(this.firstLevelDelta.longitude / this.tileWidth, this.firstLevelDelta.latitude / this.tileHeight);
213208
double level = Math.log(firstLevelDegreesPerPixel / degreesPerPixel) / Math.log(2); // fractional level address
214209
int levelNumber = (int) Math.round(level); // nearest neighbor level
215210

worldwind/src/main/java/gov/nasa/worldwind/util/LevelSetConfig.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ public class LevelSetConfig {
2525
public final Location tileOrigin = new Location(-90, -180);
2626

2727
/**
28-
* The geographic width and height in degrees of tiles in the first level (lowest resolution) of the level set.
28+
* The geographic width and height in degrees of tiles in the first level (the lowest resolution) of the level set.
2929
*/
30-
public double firstLevelDelta = 90;
30+
public final Location firstLevelDelta = new Location(90, 90);
3131

3232
/**
3333
* The number of levels in the level set.
@@ -69,12 +69,12 @@ public LevelSetConfig() {
6969
* sample points in the latitudinal direction of elevation tiles associate with the level
7070
* set
7171
*/
72-
public LevelSetConfig(Sector sector, double firstLevelDelta, int numLevels, int tileWidth, int tileHeight) {
72+
public LevelSetConfig(Sector sector, Location firstLevelDelta, int numLevels, int tileWidth, int tileHeight) {
7373
if (sector != null) {
7474
this.sector.set(sector);
7575
}
7676

77-
this.firstLevelDelta = firstLevelDelta;
77+
this.firstLevelDelta.set(firstLevelDelta);
7878
this.numLevels = numLevels;
7979
this.tileWidth = tileWidth;
8080
this.tileHeight = tileHeight;
@@ -97,7 +97,7 @@ public int numLevelsForResolution(double radiansPerPixel) {
9797
}
9898

9999
double degreesPerPixel = Math.toDegrees(radiansPerPixel);
100-
double firstLevelDegreesPerPixel = this.firstLevelDelta / Math.min(this.tileWidth, this.tileHeight);
100+
double firstLevelDegreesPerPixel = Math.max(this.firstLevelDelta.longitude / this.tileWidth, this.firstLevelDelta.latitude / this.tileHeight);
101101
double level = Math.log(firstLevelDegreesPerPixel / degreesPerPixel) / Math.log(2); // fractional level address
102102
int levelNumber = (int) Math.ceil(level); // ceiling captures the resolution
103103

@@ -126,7 +126,7 @@ public int numLevelsForMinResolution(double radiansPerPixel) {
126126
}
127127

128128
double degreesPerPixel = Math.toDegrees(radiansPerPixel);
129-
double firstLevelDegreesPerPixel = this.firstLevelDelta / this.tileHeight;
129+
double firstLevelDegreesPerPixel = Math.max(this.firstLevelDelta.longitude / this.tileWidth, this.firstLevelDelta.latitude / this.tileHeight);
130130
double level = Math.log(firstLevelDegreesPerPixel / degreesPerPixel) / Math.log(2); // fractional level address
131131
int levelNumber = (int) Math.floor(level); // floor prevents exceeding the min scale
132132

worldwind/src/main/java/gov/nasa/worldwind/util/Tile.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public Tile(Sector sector, Level level, int row, int column) {
109109
this.row = row;
110110
this.column = column;
111111
this.tileKey = level.levelNumber + "." + row + "." + column;
112-
this.texelSizeFactor = Math.toRadians(level.tileDelta / level.tileWidth) * Math.cos(Math.toRadians(sector.centroidLatitude()));
112+
this.texelSizeFactor = Math.toRadians(level.tileDelta.longitude / level.tileWidth) * Math.cos(Math.toRadians(sector.centroidLatitude()));
113113
}
114114

115115
/**
@@ -217,29 +217,29 @@ public static Collection<Tile> assembleTilesForLevel(Level level, TileFactory ti
217217

218218
Sector sector = level.parent.sector;
219219
Location tileOrigin = level.parent.tileOrigin;
220-
double tileDelta = level.tileDelta;
220+
Location tileDelta = level.tileDelta;
221221

222-
int firstRow = Tile.computeRow(tileDelta, sector.minLatitude(), tileOrigin.latitude);
223-
int lastRow = Tile.computeLastRow(tileDelta, sector.maxLatitude(), tileOrigin.latitude);
224-
int firstCol = Tile.computeColumn(tileDelta, sector.minLongitude(), tileOrigin.longitude);
225-
int lastCol = Tile.computeLastColumn(tileDelta, sector.maxLongitude(), tileOrigin.longitude);
222+
int firstRow = Tile.computeRow(tileDelta.latitude, sector.minLatitude(), tileOrigin.latitude);
223+
int lastRow = Tile.computeLastRow(tileDelta.latitude, sector.maxLatitude(), tileOrigin.latitude);
224+
int firstCol = Tile.computeColumn(tileDelta.longitude, sector.minLongitude(), tileOrigin.longitude);
225+
int lastCol = Tile.computeLastColumn(tileDelta.longitude, sector.maxLongitude(), tileOrigin.longitude);
226226

227-
double firstRowLat = tileOrigin.latitude + firstRow * tileDelta;
228-
double firstRowLon = tileOrigin.longitude + firstCol * tileDelta;
227+
double firstRowLat = tileOrigin.latitude + firstRow * tileDelta.latitude;
228+
double firstRowLon = tileOrigin.longitude + firstCol * tileDelta.longitude;
229229
double lat = firstRowLat;
230230
double lon;
231231

232232
for (int row = firstRow; row <= lastRow; row++) {
233233
lon = firstRowLon;
234234

235235
for (int col = firstCol; col <= lastCol; col++) {
236-
Sector tileSector = new Sector(lat, lon, tileDelta, tileDelta);
236+
Sector tileSector = new Sector(lat, lon, tileDelta.latitude, tileDelta.longitude);
237237
result.add(tileFactory.createTile(tileSector, level, row, col));
238238

239-
lon += tileDelta;
239+
lon += tileDelta.longitude;
240240
}
241241

242-
lat += tileDelta;
242+
lat += tileDelta.latitude;
243243
}
244244

245245
return result;
@@ -334,26 +334,27 @@ public Tile[] subdivide(TileFactory tileFactory) {
334334
double lonMin = this.sector.minLongitude();
335335
double latMid = this.sector.centroidLatitude();
336336
double lonMid = this.sector.centroidLongitude();
337-
double childDelta = this.level.tileDelta * 0.5;
337+
double childDeltaLat = this.level.tileDelta.latitude * 0.5;
338+
double childDeltaLon = this.level.tileDelta.longitude * 0.5;
338339

339340
int childRow = 2 * this.row;
340341
int childCol = 2 * this.column;
341-
Sector childSector = new Sector(latMin, lonMin, childDelta, childDelta);
342+
Sector childSector = new Sector(latMin, lonMin, childDeltaLat, childDeltaLon);
342343
children[0] = tileFactory.createTile(childSector, childLevel, childRow, childCol); // Southwest
343344

344345
childRow = 2 * this.row;
345346
childCol = 2 * this.column + 1;
346-
childSector = new Sector(latMin, lonMid, childDelta, childDelta);
347+
childSector = new Sector(latMin, lonMid, childDeltaLat, childDeltaLon);
347348
children[1] = tileFactory.createTile(childSector, childLevel, childRow, childCol); // Southeast
348349

349350
childRow = 2 * this.row + 1;
350351
childCol = 2 * this.column;
351-
childSector = new Sector(latMid, lonMin, childDelta, childDelta);
352+
childSector = new Sector(latMid, lonMin, childDeltaLat, childDeltaLon);
352353
children[2] = tileFactory.createTile(childSector, childLevel, childRow, childCol); // Northwest
353354

354355
childRow = 2 * this.row + 1;
355356
childCol = 2 * this.column + 1;
356-
childSector = new Sector(latMid, lonMid, childDelta, childDelta);
357+
childSector = new Sector(latMid, lonMid, childDeltaLat, childDeltaLon);
357358
children[3] = tileFactory.createTile(childSector, childLevel, childRow, childCol); // Northeast
358359

359360
return children;

worldwind/src/test/java/gov/nasa/worldwind/globe/BasicTerrainTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public void setUp() {
8282
this.terrain = new BasicTerrain();
8383

8484
// Add a terrain tile used to the mocked terrain
85-
LevelSet levelSet = new LevelSet(new Sector().setFullSphere(), new Location(-90, -180), 1.0, 1, 5, 5); // tiles with 5x5 vertices
85+
LevelSet levelSet = new LevelSet(new Sector().setFullSphere(), new Location(-90, -180), new Location(1.0, 1.0), 1, 5, 5); // tiles with 5x5 vertices
8686
TerrainTile tile = new TerrainTile(new Sector(0, 0, 1, 1), levelSet.firstLevel(), 90, 180);
8787
((BasicTerrain) this.terrain).addTile(tile);
8888

0 commit comments

Comments
 (0)