Update to Worldwind release 0.4.0
[worldwind-tracker.git] / gov / nasa / worldwind / layers / placename / PlaceNameService.java
blob128c9f7ac69fc98263cf015ec5260ee8730488fb
1 /*
2 Copyright (C) 2001, 2006 United States Government as represented by
3 the Administrator of the National Aeronautics and Space Administration.
4 All Rights Reserved.
5 */
6 package gov.nasa.worldwind.layers.placename;
8 import gov.nasa.worldwind.geom.*;
9 import gov.nasa.worldwind.render.DrawContext;
10 import gov.nasa.worldwind.util.*;
11 import gov.nasa.worldwind.globes.EllipsoidalGlobe;
13 /**
14 * @author Paul Collins
15 * @version $Id: PlaceNameService.java 3307 2007-10-16 14:43:49Z patrickmurris $
17 public class PlaceNameService
19 // Data retrieval and caching attributes.
20 private final String service;
21 private final String dataset;
22 private final String fileCachePath;
23 private static final String FORMAT_SUFFIX = ".xml.gz";
24 // Geospatial attributes.
25 private final Sector sector;
26 private final LatLon tileDelta;
27 private Extent extent = null;
28 private double extentVerticalExaggeration = Double.MIN_VALUE;
29 // Display attributes.
30 private final java.awt.Font font;
31 private boolean enabled;
32 private java.awt.Color color;
33 private double minDisplayDistance;
34 private double maxDisplayDistance;
35 private int numColumns;
37 private static final int MAX_ABSENT_TILE_TRIES = 2;
38 private static final int MIN_ABSENT_TILE_CHECK_INTERVAL = 10000;
39 private final AbsentResourceList absentTiles = new AbsentResourceList(MAX_ABSENT_TILE_TRIES,
40 MIN_ABSENT_TILE_CHECK_INTERVAL);
42 /**
43 * @param service
44 * @param dataset
45 * @param fileCachePath
46 * @param sector
47 * @param tileDelta
48 * @param font
49 * @throws IllegalArgumentException if any parameter is null
51 public PlaceNameService(String service, String dataset, String fileCachePath, Sector sector, LatLon tileDelta,
52 java.awt.Font font)
54 // Data retrieval and caching attributes.
55 this.service = service;
56 this.dataset = dataset;
57 this.fileCachePath = fileCachePath;
58 // Geospatial attributes.
59 this.sector = sector;
60 this.tileDelta = tileDelta;
61 // Display attributes.
62 this.font = font;
63 this.enabled = true;
64 this.color = java.awt.Color.white;
65 this.minDisplayDistance = Double.MIN_VALUE;
66 this.maxDisplayDistance = Double.MAX_VALUE;
68 String message = this.validate();
69 if (message != null)
71 Logging.logger().severe(message);
72 throw new IllegalArgumentException(message);
75 this.numColumns = this.numColumnsInLevel();
78 /**
79 * @param row
80 * @param column
81 * @return
82 * @throws IllegalArgumentException if either <code>row</code> or <code>column</code> is less than zero
84 public String createFileCachePathFromTile(int row, int column)
86 if (row < 0 || column < 0)
88 String message = Logging.getMessage("PlaceNameService.RowOrColumnOutOfRange", row, column);
89 Logging.logger().severe(message);
90 throw new IllegalArgumentException(message);
93 StringBuilder sb = new StringBuilder(this.fileCachePath);
94 sb.append(java.io.File.separator).append(this.dataset);
95 sb.append(java.io.File.separator).append(row);
96 sb.append(java.io.File.separator).append(row).append('_').append(column);
98 if (FORMAT_SUFFIX.charAt(0) != '.')
99 sb.append('.');
100 sb.append(FORMAT_SUFFIX);
102 String path = sb.toString();
103 return path.replaceAll("[:*?<>|]", "");
106 private int numColumnsInLevel()
108 int firstCol = Tile.computeColumn(this.tileDelta.getLongitude(), sector.getMinLongitude());
109 int lastCol = Tile.computeColumn(this.tileDelta.getLongitude(),
110 sector.getMaxLongitude().subtract(this.tileDelta.getLongitude()));
112 return lastCol - firstCol + 1;
115 public long getTileNumber(int row, int column)
117 return row * this.numColumns + column;
121 * @param sector
122 * @return
123 * @throws java.net.MalformedURLException
124 * @throws IllegalArgumentException if <code>sector</code> is null
126 public java.net.URL createServiceURLFromSector(Sector sector) throws java.net.MalformedURLException
128 if (sector == null)
130 String msg = Logging.getMessage("nullValue.SectorIsNull");
131 Logging.logger().severe(msg);
132 throw new IllegalArgumentException(msg);
135 StringBuilder sb = new StringBuilder(this.service);
136 if (sb.charAt(sb.length() - 1) != '?')
137 sb.append('?');
138 sb.append("TypeName=").append(dataset);
139 sb.append("&Request=GetFeature");
140 sb.append("&Service=WFS");
141 sb.append("&OUTPUTFORMAT=GML2-GZIP");
142 sb.append("&BBOX=");
143 sb.append(sector.getMinLongitude().getDegrees()).append(',');
144 sb.append(sector.getMinLatitude().getDegrees()).append(',');
145 sb.append(sector.getMaxLongitude().getDegrees()).append(',');
146 sb.append(sector.getMaxLatitude().getDegrees());
147 return new java.net.URL(sb.toString());
150 public synchronized final PlaceNameService deepCopy()
152 PlaceNameService copy = new PlaceNameService(this.service, this.dataset, this.fileCachePath, this.sector,
153 this.tileDelta,
154 this.font);
155 copy.enabled = this.enabled;
156 copy.color = this.color;
157 copy.minDisplayDistance = this.minDisplayDistance;
158 copy.maxDisplayDistance = this.maxDisplayDistance;
159 return copy;
162 @Override
163 public boolean equals(Object o)
165 if (this == o)
166 return true;
167 if (o == null || this.getClass() != o.getClass())
168 return false;
170 final PlaceNameService other = (PlaceNameService) o;
172 if (this.service != null ? !this.service.equals(other.service) : other.service != null)
173 return false;
174 if (this.dataset != null ? !this.dataset.equals(other.dataset) : other.dataset != null)
175 return false;
176 if (this.fileCachePath != null ? !this.fileCachePath.equals(other.fileCachePath) : other.fileCachePath != null)
177 return false;
178 if (this.sector != null ? !this.sector.equals(other.sector) : other.sector != null)
179 return false;
180 if (this.tileDelta != null ? !this.tileDelta.equals(other.tileDelta) : other.tileDelta != null)
181 return false;
182 if (this.font != null ? !this.font.equals(other.font) : other.font != null)
183 return false;
184 if (this.color != null ? !this.color.equals(other.color) : other.color != null)
185 return false;
186 if (this.minDisplayDistance != other.minDisplayDistance)
187 return false;
188 //noinspection RedundantIfStatement
189 if (this.maxDisplayDistance != other.maxDisplayDistance)
190 return false;
192 return true;
195 public synchronized final java.awt.Color getColor()
197 return this.color;
200 public final String getDataset()
202 return this.dataset;
206 * @param dc
207 * @return
208 * @throws IllegalArgumentException if <code>dc</code> is null
210 public final Extent getExtent(DrawContext dc)
212 if (dc == null)
214 String message = Logging.getMessage("nullValue.DrawContextIsNull");
215 Logging.logger().severe(message);
216 throw new IllegalArgumentException(message);
219 if (this.extent == null || this.extentVerticalExaggeration != dc.getVerticalExaggeration())
221 this.extentVerticalExaggeration = dc.getVerticalExaggeration();
222 this.extent = dc.getGlobe().computeBoundingCylinder(this.extentVerticalExaggeration, this.sector);
225 return extent;
228 public final String getFileCachePath()
230 return this.fileCachePath;
233 public final java.awt.Font getFont()
235 return this.font;
238 public synchronized final double getMaxDisplayDistance()
240 return this.maxDisplayDistance;
243 public synchronized final double getMinDisplayDistance()
245 return this.minDisplayDistance;
248 public final LatLon getTileDelta()
250 return tileDelta;
253 public final Sector getSector()
255 return this.sector;
258 public final String getService()
260 return this.service;
263 @Override
264 public int hashCode()
266 int result;
267 result = (service != null ? service.hashCode() : 0);
268 result = 29 * result + (this.dataset != null ? this.dataset.hashCode() : 0);
269 result = 29 * result + (this.fileCachePath != null ? this.fileCachePath.hashCode() : 0);
270 result = 29 * result + (this.sector != null ? this.sector.hashCode() : 0);
271 result = 29 * result + (this.tileDelta != null ? this.tileDelta.hashCode() : 0);
272 result = 29 * result + (this.font != null ? this.font.hashCode() : 0);
273 result = 29 * result + (this.color != null ? this.color.hashCode() : 0);
274 result = 29 * result + ((Double) minDisplayDistance).hashCode();
275 result = 29 * result + ((Double) maxDisplayDistance).hashCode();
276 return result;
279 public synchronized final boolean isEnabled()
281 return this.enabled;
285 * @param color
286 * @throws IllegalArgumentException if <code>color</code> is null
288 public synchronized final void setColor(java.awt.Color color)
290 if (color == null)
292 String message = Logging.getMessage("nullValue.ColorIsNull");
293 Logging.logger().severe(message);
294 throw new IllegalArgumentException(message);
297 this.color = color;
300 public synchronized final void setEnabled(boolean enabled)
302 this.enabled = enabled;
306 * @param maxDisplayDistance
307 * @throws IllegalArgumentException if <code>maxDisplayDistance</code> is less than the current minimum display
308 * distance
310 public synchronized final void setMaxDisplayDistance(double maxDisplayDistance)
312 if (maxDisplayDistance < this.minDisplayDistance)
314 String message = Logging.getMessage("PlaceNameService.MaxDisplayDistanceLessThanMinDisplayDistance",
315 maxDisplayDistance, this.minDisplayDistance);
316 Logging.logger().severe(message);
317 throw new IllegalArgumentException(message);
320 this.maxDisplayDistance = maxDisplayDistance;
324 * @param minDisplayDistance
325 * @throws IllegalArgumentException if <code>minDisplayDistance</code> is less than the current maximum display
326 * distance
328 public synchronized final void setMinDisplayDistance(double minDisplayDistance)
330 if (minDisplayDistance > this.maxDisplayDistance)
332 String message = Logging.getMessage("PlaceNameService.MinDisplayDistanceGrtrThanMaxDisplayDistance",
333 minDisplayDistance, this.maxDisplayDistance);
334 Logging.logger().severe(message);
335 throw new IllegalArgumentException(message);
338 this.minDisplayDistance = minDisplayDistance;
341 public synchronized final void markResourceAbsent(long tileNumber)
343 this.absentTiles.markResourceAbsent(tileNumber);
346 public synchronized final boolean isResourceAbsent(long resourceNumber)
348 return this.absentTiles.isResourceAbsent(resourceNumber);
351 public synchronized final void unmarkResourceAbsent(long tileNumber)
353 this.absentTiles.unmarkResourceAbsent(tileNumber);
357 * Determines if this <code>PlaceNameService'</code> constructor arguments are valid.
359 * @return null if valid, otherwise a <code>String</code> containing a description of why it is invalid.
361 public final String validate()
363 String msg = "";
364 if (this.service == null)
366 msg += Logging.getMessage("nullValue.ServiceIsNull") + ", ";
368 if (this.dataset == null)
370 msg += Logging.getMessage("nullValue.DataSetIsNull") + ", ";
372 if (this.fileCachePath == null)
374 msg += Logging.getMessage("nullValue.FileCachePathIsNull") + ", ";
376 if (this.sector == null)
378 msg += Logging.getMessage("nullValue.SectorIsNull") + ", ";
380 if (this.tileDelta == null)
382 msg += Logging.getMessage("nullValue.TileDeltaIsNull") + ", ";
384 if (this.font == null)
386 msg += Logging.getMessage("nullValue.FontIsNull") + ", ";
389 if (msg.length() == 0)
391 return null;
394 return msg;