Skip to content
Snippets Groups Projects
Commit bfa8d8a7 authored by Luc Maisonobe's avatar Luc Maisonobe
Browse files

Fixed longitude normalization issues.

Fixes #388
parent 769ffb99
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,9 @@
</properties>
<body>
<release version="3.0" date="TBD" description="TBD">
<action dev="luc" type="update" issue="388">
Fixed longitude normalization issue with tiles.
</action>
<action dev="luc" type="update" issue="387">
Updated dependencies to Orekit 11.0.1 (and Hipparchus 2.0).
</action>
......
......@@ -16,12 +16,11 @@
*/
package org.orekit.rugged.raster;
import java.util.Arrays;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.Precision;
import java.util.Arrays;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.rugged.errors.DumpManager;
import org.orekit.rugged.errors.RuggedException;
import org.orekit.rugged.errors.RuggedMessages;
......@@ -302,7 +301,7 @@ public class SimpleTile implements Tile {
/** {@inheritDoc} */
@Override
public NormalizedGeodeticPoint cellIntersection(final GeodeticPoint p, final Vector3D los,
public NormalizedGeodeticPoint cellIntersection(final NormalizedGeodeticPoint p, final Vector3D los,
final int latitudeIndex, final int longitudeIndex) {
// ensure neighboring cells to not fall out of tile
......@@ -317,10 +316,16 @@ public class SimpleTile implements Tile {
final double z10 = getElevationAtIndices(iLat, jLong + 1);
final double z11 = getElevationAtIndices(iLat + 1, jLong + 1);
// normalize back to tile coordinates
final NormalizedGeodeticPoint tileP = new NormalizedGeodeticPoint(p.getLatitude(),
p.getLongitude(),
p.getAltitude(),
x00);
// line-of-sight coordinates at close points
final double dxA = (p.getLongitude() - x00) / longitudeStep;
final double dyA = (p.getLatitude() - y00) / latitudeStep;
final double dzA = p.getAltitude();
final double dxA = (tileP.getLongitude() - x00) / longitudeStep;
final double dyA = (tileP.getLatitude() - y00) / latitudeStep;
final double dzA = tileP.getAltitude();
final double dxB = dxA + los.getX() / longitudeStep;
final double dyB = dyA + los.getY() / latitudeStep;
final double dzB = dzA + los.getZ();
......@@ -368,8 +373,8 @@ public class SimpleTile implements Tile {
}
final NormalizedGeodeticPoint p1 = interpolate(t1, p, dxA, dyA, los, x00);
final NormalizedGeodeticPoint p2 = interpolate(t2, p, dxA, dyA, los, x00);
final NormalizedGeodeticPoint p1 = interpolate(t1, tileP, dxA, dyA, los, x00);
final NormalizedGeodeticPoint p2 = interpolate(t2, tileP, dxA, dyA, los, x00);
// select the first point along line-of-sight
if (p1 == null) {
......@@ -384,7 +389,7 @@ public class SimpleTile implements Tile {
/** Interpolate point along a line.
* @param t abscissa along the line
* @param p start point
* @param tileP start point, normalized to tile area
* @param dxP relative coordinate of the start point with respect to current cell
* @param dyP relative coordinate of the start point with respect to current cell
* @param los direction of the line-of-sight, in geodetic space
......@@ -392,7 +397,7 @@ public class SimpleTile implements Tile {
* be normalized between lc-π and lc+π
* @return interpolated point along the line
*/
private NormalizedGeodeticPoint interpolate(final double t, final GeodeticPoint p,
private NormalizedGeodeticPoint interpolate(final double t, final NormalizedGeodeticPoint tileP,
final double dxP, final double dyP,
final Vector3D los, final double centralLongitude) {
......@@ -403,9 +408,9 @@ public class SimpleTile implements Tile {
final double dx = dxP + t * los.getX() / longitudeStep;
final double dy = dyP + t * los.getY() / latitudeStep;
if (dx >= -TOLERANCE && dx <= 1 + TOLERANCE && dy >= -TOLERANCE && dy <= 1 + TOLERANCE) {
return new NormalizedGeodeticPoint(p.getLatitude() + t * los.getY(),
p.getLongitude() + t * los.getX(),
p.getAltitude() + t * los.getZ(),
return new NormalizedGeodeticPoint(tileP.getLatitude() + t * los.getY(),
tileP.getLongitude() + t * los.getX(),
tileP.getAltitude() + t * los.getZ(),
centralLongitude);
} else {
return null;
......
......@@ -17,7 +17,6 @@
package org.orekit.rugged.raster;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.rugged.utils.NormalizedGeodeticPoint;
/** Interface representing a raster tile.
......@@ -265,8 +264,8 @@ public interface Tile extends UpdatableTile {
* @return point corresponding to line-of-sight crossing the Digital Elevation Model surface
* if it lies within the cell, null otherwise
*/
NormalizedGeodeticPoint cellIntersection(GeodeticPoint p, Vector3D los,
int latitudeIndex, int longitudeIndex);
NormalizedGeodeticPoint cellIntersection(NormalizedGeodeticPoint p, Vector3D los,
int latitudeIndex, int longitudeIndex);
/** Check if a tile covers a ground point.
* @param latitude ground point latitude
......
......@@ -18,12 +18,14 @@ package org.orekit.rugged.raster;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.MathUtils;
import org.junit.Assert;
import org.junit.Test;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.rugged.errors.RuggedException;
import org.orekit.rugged.errors.RuggedMessages;
import org.orekit.rugged.raster.Tile.Location;
import org.orekit.rugged.utils.NormalizedGeodeticPoint;
public class SimpleTileTest {
......@@ -216,16 +218,44 @@ public class SimpleTileTest {
tile.setElevation(21, 14, 162.0);
tile.setElevation(21, 15, 95.0);
tile.tileUpdateCompleted();
GeodeticPoint gpA = new GeodeticPoint(tile.getLatitudeAtIndex(20) + 0.1 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.2 * tile.getLongitudeStep(),
300.0);
GeodeticPoint gpB = new GeodeticPoint(tile.getLatitudeAtIndex(20) + 0.7 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.9 * tile.getLongitudeStep(),
10.0);
GeodeticPoint gpIAB = tile.cellIntersection(gpA, los(gpA, gpB), 20, 14);
NormalizedGeodeticPoint gpA = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(20) + 0.1 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.2 * tile.getLongitudeStep(),
300.0, tile.getLongitudeAtIndex(14));
NormalizedGeodeticPoint gpB = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(20) + 0.7 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.9 * tile.getLongitudeStep(),
10.0, tile.getLongitudeAtIndex(14));
NormalizedGeodeticPoint gpIAB = tile.cellIntersection(gpA, los(gpA, gpB), 20, 14);
checkInLine(gpA, gpB, gpIAB);
checkOnTile(tile, gpIAB);
GeodeticPoint gpIBA = tile.cellIntersection(gpB, los(gpB, gpA), 20, 14);
NormalizedGeodeticPoint gpIBA = tile.cellIntersection(gpB, los(gpB, gpA), 20, 14);
checkInLine(gpA, gpB, gpIBA);
checkOnTile(tile, gpIBA);
Assert.assertEquals(gpIAB.getLatitude(), gpIBA.getLatitude(), 1.0e-10);
Assert.assertEquals(gpIAB.getLongitude(), gpIBA.getLongitude(), 1.0e-10);
Assert.assertEquals(gpIAB.getAltitude(), gpIBA.getAltitude(), 1.0e-10);
}
@Test
public void testCellIntersection2PiWrapping() {
SimpleTile tile = new SimpleTileFactory().createTile();
tile.setGeometry(0.0, 0.0, 0.025, 0.025, 50, 50);
tile.setElevation(20, 14, 91.0);
tile.setElevation(20, 15, 210.0);
tile.setElevation(21, 14, 162.0);
tile.setElevation(21, 15, 95.0);
tile.tileUpdateCompleted();
NormalizedGeodeticPoint gpA = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(20) + 0.1 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.2 * tile.getLongitudeStep(),
300.0, +4 * FastMath.PI);
NormalizedGeodeticPoint gpB = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(20) + 0.7 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.9 * tile.getLongitudeStep(),
10.0, +4 * FastMath.PI);
NormalizedGeodeticPoint gpIAB = tile.cellIntersection(gpA, los(gpA, gpB), 20, 14);
checkInLine(gpA, gpB, gpIAB);
checkOnTile(tile, gpIAB);
NormalizedGeodeticPoint gpIBA = tile.cellIntersection(gpB, los(gpB, gpA), 20, 14);
checkInLine(gpA, gpB, gpIBA);
checkOnTile(tile, gpIBA);
......@@ -244,19 +274,19 @@ public class SimpleTileTest {
tile.setElevation(21, 14, 162.0);
tile.setElevation(21, 15, 95.0);
tile.tileUpdateCompleted();
GeodeticPoint gpA = new GeodeticPoint(tile.getLatitudeAtIndex(20) + 0.1 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.2 * tile.getLongitudeStep(),
120.0);
GeodeticPoint gpB = new GeodeticPoint(tile.getLatitudeAtIndex(20) + 0.7 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.9 * tile.getLongitudeStep(),
130.0);
NormalizedGeodeticPoint gpA = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(20) + 0.1 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.2 * tile.getLongitudeStep(),
120.0, tile.getLongitudeAtIndex(14));
NormalizedGeodeticPoint gpB = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(20) + 0.7 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.9 * tile.getLongitudeStep(),
130.0, tile.getLongitudeAtIndex(14));
// the line from gpA to gpB should traverse the DEM twice within the tile
// we use the points in the two different orders to retrieve both solutions
GeodeticPoint gpIAB = tile.cellIntersection(gpA, los(gpA, gpB), 20, 14);
NormalizedGeodeticPoint gpIAB = tile.cellIntersection(gpA, los(gpA, gpB), 20, 14);
checkInLine(gpA, gpB, gpIAB);
checkOnTile(tile, gpIAB);
GeodeticPoint gpIBA = tile.cellIntersection(gpB, los(gpB, gpA), 20, 14);
NormalizedGeodeticPoint gpIBA = tile.cellIntersection(gpB, los(gpB, gpA), 20, 14);
checkInLine(gpA, gpB, gpIBA);
checkOnTile(tile, gpIBA);
......@@ -275,12 +305,12 @@ public class SimpleTileTest {
tile.setElevation(21, 14, 162.0);
tile.setElevation(21, 15, 95.0);
tile.tileUpdateCompleted();
GeodeticPoint gpA = new GeodeticPoint(tile.getLatitudeAtIndex(20) + 0.1 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.2 * tile.getLongitudeStep(),
180.0);
GeodeticPoint gpB = new GeodeticPoint(tile.getLatitudeAtIndex(20) + 0.7 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.9 * tile.getLongitudeStep(),
190.0);
NormalizedGeodeticPoint gpA = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(20) + 0.1 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.2 * tile.getLongitudeStep(),
180.0, tile.getLongitudeAtIndex(14));
NormalizedGeodeticPoint gpB = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(20) + 0.7 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(14) + 0.9 * tile.getLongitudeStep(),
190.0, tile.getLongitudeAtIndex(14));
Assert.assertNull(tile.cellIntersection(gpA, los(gpA, gpB), 20, 14));
......@@ -295,17 +325,17 @@ public class SimpleTileTest {
tile.setElevation(1, 0, 40.0);
tile.setElevation(1, 1, 40.0);
tile.tileUpdateCompleted();
GeodeticPoint gpA = new GeodeticPoint(tile.getLatitudeAtIndex(0) + 0.25 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
50.0);
GeodeticPoint gpB = new GeodeticPoint(tile.getLatitudeAtIndex(0) + 0.75 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
20.0);
GeodeticPoint gpIAB = tile.cellIntersection(gpA, los(gpA, gpB), 0, 0);
NormalizedGeodeticPoint gpA = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(0) + 0.25 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
50.0, tile.getLongitudeAtIndex(0));
NormalizedGeodeticPoint gpB = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(0) + 0.75 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
20.0, tile.getLongitudeAtIndex(0));
NormalizedGeodeticPoint gpIAB = tile.cellIntersection(gpA, los(gpA, gpB), 0, 0);
checkInLine(gpA, gpB, gpIAB);
checkOnTile(tile, gpIAB);
GeodeticPoint gpIBA = tile.cellIntersection(gpB, los(gpB, gpA), 0, 0);
NormalizedGeodeticPoint gpIBA = tile.cellIntersection(gpB, los(gpB, gpA), 0, 0);
checkInLine(gpA, gpB, gpIBA);
checkOnTile(tile, gpIBA);
......@@ -324,12 +354,12 @@ public class SimpleTileTest {
tile.setElevation(1, 0, 40.0);
tile.setElevation(1, 1, 40.0);
tile.tileUpdateCompleted();
GeodeticPoint gpA = new GeodeticPoint(tile.getLatitudeAtIndex(0) + 0.25 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
45.0);
GeodeticPoint gpB = new GeodeticPoint(tile.getLatitudeAtIndex(0) + 0.75 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
55.0);
NormalizedGeodeticPoint gpA = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(0) + 0.25 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
45.0, tile.getLongitudeAtIndex(0));
NormalizedGeodeticPoint gpB = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(0) + 0.75 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
55.0, tile.getLongitudeAtIndex(0));
Assert.assertNull(tile.cellIntersection(gpA, los(gpA, gpB), 0, 0));
......@@ -344,12 +374,12 @@ public class SimpleTileTest {
tile.setElevation(1, 0, 40.0);
tile.setElevation(1, 1, 40.0);
tile.tileUpdateCompleted();
GeodeticPoint gpA = new GeodeticPoint(tile.getLatitudeAtIndex(0) + 0.25 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
45.0);
GeodeticPoint gpB = new GeodeticPoint(tile.getLatitudeAtIndex(0) + 0.75 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
50.0);
NormalizedGeodeticPoint gpA = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(0) + 0.25 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
45.0, tile.getLongitudeAtIndex(0));
NormalizedGeodeticPoint gpB = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(0) + 0.75 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
50.0, tile.getLongitudeAtIndex(0));
Assert.assertNull(tile.cellIntersection(gpA, los(gpA, gpB), 0, 0));
......@@ -364,17 +394,17 @@ public class SimpleTileTest {
tile.setElevation(1, 0, 40.0);
tile.setElevation(1, 1, 40.0);
tile.tileUpdateCompleted();
GeodeticPoint gpA = new GeodeticPoint(tile.getLatitudeAtIndex(0) + 0.25 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
32.5);
GeodeticPoint gpB = new GeodeticPoint(tile.getLatitudeAtIndex(0) + 0.75 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
37.5);
GeodeticPoint gpIAB = tile.cellIntersection(gpA, los(gpA, gpB), 0, 0);
NormalizedGeodeticPoint gpA = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(0) + 0.25 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
32.5, tile.getLongitudeAtIndex(0));
NormalizedGeodeticPoint gpB = new NormalizedGeodeticPoint(tile.getLatitudeAtIndex(0) + 0.75 * tile.getLatitudeStep(),
tile.getLongitudeAtIndex(0) + 0.50 * tile.getLongitudeStep(),
37.5, tile.getLongitudeAtIndex(0));
NormalizedGeodeticPoint gpIAB = tile.cellIntersection(gpA, los(gpA, gpB), 0, 0);
checkInLine(gpA, gpB, gpIAB);
checkOnTile(tile, gpIAB);
GeodeticPoint gpIBA = tile.cellIntersection(gpB, los(gpB, gpA), 0, 0);
NormalizedGeodeticPoint gpIBA = tile.cellIntersection(gpB, los(gpB, gpA), 0, 0);
checkInLine(gpA, gpB, gpIBA);
checkOnTile(tile, gpIBA);
......@@ -432,7 +462,7 @@ public class SimpleTileTest {
1.0e-10);
Assert.assertEquals(gpI.getLongitude(),
gpA.getLongitude() * (1 - t) + gpB.getLongitude() * t,
MathUtils.normalizeAngle(gpA.getLongitude() * (1 - t) + gpB.getLongitude() * t, gpI.getLongitude()),
1.0e-10);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment