From 2af73b7111427aa4a29ff62c8b3ff7aaf5224c3c Mon Sep 17 00:00:00 2001 From: gprat <guylaine.prat@csgroup.eu> Date: Tue, 29 Nov 2022 11:38:17 +0100 Subject: [PATCH] Checkstyle corrections and typo --- .../org/orekit/rugged/api/RuggedBuilder.java | 36 +- .../intersection/BasicScanAlgorithm.java | 6 +- .../duvenhage/DuvenhageAlgorithm.java | 10 +- .../orekit/rugged/raster/EarthHemisphere.java | 16 + .../org/orekit/rugged/raster/TilesCache.java | 1339 +++++++++-------- .../intersection/AbstractAlgorithmTest.java | 2 +- .../intersection/BasicScanAlgorithmTest.java | 4 +- .../duvenhage/DuvenhageAlgorithmTest.java | 4 +- .../DummySRTMsimpleElevationUpdater.java | 16 + .../orekit/rugged/raster/TilesCacheTest.java | 773 +++------- .../refraction/MultiLayerModelTest.java | 4 +- 11 files changed, 976 insertions(+), 1234 deletions(-) diff --git a/src/main/java/org/orekit/rugged/api/RuggedBuilder.java b/src/main/java/org/orekit/rugged/api/RuggedBuilder.java index bafa7eb9..a7814774 100644 --- a/src/main/java/org/orekit/rugged/api/RuggedBuilder.java +++ b/src/main/java/org/orekit/rugged/api/RuggedBuilder.java @@ -95,10 +95,10 @@ public class RuggedBuilder { /** Updater used to load Digital Elevation Model tiles. */ private TileUpdater tileUpdater; - - /** Flag to tell if the Digital Elevation Model tiles are overlapping. + + /** Flag to tell if the Digital Elevation Model tiles are overlapping. * @since X.x */ - private boolean isOvelappingTiles = true; + private boolean isOverlappingTiles = true; /** Constant elevation over ellipsoid (m). * used only with {@link AlgorithmId#CONSTANT_ELEVATION_OVER_ELLIPSOID. */ @@ -306,20 +306,20 @@ public class RuggedBuilder { * </p> * @param newTileUpdater updater used to load Digital Elevation Model tiles * @param newMaxCachedTiles maximum number of tiles stored in the cache - * @param newIsOverlappingTiles flag to tell if the DEM tiles are overlapping: + * @param newIsOverlappingTiles flag to tell if the DEM tiles are overlapping: * true if overlapping; false otherwise. * @return the builder instance * @see #setAlgorithm(AlgorithmId) * @see #getTileUpdater() * @see #getMaxCachedTiles() - * @see #isOvelappingTiles() + * @see #isOverlappingTiles() * @since X.x */ - public RuggedBuilder setDigitalElevationModel(final TileUpdater newTileUpdater, final int newMaxCachedTiles, + public RuggedBuilder setDigitalElevationModel(final TileUpdater newTileUpdater, final int newMaxCachedTiles, final boolean newIsOverlappingTiles) { this.tileUpdater = newTileUpdater; this.maxCachedTiles = newMaxCachedTiles; - this.isOvelappingTiles = newIsOverlappingTiles; + this.isOverlappingTiles = newIsOverlappingTiles; return this; } @@ -331,25 +331,25 @@ public class RuggedBuilder { public TileUpdater getTileUpdater() { return tileUpdater; } - + /** - * Get the flag telling if the DEM tiles are overlapping. - * @return true if the Digital Elevation Model tiles are overlapping; + * Get the flag telling if the DEM tiles are overlapping. + * @return true if the Digital Elevation Model tiles are overlapping; * false otherwise. Default = true. * @since X.x */ - public boolean isOvelappingTiles() { - return isOvelappingTiles; + public boolean isOverlappingTiles() { + return isOverlappingTiles; } /** - * Set the DEM overlapping tiles flag - * @param isOvelappingTiles flag to tell if the Digital Elevation Model tiles are overlapping: + * Set the DEM overlapping tiles flag. + * @param newIsOverlappingTiles flag to tell if the Digital Elevation Model tiles are overlapping: * true if overlapping; false otherwise * @since X.x */ - public void setOvelappingTiles(boolean isOvelappingTiles) { - this.isOvelappingTiles = isOvelappingTiles; + public void setOverlappingTiles(final boolean newIsOverlappingTiles) { + this.isOverlappingTiles = newIsOverlappingTiles; } /** Set the user-provided constant elevation model. @@ -993,6 +993,8 @@ public class RuggedBuilder { * @param updater updater used to load Digital Elevation Model tiles * @param maxCachedTiles maximum number of tiles stored in the cache * @param constantElevation constant elevation over ellipsoid + * @param isOverlappingTiles flag to tell if the DEM tiles are overlapping: + * true if overlapping; false otherwise. * @return selected algorithm */ private static IntersectionAlgorithm createAlgorithm(final AlgorithmId algorithmID, @@ -1034,7 +1036,7 @@ public class RuggedBuilder { } } createInterpolatorIfNeeded(); - return new Rugged(createAlgorithm(algorithmID, tileUpdater, maxCachedTiles, constantElevation, isOvelappingTiles), ellipsoid, + return new Rugged(createAlgorithm(algorithmID, tileUpdater, maxCachedTiles, constantElevation, isOverlappingTiles), ellipsoid, lightTimeCorrection, aberrationOfLightCorrection, atmosphericRefraction, scToBody, sensors, name); } } diff --git a/src/main/java/org/orekit/rugged/intersection/BasicScanAlgorithm.java b/src/main/java/org/orekit/rugged/intersection/BasicScanAlgorithm.java index eb445f8b..c338bd94 100644 --- a/src/main/java/org/orekit/rugged/intersection/BasicScanAlgorithm.java +++ b/src/main/java/org/orekit/rugged/intersection/BasicScanAlgorithm.java @@ -59,11 +59,11 @@ public class BasicScanAlgorithm implements IntersectionAlgorithm { /** Simple constructor. * @param updater updater used to load Digital Elevation Model tiles * @param maxCachedTiles maximum number of tiles stored in the cache - * @param isOvelappingTiles flag to tell if the DEM tiles are overlapping: + * @param isOverlappingTiles flag to tell if the DEM tiles are overlapping: * true if overlapping; false otherwise. */ - public BasicScanAlgorithm(final TileUpdater updater, final int maxCachedTiles, final boolean isOvelappingTiles) { - this.cache = new TilesCache<>(new SimpleTileFactory(), updater, maxCachedTiles, isOvelappingTiles); + public BasicScanAlgorithm(final TileUpdater updater, final int maxCachedTiles, final boolean isOverlappingTiles) { + this.cache = new TilesCache<>(new SimpleTileFactory(), updater, maxCachedTiles, isOverlappingTiles); this.hMin = Double.POSITIVE_INFINITY; this.hMax = Double.NEGATIVE_INFINITY; this.algorithmId = AlgorithmId.BASIC_SLOW_EXHAUSTIVE_SCAN_FOR_TESTS_ONLY; diff --git a/src/main/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithm.java b/src/main/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithm.java index bcd68532..27af7eda 100644 --- a/src/main/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithm.java +++ b/src/main/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithm.java @@ -71,13 +71,13 @@ public class DuvenhageAlgorithm implements IntersectionAlgorithm { * is therefore <em>not</em> corrected in this case. As this computation is not * costly (a few percents overhead), it is highly recommended to set this parameter * to {@code false}. This flag is mainly intended for comparison purposes with other systems - * @param isOvelappingTiles flag to tell if the DEM tiles are overlapping: - * true if overlapping; false otherwise. + * @param isOverlappingTiles flag to tell if the DEM tiles are overlapping: + * true if overlapping; false otherwise. */ public DuvenhageAlgorithm(final TileUpdater updater, final int maxCachedTiles, - final boolean flatBody, final boolean isOvelappingTiles) { - this.cache = new TilesCache<MinMaxTreeTile>(new MinMaxTreeTileFactory(), updater, - maxCachedTiles, isOvelappingTiles); + final boolean flatBody, final boolean isOverlappingTiles) { + this.cache = new TilesCache<MinMaxTreeTile>(new MinMaxTreeTileFactory(), updater, + maxCachedTiles, isOverlappingTiles); this.flatBody = flatBody; this.algorithmId = flatBody ? AlgorithmId.DUVENHAGE_FLAT_BODY : AlgorithmId.DUVENHAGE; } diff --git a/src/main/java/org/orekit/rugged/raster/EarthHemisphere.java b/src/main/java/org/orekit/rugged/raster/EarthHemisphere.java index c670938f..10906296 100644 --- a/src/main/java/org/orekit/rugged/raster/EarthHemisphere.java +++ b/src/main/java/org/orekit/rugged/raster/EarthHemisphere.java @@ -1,3 +1,19 @@ +/* Copyright 2013-2022 CS GROUP + * Licensed to CS GROUP (CS) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * CS licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.orekit.rugged.raster; /** diff --git a/src/main/java/org/orekit/rugged/raster/TilesCache.java b/src/main/java/org/orekit/rugged/raster/TilesCache.java index b2a21438..8a654f96 100644 --- a/src/main/java/org/orekit/rugged/raster/TilesCache.java +++ b/src/main/java/org/orekit/rugged/raster/TilesCache.java @@ -36,15 +36,18 @@ import org.orekit.rugged.errors.RuggedMessages; */ public class TilesCache<T extends Tile> { + /** Epsilon to test step equality in latitude and longitude. */ + private static double STEP_EQUALITY = 5 * Precision.EPSILON; + /** Factory for empty tiles. */ private final TileFactory<T> factory; /** Updater for retrieving tiles data. */ private final TileUpdater updater; - - /**Flag to tell if the Digital Elevation Model tiles are overlapping. + + /**Flag to tell if the Digital Elevation Model tiles are overlapping. * @since X.x */ - private final boolean isOvelapping; + private final boolean isOverlapping; /** Cache. */ private final T[] tiles; @@ -53,14 +56,14 @@ public class TilesCache<T extends Tile> { * @param factory factory for creating empty tiles * @param updater updater for retrieving tiles data * @param maxTiles maximum number of tiles stored simultaneously in the cache - * @param isOvelappingTiles flag to tell if the DEM tiles are overlapping: - * true if overlapping; false otherwise. + * @param isOverlappingTiles flag to tell if the DEM tiles are overlapping: + * true if overlapping; false otherwise. */ - public TilesCache(final TileFactory<T> factory, final TileUpdater updater, + public TilesCache(final TileFactory<T> factory, final TileUpdater updater, final int maxTiles, final boolean isOverlappingTiles) { this.factory = factory; this.updater = updater; - this.isOvelapping = isOverlappingTiles; + this.isOverlapping = isOverlappingTiles; @SuppressWarnings("unchecked") final T[] array = (T[]) Array.newInstance(Tile.class, maxTiles); this.tiles = array; @@ -103,49 +106,49 @@ public class TilesCache<T extends Tile> { // At this stage the found tile must be checked (HAS_INTERPOLATION_NEIGHBORS ?) // taking into account if the DEM tiles are overlapping or not - if ( !isOvelapping ) { // DEM with seamless tiles (no overlapping) - + if ( !isOverlapping ) { // DEM with seamless tiles (no overlapping) + // Check if the tile HAS INTERPOLATION NEIGHBORS (the point (latitude, longitude) is inside the tile), - // otherwise the point (latitude, longitude) is on the edge of the tile: + // otherwise the point (latitude, longitude) is on the edge of the tile: // one must create a zipper tile because tiles are not overlapping ... final Tile.Location pointLocation = tile.getLocation(latitude, longitude); - // We are on the edge of the tile + // We are on the edge of the tile if (pointLocation != Tile.Location.HAS_INTERPOLATION_NEIGHBORS) { // Create a "zipper tile" return createZipperTile(tile, latitude, longitude, pointLocation); } else { // we are NOT on the edge of the tile - + tiles[0] = tile; return tile; - - } // end if (location != Tile.Location.HAS_INTERPOLATION_NEIGHBORS) - } else { // isOvelapping: DEM with overlapping tiles (according to the flag ...) - + } // end if (location != Tile.Location.HAS_INTERPOLATION_NEIGHBORS) + + } else { // isOverlapping: DEM with overlapping tiles (according to the flag ...) + // Check if the tile HAS INTERPOLATION NEIGHBORS (the (latitude, longitude) is inside the tile) if (tile.getLocation(latitude, longitude) != Tile.Location.HAS_INTERPOLATION_NEIGHBORS) { // this should happen only if user set up an inconsistent TileUpdater throw new RuggedException(RuggedMessages.TILE_WITHOUT_REQUIRED_NEIGHBORS_SELECTED, FastMath.toDegrees(latitude), FastMath.toDegrees(longitude)); } - + tiles[0] = tile; return tile; - - } // end if (!isOvelapping) + + } // end if (!isOverlapping) } - /** Create a tile defines by its latitude and longitude + /** Create a tile defines by its latitude and longitude. * @param latitude latitude of the desired tile (rad) * @param longitude longitude of the desired tile (rad) * @return the tile * @since X.x */ private T createTile(final double latitude, final double longitude) { - + // Create the tile according to the current (latitude, longitude) and retrieve its data final T tile = factory.createTile(); @@ -164,7 +167,7 @@ public class TilesCache<T extends Tile> { return tile; } - /** Create a zipper tile for DEM with seamless tiles (no overlapping) + /** Create a zipper tile for DEM with seamless tiles (no overlapping). * @param currentTile current tile * @param latitude ground point latitude (rad) * @param longitude ground point longitude (rad) @@ -172,115 +175,115 @@ public class TilesCache<T extends Tile> { * @return zipper tile covering the ground point * @since X.x */ - private T createZipperTile(final T currentTile, - final double latitude, final double longitude, + private T createZipperTile(final T currentTile, + final double latitude, final double longitude, final Tile.Location pointLocation) { T zipperTile = null; - - // One must create a zipper tile between this tile and the neighbor tile + + // One must create a zipper tile between this tile and the neighbor tile // according to the ground point location switch (pointLocation) { - case NORTH: // pointLocation such as latitudeIndex > latitudeRows - 2 + case NORTH: // pointLocation such as latitudeIndex > latitudeRows - 2 - zipperTile = createZipperNorthOrSouth(EarthHemisphere.NORTH, longitude, currentTile); - break; - - case SOUTH: // pointLocation such as latitudeIndex < 0 + zipperTile = createZipperNorthOrSouth(EarthHemisphere.NORTH, longitude, currentTile); + break; - zipperTile = createZipperNorthOrSouth(EarthHemisphere.SOUTH, longitude, currentTile); - break; + case SOUTH: // pointLocation such as latitudeIndex < 0 - case WEST: // pointLocation such as longitudeIndex < 0 + zipperTile = createZipperNorthOrSouth(EarthHemisphere.SOUTH, longitude, currentTile); + break; - zipperTile = createZipperWestOrEast(EarthHemisphere.WEST, latitude, currentTile); - break; - - case EAST: // pointLocation such as longitudeIndex > longitudeColumns - 2 + case WEST: // pointLocation such as longitudeIndex < 0 - zipperTile = createZipperWestOrEast(EarthHemisphere.EAST, latitude, currentTile); - break; - - // One must create a corner zipper tile between this tile and the 3 surrounding tiles - // according to the ground point location - case NORTH_WEST: - - zipperTile = createCornerZipper(EarthHemisphere.NORTH, EarthHemisphere.WEST, latitude, longitude, currentTile); - break; - - case NORTH_EAST: - - zipperTile = createCornerZipper(EarthHemisphere.NORTH, EarthHemisphere.EAST, latitude, longitude, currentTile); - break; - - case SOUTH_WEST: - - zipperTile = createCornerZipper(EarthHemisphere.SOUTH, EarthHemisphere.WEST, latitude, longitude, currentTile); - break; - - case SOUTH_EAST: - - zipperTile = createCornerZipper(EarthHemisphere.SOUTH, EarthHemisphere.EAST, latitude, longitude, currentTile); - break; - - default: - // impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + zipperTile = createZipperWestOrEast(EarthHemisphere.WEST, latitude, currentTile); + break; + + case EAST: // pointLocation such as longitudeIndex > longitudeColumns - 2 + + zipperTile = createZipperWestOrEast(EarthHemisphere.EAST, latitude, currentTile); + break; + + // One must create a corner zipper tile between this tile and the 3 surrounding tiles + // according to the ground point location + case NORTH_WEST: + + zipperTile = createCornerZipper(EarthHemisphere.NORTH, EarthHemisphere.WEST, latitude, longitude, currentTile); + break; + + case NORTH_EAST: + + zipperTile = createCornerZipper(EarthHemisphere.NORTH, EarthHemisphere.EAST, latitude, longitude, currentTile); + break; + + case SOUTH_WEST: + + zipperTile = createCornerZipper(EarthHemisphere.SOUTH, EarthHemisphere.WEST, latitude, longitude, currentTile); + break; + + case SOUTH_EAST: + + zipperTile = createCornerZipper(EarthHemisphere.SOUTH, EarthHemisphere.EAST, latitude, longitude, currentTile); + break; + + default: + // impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); } // end switch - + // again make some room in the cache, possibly evicting the 2nd least recently used one for (int i = tiles.length - 1; i > 0; --i) { tiles[i] = tiles[i - 1]; } - + tiles[1] = currentTile; tiles[0] = zipperTile; - + return (T) zipperTile; } - /** Initialize the zipper tile for a given geometry and the full set of elevations - * @param zipperLatitudeMin - * @param zipperLongitudeMin - * @param zipperLatitudeStep - * @param zipperLongitudeStep - * @param zipperLatitudeRows - * @param zipperLongitudeColumns - * @param zipperElevations + /** Initialize the zipper tile for a given geometry and the full set of elevations. + * @param zipperLatMin zipper min latitude (ra) + * @param zipperLonMin zipper min longitude (rad) + * @param zipperLatStep zipper latitude step (rad) + * @param zipperLonStep zipper longitude step (rad) + * @param zipperLatRows zipper latitude rows + * @param zipperLonCols zipper longitude columns + * @param zipperElevations zipper elevations * @return the zipper tile * @since X.x */ - private T initializeZipperTile(final double zipperLatitudeMin, final double zipperLongitudeMin, - final double zipperLatitudeStep, final double zipperLongitudeStep, - final int zipperLatitudeRows, final int zipperLongitudeColumns, + private T initializeZipperTile(final double zipperLatMin, final double zipperLonMin, + final double zipperLatStep, final double zipperLonStep, + final int zipperLatRows, final int zipperLonCols, final double[][] zipperElevations) { - + // Create an empty tile final T zipperTile = factory.createTile(); // Set the tile geometry - zipperTile.setGeometry(zipperLatitudeMin, zipperLongitudeMin, zipperLatitudeStep, zipperLongitudeStep, - zipperLatitudeRows, zipperLongitudeColumns); - + zipperTile.setGeometry(zipperLatMin, zipperLonMin, zipperLatStep, zipperLonStep, + zipperLatRows, zipperLonCols); + // Fill in the tile with the relevant elevations - for (int iLat = 0; iLat < zipperLatitudeRows; iLat++) { - for (int jLon = 0; jLon < zipperLongitudeColumns; jLon++) { + for (int iLat = 0; iLat < zipperLatRows; iLat++) { + for (int jLon = 0; jLon < zipperLonCols; jLon++) { zipperTile.setElevation(iLat, jLon, zipperElevations[iLat][jLon]); } } - + // Last step in order to create the MinMax kd tree zipperTile.tileUpdateCompleted(); return zipperTile; } - /** Create the zipper tile between the current tile and the Northern or Southern tile of the current tile - * for a given longitude. The Northern or Southern tiles of the current tile may have a change in + /** Create the zipper tile between the current tile and the Northern or Southern tile of the current tile. + * for a given longitude. The Northern or Southern tiles of the current tile may have a change in * resolution either in longitude or in latitude wrt the current tile. - * The zipper has 4 rows in latitude. + * The zipper has 4 rows in latitude. * @param latitudeHemisphere hemisphere for latitude: NORTH / SOUTH * @param longitude given longitude (rad) * @param currentTile current tile @@ -288,16 +291,16 @@ public class TilesCache<T extends Tile> { * @since X.x */ private T createZipperNorthOrSouth(final EarthHemisphere latitudeHemisphere, final double longitude, final T currentTile) { - + final int currentTileLatRows = currentTile.getLatitudeRows(); final int currentTileLonCols = currentTile.getLongitudeColumns(); final double currentTileLatStep = currentTile.getLatitudeStep(); final double currentTileLonStep = currentTile.getLongitudeStep(); final double currentTileMinLat = currentTile.getMinimumLatitude(); final double currentTileMinLon = currentTile.getMinimumLongitude(); - + // Get the Northern or Southern tile - final T tileNorthOrSouth = createNorthOrSouthTile(latitudeHemisphere, longitude, currentTileMinLat, currentTileLatRows, currentTileLatStep); + final T tileNorthOrSouth = createNorthOrSouthTile(latitudeHemisphere, longitude, currentTileMinLat, currentTileLatStep, currentTileLatRows); // If NORTH hemisphere: // Create zipper tile between the current tile and the Northern tile; @@ -310,14 +313,14 @@ public class TilesCache<T extends Tile> { // 2 rows belong to the North part of the Southern tile // Initialize the zipper latitude step and number of rows (4) - int zipperLatRows = 4; + final int zipperLatRows = 4; double zipperLatStep = currentTileLatStep; - + // Check if latitude steps are the same between the current tile and the Northern or Southern tile boolean isSameStepLat = true; - double northSouthLatitudeStep = tileNorthOrSouth.getLatitudeStep(); - - if (! (Math.abs(currentTileLatStep - northSouthLatitudeStep) < 5.*Precision.EPSILON)) { + final double northSouthLatitudeStep = tileNorthOrSouth.getLatitudeStep(); + + if (!(Math.abs(currentTileLatStep - northSouthLatitudeStep) < STEP_EQUALITY)) { // Steps are not the same isSameStepLat = false; // Recompute zipper latitude step if the North or South tile latitude step is smaller @@ -325,75 +328,74 @@ public class TilesCache<T extends Tile> { zipperLatStep = northSouthLatitudeStep; } } - + // Initialize the zipper longitude step and number of columns with current tile step and columns double zipperLonStep = currentTileLonStep; int zipperLonCols = currentTileLonCols; - + // Check if longitude steps are the same boolean isSameStepLon = true; - double northSouthLongitudeStep = tileNorthOrSouth.getLongitudeStep(); - - if (! (Math.abs(currentTileLonStep - northSouthLongitudeStep) < 5.*Precision.EPSILON)) { + final double northSouthLongitudeStep = tileNorthOrSouth.getLongitudeStep(); + + if (!(Math.abs(currentTileLonStep - northSouthLongitudeStep) < STEP_EQUALITY)) { // Steps are not the same isSameStepLon = false; // Recompute zipper longitude step and columns if the North or South tile longitude step is smaller - if (northSouthLongitudeStep < currentTileLonStep) { - zipperLonStep = northSouthLongitudeStep; - zipperLonCols = tileNorthOrSouth.getLongitudeColumns(); - } + if (northSouthLongitudeStep < currentTileLonStep) { + zipperLonStep = northSouthLongitudeStep; + zipperLonCols = tileNorthOrSouth.getLongitudeColumns(); + } } - double zipperLatMin; - double zipperLonMin; - double[][] elevations; - + final double zipperLatMin; + final double zipperLonMin; + final double[][] elevations; + switch (latitudeHemisphere) { - case NORTH: - // Defines the zipper min latitude wrt the current tile max latitude minus 2 zipper step in latitude - // Explanation: we want the 2 first rows belongs to the current tile and 2 last rows to the Northern tile - // If zipperLatStep = latStep, the 2 first rows = exactly lines of the current tile - // otherwise (latStep > North tile step), the 2 first rows will be smaller (in latitude) than the 2 lines of the current tile - zipperLatMin = currentTileMinLat + currentTileLatRows * currentTileLatStep - 2*zipperLatStep; - - // Define the zipper min longitude = current tile min longitude - zipperLonMin = currentTileMinLon; - - // Fill in the zipper elevations - elevations = getZipperNorthSouthElevations(zipperLonCols, tileNorthOrSouth, currentTile, - isSameStepLat, isSameStepLon, - zipperLatMin, zipperLatStep, zipperLonMin, zipperLonStep); - break; - - case SOUTH: - // Defines the zipper min latitude wrt the current tile min latitude - // Explanation: we want the 2 last rows belongs to the current tile and 2 first rows to the Southern tile - // If zipperLatStep = latStep, the 2 last rows = exactly lines of the current tile - // otherwise (latStep > South tile step), the 2 last rows will be smaller (in latitude) than the 2 lines of the current tile - zipperLatMin = currentTileMinLat - 2*zipperLatStep; - - // Define the zipper min longitude = current tile min longitude - zipperLonMin = currentTileMinLon; - - // Fill in the zipper elevations - elevations= getZipperNorthSouthElevations(zipperLonCols, currentTile, tileNorthOrSouth, - isSameStepLat, isSameStepLon, - zipperLatMin, zipperLatStep, zipperLonMin, zipperLonStep); - break; - - default: - // impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + case NORTH: + // Defines the zipper min latitude wrt the current tile max latitude minus 2 zipper step in latitude + // Explanation: we want the 2 first rows belongs to the current tile and 2 last rows to the Northern tile + // If zipperLatStep = latStep, the 2 first rows = exactly lines of the current tile + // otherwise (latStep > North tile step), the 2 first rows will be smaller (in latitude) than the 2 lines of the current tile + zipperLatMin = currentTileMinLat + currentTileLatRows * currentTileLatStep - 2 * zipperLatStep; + + // Define the zipper min longitude = current tile min longitude + zipperLonMin = currentTileMinLon; + + // Fill in the zipper elevations + elevations = getZipperNorthSouthElevations(zipperLonCols, tileNorthOrSouth, currentTile, + isSameStepLat, isSameStepLon, + zipperLatMin, zipperLonMin, zipperLatStep, zipperLonStep); + break; + + case SOUTH: + // Defines the zipper min latitude wrt the current tile min latitude + // Explanation: we want the 2 last rows belongs to the current tile and 2 first rows to the Southern tile + // If zipperLatStep = latStep, the 2 last rows = exactly lines of the current tile + // otherwise (latStep > South tile step), the 2 last rows will be smaller (in latitude) than the 2 lines of the current tile + zipperLatMin = currentTileMinLat - 2 * zipperLatStep; + // Define the zipper min longitude = current tile min longitude + zipperLonMin = currentTileMinLon; + + // Fill in the zipper elevations + elevations = getZipperNorthSouthElevations(zipperLonCols, currentTile, tileNorthOrSouth, + isSameStepLat, isSameStepLon, + zipperLatMin, zipperLonMin, zipperLatStep, zipperLonStep); + break; + + default: + // impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); } - final T zipperNorthOrSouth = initializeZipperTile(zipperLatMin, zipperLonMin, - zipperLatStep, zipperLonStep, + final T zipperNorthOrSouth = initializeZipperTile(zipperLatMin, zipperLonMin, + zipperLatStep, zipperLonStep, zipperLatRows, zipperLonCols, elevations); return zipperNorthOrSouth; } - /** Create the zipper tile between the current tile and the Western or Eastern tile of the current tile - * for a given latitude. The Western or Eastern tiles of the current tile have the same + /** Create the zipper tile between the current tile and the Western or Eastern tile of the current tile. + * for a given latitude. The Western or Eastern tiles of the current tile have the same * resolution in longitude and in latitude as the current tile (for known DEMs). * The zipper has 4 columns in longitude. * @param longitudeHemisphere hemisphere for longitude: WEST / EAST @@ -403,18 +405,18 @@ public class TilesCache<T extends Tile> { * @since X.x */ private T createZipperWestOrEast(final EarthHemisphere longitudeHemisphere, final double latitude, final T currentTile) { - + final int currentTileLatRows = currentTile.getLatitudeRows(); final int currentTileLonCols = currentTile.getLongitudeColumns(); final double currentTileLatStep = currentTile.getLatitudeStep(); final double currentTileLonStep = currentTile.getLongitudeStep(); final double currentTileMinLon = currentTile.getMinimumLongitude(); - + // Get the West or East Tile - final T tileWestOrEast = createEastOrWestTile(longitudeHemisphere, latitude, currentTileMinLon, currentTileLonCols, currentTileLonStep); + final T tileWestOrEast = createEastOrWestTile(longitudeHemisphere, latitude, currentTileMinLon, currentTileLonStep, currentTileLonCols); - if (! (Math.abs(currentTileLatStep - tileWestOrEast.getLatitudeStep()) < 5.*Precision.EPSILON) || - ! (Math.abs(currentTileLonStep - tileWestOrEast.getLongitudeStep()) < 5.*Precision.EPSILON)) { + if (!(Math.abs(currentTileLatStep - tileWestOrEast.getLatitudeStep()) < STEP_EQUALITY) || + !(Math.abs(currentTileLonStep - tileWestOrEast.getLongitudeStep()) < STEP_EQUALITY)) { // Steps are not the same. // Along Western or Eastern edges of the tiles: no change of resolution may occurs in known DEMs. throw new RuggedException(RuggedMessages.INTERNAL_ERROR); @@ -424,68 +426,67 @@ public class TilesCache<T extends Tile> { // Create zipper tile between the current tile and the Western tile; // 2 cols belong to the West part of the current tile // 2 cols belong to the East part of the West tile - + // If EAST hemisphere // Create zipper tile between the current tile and the Eastern tile; // 2 cols belong to the East part of the current tile // 2 cols belong to the West part of the East tile - double zipperLonStep = currentTileLonStep; - int zipperLatRows = currentTileLatRows; - int zipperLonCols = 4; + final double zipperLonStep = currentTileLonStep; + final int zipperLatRows = currentTileLatRows; + final int zipperLonCols = 4; + + final double zipperLonMin; + final double[][] elevations; - double zipperLonMin; - double[][] elevations; - switch (longitudeHemisphere) { - case WEST: - zipperLonMin = currentTileMinLon - 2*currentTileLonStep; - elevations = getZipperEastWestElevations(zipperLatRows, currentTile, tileWestOrEast); - break; - - case EAST: - zipperLonMin = currentTileMinLon + (currentTileLonCols - 2)*currentTileLonStep; - - elevations = getZipperEastWestElevations(zipperLatRows, tileWestOrEast, currentTile); - break; - - default: - // impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + case WEST: + zipperLonMin = currentTileMinLon - 2 * currentTileLonStep; + elevations = getZipperEastWestElevations(zipperLatRows, currentTile, tileWestOrEast); + break; + + case EAST: + zipperLonMin = currentTileMinLon + (currentTileLonCols - 2) * currentTileLonStep; + elevations = getZipperEastWestElevations(zipperLatRows, tileWestOrEast, currentTile); + break; + + default: + // impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); } - final T zipperWestOrEast = initializeZipperTile(currentTile.getMinimumLatitude(), zipperLonMin, - currentTileLatStep, zipperLonStep, + final T zipperWestOrEast = initializeZipperTile(currentTile.getMinimumLatitude(), zipperLonMin, + currentTileLatStep, zipperLonStep, zipperLatRows, zipperLonCols, elevations); return zipperWestOrEast; } - + /** Get the latitude index of a point. * @param latitude geodetic latitude (rad) - * @param minLatitude min latitude of the tile (rad) + * @param latitudeMin min latitude of the tile (rad) * @param latitudeStep latitude step of the tile (rad) * @param latitudeRows number of rows in latitude * @return latitude index (it may lie outside of the tile!) * @since X.x */ - private int computeLatitudeIndex(final double latitude, final double minLatitude, final double latitudeStep, final int latitudeRows) { - double doubleLatitudeIndex = (latitude - minLatitude) / latitudeStep; + private int computeLatitudeIndex(final double latitude, final double latitudeMin, final double latitudeStep, final int latitudeRows) { + final double doubleLatitudeIndex = (latitude - latitudeMin) / latitudeStep; return FastMath.max(0, FastMath.min(latitudeRows - 1, (int) FastMath.floor(doubleLatitudeIndex))); } - + /** Get the longitude index of a point. * @param longitude geodetic longitude (rad) - * @param minLongitude min longitude of the tile (rad) + * @param longitudeMin min longitude of the tile (rad) * @param longitudeStep longitude step of the tile (rad) * @param longitudeColumns number of columns in longitude * @return longitude index (it may lie outside of the tile!) * @since X.x */ - private int computeLongitudeIndex(final double longitude, final double minLongitude, final double longitudeStep, final int longitudeColumns) { - double doubleLongitudeIndex = (longitude - minLongitude) / longitudeStep; + private int computeLongitudeIndex(final double longitude, final double longitudeMin, final double longitudeStep, final int longitudeColumns) { + final double doubleLongitudeIndex = (longitude - longitudeMin) / longitudeStep; return FastMath.max(0, FastMath.min(longitudeColumns - 1, (int) FastMath.floor(doubleLongitudeIndex))); } - + /** Get the elevations for the zipper tile between a northern and a southern tiles with 4 rows in latitude. * @param zipperLonCols number of column in longitude * @param northernTile the tile which is the northern @@ -493,106 +494,106 @@ public class TilesCache<T extends Tile> { * @param isSameStepLat flag to tell is latitude steps are the same (= true) * @param isSameStepLon flag to tell is longitude steps are the same (= true) * @param zipperLatMin zipper tile min latitude (rad) - * @param zipperLatStep zipper tile latitude step (rad) * @param zipperLonMin zipper tile min longitude (rad) + * @param zipperLatStep zipper tile latitude step (rad) * @param zipperLonStep zipper tile longitude step (rad) * @return the elevations to fill in the zipper tile between a northern and a southern tiles * @since X.x */ - private double[][] getZipperNorthSouthElevations(final int zipperLonCols, + private double[][] getZipperNorthSouthElevations(final int zipperLonCols, final T northernTile, final T southernTile, final boolean isSameStepLat, final boolean isSameStepLon, - final double zipperLatMin, final double zipperLatStep, - final double zipperLonMin, final double zipperLonStep) { - - double[][] elevations = new double[4][zipperLonCols]; - - if (isSameStepLat && isSameStepLon) { // tiles with same steps in latitude and longitude - - for (int jLon = 0; jLon < zipperLonCols; jLon++) { - // Part from the northern tile - int lat3 = 1; - elevations[3][jLon] = northernTile.getElevationAtIndices(lat3, jLon); - int lat2 = 0; - elevations[2][jLon] = northernTile.getElevationAtIndices(lat2, jLon); - - // Part from the southern tile - int lat1 = southernTile.getLatitudeRows() - 1; - elevations[1][jLon] = southernTile.getElevationAtIndices(lat1, jLon); - int lat0 = southernTile.getLatitudeRows() - 2; - elevations[0][jLon] = southernTile.getElevationAtIndices(lat0, jLon); - } - - } else { // tiles with different steps - - // To cover every cases and as zipper with such characteristics are rare, - // we will use conversion from (latitude, longitude) to tile indices - - // We assure to be inside a cell by adding a delta step (to avoid inappropriate index computation) - // TBN: zipperLatStep/zipperLonStep are the smallest steps vs Northern and Southern tiles - double deltaLon = 0.1*zipperLonStep; - double zipperLonCurrent = zipperLonMin + deltaLon; - - // Assure that the longitude belongs to [-180, + 180] - double zipperLonMax = MathUtils.normalizeAngle(zipperLonMin + (zipperLonCols - 1) * zipperLonStep, 0.0); - - // Northern Tile - double northernMinLat = northernTile.getMinimumLatitude(); - double northernLatStep = northernTile.getLatitudeStep(); - int northernLatRows = northernTile.getLatitudeRows(); - double northernMinLon = northernTile.getMinimumLongitude(); - double northernLonStep = northernTile.getLongitudeStep(); - int northernLonCols = northernTile.getLongitudeColumns(); - - // Southern Tile - double southernMinLat = southernTile.getMinimumLatitude(); - double southernLatStep = southernTile.getLatitudeStep(); - int southernLatRows = southernTile.getLatitudeRows(); - double southernMinLon = southernTile.getMinimumLongitude(); - double southernLonStep = southernTile.getLongitudeStep(); - int southernLonCols = southernTile.getLongitudeColumns(); - - while (zipperLonCurrent <= zipperLonMax + 2*deltaLon) { - - // Compute zipper tile longitude index - int zipperLonIndex = computeLongitudeIndex(zipperLonCurrent, zipperLonMin, zipperLonStep, zipperLonCols); - - // Part from the northern tile - // --------------------------- - // Compute northern longitude - int northenLongitudeIndex = computeLongitudeIndex(zipperLonCurrent, northernMinLon, northernLonStep, northernLonCols); - - double zipperLat3 = zipperLatMin + (3 + 0.1)*zipperLatStep; - // lat3 would be 1 if Northern latitude step smallest; could be 0 if biggest - int lat3Index = computeLatitudeIndex(zipperLat3, northernMinLat, northernLatStep, northernLatRows); - elevations[3][zipperLonIndex] = northernTile.getElevationAtIndices(lat3Index, northenLongitudeIndex); - - // lat2 is 0 whatever Northern latitude step - int lat2Index = 0; - elevations[2][zipperLonIndex] = northernTile.getElevationAtIndices(lat2Index, northenLongitudeIndex); - - // Part from the southern tile - // --------------------------- - // Compute southern longitude - int southernLongitudeIndex = computeLongitudeIndex(zipperLonCurrent, southernMinLon, southernLonStep, southernLonCols); - - // lat1 is Southern latitude rows - 1 whatever Southern latitude step - int lat1Index = southernTile.getLatitudeRows() - 1; - elevations[1][zipperLonIndex] = southernTile.getElevationAtIndices(lat1Index, southernLongitudeIndex); - - double zipperLat0 = zipperLatMin + 0.1*zipperLatStep; - // lat1 would be Southern latitude rows - 2 if Southern latitude step smallest; could be Southern latitude rows - 1 if biggest - int lat0Index = computeLatitudeIndex(zipperLat0, southernMinLat, southernLatStep, southernLatRows); - elevations[0][zipperLonIndex] = southernTile.getElevationAtIndices(lat0Index, southernLongitudeIndex); - - // Next longitude - // -------------- - zipperLonCurrent += zipperLonStep; - - } // end loop on zipperLonCurrent - } - return elevations; - } + final double zipperLatMin, final double zipperLonMin, + final double zipperLatStep, final double zipperLonStep) { + + final double[][] elevations = new double[4][zipperLonCols]; + + if (isSameStepLat && isSameStepLon) { // tiles with same steps in latitude and longitude + + for (int jLon = 0; jLon < zipperLonCols; jLon++) { + // Part from the northern tile + final int lat3 = 1; + elevations[3][jLon] = northernTile.getElevationAtIndices(lat3, jLon); + final int lat2 = 0; + elevations[2][jLon] = northernTile.getElevationAtIndices(lat2, jLon); + + // Part from the southern tile + final int lat1 = southernTile.getLatitudeRows() - 1; + elevations[1][jLon] = southernTile.getElevationAtIndices(lat1, jLon); + final int lat0 = southernTile.getLatitudeRows() - 2; + elevations[0][jLon] = southernTile.getElevationAtIndices(lat0, jLon); + } + + } else { // tiles with different steps + + // To cover every cases and as zipper with such characteristics are rare, + // we will use conversion from (latitude, longitude) to tile indices + + // We assure to be inside a cell by adding a delta step (to avoid inappropriate index computation) + // TBN: zipperLatStep/zipperLonStep are the smallest steps vs Northern and Southern tiles + final double deltaLon = 0.1 * zipperLonStep; + double zipperLonCurrent = zipperLonMin + deltaLon; + + // Assure that the longitude belongs to [-180, + 180] + final double zipperLonMax = MathUtils.normalizeAngle(zipperLonMin + (zipperLonCols - 1) * zipperLonStep, 0.0); + + // Northern Tile + final double northernMinLat = northernTile.getMinimumLatitude(); + final double northernLatStep = northernTile.getLatitudeStep(); + final int northernLatRows = northernTile.getLatitudeRows(); + final double northernMinLon = northernTile.getMinimumLongitude(); + final double northernLonStep = northernTile.getLongitudeStep(); + final int northernLonCols = northernTile.getLongitudeColumns(); + + // Southern Tile + final double southernMinLat = southernTile.getMinimumLatitude(); + final double southernLatStep = southernTile.getLatitudeStep(); + final int southernLatRows = southernTile.getLatitudeRows(); + final double southernMinLon = southernTile.getMinimumLongitude(); + final double southernLonStep = southernTile.getLongitudeStep(); + final int southernLonCols = southernTile.getLongitudeColumns(); + + while (zipperLonCurrent <= zipperLonMax + 2 * deltaLon) { + + // Compute zipper tile longitude index + final int zipperLonIndex = computeLongitudeIndex(zipperLonCurrent, zipperLonMin, zipperLonStep, zipperLonCols); + + // Part from the northern tile + // --------------------------- + // Compute northern longitude + final int northenLongitudeIndex = computeLongitudeIndex(zipperLonCurrent, northernMinLon, northernLonStep, northernLonCols); + + final double zipperLat3 = zipperLatMin + (3 + 0.1) * zipperLatStep; + // lat3 would be 1 if Northern latitude step smallest; could be 0 if biggest + final int lat3Index = computeLatitudeIndex(zipperLat3, northernMinLat, northernLatStep, northernLatRows); + elevations[3][zipperLonIndex] = northernTile.getElevationAtIndices(lat3Index, northenLongitudeIndex); + + // lat2 is 0 whatever Northern latitude step + final int lat2Index = 0; + elevations[2][zipperLonIndex] = northernTile.getElevationAtIndices(lat2Index, northenLongitudeIndex); + + // Part from the southern tile + // --------------------------- + // Compute southern longitude + final int southernLongitudeIndex = computeLongitudeIndex(zipperLonCurrent, southernMinLon, southernLonStep, southernLonCols); + + // lat1 is Southern latitude rows - 1 whatever Southern latitude step + final int lat1Index = southernTile.getLatitudeRows() - 1; + elevations[1][zipperLonIndex] = southernTile.getElevationAtIndices(lat1Index, southernLongitudeIndex); + + final double zipperLat0 = zipperLatMin + 0.1 * zipperLatStep; + // lat1 would be Southern latitude rows - 2 if Southern latitude step smallest; could be Southern latitude rows - 1 if biggest + final int lat0Index = computeLatitudeIndex(zipperLat0, southernMinLat, southernLatStep, southernLatRows); + elevations[0][zipperLonIndex] = southernTile.getElevationAtIndices(lat0Index, southernLongitudeIndex); + + // Next longitude + // -------------- + zipperLonCurrent += zipperLonStep; + + } // end loop on zipperLonCurrent + } + return elevations; + } /** Get the elevations for the zipper tile between a eastern and a western tiles with 4 columns in longitude. * @param zipperLatRows number of rows in latitude @@ -601,242 +602,260 @@ public class TilesCache<T extends Tile> { * @return the elevations to fill in the zipper tile between a eastern and a western tiles * @since X.x */ - private double[][] getZipperEastWestElevations(final int zipperLatRows, - final T easternTile, final T westernTile) { - - double[][] elevations = new double[zipperLatRows][4]; - - for (int iLat = 0; iLat < zipperLatRows; iLat++) { - // Part from the eastern tile - int lon3 = 1; - elevations[iLat][3] = easternTile.getElevationAtIndices(iLat, lon3); - int lon2 = 0; - elevations[iLat][2] = easternTile.getElevationAtIndices(iLat, lon2); - - // Part from the western tile - int lon1 = westernTile.getLongitudeColumns() - 1; - elevations[iLat][1] = westernTile.getElevationAtIndices(iLat, lon1); - int lon0 = westernTile.getLongitudeColumns() - 2; - elevations[iLat][0] = westernTile.getElevationAtIndices(iLat, lon0); - } - return elevations; - } - - /** Create the corner zipper tile. - * Hypothesis: along Western or Eastern edges of the tiles: no change of resolution may occurs in known DEMs. - * @param latitudeHemisphere latitude hemisphere (North or South) - * @param longitudeHemisphere longitude hemisphere (West or East) - * @param latitude ground point latitude (rad) - * @param longitude ground point longitude (rad) - * @param currentTile current tile - * @return the corner zipper tile - * @since X.x - */ - private T createCornerZipper(final EarthHemisphere latitudeHemisphere, final EarthHemisphere longitudeHemisphere, - final double latitude, final double longitude, final T currentTile) { - - final int currentTileLatRows = currentTile.getLatitudeRows(); - final int currentTileLonCols = currentTile.getLongitudeColumns(); - final double currentTileLatStep = currentTile.getLatitudeStep(); - final double currentTileLonStep = currentTile.getLongitudeStep(); - final double currentTileMinLon = currentTile.getMinimumLongitude(); - final double currentTileMinLat = currentTile.getMinimumLatitude(); - - T belowLeftTile; - T belowRightTile; - T aboveLeftTile; - T aboveRightTile; - - switch (latitudeHemisphere) { - case NORTH: - - switch (longitudeHemisphere) { - case WEST: - - // Get the West Tile - T tileWest = createEastOrWestTile(EarthHemisphere.WEST, latitude, currentTileMinLon, currentTileLonCols, currentTileLonStep); - // Get the North Tile - T tileNorth = createNorthOrSouthTile(EarthHemisphere.NORTH, longitude, currentTileMinLat, currentTileLatRows, currentTileLatStep); - // Get the North-West Tile - T tileNorthWest = createIntercardinalTile(EarthHemisphere.NORTH, currentTileMinLat, currentTileLatRows, currentTileLatStep, - EarthHemisphere.WEST, currentTileMinLon, currentTileLonCols, currentTileLonStep); - belowLeftTile = tileWest; - belowRightTile = currentTile; - aboveLeftTile = tileNorthWest; - aboveRightTile = tileNorth; - - break; - - case EAST: - - // Get the East Tile - T tileEast = createEastOrWestTile(EarthHemisphere.EAST, latitude, currentTileMinLon, currentTileLonCols, currentTileLonStep); - // Get the North Tile - tileNorth = createNorthOrSouthTile(EarthHemisphere.NORTH, longitude, currentTileMinLat, currentTileLatRows, currentTileLatStep); - // Get the North-East Tile - T tileNorthEast = createIntercardinalTile(EarthHemisphere.NORTH, currentTileMinLat, currentTileLatRows, currentTileLatStep, - EarthHemisphere.EAST, currentTileMinLon, currentTileLonCols, currentTileLonStep); - belowLeftTile = currentTile; - belowRightTile = tileEast; - aboveLeftTile = tileNorth; - aboveRightTile = tileNorthEast; - - break; - - default: - // impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); - } // end switch longitudeHemisphere - - break; - - case SOUTH: - - switch (longitudeHemisphere) { - case WEST: - - // Get the West Tile - T tileWest = createEastOrWestTile(EarthHemisphere.WEST, latitude, currentTileMinLon, currentTileLonCols, currentTileLonStep); - // Get the South Tile - T tileSouth = createNorthOrSouthTile(EarthHemisphere.SOUTH, longitude, currentTileMinLat, currentTileLatRows, currentTileLatStep); - // Get the South-West Tile - T tileSouthhWest = createIntercardinalTile(EarthHemisphere.SOUTH, currentTileMinLat, currentTileLatRows, currentTileLatStep, - EarthHemisphere.WEST, currentTileMinLon, currentTileLonCols, currentTileLonStep); - belowLeftTile = tileSouthhWest; - belowRightTile = tileSouth; - aboveLeftTile = tileWest; - aboveRightTile = currentTile; - - break; - - case EAST: - - // Get the East Tile - T tileEast = createEastOrWestTile(EarthHemisphere.EAST, latitude, currentTileMinLon, currentTileLonCols, currentTileLonStep); - // Get the South Tile - tileSouth = createNorthOrSouthTile(EarthHemisphere.SOUTH, longitude, currentTileMinLat, currentTileLatRows, currentTileLatStep); - // Get the South-East Tile - T tileSouthhEast = createIntercardinalTile(EarthHemisphere.SOUTH, currentTileMinLat, currentTileLatRows, currentTileLatStep, - EarthHemisphere.EAST, currentTileMinLon, currentTileLonCols, currentTileLonStep); - belowLeftTile = tileSouth; - belowRightTile = tileSouthhEast; - aboveLeftTile = currentTile; - aboveRightTile = tileEast; - - break; - - default: - // case impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); - } // end switch longitudeHemisphere - - break; - - default: - // case impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); - } // end switch latitudeHemisphere - - - // Check that tiles at same latitude have same steps in longitude and latitude - // Along Western or Eastern edges of the tiles: no change of resolution may occurs in known DEMs. - if (! (Math.abs(belowLeftTile.getLatitudeStep() - belowRightTile.getLatitudeStep()) < 5.*Precision.EPSILON) || - ! (Math.abs(belowLeftTile.getLongitudeStep() - belowRightTile.getLongitudeStep()) < 5.*Precision.EPSILON) || - ! (Math.abs(aboveLeftTile.getLatitudeStep() - aboveRightTile.getLatitudeStep()) < 5.*Precision.EPSILON) || - ! (Math.abs(aboveLeftTile.getLongitudeStep() - aboveRightTile.getLongitudeStep()) < 5.*Precision.EPSILON)) { - // Steps are not the same. - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); - } - - - // Compute the zipper steps in latitude and longitude. - // If steps are different, the zipper will have the smallest steps. - - // at this stage the latitude steps of the right and left tiles are the same - double belowLatitudeStep = belowRightTile.getLatitudeStep(); - double aboveLatitudeStep = aboveRightTile.getLatitudeStep(); - - // initialize the zipper latitude step - double zipperLatStep = belowLatitudeStep; - - // check if latitude steps are the same between the above and below tiles - boolean isSameStepLat = true; - - if (! (Math.abs(belowLatitudeStep - aboveLatitudeStep) < 5.*Precision.EPSILON)) { - - // Latitude steps are not the same - isSameStepLat = false; - - // Recompute zipper latitude step if the above tiles latitude step is smaller - if (aboveLatitudeStep < belowLatitudeStep) { - zipperLatStep = aboveLatitudeStep; - } - } - - // at this stage the longitude steps of the right and left tiles are the same - double belowLongitudeStep = belowRightTile.getLongitudeStep(); - double aboveLongitudeStep = aboveRightTile.getLongitudeStep(); - - // initialize the zipper longitude step - double zipperLonStep = belowLongitudeStep; - - // check if longitude steps are the same between the above and below tiles - boolean isSameStepLon = true; - - if (! (Math.abs(belowLongitudeStep - aboveLongitudeStep) < 5.*Precision.EPSILON)) { - - // Longitude steps are not the same - isSameStepLon = false; - - // Recompute zipper longitude step if the above tiles longitude step is smaller - if (aboveLongitudeStep < belowLongitudeStep) { - zipperLonStep = aboveLongitudeStep; - } - } - - // Define the zipper min latitude and min longitude. - // Explanation: - // We want the zipper 2 first rows belongs to the below tiles and the zipper 2 last rows to the above tiles. - // We want the zipper 2 first columns belongs to the left tiles and the zipper 2 last columns to the right tiles. - // We use the current tile origin AND the zipper steps to compute the zipper origin - GeodeticPoint zipperCorner = computeCornerZipperOrigin(zipperLatStep, zipperLonStep, - latitudeHemisphere, currentTileMinLat, - currentTileLatRows, currentTileLatStep, - longitudeHemisphere, currentTileMinLon, - currentTileLonCols, currentTileLonStep); - - // Initialize corner tile - return initializeCornerZipperTile(zipperCorner.getLatitude(), zipperLatStep, zipperCorner.getLongitude(), zipperLonStep, - belowLeftTile, aboveLeftTile, belowRightTile, aboveRightTile, - isSameStepLat, isSameStepLon); - - } - - /** Initialize a corner zipper tile (with 4 rows in latitude and 4 columns in longitude) - * @param zipperCorner zipper tile point at minimum latitude and minimum longitude - * @param zipperLatStep latitude step (rad) - * @param zipperLonStep longitude step (rad) + private double[][] getZipperEastWestElevations(final int zipperLatRows, + final T easternTile, final T westernTile) { + + final double[][] elevations = new double[zipperLatRows][4]; + + for (int iLat = 0; iLat < zipperLatRows; iLat++) { + // Part from the eastern tile + final int lon3 = 1; + elevations[iLat][3] = easternTile.getElevationAtIndices(iLat, lon3); + final int lon2 = 0; + elevations[iLat][2] = easternTile.getElevationAtIndices(iLat, lon2); + + // Part from the western tile + final int lon1 = westernTile.getLongitudeColumns() - 1; + elevations[iLat][1] = westernTile.getElevationAtIndices(iLat, lon1); + final int lon0 = westernTile.getLongitudeColumns() - 2; + elevations[iLat][0] = westernTile.getElevationAtIndices(iLat, lon0); + } + return elevations; + } + + /** Create the corner zipper tile. + * Hypothesis: along Western or Eastern edges of the tiles: no change of resolution may occurs in known DEMs. + * @param latitudeHemisphere latitude hemisphere (North or South) + * @param longitudeHemisphere longitude hemisphere (West or East) + * @param latitude ground point latitude (rad) + * @param longitude ground point longitude (rad) * @param currentTile current tile + * @return the corner zipper tile + * @since X.x + */ + private T createCornerZipper(final EarthHemisphere latitudeHemisphere, final EarthHemisphere longitudeHemisphere, + final double latitude, final double longitude, final T currentTile) { + + final int currentTileLatRows = currentTile.getLatitudeRows(); + final int currentTileLonCols = currentTile.getLongitudeColumns(); + final double currentTileLatStep = currentTile.getLatitudeStep(); + final double currentTileLonStep = currentTile.getLongitudeStep(); + final double currentTileLonMin = currentTile.getMinimumLongitude(); + final double currentTileLatMin = currentTile.getMinimumLatitude(); + + final T belowLeftTile; + final T belowRightTile; + final T aboveLeftTile; + final T aboveRightTile; + + switch (latitudeHemisphere) { + case NORTH: + + switch (longitudeHemisphere) { + case WEST: + + // Get the West Tile + final T tileWest = createEastOrWestTile(EarthHemisphere.WEST, latitude, + currentTileLonMin, currentTileLonStep, currentTileLonCols); + // Get the North Tile + T tileNorth = createNorthOrSouthTile(EarthHemisphere.NORTH, longitude, + currentTileLatMin, currentTileLatStep, currentTileLatRows); + // Get the North-West Tile + final T tileNorthWest = createIntercardinalTile(EarthHemisphere.NORTH, + currentTileLatMin, currentTileLatStep, currentTileLatRows, + EarthHemisphere.WEST, + currentTileLonMin, currentTileLonStep, currentTileLonCols); + belowLeftTile = tileWest; + belowRightTile = currentTile; + aboveLeftTile = tileNorthWest; + aboveRightTile = tileNorth; + + break; + + case EAST: + + // Get the East Tile + final T tileEast = createEastOrWestTile(EarthHemisphere.EAST, latitude, + currentTileLonMin, currentTileLonStep, currentTileLonCols); + // Get the North Tile + tileNorth = createNorthOrSouthTile(EarthHemisphere.NORTH, longitude, + currentTileLatMin, currentTileLatStep, currentTileLatRows); + // Get the North-East Tile + final T tileNorthEast = createIntercardinalTile(EarthHemisphere.NORTH, + currentTileLatMin, currentTileLatStep, currentTileLatRows, + EarthHemisphere.EAST, + currentTileLonMin, currentTileLonStep, currentTileLonCols); + belowLeftTile = currentTile; + belowRightTile = tileEast; + aboveLeftTile = tileNorth; + aboveRightTile = tileNorthEast; + + break; + + default: + // impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + } // end switch longitudeHemisphere + + break; + + case SOUTH: + + switch (longitudeHemisphere) { + case WEST: + + // Get the West Tile + final T tileWest = createEastOrWestTile(EarthHemisphere.WEST, latitude, + currentTileLonMin, currentTileLonStep, currentTileLonCols); + // Get the South Tile + T tileSouth = createNorthOrSouthTile(EarthHemisphere.SOUTH, longitude, + currentTileLatMin, currentTileLatStep, currentTileLatRows); + // Get the South-West Tile + final T tileSouthhWest = createIntercardinalTile(EarthHemisphere.SOUTH, + currentTileLatMin, currentTileLatStep, currentTileLatRows, + EarthHemisphere.WEST, + currentTileLonMin, currentTileLonStep, currentTileLonCols); + belowLeftTile = tileSouthhWest; + belowRightTile = tileSouth; + aboveLeftTile = tileWest; + aboveRightTile = currentTile; + + break; + + case EAST: + + // Get the East Tile + final T tileEast = createEastOrWestTile(EarthHemisphere.EAST, latitude, + currentTileLonMin, currentTileLonStep, currentTileLonCols); + // Get the South Tile + tileSouth = createNorthOrSouthTile(EarthHemisphere.SOUTH, longitude, + currentTileLatMin, currentTileLatStep, currentTileLatRows); + // Get the South-East Tile + final T tileSouthhEast = createIntercardinalTile(EarthHemisphere.SOUTH, + currentTileLatMin, currentTileLatStep, currentTileLatRows, + EarthHemisphere.EAST, + currentTileLonMin, currentTileLonStep, currentTileLonCols); + belowLeftTile = tileSouth; + belowRightTile = tileSouthhEast; + aboveLeftTile = currentTile; + aboveRightTile = tileEast; + + break; + + default: + // case impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + } // end switch longitudeHemisphere + + break; + + default: + // case impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + } // end switch latitudeHemisphere + + + // Check that tiles at same latitude have same steps in longitude and latitude + // Along Western or Eastern edges of the tiles: no change of resolution may occurs in known DEMs. + if (!(Math.abs(belowLeftTile.getLatitudeStep() - belowRightTile.getLatitudeStep()) < STEP_EQUALITY) || + !(Math.abs(belowLeftTile.getLongitudeStep() - belowRightTile.getLongitudeStep()) < STEP_EQUALITY) || + !(Math.abs(aboveLeftTile.getLatitudeStep() - aboveRightTile.getLatitudeStep()) < STEP_EQUALITY) || + !(Math.abs(aboveLeftTile.getLongitudeStep() - aboveRightTile.getLongitudeStep()) < STEP_EQUALITY)) { + // Steps are not the same. + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + } + + + // Compute the zipper steps in latitude and longitude. + // If steps are different, the zipper will have the smallest steps. + + // at this stage the latitude steps of the right and left tiles are the same + final double belowLatitudeStep = belowRightTile.getLatitudeStep(); + final double aboveLatitudeStep = aboveRightTile.getLatitudeStep(); + + // initialize the zipper latitude step + double zipperLatStep = belowLatitudeStep; + + // check if latitude steps are the same between the above and below tiles + boolean isSameStepLat = true; + + if (!(Math.abs(belowLatitudeStep - aboveLatitudeStep) < STEP_EQUALITY)) { + + // Latitude steps are not the same + isSameStepLat = false; + + // Recompute zipper latitude step if the above tiles latitude step is smaller + if (aboveLatitudeStep < belowLatitudeStep) { + zipperLatStep = aboveLatitudeStep; + } + } + + // at this stage the longitude steps of the right and left tiles are the same + final double belowLongitudeStep = belowRightTile.getLongitudeStep(); + final double aboveLongitudeStep = aboveRightTile.getLongitudeStep(); + + // initialize the zipper longitude step + double zipperLonStep = belowLongitudeStep; + + // check if longitude steps are the same between the above and below tiles + boolean isSameStepLon = true; + + if (!(Math.abs(belowLongitudeStep - aboveLongitudeStep) < STEP_EQUALITY)) { + + // Longitude steps are not the same + isSameStepLon = false; + + // Recompute zipper longitude step if the above tiles longitude step is smaller + if (aboveLongitudeStep < belowLongitudeStep) { + zipperLonStep = aboveLongitudeStep; + } + } + + // Define the zipper min latitude and min longitude. + // Explanation: + // We want the zipper 2 first rows belongs to the below tiles and the zipper 2 last rows to the above tiles. + // We want the zipper 2 first columns belongs to the left tiles and the zipper 2 last columns to the right tiles. + // We use the current tile origin AND the zipper steps to compute the zipper origin + final GeodeticPoint zipperCorner = computeCornerZipperOrigin(zipperLatStep, zipperLonStep, + latitudeHemisphere, currentTileLatMin, + currentTileLatStep, currentTileLatRows, + longitudeHemisphere, currentTileLonMin, + currentTileLonStep, currentTileLonCols); + + // Initialize corner tile + return initializeCornerZipperTile(zipperCorner.getLatitude(), zipperCorner.getLongitude(), zipperLatStep, zipperLonStep, + belowLeftTile, aboveLeftTile, belowRightTile, aboveRightTile, + isSameStepLat, isSameStepLon); + + } + + /** Initialize a corner zipper tile (with 4 rows in latitude and 4 columns in longitude). + * @param zipperLatMin zipper min latitude (ra) + * @param zipperLonMin zipper min longitude (rad) + * @param zipperLatStep zipper latitude step (rad) + * @param zipperLonStep zipper longitude step (rad) * @param belowLeftTile below left tile * @param aboveLeftTile above left tile * @param belowRightTile below right tile * @param aboveRightTile above right tile + * @param isSameStepLat flag to tell if latitude steps are the same (true) + * @param isSameStepLon flag to tell if longitude steps are the same (true) * @return corner zipper tile * @since X.x */ - private T initializeCornerZipperTile(final double zipperLatMin, final double zipperLatStep, - final double zipperLonMin, final double zipperLonStep, + private T initializeCornerZipperTile(final double zipperLatMin, final double zipperLonMin, + final double zipperLatStep, final double zipperLonStep, final T belowLeftTile, final T aboveLeftTile, final T belowRightTile, final T aboveRightTile, final boolean isSameStepLat, final boolean isSameStepLon) { - + // Defines with 4 cells from each of the 4 tiles at the corner final int zipperLatRows = 4; final int zipperLonCols = 4; - double[][] elevations = new double[zipperLatRows][zipperLonCols]; - + final double[][] elevations = new double[zipperLatRows][zipperLonCols]; + if (isSameStepLat && isSameStepLon) { // tiles with same steps in latitude and longitude - // Rows 0 and 1 of zipper: + // Rows 0 and 1 of zipper: // 2 first cells belong to the below left tile and 2 last cells to the below right tile // row 0 @@ -853,7 +872,7 @@ public class TilesCache<T extends Tile> { elevations[1][2] = belowRightTile.getElevationAtIndices(belowRightTile.getLatitudeRows() - 1, 0); elevations[1][3] = belowRightTile.getElevationAtIndices(belowRightTile.getLatitudeRows() - 1, 1); - // Rows 2 and 3 of zipper: + // Rows 2 and 3 of zipper: // 2 first cells belong to the above left tile and 2 last cells to the above right tile // row 2 @@ -873,53 +892,53 @@ public class TilesCache<T extends Tile> { } else { // tiles with different steps - // To cover every cases and as zipper with such characteristics are rare, + // To cover every cases and as zipper with such characteristics are rare, // we will use conversion from (latitude, longitude) to tile indices // We assure to be inside a cell by adding a delta step (to avoid inappropriate index computation) // TBN: zipperLatStep/zipperLonStep are the smallest steps vs below and above tiles // Compute latitude and longitude of each zipper cells - double zipperLat0 = zipperLatMin + 0.1*zipperLatStep; - double zipperLat1 = zipperLat0 + zipperLatStep; - double zipperLat2 = zipperLat1 + zipperLatStep; - double zipperLat3 = zipperLat2 + zipperLatStep; + final double zipperLat0 = zipperLatMin + 0.1 * zipperLatStep; + final double zipperLat1 = zipperLat0 + zipperLatStep; + final double zipperLat2 = zipperLat1 + zipperLatStep; + final double zipperLat3 = zipperLat2 + zipperLatStep; - double zipperLon0 = zipperLonMin + 0.1*zipperLonStep; - double zipperLon1 = zipperLon0 + zipperLonStep; - double zipperLon2 = zipperLon1 + zipperLonStep; - double zipperLon3 = zipperLon2 + zipperLonStep; + final double zipperLon0 = zipperLonMin + 0.1 * zipperLonStep; + final double zipperLon1 = zipperLon0 + zipperLonStep; + final double zipperLon2 = zipperLon1 + zipperLonStep; + final double zipperLon3 = zipperLon2 + zipperLonStep; // Compute the tiles index in latitude - int belowLeftLatitudeIndex0 = computeLatitudeIndex(zipperLat0, belowLeftTile.getMinimumLatitude(), belowLeftTile.getLatitudeStep(), belowLeftTile.getLatitudeRows()); - int belowLeftLatitudeIndex1 = computeLatitudeIndex(zipperLat1, belowLeftTile.getMinimumLatitude(), belowLeftTile.getLatitudeStep(), belowLeftTile.getLatitudeRows()); + final int belowLeftLatitudeIndex0 = computeLatitudeIndex(zipperLat0, belowLeftTile.getMinimumLatitude(), belowLeftTile.getLatitudeStep(), belowLeftTile.getLatitudeRows()); + final int belowLeftLatitudeIndex1 = computeLatitudeIndex(zipperLat1, belowLeftTile.getMinimumLatitude(), belowLeftTile.getLatitudeStep(), belowLeftTile.getLatitudeRows()); - int belowRightLatitudeIndex0 = computeLatitudeIndex(zipperLat0, belowRightTile.getMinimumLatitude(), belowRightTile.getLatitudeStep(), belowRightTile.getLatitudeRows()); - int belowRightLatitudeIndex1 = computeLatitudeIndex(zipperLat1, belowRightTile.getMinimumLatitude(), belowRightTile.getLatitudeStep(), belowRightTile.getLatitudeRows()); + final int belowRightLatitudeIndex0 = computeLatitudeIndex(zipperLat0, belowRightTile.getMinimumLatitude(), belowRightTile.getLatitudeStep(), belowRightTile.getLatitudeRows()); + final int belowRightLatitudeIndex1 = computeLatitudeIndex(zipperLat1, belowRightTile.getMinimumLatitude(), belowRightTile.getLatitudeStep(), belowRightTile.getLatitudeRows()); - int aboveLeftLatitudeIndex2 = computeLatitudeIndex(zipperLat2, aboveLeftTile.getMinimumLatitude(), aboveLeftTile.getLatitudeStep(), aboveLeftTile.getLatitudeRows()); - int aboveLeftLatitudeIndex3 = computeLatitudeIndex(zipperLat3, aboveLeftTile.getMinimumLatitude(), aboveLeftTile.getLatitudeStep(), aboveLeftTile.getLatitudeRows()); + final int aboveLeftLatitudeIndex2 = computeLatitudeIndex(zipperLat2, aboveLeftTile.getMinimumLatitude(), aboveLeftTile.getLatitudeStep(), aboveLeftTile.getLatitudeRows()); + final int aboveLeftLatitudeIndex3 = computeLatitudeIndex(zipperLat3, aboveLeftTile.getMinimumLatitude(), aboveLeftTile.getLatitudeStep(), aboveLeftTile.getLatitudeRows()); - int aboveRightLatitudeIndex2 = computeLatitudeIndex(zipperLat2, aboveRightTile.getMinimumLatitude(), aboveRightTile.getLatitudeStep(), aboveRightTile.getLatitudeRows()); - int aboveRightLatitudeIndex3 = computeLatitudeIndex(zipperLat3, aboveRightTile.getMinimumLatitude(), aboveRightTile.getLatitudeStep(), aboveRightTile.getLatitudeRows()); + final int aboveRightLatitudeIndex2 = computeLatitudeIndex(zipperLat2, aboveRightTile.getMinimumLatitude(), aboveRightTile.getLatitudeStep(), aboveRightTile.getLatitudeRows()); + final int aboveRightLatitudeIndex3 = computeLatitudeIndex(zipperLat3, aboveRightTile.getMinimumLatitude(), aboveRightTile.getLatitudeStep(), aboveRightTile.getLatitudeRows()); // Compute the tiles index in longitude - int belowLeftLongitudeIndex0 = computeLongitudeIndex(zipperLon0, belowLeftTile.getMinimumLongitude(), belowLeftTile.getLongitudeStep(), belowLeftTile.getLongitudeColumns()); - int belowLeftLongitudeIndex1 = computeLongitudeIndex(zipperLon1, belowLeftTile.getMinimumLongitude(), belowLeftTile.getLongitudeStep(), belowLeftTile.getLongitudeColumns()); + final int belowLeftLongitudeIndex0 = computeLongitudeIndex(zipperLon0, belowLeftTile.getMinimumLongitude(), belowLeftTile.getLongitudeStep(), belowLeftTile.getLongitudeColumns()); + final int belowLeftLongitudeIndex1 = computeLongitudeIndex(zipperLon1, belowLeftTile.getMinimumLongitude(), belowLeftTile.getLongitudeStep(), belowLeftTile.getLongitudeColumns()); - int belowRightLongitudeIndex2 = computeLongitudeIndex(zipperLon2, belowRightTile.getMinimumLongitude(), belowRightTile.getLongitudeStep(), belowRightTile.getLongitudeColumns()); - int belowRightLongitudeIndex3 = computeLongitudeIndex(zipperLon3, belowRightTile.getMinimumLongitude(), belowRightTile.getLongitudeStep(), belowRightTile.getLongitudeColumns()); + final int belowRightLongitudeIndex2 = computeLongitudeIndex(zipperLon2, belowRightTile.getMinimumLongitude(), belowRightTile.getLongitudeStep(), belowRightTile.getLongitudeColumns()); + final int belowRightLongitudeIndex3 = computeLongitudeIndex(zipperLon3, belowRightTile.getMinimumLongitude(), belowRightTile.getLongitudeStep(), belowRightTile.getLongitudeColumns()); - int aboveLeftLongitudeIndex0 = computeLongitudeIndex(zipperLon0, aboveLeftTile.getMinimumLongitude(), aboveLeftTile.getLongitudeStep(), aboveLeftTile.getLongitudeColumns()); - int aboveLeftLongitudeIndex1 = computeLongitudeIndex(zipperLon1, aboveLeftTile.getMinimumLongitude(), aboveLeftTile.getLongitudeStep(), aboveLeftTile.getLongitudeColumns()); + final int aboveLeftLongitudeIndex0 = computeLongitudeIndex(zipperLon0, aboveLeftTile.getMinimumLongitude(), aboveLeftTile.getLongitudeStep(), aboveLeftTile.getLongitudeColumns()); + final int aboveLeftLongitudeIndex1 = computeLongitudeIndex(zipperLon1, aboveLeftTile.getMinimumLongitude(), aboveLeftTile.getLongitudeStep(), aboveLeftTile.getLongitudeColumns()); - int aboveRightLongitudeIndex2 = computeLongitudeIndex(zipperLon2, aboveRightTile.getMinimumLongitude(), aboveRightTile.getLongitudeStep(), aboveRightTile.getLongitudeColumns()); - int aboveRightLongitudeIndex3 = computeLongitudeIndex(zipperLon3, aboveRightTile.getMinimumLongitude(), aboveRightTile.getLongitudeStep(), aboveRightTile.getLongitudeColumns()); + final int aboveRightLongitudeIndex2 = computeLongitudeIndex(zipperLon2, aboveRightTile.getMinimumLongitude(), aboveRightTile.getLongitudeStep(), aboveRightTile.getLongitudeColumns()); + final int aboveRightLongitudeIndex3 = computeLongitudeIndex(zipperLon3, aboveRightTile.getMinimumLongitude(), aboveRightTile.getLongitudeStep(), aboveRightTile.getLongitudeColumns()); - // Rows 0 and 1 of zipper: + // Rows 0 and 1 of zipper: // 2 first cells belong to the below left tile and 2 last cells to the below right tile - // row 0 + // row 0 elevations[0][0] = belowLeftTile.getElevationAtIndices(belowLeftLatitudeIndex0, belowLeftLongitudeIndex0); elevations[0][1] = belowLeftTile.getElevationAtIndices(belowLeftLatitudeIndex0, belowLeftLongitudeIndex1); @@ -933,7 +952,7 @@ public class TilesCache<T extends Tile> { elevations[1][2] = belowRightTile.getElevationAtIndices(belowRightLatitudeIndex1, belowRightLongitudeIndex2); elevations[1][3] = belowRightTile.getElevationAtIndices(belowRightLatitudeIndex1, belowRightLongitudeIndex3); - // Rows 2 and 3 of zipper: + // Rows 2 and 3 of zipper: // 2 first cells belong to the above left tile and 2 last cells to the above right tile // row 2 @@ -951,200 +970,200 @@ public class TilesCache<T extends Tile> { elevations[3][3] = aboveRightTile.getElevationAtIndices(aboveRightLatitudeIndex3, aboveRightLongitudeIndex3); } // end test isSameStepLat && isSameStepLon - + // Initialize the corner zipper tile - final T cornerZipperTile = initializeZipperTile(zipperLatMin, zipperLonMin, - zipperLatStep, zipperLonStep, + final T cornerZipperTile = initializeZipperTile(zipperLatMin, zipperLonMin, + zipperLatStep, zipperLonStep, zipperLatRows, zipperLonCols, elevations); return cornerZipperTile; } - + /** - * Create the tile in intercardinal direction of the current Tile i.e. NW, NE, SW, SE + * Create the tile in intercardinal direction of the current Tile i.e. NW, NE, SW, SE. * @param latitudeHemisphere hemisphere for latitude: NORTH / SOUTH - * @param minLat latitude minimum for the tile (rad) + * @param latitudeMin latitude minimum for the tile (rad) + * @param latitudeStep latitude step (rad) * @param latitudeRows latitude rows - * @param latStep latitude step (rad) * @param longitudeHemisphere hemisphere for longitude : WEST / EAST - * @param minLon longitude minimum for the tile (rad) + * @param longitudeMin longitude minimum for the tile (rad) + * @param longitudeStep longitude step (rad) * @param longitudeCols longitude columns - * @param lonStep longitude step (rad) * @return the tile in intercardinal direction * @since X.x */ - private T createIntercardinalTile(final EarthHemisphere latitudeHemisphere, - final double minLat, final int latitudeRows, final double latStep, - final EarthHemisphere longitudeHemisphere, - final double minLon, final int longitudeCols, final double lonStep) { - - // lonHemisphere = +1 : East or = -1 : West - int lonHemisphere; - switch (longitudeHemisphere) { - case EAST: - lonHemisphere = +1; - break; - case WEST: - lonHemisphere = -1; - break; - default: - // impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); - } - - // latHemisphere = +1 : North or = -1 : South - int latHemisphere; - switch (latitudeHemisphere) { - case NORTH: - latHemisphere = +1; - break; - case SOUTH: - latHemisphere = -1; - break; - default: - // impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); - } - - final double latToGetIntercardinalTile = minLat + latHemisphere*latitudeRows*latStep; - final double lonToGetIntercardinalTile = minLon + lonHemisphere*longitudeCols*lonStep; - final T intercardinalTile = createTile(latToGetIntercardinalTile, lonToGetIntercardinalTile); - return intercardinalTile; - } + private T createIntercardinalTile(final EarthHemisphere latitudeHemisphere, + final double latitudeMin, final double latitudeStep, final int latitudeRows, + final EarthHemisphere longitudeHemisphere, + final double longitudeMin, final double longitudeStep, final int longitudeCols) { + + // longitudeHemisphere = +1 : East or = -1 : West + final int lonHemisphere; + switch (longitudeHemisphere) { + case EAST: + lonHemisphere = +1; + break; + case WEST: + lonHemisphere = -1; + break; + default: + // impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + } + + // latitudeHemisphere = +1 : North or = -1 : South + final int latHemisphere; + switch (latitudeHemisphere) { + case NORTH: + latHemisphere = +1; + break; + case SOUTH: + latHemisphere = -1; + break; + default: + // impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + } + + final double latToGetIntercardinalTile = latitudeMin + latHemisphere * latitudeRows * latitudeStep; + final double lonToGetIntercardinalTile = longitudeMin + lonHemisphere * longitudeCols * longitudeStep; + final T intercardinalTile = createTile(latToGetIntercardinalTile, lonToGetIntercardinalTile); + return intercardinalTile; + } /** Compute the corner zipper tile origin (min latitude and min longitude). * @param zipperLatStep zipper latitude step (rad) * @param zipperLonStep zipper longitude step (rad) * @param latitudeHemisphere latitude hemisphere of the zipper vs the current tile - * @param currentTileMinLat current tile latitude origin (rad) - * @param currentTileLatRows current tile latitude rows + * @param currentTileLatMin current tile latitude origin (rad) * @param currentTileLatStep current tile latitude step (rad) + * @param currentTileLatRows current tile latitude rows * @param longitudeHemisphere longitude hemisphere of the zipper vs the current tile - * @param currentTileMinLon current tile tile longitude origin (rad) - * @param currentTileLonCols current tile longitude columns + * @param currentTileLonMin current tile tile longitude origin (rad) * @param currentTileLonStep current tile longitude step (rad) + * @param currentTileLonCols current tile longitude columns * @return corner zipper tile origin point * @since X.x */ private GeodeticPoint computeCornerZipperOrigin(final double zipperLatStep, final double zipperLonStep, - final EarthHemisphere latitudeHemisphere, final double currentTileMinLat, - final int currentTileLatRows, final double currentTileLatStep, - final EarthHemisphere longitudeHemisphere, final double currentTileMinLon, - final int currentTileLonCols, final double currentTileLonStep) { - double zipperLatMin; - double zipperLonMin; - - // Explanation: + final EarthHemisphere latitudeHemisphere, + final double currentTileLatMin, final double currentTileLatStep, final int currentTileLatRows, + final EarthHemisphere longitudeHemisphere, + final double currentTileLonMin, final double currentTileLonStep, final int currentTileLonCols) { + final double zipperLatMin; + final double zipperLonMin; + + // Explanation: // We want the zipper 2 first rows belongs to the below tiles and the zipper 2 last rows to the above tiles. // We want the zipper 2 first columns belongs to the left tiles and the zipper 2 last columns to the right tiles. // We use the current tile origin AND the zipper steps to compute the zipper origin switch (latitudeHemisphere) { - case NORTH: + case NORTH: - switch (longitudeHemisphere) { - case WEST: - zipperLatMin = currentTileMinLat + currentTileLatRows * currentTileLatStep - 2*zipperLatStep; - zipperLonMin = currentTileMinLon - 2*zipperLonStep; - break; + switch (longitudeHemisphere) { + case WEST: + zipperLatMin = currentTileLatMin + currentTileLatRows * currentTileLatStep - 2 * zipperLatStep; + zipperLonMin = currentTileLonMin - 2 * zipperLonStep; + break; + + case EAST: + zipperLatMin = currentTileLatMin + currentTileLatRows * currentTileLatStep - 2 * zipperLatStep; + zipperLonMin = currentTileLonMin + currentTileLonCols * currentTileLonStep - 2 * zipperLonStep; + break; + + default: + // case impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + } // end switch longitudeHemisphere - case EAST: - zipperLatMin = currentTileMinLat + currentTileLatRows * currentTileLatStep - 2*zipperLatStep; - zipperLonMin = currentTileMinLon + currentTileLonCols * currentTileLonStep - 2*zipperLonStep; break; - default: - // case impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); - } // end switch longitudeHemisphere + case SOUTH: - break; + switch (longitudeHemisphere) { + case WEST: + zipperLatMin = currentTileLatMin - 2 * zipperLatStep; + zipperLonMin = currentTileLonMin - 2 * zipperLonStep; + break; - case SOUTH: - - switch (longitudeHemisphere) { - case WEST: - zipperLatMin = currentTileMinLat - 2*zipperLatStep; - zipperLonMin = currentTileMinLon - 2*zipperLonStep; - break; + case EAST: + zipperLatMin = currentTileLatMin - 2 * zipperLatStep; + zipperLonMin = currentTileLonMin + currentTileLonCols * currentTileLonStep - 2 * zipperLonStep; + break; + + default: + // case impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + } // end switch longitudeHemisphere - case EAST: - zipperLatMin = currentTileMinLat - 2*zipperLatStep; - zipperLonMin = currentTileMinLon + currentTileLonCols * currentTileLonStep - 2*zipperLonStep; break; default: - // case impossible to reach + // impossible to reach throw new RuggedException(RuggedMessages.INTERNAL_ERROR); - } // end switch longitudeHemisphere + } // end switch latitudeHemisphere - break; + return new GeodeticPoint(zipperLatMin, zipperLonMin, 0); + } - default: - // impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); - } // end switch latitudeHemisphere - return new GeodeticPoint(zipperLatMin, zipperLonMin, 0); - } - - - /** Create the Northern or Southern tile of a given tile defined by minLat, longitude, latitudeRows and latStep + /** Create the Northern or Southern tile of a given tile defined by minLat, longitude, latitudeRows and latStep. * @param latitudeHemisphere latitude hemisphere * @param longitude longitude to define the tile (rad) - * @param minLat minimum latitude to define the tile (rad) + * @param latitudeMin minimum latitude to define the tile (rad) + * @param latitudeStep latitude step (rad) * @param latitudeRows latitude rows - * @param latStep latitude step (rad) * @return North or South tile according to the Earth hemisphere * @since X.x */ - private T createNorthOrSouthTile(final EarthHemisphere latitudeHemisphere, final double longitude, - final double minLat, final int latitudeRows, final double latStep) { + private T createNorthOrSouthTile(final EarthHemisphere latitudeHemisphere, final double longitude, + final double latitudeMin, final double latitudeStep, final int latitudeRows) { // hemisphere = +1 : North or = -1 : South - int hemisphere; + final int hemisphere; switch (latitudeHemisphere) { - case NORTH: - hemisphere = +1; - break; - case SOUTH: - hemisphere = -1; - break; - default: - // impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + case NORTH: + hemisphere = +1; + break; + case SOUTH: + hemisphere = -1; + break; + default: + // impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); } - - final double latToGetNewTile = minLat + hemisphere*latitudeRows*latStep; + + final double latToGetNewTile = latitudeMin + hemisphere * latitudeRows * latitudeStep; return createTile(latToGetNewTile, longitude); } - - - /** Create the Eastern or Western tile of a given tile defined by latitude, minLon, longitudeCols and lonStep + + + /** Create the Eastern or Western tile of a given tile defined by latitude, minLon, longitudeCols and lonStep. * @param longitudeHemisphere longitude hemisphere * @param latitude latitude to define the tile (rad) - * @param minLon minimum longitude to define the tile (rad) + * @param longitudeMin minimum longitude to define the tile (rad) + * @param longitudeStep longitude step (rad) * @param longitudeCols longitude columns - * @param lonStep longitude step (rad) * @return East or West tile tile according to the Earth hemisphere * @since X.x */ - private T createEastOrWestTile(final EarthHemisphere longitudeHemisphere, final double latitude, - final double minLon, final int longitudeCols, final double lonStep) { + private T createEastOrWestTile(final EarthHemisphere longitudeHemisphere, final double latitude, + final double longitudeMin, final double longitudeStep, final int longitudeCols) { // hemisphere = +1 : East or = -1 : West - int hemisphere; + final int hemisphere; switch (longitudeHemisphere) { - case EAST: - hemisphere = +1; - break; - case WEST: - hemisphere = -1; - break; - default: - // impossible to reach - throw new RuggedException(RuggedMessages.INTERNAL_ERROR); + case EAST: + hemisphere = +1; + break; + case WEST: + hemisphere = -1; + break; + default: + // impossible to reach + throw new RuggedException(RuggedMessages.INTERNAL_ERROR); } - - final double lonToGetNewTile = minLon + hemisphere*longitudeCols*lonStep; + + final double lonToGetNewTile = longitudeMin + hemisphere * longitudeCols * longitudeStep; return createTile(latitude, lonToGetNewTile); } } diff --git a/src/test/java/org/orekit/rugged/intersection/AbstractAlgorithmTest.java b/src/test/java/org/orekit/rugged/intersection/AbstractAlgorithmTest.java index 34953d87..2e677d7c 100644 --- a/src/test/java/org/orekit/rugged/intersection/AbstractAlgorithmTest.java +++ b/src/test/java/org/orekit/rugged/intersection/AbstractAlgorithmTest.java @@ -50,7 +50,7 @@ import org.orekit.utils.PVCoordinates; public abstract class AbstractAlgorithmTest { - protected abstract IntersectionAlgorithm createAlgorithm(TileUpdater updater, int maxCachedTiles, boolean isOvelappingTiles); + protected abstract IntersectionAlgorithm createAlgorithm(TileUpdater updater, int maxCachedTiles, boolean isOverlappingTiles); @Test public void testMayonVolcanoOnSubTileCorner() { diff --git a/src/test/java/org/orekit/rugged/intersection/BasicScanAlgorithmTest.java b/src/test/java/org/orekit/rugged/intersection/BasicScanAlgorithmTest.java index e1b7d937..8418c834 100644 --- a/src/test/java/org/orekit/rugged/intersection/BasicScanAlgorithmTest.java +++ b/src/test/java/org/orekit/rugged/intersection/BasicScanAlgorithmTest.java @@ -25,8 +25,8 @@ import org.orekit.rugged.raster.TileUpdater; public class BasicScanAlgorithmTest extends AbstractAlgorithmTest { - public IntersectionAlgorithm createAlgorithm(final TileUpdater updater, final int maxCachedTiles, final boolean isOvelappingTiles) { - return new BasicScanAlgorithm(updater, maxCachedTiles, isOvelappingTiles); + public IntersectionAlgorithm createAlgorithm(final TileUpdater updater, final int maxCachedTiles, final boolean isOverlappingTiles) { + return new BasicScanAlgorithm(updater, maxCachedTiles, isOverlappingTiles); } @Test diff --git a/src/test/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithmTest.java b/src/test/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithmTest.java index 6d7a82c1..09de20ae 100644 --- a/src/test/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithmTest.java +++ b/src/test/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithmTest.java @@ -44,8 +44,8 @@ import org.orekit.rugged.utils.NormalizedGeodeticPoint; public class DuvenhageAlgorithmTest extends AbstractAlgorithmTest { - protected IntersectionAlgorithm createAlgorithm(final TileUpdater updater, final int maxCachedTiles, final boolean isOvelappingTiles) { - return new DuvenhageAlgorithm(updater, maxCachedTiles, false, isOvelappingTiles); + protected IntersectionAlgorithm createAlgorithm(final TileUpdater updater, final int maxCachedTiles, final boolean isOverlappingTiles) { + return new DuvenhageAlgorithm(updater, maxCachedTiles, false, isOverlappingTiles); } @Test diff --git a/src/test/java/org/orekit/rugged/raster/DummySRTMsimpleElevationUpdater.java b/src/test/java/org/orekit/rugged/raster/DummySRTMsimpleElevationUpdater.java index f06117c9..27feb6b7 100644 --- a/src/test/java/org/orekit/rugged/raster/DummySRTMsimpleElevationUpdater.java +++ b/src/test/java/org/orekit/rugged/raster/DummySRTMsimpleElevationUpdater.java @@ -1,3 +1,19 @@ +/* Copyright 2013-2022 CS GROUP + * Licensed to CS GROUP (CS) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * CS licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.orekit.rugged.raster; import org.hipparchus.util.FastMath; diff --git a/src/test/java/org/orekit/rugged/raster/TilesCacheTest.java b/src/test/java/org/orekit/rugged/raster/TilesCacheTest.java index 6986d144..b22f0349 100644 --- a/src/test/java/org/orekit/rugged/raster/TilesCacheTest.java +++ b/src/test/java/org/orekit/rugged/raster/TilesCacheTest.java @@ -33,6 +33,7 @@ import org.hipparchus.random.Well19937a; import org.hipparchus.util.FastMath; import org.hipparchus.util.MathUtils; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; /** @@ -185,7 +186,6 @@ public class TilesCacheTest { double tileSizeDeg = srtmUpdater.getTileSizeDeg(); double rasterStepDeg = srtmUpdater.getTileStepDeg(); - System.out.println("Default size: " + srtmUpdater.getTileSizeDeg() + " step " + srtmUpdater.getTileStepDeg()); CountingFactory factory = new CountingFactory(); TilesCache<SimpleTile> cache = new TilesCache<SimpleTile>(factory, srtmUpdater , 5, false); @@ -203,36 +203,29 @@ public class TilesCacheTest { // North-East hemisphere // ===================== - System.out.println("\n\n#################################"); - System.out.println("NORTH EAST hemisphere"); latTileDeg = 47.; lonTileDeg = 12.3; - System.out.println(">>>> Search lat deg = " + latTileDeg + " lon deg= " + lonTileDeg + "\n"); SimpleTile tileNEhemisphere = cache.getTile(FastMath.toRadians(latTileDeg), FastMath.toRadians(lonTileDeg)); // Latitude North of the tile - System.out.println("##### Bord de tuile au niveau latitude North #####"); latDeg = getNorthernEdgeOfTile(tileNEhemisphere); lonDeg = lonTileDeg; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.NORTH, tileNEhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Latitude South of the tile - System.out.println("#### Bord de tuile au niveau latitude South #####"); latDeg = getSouthernEdgeOfTile(tileNEhemisphere); lonDeg = lonTileDeg; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.SOUTH, tileNEhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Longitude West of the tile - System.out.println("#### Bord de tuile au niveau longitude West #####"); latDeg = latTileDeg; lonDeg = getWesternEdgeOfTile(tileNEhemisphere); searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.WEST, tileNEhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Longitude East of the tile - System.out.println("#### Bord de tuile au niveau longitude East #####"); latDeg = latTileDeg; lonDeg = getEasternEdgeOfTile(tileNEhemisphere); @@ -243,39 +236,29 @@ public class TilesCacheTest { // South-East hemisphere // ===================== - System.out.println("\n\n#################################"); - System.out.println("SOUTH EAST hemisphere"); - latTileDeg = -16.2; lonTileDeg = 22.3; - System.out.println(">>>> Search lat deg = " + latTileDeg + " lon deg= " + lonTileDeg + "\n"); SimpleTile tileSEhemisphere = cache.getTile(FastMath.toRadians(latTileDeg), FastMath.toRadians(lonTileDeg)); - printTileInfo(tileSEhemisphere, rasterStepDeg, rasterStepDeg); - // Latitude North of the tile - System.out.println("##### Bord de tuile au niveau latitude North #####"); latDeg = getNorthernEdgeOfTile(tileSEhemisphere); lonDeg = lonTileDeg; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.NORTH, tileSEhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Latitude South of the tile - System.out.println("#### Bord de tuile au niveau latitude South #####"); latDeg = getSouthernEdgeOfTile(tileSEhemisphere); lonDeg = lonTileDeg; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.SOUTH, tileSEhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Longitude West of the tile - System.out.println("#### Bord de tuile au niveau longitude West #####"); latDeg = latTileDeg; lonDeg = getWesternEdgeOfTile(tileSEhemisphere); searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.WEST, tileSEhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Longitude East of the tile - System.out.println("#### Bord de tuile au niveau longitude East #####"); latDeg = latTileDeg; lonDeg = getEasternEdgeOfTile(tileSEhemisphere); searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.EAST, tileSEhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); @@ -285,38 +268,30 @@ public class TilesCacheTest { // North-West hemisphere // ===================== - System.out.println("\n\n#################################"); - System.out.println("NORTH WEST hemisphere"); latTileDeg = 46.8; lonTileDeg = -66.5; - System.out.println(">>>> Search lat deg = " + latTileDeg + " lon deg= " + lonTileDeg + "\n"); SimpleTile tileNWhemisphere = cache.getTile(FastMath.toRadians(latTileDeg), FastMath.toRadians(lonTileDeg)); - printTileInfo(tileNWhemisphere, rasterStepDeg, rasterStepDeg); // Latitude North of the tile - System.out.println("##### Bord de tuile au niveau latitude North #####"); latDeg = getNorthernEdgeOfTile(tileNWhemisphere); lonDeg = lonTileDeg; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.NORTH, tileNWhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Latitude South of the tile - System.out.println("#### Bord de tuile au niveau latitude South #####"); latDeg = getSouthernEdgeOfTile(tileNWhemisphere); lonDeg = lonTileDeg; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.SOUTH, tileNWhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Longitude West of the tile - System.out.println("#### Bord de tuile au niveau longitude West #####"); latDeg = latTileDeg; lonDeg = getWesternEdgeOfTile(tileNWhemisphere); searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.WEST, tileNWhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Longitude East of the tile - System.out.println("#### Bord de tuile au niveau longitude East #####"); latDeg = latTileDeg; lonDeg = getEasternEdgeOfTile(tileNWhemisphere); @@ -327,38 +302,29 @@ public class TilesCacheTest { // South-West hemisphere // ===================== - System.out.println("\n\n#################################"); - System.out.println("SOUTH WEST hemisphere"); - latTileDeg = -28.8 ; lonTileDeg = -58.4; - System.out.println(">>>> Search lat deg = " + latTileDeg + " lon deg= " + lonTileDeg + "\n"); SimpleTile tileSWhemisphere = cache.getTile(FastMath.toRadians(latTileDeg), FastMath.toRadians(lonTileDeg)); - printTileInfo(tileSWhemisphere, rasterStepDeg, rasterStepDeg); // Latitude North of the tile - System.out.println("##### Bord de tuile au niveau latitude North #####"); latDeg = getNorthernEdgeOfTile(tileSWhemisphere); lonDeg = lonTileDeg; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.NORTH, tileSWhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Latitude South of the tile - System.out.println("#### Bord de tuile au niveau latitude South #####"); latDeg = getSouthernEdgeOfTile(tileSWhemisphere); lonDeg = lonTileDeg; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.SOUTH, tileSWhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Longitude West of the tile - System.out.println("#### Bord de tuile au niveau longitude West #####"); latDeg = latTileDeg; lonDeg = getWesternEdgeOfTile(tileSWhemisphere); searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.WEST, tileSWhemisphere, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Longitude East of the tile - System.out.println("#### Bord de tuile au niveau longitude East #####"); latDeg = latTileDeg; lonDeg = getEasternEdgeOfTile(tileSWhemisphere); @@ -369,31 +335,23 @@ public class TilesCacheTest { // Anti meridians (180 degrees W/E) // ===================== - System.out.println("\n\n#################################"); - System.out.println("Anti meridien test (180 degre East)"); // tile SRTM 72/16: 175 - 180 East / 15 - 20 South latTileDeg = -18.; lonTileDeg = 178.; - System.out.println(">>>> Search lat deg = " + latTileDeg + " lon deg= " + lonTileDeg + "\n"); SimpleTile tileAntiMeridianEast = cache.getTile(FastMath.toRadians(latTileDeg), FastMath.toRadians(lonTileDeg)); // Longitude East of the tile - System.out.println("#### Bord de tuile au niveau longitude East #####"); latDeg = latTileDeg; lonDeg = getEasternEdgeOfTile(tileAntiMeridianEast); searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.EAST,tileAntiMeridianEast, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); - System.out.println("#################################"); - System.out.println("Anti meridien test (180 degre West)"); // tile SRTM 01/16: 175 - 180 West / 15 - 20 South latTileDeg = -18.; lonTileDeg = -178.; - System.out.println(">>>> Search lat deg = " + latTileDeg + " lon deg= " + lonTileDeg + "\n"); SimpleTile tileAntiMeridianWest = cache.getTile(FastMath.toRadians(latTileDeg), FastMath.toRadians(lonTileDeg)); // Longitude West of the tile - System.out.println("#### Bord de tuile au niveau longitude West #####"); latDeg = latTileDeg; lonDeg = getWesternEdgeOfTile(tileAntiMeridianWest); @@ -415,20 +373,14 @@ public class TilesCacheTest { // Above 60 degrees // ================ - System.out.println("\n\n#################################"); - System.out.println("Above 60 degrees "); latTileDeg = 59.; lonTileDeg = 12.3; - System.out.println(">>>> Search lat deg = " + latTileDeg + " lon deg= " + lonTileDeg + "\n"); SimpleTile tileAround60deg = cache.getTile(FastMath.toRadians(latTileDeg), FastMath.toRadians(lonTileDeg)); // Latitude North of the tile - System.out.println("##### Bord de tuile au niveau latitude North #####"); - latDeg = getNorthernEdgeOfTile(tileAround60deg); lonDeg = lonTileDeg; - System.out.println(">>>> Bord Nord lat deg = " + latDeg + "\n"); isDifferentStep = true; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.NORTH, tileAround60deg, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); @@ -441,20 +393,14 @@ public class TilesCacheTest { // Below -60 degrees // ================= - System.out.println("\n\n#################################"); - System.out.println("Below -60 degrees "); latTileDeg = -59.; lonTileDeg = 12.3; - System.out.println(">>>> Search lat deg = " + latTileDeg + " lon deg= " + lonTileDeg + "\n"); SimpleTile tileAroundMinus60deg = cache.getTile(FastMath.toRadians(latTileDeg), FastMath.toRadians(lonTileDeg)); // Latitude South of the tile - System.out.println("##### Bord de tuile au niveau latitude South #####"); - latDeg = getSouthernEdgeOfTile(tileAroundMinus60deg); lonDeg = lonTileDeg; - System.out.println(">>>> Bord South lat deg = " + latDeg + "\n"); isDifferentStep = true; searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.SOUTH, tileAroundMinus60deg, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); @@ -503,45 +449,33 @@ public class TilesCacheTest { SimpleTile cornerZipperTile; // Latitude/Longitude corner NW - System.out.println("##### Coin de tuile au niveau latitude North et longitude West #####"); latDeg = getNorthernEdgeOfTile(tile); lonDeg = getWesternEdgeOfTile(tile); - System.out.println(">>>> Search lat deg = " + latDeg + " lon deg= " + lonDeg + "\n"); cornerZipperTile = cache.getTile(FastMath.toRadians(latDeg), FastMath.toRadians(lonDeg)); -// printTileInfo(cornerZipperTile, rasterStepDeg, rasterStepDeg); checkGeodeticPointBelongsToZipper(FastMath.toRadians(latDeg), FastMath.toRadians(lonDeg), cornerZipperTile); checkCornerZipperTile(cornerZipperTile, Tile.Location.NORTH_WEST, tile, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Latitude/Longitude corner SW - System.out.println("##### Coin de tuile au niveau latitude South et longitude West #####"); latDeg = getSouthernEdgeOfTile(tile); lonDeg = getWesternEdgeOfTile(tile); - System.out.println(">>>> Search lat deg = " + latDeg + " lon deg= " + lonDeg + "\n"); cornerZipperTile = cache.getTile(FastMath.toRadians(latDeg), FastMath.toRadians(lonDeg)); -// printTileInfo(cornerZipperTile, rasterStepDeg, rasterStepDeg); checkGeodeticPointBelongsToZipper(FastMath.toRadians(latDeg), FastMath.toRadians(lonDeg), cornerZipperTile); checkCornerZipperTile(cornerZipperTile, Tile.Location.SOUTH_WEST, tile, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Latitude/Longitude corner NE - System.out.println("##### Coin de tuile au niveau latitude North et longitude Est #####"); latDeg = getNorthernEdgeOfTile(tile); lonDeg = getEasternEdgeOfTile(tile); - System.out.println(">>>> Search lat deg = " + latDeg + " lon deg= " + lonDeg + "\n"); cornerZipperTile = cache.getTile(FastMath.toRadians(latDeg), FastMath.toRadians(lonDeg)); -// printTileInfo(cornerZipperTile, rasterStepDeg, rasterStepDeg); checkGeodeticPointBelongsToZipper(FastMath.toRadians(latDeg), FastMath.toRadians(lonDeg), cornerZipperTile); checkCornerZipperTile(cornerZipperTile, Tile.Location.NORTH_EAST, tile, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // Latitude/Longitude corner SE - System.out.println("##### Coin de tuile au niveau latitude South et longitude Est #####"); latDeg = getSouthernEdgeOfTile(tile); lonDeg = getEasternEdgeOfTile(tile); - System.out.println(">>>> Search lat deg = " + latDeg + " lon deg= " + lonDeg + "\n"); cornerZipperTile = cache.getTile(FastMath.toRadians(latDeg), FastMath.toRadians(lonDeg)); -// printTileInfo(cornerZipperTile, rasterStepDeg, rasterStepDeg); checkGeodeticPointBelongsToZipper(FastMath.toRadians(latDeg), FastMath.toRadians(lonDeg), cornerZipperTile); checkCornerZipperTile(cornerZipperTile, Tile.Location.SOUTH_EAST, tile, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); @@ -559,50 +493,6 @@ public class TilesCacheTest { assertTrue((lonMin <= longitude) && (longitude <= lonMax)); } - - private void printSurroundingTiles(double latDeg, double lonDeg, final double sizeDeg, final double rasterStepDeg, - TilesCache<SimpleTile> cache, int stepPrint, int nbRowCol) throws FileNotFoundException, UnsupportedEncodingException { - - // print tile above ... - double latUp = latDeg + sizeDeg; - SimpleTile tileUp = cache.getTile(FastMath.toRadians(latUp), FastMath.toRadians(lonDeg)); - String tileUpName = "above_lat" + Double.toString(latUp) + "lon" + Double.toString(lonDeg) + ".txt"; - printExtractTileData(tileUpName, tileUp, stepPrint, 0, nbRowCol, 0, tileUp.getLongitudeColumns()); - - // print tile below - double latBelow = latDeg - sizeDeg; - SimpleTile tileBelow = cache.getTile(FastMath.toRadians(latBelow), FastMath.toRadians(lonDeg)); - String tileBelowName = "below_lat" + Double.toString(latBelow) + "lon" + Double.toString(lonDeg) + ".txt"; - printExtractTileData(tileBelowName, tileBelow, stepPrint, tileBelow.getLatitudeRows() - nbRowCol, tileBelow.getLatitudeRows(), 0, tileBelow.getLongitudeColumns()); - - // print tile left - double lonLeft = lonDeg - sizeDeg; - SimpleTile tileLeft = cache.getTile(FastMath.toRadians(latDeg), FastMath.toRadians(lonLeft)); - String tileLeftName = "left_lat" + Double.toString(latDeg) + "lon" + Double.toString(lonLeft) + ".txt"; - printExtractTileData(tileLeftName, tileLeft, stepPrint, 0, tileLeft.getLatitudeRows(),tileLeft.getLongitudeColumns() - nbRowCol, tileLeft.getLongitudeColumns()); - - // print tile right - double lonRight = lonDeg + sizeDeg; - SimpleTile tileRight = cache.getTile(FastMath.toRadians(latDeg), FastMath.toRadians(lonRight)); - String tileRightName = "right_lat" + Double.toString(latDeg) + "lon" + Double.toString(lonRight) + ".txt"; - printExtractTileData(tileRightName, tileRight, stepPrint, 0, tileRight.getLatitudeRows(), 0, nbRowCol); - - } - - private void checkOneValueZipperTile(double latDeg, double lonDeg, SimpleTile zipperTile, - final int nbRows, final int nbCols, - double epsilonLatLon, double minLat, double maxLat, double minLon, double maxLon, - final int expectedLatIndex, final int expectedLonIndex, final double expectedElevation) { - - assertTrue(zipperTile.getLatitudeRows() == nbRows); - assertTrue(zipperTile.getLongitudeColumns() == nbCols); - assertEquals(FastMath.toDegrees(zipperTile.getMinimumLatitude()), minLat, epsilonLatLon); - assertEquals(FastMath.toDegrees(zipperTile.getMaximumLatitude()), maxLat, epsilonLatLon); - assertEquals(FastMath.toDegrees(zipperTile.getMinimumLongitude()), minLon, epsilonLatLon); - assertEquals(FastMath.toDegrees(zipperTile.getMaximumLongitude()), maxLon, epsilonLatLon); - checkLatLonIndex(latDeg, expectedLatIndex, lonDeg, expectedLonIndex, expectedElevation, zipperTile); - } - private void checkCornerZipperTile(SimpleTile cornerZipperTile, Tile.Location location, SimpleTile originTile, double tileSizeDeg, TilesCache<SimpleTile> cache, double epsilonLatLon, boolean isDifferentStep) { @@ -637,14 +527,8 @@ public class TilesCacheTest { SimpleTile aboveRight = originTile; SimpleTile aboveLeft = tileLeft; - - System.out.println("CORNER SOUTH WEST"); - printSurroundingCorner(cornerZipperTile,belowRight, belowLeft, aboveRight, aboveLeft); - checkCornerElevationsDifferentStep(cornerZipperTile, originTile, belowLeft, belowRight, aboveLeft, aboveRight, epsilonLatLon); - } - } else if (location == Tile.Location.NORTH_WEST) { SimpleTile tileAbove = surroundingTiles.getTileAbove(); @@ -675,11 +559,7 @@ public class TilesCacheTest { SimpleTile aboveRight = tileAbove; SimpleTile aboveLeft = leftAboveOfCurrent; - System.out.println("CORNER NORTH WEST"); - printSurroundingCorner(cornerZipperTile,belowRight, belowLeft, aboveRight, aboveLeft); - checkCornerElevationsDifferentStep(cornerZipperTile, originTile, belowLeft, belowRight, aboveLeft, aboveRight, epsilonLatLon); - } @@ -712,12 +592,8 @@ public class TilesCacheTest { SimpleTile aboveRight = tileRight; SimpleTile aboveLeft = originTile; - System.out.println("CORNER SOUTH EAST"); - printSurroundingCorner(cornerZipperTile,belowRight, belowLeft, aboveRight, aboveLeft); - checkCornerElevationsDifferentStep(cornerZipperTile, originTile, belowLeft, belowRight, aboveLeft, aboveRight, epsilonLatLon); } - } else if (location == Tile.Location.NORTH_EAST) { SimpleTile tileAbove = surroundingTiles.getTileAbove(); @@ -747,118 +623,10 @@ public class TilesCacheTest { SimpleTile aboveRight = aboveRightOfCurrent; SimpleTile aboveLeft = tileAbove; - System.out.println("CORNER NORTH_EAST"); - printSurroundingCorner(cornerZipperTile,belowRight, belowLeft, aboveRight, aboveLeft); - checkCornerElevationsDifferentStep(cornerZipperTile, originTile, belowLeft, belowRight, aboveLeft, aboveRight, epsilonLatLon); - } } } - - private void printSurroundingCorner(SimpleTile cornerZipperTile, SimpleTile belowRight, SimpleTile belowLeft, SimpleTile aboveRight, - SimpleTile aboveLeft) { - - - for (int i = 3; i >= 0; i--) { - System.out.println(cornerZipperTile.getElevationAtIndices(i, 0) + " | " + cornerZipperTile.getElevationAtIndices(i, 1) + " | " + - cornerZipperTile.getElevationAtIndices(i, 2) + " | " + cornerZipperTile.getElevationAtIndices(i, 3) + " | " ); - } - - System.out.println(" BELOW RIGHT"); - if (belowRight.getLongitudeColumns() > 3) { - for (int i = belowRight.getLatitudeRows() - 1; i >= belowRight.getLatitudeRows() - 3; i--) { - System.out.println(belowRight.getElevationAtIndices(i, 0) + " | " + - belowRight.getElevationAtIndices(i, 1) + " | " + - belowRight.getElevationAtIndices(i, 2) + " | " + - belowRight.getElevationAtIndices(i, 3) + " | " + - belowRight.getElevationAtIndices(i, 4) + " | " + - belowRight.getElevationAtIndices(i, 5) + " | " + - belowRight.getElevationAtIndices(i, 6) + " | " + - belowRight.getElevationAtIndices(i, 7) + " | " + - belowRight.getElevationAtIndices(i, 8) + " | " + - belowRight.getElevationAtIndices(i, 9) + " | "); - } - } else { - for (int i = 2; i >= 0; i--) { - System.out.println(belowRight.getElevationAtIndices(i, 0) + " | " + - belowRight.getElevationAtIndices(i, 1) + " | " + - belowRight.getElevationAtIndices(i, 2) + " | " ); - } - } - - System.out.println(" BELOW LEFT"); - if (belowLeft.getLongitudeColumns() > 3) { - for (int i = belowLeft.getLatitudeRows() - 1; i >= belowLeft.getLatitudeRows() - 3; i--) { - System.out.println(belowLeft.getElevationAtIndices(i, 0) + " | " + - belowLeft.getElevationAtIndices(i, 1) + " | " + - belowLeft.getElevationAtIndices(i, 2) + " | " + - belowLeft.getElevationAtIndices(i, 3) + " | " + - belowLeft.getElevationAtIndices(i, 4) + " | " + - belowLeft.getElevationAtIndices(i, 5) + " | " + - belowLeft.getElevationAtIndices(i, 6) + " | " + - belowLeft.getElevationAtIndices(i, 7) + " | " + - belowLeft.getElevationAtIndices(i, 8) + " | " + - belowLeft.getElevationAtIndices(i, 9) + " | "); - } - } else { - for (int i = 2; i >= 0; i--) { - System.out.println(belowLeft.getElevationAtIndices(i, 0) + " | " + - belowLeft.getElevationAtIndices(i, 1) + " | " + - belowLeft.getElevationAtIndices(i, 2) + " | " ); - } - - } - - - System.out.println(" ABOVE RIGHT"); - - if (aboveRight.getLongitudeColumns() > 3) { - for (int i = 3; i >= 0; i--) { - System.out.println(aboveRight.getElevationAtIndices(i, 0) + " | " + - aboveRight.getElevationAtIndices(i, 1) + " | " + - aboveRight.getElevationAtIndices(i, 2) + " | " + - aboveRight.getElevationAtIndices(i, 3) + " | " + - aboveRight.getElevationAtIndices(i, 4) + " | " + - aboveRight.getElevationAtIndices(i, 5) + " | " + - aboveRight.getElevationAtIndices(i, 6) + " | " + - aboveRight.getElevationAtIndices(i, 7) + " | " + - aboveRight.getElevationAtIndices(i, 8) + " | " + - aboveRight.getElevationAtIndices(i, 9) + " | "); - } - - } else { - for (int i = 2; i >= 0; i--) { - System.out.println(aboveRight.getElevationAtIndices(i, 0) + " | " + - aboveRight.getElevationAtIndices(i, 1) + " | " + - aboveRight.getElevationAtIndices(i, 2) + " | " ); - } - } - - System.out.println(" ABOVE LEFT"); - if (aboveLeft.getLongitudeColumns() > 3) { - for (int i = 3; i >= 0; i--) { - System.out.println(aboveLeft.getElevationAtIndices(i, 0) + " | " + - aboveLeft.getElevationAtIndices(i, 1) + " | " + - aboveLeft.getElevationAtIndices(i, 2) + " | " + - aboveLeft.getElevationAtIndices(i, 3) + " | " + - aboveLeft.getElevationAtIndices(i, 4) + " | " + - aboveLeft.getElevationAtIndices(i, 5) + " | " + - aboveLeft.getElevationAtIndices(i, 6) + " | " + - aboveLeft.getElevationAtIndices(i, 7) + " | " + - aboveLeft.getElevationAtIndices(i, 8) + " | " + - aboveLeft.getElevationAtIndices(i, 9) + " | "); - } - - } else { - for (int i = 2; i >= 0; i--) { - System.out.println(aboveLeft.getElevationAtIndices(i, 0) + " | " + - aboveLeft.getElevationAtIndices(i, 1) + " | " + - aboveLeft.getElevationAtIndices(i, 2) + " | " ); - } - } - } - private void checkCornerElevations(SimpleTile cornerZipperTile, SimpleTile originTile, SimpleTile belowLeft, SimpleTile belowRight, SimpleTile aboveLeft, SimpleTile aboveRight, double epsilonLatLon) { @@ -941,10 +709,9 @@ public class TilesCacheTest { assertEquals(aboveRightElevation, cornerZipperElevation, epsilonLatLon); } - private void checkCornerElevationsDifferentStep(SimpleTile cornerZipperTile, SimpleTile originTile, - SimpleTile belowLeft, SimpleTile belowRight, SimpleTile aboveLeft, SimpleTile aboveRight, - double epsilonLatLon) { + SimpleTile belowLeft, SimpleTile belowRight, SimpleTile aboveLeft, SimpleTile aboveRight, + double epsilonLatLon) { // We assure to be inside a cell by adding a delta step (to avoid inappropriate index computation) @@ -1086,7 +853,6 @@ public class TilesCacheTest { assertEquals(aboveRightElevation, cornerZipperElevation, epsilonLatLon); } - private void checkZipperTile(SimpleTile zipperTile, Tile.Location zipperLocation, SimpleTile originTile, double tileSizeDeg, TilesCache<SimpleTile> cache, double epsilonLatLon) { @@ -1211,7 +977,6 @@ public class TilesCacheTest { double belowTileDoubleLongitudeIndex = (zipperLongitude - tileBelow.getMinimumLongitude()) / tileBelow.getLongitudeStep(); int belowTileLongitudeIndex = FastMath.max(0, FastMath.min(tileBelow.getLongitudeColumns() - 1, (int) FastMath.floor(belowTileDoubleLongitudeIndex))); - // row 0 of zipper double zipperLat0 = zipperTile.getMinimumLatitude() + 0.1*zipperTile.getLatitudeStep(); double belowTileDoubleLatitudeIndex = (zipperLat0 - tileBelow.getMinimumLatitude()) / tileBelow.getLatitudeStep(); @@ -1350,7 +1115,6 @@ public class TilesCacheTest { } } - private final static double getNorthernEdgeOfTile(SimpleTile tile) { double northernLatitudeForTile = getNorthernLatitudeForTile(tile); // Inside the northern row of latitude @@ -1375,7 +1139,6 @@ public class TilesCacheTest { return easternLongitudeForTile - 0.1*FastMath.toDegrees(tile.getLongitudeStep()); } - private final static double getNorthernLatitudeForTile(SimpleTile tile) { return FastMath.toDegrees(tile.getMaximumLatitude()) + 0.5*FastMath.toDegrees(tile.getLatitudeStep()); } @@ -1392,112 +1155,11 @@ public class TilesCacheTest { return FastMath.toDegrees(tile.getMaximumLongitude()) + 0.5*FastMath.toDegrees(tile.getLongitudeStep()); } - - - private void checkLatLonIndex(final double latDeg, final int expectedLatIndex, - final double lonDeg, final int expectedLonIndex, - final double expectedElevation, - final SimpleTile tile) { - - double latRad = FastMath.toRadians(latDeg); - double lonRad = FastMath.toRadians(lonDeg); - - assertTrue(tile.getFloorLatitudeIndex(latRad) == expectedLatIndex); - assertTrue((FastMath.toDegrees(tile.getLatitudeAtIndex(expectedLatIndex)) <= latDeg && - (FastMath.toDegrees(tile.getLatitudeAtIndex(expectedLatIndex+1)) >= latDeg))); - - assertTrue(tile.getFloorLongitudeIndex(lonRad) == expectedLonIndex); - assertTrue((FastMath.toDegrees(tile.getLongitudeAtIndex(expectedLonIndex)) <= lonDeg && - (FastMath.toDegrees(tile.getLongitudeAtIndex(expectedLonIndex+1)) >= lonDeg))); - - assertEquals(expectedElevation, tile.getElevationAtIndices(expectedLatIndex, expectedLonIndex), epsilonElevation); - } - final static double epsilonElevation = 1.e-6; final static java.text.DecimalFormatSymbols symbols = new java.text.DecimalFormatSymbols(java.util.Locale.US); final static java.text.DecimalFormat dfs = new java.text.DecimalFormat("#.#####",symbols); - private void printTileInfo(SimpleTile tile, double stepLatDeg, double stepLonDeg){ - try { - System.out.format( - "Bilan found Tile: " + tile.getLatitudeRows() + " lat rows x " + - tile.getLongitudeColumns() + " long columns \n" + - " Rugged Convention { " + - " min lat = " + dfs.format(FastMath.toDegrees(tile.getMinimumLatitude())) + - " max lat = " + dfs.format(FastMath.toDegrees(tile.getMaximumLatitude())) + "}" + - " {" + - " min lon = " + dfs.format(FastMath.toDegrees(tile.getMinimumLongitude())) + - " max lon = " + dfs.format(FastMath.toDegrees(tile.getMaximumLongitude())) + "}\n"); - System.out.format( - " SRTM Convention { "+ - " min lat = " + dfs.format(FastMath.toDegrees(tile.getMinimumLatitude())-0.5*stepLatDeg) + - " max lat = " + dfs.format(FastMath.toDegrees(tile.getMaximumLatitude())+0.5*stepLatDeg) + "}" + - " {" + - " min lon = " + dfs.format(FastMath.toDegrees(tile.getMinimumLongitude())-0.5*stepLonDeg) + - " max lon = " + dfs.format(FastMath.toDegrees(tile.getMaximumLongitude())+0.5*stepLonDeg) + "}" + - " \n\n"); - } catch (Exception e) { - System.out.println("problem"); - } - } - - private void printTileData(String tileName, SimpleTile tile, int stepPrint) throws FileNotFoundException, UnsupportedEncodingException { - - printExtractTileData(tileName, tile, stepPrint, 0, tile.getLatitudeRows(), 0, tile.getLongitudeColumns()); - } - - private void printExtractTileData(String tileName, SimpleTile tile, int stepPrint, - int iLatMin, int iLatMax, int jLonMin, int jLonMax) throws FileNotFoundException, UnsupportedEncodingException { - - PrintWriter elevationPrinter = new PrintWriter(tileName, "UTF-8"); - -// elevationPrinter.println("# latitude(°) longitude(°) h (m)" + "\n" + delimiter); - for (int jLon = jLonMin; jLon < jLonMax; jLon += stepPrint) { -// if (jLon % 100 == 0) System.out.println("longitude = " + jLon); - for (int iLat = iLatMin; iLat < iLatMax; iLat += stepPrint) { - - double elevation = tile.getElevationAtIndices(iLat, jLon); - double latitude = tile.getLatitudeAtIndex(iLat); - double longitude = tile.getLongitudeAtIndex(jLon); - elevationPrinter.format(Locale.US, "%3.8f %3.8f %.4f%n", - FastMath.toDegrees(latitude), FastMath.toDegrees(longitude), elevation); - } - } - if (elevationPrinter != null) elevationPrinter.close(); - - } - - private void printEdgeTileData(String tileName, SimpleTile tile, int stepPrint, - int iLatMax, int jLonMax, int nbRowCols) throws FileNotFoundException, UnsupportedEncodingException { - - PrintWriter elevationPrinter = new PrintWriter(tileName, "UTF-8"); - - for (int jLon = 0; jLon < jLonMax; jLon += stepPrint) { -// if (jLon % 100 == 0) System.out.println("longitude = " + jLon); - for (int iLat = 0; iLat < iLatMax; iLat += stepPrint) { - - if ((((0 <= iLat) && (iLat < nbRowCols)) || ((iLatMax - nbRowCols <= iLat) && (iLat < iLatMax))) || - (((0 <= jLon) && (jLon < nbRowCols)) || ((jLonMax - nbRowCols <= jLon) && (jLon < jLonMax))) - ) { - double elevation = tile.getElevationAtIndices(iLat, jLon); - double latitude = tile.getLatitudeAtIndex(iLat); - double longitude = tile.getLongitudeAtIndex(jLon); - elevationPrinter.format(Locale.US, "%3.8f %3.8f %.4f%n", - FastMath.toDegrees(latitude), FastMath.toDegrees(longitude), elevation); - } - } - } - if (elevationPrinter != null) elevationPrinter.close(); - -// + printExtractTileData(tileName + "NorthEdge", tile, stepPrint, iLatMax - nbRowCols, iLatMax, 0, jLonMax); -// + printExtractTileData(tileName + "SouthEdge", tile, stepPrint, 0, nbRowCols, 0, jLonMax); -// + printExtractTileData(tileName + "WestEdge", tile, stepPrint, 0, iLatMax, 0, nbRowCols); -// + printExtractTileData(tileName + "EastEdge", tile, stepPrint, 0, iLatMax, jLonMax - nbRowCols, jLonMax); - - } - - /** Clean up of factory map * @param factoryClass */ @@ -1815,214 +1477,36 @@ public class TilesCacheTest { // // searchAndVerifyZipperTile(latDeg, lonDeg, Tile.Location.WEST,tileAntiMeridianWest, tileSizeDeg, cache, epsilonLatLon, isDifferentStep); // -// } - - -} - -//// Test for development purpose only: use a real DEM (SRTM) -// -///** -// * To read SRTM tiles (get from http://dwtkns.com/srtm/) -// * The tiles are seamless = no overlapping -// */ -//class SRTMElevationUpdater implements TileUpdater { -// -// /** Last lat value used to ask to update a tile. */ -// private double lastLat = Double.NaN; -// -// /** Last lon value used to ask to update a tile. */ -// private double lastLon = Double.NaN; -// -// /** Nb times the same lat/lon value is used to ask to update a tile (used to avoid infinite loop). */ -// private int nbCall = 0; -// -// /** Nb time rugged ask exactly same DEM tile: means that infinite loop. */ -// private static final int NB_TIME_ASK_SAME_TILE = 1000; -// -// /** Raster root directory, should contains raster files. */ -// private String rootDirectory; -// -// -// /** -// * Constructor. -// */ -// public SRTMElevationUpdater(final String rootDirectory) { -// -// this.rootDirectory = rootDirectory; -// checkRasterDirectory(rootDirectory); -// } -// -// /** Update given tile using DEM elevation. -// * @param latitude latitude that must be covered by the tile (rad) -// * @param longitude longitude that must be covered by the tile (rad) -// * @param tile to update -// */ -// @Override -// public void updateTile(final double latitude, final double longitude, final UpdatableTile tile) { -// -// // Check if latitude and longitude already known -// if (latitude == this.lastLat && longitude == this.lastLon) { -// this.nbCall++; -// } else { -// this.lastLat = latitude; -// this.lastLon = longitude; -// this.nbCall = 0; -// } -// if (this.nbCall > NB_TIME_ASK_SAME_TILE) { -// String str = String.format("infinite loop for %3.8f long %3.8f lat ", longitude, latitude); -// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); -// throw new org.orekit.rugged.errors.RuggedException(message); -// } -// -// String rasterFileName = getRasterFilePath(latitude, longitude); // -//// java.io.FileFile rasterFile = new java.io.File(rasterFileName); -//// if (!rasterFile.exists()) { -//// // No DEM => we are on water => read geoid -//// GeoidHandler geoidHandler = GeoidHandler.getInstance(); -//// geoidHandler.updateTile(latitude, longitude, tile); -//// System.out.format("WARNING: No DEM tile found for latitude (deg) = %3.8f and longitude (deg) = %3.8f." + -//// " DEM file %s doesn't exist. Use of Geoid data instead.%n", -//// FastMath.toDegrees(latitude), FastMath.toDegrees(longitude), rasterFileName); -//// return; -//// } -// -// org.gdal.gdal.Dataset ds = org.gdal.gdal.gdal.Open(rasterFileName, org.gdal.gdalconst.gdalconst.GA_ReadOnly); -// int rasterLonSize = ds.GetRasterXSize(); -// int rasterLatSize = ds.GetRasterYSize(); -// double[] geoTransformInfo = ds.GetGeoTransform(); -// -// double minLat = Double.NaN; -// double minLon = Double.NaN; -// double lonStep = Double.NaN; -// double latStep = Double.NaN; -// -// if (geoTransformInfo.length < 6) { // Check that the geoTransformInfo is correct -// String str = "GDALGeoTransform has < 6 elements"; -// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); -// throw new org.orekit.rugged.errors.RuggedException(message); -// } else { -// lonStep = FastMath.abs(geoTransformInfo[1]); -// latStep = FastMath.abs(geoTransformInfo[5]); -// -// minLon = geoTransformInfo[0] + 0.5 * lonStep; -// minLat = geoTransformInfo[3] - (rasterLatSize - 0.5) * latStep; -// } -// -// org.gdal.gdal.Band band = ds.GetRasterBand(1); -// -// // Define Tile Geometry -// tile.setGeometry(FastMath.toRadians(minLat), FastMath.toRadians(minLon), FastMath.toRadians(latStep), FastMath.toRadians(lonStep), rasterLatSize, rasterLonSize); -// -// // Loop over raster values -// double[] data = new double[rasterLatSize * rasterLonSize]; -// -//// // SRTM is given above the geoid -//// GeoidHandler geoidHandler = GeoidHandler.getInstance(); -//// GdalTransformTools gtTools = new GdalTransformTools(geoTransformInfo, rasterLonSize, rasterLatSize); -// -// // We read all raster at once to limit the numbers of Band.ReadRaster calls -// band.ReadRaster(0, 0, rasterLonSize, rasterLatSize, data); -// -// // Get the no data value from the raster -// Double[] noDataValue = new Double[1]; -// band.GetNoDataValue(noDataValue); -// -// // test if the no data value exists -// Boolean noDataValueExist = false; -// if (noDataValue[0] != null) noDataValueExist = true; -// -// // from bottom left to upper right corner -// for (int iLat = rasterLatSize - 1; iLat >= 0; iLat--) { -// for (int jLon = 0; jLon < rasterLonSize; jLon++) { -// -// double elevationOverEllipsoid = 0.0; -// elevationOverEllipsoid = data[iLat * rasterLonSize + jLon]; -// -// if (noDataValueExist && (elevationOverEllipsoid == noDataValue[0])) { -// elevationOverEllipsoid = 0.0; -// } -// -//// // The elevation value we send to rugged must be computed against ellipsoid -//// // => when DEM is SRTM , we must add geoid value -//// double lon = gtTools.getXFromPixelLine(jLon, iLat); -//// double lat = gtTools.getYFromPixelLine(jLon, iLat); -//// elevationOverEllipsoid = elevationOverEllipsoid + geoidHandler.getElevationDegree(lat, lon); -// -// // Set elevation over the ellipsoid -// tile.setElevation(rasterLatSize - 1 - iLat, jLon, elevationOverEllipsoid); -// } -// } -// band.delete(); -// band = null; -// ds.delete(); -// ds = null; -// } +// // Change of resolution between tiles +// // ================================== +// // Cleanup +// clearFactoryMaps(CountingFactory.class); +// factory = new CountingFactory(); +// cache = new TilesCache<SimpleTile>(factory, srtmUpdater , 5, false); // -// private String getRasterFilePath(final double latitude, final double longitude) { +// isDifferentStep = true; // -// double latDeg = FastMath.toDegrees(latitude); -// // Assure that the longitude belongs to [-180, + 180] -// double lonDeg = FastMath.toDegrees(MathUtils.normalizeAngle(longitude, 0.0)); +//// // North-East hemisphere +//// // ===================== +//// System.out.println("#################################"); +//// System.out.println("NORTH EAST hemisphere"); +//// // tile SRTM: 45N - 50N / 10E-15E +//// latTileDeg = 47.; +//// lonTileDeg = 12.3; +//// +//// System.out.println(">>>> Search lat deg = " + latTileDeg + " lon deg= " + lonTileDeg + "\n"); +//// SimpleTile tileNEhemisphere = cache.getTile(FastMath.toRadians(latTileDeg), FastMath.toRadians(lonTileDeg)); +//// // same step and size in longitude and latitude +//// double tileSizeDeg = FastMath.toDegrees(tileNEhemisphere.getLatitudeRows()*tileNEhemisphere.getLatitudeStep()); +//// double rasterStepDeg = FastMath.toDegrees(tileNEhemisphere.getLatitudeStep()); // -// // Compute parent dir with longitude value -// int parentDirValue = (int) (1 + (lonDeg + 180.) / 5); -// String parentDir = String.format("%02d", parentDirValue); // -// // Compute sub dir with latitude value -// int subDirValue = (int) (1 + (60. - latDeg) / 5); -// String subDir = String.format("%02d", subDirValue); // -// String filePath = this.rootDirectory + java.io.File.separator + parentDir + java.io.File.separator + subDir + java.io.File.separator + -// "srtm_" + parentDir + "_" + subDir + ".tif"; -// return filePath; // } -// -// private boolean checkRasterDirectory(final String directory) { -// -// if (directory == null) { -// -// String str = "Directory not defined"; -// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); -// throw new org.orekit.rugged.errors.RuggedException(message); -// -// } else { -// try { -// java.nio.file.Path dir = java.nio.file.FileSystems.getDefault().getPath(directory); -// java.nio.file.DirectoryStream<java.nio.file.Path> stream = java.nio.file.Files.newDirectoryStream(dir); -// boolean found = false; -// for (java.nio.file.Path path : stream) { -// if (!found) { -// java.io.File currentFile = path.toFile(); -// if (currentFile.isDirectory()) { -// found = checkRasterDirectory(currentFile.getAbsolutePath()); -// } else { -// String filePath = currentFile.getAbsolutePath(); -// if (filePath.matches(".*.tif")) { -// found = true; -// } -// } -// if (found) { -// stream.close(); -// return true; -// } -// } -// } -// stream.close(); -// -// String str = "raster not found in" + directory; -// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); -// throw new org.orekit.rugged.errors.RuggedException(message); -// -// } catch (java.io.IOException e) { -// String str = "dir not found " + directory; -// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); -// throw new org.orekit.rugged.errors.RuggedException(message); -// } -// } -// } -//} + + +} class SurroundingTiles { @@ -2076,3 +1560,208 @@ class SurroundingTiles { return cache.getTile(FastMath.toRadians(latDeg), lonRightNorm); } } + +////Test for development purpose only: use a real DEM (SRTM) +// +///** +//* To read SRTM tiles (get from http://dwtkns.com/srtm/) +//* The tiles are seamless = no overlapping +//*/ +//class SRTMElevationUpdater implements TileUpdater { +// +///** Last lat value used to ask to update a tile. */ +//private double lastLat = Double.NaN; +// +///** Last lon value used to ask to update a tile. */ +//private double lastLon = Double.NaN; +// +///** Nb times the same lat/lon value is used to ask to update a tile (used to avoid infinite loop). */ +//private int nbCall = 0; +// +///** Nb time rugged ask exactly same DEM tile: means that infinite loop. */ +//private static final int NB_TIME_ASK_SAME_TILE = 1000; +// +///** Raster root directory, should contains raster files. */ +//private String rootDirectory; +// +// +///** +//* Constructor. +//*/ +//public SRTMElevationUpdater(final String rootDirectory) { +// +// this.rootDirectory = rootDirectory; +// checkRasterDirectory(rootDirectory); +//} +// +///** Update given tile using DEM elevation. +//* @param latitude latitude that must be covered by the tile (rad) +//* @param longitude longitude that must be covered by the tile (rad) +//* @param tile to update +//*/ +//@Override +//public void updateTile(final double latitude, final double longitude, final UpdatableTile tile) { +// +// // Check if latitude and longitude already known +// if (latitude == this.lastLat && longitude == this.lastLon) { +// this.nbCall++; +// } else { +// this.lastLat = latitude; +// this.lastLon = longitude; +// this.nbCall = 0; +// } +// if (this.nbCall > NB_TIME_ASK_SAME_TILE) { +// String str = String.format("infinite loop for %3.8f long %3.8f lat ", longitude, latitude); +// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); +// throw new org.orekit.rugged.errors.RuggedException(message); +// } +// +// String rasterFileName = getRasterFilePath(latitude, longitude); +// +//// java.io.FileFile rasterFile = new java.io.File(rasterFileName); +//// if (!rasterFile.exists()) { +//// // No DEM => we are on water => read geoid +//// GeoidHandler geoidHandler = GeoidHandler.getInstance(); +//// geoidHandler.updateTile(latitude, longitude, tile); +//// System.out.format("WARNING: No DEM tile found for latitude (deg) = %3.8f and longitude (deg) = %3.8f." + +//// " DEM file %s doesn't exist. Use of Geoid data instead.%n", +//// FastMath.toDegrees(latitude), FastMath.toDegrees(longitude), rasterFileName); +//// return; +//// } +// +// org.gdal.gdal.Dataset ds = org.gdal.gdal.gdal.Open(rasterFileName, org.gdal.gdalconst.gdalconst.GA_ReadOnly); +// int rasterLonSize = ds.GetRasterXSize(); +// int rasterLatSize = ds.GetRasterYSize(); +// double[] geoTransformInfo = ds.GetGeoTransform(); +// +// double minLat = Double.NaN; +// double minLon = Double.NaN; +// double lonStep = Double.NaN; +// double latStep = Double.NaN; +// +// if (geoTransformInfo.length < 6) { // Check that the geoTransformInfo is correct +// String str = "GDALGeoTransform has < 6 elements"; +// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); +// throw new org.orekit.rugged.errors.RuggedException(message); +// } else { +// lonStep = FastMath.abs(geoTransformInfo[1]); +// latStep = FastMath.abs(geoTransformInfo[5]); +// +// minLon = geoTransformInfo[0] + 0.5 * lonStep; +// minLat = geoTransformInfo[3] - (rasterLatSize - 0.5) * latStep; +// } +// +// org.gdal.gdal.Band band = ds.GetRasterBand(1); +// +// // Define Tile Geometry +// tile.setGeometry(FastMath.toRadians(minLat), FastMath.toRadians(minLon), FastMath.toRadians(latStep), FastMath.toRadians(lonStep), rasterLatSize, rasterLonSize); +// +// // Loop over raster values +// double[] data = new double[rasterLatSize * rasterLonSize]; +// +//// // SRTM is given above the geoid +//// GeoidHandler geoidHandler = GeoidHandler.getInstance(); +//// GdalTransformTools gtTools = new GdalTransformTools(geoTransformInfo, rasterLonSize, rasterLatSize); +// +// // We read all raster at once to limit the numbers of Band.ReadRaster calls +// band.ReadRaster(0, 0, rasterLonSize, rasterLatSize, data); +// +// // Get the no data value from the raster +// Double[] noDataValue = new Double[1]; +// band.GetNoDataValue(noDataValue); +// +// // test if the no data value exists +// Boolean noDataValueExist = false; +// if (noDataValue[0] != null) noDataValueExist = true; +// +// // from bottom left to upper right corner +// for (int iLat = rasterLatSize - 1; iLat >= 0; iLat--) { +// for (int jLon = 0; jLon < rasterLonSize; jLon++) { +// +// double elevationOverEllipsoid = 0.0; +// elevationOverEllipsoid = data[iLat * rasterLonSize + jLon]; +// +// if (noDataValueExist && (elevationOverEllipsoid == noDataValue[0])) { +// elevationOverEllipsoid = 0.0; +// } +// +//// // The elevation value we send to rugged must be computed against ellipsoid +//// // => when DEM is SRTM , we must add geoid value +//// double lon = gtTools.getXFromPixelLine(jLon, iLat); +//// double lat = gtTools.getYFromPixelLine(jLon, iLat); +//// elevationOverEllipsoid = elevationOverEllipsoid + geoidHandler.getElevationDegree(lat, lon); +// +// // Set elevation over the ellipsoid +// tile.setElevation(rasterLatSize - 1 - iLat, jLon, elevationOverEllipsoid); +// } +// } +// band.delete(); +// band = null; +// ds.delete(); +// ds = null; +//} +// +//private String getRasterFilePath(final double latitude, final double longitude) { +// +// double latDeg = FastMath.toDegrees(latitude); +// // Assure that the longitude belongs to [-180, + 180] +// double lonDeg = FastMath.toDegrees(MathUtils.normalizeAngle(longitude, 0.0)); +// +// // Compute parent dir with longitude value +// int parentDirValue = (int) (1 + (lonDeg + 180.) / 5); +// String parentDir = String.format("%02d", parentDirValue); +// +// // Compute sub dir with latitude value +// int subDirValue = (int) (1 + (60. - latDeg) / 5); +// String subDir = String.format("%02d", subDirValue); +// +// String filePath = this.rootDirectory + java.io.File.separator + parentDir + java.io.File.separator + subDir + java.io.File.separator + +// "srtm_" + parentDir + "_" + subDir + ".tif"; +// return filePath; +//} +// +//private boolean checkRasterDirectory(final String directory) { +// +// if (directory == null) { +// +// String str = "Directory not defined"; +// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); +// throw new org.orekit.rugged.errors.RuggedException(message); +// +// } else { +// try { +// java.nio.file.Path dir = java.nio.file.FileSystems.getDefault().getPath(directory); +// java.nio.file.DirectoryStream<java.nio.file.Path> stream = java.nio.file.Files.newDirectoryStream(dir); +// boolean found = false; +// for (java.nio.file.Path path : stream) { +// if (!found) { +// java.io.File currentFile = path.toFile(); +// if (currentFile.isDirectory()) { +// found = checkRasterDirectory(currentFile.getAbsolutePath()); +// } else { +// String filePath = currentFile.getAbsolutePath(); +// if (filePath.matches(".*.tif")) { +// found = true; +// } +// } +// if (found) { +// stream.close(); +// return true; +// } +// } +// } +// stream.close(); +// +// String str = "raster not found in" + directory; +// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); +// throw new org.orekit.rugged.errors.RuggedException(message); +// +// } catch (java.io.IOException e) { +// String str = "dir not found " + directory; +// org.hipparchus.exception.DummyLocalizable message = new org.hipparchus.exception.DummyLocalizable(str); +// throw new org.orekit.rugged.errors.RuggedException(message); +// } +// } +//} +//} + diff --git a/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java b/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java index 466f7ab2..7424ffb8 100644 --- a/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java +++ b/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java @@ -257,8 +257,8 @@ public class MultiLayerModelTest extends AbstractAlgorithmTest { } @Override - protected IntersectionAlgorithm createAlgorithm(TileUpdater updater, int maxCachedTiles, boolean isOvelappingTiles) { - return new DuvenhageAlgorithm(updater, maxCachedTiles, false, isOvelappingTiles); + protected IntersectionAlgorithm createAlgorithm(TileUpdater updater, int maxCachedTiles, boolean isOverlappingTiles) { + return new DuvenhageAlgorithm(updater, maxCachedTiles, false, isOverlappingTiles); } } -- GitLab