Tile.java

  1. /* Copyright 2013-2022 CS GROUP
  2.  * Licensed to CS GROUP (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.rugged.raster;

  18. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  19. import org.orekit.rugged.utils.NormalizedGeodeticPoint;

  20. /** Interface representing a raster tile.
  21.  * <p>
  22.  * The elevations are considered to be at the <em>center</em> of each cells.
  23.  * The minimum latitude and longitude hence correspond to the <em>center</em>
  24.  * of the most South-West cell, and the maximum latitude and longitude
  25.  * correspond to the <em>center</em> of the most North-East cell.
  26.  * </p>
  27.  * @author Luc Maisonobe
  28.  * @author Guylaine Prat
  29.  */
  30. public interface Tile extends UpdatableTile {

  31.     /** Enumerate for point location with respect to the interpolation grid of a tile.
  32.      * <p>
  33.      * Elevations in a tile are interpolated using the four neighboring points
  34.      * in a grid: (i, j), (i+1, j), (i, j+1), (i+1), (j+1). This implies that a point
  35.      * can be interpolated only if the elevation for these four points is available
  36.      * in the tile. A consequence is that a point in the northernmost row (resp.
  37.      * easternmost column) miss neighboring points at row j+1 (resp. neighboring points
  38.      * at column i+1) and therefore cannot be interpolated.
  39.      * </p>
  40.      * <p>
  41.      * This enumerate represent the position of a point taking this off-by-one property
  42.      * into account, the value {@link #HAS_INTERPOLATION_NEIGHBORS} correspond to points that
  43.      * do have the necessary four neightbors, whereas the other values correspond to points
  44.      * that are either completely outside of the tile or within the tile but in either the
  45.      * northernmost row or easternmost column.
  46.      * </p>
  47.      */
  48.     enum Location {

  49.         /** Location for points out of tile interpolation grid, in the South-West corner direction. */
  50.         SOUTH_WEST,

  51.         /** Location for points out of tile interpolation grid, in the West edge direction. */
  52.         WEST,

  53.         /** Location for points out of tile interpolation grid, in the North-West corner direction.
  54.          * <p>
  55.          * The point may still be in the tile, but in the northernmost row thus missing required
  56.          * interpolation points.
  57.          * </p>
  58.          */
  59.         NORTH_WEST,

  60.         /** Location for points out of tile interpolation grid, in the North edge direction.
  61.          * <p>
  62.          * The point may still be in the tile, but in the northernmost row thus missing required
  63.          * interpolation points.
  64.          * </p>
  65.          */
  66.         NORTH,

  67.         /** Location for points out of tile interpolation grid, in the North-East corner direction.
  68.          * <p>
  69.          * The point may still be in the tile, but either in the northernmost row or in the
  70.          * easternmost column thus missing required interpolation points.
  71.          * </p>
  72.          */
  73.         NORTH_EAST,

  74.         /** Location for points out of tile interpolation grid, in the East edge direction.
  75.          * <p>
  76.          * The point may still be in the tile, but in the easternmost column thus missing required
  77.          * interpolation points.
  78.          * </p>
  79.          */
  80.         EAST,

  81.         /** Location for points out of tile interpolation grid, in the South-East corner direction.
  82.          * <p>
  83.          * The point may still be in the tile, but in the easternmost column thus missing required
  84.          * interpolation points.
  85.          * </p>
  86.          */
  87.         SOUTH_EAST,

  88.         /** Location for points out of tile interpolation grid, in the South edge direction. */
  89.         SOUTH,

  90.         /** Location for points that do have interpolation neighbors.
  91.          * <p>
  92.          * The value corresponds to points that can be interpolated using their four
  93.          * neighboring points in the grid at indices (i, j), (i+1, j), (i, j+1), (i+1),
  94.          * (j+1). This implies that these points are neither in the northernmost latitude
  95.          * row nor in the easternmost longitude column.
  96.          * </p>
  97.          */
  98.         HAS_INTERPOLATION_NEIGHBORS

  99.     }

  100.     /** Hook called at the end of tile update completion.
  101.      */
  102.     void tileUpdateCompleted();

  103.     /** Get minimum latitude of grid interpolation points.
  104.      * @return minimum latitude of grid interpolation points (rad)
  105.      * (latitude of the center of the cells of South row)
  106.      */
  107.     double getMinimumLatitude();

  108.     /** Get the latitude at some index.
  109.      * @param latitudeIndex latitude index
  110.      * @return latitude at the specified index (rad)
  111.      * (latitude of the center of the cells of specified row)
  112.      */
  113.     double getLatitudeAtIndex(int latitudeIndex);

  114.     /** Get maximum latitude.
  115.      * <p>
  116.      * Beware that as a point at maximum latitude is the northernmost
  117.      * one of the grid, it doesn't have a northwards neighbor and
  118.      * therefore calling {@link #getLocation(double, double) getLocation}
  119.      * on such a latitude will return either {@link Location#NORTH_WEST},
  120.      * {@link Location#NORTH} or {@link Location#NORTH_EAST}, but can
  121.      * <em>never</em> return {@link Location#HAS_INTERPOLATION_NEIGHBORS}!
  122.      * </p>
  123.      * @return maximum latitude (rad)
  124.      * (latitude of the center of the cells of North row)
  125.      */
  126.     double getMaximumLatitude();

  127.     /** Get minimum longitude.
  128.      * @return minimum longitude (rad)
  129.      * (longitude of the center of the cells of West column)
  130.      */
  131.     double getMinimumLongitude();

  132.     /** Get the longitude at some index.
  133.      * @param longitudeIndex longitude index
  134.      * @return longitude at the specified index (rad)
  135.      * (longitude of the center of the cells of specified column)
  136.      */
  137.     double getLongitudeAtIndex(int longitudeIndex);

  138.     /** Get maximum longitude.
  139.      * <p>
  140.      * Beware that as a point at maximum longitude is the easternmost
  141.      * one of the grid, it doesn't have an eastwards neighbor and
  142.      * therefore calling {@link #getLocation(double, double) getLocation}
  143.      * on such a longitude will return either {@link Location#SOUTH_EAST},
  144.      * {@link Location#EAST} or {@link Location#NORTH_EAST}, but can
  145.      * <em>never</em> return {@link Location#HAS_INTERPOLATION_NEIGHBORS}!
  146.      * </p>
  147.      * @return maximum longitude (rad)
  148.      * (longitude of the center of the cells of East column)
  149.      */
  150.     double getMaximumLongitude();

  151.     /** Get step in latitude (size of one raster element).
  152.      * @return step in latitude (rad)
  153.      */
  154.     double getLatitudeStep();

  155.     /** Get step in longitude (size of one raster element).
  156.      * @return step in longitude (rad)
  157.      */
  158.     double getLongitudeStep();

  159.     /** Get number of latitude rows.
  160.      * @return number of latitude rows
  161.      */
  162.     int getLatitudeRows();

  163.     /** Get number of longitude columns.
  164.      * @return number of longitude columns
  165.      */
  166.     int getLongitudeColumns();

  167.     /** Get the floor latitude index of a point.
  168.      * <p>
  169.      * The specified latitude is always between index and index+1.
  170.      * </p>
  171.      * @param latitude geodetic latitude
  172.      * @return floor latitude index (it may lie outside of the tile!)
  173.      */
  174.     int getFloorLatitudeIndex(double latitude);

  175.     /** Get the floor longitude index of a point.
  176.      * <p>
  177.      * The specified longitude is always between index and index+1.
  178.      * </p>
  179.      * @param longitude geodetic longitude
  180.      * @return floor longitude index (it may lie outside of the tile!)
  181.      */
  182.     int getFloorLongitudeIndex(double longitude);

  183.     /** Get the minimum elevation in the tile.
  184.      * @return minimum elevation in the tile (m)
  185.      */
  186.     double getMinElevation();

  187.     /** Get the latitude index of min elevation.
  188.      * @return latitude index of min elevation*/
  189.     int getMinElevationLatitudeIndex();

  190.     /** Get the longitude index of min elevation.
  191.      * @return longitude index of min elevation*/
  192.     int getMinElevationLongitudeIndex();

  193.    /** Get the maximum elevation in the tile.
  194.      * @return maximum elevation in the tile (m)
  195.      */
  196.     double getMaxElevation();

  197.     /** Get the latitude index of max elevation.
  198.      * @return latitude index of max elevation*/
  199.     int getMaxElevationLatitudeIndex();

  200.     /** Get the longitude index of max elevation.
  201.      * @return longitude index of max elevation*/
  202.     int getMaxElevationLongitudeIndex();

  203.     /** Get the elevation of an exact grid point.
  204.      * @param latitudeIndex grid point index along latitude
  205.      * @param longitudeIndex grid point index along longitude
  206.      * @return elevation at grid point (m)
  207.      */
  208.     double getElevationAtIndices(int latitudeIndex, int longitudeIndex);

  209.     /** Interpolate elevation.
  210.      * <p>
  211.      * In order to cope with numerical accuracy issues when computing
  212.      * points at tile boundary, a slight tolerance (typically 1/8 cell)
  213.      * around the tile is allowed. Elevation can therefore be interpolated
  214.      * (really extrapolated in this case) even for points slightly overshooting
  215.      * tile boundaries, using the closest tile cell. Attempting to interpolate
  216.      * too far from the tile will trigger an exception.
  217.      * </p>
  218.      * @param latitude ground point latitude
  219.      * @param longitude ground point longitude
  220.      * @return interpolated elevation (m)
  221.      */
  222.     double interpolateElevation(double latitude, double longitude);

  223.     /** Find the intersection of a line-of-sight and a Digital Elevation Model cell.
  224.      * <p>
  225.      * Beware that for continuity reasons, the point argument in {@code cellIntersection} is normalized
  226.      * with respect to other points used by the caller. This implies that the longitude may be
  227.      * outside of the [-π ; +π] interval (or the [0 ; 2π] interval, depending on the DEM). In particular,
  228.      * when a Line Of Sight crosses the antimeridian at  ±π longitude, the library may call the
  229.      * {@code cellIntersection} method with a point having a longitude of -π-ε to ensure this continuity.
  230.      * As tiles are stored with longitude clipped to a some DEM specific interval (either  [-π ; +π] or [0 ; 2π]),
  231.      * implementations MUST take care to clip the input point back to the tile interval using
  232.      * {@link org.hipparchus.util.MathUtils#normalizeAngle(double, double) MathUtils.normalizeAngle(p.getLongitude(),
  233.      * someLongitudeWithinTheTile)}. The output point normalization should also be made consistent with
  234.      * the current tile.
  235.      * </p>
  236.      * @param p point on the line (beware its longitude is <em>not</em> normalized with respect to tile)
  237.      * @param los line-of-sight, in the topocentric frame (East, North, Zenith) of the point,
  238.      * scaled to match radians in the horizontal plane and meters along the vertical axis
  239.      * @param latitudeIndex latitude index of the Digital Elevation Model cell
  240.      * @param longitudeIndex longitude index of the Digital Elevation Model cell
  241.      * @return point corresponding to line-of-sight crossing the Digital Elevation Model surface
  242.      * if it lies within the cell, null otherwise
  243.      */
  244.     NormalizedGeodeticPoint cellIntersection(NormalizedGeodeticPoint p, Vector3D los,
  245.                                              int latitudeIndex, int longitudeIndex);

  246.     /** Check if a tile covers a ground point.
  247.      * @param latitude ground point latitude
  248.      * @param longitude ground point longitude
  249.      * @return location of the ground point with respect to tile
  250.      */
  251.     Location getLocation(double latitude, double longitude);

  252. }