/** * {@inheritDoc} * * @return {@code true} if the parameters describe no operation. */ @Override public boolean isIdentity() { return super.isIdentity() && dtX == 0 && dtY == 0 && dtZ == 0; }
/** * Returns {@code true} if a transformation built from this set of parameters would perform no operation. * This is true when the value of all parameters is zero. * * @return {@code true} if the parameters describe no operation. */ public boolean isIdentity() { return tX == 0 && tY == 0 && tZ == 0 && isTranslation(); }
/** * Creates the {@code TOWGS84} element during parsing of a WKT version 1. * * @param values the 7 Bursa-Wolf parameter values. * @return the {@link BursaWolfParameters}. * * @since 0.6 */ @Override public Object createToWGS84(final double[] values) { final BursaWolfParameters info = new BursaWolfParameters(CommonCRS.WGS84.datum(), null); info.setValues(values); return info; }
/** * Inverts in-place the transformation by inverting the sign of all numerical parameters. * The {@linkplain #getPositionVectorTransformation(Date) position vector transformation} matrix * created from inverted Bursa-Wolf parameters will be <strong>approximatively</strong> equals * to the {@linkplain org.apache.sis.referencing.operation.matrix.MatrixSIS#inverse() inverse} * of the matrix created from the original parameters. The equality holds approximatively only * because the parameter values are very small (parts per millions and arc-seconds). */ public void invert() { final double[] values = getValues(); for (int i=0; i<values.length; i++) { values[i] = -values[i]; } setValues(values); }
/** * Returns the parameters for the <cite>WGS 72 to WGS 84 (2)</cite> transformation (EPSG:1238). * Area of validity is the World. */ static BursaWolfParameters createWGS72_to_WGS84() { final BursaWolfParameters bursaWolf = new BursaWolfParameters(GeodeticDatumMock.WGS84, Extents.WORLD); bursaWolf.tZ = 4.5; bursaWolf.rZ = 0.554; bursaWolf.dS = 0.219; bursaWolf.verify(PrimeMeridianMock.GREENWICH); assertFalse("isIdentity", bursaWolf.isIdentity()); assertFalse("isTranslation", bursaWolf.isTranslation()); return bursaWolf; }
/** * Tests the {@link BursaWolfParameters#setPositionVectorTransformation(Matrix, double)} method. * This is an internal consistency test. */ @Test @DependsOnMethod("testGetPositionVectorTransformation") public void testSetPositionVectorTransformation() { final BursaWolfParameters bursaWolf = createED87_to_WGS84(); final Matrix matrix = bursaWolf.getPositionVectorTransformation(null); final BursaWolfParameters actual = new BursaWolfParameters( bursaWolf.getTargetDatum(), bursaWolf.getDomainOfValidity()); actual.setPositionVectorTransformation(matrix, 1E-10); assertEquals(bursaWolf, actual); }
final BursaWolfParameters parameters = new BursaWolfParameters(null, null); try { parameters.setPositionVectorTransformation(((LinearTransform) step).getMatrix(), BURSAWOLF_TOLERANCE); } catch (IllegalArgumentException e) { continue; final boolean isTranslation = parameters.isTranslation(); final Parameters values = createParameters(isTranslation ? GeocentricTranslation.PARAMETERS : PositionVector7Param.PARAMETERS, parameters, isTranslation);
final double[] values = getValues(); for (final double value : values) { formatter.append(value); if (isToWGS84()) { if (values.length > 7) { formatter.setInvalidWKT(BursaWolfParameters.class, null); String name = IdentifiedObjects.getUnicodeIdentifier(getTargetDatum()); if (name == null) { name = "Unknown";
if (datum instanceof DefaultGeodeticDatum) { for (final BursaWolfParameters bwp : ((DefaultGeodeticDatum) datum).getBursaWolfParameters()) { if (Utilities.equalsIgnoreMetadata(CommonCRS.WGS84.datum(), bwp.getTargetDatum())) { definition.append(" +towgs84=").append(bwp.tX).append(',').append(bwp.tY).append(',').append(bwp.tZ); if (!bwp.isTranslation()) { definition.append(',').append(bwp.rX).append(',').append(bwp.rY).append(',').append(bwp.rZ).append(',').append(bwp.dS);
/** * Returns the best parameters matching the given criteria, or {@code null} if none. */ private BursaWolfParameters select(final GeodeticDatum targetDatum, final ExtentSelector<BursaWolfParameters> selector) { if (bursaWolf == null) { return null; } for (final BursaWolfParameters candidate : bursaWolf) { if (deepEquals(targetDatum, candidate.getTargetDatum(), ComparisonMode.IGNORE_METADATA)) { selector.evaluate(candidate.getDomainOfValidity(), candidate); } } return selector.best(); }
/** * Tests {@link BursaWolfParameters#setValues(double[])}. */ @Test @DependsOnMethod("testGetValues") public void testSetValues() { final BursaWolfParameters actual = createWGS72_to_WGS84(); final BursaWolfParameters expected = createED87_to_WGS84(); final double[] values = expected.getValues(); assertFalse("equals(Object) before to set the values.", actual.equals(expected)); actual.setValues(values); assertArrayEquals("getValues() after setting the values.", values, actual.getValues(), STRICT); // Can not test assertEquals(expected, actual) because of different geographic extent. }
/** * Tests the conversion from {@code CompoundCRS[EPSG:3035 + Sigma-level]} to {@code EPSG:4326}. * The interesting part in this test is that the height is not a standard height, and the * referencing module is not supposed to known how to build a 3D Geographic CRS (needed as * an intermediate step for the datum shift) with that height. * * @throws FactoryException Should never happen. * * @see <a href="http://jira.geotoolkit.org/browse/GEOTK-71">GEOTK-71</a> */ @Test @Ignore("JSR-275 does not accept unit named 'level'.") public void testProjected3D_to_2D() throws FactoryException { CoordinateReferenceSystem targetCRS = CommonCRS.WGS84.geographic(); CoordinateReferenceSystem sourceCRS = CRS.forCode("EPSG:3035"); GeodeticDatum targetDatum = ((GeographicCRS) targetCRS).getDatum(); GeodeticDatum sourceDatum = ((ProjectedCRS) sourceCRS).getDatum(); final BursaWolfParameters[] params = ((DefaultGeodeticDatum) sourceDatum).getBursaWolfParameters(); assertEquals("This test requires that an explicit BursaWolf parameter exists.", 1, params.length); assertEquals("targetDatum", targetDatum, params[0].getTargetDatum()); assertTrue("This test requires that the BursaWolf parameter is set to identity.", params[0].isIdentity()); CoordinateReferenceSystem vertCRS = CRS.fromWKT( "VERT_CS[\"Sigma Level\",VERT_DATUM[\"Sigma Level\",2000],UNIT[\"level\",1.0],AXIS[\"Sigma Level\",DOWN]]"); sourceCRS = new DefaultCompoundCRS(singletonMap(NAME_KEY, "ETRS89 + Sigma level"), sourceCRS, vertCRS); final MathTransform tr = CRS.findOperation(sourceCRS, targetCRS, null).getMathTransform(); assertSame(tr, CRS.findOperation(sourceCRS, targetCRS, null).getMathTransform()); assertSame(tr, CRS.findOperation(sourceCRS, targetCRS, null).getMathTransform()); assertEquals(3, tr.getSourceDimensions()); assertEquals(2, tr.getTargetDimensions()); }
throws FactoryException final BursaWolfParameters parameters = new BursaWolfParameters(null, null); final Parameters pv = Parameters.castOrWrap(values); boolean reverseRotation = false; parameters.reverseRotation(); return MathTransforms.linear(parameters.getPositionVectorTransformation(null));
final DoubleDouble period = period(time); if (period == null && isTranslation()) { final Matrix4 matrix = new Matrix4(); matrix.m03 = tX; final DoubleDouble S = param(6, period); S.divide(PPM, 0); S.add(1, 0); // S = 1 + dS / PPM; final DoubleDouble X = param(3, period); X.multiply(RS); final DoubleDouble Y = param(4, period); Y.multiply(RS); final DoubleDouble Z = param(5, period); Z.multiply(RS); final DoubleDouble mX = new DoubleDouble(X); mX.negate(); final DoubleDouble mY = new DoubleDouble(Y); mY.negate(); final Integer O = 0; // Fetch Integer instance only once. return Matrices.create(4, 4, new Number[] { S, mZ, Y, param(0, period), Z, S, mX, param(1, period), mY, X, S, param(2, period), O, O, O, 1});
/** * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Date)} * and compares with our own matrix calculated using double arithmetic. */ private static MatrixSIS getPositionVectorTransformation(final BursaWolfParameters p) { final double S = 1 + p.dS / BursaWolfParameters.PPM; final double RS = TO_RADIANS * S; final Matrix4 expected = new Matrix4( S, -p.rZ*RS, +p.rY*RS, p.tX, +p.rZ*RS, S, -p.rX*RS, p.tY, -p.rY*RS, +p.rX*RS, S, p.tZ, 0, 0, 0, 1); final MatrixSIS matrix = MatrixSIS.castOrCopy(p.getPositionVectorTransformation(null)); assertMatrixEquals("getPositionVectorTransformation", expected, matrix, p.isTranslation() ? 0 : 1E-14); return matrix; }
/** * Returns a hash value for this object. * * @return the hash code value. This value does not need to be the same in past or future versions of this class. */ @Override public int hashCode() { return Arrays.hashCode(getValues()) ^ (int) serialVersionUID; }
continue; final BursaWolfParameters bwp = new BursaWolfParameters(datum, info.getDomainOfValidity(owner)); try (ResultSet result = executeQuery("BursaWolfParameters", "SELECT PARAMETER_CODE," + bwp.reverseRotation();
/** * {@inheritDoc} * * @return {@code true} if the given object is equal to this {@code TimeDependentBWP}. */ @Override public boolean equals(final Object object) { return super.equals(object) && timeReference == ((TimeDependentBWP) object).timeReference; }
/** * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Date)} for a date calculated from * the temporal elements on the given extent. This method chooses an instant located midway between the * start and end time. */ private static Matrix createTransformation(final BursaWolfParameters bursaWolf, final Extent areaOfInterest) { /* * Implementation note: we know that we do not need to compute an instant if the parameters is * not a subclass of BursaWolfParameters. This optimisation covers the vast majority of cases. */ return bursaWolf.getPositionVectorTransformation(bursaWolf.getClass() != BursaWolfParameters.class ? Extents.getDate(areaOfInterest, 0.5) : null); // 0.5 is for choosing midway instant. }
/** * Sets the parameters to the given values. The given array can have any length. The first array elements will be * assigned to the {@link #tX tX}, {@link #tY tY}, {@link #tZ tZ}, {@link #rX rX}, {@link #rY rY}, {@link #rZ rZ}, * {@link #dS dS}, {@link #dtX}, {@link #dtY}, {@link #dtZ}, {@link #drX}, {@link #drY}, {@link #drZ} and * {@link #ddS} fields in that order. * * @param elements the new parameter values, as an array of any length. * * @since 0.6 */ @Override @SuppressWarnings("fallthrough") public void setValues(final double... elements) { if (elements.length >= 8) { switch (elements.length) { default: ddS = elements[13]; // Fallthrough everywhere. case 13: drZ = elements[12]; case 12: drY = elements[11]; case 11: drX = elements[10]; case 10: dtZ = elements[ 9]; case 9: dtY = elements[ 8]; case 8: dtX = elements[ 7]; } } super.setValues(elements); }