placenamelayer.java
来自「world wind java sdk 源码」· Java 代码 · 共 1,493 行 · 第 1/4 页
JAVA
1,493 行
View view = dc.getView();
Position eyePos = view.getEyePosition();
if (eyePos == null)
return false;
Angle lat = clampAngle(eyePos.getLatitude(), sector.getMinLatitude(), sector.getMaxLatitude());
Angle lon = clampAngle(eyePos.getLongitude(), sector.getMinLongitude(), sector.getMaxLongitude());
Vec4 p = dc.getGlobe().computePointFromPosition(lat, lon, 0d);
double distSquared = dc.getView().getEyePoint().distanceToSquared3(p);
//noinspection RedundantIfStatement
if (minDistanceSquared > distSquared || maxDistanceSquared < distSquared)
return false;
return true;
}
private static boolean isTileVisible(DrawContext dc, Tile tile, double minDistanceSquared,
double maxDistanceSquared)
{
if (!tile.getSector().intersects(dc.getVisibleSector()))
return false;
View view = dc.getView();
Position eyePos = view.getEyePosition();
if (eyePos == null)
return false;
Angle lat = clampAngle(eyePos.getLatitude(), tile.getSector().getMinLatitude(),
tile.getSector().getMaxLatitude());
Angle lon = clampAngle(eyePos.getLongitude(), tile.getSector().getMinLongitude(),
tile.getSector().getMaxLongitude());
Vec4 p = dc.getGlobe().computePointFromPosition(lat, lon, 0d);
double distSquared = dc.getView().getEyePoint().distanceToSquared3(p);
//noinspection RedundantIfStatement
if (minDistanceSquared > distSquared || maxDistanceSquared < distSquared)
return false;
return true;
}
private static boolean isNameVisible(DrawContext dc, PlaceNameService service, Position namePosition)
{
double elevation = dc.getVerticalExaggeration() * namePosition.getElevation();
Vec4 namePoint = dc.getGlobe().computePointFromPosition(namePosition.getLatitude(),
namePosition.getLongitude(), elevation);
Vec4 eyeVec = dc.getView().getEyePoint();
double dist = eyeVec.distanceTo3(namePoint);
return dist >= service.getMinDisplayDistance() && dist <= service.getMaxDisplayDistance();
}
private static Angle clampAngle(Angle a, Angle min, Angle max)
{
double degrees = a.degrees;
double minDegrees = min.degrees;
double maxDegrees = max.degrees;
return Angle.fromDegrees(degrees < minDegrees ? minDegrees : (degrees > maxDegrees ? maxDegrees : degrees));
}
// ============== Image Reading and Downloading ======================= //
// ============== Image Reading and Downloading ======================= //
// ============== Image Reading and Downloading ======================= //
private void requestTile(DrawContext dc, Tile tile)
{
Vec4 centroid = tile.getCentroidPoint(dc.getGlobe());
if (this.getReferencePoint() != null)
tile.setPriority(centroid.distanceTo3(this.getReferencePoint()));
RequestTask task = new RequestTask(tile, this);
this.getRequestQ().add(task);
}
private void sendRequests()
{
Runnable task = this.requestQ.poll();
while (task != null)
{
if (!WorldWind.getTaskService().isFull())
{
WorldWind.getTaskService().addTask(task);
}
task = this.requestQ.poll();
}
}
private static class RequestTask implements Runnable, Comparable<RequestTask>
{
private final PlaceNameLayer layer;
private final Tile tile;
RequestTask(Tile tile, PlaceNameLayer layer)
{
this.layer = layer;
this.tile = tile;
}
public void run()
{
if (this.tile.isTileInMemoryWithData())
return;
final java.net.URL tileURL = WorldWind.getDataFileStore().findFile(tile.getFileCachePath(), false);
if (tileURL != null)
{
if (this.layer.loadTile(this.tile, tileURL))
{
tile.getPlaceNameService().unmarkResourceAbsent(tile.getPlaceNameService().getTileNumber(
tile.row,
tile.column));
this.layer.firePropertyChange(AVKey.LAYER, null, this);
return;
}
else
{
// Assume that something's wrong with the file and delete it.
WorldWind.getDataFileStore().removeFile(tileURL);
tile.getPlaceNameService().markResourceAbsent(tile.getPlaceNameService().getTileNumber(tile.row,
tile.column));
String message = Logging.getMessage("generic.DeletedCorruptDataFile", tileURL);
Logging.logger().fine(message);
}
}
this.layer.downloadTile(this.tile);
}
/**
* @param that the task to compare
* @return -1 if <code>this</code> less than <code>that</code>, 1 if greater than, 0 if equal
* @throws IllegalArgumentException if <code>that</code> is null
*/
public int compareTo(RequestTask that)
{
if (that == null)
{
String msg = Logging.getMessage("nullValue.RequestTaskIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
return this.tile.getPriority() == that.tile.getPriority() ? 0 :
this.tile.getPriority() < that.tile.getPriority() ? -1 : 1;
}
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
final RequestTask that = (RequestTask) o;
// Don't include layer in comparison so that requests are shared among layers
return !(tile != null ? !tile.equals(that.tile) : that.tile != null);
}
public int hashCode()
{
return (tile != null ? tile.hashCode() : 0);
}
public String toString()
{
return this.tile.toString();
}
}
private boolean loadTile(Tile tile, java.net.URL url)
{
if (WWIO.isFileOutOfDate(url, this.placeNameServiceSet.getExpiryTime()))
{
// The file has expired. Delete it then request download of newer.
WorldWind.getDataFileStore().removeFile(url);
String message = Logging.getMessage("generic.DataFileExpired", url);
Logging.logger().fine(message);
return false;
}
PlaceNameChunk tileData;
synchronized (this.fileLock)
{
tileData = readTileData(tile, url);
}
if (tileData == null)
return false;
tile.setDataChunk(tileData);
WorldWind.getMemoryCache(Tile.class.getName()).add(tile.getHashInt(), tile);
return true;
}
private static PlaceNameChunk readTileData(Tile tile, java.net.URL url)
{
java.io.InputStream is = null;
try
{
String path = url.getFile();
path = path.replaceAll("%20", " "); // TODO: find a better way to get a path usable by FileInputStream
java.io.FileInputStream fis = new java.io.FileInputStream(path);
java.io.BufferedInputStream buf = new java.io.BufferedInputStream(fis);
is = new java.util.zip.GZIPInputStream(buf);
GMLPlaceNameSAXHandler handler = new GMLPlaceNameSAXHandler();
javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().parse(is, handler);
return handler.createPlaceNameChunk(tile.getPlaceNameService());
}
catch (Exception e)
{
//todo log actual error
Logging.logger().log(Level.FINE,
Logging.getMessage("layers.PlaceNameLayer.ExceptionAttemptingToReadFile", url.toString()), e);
}
finally
{
try
{
if (is != null)
is.close();
}
catch (java.io.IOException e)
{
Logging.logger().log(Level.FINE,
Logging.getMessage("layers.PlaceNameLayer.ExceptionAttemptingToReadFile", url.toString()), e);
}
}
return null;
}
private static CharBuffer newCharBuffer(int numElements)
{
ByteBuffer bb = ByteBuffer.allocateDirect((Character.SIZE / 8) * numElements);
bb.order(ByteOrder.nativeOrder());
return bb.asCharBuffer();
}
private static class GMLPlaceNameSAXHandler extends org.xml.sax.helpers.DefaultHandler
{
static final String GML_FEATURE_MEMBER = "gml:featureMember";
static final String TOPP_FULL_NAME_ND = "topp:full_name_nd";
static final String TOPP_LATITUDE = "topp:latitude";
static final String TOPP_LONGITUDE = "topp:longitude";
final LinkedList<String> internedQNameStack = new LinkedList<String>();
boolean inBeginEndPair = false;
StringBuilder latBuffer = new StringBuilder();
StringBuilder lonBuffer = new StringBuilder();
StringBuilder textArray = new StringBuilder();
int[] textIndexArray = new int[16];
double[] latlonArray = new double[16];
int numEntries = 0;
GMLPlaceNameSAXHandler()
{
}
PlaceNameChunk createPlaceNameChunk(PlaceNameService service)
{
int numChars = this.textArray.length();
CharBuffer textBuffer = newCharBuffer(numChars);
textBuffer.put(this.textArray.toString());
textBuffer.rewind();
return new PlaceNameChunk(service, textBuffer, this.textIndexArray, this.latlonArray, this.numEntries);
}
void beginEntry()
{
int textIndex = this.textArray.length();
this.textIndexArray = append(this.textIndexArray, this.numEntries, textIndex);
this.inBeginEndPair = true;
}
void endEntry()
{
double lat = this.parseDouble(this.latBuffer);
double lon = this.parseDouble(this.lonBuffer);
int numLatLon = 2 * this.numEntries;
this.latlonArray = this.append(this.latlonArray, numLatLon, lat);
numLatLon++;
this.latlonArray = this.append(this.latlonArray, numLatLon, lon);
this.latBuffer.delete(0, this.latBuffer.length());
this.lonBuffer.delete(0, this.lonBuffer.length());
this.inBeginEndPair = false;
this.numEntries++;
}
double parseDouble(StringBuilder sb)
{
double value = 0;
try
{
value = Double.parseDouble(sb.toString());
}
catch (NumberFormatException e)
{
Logging.logger().log(Level.FINE,
Logging.getMessage("layers.PlaceNameLayer.ExceptionAttemptingToReadFile", ""), e);
}
return value;
}
int[] append(int[] array, int index, int value)
{
if (index >= array.length)
array = this.resizeArray(array);
array[index] = value;
return array;
}
int[] resizeArray(int[] oldArray)
{
int newSize = 2 * oldArray.length;
int[] newArray = new int[newSize];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
return newArray;
}
double[] append(double[] array, int index, double value)
{
if (index >= array.length)
array = this.resizeArray(array);
array[index] = value;
return array;
}
double[] resizeArray(double[] oldArray)
{
int newSize = 2 * oldArray.length;
double[] newArray = new double[newSize];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
return newArray;
}
@SuppressWarnings({"StringEquality"})
public void characters(char ch[], int start, int length)
{
if (!this.inBeginEndPair)
return;
// Top of QName stack is an interned string,
// so we can use pointer comparison.
String internedTopQName = this.internedQNameStack.getFirst();
StringBuilder sb = null;
if (TOPP_LATITUDE == internedTopQName)
sb = this.latBuffer;
else if (TOPP_LONGITUDE == internedTopQName)
sb = this.lonBuffer;
else if (TOPP_FULL_NAME_ND == internedTopQName)
sb = this.textArray;
if (sb != null)
sb.append(ch, start, length);
}
public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes attributes)
{
// Don't validate uri, localName or attributes because they aren't used.
// Intern the qName string so we can use pointer comparison.
String internedQName = qName.intern();
//noinspection StringEquality
if (GML_FEATURE_MEMBER == internedQName)
this.beginEntry();
this.internedQNameStack.addFirst(internedQName);
}
public void endElement(String uri, String localName, String qName)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?