Updated to worldwind release 20070817
[worldwind-tracker.git] / gov / nasa / worldwind / PlaceNameService.java
blob93af36d9bf4d6968eb22fcac19733ca9f2d00f58
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;
8 import gov.nasa.worldwind.geom.*;
10 /**
11 * @author Paul Collins
12 * @version $Id: PlaceNameService.java 1759 2007-05-07 19:27:49Z dcollins $
14 public class PlaceNameService
16 // Data retrieval and caching attributes.
17 private final String service;
18 private final String dataset;
19 private final String fileCachePath;
20 private static final String FORMAT_SUFFIX = ".xml.gz";
21 // Geospatial attributes.
22 private final Sector sector;
23 private final LatLon tileDelta;
24 private Extent extent = null;
25 private double extentVerticalExaggeration = Double.MIN_VALUE;
26 // Display attributes.
27 private final java.awt.Font font;
28 private boolean enabled;
29 private java.awt.Color color;
30 private double minDisplayDistance;
31 private double maxDisplayDistance;
32 private int numColumns;
34 private static final int MAX_ABSENT_TILE_TRIES = 2;
35 private static final int MIN_ABSENT_TILE_CHECK_INTERVAL = 10000;
36 private final AbsentResourceList absentTiles = new AbsentResourceList(MAX_ABSENT_TILE_TRIES,
37 MIN_ABSENT_TILE_CHECK_INTERVAL);
39 /**
40 * @param service
41 * @param dataset
42 * @param fileCachePath
43 * @param sector
44 * @param tileDelta
45 * @param font
46 * @throws IllegalArgumentException if any parameter is null
48 public PlaceNameService(String service, String dataset, String fileCachePath, Sector sector, LatLon tileDelta,
49 java.awt.Font font)
51 // Data retrieval and caching attributes.
52 this.service = service;
53 this.dataset = dataset;
54 this.fileCachePath = fileCachePath;
55 // Geospatial attributes.
56 this.sector = sector;
57 this.tileDelta = tileDelta;
58 // Display attributes.
59 this.font = font;
60 this.enabled = true;
61 this.color = java.awt.Color.white;
62 this.minDisplayDistance = Double.MIN_VALUE;
63 this.maxDisplayDistance = Double.MAX_VALUE;
65 String message = this.validate();
66 if (message != null)
68 WorldWind.logger().log(java.util.logging.Level.FINE, message);
69 throw new IllegalArgumentException(message);
72 this.numColumns = this.numColumnsInLevel();
75 /**
76 * @param row
77 * @param column
78 * @return
79 * @throws IllegalArgumentException if either <code>row</code> or <code>column</code> is less than zero
81 public String createFileCachePathFromTile(int row, int column)
83 if (row < 0 || column < 0)
85 String message = WorldWind.retrieveErrMsg("PlaceNameService.RowOrColumnOutOfRange");
86 WorldWind.logger().log(java.util.logging.Level.FINE, message);
87 throw new IllegalArgumentException(message);
90 StringBuilder sb = new StringBuilder(this.fileCachePath);
91 sb.append(java.io.File.separator).append(this.dataset);
92 sb.append(java.io.File.separator).append(row);
93 sb.append(java.io.File.separator).append(row).append('_').append(column);
95 if (FORMAT_SUFFIX.charAt(0) != '.')
96 sb.append('.');
97 sb.append(FORMAT_SUFFIX);
99 String path = sb.toString();
100 return path.replaceAll("[:*?<>|]", "");
103 private int numColumnsInLevel()
105 int firstCol = Tile.computeColumn(this.tileDelta.getLongitude(), sector.getMinLongitude());
106 int lastCol = Tile.computeColumn(this.tileDelta.getLongitude(),
107 sector.getMaxLongitude().subtract(this.tileDelta.getLongitude()));
109 return lastCol - firstCol + 1;
112 public long getTileNumber(int row, int column)
114 return row * this.numColumns + column;
118 * @param sector
119 * @return
120 * @throws java.net.MalformedURLException
121 * @throws IllegalArgumentException if <code>sector</code> is null
123 public java.net.URL createServiceURLFromSector(Sector sector) throws java.net.MalformedURLException
125 if (sector == null)
127 String msg = WorldWind.retrieveErrMsg("nullValue.SectorIsNull");
128 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
129 throw new IllegalArgumentException(msg);
132 StringBuilder sb = new StringBuilder(this.service);
133 if (sb.charAt(sb.length() - 1) != '?')
134 sb.append('?');
135 sb.append("TypeName=").append(dataset);
136 sb.append("&Request=GetFeature");
137 sb.append("&Service=WFS");
138 sb.append("&OUTPUTFORMAT=GML2-GZIP");
139 sb.append("&BBOX=");
140 sb.append(sector.getMinLongitude().getDegrees()).append(',');
141 sb.append(sector.getMinLatitude().getDegrees()).append(',');
142 sb.append(sector.getMaxLongitude().getDegrees()).append(',');
143 sb.append(sector.getMaxLatitude().getDegrees());
144 return new java.net.URL(sb.toString());
147 public synchronized final PlaceNameService deepCopy()
149 PlaceNameService copy = new PlaceNameService(this.service, this.dataset, this.fileCachePath, this.sector,
150 this.tileDelta,
151 this.font);
152 copy.enabled = this.enabled;
153 copy.color = this.color;
154 copy.minDisplayDistance = this.minDisplayDistance;
155 copy.maxDisplayDistance = this.maxDisplayDistance;
156 return copy;
159 @Override
160 public boolean equals(Object o)
162 if (this == o)
163 return true;
164 if (o == null || this.getClass() != o.getClass())
165 return false;
167 final PlaceNameService other = (PlaceNameService) o;
169 if (this.service != null ? !this.service.equals(other.service) : other.service != null)
170 return false;
171 if (this.dataset != null ? !this.dataset.equals(other.dataset) : other.dataset != null)
172 return false;
173 if (this.fileCachePath != null ? !this.fileCachePath.equals(other.fileCachePath) : other.fileCachePath != null)
174 return false;
175 if (this.sector != null ? !this.sector.equals(other.sector) : other.sector != null)
176 return false;
177 if (this.tileDelta != null ? !this.tileDelta.equals(other.tileDelta) : other.tileDelta != null)
178 return false;
179 if (this.font != null ? !this.font.equals(other.font) : other.font != null)
180 return false;
181 if (this.color != null ? !this.color.equals(other.color) : other.color != null)
182 return false;
183 if (this.minDisplayDistance != other.minDisplayDistance)
184 return false;
185 //noinspection RedundantIfStatement
186 if (this.maxDisplayDistance != other.maxDisplayDistance)
187 return false;
189 return true;
192 public synchronized final java.awt.Color getColor()
194 return this.color;
197 public final String getDataset()
199 return this.dataset;
203 * @param dc
204 * @return
205 * @throws IllegalArgumentException if <code>dc</code> is null
207 public final Extent getExtent(DrawContext dc)
209 if (dc == null)
211 String message = WorldWind.retrieveErrMsg("nullValue.DrawContextIsNull");
212 WorldWind.logger().log(java.util.logging.Level.FINE, message);
213 throw new IllegalArgumentException(message);
216 if (this.extent == null || this.extentVerticalExaggeration != dc.getVerticalExaggeration())
218 this.extentVerticalExaggeration = dc.getVerticalExaggeration();
219 this.extent = Sector.computeBoundingCylinder(dc.getGlobe(), this.extentVerticalExaggeration, this.sector);
222 return extent;
225 public final String getFileCachePath()
227 return this.fileCachePath;
230 public final java.awt.Font getFont()
232 return this.font;
235 public synchronized final double getMaxDisplayDistance()
237 return this.maxDisplayDistance;
240 public synchronized final double getMinDisplayDistance()
242 return this.minDisplayDistance;
245 public final LatLon getTileDelta()
247 return tileDelta;
250 public final Sector getSector()
252 return this.sector;
255 public final String getService()
257 return this.service;
260 @Override
261 public int hashCode()
263 int result;
264 result = (service != null ? service.hashCode() : 0);
265 result = 29 * result + (this.dataset != null ? this.dataset.hashCode() : 0);
266 result = 29 * result + (this.fileCachePath != null ? this.fileCachePath.hashCode() : 0);
267 result = 29 * result + (this.sector != null ? this.sector.hashCode() : 0);
268 result = 29 * result + (this.tileDelta != null ? this.tileDelta.hashCode() : 0);
269 result = 29 * result + (this.font != null ? this.font.hashCode() : 0);
270 result = 29 * result + (this.color != null ? this.color.hashCode() : 0);
271 result = 29 * result + ((Double) minDisplayDistance).hashCode();
272 result = 29 * result + ((Double) maxDisplayDistance).hashCode();
273 return result;
276 public synchronized final boolean isEnabled()
278 return this.enabled;
282 * @param color
283 * @throws IllegalArgumentException if <code>color</code> is null
285 public synchronized final void setColor(java.awt.Color color)
287 if (color == null)
289 String message = WorldWind.retrieveErrMsg("nullValue.ColorIsNull");
290 WorldWind.logger().log(java.util.logging.Level.FINE, message);
291 throw new IllegalArgumentException(message);
294 this.color = color;
297 public synchronized final void setEnabled(boolean enabled)
299 this.enabled = enabled;
303 * @param maxDisplayDistance
304 * @throws IllegalArgumentException if <code>maxDisplayDistance</code> is less than the current minimum display
305 * distance
307 public synchronized final void setMaxDisplayDistance(double maxDisplayDistance)
309 if (maxDisplayDistance < this.minDisplayDistance)
311 String message = WorldWind.retrieveErrMsg("PlaceNameService.MaxDisplayDistanceLessThanMinDisplayDistance");
312 WorldWind.logger().log(java.util.logging.Level.FINE, message);
313 throw new IllegalArgumentException(message);
316 this.maxDisplayDistance = maxDisplayDistance;
320 * @param minDisplayDistance
321 * @throws IllegalArgumentException if <code>minDisplayDistance</code> is less than the current maximum display
322 * distance
324 public synchronized final void setMinDisplayDistance(double minDisplayDistance)
326 if (minDisplayDistance > this.maxDisplayDistance)
328 String message = WorldWind.retrieveErrMsg("PlaceNameService.MinDisplayDistanceGrtrThanMaxDisplayDistance");
329 WorldWind.logger().log(java.util.logging.Level.FINE, message);
330 throw new IllegalArgumentException(message);
333 this.minDisplayDistance = minDisplayDistance;
336 public synchronized final void markResourceAbsent(long tileNumber)
338 this.absentTiles.markResourceAbsent(tileNumber);
341 public synchronized final boolean isResourceAbsent(long resourceNumber)
343 return this.absentTiles.isResourceAbsent(resourceNumber);
346 public synchronized final void unmarkResourceAbsent(long tileNumber)
348 this.absentTiles.unmarkResourceAbsent(tileNumber);
352 * Determines if this <code>PlaceNameService'</code> constructor arguments are valid.
354 * @return null if valid, otherwise a <code>String</code> containing a description of why it is invalid.
356 public final String validate()
358 String msg = "";
359 if (this.service == null)
361 msg += WorldWind.retrieveErrMsg("nullValue.ServiceIsNull") + ", ";
363 if (this.dataset == null)
365 msg += WorldWind.retrieveErrMsg("nullValue.DataSetIsNull") + ", ";
367 if (this.fileCachePath == null)
369 msg += WorldWind.retrieveErrMsg("nullValue.FileCachePathIsNull") + ", ";
371 if (this.sector == null)
373 msg += WorldWind.retrieveErrMsg("nullValue.SectorIsNull") + ", ";
375 if (this.tileDelta == null)
377 msg += WorldWind.retrieveErrMsg("nullValue.TileDeltaIsNull") + ", ";
379 if (this.font == null)
381 msg += WorldWind.retrieveErrMsg("nullValue.FontIsNull") + ", ";
384 if (msg.length() == 0)
386 return null;
389 return msg;