2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
7 package gov
.nasa
.worldwind
.util
;
9 import gov
.nasa
.worldwind
.avlist
.*;
10 import gov
.nasa
.worldwind
.geom
.LatLon
;
14 * @version $Id: Level.java 2471 2007-07-31 21:50:57Z tgaskins $
16 public class Level
implements Comparable
<Level
>
18 private final AVList params
;
19 private final int levelNumber
;
20 private final String levelName
; // null or empty level name signifies no data resources associated with this level
21 private final LatLon tileDelta
;
22 private final int tileWidth
;
23 private final int tileHeight
;
24 private final String cacheName
;
25 private final String service
;
26 private final String dataset
;
27 private final String formatSuffix
;
28 private final double averageTexelSize
;
29 private final String path
;
30 private final TileUrlBuilder urlBuilder
;
31 private long expiryTime
= 0;
33 // Absent tiles: A tile is deemed absent if a specified maximum number of attempts have been made to retrieve it.
34 // Retrieval attempts are governed by a minimum time interval between successive attempts. If an attempt is made
35 // within this interval, the tile is still deemed to be absent until the interval expires.
36 private final AbsentResourceList absentTiles
;
37 int DEFAULT_MAX_ABSENT_TILE_ATTEMPTS
= 2;
38 int DEFAULT_MIN_ABSENT_TILE_CHECK_INTERVAL
= 10000; // milliseconds
40 public Level(AVList params
)
44 String message
= Logging
.getMessage("nullValue.LayerParams");
45 Logging
.logger().severe(message
);
46 throw new IllegalArgumentException(message
);
49 this.params
= params
.copy(); // Private copy to insulate from subsequent changes by the app
50 String message
= this.validate(params
);
53 Logging
.logger().severe(message
);
54 throw new IllegalArgumentException(message
);
57 String ln
= this.params
.getStringValue(AVKey
.LEVEL_NAME
);
58 this.levelName
= ln
!= null ? ln
: "";
60 this.levelNumber
= (Integer
) this.params
.getValue(AVKey
.LEVEL_NUMBER
);
61 this.tileDelta
= (LatLon
) this.params
.getValue(AVKey
.TILE_DELTA
);
62 this.tileWidth
= (Integer
) this.params
.getValue(AVKey
.TILE_WIDTH
);
63 this.tileHeight
= (Integer
) this.params
.getValue(AVKey
.TILE_HEIGHT
);
64 this.cacheName
= this.params
.getStringValue(AVKey
.DATA_CACHE_NAME
);
65 this.service
= this.params
.getStringValue(AVKey
.SERVICE
);
66 this.dataset
= this.params
.getStringValue(AVKey
.DATASET_NAME
);
67 this.formatSuffix
= this.params
.getStringValue(AVKey
.FORMAT_SUFFIX
);
68 this.urlBuilder
= (TileUrlBuilder
) this.params
.getValue(AVKey
.TILE_URL_BUILDER
);
69 this.expiryTime
= AVListImpl
.getLongValue(params
, AVKey
.EXPIRY_TIME
, 0L);
71 double averageTileSize
= 0.5 * (this.tileWidth
+ this.tileHeight
);
72 double averageTileDelta
=
73 0.5 * (this.tileDelta
.getLatitude().getRadians() + this.tileDelta
.getLongitude().getRadians());
74 this.averageTexelSize
= averageTileDelta
/ averageTileSize
;
76 this.path
= this.cacheName
+ "/" + this.levelName
;
78 Integer maxAbsentTileAttempts
= (Integer
) this.params
.getValue(AVKey
.MAX_ABSENT_TILE_ATTEMPTS
);
79 if (maxAbsentTileAttempts
== null)
80 maxAbsentTileAttempts
= DEFAULT_MAX_ABSENT_TILE_ATTEMPTS
;
82 Integer minAbsentTileCheckInterval
= (Integer
) this.params
.getValue(AVKey
.MIN_ABSENT_TILE_CHECK_INTERVAL
);
83 if (minAbsentTileCheckInterval
== null)
84 minAbsentTileCheckInterval
= DEFAULT_MIN_ABSENT_TILE_CHECK_INTERVAL
;
86 this.absentTiles
= new AbsentResourceList(maxAbsentTileAttempts
, minAbsentTileCheckInterval
);
90 * Determines whether the constructor arguments are valid.
91 * @param params the list of parameters to validate.
92 * @return null if valid, otherwise a <code>String</code> containing a description of why it's invalid.
94 protected String
validate(AVList params
)
96 StringBuffer sb
= new StringBuffer();
98 Object o
= params
.getValue(AVKey
.LEVEL_NUMBER
);
99 if (o
== null || !(o
instanceof Integer
) || ((Integer
) o
) < 0)
100 sb
.append(Logging
.getMessage("term.levelNumber"));
102 o
= params
.getValue(AVKey
.LEVEL_NAME
);
103 if (o
== null || !(o
instanceof String
))
104 sb
.append(Logging
.getMessage("term.levelName"));
106 o
= params
.getValue(AVKey
.TILE_WIDTH
);
107 if (o
== null || !(o
instanceof Integer
) || ((Integer
) o
) < 0)
108 sb
.append(Logging
.getMessage("term.tileWidth"));
110 o
= params
.getValue(AVKey
.TILE_HEIGHT
);
111 if (o
== null || !(o
instanceof Integer
) || ((Integer
) o
) < 0)
112 sb
.append(Logging
.getMessage("term.tileHeight"));
114 o
= params
.getValue(AVKey
.TILE_DELTA
);
115 if (o
== null || !(o
instanceof LatLon
))
116 sb
.append(Logging
.getMessage("term.tileDelta"));
118 o
= params
.getValue(AVKey
.DATA_CACHE_NAME
);
119 if (o
== null || !(o
instanceof String
) || ((String
) o
).length() < 1)
120 sb
.append(Logging
.getMessage("term.cacheFolder"));
122 o
= params
.getValue(AVKey
.TILE_URL_BUILDER
);
123 if (o
== null || !(o
instanceof TileUrlBuilder
))
124 sb
.append(Logging
.getMessage("term.tileURLBuilder"));
126 o
= params
.getValue(AVKey
.EXPIRY_TIME
);
127 if (o
!= null && (!(o
instanceof Long
) || ((Long
) o
) < 1))
128 sb
.append(Logging
.getMessage("term.expiryTime"));
130 if (params
.getStringValue(AVKey
.LEVEL_NAME
).length() > 0)
132 o
= params
.getValue(AVKey
.SERVICE
);
133 if (o
== null || !(o
instanceof String
) || ((String
) o
).length() < 1)
134 sb
.append(Logging
.getMessage("term.service"));
136 o
= params
.getValue(AVKey
.DATASET_NAME
);
137 if (o
== null || !(o
instanceof String
) || ((String
) o
).length() < 1)
138 sb
.append(Logging
.getMessage("term.datasetName"));
140 o
= params
.getValue(AVKey
.FORMAT_SUFFIX
);
141 if (o
== null || !(o
instanceof String
) || ((String
) o
).length() < 1)
142 sb
.append(Logging
.getMessage("term.formatSuffix"));
145 if (sb
.length() == 0)
148 return Logging
.getMessage("layers.LevelSet.InvalidLevelDescriptorFields", sb
.toString());
151 public final AVList
getParams()
156 public String
getPath()
161 public final int getLevelNumber()
163 return this.levelNumber
;
166 public String
getLevelName()
168 return this.levelName
;
171 public LatLon
getTileDelta()
173 return this.tileDelta
;
176 public final int getTileWidth()
178 return this.tileWidth
;
181 public final int getTileHeight()
183 return this.tileHeight
;
186 public final String
getFormatSuffix()
188 return this.formatSuffix
;
191 public final String
getService()
196 public final String
getDataset()
201 public final String
getCacheName()
203 return this.cacheName
;
206 public final double getTexelSize(double radius
)
208 return radius
* this.averageTexelSize
;
211 public final boolean isEmpty()
213 return this.levelName
== null || this.levelName
.equals("");
216 public final void markResourceAbsent(long tileNumber
)
218 this.absentTiles
.markResourceAbsent(tileNumber
);
221 public final boolean isResourceAbsent(long tileNumber
)
223 return this.absentTiles
.isResourceAbsent(tileNumber
);
226 public final void unmarkResourceAbsent(long tileNumber
)
228 this.absentTiles
.unmarkResourceAbsent(tileNumber
);
231 public final long getExpiryTime()
236 public void setExpiryTime(long expiryTime
) // TODO: remove
238 this.expiryTime
= expiryTime
;
241 // public interface TileURLBuilder
243 // public URL getURL(Tile tile) throws java.net.MalformedURLException;
247 * Returns the URL necessary to retrieve the specified tile.
248 * @param tile the tile who's resources will be retrieved.
249 * @return the resource URL.
250 * @throws java.net.MalformedURLException if the URL cannot be formed from the tile's parameters.
251 * @throws IllegalArgumentException if <code>tile</code> is null.
253 public java
.net
.URL
getTileResourceURL(Tile tile
) throws java
.net
.MalformedURLException
257 String msg
= Logging
.getMessage("nullValue.TileIsNull");
258 Logging
.logger().severe(msg
);
259 throw new IllegalArgumentException(msg
);
262 return this.urlBuilder
.getURL(tile
);
265 public int compareTo(Level that
)
269 String msg
= Logging
.getMessage("nullValue.LevelIsNull");
270 Logging
.logger().severe(msg
);
271 throw new IllegalArgumentException(msg
);
273 return this.levelNumber
< that
.levelNumber ?
-1 : this.levelNumber
== that
.levelNumber ?
0 : 1;
276 public boolean equals(Object o
)
280 if (o
== null || getClass() != o
.getClass())
283 final Level level
= (Level
) o
;
285 if (levelNumber
!= level
.levelNumber
)
287 if (tileHeight
!= level
.tileHeight
)
289 if (tileWidth
!= level
.tileWidth
)
291 if (cacheName
!= null ?
!cacheName
.equals(level
.cacheName
) : level
.cacheName
!= null)
293 if (dataset
!= null ?
!dataset
.equals(level
.dataset
) : level
.dataset
!= null)
295 if (formatSuffix
!= null ?
!formatSuffix
.equals(level
.formatSuffix
) : level
.formatSuffix
!= null)
297 if (levelName
!= null ?
!levelName
.equals(level
.levelName
) : level
.levelName
!= null)
299 if (service
!= null ?
!service
.equals(level
.service
) : level
.service
!= null)
301 //noinspection RedundantIfStatement
302 if (tileDelta
!= null ?
!tileDelta
.equals(level
.tileDelta
) : level
.tileDelta
!= null)
308 public int hashCode()
311 result
= levelNumber
;
312 result
= 29 * result
+ (levelName
!= null ? levelName
.hashCode() : 0);
313 result
= 29 * result
+ (tileDelta
!= null ? tileDelta
.hashCode() : 0);
314 result
= 29 * result
+ tileWidth
;
315 result
= 29 * result
+ tileHeight
;
316 result
= 29 * result
+ (formatSuffix
!= null ? formatSuffix
.hashCode() : 0);
317 result
= 29 * result
+ (service
!= null ? service
.hashCode() : 0);
318 result
= 29 * result
+ (dataset
!= null ? dataset
.hashCode() : 0);
319 result
= 29 * result
+ (cacheName
!= null ? cacheName
.hashCode() : 0);
324 public String
toString()