use of org.apache.sis.geometry.DirectPosition2D in project sis by apache.
the class MilitaryGridReferenceSystemTest method verifyDecoderTables.
/**
* Verifies the hard-coded tables used for decoding purpose.
* This method performs its computation using UTM zone 31, which is the zone from 0° to 6°E.
* The results should be the same for all other zones.
*
* @throws TransformException if an error occurred while projecting a geographic coordinate.
* @throws ReflectiveOperationException if this test method can not access the table to verify.
*/
@Test
@DependsOnMethod("verifyInvariants")
public void verifyDecoderTables() throws TransformException, ReflectiveOperationException {
final int numBands = 20;
final double zoneCentre = 3;
final double zoneBorder = 0;
final CommonCRS datum = CommonCRS.WGS84;
final DirectPosition2D geographic = new DirectPosition2D();
final DirectPosition2D projected = new DirectPosition2D();
final MathTransform northMT = datum.universal(+1, zoneCentre).getConversionFromBase().getMathTransform();
final MathTransform southMT = datum.universal(-1, zoneCentre).getConversionFromBase().getMathTransform();
final int[] table;
{
// Use reflection for keeping MilitaryGridReferenceSystem.Decoder.ROW_RESOLVER private.
final Field f = MilitaryGridReferenceSystem.Decoder.class.getDeclaredField("ROW_RESOLVER");
f.setAccessible(true);
table = (int[]) f.get(null);
assertEquals("ROW_RESOLVER.length", numBands, table.length);
}
for (int band = 0; band < numBands; band++) {
final double φ = band * MilitaryGridReferenceSystem.LATITUDE_BAND_HEIGHT + TransverseMercator.Zoner.SOUTH_BOUNDS;
final boolean isSouth = (φ < 0);
final MathTransform projection = (isSouth) ? southMT : northMT;
/*
* Computes the smallest possible northing value. In the North hemisphere, this is the value
* on the central meridian because northing values tends toward the poles as we increase the
* distance from that centre. In the South hemisphere, this is the value on the zone border
* where we have the maximal distance from the centre.
*/
geographic.x = φ;
geographic.y = isSouth ? zoneBorder : zoneCentre;
final double ymin = projection.transform(geographic, projected).getOrdinate(1);
/*
* Computes the largest possible northing value. This is not only the value of the next latitude band;
* we also need to interchange the "zone centre" and "zone border" logic described in previous comment.
* The result is that we will have some overlap in the northing value of consecutive latitude bands.
*/
geographic.y = isSouth ? zoneCentre : zoneBorder;
geographic.x = MilitaryGridReferenceSystem.Decoder.upperBound(φ);
final double ymax = projection.transform(geographic, projected).getOrdinate(1);
/*
* Computes the value that we will encode in the MilitaryGridReferenceSystem.Decoder.ROW_RESOLVER table.
* The lowest 4 bits are the number of the row cycle (a cycle of 2000 km). The remaining bits tell which
* rows are valid in that latitude band.
*/
final int rowCycle = (int) StrictMath.floor(ymin / (MilitaryGridReferenceSystem.GRID_SQUARE_SIZE * MilitaryGridReferenceSystem.GRID_ROW_COUNT));
// Inclusive
final int lowerRow = (int) StrictMath.floor(ymin / MilitaryGridReferenceSystem.GRID_SQUARE_SIZE);
// Exclusive
final int upperRow = (int) StrictMath.ceil(ymax / MilitaryGridReferenceSystem.GRID_SQUARE_SIZE);
assertTrue("rowCycle", rowCycle >= 0 && rowCycle <= MilitaryGridReferenceSystem.Decoder.NORTHING_BITS_MASK);
assertTrue("lowerRow", lowerRow >= 0);
assertTrue("upperRow", upperRow >= 0);
int validRows = 0;
for (int i = lowerRow; i < upperRow; i++) {
validRows |= 1 << (i % MilitaryGridReferenceSystem.GRID_ROW_COUNT);
}
final int bits = (validRows << MilitaryGridReferenceSystem.Decoder.NORTHING_BITS_COUNT) | rowCycle;
/*
* Verification. If it fails, format the line of code that should be inserted
* in the MilitaryGridReferenceSystem.Decoder.ROW_RESOLVER table definition.
*/
if (table[band] != bits) {
String bitMasks = Integer.toBinaryString(validRows);
bitMasks = "00000000000000000000".substring(bitMasks.length()).concat(bitMasks);
fail(String.format("ROW_RESOLVER[%d]: expected %d but got %d. Below is suggested line of code:%n" + "/* Latitude band %c (from %3.0f°) */ %d | 0b%s_0000%n", band, bits, table[band], MilitaryGridReferenceSystem.Encoder.latitudeBand(φ), φ, rowCycle, bitMasks));
}
}
}
use of org.apache.sis.geometry.DirectPosition2D in project sis by apache.
the class MilitaryGridReferenceSystemTest method testEncodeUPS.
/**
* Tests encoding of various coordinates in Universal Polar Stereographic (UPS) projection.
*
* @throws TransformException if an error occurred while computing the MGRS label.
*/
@Test
@DependsOnMethod("verifyInvariants")
public void testEncodeUPS() throws TransformException {
final MilitaryGridReferenceSystem.Coder coder = coder();
final DirectPosition2D position = new DirectPosition2D();
/*
* South case.
*/
position.setCoordinateReferenceSystem(CommonCRS.WGS84.universal(-90, 0));
position.x = 2000010;
position.y = 2000010;
assertEquals("BAN0001000010", coder.encode(position));
position.x = 1999990;
position.y = 1999990;
assertEquals("AZM9999099990", coder.encode(position));
position.x = 2806727;
position.y = 1602814;
assertEquals("BLJ0672702814", coder.encode(position));
/*
* North case.
*/
position.setCoordinateReferenceSystem(CommonCRS.WGS84.universal(90, 0));
position.x = 2000010;
position.y = 2000010;
assertEquals("ZAH0001000010", coder.encode(position));
position.x = 1999990;
position.y = 1999990;
assertEquals("YZG9999099990", coder.encode(position));
position.x = 1386727;
position.y = 2202814;
assertEquals("YRK8672702814", coder.encode(position));
}
use of org.apache.sis.geometry.DirectPosition2D in project sis by apache.
the class MilitaryGridReferenceSystemTest method testPrecision.
/**
* Tests encoding of the same coordinate at various precision.
*
* @throws TransformException if an error occurred while computing the MGRS label.
*/
@Test
@DependsOnMethod("testEncodeUTM")
public void testPrecision() throws TransformException {
final MilitaryGridReferenceSystem.Coder coder = coder();
final DirectPosition2D position = new DirectPosition2D(CommonCRS.WGS84.universal(13, 103));
position.x = 377299;
position.y = 1483035;
assertEquals("precision", 1, coder.getPrecision(), STRICT);
assertEquals("48PUV7729983035", coder.encode(position));
coder.setPrecision(10);
assertEquals("precision", 10, coder.getPrecision(), STRICT);
assertEquals("48PUV77298303", coder.encode(position));
coder.setPrecision(304);
assertEquals("precision", 100, coder.getPrecision(), STRICT);
assertEquals("48PUV772830", coder.encode(position));
coder.setPrecision(1002);
assertEquals("precision", 1000, coder.getPrecision(), STRICT);
assertEquals("48PUV7783", coder.encode(position));
coder.setPrecision(10000);
assertEquals("precision", 10000, coder.getPrecision(), STRICT);
assertEquals("48PUV78", coder.encode(position));
coder.setPrecision(990004);
assertEquals("precision", 100000, coder.getPrecision(), STRICT);
assertEquals("48PUV", coder.encode(position));
coder.setPrecision(1000000);
assertEquals("precision", 1000000, coder.getPrecision(), STRICT);
assertEquals("48P", coder.encode(position));
}
use of org.apache.sis.geometry.DirectPosition2D in project sis by apache.
the class MilitaryGridReferenceSystemTest method testSeparator.
/**
* Tests encoding of the same coordinate with various separators, mixed with various precisions.
*
* @throws TransformException if an error occurred while computing the MGRS label.
*/
@Test
@DependsOnMethod("testPrecision")
public void testSeparator() throws TransformException {
final MilitaryGridReferenceSystem.Coder coder = coder();
final DirectPosition2D position = new DirectPosition2D(CommonCRS.WGS84.universal(13, 103));
position.x = 377299;
position.y = 1483035;
assertEquals("separator", "", coder.getSeparator());
assertEquals("48PUV7729983035", coder.encode(position));
coder.setSeparator(" ");
assertEquals("separator", " ", coder.getSeparator());
assertEquals("48 P UV 77299 83035", coder.encode(position));
coder.setSeparator("/");
coder.setPrecision(100000);
assertEquals("separator", "/", coder.getSeparator());
assertEquals("48/P/UV", coder.encode(position));
}
use of org.apache.sis.geometry.DirectPosition2D in project sis by apache.
the class MilitaryGridReferenceSystemTest method decode.
/**
* Decodes the given reference and returns its direct position.
*/
private static DirectPosition decode(final MilitaryGridReferenceSystem.Coder coder, final String reference) throws TransformException {
final AbstractLocation loc = coder.decode(reference);
final Envelope2D envelope = new Envelope2D(loc.getEnvelope());
final DirectPosition2D pos = new DirectPosition2D(loc.getPosition().getDirectPosition());
assertTrue(reference, envelope.contains(pos));
return pos;
}
Aggregations