1   /* Copyright 2013-2017 CS Systèmes d'Information
2    * Licensed to CS Systèmes d'Information (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  
19  import org.hipparchus.geometry.euclidean.threed.Vector3D;
20  import org.orekit.bodies.GeodeticPoint;
21  import org.orekit.rugged.errors.RuggedException;
22  import org.orekit.rugged.utils.NormalizedGeodeticPoint;
23  
24  /** Interface representing a raster tile.
25   * <p>
26   * The elevations are considered to be at the <em>center</em> of each cells.
27   * The minimum latitude and longitude hence correspond to the <em>center</em>
28   * of the most South-West cell, and the maximum latitude and longitude
29   * correspond to the <em>center</em> of the most North-East cell.
30   * </p>
31   * @author Luc Maisonobe
32   */
33  public interface Tile extends UpdatableTile {
34  
35      /** Enumerate for point location with respect to the interpolation grid of a tile.
36       * <p>
37       * Elevations in a tile are interpolated using the four neighboring points
38       * in a grid: (i, j), (i+1, j), (i, j+1), (i+1), (j+1). This implies that a point
39       * can be interpolated only if the elevation for these four points is available
40       * in the tile. A consequence is that a point in the northernmost row (resp.
41       * easternmost column) miss neighboring points at row j+1 (resp. neighboring points
42       * at column i+1) and therefore cannot be interpolated.
43       * </p>
44       * <p>
45       * This enumerate represent the position of a point taking this off-by-one property
46       * into account, the value {@link #HAS_INTERPOLATION_NEIGHBORS} correspond to points that
47       * do have the necessary four neightbors, whereas the other values correspond to points
48       * that are either completely outside of the tile or within the tile but in either the
49       * northernmost row or easternmost column.
50       * </p>
51       */
52      enum Location {
53  
54          /** Location for points out of tile interpolation grid, in the South-West corner direction. */
55          SOUTH_WEST,
56  
57          /** Location for points out of tile interpolation grid, in the West edge direction. */
58          WEST,
59  
60          /** Location for points out of tile interpolation grid, in the North-West corner 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_WEST,
67  
68          /** Location for points out of tile interpolation grid, in the North edge direction.
69           * <p>
70           * The point may still be in the tile, but in the northernmost row thus missing required
71           * interpolation points.
72           * </p>
73           */
74          NORTH,
75  
76          /** Location for points out of tile interpolation grid, in the North-East corner direction.
77           * <p>
78           * The point may still be in the tile, but either in the northernmost row or in the
79           * easternmost column thus missing required interpolation points.
80           * </p>
81           */
82          NORTH_EAST,
83  
84          /** Location for points out of tile interpolation grid, in the East edge direction.
85           * <p>
86           * The point may still be in the tile, but in the easternmost column thus missing required
87           * interpolation points.
88           * </p>
89           */
90          EAST,
91  
92          /** Location for points out of tile interpolation grid, in the South-East corner direction.
93           * <p>
94           * The point may still be in the tile, but in the easternmost column thus missing required
95           * interpolation points.
96           * </p>
97           */
98          SOUTH_EAST,
99  
100         /** Location for points out of tile interpolation grid, in the South edge direction. */
101         SOUTH,
102 
103         /** Location for points that do have interpolation neighbors.
104          * <p>
105          * The value corresponds to points that can be interpolated using their four
106          * neighboring points in the grid at indices (i, j), (i+1, j), (i, j+1), (i+1),
107          * (j+1). This implies that these points are neither in the northernmost latitude
108          * row nor in the easternmost longitude column.
109          * </p>
110          */
111         HAS_INTERPOLATION_NEIGHBORS
112 
113     }
114 
115     /** Hook called at the end of tile update completion.
116      * @exception RuggedException if something wrong occurs
117      * (missing data ...)
118      */
119     void tileUpdateCompleted() throws RuggedException;
120 
121     /** Get minimum latitude of grid interpolation points.
122      * @return minimum latitude of grid interpolation points
123      * (latitude of the center of the cells of South row)
124      */
125     double getMinimumLatitude();
126 
127     /** Get the latitude at some index.
128      * @param latitudeIndex latitude index
129      * @return latitude at the specified index
130      * (latitude of the center of the cells of specified row)
131      */
132     double getLatitudeAtIndex(int latitudeIndex);
133 
134     /** Get maximum latitude.
135      * <p>
136      * Beware that as a point at maximum latitude is the northernmost
137      * one of the grid, it doesn't have a northwards neighbor and
138      * therefore calling {@link #getLocation(double, double) getLocation}
139      * on such a latitude will return either {@link Location#NORTH_WEST},
140      * {@link Location#NORTH} or {@link Location#NORTH_EAST}, but can
141      * <em>never</em> return {@link Location#HAS_INTERPOLATION_NEIGHBORS}!
142      * </p>
143      * @return maximum latitude
144      * (latitude of the center of the cells of North row)
145      */
146     double getMaximumLatitude();
147 
148     /** Get minimum longitude.
149      * @return minimum longitude
150      * (longitude of the center of the cells of West column)
151      */
152     double getMinimumLongitude();
153 
154     /** Get the longitude at some index.
155      * @param longitudeIndex longitude index
156      * @return longitude at the specified index
157      * (longitude of the center of the cells of specified column)
158      */
159     double getLongitudeAtIndex(int longitudeIndex);
160 
161     /** Get maximum longitude.
162      * <p>
163      * Beware that as a point at maximum longitude is the easternmost
164      * one of the grid, it doesn't have an eastwards neighbor and
165      * therefore calling {@link #getLocation(double, double) getLocation}
166      * on such a longitude will return either {@link Location#SOUTH_EAST},
167      * {@link Location#EAST} or {@link Location#NORTH_EAST}, but can
168      * <em>never</em> return {@link Location#HAS_INTERPOLATION_NEIGHBORS}!
169      * </p>
170      * @return maximum longitude
171      * (longitude of the center of the cells of East column)
172      */
173     double getMaximumLongitude();
174 
175     /** Get step in latitude (size of one raster element).
176      * @return step in latitude
177      */
178     double getLatitudeStep();
179 
180     /** Get step in longitude (size of one raster element).
181      * @return step in longitude
182      */
183     double getLongitudeStep();
184 
185     /** Get number of latitude rows.
186      * @return number of latitude rows
187      */
188     int getLatitudeRows();
189 
190     /** Get number of longitude columns.
191      * @return number of longitude columns
192      */
193     int getLongitudeColumns();
194 
195     /** Get the floor latitude index of a point.
196      * <p>
197      * The specified latitude is always between index and index+1.
198      * </p>
199      * @param latitude geodetic latitude
200      * @return floor latitude index (it may lie outside of the tile!)
201      */
202     int getFloorLatitudeIndex(double latitude);
203 
204     /** Get the floor longitude index of a point.
205      * <p>
206      * The specified longitude is always between index and index+1.
207      * </p>
208      * @param longitude geodetic longitude
209      * @return floor longitude index (it may lie outside of the tile!)
210      */
211     int getFloorLongitudeIndex(double longitude);
212 
213     /** Get the minimum elevation in the tile.
214      * @return minimum elevation in the tile
215      */
216     double getMinElevation();
217 
218     /** Get the latitude index of min elevation.
219      * @return latitude index of min elevation*/
220     int getMinElevationLatitudeIndex();
221 
222     /** Get the longitude index of min elevation.
223      * @return longitude index of min elevation*/
224     int getMinElevationLongitudeIndex();
225 
226    /** Get the maximum elevation in the tile.
227      * @return maximum elevation in the tile
228      */
229     double getMaxElevation();
230 
231     /** Get the latitude index of max elevation.
232      * @return latitude index of max elevation*/
233     int getMaxElevationLatitudeIndex();
234 
235     /** Get the longitude index of max elevation.
236      * @return longitude index of max elevation*/
237     int getMaxElevationLongitudeIndex();
238 
239     /** Get the elevation of an exact grid point.
240      * @param latitudeIndex grid point index along latitude
241      * @param longitudeIndex grid point index along longitude
242      * @return elevation at grid point
243      * @exception RuggedException if indices are out of bound
244      */
245     double getElevationAtIndices(int latitudeIndex, int longitudeIndex)
246         throws RuggedException;
247 
248     /** Interpolate elevation.
249      * <p>
250      * In order to cope with numerical accuracy issues when computing
251      * points at tile boundary, a slight tolerance (typically 1/8 cell)
252      * around the tile is allowed. Elevation can therefore be interpolated
253      * (really extrapolated in this case) even for points slightly overshooting
254      * tile boundaries, using the closest tile cell. Attempting to interpolate
255      * too far from the tile will trigger an exception.
256      * </p>
257      * @param latitude ground point latitude
258      * @param longitude ground point longitude
259      * @return interpolated elevation
260      * @exception RuggedException if point is farthest from the tile than the tolerance
261      */
262     double interpolateElevation(double latitude, double longitude)
263         throws RuggedException;
264 
265     /** Find the intersection of a line-of-sight and a Digital Elevation Model cell.
266      * @param p point on the line
267      * @param los line-of-sight, in the topocentric frame (East, North, Zenith) of the point,
268      * scaled to match radians in the horizontal plane and meters along the vertical axis
269      * @param latitudeIndex latitude index of the Digital Elevation Model cell
270      * @param longitudeIndex longitude index of the Digital Elevation Model cell
271      * @return point corresponding to line-of-sight crossing the Digital Elevation Model surface
272      * if it lies within the cell, null otherwise
273      * @exception RuggedException if intersection point cannot be computed
274      */
275     NormalizedGeodeticPoint cellIntersection(GeodeticPoint p, Vector3D los,
276                                               int latitudeIndex, int longitudeIndex)
277         throws RuggedException;
278 
279     /** Check if a tile covers a ground point.
280      * @param latitude ground point latitude
281      * @param longitude ground point longitude
282      * @return location of the ground point with respect to tile
283      */
284     Location getLocation(double latitude, double longitude);
285 
286 }