From 0efb1aa80bc714bfdab477b0ea09cc985784162c Mon Sep 17 00:00:00 2001 From: Luc Maisonobe <luc@orekit.org> Date: Wed, 20 Feb 2019 18:22:05 +0100 Subject: [PATCH] Improved robustness of recovery algorithm when refining returns null. Direct location is performed in two phases, with a first intersection being computed without corrections, then correction are applied and the first solution is "refined". It was expected that the DEM cell did not change there. Unfortunately, sometimes the refining did not find a result in the same DEM cell. This was a very rare occurrence, and was detected first on very ... rugged areas like mountains. Now, when this rare event is detected, we restart a full-blown intersection but starting from a point just after the exit of the failing cell, when LOS is still above DEM and we prevent the algorithm to find solutions backward (i.e. we prevent it from finding the previous solution again and looping infinitely). --- .../duvenhage/DuvenhageAlgorithm.java | 175 +++++++++++------- .../rugged/errors/DumpReplayerTest.java | 6 +- .../replay/replay-direct-loc-Issue376-01.txt | 10 +- .../replay/replay-direct-loc-Issue376-02.txt | 8 +- .../replay/replay-direct-loc-Issue376-03.txt | 8 +- 5 files changed, 123 insertions(+), 84 deletions(-) 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 70096451..ba6e1b8e 100644 --- a/src/main/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithm.java +++ b/src/main/java/org/orekit/rugged/intersection/duvenhage/DuvenhageAlgorithm.java @@ -44,9 +44,12 @@ public class DuvenhageAlgorithm implements IntersectionAlgorithm { /** Step size when skipping from one tile to a neighbor one, in meters. */ private static final double STEP = 0.01; - /** Nb time cell intersection (with DEM) performed for null intersection: means that infinite loop. + /** Maximum number of attempts to refine intersection. + * <p> + * This parameter is intended to prevent infinite loops. + * </p> * @since 2.1 */ - private static final int NB_TIME_CELL_INTERSECTION = 100; + private static final int MAX_REFINING_ATTEMPTS = 100; /** Cache for DEM tiles. */ private final TilesCache<MinMaxTreeTile> cache; @@ -91,9 +94,31 @@ public class DuvenhageAlgorithm implements IntersectionAlgorithm { final Vector3D entryP = ellipsoid.pointAtAltitude(position, los, hMax + STEP); if (Vector3D.dotProduct(entryP.subtract(position), los) < 0) { // the entry point is behind spacecraft! - throw new RuggedException(RuggedMessages.DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT); + + // let's see if at least we are above DEM + try { + final NormalizedGeodeticPoint positionGP = + ellipsoid.transform(position, ellipsoid.getBodyFrame(), null, tile.getMinimumLongitude()); + final double elevationAtPosition = tile.interpolateElevation(positionGP.getLatitude(), positionGP.getLongitude()); + if (positionGP.getAltitude() >= elevationAtPosition) { + // we can use the current position as the entry point + current = positionGP; + } else { + current = null; + } + } catch (RuggedException re) { + if (re.getSpecifier() == RuggedMessages.OUT_OF_TILE_ANGLES) { + current = null; + } + } + + if (current == null) { + throw new RuggedException(RuggedMessages.DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT); + } + + } else { + current = ellipsoid.transform(entryP, ellipsoid.getBodyFrame(), null, tile.getMinimumLongitude()); } - current = ellipsoid.transform(entryP, ellipsoid.getBodyFrame(), null, tile.getMinimumLongitude()); if (tile.getLocation(current.getLatitude(), current.getLongitude()) != Tile.Location.HAS_INTERPOLATION_NEIGHBORS) { // the entry point is in another tile @@ -170,40 +195,35 @@ public class DuvenhageAlgorithm implements IntersectionAlgorithm { DumpManager.dumpAlgorithm(flatBody ? AlgorithmId.DUVENHAGE_FLAT_BODY : AlgorithmId.DUVENHAGE); - NormalizedGeodeticPoint currentGuess = closeGuess; - NormalizedGeodeticPoint foundIntersection = null; - if (flatBody) { // under the (bad) flat-body assumption, the reference point must remain // at DEM entry and exit, even if we already have a much better close guess :-( // this is in order to remain consistent with other systems - final Tile tile = cache.getTile(currentGuess.getLatitude(), currentGuess.getLongitude()); + final Tile tile = cache.getTile(closeGuess.getLatitude(), closeGuess.getLongitude()); final Vector3D exitP = ellipsoid.pointAtAltitude(position, los, tile.getMinElevation()); final Vector3D entryP = ellipsoid.pointAtAltitude(position, los, tile.getMaxElevation()); final NormalizedGeodeticPoint entry = ellipsoid.transform(entryP, ellipsoid.getBodyFrame(), null, tile.getMinimumLongitude()); - foundIntersection = tile.cellIntersection(entry, ellipsoid.convertLos(entryP, exitP), - tile.getFloorLatitudeIndex(currentGuess.getLatitude()), - tile.getFloorLongitudeIndex(currentGuess.getLongitude())); + return tile.cellIntersection(entry, ellipsoid.convertLos(entryP, exitP), + tile.getFloorLatitudeIndex(closeGuess.getLatitude()), + tile.getFloorLongitudeIndex(closeGuess.getLongitude())); - } else { // with a DEM - - // Keep the initial guess - final NormalizedGeodeticPoint currentGuess0 = closeGuess; + } else { + // regular curved ellipsoid model - // number of times cell intersection (with DEM) is performed for null intersection (used to avoid infinite loop) - int nbCall = 0; - // Shift for s to find the solution if foundIntersection is null - double deltaS = -1.; - // if the shifts in one way was not successful, try the other way - boolean secondChance = false; + NormalizedGeodeticPoint currentGuess = closeGuess; - while (foundIntersection == null && (nbCall < NB_TIME_CELL_INTERSECTION)) { + // normally, we should succeed at first attempt but in very rare cases + // we may loose the intersection (typically because some corrections introduced + // between the first intersection and the refining have slightly changed the + // relative geometry between Digital Elevation Model and Line Of Sight). + // In these rare cases, we have to recover a new intersection + for (int i = 0; i < MAX_REFINING_ATTEMPTS; ++i) { - final Vector3D delta = ellipsoid.transform(currentGuess).subtract(position); - final double s = Vector3D.dotProduct(delta, los) / los.getNormSq(); - final GeodeticPoint projected = ellipsoid.transform(new Vector3D(1, position, s, los), - ellipsoid.getBodyFrame(), null); + final Vector3D delta = ellipsoid.transform(currentGuess).subtract(position); + final double s = Vector3D.dotProduct(delta, los) / los.getNormSq(); + final Vector3D projectedP = new Vector3D(1, position, s, los); + final GeodeticPoint projected = ellipsoid.transform(projectedP, ellipsoid.getBodyFrame(), null); final NormalizedGeodeticPoint normalizedProjected = new NormalizedGeodeticPoint(projected.getLatitude(), projected.getLongitude(), @@ -211,38 +231,47 @@ public class DuvenhageAlgorithm implements IntersectionAlgorithm { currentGuess.getLongitude()); final Tile tile = cache.getTile(normalizedProjected.getLatitude(), normalizedProjected.getLongitude()); - foundIntersection = tile.cellIntersection(normalizedProjected, - ellipsoid.convertLos(normalizedProjected, los), - tile.getFloorLatitudeIndex(normalizedProjected.getLatitude()), - tile.getFloorLongitudeIndex(normalizedProjected.getLongitude())); - - // For extremely rare case : the cell intersection gave no results ... - // We use as a new guess a slightly modified projected geodetic point (which is on the LOS line) - if (foundIntersection == null) { - final double shiftedS = s + deltaS; - final GeodeticPoint currentGuessGP = ellipsoid.transform(new Vector3D(1, position, shiftedS, los), - ellipsoid.getBodyFrame(), null); + final Vector3D topoLOS = ellipsoid.convertLos(normalizedProjected, los); + final int iLat = tile.getFloorLatitudeIndex(normalizedProjected.getLatitude()); + final int iLon = tile.getFloorLongitudeIndex(normalizedProjected.getLongitude()); + final NormalizedGeodeticPoint foundIntersection = tile.cellIntersection(normalizedProjected, topoLOS, iLat, iLon); + + if (foundIntersection != null) { + // nominal case, we were able to refine the intersection + return foundIntersection; + } else { + // extremely rare case: we have lost the intersection + + // safety check, which should never be triggered... + if (currentGuess.getAltitude() < + tile.interpolateElevation(currentGuess.getLatitude(), currentGuess.getLongitude())) { + // this should never happen, we are below the DEM + throw RuggedException.createInternalError(null); + } + + // find a start point for new search, leaving the current cell behind + final double cellBoundaryLatitude = tile.getLatitudeAtIndex(topoLOS.getY() <= 0 ? iLat : iLat + 1); + final double cellBoundaryLongitude = tile.getLongitudeAtIndex(topoLOS.getX() <= 0 ? iLon : iLon + 1); + final Vector3D cellExit = new Vector3D(1, selectClosest(latitudeCrossing(ellipsoid, projectedP, los, cellBoundaryLatitude, projectedP), + longitudeCrossing(ellipsoid, projectedP, los, cellBoundaryLongitude, projectedP), + projectedP), + STEP, los); + + // We recompute fully a new guess, starting from the point after current cell + final GeodeticPoint currentGuessGP = intersection(ellipsoid, cellExit, los); currentGuess = new NormalizedGeodeticPoint(currentGuessGP.getLatitude(), currentGuessGP.getLongitude(), currentGuessGP.getAltitude(), projected.getLongitude()); - // to avoid infinite loop ... - nbCall++; - - // if impossible to find a solution with deltaS = -1 - // we start a new search with deltaS = +1 - if (nbCall == NB_TIME_CELL_INTERSECTION && !secondChance) { - currentGuess = currentGuess0; - deltaS = 1.; - nbCall = 0; - secondChance = true; // to avoid infinite loop if second chance does not work ! - } // end if nbCall == NB_TIME_CELL_INTERSECTION - } // end if foundIntersection = null - } // end while foundIntersection = null + } + + } + + // no intersection found + return null; } // end test on flatbody - return foundIntersection; } /** {@inheritDoc} */ @@ -487,24 +516,26 @@ public class DuvenhageAlgorithm implements IntersectionAlgorithm { if (gp != null) { // improve the point, by projecting it back on the 3D line, fixing the small body curvature at cell level - final Vector3D delta = ellipsoid.transform(gp).subtract(position); - final double s = Vector3D.dotProduct(delta, los) / los.getNormSq(); - final GeodeticPoint projected = ellipsoid.transform(new Vector3D(1, position, s, los), - ellipsoid.getBodyFrame(), null); - final NormalizedGeodeticPoint normalizedProjected = new NormalizedGeodeticPoint(projected.getLatitude(), - projected.getLongitude(), - projected.getAltitude(), - gp.getLongitude()); - final NormalizedGeodeticPoint gpImproved = tile.cellIntersection(normalizedProjected, - ellipsoid.convertLos(normalizedProjected, los), - i, j); - - if (gpImproved != null) { - final Vector3D point = ellipsoid.transform(gpImproved); - final double dot = Vector3D.dotProduct(point.subtract(position), los); - if (dot < intersectionDot) { - intersectionGP = gpImproved; - intersectionDot = dot; + final Vector3D delta = ellipsoid.transform(gp).subtract(position); + final double s = Vector3D.dotProduct(delta, los) / los.getNormSq(); + if (s > 0) { + final GeodeticPoint projected = ellipsoid.transform(new Vector3D(1, position, s, los), + ellipsoid.getBodyFrame(), null); + final NormalizedGeodeticPoint normalizedProjected = new NormalizedGeodeticPoint(projected.getLatitude(), + projected.getLongitude(), + projected.getAltitude(), + gp.getLongitude()); + final NormalizedGeodeticPoint gpImproved = tile.cellIntersection(normalizedProjected, + ellipsoid.convertLos(normalizedProjected, los), + i, j); + + if (gpImproved != null) { + final Vector3D point = ellipsoid.transform(gpImproved); + final double dot = Vector3D.dotProduct(point.subtract(position), los); + if (dot < intersectionDot) { + intersectionGP = gpImproved; + intersectionDot = dot; + } } } @@ -621,7 +652,7 @@ public class DuvenhageAlgorithm implements IntersectionAlgorithm { * @param latitude latitude with respect to ellipsoid * @param closeReference reference point used to select the closest solution * when there are two points at the desired latitude along the line - * @return point at altitude, or closeReference if no such point can be found + * @return point at latitude, or closeReference if no such point can be found */ private Vector3D latitudeCrossing(final ExtendedEllipsoid ellipsoid, final Vector3D position, final Vector3D los, @@ -639,8 +670,8 @@ public class DuvenhageAlgorithm implements IntersectionAlgorithm { * @param los pixel line-of-sight, not necessarily normalized (in body frame) * @param longitude longitude with respect to ellipsoid * @param closeReference reference point used to select the closest solution - * when there are two points at the desired latitude along the line - * @return point at altitude, or closeReference if no such point can be found + * when there are two points at the desired longitude along the line + * @return point at longitude, or closeReference if no such point can be found */ private Vector3D longitudeCrossing(final ExtendedEllipsoid ellipsoid, final Vector3D position, final Vector3D los, diff --git a/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java b/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java index 9b2bca87..85b06b8b 100644 --- a/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java +++ b/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java @@ -261,7 +261,7 @@ public class DumpReplayerTest { } } - + @Test public void testDirectLocIssue376_01() throws URISyntaxException, IOException { @@ -281,7 +281,7 @@ public class DumpReplayerTest { rugged.getEllipsoid().transform(replayedGP)); Assert.assertEquals(0.0, distance, 1.0e-8); } - + @Test public void testDirectLocIssue376_02() throws URISyntaxException, IOException { @@ -301,7 +301,7 @@ public class DumpReplayerTest { rugged.getEllipsoid().transform(replayedGP)); Assert.assertEquals(0.0, distance, 1.0e-8); } - + @Test public void testDirectLocIssue376_03() throws URISyntaxException, IOException { diff --git a/src/test/resources/replay/replay-direct-loc-Issue376-01.txt b/src/test/resources/replay/replay-direct-loc-Issue376-01.txt index 89e6aee2..8d3a0975 100644 --- a/src/test/resources/replay/replay-direct-loc-Issue376-01.txt +++ b/src/test/resources/replay/replay-direct-loc-Issue376-01.txt @@ -7,8 +7,8 @@ span: minDate 2018-11-17T09:28:09.75815400000000Z maxDate 2018-11-17T09:28:24.37 transform: index 3749 body r -1.582419730578572e-01 -8.877875020391763e-04 1.556906340657658e-04 -9.873999521756794e-01 Ω -1.314379576583188e-07 1.929883563714465e-09 -7.292103298515694e-05 ΩDot -1.238204383721699e-16 -4.429578390177184e-17 2.220234885205757e-19 spacecraft p -2.043780763621181e+06 2.649055676516346e+06 -6.230074460056063e+06 v 8.500193464365886e+03 -1.120156363674237e+04 -7.562611889558547e+03 a -7.774014494482032e+02 -2.165448216679694e+02 2.038618372832540e+02 r -4.471787778551135e-01 -2.556359378108412e-01 7.875656535717214e-01 3.382628404801900e-01 Ω 1.895876683374440e-03 6.208707436271533e-04 6.748857995964048e-04 ΩDot 2.850236048816703e-06 1.374797997377696e-04 -1.976120196823438e-05 algorithm: DUVENHAGE ellipsoid: ae 6.378137000000000e+06 f 3.352810664747481e-03 frame ITRF_CIO_CONV_2010_SIMPLE_EOP -DEM tile: t0 latMin 7.854054356026650e-01 latStep 1.454441043328608e-05 latRows 6000 lonMin 1.745401974046496e-01 lonStep 1.454441043328608e-05 lonCols 6000 -DEM cell: t0 latIndex 1051 lonIndex 4137 elevation 1.309400956268308e+01 +DEM tile: t0 latMin 7.854054356026650e-01 latStep 1.454441043328608e-05 latRows 1850 lonMin 1.745401974046496e-01 lonStep 1.454441043328608e-05 lonCols 2950 +DEM cell: t0 latIndex 1051 lonIndex 2937 elevation 1.309400956268308e+01 DEM cell: t0 latIndex 1809 lonIndex 653 elevation 3.915338283287048e+03 DEM cell: t0 latIndex 1743 lonIndex 2713 elevation 3.241641450760227e+03 DEM cell: t0 latIndex 1744 lonIndex 2713 elevation 3.183645801580853e+03 @@ -42,4 +42,8 @@ DEM cell: t0 latIndex 1750 lonIndex 2691 elevation 2.046708412363307e+03 DEM cell: t0 latIndex 1751 lonIndex 2691 elevation 1.988712685290527e+03 DEM cell: t0 latIndex 1752 lonIndex 2690 elevation 1.767717871236589e+03 DEM cell: t0 latIndex 1752 lonIndex 2691 elevation 1.932716958217748e+03 -direct location result: latitude 8.108743132084988e-01 longitude 2.136723329659456e-01 elevation 2.015454838793325e+03 +DEM cell: t0 latIndex 1751 lonIndex 2689 elevation 1.977714519950358e+03 +DEM cell: t0 latIndex 1752 lonIndex 2689 elevation 1.812718784255430e+03 +DEM cell: t0 latIndex 1753 lonIndex 2689 elevation 1.752723048560503e+03 +DEM cell: t0 latIndex 1753 lonIndex 2690 elevation 1.771722139852736e+03 +direct location result: latitude 8.108879611499973e-01 longitude 2.136511932240912e-01 elevation 1.806659334316842e+03 diff --git a/src/test/resources/replay/replay-direct-loc-Issue376-02.txt b/src/test/resources/replay/replay-direct-loc-Issue376-02.txt index 72733be7..193745fd 100644 --- a/src/test/resources/replay/replay-direct-loc-Issue376-02.txt +++ b/src/test/resources/replay/replay-direct-loc-Issue376-02.txt @@ -7,8 +7,8 @@ span: minDate 2018-11-17T09:28:09.75815400000000Z maxDate 2018-11-17T09:28:24.37 transform: index 5248 body r -1.582959385747423e-01 -8.877789928041023e-04 1.557391550098440e-04 -9.873913020806478e-01 Ω -1.314379578439253e-07 1.929883497315641e-09 -7.292103298515672e-05 ΩDot -1.238198063406674e-16 -4.429504278953000e-17 2.220223692809437e-19 spacecraft p -2.031142024066962e+06 2.632378682422574e+06 -6.241283006704280e+06 v 8.397013991525502e+03 -1.122240538848754e+04 -7.476888804772309e+03 a -5.680029219465155e+02 -2.953217064872529e+02 9.484900057803327e+01 r -4.473594211185816e-01 -2.560156449934148e-01 7.879614096264105e-01 3.368120466886735e-01 Ω 1.874199110824172e-03 6.297218887138226e-04 6.941311311658171e-04 ΩDot 2.110863271348145e-05 1.094333236463635e-04 -6.188132051280828e-06 algorithm: DUVENHAGE ellipsoid: ae 6.378137000000000e+06 f 3.352810664747481e-03 frame ITRF_CIO_CONV_2010_SIMPLE_EOP -DEM tile: t0 latMin 7.854054356026650e-01 latStep 1.454441043328608e-05 latRows 6000 lonMin 1.745401974046496e-01 lonStep 1.454441043328608e-05 lonCols 6000 -DEM cell: t0 latIndex 1051 lonIndex 4137 elevation 1.309400956268308e+01 +DEM tile: t0 latMin 7.854054356026650e-01 latStep 1.454441043328608e-05 latRows 1850 lonMin 1.745401974046496e-01 lonStep 1.454441043328608e-05 lonCols 2950 +DEM cell: t0 latIndex 1051 lonIndex 2937 elevation 1.309400956268308e+01 DEM cell: t0 latIndex 1809 lonIndex 653 elevation 3.915338283287048e+03 DEM cell: t0 latIndex 1611 lonIndex 2905 elevation 2.683570229905023e+03 DEM cell: t0 latIndex 1612 lonIndex 2905 elevation 2.659575158110089e+03 @@ -45,4 +45,6 @@ DEM cell: t0 latIndex 1597 lonIndex 2866 elevation 2.091603812329271e+03 DEM cell: t0 latIndex 1598 lonIndex 2866 elevation 2.054608623253123e+03 DEM cell: t0 latIndex 1599 lonIndex 2865 elevation 1.847616058349609e+03 DEM cell: t0 latIndex 1599 lonIndex 2866 elevation 1.838613434176975e+03 -direct location result: latitude 8.086486919600299e-01 longitude 2.162109977595155e-01 elevation 2.040458228825512e+03 +DEM cell: t0 latIndex 1598 lonIndex 2864 elevation 1.985613877612813e+03 +DEM cell: t0 latIndex 1599 lonIndex 2864 elevation 1.872618682522244e+03 +direct location result: latitude 8.086569515781713e-01 longitude 2.161986944259714e-01 elevation 1.912154442728379e+03 diff --git a/src/test/resources/replay/replay-direct-loc-Issue376-03.txt b/src/test/resources/replay/replay-direct-loc-Issue376-03.txt index b6b1a0b7..7853cc5c 100644 --- a/src/test/resources/replay/replay-direct-loc-Issue376-03.txt +++ b/src/test/resources/replay/replay-direct-loc-Issue376-03.txt @@ -9,8 +9,8 @@ span: minDate 2018-11-17T09:28:09.75815400000000Z maxDate 2018-11-17T09:28:24.37 transform: index 9366 body r -1.584446506666181e-01 -8.881578177468675e-04 1.564888965877765e-04 -9.873674490087516e-01 Ω -1.314379583538120e-07 1.929883314912744e-09 -7.292103298515580e-05 ΩDot -1.238180701885198e-16 -4.429300681876970e-17 2.220189200053709e-19 spacecraft p -1.997175450486062e+06 2.586441579861389e+06 -6.271423934028421e+06 v 8.113280864301501e+03 -1.114024972785023e+04 -7.189075879755639e+03 a -1.053681313757033e+03 -1.503500666930414e+03 -2.459309668330822e+02 r -4.479168627946637e-01 -2.570042078686272e-01 7.890099484043995e-01 3.328402356700476e-01 Ω 1.817311260304385e-03 6.600167203271428e-04 7.119941113907730e-04 ΩDot 4.061126512029496e-05 1.694535855585867e-04 2.046888666103640e-04 algorithm: DUVENHAGE ellipsoid: ae 6.378137000000000e+06 f 3.352810664747481e-03 frame ITRF_CIO_CONV_2010_SIMPLE_EOP -DEM tile: t0 latMin 7.854054356026650e-01 latStep 1.454441043328608e-05 latRows 6000 lonMin 1.745401974046496e-01 lonStep 1.454441043328608e-05 lonCols 6000 -DEM cell: t0 latIndex 1051 lonIndex 4137 elevation 1.309400956268308e+01 +DEM tile: t0 latMin 7.854054356026650e-01 latStep 1.454441043328608e-05 latRows 1850 lonMin 1.745401974046496e-01 lonStep 1.454441043328608e-05 lonCols 2950 +DEM cell: t0 latIndex 1051 lonIndex 2937 elevation 1.309400956268308e+01 DEM cell: t0 latIndex 1809 lonIndex 653 elevation 3.915338283287048e+03 DEM cell: t0 latIndex 1248 lonIndex 2816 elevation 1.597661494047886e+03 DEM cell: t0 latIndex 1249 lonIndex 2816 elevation 1.603667936647203e+03 @@ -67,7 +67,9 @@ DEM cell: t0 latIndex 1242 lonIndex 2787 elevation 1.053714592147954e+03 DEM cell: t0 latIndex 1243 lonIndex 2787 elevation 1.076721007775370e+03 direct location result: latitude 8.034857669188987e-01 longitude 2.149854849334069e-01 elevation 6.876149051242718e+02 direct location: date 2018-11-17T09:28:19.12459483660332Z position 0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00 los 1.674948750587419e-03 -1.457123926920459e-02 9.998924309808744e-01 lightTime false aberration false refraction false -direct location result: latitude 8.034823539452234e-01 longitude 2.149911720557955e-01 elevation 7.409412497822065e+02 +DEM cell: t0 latIndex 1243 lonIndex 2779 elevation 6.157463116992526e+02 +DEM cell: t0 latIndex 1244 lonIndex 2779 elevation 5.807527198861440e+02 +direct location result: latitude 8.034854772265824e-01 longitude 2.149864448298378e-01 elevation 6.912515480966839e+02 direct location: date 2018-11-17T09:28:19.12459483660332Z position 0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00 los 1.674917457576505e-03 -1.457437451670205e-02 9.998923853390211e-01 lightTime false aberration false refraction false direct location result: latitude 8.034781401708480e-01 longitude 2.149980710325160e-01 elevation 8.070092894686161e+02 direct location: date 2018-11-17T09:28:19.12459483660332Z position 0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00 los 1.674886170278741e-03 -1.457750977938711e-02 9.998923396871029e-01 lightTime false aberration false refraction false -- GitLab