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
;
9 import gov
.nasa
.worldwind
.geom
.*;
16 * @version $Id: LevelSet.java 1746 2007-05-06 17:21:30Z tgaskins $
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(Level
.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"));
38 o
= params
.getValue(Level
.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(Level
.NUM_EMPTY_LEVELS
);
44 if (o
== null || !(o
instanceof Integer
) || (numEmptyLevels
= (Integer
) o
) < 0)
45 sb
.append(WorldWind
.retrieveErrMsg("term.numEMptyLevels"));
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(Level
.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 Level
.TileURLBuilder tub
= (Level
.TileURLBuilder
) params
.getValue(Level
.TILE_URL_BUILDER
);
63 params
.setValue(Level
.TILE_URL_BUILDER
, new Level
.TileURLBuilder()
65 public URL
getURL(Tile tile
) throws MalformedURLException
67 StringBuffer sb
= new StringBuffer(tile
.getLevel().getService());
68 if (sb
.lastIndexOf("?") != sb
.length() - 1)
71 sb
.append(tile
.getLevel().getDataset());
73 sb
.append(tile
.getLevel().getLevelName());
75 sb
.append(tile
.getColumn());
77 sb
.append(tile
.getRow());
79 return new URL(sb
.toString());
84 for (int i
= 0; i
< numLevels
; i
++)
86 params
.setValue(Level
.LEVEL_NAME
, i
< numEmptyLevels ?
"" : Integer
.toString(i
- numEmptyLevels
));
87 params
.setValue(Level
.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(Level
.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
)
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()
124 public final LatLon
getLevelZeroTileDelta()
126 return this.levelZeroTileDelta
;
129 public final ArrayList
<Level
> getLevels()
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
)
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
)
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())
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
)
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
));