placenamelayer.java
来自「world wind java sdk 源码」· Java 代码 · 共 1,493 行 · 第 1/4 页
JAVA
1,493 行
// Don't validate uri or localName 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.endEntry();
this.internedQNameStack.removeFirst();
}
}
private void downloadTile(final Tile tile)
{
downloadTile(tile, null);
}
private void downloadTile(final Tile tile, DownloadPostProcessor postProcessor)
{
if (!this.isNetworkRetrievalEnabled())
return;
if (!WorldWind.getRetrievalService().isAvailable())
return;
java.net.URL url;
try
{
url = tile.getRequestURL();
if (WorldWind.getNetworkStatus().isHostUnavailable(url))
return;
}
catch (java.net.MalformedURLException e)
{
Logging.logger().log(java.util.logging.Level.SEVERE,
Logging.getMessage("layers.PlaceNameLayer.ExceptionCreatingUrl", tile), e);
return;
}
Retriever retriever;
if ("http".equalsIgnoreCase(url.getProtocol()) || "https".equalsIgnoreCase(url.getProtocol()))
{
if (postProcessor == null)
postProcessor = new DownloadPostProcessor(this, tile);
retriever = new HTTPRetriever(url, postProcessor);
}
else
{
Logging.logger().severe(
Logging.getMessage("layers.PlaceNameLayer.UnknownRetrievalProtocol", url.toString()));
return;
}
// Apply any overridden timeouts.
Integer cto = AVListImpl.getIntegerValue(this, AVKey.URL_CONNECT_TIMEOUT);
if (cto != null && cto > 0)
retriever.setConnectTimeout(cto);
Integer cro = AVListImpl.getIntegerValue(this, AVKey.URL_READ_TIMEOUT);
if (cro != null && cro > 0)
retriever.setReadTimeout(cro);
Integer srl = AVListImpl.getIntegerValue(this, AVKey.RETRIEVAL_QUEUE_STALE_REQUEST_LIMIT);
if (srl != null && srl > 0)
retriever.setStaleRequestLimit(srl);
WorldWind.getRetrievalService().runRetriever(retriever, tile.getPriority());
}
private void saveBuffer(java.nio.ByteBuffer buffer, java.io.File outFile) throws java.io.IOException
{
synchronized (this.fileLock) // sychronized with read of file in RequestTask.run()
{
WWIO.saveBuffer(buffer, outFile);
}
}
private static class DownloadPostProcessor implements RetrievalPostProcessor
{
final PlaceNameLayer layer;
final Tile tile;
private DownloadPostProcessor(PlaceNameLayer layer, Tile tile)
{
this.layer = layer;
this.tile = tile;
}
public java.nio.ByteBuffer run(Retriever retriever)
{
if (retriever == null)
{
String msg = Logging.getMessage("nullValue.RetrieverIsNull");
Logging.logger().fine(msg);
throw new IllegalArgumentException(msg);
}
try
{
if (!retriever.getState().equals(Retriever.RETRIEVER_STATE_SUCCESSFUL))
return null;
URLRetriever r = (URLRetriever) retriever;
ByteBuffer buffer = r.getBuffer();
if (retriever instanceof HTTPRetriever)
{
HTTPRetriever htr = (HTTPRetriever) retriever;
if (htr.getResponseCode() == java.net.HttpURLConnection.HTTP_NO_CONTENT)
{
// Mark tile as missing to avoid further attempts
tile.getPlaceNameService().markResourceAbsent(tile.getPlaceNameService().getTileNumber(tile.row,
tile.column));
return null;
}
else if (htr.getResponseCode() != java.net.HttpURLConnection.HTTP_OK)
{
// Also mark tile as missing, but for an unknown reason.
tile.getPlaceNameService().markResourceAbsent(tile.getPlaceNameService().getTileNumber(tile.row,
tile.column));
return null;
}
}
final java.io.File outFile = WorldWind.getDataFileStore().newFile(this.tile.getFileCachePath());
if (outFile == null)
return null;
if (outFile.exists())
return buffer; // info is already here; don't need to do anything
if (buffer != null)
{
String contentType = retriever.getContentType();
if (contentType == null)
{
// TODO: logger message
return null;
}
this.layer.saveBuffer(buffer, outFile);
this.layer.firePropertyChange(AVKey.LAYER, null, this);
return buffer;
}
}
catch (ClosedByInterruptException e)
{
Logging.logger().log(java.util.logging.Level.FINE,
Logging.getMessage("generic.OperationCancelled", "placename retrieval"), e);
}
catch (java.io.IOException e)
{
tile.getPlaceNameService().markResourceAbsent(tile.getPlaceNameService().getTileNumber(tile.row,
tile.column));
Logging.logger().log(Level.FINE, Logging.getMessage(
"layers.PlaceNameLayer.ExceptionSavingRetrievedFile", this.tile.getFileCachePath()), e);
}
return null;
}
}
// *** Bulk download ***
// *** Bulk download ***
// *** Bulk download ***
private static final long AVG_TILE_SIZE = 8*1024;
/**
* Start a new {@link gov.nasa.worldwind.retrieve.BulkRetrievalThread} that will try to download all place name
* tiles for a given {@link Sector} and resolution. Note that the target resolution is ignored right now.
*
* @param sector the {@link Sector} to download tiles for.
* @param resolution the target resolution - ignored.
* @return the {@link gov.nasa.worldwind.retrieve.BulkRetrievalThread} that executes the retrieval.
*/
public BulkRetrievalThread makeLocal(Sector sector, double resolution)
{
BulkTileDownloadThread thread = new BulkTileDownloadThread(this, sector, resolution);
thread.setDaemon(true);
thread.start();
return thread;
}
/**
* Get the estimated size in byte of the missing data for the given {@link Sector}
* and resolution. Note that the target resolution must be provided in radian latitude per
* data sample - which is the resolution in meter divided by the globe radius.
*
* @param sector the {@link Sector} to estimate.
* @param resolution the target resolution provided in radian latitude per texel.
* @return the estimated size in byte of the missing imagery.
*/
public long getEstimatedMissingDataSize(Sector sector, double resolution)
{
int tileCount;
try
{
tileCount=this.getMissingTilesCountEstimate(sector, resolution);
}
catch (Exception e)
{
String message = Logging.getMessage("generic.ExceptionDuringDataSizeEstimate", this.getName());
Logging.logger().severe(message);
throw new RuntimeException(message);
}
return tileCount * AVG_TILE_SIZE;
}
private class BulkTileDownloadThread extends BulkRetrievalThread
{
private int MAX_TILE_COUNT_PER_REGION = 200;
private final PlaceNameLayer layer;
private ArrayList<Tile> missingTiles;
public BulkTileDownloadThread(PlaceNameLayer layer, Sector sector, double resolution)
{
//resolution is compared to the maxDsiatnce value in each placenameservice
super(layer, sector, resolution);
this.layer = layer;
}
public void run()
{
try
{
// Cycle though placenameservices and find missing tiles
missingTiles = new ArrayList<Tile>();
ArrayList<Tile> allMissingTiles =layer.getMissingTilesInSector(this.sector, this.resolution);
this.progress.setTotalCount(allMissingTiles.size());
// Submit missing tiles requests at 10 sec intervals
while (allMissingTiles.size() > 0)
{
transferMissingTiles(allMissingTiles, missingTiles, MAX_TILE_COUNT_PER_REGION);
while (missingTiles.size() > 0)
{
submitMissingTilesRequests();
if (missingTiles.size() > 0)
Thread.sleep(RETRIEVAL_SERVICE_POLL_DELAY);
}
}
}
catch (InterruptedException e)
{
String message = Logging.getMessage("generic.BulkRetrievalInterrupted", layer.getName());
Logging.logger().log(java.util.logging.Level.WARNING, message, e);
}
catch (Exception e)
{
String message = Logging.getMessage("generic.ExceptionDuringBulkRetrieval", layer.getName());
Logging.logger().severe(message);
throw new RuntimeException(message);
}
}
private void transferMissingTiles(ArrayList<Tile> source, ArrayList<Tile> destination, int maxCount)
{
int i = 0;
while (i < maxCount && source.size() > 0)
{
destination.add(source.remove(0));
i++;
}
}
private synchronized void submitMissingTilesRequests() throws InterruptedException
{
RetrievalService rs = WorldWind.getRetrievalService();
int i = 0;
while (this.missingTiles.size() > i && rs.isAvailable())
{
Thread.sleep(1); // generates InterruptedException if thread has been interrupted
Tile tile = this.missingTiles.get(i);
if (tile.isTileLocalOrAbsent())
{
// No need to request that tile anymore
this.missingTiles.remove(i);
}
else
{
layer.downloadTile(tile, new BulkDownloadPostProcessor(layer, tile));
i++;
}
}
}
private class BulkDownloadPostProcessor extends DownloadPostProcessor
{
public BulkDownloadPostProcessor(PlaceNameLayer layer, Tile tile)
{
super(layer, tile);
}
public ByteBuffer run(Retriever retriever)
{
ByteBuffer buffer = super.run(retriever);
if (buffer != null)
removeRetrievedTile(this.tile);
return buffer;
}
}
private synchronized void removeRetrievedTile(Tile tile)
{
this.missingTiles.remove(tile);
this.progress.setCurrentCount(this.progress.getCurrentCount() + 1);
this.progress.setCurrentSize(this.progress.getCurrentSize() + AVG_TILE_SIZE);
this.progress.setLastUpdateTime(System.currentTimeMillis());
// Estimate total size
this.progress.setTotalSize(
this.progress.getCurrentSize() / this.progress.getCurrentCount() * this.progress.getTotalCount());
}
}
private int getMissingTilesCountEstimate(Sector sector, double resolution)
{
int tileCount=0;
int serviceCount = this.placeNameServiceSet.getServiceCount();
for (int i = 0; i < serviceCount; i++)
{
int serviceTileCount=0;
PlaceNameService service = this.getPlaceNameServiceSet().getService(i);
if (service.getMaxDisplayDistance() > resolution)
{
NavigationTile navTile = this.navTiles.get(i);
// drill down into tiles to find bottom level navTiles visible
List<NavigationTile> list = navTile.navTilesVisible(sector);
for(NavigationTile nt: list)
{
serviceTileCount += nt.estimateNumberTilesinSector(sector);
}
}
tileCount += serviceTileCount;
}
return tileCount;
}
private ArrayList<Tile> getMissingTilesInSector(Sector sector, double resolution) throws InterruptedException
{
ArrayList<Tile> allMissingTiles =new ArrayList<Tile>();
int serviceCount = this.placeNameServiceSet.getServiceCount();
for (int i = 0; i < serviceCount; i++)
{
PlaceNameService service = this.getPlaceNameServiceSet().getService(i);
if (service.getMaxDisplayDistance() > resolution)
{
// get tiles in sector
ArrayList<Tile> baseTiles = new ArrayList<Tile>();
NavigationTile navTile = this.navTiles.get(i);
// drill down into tiles to find bottom level navTiles visible
List<NavigationTile> list = navTile.navTilesVisible(sector);
for(NavigationTile nt: list)
{
baseTiles.addAll(nt.getTiles());
}
for (Tile tile : baseTiles)
{
if ((tile.getSector().intersects(sector)) && (!tile.isTileLocalOrAbsent()))
allMissingTiles.add(tile);
}
}
}
return allMissingTiles;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?