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 + -
显示快捷键?