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 }