2 Copyright (C) 2001, 2006 United States Government as represented by
3 the Administrator of the National Aeronautics and Space Administration.
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
;
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
);
45 * @param fileCachePath
49 * @throws IllegalArgumentException if any parameter is null
51 public PlaceNameService(String service
, String dataset
, String fileCachePath
, Sector sector
, LatLon tileDelta
,
54 // Data retrieval and caching attributes.
55 this.service
= service
;
56 this.dataset
= dataset
;
57 this.fileCachePath
= fileCachePath
;
58 // Geospatial attributes.
60 this.tileDelta
= tileDelta
;
61 // Display attributes.
64 this.color
= java
.awt
.Color
.white
;
65 this.minDisplayDistance
= Double
.MIN_VALUE
;
66 this.maxDisplayDistance
= Double
.MAX_VALUE
;
68 String message
= this.validate();
71 Logging
.logger().severe(message
);
72 throw new IllegalArgumentException(message
);
75 this.numColumns
= this.numColumnsInLevel();
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) != '.')
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
;
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
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) != '?')
138 sb
.append("TypeName=").append(dataset
);
139 sb
.append("&Request=GetFeature");
140 sb
.append("&Service=WFS");
141 sb
.append("&OUTPUTFORMAT=GML2-GZIP");
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
,
155 copy
.enabled
= this.enabled
;
156 copy
.color
= this.color
;
157 copy
.minDisplayDistance
= this.minDisplayDistance
;
158 copy
.maxDisplayDistance
= this.maxDisplayDistance
;
163 public boolean equals(Object o
)
167 if (o
== null || this.getClass() != o
.getClass())
170 final PlaceNameService other
= (PlaceNameService
) o
;
172 if (this.service
!= null ?
!this.service
.equals(other
.service
) : other
.service
!= null)
174 if (this.dataset
!= null ?
!this.dataset
.equals(other
.dataset
) : other
.dataset
!= null)
176 if (this.fileCachePath
!= null ?
!this.fileCachePath
.equals(other
.fileCachePath
) : other
.fileCachePath
!= null)
178 if (this.sector
!= null ?
!this.sector
.equals(other
.sector
) : other
.sector
!= null)
180 if (this.tileDelta
!= null ?
!this.tileDelta
.equals(other
.tileDelta
) : other
.tileDelta
!= null)
182 if (this.font
!= null ?
!this.font
.equals(other
.font
) : other
.font
!= null)
184 if (this.color
!= null ?
!this.color
.equals(other
.color
) : other
.color
!= null)
186 if (this.minDisplayDistance
!= other
.minDisplayDistance
)
188 //noinspection RedundantIfStatement
189 if (this.maxDisplayDistance
!= other
.maxDisplayDistance
)
195 public synchronized final java
.awt
.Color
getColor()
200 public final String
getDataset()
208 * @throws IllegalArgumentException if <code>dc</code> is null
210 public final Extent
getExtent(DrawContext dc
)
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
);
228 public final String
getFileCachePath()
230 return this.fileCachePath
;
233 public final java
.awt
.Font
getFont()
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()
253 public final Sector
getSector()
258 public final String
getService()
264 public int hashCode()
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();
279 public synchronized final boolean isEnabled()
286 * @throws IllegalArgumentException if <code>color</code> is null
288 public synchronized final void setColor(java
.awt
.Color color
)
292 String message
= Logging
.getMessage("nullValue.ColorIsNull");
293 Logging
.logger().severe(message
);
294 throw new IllegalArgumentException(message
);
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
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
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()
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)