diff --git a/rugged-core/src/main/java/org/orekit/rugged/core/dem/AbstractTile.java b/rugged-core/src/main/java/org/orekit/rugged/core/dem/AbstractTile.java index af448dae7daf581ed4d7797003bc9990539d08a4..22b3f0507ad78ad81ec0422048bea3f709b4d3a1 100644 --- a/rugged-core/src/main/java/org/orekit/rugged/core/dem/AbstractTile.java +++ b/rugged-core/src/main/java/org/orekit/rugged/core/dem/AbstractTile.java @@ -43,6 +43,12 @@ public abstract class AbstractTile implements Tile { /** Number of longitude columns. */ private int longitudeColumns; + /** Minimum elevation. */ + private double minElevation; + + /** Maximum elevation. */ + private double maxElevation; + /** Simple constructor. * <p> * Creates an empty tile. @@ -62,8 +68,27 @@ public abstract class AbstractTile implements Tile { this.longitudeStep = longitudeStep; this.latitudeRows = latitudeRows; this.longitudeColumns = longitudeColumns; + this.minElevation = Double.POSITIVE_INFINITY; + this.maxElevation = Double.NEGATIVE_INFINITY; + doSetGeometry(minLatitude, minLongitude, latitudeStep, longitudeStep, latitudeRows, longitudeColumns); } + /** Set the tile global geometry. + * <p> + * This method is called by {@link #setGeometry(double, double, double, + * double, int, int)} after boilerplate processing has been performed. + * </p> + * @param minLatitude minimum latitude + * @param minLongitude minimum longitude + * @param latitudeStep step in latitude (size of one raster element) + * @param longitudeStep step in longitude (size of one raster element) + * @param latitudeRows number of latitude rows + * @param longitudeColumns number of longitude columns + */ + protected abstract void doSetGeometry(double minLatitude, double minLongitude, + double latitudeStep, double longitudeStep, + int latitudeRows, int longitudeColumns); + /** {@inheritDoc} */ @Override public void tileUpdateCompleted() throws RuggedException { @@ -106,6 +131,61 @@ public abstract class AbstractTile implements Tile { return longitudeColumns; } + /** {@inheritDoc} */ + @Override + public double getMinElevation() { + return minElevation; + } + + /** {@inheritDoc} */ + @Override + public double getMaxElevation() { + return maxElevation; + } + + /** {@inheritDoc} */ + @Override + public void setElevation(final int latitudeIndex, final int longitudeIndex, + final double elevation) throws RuggedException { + checkIndices(latitudeIndex, longitudeIndex); + minElevation = FastMath.min(minElevation, elevation); + maxElevation = FastMath.max(maxElevation, elevation); + doSetElevation(latitudeIndex, longitudeIndex, elevation); + } + + /** Set the elevation for one raster element. + * <p> + * This method is called by {@link #setElevation(int, int, double)} after + * boilerplate processing has been performed, including indices checks. + * </p> + * @param latitudeIndex index of latitude (row index) + * @param longitudeIndex index of longitude (column index) + * @param elevation elevation (m) + * @exception RuggedException if indices are out of bound + */ + protected abstract void doSetElevation(int latitudeIndex, int longitudeIndex, double elevation) + throws RuggedException; + + /** {@inheritDoc} */ + @Override + public double getElevationAtIndices(int latitudeIndex, int longitudeIndex) + throws RuggedException { + checkIndices(latitudeIndex, longitudeIndex); + return doGetElevationAtIndices(latitudeIndex, longitudeIndex); + } + + /** Get the elevation of an exact grid point. + * <p> + * This method is called by {@link #getElevationAtIndices(int, int)} after + * boilerplate processing has been performed, including indices checks. + * </p> + * @param latitudeIndex + * @param longitudeIndex + * @return elevation + */ + protected abstract double doGetElevationAtIndices(int latitudeIndex, int longitudeIndex) + throws RuggedException; + /** {@inheritDoc} */ @Override public boolean covers(final double latitude, final double longitude) { @@ -120,7 +200,7 @@ public abstract class AbstractTile implements Tile { * @param longitudeIndex * @exception IllegalArgumentException if indices are out of bound */ - protected void checkIndices(int latitudeIndex, int longitudeIndex) + private void checkIndices(int latitudeIndex, int longitudeIndex) throws RuggedException { if (latitudeIndex < 0 || latitudeIndex >= latitudeRows || longitudeIndex < 0 || longitudeIndex >= longitudeColumns) { diff --git a/rugged-core/src/main/java/org/orekit/rugged/core/dem/SimpleTile.java b/rugged-core/src/main/java/org/orekit/rugged/core/dem/SimpleTile.java index f7e49a906e33553f8c713ce2651a9cc71ab7538d..33ae236c12acf5ebe5e107e3094b96c5d80be251 100644 --- a/rugged-core/src/main/java/org/orekit/rugged/core/dem/SimpleTile.java +++ b/rugged-core/src/main/java/org/orekit/rugged/core/dem/SimpleTile.java @@ -16,7 +16,6 @@ */ package org.orekit.rugged.core.dem; -import org.orekit.rugged.api.RuggedException; /** Simple implementation of a {@link Tile}. * @see SimpleTileFactory @@ -37,27 +36,22 @@ public class SimpleTile extends AbstractTile { /** {@inheritDoc} */ @Override - public void setGeometry(final double minLatitude, final double minLongitude, - final double latitudeStep, final double longitudeStep, - final int latitudeRows, final int longitudeColumns) { - super.setGeometry(minLatitude, minLongitude, latitudeStep, longitudeStep, - latitudeRows, longitudeColumns); + protected void doSetGeometry(final double minLatitude, final double minLongitude, + final double latitudeStep, final double longitudeStep, + final int latitudeRows, final int longitudeColumns) { this.elevations = new double[latitudeRows * longitudeColumns]; } /** {@inheritDoc} */ @Override - public void setElevation(final int latitudeIndex, final int longitudeIndex, - final double elevation) throws RuggedException { - checkIndices(latitudeIndex, longitudeIndex); + protected void doSetElevation(final int latitudeIndex, final int longitudeIndex, + final double elevation) { elevations[latitudeIndex * getLongitudeColumns() + longitudeIndex] = elevation; } /** {@inheritDoc} */ @Override - public double getElevationAtIndices(int latitudeIndex, int longitudeIndex) - throws RuggedException { - checkIndices(latitudeIndex, longitudeIndex); + protected double doGetElevationAtIndices(int latitudeIndex, int longitudeIndex) { return elevations[latitudeIndex * getLongitudeColumns() + longitudeIndex]; } diff --git a/rugged-core/src/main/java/org/orekit/rugged/core/dem/Tile.java b/rugged-core/src/main/java/org/orekit/rugged/core/dem/Tile.java index cea32b7376bf1126ed8455eebeddcaef7dd60366..c72ca7836958d15ff4822e2c5ed6721c68794748 100644 --- a/rugged-core/src/main/java/org/orekit/rugged/core/dem/Tile.java +++ b/rugged-core/src/main/java/org/orekit/rugged/core/dem/Tile.java @@ -60,6 +60,16 @@ public interface Tile extends UpdatableTile { */ int getLongitudeColumns(); + /** Get the minimum elevation in the tile. + * @return minimum elevation in the tile + */ + double getMinElevation(); + + /** Get the maximum elevation in the tile. + * @return maximum elevation in the tile + */ + double getMaxElevation(); + /** Get the elevation of an exact grid point. * @param latitudeIndex * @param longitudeIndex diff --git a/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java b/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java index 21fc47617cd2a362b617330e5effedaf1b511437..80fa5377e82b0d1ed110f0f9beb02ab4ff1c77b3 100644 --- a/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java +++ b/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java @@ -39,11 +39,9 @@ public class MinMaxTreeTile extends AbstractTile { /** {@inheritDoc} */ @Override - public void setGeometry(final double minLatitude, final double minLongitude, - final double latitudeStep, final double longitudeStep, - final int latitudeRows, final int longitudeColumns) { - super.setGeometry(minLatitude, minLongitude, latitudeStep, longitudeStep, - latitudeRows, longitudeColumns); + protected void doSetGeometry(final double minLatitude, final double minLongitude, + final double latitudeStep, final double longitudeStep, + final int latitudeRows, final int longitudeColumns) { this.elevations = new double[latitudeRows * longitudeColumns]; } @@ -56,18 +54,16 @@ public class MinMaxTreeTile extends AbstractTile { /** {@inheritDoc} */ @Override - public void setElevation(final int latitudeIndex, final int longitudeIndex, - final double elevation) throws RuggedException { - checkIndices(latitudeIndex, longitudeIndex); + protected void doSetElevation(final int latitudeIndex, final int longitudeIndex, + final double elevation) { elevations[latitudeIndex * getLongitudeColumns() + longitudeIndex] = elevation; } /** {@inheritDoc} */ @Override - public double getElevationAtIndices(int latitudeIndex, int longitudeIndex) - throws RuggedException { - checkIndices(latitudeIndex, longitudeIndex); + protected double doGetElevationAtIndices(int latitudeIndex, int longitudeIndex) { return elevations[latitudeIndex * getLongitudeColumns() + longitudeIndex]; } + } diff --git a/rugged-core/src/test/java/orekit/rugged/core/dem/ConstantElevationUpdater.java b/rugged-core/src/test/java/orekit/rugged/core/dem/CheckedPatternElevationUpdater.java similarity index 76% rename from rugged-core/src/test/java/orekit/rugged/core/dem/ConstantElevationUpdater.java rename to rugged-core/src/test/java/orekit/rugged/core/dem/CheckedPatternElevationUpdater.java index 00adab3ed2a4b19900740a272eb752984384e88d..8957e4bf97f3c80aeb9a270635667cd02bc6dd35 100644 --- a/rugged-core/src/test/java/orekit/rugged/core/dem/ConstantElevationUpdater.java +++ b/rugged-core/src/test/java/orekit/rugged/core/dem/CheckedPatternElevationUpdater.java @@ -21,16 +21,18 @@ import org.orekit.rugged.api.RuggedException; import org.orekit.rugged.api.TileUpdater; import org.orekit.rugged.api.UpdatableTile; -public class ConstantElevationUpdater implements TileUpdater { +public class CheckedPatternElevationUpdater implements TileUpdater { private double size; private int n; - private double elevation; + private double elevation1; + private double elevation2; - public ConstantElevationUpdater(double size, int n, double elevation) { - this.size = size; - this.n = n; - this.elevation = elevation; + public CheckedPatternElevationUpdater(double size, int n, double elevation1, double elevation2) { + this.size = size; + this.n = n; + this.elevation1 = elevation1; + this.elevation2 = elevation2; } public void updateTile(double latitude, double longitude, UpdatableTile tile) @@ -40,7 +42,7 @@ public class ConstantElevationUpdater implements TileUpdater { size / n, size / n, n, n); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { - tile.setElevation(i, j, elevation); + tile.setElevation(i, j, (((i ^ j) & 0x1) == 0) ? elevation1 : elevation2); } } } diff --git a/rugged-core/src/test/java/orekit/rugged/core/dem/TilesCacheTest.java b/rugged-core/src/test/java/orekit/rugged/core/dem/TilesCacheTest.java index f17275f0f1feec17b134c191c5d57d18bc9abe52..377f7fa432371001ef75baeae4d0aee913e28048 100644 --- a/rugged-core/src/test/java/orekit/rugged/core/dem/TilesCacheTest.java +++ b/rugged-core/src/test/java/orekit/rugged/core/dem/TilesCacheTest.java @@ -31,20 +31,22 @@ public class TilesCacheTest { public void testSingleTile() throws RuggedException { CountingFactory factory = new CountingFactory(); TilesCache<SimpleTile> cache = new TilesCache<SimpleTile>(factory, - new ConstantElevationUpdater(FastMath.toRadians(3.0), 10, 10.0), 1000); + new CheckedPatternElevationUpdater(FastMath.toRadians(3.0), 10, 10.0, 20.0), 1000); SimpleTile tile = cache.getTile(FastMath.toRadians(-23.2), FastMath.toRadians(137.5)); Assert.assertEquals(1, factory.getCount()); Assert.assertEquals(-24.0, FastMath.toDegrees(tile.getMinimumLatitude()), 1.0e-10); Assert.assertEquals(135.0, FastMath.toDegrees(tile.getMinimumLongitude()), 1.0e-10); Assert.assertEquals( 0.3, FastMath.toDegrees(tile.getLatitudeStep()), 1.0e-10); Assert.assertEquals( 0.3, FastMath.toDegrees(tile.getLongitudeStep()), 1.0e-10); + Assert.assertEquals(10.0, tile.getMinElevation(), 1.0e-10); + Assert.assertEquals(20.0, tile.getMaxElevation(), 1.0e-10); } @Test public void testEviction() throws RuggedException { CountingFactory factory = new CountingFactory(); TilesCache<SimpleTile> cache = new TilesCache<SimpleTile>(factory, - new ConstantElevationUpdater(FastMath.toRadians(1.0), 10, 10.0), 12); + new CheckedPatternElevationUpdater(FastMath.toRadians(1.0), 10, 10.0, 20.0), 12); // fill up the 12 tiles we can keep in cache for (int i = 0; i < 4; ++i) { @@ -90,7 +92,7 @@ public class TilesCacheTest { CountingFactory factory = new CountingFactory(); TilesCache<SimpleTile> cache = new TilesCache<SimpleTile>(factory, - new ConstantElevationUpdater(0.125, 8, 10.0), + new CheckedPatternElevationUpdater(0.125, 8, 10.0, 20.0), 12); SimpleTile regularTile = cache.getTile(0.2, 0.6); @@ -99,6 +101,8 @@ public class TilesCacheTest { Assert.assertEquals(0.5, regularTile.getMinimumLongitude(), 1.0e-10); Assert.assertEquals(0.015625, regularTile.getLatitudeStep(), 1.0e-10); Assert.assertEquals(0.015625, regularTile.getLongitudeStep(), 1.0e-10); + Assert.assertEquals(10.0, regularTile.getMinElevation(), 1.0e-10); + Assert.assertEquals(20.0, regularTile.getMaxElevation(), 1.0e-10); SimpleTile tileAtEnd = cache.getTile(0.250, 0.625); Assert.assertEquals(1, factory.getCount()); @@ -106,6 +110,8 @@ public class TilesCacheTest { Assert.assertEquals(0.5, tileAtEnd.getMinimumLongitude(), 1.0e-10); Assert.assertEquals(0.015625, tileAtEnd.getLatitudeStep(), 1.0e-10); Assert.assertEquals(0.015625, tileAtEnd.getLongitudeStep(), 1.0e-10); + Assert.assertEquals(10.0, tileAtEnd.getMinElevation(), 1.0e-10); + Assert.assertEquals(20.0, tileAtEnd.getMaxElevation(), 1.0e-10); } @@ -114,7 +120,7 @@ public class TilesCacheTest { CountingFactory factory = new CountingFactory(); TilesCache<SimpleTile> cache = new TilesCache<SimpleTile>(factory, - new ConstantElevationUpdater(FastMath.toRadians(1.0), 10, 10.0), + new CheckedPatternElevationUpdater(FastMath.toRadians(1.0), 10, 10.0, 20.0), 16); cache.getTile(FastMath.toRadians(1.5), FastMath.toRadians(0.5));