1 /* Copyright 2013-2019 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.utils.NormalizedGeodeticPoint;
22
23 /** Interface representing a raster tile.
24 * <p>
25 * The elevations are considered to be at the <em>center</em> of each cells.
26 * The minimum latitude and longitude hence correspond to the <em>center</em>
27 * of the most South-West cell, and the maximum latitude and longitude
28 * correspond to the <em>center</em> of the most North-East cell.
29 * </p>
30 * @author Luc Maisonobe
31 * @author Guylaine Prat
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 */
117 void tileUpdateCompleted();
118
119 /** Get minimum latitude of grid interpolation points.
120 * @return minimum latitude of grid interpolation points (rad)
121 * (latitude of the center of the cells of South row)
122 */
123 double getMinimumLatitude();
124
125 /** Get the latitude at some index.
126 * @param latitudeIndex latitude index
127 * @return latitude at the specified index (rad)
128 * (latitude of the center of the cells of specified row)
129 */
130 double getLatitudeAtIndex(int latitudeIndex);
131
132 /** Get maximum latitude.
133 * <p>
134 * Beware that as a point at maximum latitude is the northernmost
135 * one of the grid, it doesn't have a northwards neighbor and
136 * therefore calling {@link #getLocation(double, double) getLocation}
137 * on such a latitude will return either {@link Location#NORTH_WEST},
138 * {@link Location#NORTH} or {@link Location#NORTH_EAST}, but can
139 * <em>never</em> return {@link Location#HAS_INTERPOLATION_NEIGHBORS}!
140 * </p>
141 * @return maximum latitude (rad)
142 * (latitude of the center of the cells of North row)
143 */
144 double getMaximumLatitude();
145
146 /** Get minimum longitude.
147 * @return minimum longitude (rad)
148 * (longitude of the center of the cells of West column)
149 */
150 double getMinimumLongitude();
151
152 /** Get the longitude at some index.
153 * @param longitudeIndex longitude index
154 * @return longitude at the specified index (rad)
155 * (longitude of the center of the cells of specified column)
156 */
157 double getLongitudeAtIndex(int longitudeIndex);
158
159 /** Get maximum longitude.
160 * <p>
161 * Beware that as a point at maximum longitude is the easternmost
162 * one of the grid, it doesn't have an eastwards neighbor and
163 * therefore calling {@link #getLocation(double, double) getLocation}
164 * on such a longitude will return either {@link Location#SOUTH_EAST},
165 * {@link Location#EAST} or {@link Location#NORTH_EAST}, but can
166 * <em>never</em> return {@link Location#HAS_INTERPOLATION_NEIGHBORS}!
167 * </p>
168 * @return maximum longitude (rad)
169 * (longitude of the center of the cells of East column)
170 */
171 double getMaximumLongitude();
172
173 /** Get step in latitude (size of one raster element).
174 * @return step in latitude (rad)
175 */
176 double getLatitudeStep();
177
178 /** Get step in longitude (size of one raster element).
179 * @return step in longitude (rad)
180 */
181 double getLongitudeStep();
182
183 /** Get number of latitude rows.
184 * @return number of latitude rows
185 */
186 int getLatitudeRows();
187
188 /** Get number of longitude columns.
189 * @return number of longitude columns
190 */
191 int getLongitudeColumns();
192
193 /** Get the floor latitude index of a point.
194 * <p>
195 * The specified latitude is always between index and index+1.
196 * </p>
197 * @param latitude geodetic latitude
198 * @return floor latitude index (it may lie outside of the tile!)
199 */
200 int getFloorLatitudeIndex(double latitude);
201
202 /** Get the floor longitude index of a point.
203 * <p>
204 * The specified longitude is always between index and index+1.
205 * </p>
206 * @param longitude geodetic longitude
207 * @return floor longitude index (it may lie outside of the tile!)
208 */
209 int getFloorLongitudeIndex(double longitude);
210
211 /** Get the minimum elevation in the tile.
212 * @return minimum elevation in the tile (m)
213 */
214 double getMinElevation();
215
216 /** Get the latitude index of min elevation.
217 * @return latitude index of min elevation*/
218 int getMinElevationLatitudeIndex();
219
220 /** Get the longitude index of min elevation.
221 * @return longitude index of min elevation*/
222 int getMinElevationLongitudeIndex();
223
224 /** Get the maximum elevation in the tile.
225 * @return maximum elevation in the tile (m)
226 */
227 double getMaxElevation();
228
229 /** Get the latitude index of max elevation.
230 * @return latitude index of max elevation*/
231 int getMaxElevationLatitudeIndex();
232
233 /** Get the longitude index of max elevation.
234 * @return longitude index of max elevation*/
235 int getMaxElevationLongitudeIndex();
236
237 /** Get the elevation of an exact grid point.
238 * @param latitudeIndex grid point index along latitude
239 * @param longitudeIndex grid point index along longitude
240 * @return elevation at grid point (m)
241 */
242 double getElevationAtIndices(int latitudeIndex, int longitudeIndex);
243
244 /** Interpolate elevation.
245 * <p>
246 * In order to cope with numerical accuracy issues when computing
247 * points at tile boundary, a slight tolerance (typically 1/8 cell)
248 * around the tile is allowed. Elevation can therefore be interpolated
249 * (really extrapolated in this case) even for points slightly overshooting
250 * tile boundaries, using the closest tile cell. Attempting to interpolate
251 * too far from the tile will trigger an exception.
252 * </p>
253 * @param latitude ground point latitude
254 * @param longitude ground point longitude
255 * @return interpolated elevation (m)
256 */
257 double interpolateElevation(double latitude, double longitude);
258
259 /** Find the intersection of a line-of-sight and a Digital Elevation Model cell.
260 * @param p point on the line
261 * @param los line-of-sight, in the topocentric frame (East, North, Zenith) of the point,
262 * scaled to match radians in the horizontal plane and meters along the vertical axis
263 * @param latitudeIndex latitude index of the Digital Elevation Model cell
264 * @param longitudeIndex longitude index of the Digital Elevation Model cell
265 * @return point corresponding to line-of-sight crossing the Digital Elevation Model surface
266 * if it lies within the cell, null otherwise
267 */
268 NormalizedGeodeticPoint cellIntersection(GeodeticPoint p, Vector3D los,
269 int latitudeIndex, int longitudeIndex);
270
271 /** Check if a tile covers a ground point.
272 * @param latitude ground point latitude
273 * @param longitude ground point longitude
274 * @return location of the ground point with respect to tile
275 */
276 Location getLocation(double latitude, double longitude);
277
278 }