tiledrasterproducer.java
来自「world wind java sdk 源码」· Java 代码 · 共 965 行 · 第 1/3 页
JAVA
965 行
minLon = tileOrigin.getLongitude().degrees + minLon * tileDelta.getLongitude().degrees;
double maxLon = Math.ceil((sector.getMaxLongitude().degrees - tileOrigin.getLongitude().degrees)
/ tileDelta.getLongitude().degrees);
maxLon = tileOrigin.getLongitude().degrees + maxLon * tileDelta.getLongitude().degrees;
return Sector.fromDegrees(minLat, maxLat, minLon, maxLon).isWithinLatLonLimits();
}
protected Sector computeBoundingSector(Iterable<? extends DataRaster> rasters)
{
Sector sector = null;
for (DataRaster raster : rasters)
sector = (sector != null) ? raster.getSector().union(sector) : raster.getSector();
return sector;
}
protected LatLon computeRasterTileDelta(int tileWidth, int tileHeight, Iterable<? extends DataRaster> rasters)
{
LatLon pixelSize = this.computeSmallestPixelSize(rasters);
// Compute the tile size in latitude and longitude, given a raster's sector and dimension, and the tile
// dimensions. In this computation a pixel is assumed to cover a finite area.
double latDelta = tileHeight * pixelSize.getLatitude().degrees;
double lonDelta = tileWidth * pixelSize.getLongitude().degrees;
return LatLon.fromDegrees(latDelta, lonDelta);
}
protected LatLon computeDesiredTileDelta(Sector sector)
{
double levelZeroLat = Math.min(sector.getDeltaLatDegrees(), DEFAULT_LEVEL_ZERO_TILE_DELTA);
double levelZeroLon = Math.min(sector.getDeltaLonDegrees(), DEFAULT_LEVEL_ZERO_TILE_DELTA);
return LatLon.fromDegrees(levelZeroLat, levelZeroLon);
}
protected LatLon computeRasterPixelSize(DataRaster raster)
{
// Compute the raster's pixel dimension in latitude and longitude. In this computation a pixel is assumed to
// cover a finite area.
return LatLon.fromDegrees(
raster.getSector().getDeltaLatDegrees() / raster.getHeight(),
raster.getSector().getDeltaLonDegrees() / raster.getWidth());
}
protected LatLon computeSmallestPixelSize(Iterable<? extends DataRaster> rasters)
{
// Find the smallest pixel dimensions in the given rasters.
double smallestLat = Double.MAX_VALUE;
double smallestLon = Double.MAX_VALUE;
for (DataRaster raster : rasters)
{
LatLon curSize = this.computeRasterPixelSize(raster);
if (smallestLat > curSize.getLatitude().degrees)
smallestLat = curSize.getLatitude().degrees;
if (smallestLon > curSize.getLongitude().degrees)
smallestLon = curSize.getLongitude().degrees;
}
return LatLon.fromDegrees(smallestLat, smallestLon);
}
protected int computeNumLevels(LatLon levelZeroDelta, LatLon lastLevelDelta)
{
// Compute the number of levels needed to achieve the given last level tile delta, starting from the given
// level zero tile delta.
double numLatLevels = WWMath.logBase2(levelZeroDelta.getLatitude().getDegrees())
- WWMath.logBase2(lastLevelDelta.getLatitude().getDegrees());
double numLonLevels = WWMath.logBase2(levelZeroDelta.getLongitude().getDegrees())
- WWMath.logBase2(lastLevelDelta.getLongitude().getDegrees());
// Compute the maximum number of levels needed, but limit the number of levels to positive integers greater
// than or equal to one.
int numLevels = (int) Math.ceil(Math.max(numLatLevels, numLonLevels));
if (numLevels < 1)
numLevels = 1;
return numLevels;
}
//**************************************************************//
//******************** DataRaster Assembly *******************//
//**************************************************************//
protected void assembleDataRasters() throws Exception
{
// Exit if the caller has instructed us to stop production.
if (this.isStopped())
return;
for (DataSource source : this.getDataSourceList())
{
// Exit if the caller has instructed us to stop production.
if (this.isStopped())
break;
String message = this.validateDataSource(source);
if (message != null)
{
Logging.logger().severe(message);
throw new java.io.IOException(message);
}
this.assembleDataSource(source);
}
}
protected void assembleDataSource(DataSource dataSource) throws Exception
{
if (dataSource.getSource() instanceof DataRaster)
{
this.dataRasterList.add((DataRaster) dataSource.getSource());
}
else
{
DataRasterReader reader = ReadableDataRaster.findReaderFor(dataSource, this.getDataRasterReaders());
this.dataRasterList.add(new ReadableDataRaster(dataSource, reader, this.getCache()));
}
}
protected String validateDataSource(DataSource dataSource)
{
if (dataSource == null)
return Logging.getMessage("nullValue.DataSourceIsNull");
if (!(dataSource.getSource() instanceof DataRaster))
{
DataRasterReader reader = ReadableDataRaster.findReaderFor(dataSource, this.getDataRasterReaders());
if (reader == null)
return Logging.getMessage("DataStoreProducer.InvalidDataSource", dataSource);
}
return null;
}
protected static MemoryCache createDefaultCache()
{
long cacheSize = Configuration.getLongValue(AVKey.TILED_RASTER_PRODUCER_CACHE_SIZE,
DEFAULT_TILED_RASTER_PRODUCER_CACHE_SIZE);
return new BasicMemoryCache((long) (0.8 * cacheSize), cacheSize);
}
//**************************************************************//
//******************** LevelSet Installation *****************//
//**************************************************************//
protected void installLevelSet(LevelSet levelSet, AVList params) throws java.io.IOException
{
// Exit if the caller has instructed us to stop production.
if (this.isStopped())
return;
// Setup the progress parameters.
this.setProgressParams(levelSet);
this.startProgress();
Sector sector = levelSet.getSector();
Level level = levelSet.getFirstLevel();
Angle dLat = level.getTileDelta().getLatitude();
Angle dLon = level.getTileDelta().getLongitude();
Angle latOrigin = levelSet.getTileOrigin().getLatitude();
Angle lonOrigin = levelSet.getTileOrigin().getLongitude();
int firstRow = Tile.computeRow(dLat, sector.getMinLatitude(), latOrigin);
int firstCol = Tile.computeColumn(dLon, sector.getMinLongitude(), lonOrigin);
int lastRow = Tile.computeRow(dLat, sector.getMaxLatitude(), latOrigin);
int lastCol = Tile.computeColumn(dLon, sector.getMaxLongitude(), lonOrigin);
Angle p1 = Tile.computeRowLatitude(firstRow, dLat, latOrigin);
for (int row = firstRow; row <= lastRow; row++)
{
// Exit if the caller has instructed us to stop production.
if (this.isStopped())
break;
Angle p2 = p1.add(dLat);
Angle t1 = Tile.computeColumnLongitude(firstCol, dLon, lonOrigin);
for (int col = firstCol; col <= lastCol; col++)
{
// Exit if the caller has instructed us to stop production.
if (this.isStopped())
break;
Angle t2 = t1.add(dLon);
Tile tile = new Tile(new Sector(p1, p2, t1, t2), level, row, col);
DataRaster tileRaster = this.createTileRaster(levelSet, tile, params);
// Write the top-level tile raster to disk.
if (tileRaster != null)
this.installTileRasterLater(tile, tileRaster, params);
t1 = t2;
}
p1 = p2;
}
}
protected DataRaster createTileRaster(LevelSet levelSet, Tile tile, AVList params) throws java.io.IOException
{
// Exit if the caller has instructed us to stop production.
if (this.isStopped())
return null;
DataRaster tileRaster;
// If we have reached the final level, then create a tile raster from the original data sources.
if (levelSet.isFinalLevel(tile.getLevelNumber()))
{
tileRaster = this.drawDataSources(levelSet, tile, this.dataRasterList, params);
}
// Otherwise, recursively create a tile raster from the next level's tile rasters.
else
{
tileRaster = this.drawDescendants(levelSet, tile, params);
}
this.updateProgress();
return tileRaster;
}
protected DataRaster drawDataSources(LevelSet levelSet, Tile tile, Iterable<DataRaster> dataRasters, AVList params)
throws java.io.IOException
{
DataRaster tileRaster = null;
// Find the data sources that intersect this tile and intersect the LevelSet sector.
java.util.ArrayList<DataRaster> intersectingRasters = new java.util.ArrayList<DataRaster>();
for (DataRaster raster : dataRasters)
{
if (raster.getSector().intersects(tile.getSector()) && raster.getSector().intersects(levelSet.getSector()))
intersectingRasters.add(raster);
}
// If any data sources intersect this tile, and the tile's level is not empty, then we attempt to read those
// sources and render them into this tile.
if (!intersectingRasters.isEmpty() && !tile.getLevel().isEmpty())
{
// Create the tile raster to render into.
tileRaster = this.createDataRaster(tile.getLevel().getTileWidth(), tile.getLevel().getTileHeight(),
tile.getSector(), params);
// Render each data source raster into the tile raster.
for (DataRaster raster : intersectingRasters)
raster.drawOnCanvas(tileRaster);
}
// Make the data rasters available for garbage collection.
intersectingRasters.clear();
//noinspection UnusedAssignment
intersectingRasters = null;
return tileRaster;
}
protected DataRaster drawDescendants(LevelSet levelSet, Tile tile, AVList params) throws java.io.IOException
{
DataRaster tileRaster = null;
boolean hasDescendants = false;
// Recursively create sub-tile rasters.
Tile[] subTiles = this.createSubTiles(tile, levelSet.getLevel(tile.getLevelNumber() + 1));
DataRaster[] subRasters = new DataRaster[subTiles.length];
for (int index = 0; index < subTiles.length; index++)
{
// If the sub-tile does not intersect the level set, then skip that sub-tile.
if (subTiles[index].getSector().intersects(levelSet.getSector()))
{
// Recursively create the sub-tile raster.
DataRaster subRaster = this.createTileRaster(levelSet, subTiles[index], params);
// If creating the sub-tile raster fails, then skip that sub-tile.
if (subRaster != null)
{
subRasters[index] = subRaster;
hasDescendants = true;
}
}
}
// Exit if the caller has instructed us to stop production.
if (this.isStopped())
return null;
// If any of the sub-tiles successfully created a data raster, then we potentially create this tile's raster,
// then write the sub-tiles to disk.
if (hasDescendants)
{
// If this tile's level is not empty, then create and render the tile's raster.
if (!tile.getLevel().isEmpty())
{
// Create the tile's raster.
tileRaster = this.createDataRaster(tile.getLevel().getTileWidth(), tile.getLevel().getTileHeight(),
tile.getSector(), params);
for (int index = 0; index < subTiles.length; index++)
{
if (subRasters[index] != null)
{
// Render the sub-tile raster to this this tile raster.
subRasters[index].drawOnCanvas(tileRaster);
// Write the sub-tile raster to disk.
this.installTileRasterLater(subTiles[index], subRasters[index], params);
}
}
}
}
// Make the sub-tiles and sub-rasters available for garbage collection.
for (int index = 0; index < subTiles.length; index++)
{
subTiles[index] = null;
subRasters[index] = null;
}
//noinspection UnusedAssignment
subTiles = null;
//noinspection UnusedAssignment
subRasters = null;
return tileRaster;
}
protected Tile[] createSubTiles(Tile tile, Level nextLevel)
{
Angle p0 = tile.getSector().getMinLatitude();
Angle p2 = tile.getSector().getMaxLatitude();
Angle p1 = Angle.midAngle(p0, p2);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?