Worldwind public release 0.2.1
[worldwind-tracker.git] / gov / nasa / worldwind / LevelSet.java
blobc044f490cccaa8ce11eafda4b3890a8e3510fa40
1 /*
2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
5 All Rights Reserved.
6 */
7 package gov.nasa.worldwind;
9 import gov.nasa.worldwind.geom.*;
11 import java.net.*;
12 import java.util.*;
14 /**
15 * @author tag
16 * @version $Id: LevelSet.java 2092 2007-06-19 07:55:46Z garakl $
18 public class LevelSet extends WWObjectImpl
20 private final Sector sector;
21 private final LatLon levelZeroTileDelta;
22 private final int numLevelZeroColumns;
23 private final java.util.ArrayList<Level> levels = new java.util.ArrayList<Level>();
25 public LevelSet(AVList params)
27 StringBuffer sb = new StringBuffer();
29 Object o = params.getValue(AVKey.LEVEL_ZERO_TILE_DELTA);
30 if (o == null || !(o instanceof LatLon))
31 sb.append(WorldWind.retrieveErrMsg("term.tileDelta"));
33 o = params.getValue(AVKey.SECTOR);
34 if (o == null || !(o instanceof Sector))
35 sb.append(WorldWind.retrieveErrMsg("term.sector"));
37 int numLevels = 0;
38 o = params.getValue(AVKey.NUM_LEVELS);
39 if (o == null || !(o instanceof Integer) || (numLevels = (Integer) o) < 1)
40 sb.append(WorldWind.retrieveErrMsg("term.numLevels"));
42 int numEmptyLevels = 0;
43 o = params.getValue(AVKey.NUM_EMPTY_LEVELS);
44 if (o == null || !(o instanceof Integer) || (numEmptyLevels = (Integer) o) < 0)
45 sb.append(WorldWind.retrieveErrMsg("term.numEMptyLevels"));
47 if (sb.length() > 0)
49 String message = WorldWind.retrieveErrMsg("layers.LevelSet.InvalidLevelDescriptorFields")
50 + " " + sb.toString();
51 WorldWind.logger().log(java.util.logging.Level.FINE, message);
52 throw new IllegalArgumentException(message);
55 this.levelZeroTileDelta = (LatLon) params.getValue(AVKey.LEVEL_ZERO_TILE_DELTA);
56 this.sector = (Sector) params.getValue(AVKey.SECTOR);
58 params = params.copy(); // copy so as not to modify the user's params
60 TileUrlBuilder tub = (TileUrlBuilder) params.getValue(AVKey.TILE_URL_BUILDER);
61 if (tub == null)
63 params.setValue(AVKey.TILE_URL_BUILDER, new TileUrlBuilder()
65 public URL getURL(Tile tile) throws MalformedURLException
67 StringBuffer sb = new StringBuffer(tile.getLevel().getService());
68 if (sb.lastIndexOf("?") != sb.length() - 1)
69 sb.append("?");
70 sb.append("T=");
71 sb.append(tile.getLevel().getDataset());
72 sb.append("&L=");
73 sb.append(tile.getLevel().getLevelName());
74 sb.append("&X=");
75 sb.append(tile.getColumn());
76 sb.append("&Y=");
77 sb.append(tile.getRow());
79 return new URL(sb.toString());
81 });
84 for (int i = 0; i < numLevels; i++)
86 params.setValue(AVKey.LEVEL_NAME, i < numEmptyLevels ? "" : Integer.toString(i - numEmptyLevels));
87 params.setValue(AVKey.LEVEL_NUMBER, i);
89 Angle latDelta = this.levelZeroTileDelta.getLatitude().divide(Math.pow(2, i));
90 Angle lonDelta = this.levelZeroTileDelta.getLongitude().divide(Math.pow(2, i));
91 params.setValue(AVKey.TILE_DELTA, new LatLon(latDelta, lonDelta));
93 this.levels.add(new Level(params));
96 this.numLevelZeroColumns =
97 (int) Math.round(this.sector.getDeltaLon().divide(this.levelZeroTileDelta.getLongitude()));
100 public LevelSet(LevelSet source)
102 if (source == null)
104 String msg = WorldWind.retrieveErrMsg("nullValue.LevelSetIsNull");
105 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
106 throw new IllegalArgumentException(msg);
109 this.levelZeroTileDelta = source.levelZeroTileDelta;
110 this.sector = source.sector;
111 this.numLevelZeroColumns = source.numLevelZeroColumns;
113 for (Level level : source.levels)
115 this.levels.add(level); // Levels are final, so it's safe to copy references.
119 public final Sector getSector()
121 return this.sector;
124 public final LatLon getLevelZeroTileDelta()
126 return this.levelZeroTileDelta;
129 public final ArrayList<Level> getLevels()
131 return this.levels;
134 public final Level getLevel(int levelNumber)
136 return (levelNumber >= 0 && levelNumber < this.levels.size()) ? this.levels.get(levelNumber) : null;
139 public final int getNumLevels()
141 return this.levels.size();
144 public final Level getFirstLevel()
146 return this.getLevel(0);
149 public final Level getLastLevel()
151 return this.getLevel(this.getNumLevels() - 1);
154 public final boolean isFinalLevel(int levelNum)
156 return levelNum == this.getNumLevels() - 1;
159 public final boolean isLevelEmpty(int levelNumber)
161 return this.levels.get(levelNumber).isEmpty();
164 private int numColumnsInLevel(Level level)
166 int levelDelta = level.getLevelNumber() - this.getFirstLevel().getLevelNumber();
167 double twoToTheN = Math.pow(2, levelDelta);
168 return (int) (twoToTheN * this.numLevelZeroColumns);
171 private long getTileNumber(Tile tile)
173 return tile.getRow() * this.numColumnsInLevel(tile.getLevel()) + tile.getColumn();
177 * Instructs the level set that a tile is likely to be absent.
179 * @param tile The tile to mark as having an absent resource.
180 * @throws IllegalArgumentException if <code>tile</code> is null
182 public final void markResourceAbsent(Tile tile)
184 if (tile == null)
186 String msg = WorldWind.retrieveErrMsg("nullValue.TileIsNull");
187 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
188 throw new IllegalArgumentException(msg);
191 tile.getLevel().markResourceAbsent(this.getTileNumber(tile));
195 * Indicates whether a tile has been marked as absent.
197 * @param tile The tile in question.
198 * @return <code>true</code> if the tile is marked absent, otherwise <code>false</code>.
199 * @throws IllegalArgumentException if <code>tile</code> is null
201 public final boolean isResourceAbsent(Tile tile)
203 if (tile == null)
205 String msg = WorldWind.retrieveErrMsg("nullValue.TileIsNull");
206 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
207 throw new IllegalArgumentException(msg);
210 if (tile.getLevel().isEmpty())
211 return true;
213 int tileNumber = tile.getRow() * this.numColumnsInLevel(tile.getLevel()) + tile.getColumn();
214 return tile.getLevel().isResourceAbsent(tileNumber);
218 * Removes the absent-tile mark associated with a tile, if one is associatied.
220 * @param tile The tile to unmark.
221 * @throws IllegalArgumentException if <code>tile</code> is null
223 public final void unmarkResourceAbsent(Tile tile)
225 if (tile == null)
227 String msg = WorldWind.retrieveErrMsg("nullValue.TileIsNull");
228 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
229 throw new IllegalArgumentException(msg);
232 tile.getLevel().unmarkResourceAbsent(this.getTileNumber(tile));