Worldwind public release 0.2.1
[worldwind-tracker.git] / gov / nasa / worldwind / Tile.java
blob73fec235c9854d513bf326721d76ebdb639aaa85
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 /**
12 * @author tag
13 * @version $Id: Tile.java 2029 2007-06-14 02:44:20Z tgaskins $
15 public class Tile implements Comparable<Tile>, Cacheable
17 private final Sector sector;
18 private final gov.nasa.worldwind.Level level;
19 private final int row;
20 private final int column;
21 private final TileKey tileKey;
22 private double priority = Double.MAX_VALUE; // Default is minimum priority
23 // The following is late bound because it's only selectively needed and costly to create
24 private String path;
26 public Tile(Sector sector, Level level, int row, int column)
28 if (sector == null)
30 String msg = WorldWind.retrieveErrMsg("nullValue.SectorIsNull");
31 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
32 throw new IllegalArgumentException(msg);
34 if (level == null)
36 String msg = WorldWind.retrieveErrMsg("nullValue.LevelIsNull");
37 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
38 throw new IllegalArgumentException(msg);
40 if (row < 0)
42 String msg = WorldWind.retrieveErrMsg("generic.rowIndexOutOfRange");
43 msg += WorldWind.retrieveErrMsg("punctuation.space");
44 msg += String.valueOf(row);
46 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
47 throw new IllegalArgumentException(msg);
49 if (column < 0)
51 String msg = WorldWind.retrieveErrMsg("generic.columnIndexOutOfRange");
52 msg += WorldWind.retrieveErrMsg("punctuation.space");
53 msg += String.valueOf(row);
55 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
56 throw new IllegalArgumentException(msg);
59 this.sector = sector;
60 this.level = level;
61 this.row = row;
62 this.column = column;
63 this.tileKey = new TileKey(this);
64 this.path = null;
67 public Tile(Sector sector, gov.nasa.worldwind.Level level)
69 if (sector == null)
71 String msg = WorldWind.retrieveErrMsg("nullValue.SectorIsNull");
72 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
73 throw new IllegalArgumentException(msg);
75 if (level == null)
77 String msg = WorldWind.retrieveErrMsg("nullValue.LevelIsNull");
78 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
79 throw new IllegalArgumentException(msg);
82 this.sector = sector;
83 this.level = level;
84 this.row = Tile.computeRow(sector.getDeltaLat(), sector.getMinLatitude());
85 this.column = Tile.computeColumn(sector.getDeltaLon(), sector.getMinLongitude());
86 this.tileKey = new TileKey(this);
87 this.path = null;
90 public Tile(Sector sector)
92 if (sector == null)
94 String msg = WorldWind.retrieveErrMsg("nullValue.SectorIsNull");
95 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
96 throw new IllegalArgumentException(msg);
99 this.sector = sector;
100 this.level = null;
101 this.row = 0;
102 this.column = 0;
103 this.tileKey = new TileKey(this);
104 this.path = null;
107 public long getSizeInBytes()
109 // Return just an approximate size
110 long size = 0;
112 if (this.sector != null)
113 size += this.sector.getSizeInBytes();
115 if (this.path != null)
116 size += this.getPath().length();
118 size += 32; // to account for the references and the TileKey size
120 return size;
123 public String getPath()
125 if (this.path == null)
127 this.path = this.level.getPath() + "/" + this.row + "/" + this.row + "_" + this.column;
128 if (!this.level.isEmpty())
129 path += this.level.getFormatSuffix();
132 return this.path;
135 public final Sector getSector()
137 return sector;
140 public gov.nasa.worldwind.Level getLevel()
142 return level;
145 public final int getLevelNumber()
147 return this.level != null ? this.level.getLevelNumber() : 0;
150 public final String getLevelName()
152 return this.level != null ? this.level.getLevelName() : "";
155 public final int getRow()
157 return row;
160 public final int getColumn()
162 return column;
165 public final String getCacheName()
167 return this.level != null ? this.level.getCacheName() : null;
170 public final String getFormatSuffix()
172 return this.level != null ? this.level.getFormatSuffix() : null;
175 public final TileKey getTileKey()
177 return this.tileKey;
180 public java.net.URL getResourceURL() throws java.net.MalformedURLException
182 return this.level != null ? this.level.getTileResourceURL(this) : null;
185 public String getLabel()
187 StringBuilder sb = new StringBuilder();
189 sb.append(this.getLevelNumber());
190 sb.append("(");
191 sb.append(this.getLevelName());
192 sb.append(")");
193 sb.append(", ").append(this.getRow());
194 sb.append(", ").append(this.getColumn());
196 return sb.toString();
199 public int compareTo(Tile tile)
201 if (tile == null)
203 String msg = WorldWind.retrieveErrMsg("nullValue.TileIsNull");
204 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
205 throw new IllegalArgumentException(msg);
208 // No need to compare Sectors or path because they are redundant with row and column
209 if (tile.getLevelNumber() == this.getLevelNumber() && tile.row == this.row && tile.column == this.column)
210 return 0;
212 if (this.getLevelNumber() < tile.getLevelNumber()) // Lower-res levels compare lower than higher-res
213 return -1;
214 if (this.getLevelNumber() > tile.getLevelNumber())
215 return 1;
217 if (this.row < tile.row)
218 return -1;
219 if (this.row > tile.row)
220 return 1;
222 if (this.column < tile.column)
223 return -1;
225 return 1; // tile.column must be > this.column because equality was tested above
228 @Override
229 public boolean equals(Object o)
231 // Equality based only on the tile key
232 if (this == o)
233 return true;
234 if (o == null || getClass() != o.getClass())
235 return false;
237 final Tile tile = (Tile) o;
239 return !(tileKey != null ? !tileKey.equals(tile.tileKey) : tile.tileKey != null);
242 @Override
243 public int hashCode()
245 return (tileKey != null ? tileKey.hashCode() : 0);
248 @Override
249 public String toString()
251 return this.getPath();
255 * Computes the row index of a latitude in the global tile grid corresponding to a specified grid interval.
257 * @param delta the grid interval
258 * @param latitude the latitude for which to compute the row index
259 * @return the row index of the row containing the specified latitude
260 * @throws IllegalArgumentException if <code>delta</code> is null or non-positive, or <code>latitude</code> is null,
261 * greater than positive 90 degrees, or less than negative 90 degrees
263 public static int computeRow(Angle delta, Angle latitude)
265 if (delta == null || latitude == null)
267 String message = WorldWind.retrieveErrMsg("nullValue.AngleIsNull");
268 WorldWind.logger().log(java.util.logging.Level.FINE, message);
269 throw new IllegalArgumentException(message);
272 if (delta.degrees <= 0d)
274 String message = WorldWind.retrieveErrMsg("generic.deltaAngleOutOfRange");
275 WorldWind.logger().log(java.util.logging.Level.FINE, message);
276 throw new IllegalArgumentException(message);
279 if (latitude.degrees < -90d || latitude.degrees > 90d)
281 String message = WorldWind.retrieveErrMsg("generic.angleOutOfRange");
282 WorldWind.logger().log(java.util.logging.Level.FINE, message);
283 throw new IllegalArgumentException(message);
286 if (latitude.degrees == 90d)
287 return (int) (180d / delta.degrees) - 1;
288 else
289 return (int) ((latitude.degrees + 90d) / delta.degrees);
293 * Computes the column index of a longitude in the global tile grid corresponding to a specified grid interval.
295 * @param delta the grid interval
296 * @param longitude the longitude for which to compute the column index
297 * @return the column index of the column containing the specified latitude
298 * @throws IllegalArgumentException if <code>delta</code> is null or non-positive, or <code>longitude</code> is
299 * null, greater than positive 180 degrees, or less than negative 180 degrees
301 public static int computeColumn(Angle delta, Angle longitude)
303 if (delta == null || longitude == null)
305 String message = WorldWind.retrieveErrMsg("nullValue.AngleIsNull");
306 WorldWind.logger().log(java.util.logging.Level.FINE, message);
307 throw new IllegalArgumentException(message);
310 if (delta.degrees <= 0d)
312 String message = WorldWind.retrieveErrMsg("generic.deltaAngleOutOfRange");
313 WorldWind.logger().log(java.util.logging.Level.FINE, message);
314 throw new IllegalArgumentException(message);
317 if (longitude.degrees < -180d || longitude.degrees > 180d)
319 String message = WorldWind.retrieveErrMsg("generic.angleOutOfRange");
320 WorldWind.logger().log(java.util.logging.Level.FINE, message);
321 throw new IllegalArgumentException(message);
324 if (longitude.degrees == 180d)
325 return (int) (360d / delta.degrees) - 1;
326 else
327 return (int) ((longitude.degrees + 180d) / delta.degrees);
331 * Determines the minimum latitude of a row in the global tile grid corresponding to a specified grid interval.
333 * @param row the row index of the row in question
334 * @param delta the grid interval
335 * @return the minimum latitude of the tile corresponding to the specified row
336 * @throws IllegalArgumentException if the grid interval (<code>delta</code>) is null or zero or the row index is
337 * negative.
339 public static Angle computeRowLatitude(int row, Angle delta)
341 if (delta == null)
343 String message = WorldWind.retrieveErrMsg("nullValue.AngleIsNull");
344 WorldWind.logger().log(java.util.logging.Level.FINE, message);
345 throw new IllegalArgumentException(message);
347 if (row < 0)
349 String msg = WorldWind.retrieveErrMsg("generic.rowIndexOutOfRange");
350 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
351 throw new IllegalArgumentException(msg);
354 if (delta.degrees <= 0d)
356 String message = WorldWind.retrieveErrMsg("generic.deltaAngleOutOfRange");
357 WorldWind.logger().log(java.util.logging.Level.FINE, message);
358 throw new IllegalArgumentException(message);
361 return Angle.fromDegrees(-90d + delta.degrees * row);
365 * Determines the minimum longitude of a column in the global tile grid corresponding to a specified grid interval.
367 * @param column the row index of the row in question
368 * @param delta the grid interval
369 * @return the minimum longitude of the tile corresponding to the specified column
370 * @throws IllegalArgumentException if the grid interval (<code>delta</code>) is null or zero or the column index is
371 * negative.
373 public static Angle computeColumnLongitude(int column, Angle delta)
375 if (delta == null)
377 String message = WorldWind.retrieveErrMsg("nullValue.AngleIsNull");
378 WorldWind.logger().log(java.util.logging.Level.FINE, message);
379 throw new IllegalArgumentException(message);
381 if (column < 0)
383 String msg = WorldWind.retrieveErrMsg("generic.columnIndexOutOfRange");
384 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
385 throw new IllegalArgumentException(msg);
388 if (delta.degrees <= 0d)
390 String message = WorldWind.retrieveErrMsg("generic.deltaAngleOutOfRange");
391 WorldWind.logger().log(java.util.logging.Level.FINE, message);
392 throw new IllegalArgumentException(message);
395 return Angle.fromDegrees(-180 + delta.degrees * column);
398 public double getPriority()
400 return priority;
403 public void setPriority(double priority)
405 this.priority = priority;