org.opengis.referencing.operation.Conversion Java Examples

The following examples show how to use org.opengis.referencing.operation.Conversion. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CoordinateOperationFinderTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests a conversion of the temporal axis. We convert 1899-12-31 from a CRS having its epoch at 1970-1-1
 * to an other CRS having its epoch at 1858-11-17, so the new value shall be approximately 41 years
 * after the new epoch. This conversion also implies a change of units from seconds to days.
 *
 * @throws FactoryException if the operation can not be created.
 * @throws TransformException if an error occurred while converting the test points.
 */
@Test
@DependsOnMethod("testIdentityTransform")
public void testTemporalConversion() throws FactoryException, TransformException {
    final TemporalCRS sourceCRS = CommonCRS.Temporal.UNIX.crs();
    final TemporalCRS targetCRS = CommonCRS.Temporal.MODIFIED_JULIAN.crs();
    final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
    assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
    assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
    assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
    assertInstanceOf("operation", Conversion.class, operation);

    transform = operation.getMathTransform();
    tolerance = 1E-12;
    verifyTransform(new double[] {
        // December 31, 1899 at 12:00 UTC in seconds.
        CommonCRS.Temporal.DUBLIN_JULIAN.datum().getOrigin().getTime() / 1000
    }, new double[] {
        15019.5
    });
    validate();
}
 
Example #2
Source File: AbstractDerivedCRS.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a derived CRS from a defining conversion.
 * The properties given in argument follow the same rules than for the
 * {@linkplain AbstractCRS#AbstractCRS(Map, CoordinateSystem) super-class constructor}.
 *
 * @param  properties  the properties to be given to the new derived CRS object.
 * @param  baseCRS     coordinate reference system to base the derived CRS on.
 * @param  conversion  the defining conversion from a normalized base to a normalized derived CRS.
 * @param  derivedCS   the coordinate system for the derived CRS. The number of axes must match
 *                     the target dimension of the {@code baseToDerived} transform.
 * @throws MismatchedDimensionException if the source and target dimensions of {@code baseToDerived}
 *         do not match the dimensions of {@code base} and {@code derivedCS} respectively.
 */
AbstractDerivedCRS(final Map<String,?>    properties,
                   final SingleCRS        baseCRS,
                   final Conversion       conversion,
                   final CoordinateSystem derivedCS)
        throws MismatchedDimensionException
{
    super(properties, derivedCS);
    ArgumentChecks.ensureNonNull("baseCRS", baseCRS);
    ArgumentChecks.ensureNonNull("conversion", conversion);
    final MathTransform baseToDerived = conversion.getMathTransform();
    if (baseToDerived != null) {
        ArgumentChecks.ensureDimensionMatches("baseCRS",   baseToDerived.getSourceDimensions(), baseCRS);
        ArgumentChecks.ensureDimensionMatches("derivedCS", baseToDerived.getTargetDimensions(), derivedCS);
    }
    conversionFromBase = createConversionFromBase(properties, baseCRS, conversion);
}
 
Example #3
Source File: AbstractDerivedCRS.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Creates the conversion instance to associate with this {@code AbstractDerivedCRS}.
 *
 * <p><b>WARNING:</b> this method is invoked at construction time and will invoke indirectly
 * (through {@link DefaultConversion}) the {@link #getCoordinateSystem()} method on {@code this}.
 * Consequently this method shall be invoked only after the construction of this {@code AbstractDerivedCRS}
 * instance is advanced enough for allowing the {@code getCoordinateSystem()} method to execute.
 * Subclasses may consider to make the {@code getCoordinateSystem()} method final for better guarantees.</p>
 */
private C createConversionFromBase(final Map<String,?> properties, final SingleCRS baseCRS, final Conversion conversion) {
    MathTransformFactory factory = null;
    if (properties != null) {
        factory = (MathTransformFactory) properties.get(ReferencingFactoryContainer.MT_FACTORY);
    }
    if (factory == null) {
        factory = DefaultFactories.forBuildin(MathTransformFactory.class);
    }
    try {
        return DefaultConversion.castOrCopy(conversion).specialize(getConversionType(), baseCRS, this, factory);
    } catch (FactoryException e) {
        throw new IllegalArgumentException(Errors.getResources(properties).getString(
                Errors.Keys.IllegalArgumentValue_2, "conversion", conversion.getName()), e);
    }
}
 
Example #4
Source File: DefaultDerivedCRSTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
     * Tests the construction of a {@link DefaultDerivedCRS}.
     */
    @Test
    public void testConstruction() {
        final DefaultDerivedCRS crs = createLongitudeRotation();
//      Validators.validate(crs);

        assertEquals("name",    "Back to Greenwich",                crs.getName().getCode());
        assertEquals("baseCRS", "NTF (Paris)",                      crs.getBaseCRS().getName().getCode());
        assertEquals("datum",   "Nouvelle Triangulation Française", crs.getDatum().getName().getCode());
        assertSame  ("coordinateSystem", HardCodedCS.GEODETIC_φλ,   crs.getCoordinateSystem());

        final Conversion conversion = crs.getConversionFromBase();
        assertSame("sourceCRS", crs.getBaseCRS(), conversion.getSourceCRS());
        assertSame("targetCRS", crs,              conversion.getTargetCRS());
        assertMatrixEquals("Longitude rotation", new Matrix3(
                0, 1, 0,
                1, 0, 2.33722917,
                0, 0, 1), MathTransforms.getMatrix(conversion.getMathTransform()), STRICT);
    }
 
Example #5
Source File: DefaultDerivedCRSTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests (un)marshalling of a derived coordinate reference system.
 *
 * @throws JAXBException if an error occurred during (un)marshalling.
 *
 * @since 0.7
 */
@Test
public void testXML() throws JAXBException {
    final DefaultDerivedCRS crs = unmarshalFile(DefaultDerivedCRS.class, XML_FILE);
    Validators.validate(crs);
    assertEpsgNameAndIdentifierEqual("WGS 84", 4979, crs.getBaseCRS());
    assertAxisDirectionsEqual("baseCRS", crs.getBaseCRS().getCoordinateSystem(), AxisDirection.NORTH, AxisDirection.EAST, AxisDirection.UP);
    assertAxisDirectionsEqual("coordinateSystem", crs.getCoordinateSystem(), AxisDirection.EAST, AxisDirection.NORTH, AxisDirection.UP);

    final Conversion conversion = crs.getConversionFromBase();
    final ParameterValueGroup pg = conversion.getParameterValues();
    assertEpsgNameAndIdentifierEqual("Geographic/topocentric conversions", 9837, conversion.getMethod());
    assertEquals("Latitude", 55, pg.parameter("Latitude of topocentric origin" ).doubleValue(Units.DEGREE), STRICT);
    assertEquals("Longitude", 5, pg.parameter("Longitude of topocentric origin").doubleValue(Units.DEGREE), STRICT);
    assertEquals("Height",    0, pg.parameter("Ellipsoidal height of topocentric origin").doubleValue(Units.METRE),  STRICT);
    /*
     * Test marshalling and compare with the original file.
     */
    assertMarshalEqualsFile(XML_FILE, crs, "xmlns:*", "xsi:schemaLocation");
}
 
Example #6
Source File: DefaultMathTransformFactoryTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests the {@link DefaultMathTransformFactory#getAvailableMethods(Class)} method.
 *
 * @throws NoSuchIdentifierException if the operation was not found.
 */
@Test
@DependsOnMethod("testGetOperationMethod")
public void testGetAvailableMethods() throws NoSuchIdentifierException {
    final DefaultMathTransformFactory factory = factory();
    final Set<OperationMethod> transforms  = factory.getAvailableMethods(SingleOperation.class);
    final Set<OperationMethod> conversions = factory.getAvailableMethods(Conversion.class);
    final Set<OperationMethod> projections = factory.getAvailableMethods(Projection.class);
    /*
     * Following tests should not cause loading of more classes than needed.
     */
    assertFalse(transforms .isEmpty());
    assertFalse(conversions.isEmpty());
    assertFalse(projections.isEmpty());
    assertTrue (transforms.contains(factory.getOperationMethod(Constants.AFFINE)));
    /*
     * Following tests will force instantiation of all remaining OperationMethod.
     */
    assertTrue("Conversions should be a subset of transforms.",  transforms .containsAll(conversions));
    assertTrue("Projections should be a subset of conversions.", conversions.containsAll(projections));
}
 
Example #7
Source File: CC_Conversion.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Temporarily stores the {@code baseCRS} associated to the given {@code Conversion}.  This temporary storage is
 * needed because {@code org.apache.sis.referencing.crs.AbstractDerivedCRS} does not have any explicit field for
 * {@code baseCRS}. Instead the base CRS is stored in {@link Conversion#getSourceCRS()}, but we can set this
 * property only after the {@code DerivedCRS} coordinate system has been unmarshalled.
 *
 * See {@code AbstractDerivedCRS.afterUnmarshal(Unmarshaller, Object parent)} for more information.
 *
 * @param  conversion  the conversion to which to associate a base CRS.
 * @param  crs         the base CRS to associate to the given conversion.
 * @return the previous base CRS, or {@code null} if none.
 */
public static SingleCRS setBaseCRS(final Conversion conversion, final SingleCRS crs) {
    /*
     * Implementation note: we store the base CRS in the marshalling context because:
     *
     *   - we want to keep each thread isolated (using ThreadLocal), and
     *   - we want to make sure that the reference is disposed even if the unmarshaller throws an exception.
     *     This is guaranteed because the Context is disposed by Apache SIS in "try … finally" constructs.
     */
    final PropertyType<?,?> wrapper = Context.getWrapper(Context.current());
    if (wrapper instanceof CC_Conversion) {
        final CC_Conversion c = (CC_Conversion) wrapper;
        if (c.getElement() == conversion) {  // For making sure that we do not confuse with another conversion.
            final SingleCRS previous = c.baseCRS;
            c.baseCRS = crs;
            return previous;
        }
    }
    return null;
}
 
Example #8
Source File: OperationMethodCrsProvider.java    From snap-desktop with GNU General Public License v3.0 6 votes vote down vote up
@Override
public CoordinateReferenceSystem getCRS(final GeoPos referencePos, ParameterValueGroup parameters,
                                        GeodeticDatum datum) throws FactoryException {
    final CRSFactory crsFactory = ReferencingFactoryFinder.getCRSFactory(null);
    // in some cases, depending on the parameters set, the effective transformation can be different
    // from the transformation given by the OperationMethod.
    // So we create a new one
    final MathTransformFactory mtFactory = ReferencingFactoryFinder.getMathTransformFactory(null);
    final MathTransform transform = mtFactory.createParameterizedTransform(parameters);
    final DefaultOperationMethod operationMethod = new DefaultOperationMethod(transform);

    final Conversion conversion = new DefiningConversion(AbstractIdentifiedObject.getProperties(operationMethod),
                                                         operationMethod, transform);

    final HashMap<String, Object> baseCrsProperties = new HashMap<String, Object>();
    baseCrsProperties.put("name", datum.getName().getCode());
    GeographicCRS baseCrs = crsFactory.createGeographicCRS(baseCrsProperties,
                                                           datum,
                                                           DefaultEllipsoidalCS.GEODETIC_2D);

    final HashMap<String, Object> projProperties = new HashMap<String, Object>();
    projProperties.put("name", conversion.getName().getCode() + " / " + datum.getName().getCode());
    return crsFactory.createProjectedCRS(projProperties, baseCrs, conversion, DefaultCartesianCS.PROJECTED);
}
 
Example #9
Source File: AbstractUTMCrsProvider.java    From snap-desktop with GNU General Public License v3.0 6 votes vote down vote up
CoordinateReferenceSystem createCrs(String crsName, OperationMethod method,
                                              ParameterValueGroup parameters,
                                              GeodeticDatum datum) throws FactoryException {
    final CRSFactory crsFactory = ReferencingFactoryFinder.getCRSFactory(null);
    final CoordinateOperationFactory coFactory = ReferencingFactoryFinder.getCoordinateOperationFactory(null);
    final HashMap<String, Object> projProperties = new HashMap<String, Object>();
    projProperties.put("name", crsName + " / " + datum.getName().getCode());
    final Conversion conversion = coFactory.createDefiningConversion(projProperties,
                                                                     method,
                                                                     parameters);
    final HashMap<String, Object> baseCrsProperties = new HashMap<String, Object>();
    baseCrsProperties.put("name", datum.getName().getCode());
    final GeographicCRS baseCrs = crsFactory.createGeographicCRS(baseCrsProperties, datum,
                                                                 DefaultEllipsoidalCS.GEODETIC_2D);
    return crsFactory.createProjectedCRS(projProperties, baseCrs, conversion, DefaultCartesianCS.PROJECTED);
}
 
Example #10
Source File: EnvelopesTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests {@link Envelopes#findOperation(Envelope, Envelope)}.
 *
 * @throws FactoryException if an error occurred while searching the operation.
 *
 * @since 1.0
 */
@Test
public void testFindOperation() throws FactoryException {
    final GeneralEnvelope source = new GeneralEnvelope(HardCodedCRS.WGS84);
    final GeneralEnvelope target = new GeneralEnvelope(HardCodedCRS.GEOCENTRIC);
    source.setRange(0, 20, 30);
    source.setRange(1, 40, 45);
    target.setRange(0, 6000, 8000);
    target.setRange(1, 7000, 9000);
    target.setRange(2, 4000, 5000);
    CoordinateOperation op = Envelopes.findOperation(source, target);
    assertInstanceOf("findOperation", Conversion.class, op);
    assertEquals("Geographic/geocentric conversions", ((Conversion) op).getMethod().getName().getCode());
}
 
Example #11
Source File: TransformTestCase.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests transform of an envelope over the ±180° limit. The Mercator projection used in this test
 * is not expected to wrap the longitude around Earth when using only the {@code MathTransform}.
 * However when the target CRS is known, then "wrap around" should be applied.
 *
 * @throws TransformException if an error occurred while transforming the envelope.
 *
 * @since 0.8
 */
@Test
@DependsOnMethod("testTransform")
public final void testTransformOverAntiMeridian() throws TransformException {
    final ProjectedCRS  sourceCRS  = HardCodedConversions.mercator();
    final GeographicCRS targetCRS  = sourceCRS.getBaseCRS();
    final Conversion    conversion = inverse(sourceCRS.getConversionFromBase());
    final G expected  = createFromExtremums(targetCRS, 179, 40, 181, 50);
    final G rectangle = createFromExtremums(sourceCRS,
            19926188.852, 4838471.398,                      // Computed by SIS (not validated by external authority).
            20148827.834, 6413524.594);
    final G actual = transform(conversion, rectangle);
    assertGeometryEquals(expected, actual, ANGULAR_TOLERANCE, ANGULAR_TOLERANCE);
}
 
Example #12
Source File: CoordinateOperationFinderTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests transformation from a tree-dimensional geographic CRS to an ellipsoidal CRS.
 * Such vertical CRS are illegal according ISO 19111, but they are the easiest test
 * that we can perform for geographic → vertical transformation.
 *
 * @throws FactoryException if the operation can not be created.
 * @throws TransformException if an error occurred while converting the test points.
 */
@Test
@DependsOnMethod("testIdentityTransform")
public void testGeographic3D_to_EllipsoidalHeight() throws FactoryException, TransformException {
    final CoordinateReferenceSystem sourceCRS = CommonCRS.WGS84.geographic3D();
    final CoordinateReferenceSystem targetCRS = HardCodedCRS.ELLIPSOIDAL_HEIGHT_cm;
    final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
    assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
    assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
    assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
    assertInstanceOf("operation", Conversion.class, operation);

    transform = operation.getMathTransform();
    assertInstanceOf("transform", LinearTransform.class, transform);
    assertEquals("sourceDimensions", 3, transform.getSourceDimensions());
    assertEquals("targetDimensions", 1, transform.getTargetDimensions());
    Assert.assertMatrixEquals("transform.matrix", Matrices.create(2, 4, new double[] {
        0, 0, 100, 0,
        0, 0,   0, 1
    }), ((LinearTransform) transform).getMatrix(), STRICT);

    isInverseTransformSupported = false;
    verifyTransform(new double[] {
         0,  0,  0,
         5,  8, 20,
        -5, -8, 24
    }, new double[] {
                 0,
              2000,
              2400,
    });
    validate();
}
 
Example #13
Source File: TransformTestCase.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests conversions of an envelope or rectangle which is <strong>not</strong> over a pole,
 * but was wrongly considered as over a pole before SIS-329 fix.
 *
 * @throws FactoryException if an error occurred while creating the operation.
 * @throws TransformException if an error occurred while transforming the envelope.
 *
 * @see <a href="https://issues.apache.org/jira/browse/SIS-329">SIS-329</a>
 */
@Test
@DependsOnMethod("testTransform")
public final void testTransformNotOverPole() throws FactoryException, TransformException {
    final ProjectedCRS  sourceCRS  = CommonCRS.WGS84.universal(10, -3.5);
    final GeographicCRS targetCRS  = sourceCRS.getBaseCRS();
    final Conversion    conversion = inverse(sourceCRS.getConversionFromBase());
    final G rectangle = createFromExtremums(sourceCRS, 199980, 4490220, 309780, 4600020);
    final G expected  = createFromExtremums(targetCRS,
            40.50846282536367, -6.594124551832373,          // Computed by SIS (not validated by external authority).
            41.52923550023067, -5.246186118392847);
    final G actual = transform(conversion, rectangle);
    assertGeometryEquals(expected, actual, ANGULAR_TOLERANCE, ANGULAR_TOLERANCE);
}
 
Example #14
Source File: CRSBuilder.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Verifies if the user-defined CRS created from GeoTIFF values
 * matches the given CRS created from the EPSG geodetic dataset.
 * This method does not verify the EPSG code of the given CRS.
 *
 * @param  crs  the CRS created from the EPSG geodetic dataset.
 */
private void verify(final ProjectedCRS crs) throws FactoryException {
    final Unit<Length> linearUnit  = createUnit(GeoKeys.LinearUnits,  GeoKeys.LinearUnitSize, Length.class, Units.METRE);
    final Unit<Angle>  angularUnit = createUnit(GeoKeys.AngularUnits, GeoKeys.AngularUnitSize, Angle.class, Units.DEGREE);
    final GeographicCRS baseCRS = crs.getBaseCRS();
    verifyIdentifier(crs, baseCRS, GeoKeys.GeographicType);
    verify(baseCRS, angularUnit);
    final Conversion projection = crs.getConversionFromBase();
    verifyIdentifier(crs, projection, GeoKeys.Projection);
    verify(projection, angularUnit, linearUnit);
}
 
Example #15
Source File: Proj4FactoryTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests the transformation from {@code "+init=epsg:4326"} to {@code "+init=epsg:3395"}.
 *
 * @throws FactoryException if an error occurred while creating the CRS objects.
 * @throws TransformException if an error occurred while projecting a test point.
 */
@Test
public void testTransform() throws FactoryException, TransformException {
    final Proj4Factory  factory   = Proj4Factory.INSTANCE;
    final GeographicCRS sourceCRS = factory.createGeographicCRS("+init=epsg:4326");
    final ProjectedCRS  targetCRS = factory.createProjectedCRS("+init=epsg:3395");
    final CoordinateOperation op  = factory.createOperation(sourceCRS, targetCRS, true);
    assertInstanceOf("createOperation", Conversion.class, op);
    testMercatorProjection(op.getMathTransform());
}
 
Example #16
Source File: TransformTestCase.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests the transformation of an envelope or rectangle. This is a relatively simple test case
 * working in the two-dimensional space only, with a coordinate operation of type "conversion"
 * (not a "transformation") and with no need to adjust for poles.
 *
 * @throws FactoryException if an error occurred while creating the operation.
 * @throws TransformException if an error occurred while transforming the envelope.
 */
@Test
public final void testTransform() throws FactoryException, TransformException {
    final ProjectedCRS    targetCRS  = CommonCRS.WGS84.universal(10, -123.5);
    final GeographicCRS   sourceCRS  = targetCRS.getBaseCRS();
    final Conversion      conversion = targetCRS.getConversionFromBase();
    final MathTransform2D transform  = (MathTransform2D) conversion.getMathTransform();
    /*
     * Transforms envelopes using MathTransform. Geographic coordinates are in (latitude, longitude) order.
     * Opportunistically check that the transform using a CoordinateOperation object produces the same result.
     */
    final G rectλφ = createFromExtremums(sourceCRS, -20, -126, 40, -120);
    final G rectXY = transform(targetCRS, transform, rectλφ);
    assertEquals("Conversion should produce the same result.", rectXY, transform(conversion, rectλφ));
    /*
     * Expected values are determined empirically by projecting many points.
     * Those values are the same than in EnvelopesTest.testTransform().
     */
    final G expected = createFromExtremums(targetCRS, 166021.56, -2214294.03,
                                                      833978.44,  4432069.06);
    assertGeometryEquals(expected, rectXY, LINEAR_TOLERANCE, LINEAR_TOLERANCE);
    /*
     * Test the inverse conversion.
     * Final envelope should be slightly bigger than the original.
     */
    final G rectBack = transform(sourceCRS, transform.inverse(), rectXY);
    assertTrue("Transformed envelope should not be smaller than the original one.", contains(rectBack, rectλφ));
    assertGeometryEquals(rectλφ, rectBack, 0.05, 1.0);
}
 
Example #17
Source File: MTFactory.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Unsupported by the {@literal Proj.4} wrapper — delegates to the Apache SIS default factory.
 */
@Override
public Conversion createDefiningConversion(Map<String,?> properties, OperationMethod method, ParameterValueGroup parameters)
        throws FactoryException
{
    return opFactory().createDefiningConversion(properties, method, parameters);
}
 
Example #18
Source File: DefaultConversionTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests {@link DefaultConversion#specialize DefaultConversion.specialize(…)} with new source and target CRS.
 * This test attempts to swap axis order and change the number of dimensions of the <em>target</em> CRS.
 *
 * <div class="note"><b>Note:</b>
 * By contrast, {@link #testDefiningConversion()} tested swapping axis order in the <em>source</em> CRS.</div>
 *
 * @throws FactoryException if an error occurred while creating the conversion.
 */
@Test
@DependsOnMethod("testDefiningConversion")
public void testSpecialize() throws FactoryException {
    final MathTransformFactory factory = DefaultFactories.forBuildin(MathTransformFactory.class);
    DefaultConversion op = createLongitudeRotation(
            createParisCRS(true,  HardCodedCS.GEODETIC_3D, false),
            createParisCRS(false, HardCodedCS.GEODETIC_3D, true), null);
    assertMatrixEquals("Longitude rotation of a three-dimensional CRS", new Matrix4(
            1, 0, 0, OFFSET,
            0, 1, 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1), MathTransforms.getMatrix(op.getMathTransform()), STRICT);
    /*
     * When asking for a "specialization" with the same properties,
     * we should get the existing instance since no change is needed.
     */
    assertSame(op, op.specialize(Conversion.class, op.getSourceCRS(), op.getTargetCRS(), factory));
    /*
     * Reducing the number of dimensions to 2 and swapping (latitude, longitude) axes.
     */
    op = op.specialize(DefaultConversion.class, op.getSourceCRS(),
            changeCS(op.getTargetCRS(), HardCodedCS.GEODETIC_φλ), factory);
    assertMatrixEquals("Longitude rotation of a two-dimensional CRS", Matrices.create(3, 4, new double[] {
            0, 1, 0, 0,
            1, 0, 0, OFFSET,
            0, 0, 0, 1}), MathTransforms.getMatrix(op.getMathTransform()), STRICT);
}
 
Example #19
Source File: CoordinateOperationFinderTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests extracting the vertical part of a spatiotemporal CRS.
 *
 * @throws FactoryException if the operation can not be created.
 * @throws TransformException if an error occurred while converting the test points.
 */
@Test
@DependsOnMethod("testGeographic3D_to_EllipsoidalHeight")
public void testGeographic4D_to_EllipsoidalHeight() throws FactoryException, TransformException {
    // NOTE: make sure that the 'sourceCRS' below is not equal to any other 'sourceCRS' created in this class.
    final CompoundCRS sourceCRS = compound("Test4D", CommonCRS.WGS84.geographic3D(), CommonCRS.Temporal.JULIAN.crs());
    final VerticalCRS targetCRS = CommonCRS.Vertical.ELLIPSOIDAL.crs();
    final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
    assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
    assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
    assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
    assertInstanceOf("operation", Conversion.class, operation);

    transform = operation.getMathTransform();
    assertInstanceOf("transform", LinearTransform.class, transform);
    assertEquals("sourceDimensions", 4, transform.getSourceDimensions());
    assertEquals("targetDimensions", 1, transform.getTargetDimensions());
    Assert.assertMatrixEquals("transform.matrix", Matrices.create(2, 5, new double[] {
        0, 0, 1, 0, 0,
        0, 0, 0, 0, 1
    }), ((LinearTransform) transform).getMatrix(), STRICT);

    isInverseTransformSupported = false;
    verifyTransform(new double[] {
         0,  0,  0,  0,
         5,  8, 20, 10,
        -5, -8, 24, 30
    }, new double[] {
                 0,
                20,
                24,
    });
    validate();
}
 
Example #20
Source File: DefaultDerivedCRS.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a derived CRS from a defining conversion and a type inferred from the given arguments.
 * This method expects the same arguments and performs the same work than the
 * {@linkplain #DefaultDerivedCRS(Map, SingleCRS, Conversion, CoordinateSystem) above constructor},
 * except that the {@code DerivedCRS} instance returned by this method may additionally implement
 * the {@link GeodeticCRS}, {@link VerticalCRS}, {@link TemporalCRS}, {@link ParametricCRS} or
 * {@link EngineeringCRS} interface.
 * See the class javadoc for more information.
 *
 * @param  properties  the properties to be given to the new derived CRS object.
 * @param  baseCRS     coordinate reference system to base the derived CRS on.
 * @param  conversion  the defining conversion from a normalized base to a normalized derived CRS.
 * @param  derivedCS   the coordinate system for the derived CRS. The number of axes
 *                     must match the target dimension of the {@code baseToDerived} transform.
 * @return the newly created derived CRS, potentially implementing an additional CRS interface.
 * @throws MismatchedDimensionException if the source and target dimensions of {@code baseToDerived}
 *         do not match the dimensions of {@code base} and {@code derivedCS} respectively.
 *
 * @see #DefaultDerivedCRS(Map, SingleCRS, Conversion, CoordinateSystem)
 * @see org.apache.sis.referencing.factory.GeodeticObjectFactory#createDerivedCRS(Map, CoordinateReferenceSystem, Conversion, CoordinateSystem)
 */
public static DefaultDerivedCRS create(final Map<String,?>    properties,
                                       final SingleCRS        baseCRS,
                                       final Conversion       conversion,
                                       final CoordinateSystem derivedCS)
        throws MismatchedDimensionException
{
    if (baseCRS != null && derivedCS != null) {
        final String type = getType(baseCRS, derivedCS);
        if (type != null) switch (type) {
            case WKTKeywords.GeodeticCRS:   return new Geodetic  (properties, (GeodeticCRS)   baseCRS, conversion,                derivedCS);
            case WKTKeywords.VerticalCRS:   return new Vertical  (properties, (VerticalCRS)   baseCRS, conversion,   (VerticalCS) derivedCS);
            case WKTKeywords.TimeCRS:       return new Temporal  (properties, (TemporalCRS)   baseCRS, conversion,       (TimeCS) derivedCS);
            case WKTKeywords.ParametricCRS: return new Parametric(properties, (ParametricCRS) baseCRS, conversion, (DefaultParametricCS) derivedCS);
            case WKTKeywords.EngineeringCRS: {
                /*
                 * This case may happen for baseCRS of kind GeodeticCRS, ProjectedCRS or EngineeringCRS.
                 * But only the later is associated to EngineeringDatum; the two formers are associated
                 * to GeodeticDatum. Consequently we can implement the EngineeringCRS.getDatum() method
                 * only if the base CRS is itself of kind EngineeringCRS.  Otherwise we will return the
                 * "type-neutral" DefaultDerivedCRS implementation.   Note that even in the later case,
                 * the WKT format will still be able to detect that the WKT keyword is "EngineeringCRS".
                 */
                if (baseCRS instanceof EngineeringCRS) {
                    return new Engineering(properties, (EngineeringCRS) baseCRS, conversion, derivedCS);
                }
                break;
            }
        }
    }
    return new DefaultDerivedCRS(properties, baseCRS, conversion, derivedCS);
}
 
Example #21
Source File: CoordinateOperationFinderTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests the conversion from a two-dimensional geographic CRS to a three-dimensional geographic CRS.
 * Coordinate values of the vertical dimension should be set to zero.
 *
 * @throws FactoryException if the operation can not be created.
 * @throws TransformException if an error occurred while converting the test points.
 */
@Test
@DependsOnMethod("testGeographic3D_to_2D")
public void testGeographic2D_to_3D() throws FactoryException, TransformException {
    final GeographicCRS sourceCRS = CommonCRS.WGS84.geographic();
    final GeographicCRS targetCRS = CommonCRS.WGS84.geographic3D();
    final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
    assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
    assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
    assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
    assertInstanceOf("operation", Conversion.class, operation);

    final ParameterValueGroup parameters = ((SingleOperation) operation).getParameterValues();
    assertEquals("parameters.descriptor", "Geographic2D to 3D conversion", parameters.getDescriptor().getName().getCode());
    assertEquals("parameters.height", 0, parameters.parameter("height").doubleValue(), STRICT);

    transform = operation.getMathTransform();
    assertInstanceOf("transform", LinearTransform.class, transform);
    assertEquals("sourceDimensions", 2, transform.getSourceDimensions());
    assertEquals("targetDimensions", 3, transform.getTargetDimensions());
    Assert.assertMatrixEquals("transform.matrix", Matrices.create(4, 3, new double[] {
        1, 0, 0,
        0, 1, 0,
        0, 0, 0,
        0, 0, 1
    }), ((LinearTransform) transform).getMatrix(), STRICT);

    verifyTransform(new double[] {
        30, 10,
        20, 30
    }, new double[] {
        30, 10, 0,
        20, 30, 0
    });
    validate();
}
 
Example #22
Source File: CoordinateOperationFinderTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests the conversion from a three-dimensional geographic CRS to a two-dimensional geographic CRS.
 * The vertical dimension is simply dropped.
 *
 * @throws FactoryException if the operation can not be created.
 * @throws TransformException if an error occurred while converting the test points.
 */
@Test
@DependsOnMethod("testIdentityTransform")
public void testGeographic3D_to_2D() throws FactoryException, TransformException {
    final GeographicCRS sourceCRS = CommonCRS.WGS84.geographic3D();
    final GeographicCRS targetCRS = CommonCRS.WGS84.geographic();
    final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
    assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
    assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
    assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
    assertInstanceOf("operation", Conversion.class, operation);

    final ParameterValueGroup parameters = ((SingleOperation) operation).getParameterValues();
    assertEquals("parameters.descriptor", "Geographic3D to 2D conversion", parameters.getDescriptor().getName().getCode());
    assertTrue  ("parameters.isEmpty", parameters.values().isEmpty());

    transform = operation.getMathTransform();
    assertInstanceOf("transform", LinearTransform.class, transform);
    assertEquals("sourceDimensions", 3, transform.getSourceDimensions());
    assertEquals("targetDimensions", 2, transform.getTargetDimensions());
    Assert.assertMatrixEquals("transform.matrix", Matrices.create(3, 4, new double[] {
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 0, 1
    }), ((LinearTransform) transform).getMatrix(), STRICT);

    isInverseTransformSupported = false;
    verifyTransform(new double[] {
        30, 10,  20,
        20, 30, -10
    }, new double[] {
        30, 10,
        20, 30
    });
    validate();
}
 
Example #23
Source File: CoordinateOperationFinderTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests a single case of Geographic ↔︎ Geocentric conversions.
 */
private void testGeocentricConversion(final CoordinateReferenceSystem sourceCRS,
                                      final CoordinateReferenceSystem targetCRS)
        throws FactoryException
{
    final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
    assertSame      ("sourceCRS", sourceCRS,               operation.getSourceCRS());
    assertSame      ("targetCRS", targetCRS,               operation.getTargetCRS());
    assertEquals    ("name",      "Geocentric conversion", operation.getName().getCode());
    assertInstanceOf("operation", Conversion.class,        operation);
}
 
Example #24
Source File: CoordinateOperationFinderTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Implementation of {@link #testIdentityTransform()} using the given CRS.
 */
private void testIdentityTransform(final CoordinateReferenceSystem crs) throws FactoryException {
    final CoordinateOperation operation = finder.createOperation(crs, crs);
    assertSame      ("sourceCRS",  crs, operation.getSourceCRS());
    assertSame      ("targetCRS",  crs, operation.getTargetCRS());
    assertTrue      ("isIdentity", operation.getMathTransform().isIdentity());
    assertTrue      ("accuracy",   operation.getCoordinateOperationAccuracy().isEmpty());
    assertInstanceOf("operation",  Conversion.class, operation);
    finder = new CoordinateOperationFinder(null, factory, null);        // Reset for next call.
}
 
Example #25
Source File: DefinitionVerifier.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a code indicating in which part the two given CRS differ. The given iterators usually iterate over
 * exactly one element, but may iterate over more elements if the CRS were instance of {@code CompoundCRS}.
 * The returned value is one of {@link #METHOD}, {@link #CONVERSION}, {@link #CS}, {@link #DATUM},
 * {@link #PRIME_MERIDIAN} or {@link #OTHER} constants.
 */
private static int diffCode(final Iterator<SingleCRS> authoritative, final Iterator<SingleCRS> given) {
    while (authoritative.hasNext() && given.hasNext()) {
        final SingleCRS crsA = authoritative.next();
        final SingleCRS crsG = given.next();
        if (!Utilities.equalsApproximately(crsA, crsG)) {
            if (crsA instanceof GeneralDerivedCRS && crsG instanceof GeneralDerivedCRS) {
                final Conversion cnvA = ((GeneralDerivedCRS) crsA).getConversionFromBase();
                final Conversion cnvG = ((GeneralDerivedCRS) crsG).getConversionFromBase();
                if (!Utilities.equalsApproximately(cnvA, cnvG)) {
                    return Utilities.equalsApproximately(cnvA.getMethod(), cnvG.getMethod()) ? CONVERSION : METHOD;
                }
            }
            if (!Utilities.equalsApproximately(crsA.getCoordinateSystem(), crsG.getCoordinateSystem())) {
                return CS;
            }
            final Datum datumA = crsA.getDatum();
            final Datum datumG = crsG.getDatum();
            if (!Utilities.equalsApproximately(datumA, datumG)) {
                if ((datumA instanceof GeodeticDatum) && (datumG instanceof GeodeticDatum) &&
                    !Utilities.equalsApproximately(((GeodeticDatum) datumA).getPrimeMeridian(),
                                                   ((GeodeticDatum) datumG).getPrimeMeridian()))
                {
                    return PRIME_MERIDIAN;
                }
                return DATUM;
            }
            break;
        }
    }
    return OTHER;
}
 
Example #26
Source File: DefaultProjectedCRS.java    From sis with Apache License 2.0 5 votes vote down vote up
/** Formats this {@code Conversion} element. */
@Override protected String formatTo(final Formatter formatter) {
    WKTUtilities.appendName(conversion, formatter, null);
    formatter.newLine();
    append(formatter);
    return WKTKeywords.Conversion;
}
 
Example #27
Source File: DefaultDerivedCRS.java    From sis with Apache License 2.0 4 votes vote down vote up
/** Returns a coordinate reference system of the same type than this CRS but with different axes. */
@Override AbstractCRS createSameType(final Map<String,?> properties, final CoordinateSystem derivedCS) {
    final Conversion conversionFromBase = getConversionFromBase();
    return new Engineering(properties, (EngineeringCRS) conversionFromBase.getSourceCRS(), conversionFromBase, derivedCS);
}
 
Example #28
Source File: GeneralDerivedCrsImpl.java    From geomajas-project-server with GNU Affero General Public License v3.0 4 votes vote down vote up
public Conversion getConversionFromBase() {
	return base.getConversionFromBase();
}
 
Example #29
Source File: PositionalAccuracyConstant.java    From sis with Apache License 2.0 4 votes vote down vote up
/**
 * Convenience method returning the accuracy in meters for the specified operation.
 * This method tries each of the following procedures and returns the first successful one:
 *
 * <ul>
 *   <li>If at least one {@link QuantitativeResult} is found with a linear unit, then the largest
 *       accuracy estimate is converted to {@linkplain Units#METRE metres} and returned.</li>
 *   <li>Otherwise, if the operation is a {@link Conversion}, then returns 0 since a conversion
 *       is by definition accurate up to rounding errors.</li>
 *   <li>Otherwise, if the operation is a {@link Transformation}, then checks if the datum shift
 *       were applied with the help of Bursa-Wolf parameters. This procedure looks for SIS-specific
 *       {@link #DATUM_SHIFT_APPLIED} and {@link #DATUM_SHIFT_OMITTED DATUM_SHIFT_OMITTED} constants.</li>
 *   <li>Otherwise, if the operation is a {@link ConcatenatedOperation}, returns the sum of the accuracy
 *       of all components. This is a conservative scenario where we assume that errors cumulate linearly.
 *       Note that this is not necessarily the "worst case" scenario since the accuracy could be worst
 *       if the math transforms are highly non-linear.</li>
 * </ul>
 *
 * If the above is modified, please update {@code AbstractCoordinateOperation.getLinearAccuracy()} javadoc.
 *
 * @param  operation  the operation to inspect for accuracy.
 * @return the accuracy estimate (always in meters), or NaN if unknown.
 *
 * @see org.apache.sis.referencing.operation.AbstractCoordinateOperation#getLinearAccuracy()
 */
public static double getLinearAccuracy(final CoordinateOperation operation) {
    double accuracy = Double.NaN;
    final Collection<PositionalAccuracy> accuracies = operation.getCoordinateOperationAccuracy();
    for (final PositionalAccuracy metadata : accuracies) {
        for (final Result result : metadata.getResults()) {
            if (result instanceof QuantitativeResult) {
                final QuantitativeResult quantity = (QuantitativeResult) result;
                final Collection<? extends Record> records = quantity.getValues();
                if (records != null) {
                    final Unit<?> unit = quantity.getValueUnit();
                    if (Units.isLinear(unit)) {
                        final Unit<Length> unitOfLength = unit.asType(Length.class);
                        for (final Record record : records) {
                            for (final Object value : record.getAttributes().values()) {
                                if (value instanceof Number) {
                                    double v = ((Number) value).doubleValue();
                                    v = unitOfLength.getConverterTo(Units.METRE).convert(v);
                                    if (v >= 0 && !(v <= accuracy)) {       // '!' is for replacing the NaN value.
                                        accuracy = v;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if (Double.isNaN(accuracy)) {
        /*
         * No quantitative (linear) accuracy were found. If the coordinate operation is actually
         * a conversion, the accuracy is up to rounding error (i.e. conceptually 0) by definition.
         */
        if (operation instanceof Conversion) {
            return 0;
        }
        /*
         * If the coordinate operation is actually a transformation, checks if Bursa-Wolf parameters
         * were available for the datum shift. This is SIS-specific. See field javadoc for a rational
         * about the return values chosen.
         */
        if (operation instanceof Transformation) {
            if (accuracies.contains(DATUM_SHIFT_APPLIED)) {
                return DATUM_SHIFT_ACCURACY;
            }
            if (accuracies.contains(DATUM_SHIFT_OMITTED)) {
                return UNKNOWN_ACCURACY;
            }
        }
        /*
         * If the coordinate operation is a compound of other coordinate operations, returns the sum of their accuracy,
         * skipping unknown ones. Making the sum is a conservative approach (not exactly the "worst case" scenario,
         * since it could be worst if the transforms are highly non-linear).
         */
        if (operation instanceof ConcatenatedOperation) {
            for (final CoordinateOperation op : ((ConcatenatedOperation) operation).getOperations()) {
                final double candidate = Math.abs(getLinearAccuracy(op));
                if (!Double.isNaN(candidate)) {
                    if (Double.isNaN(accuracy)) {
                        accuracy = candidate;
                    } else {
                        accuracy += candidate;
                    }
                }
            }
        }
    }
    return accuracy;
}
 
Example #30
Source File: EPSGFactoryTest.java    From sis with Apache License 2.0 4 votes vote down vote up
/**
 * Tests the "UTM zone 10N" conversion (EPSG:16010).
 *
 * @throws FactoryException if an error occurred while querying the factory.
 */
@Test
@DependsOnMethod("testProjectedWithSharedConversion")
public void testConversion() throws FactoryException {
    final EPSGFactory factory = TestFactorySource.factory;
    assumeNotNull(factory);
    /*
     * Fetch directly the "UTM zone 10N" operation. Because this operation was not obtained in
     * the context of a projected CRS, the source and target CRS shall be unspecified (i.e. null).
     */
    final CoordinateOperation operation = factory.createCoordinateOperation("16010");
    assertEpsgNameAndIdentifierEqual("UTM zone 10N", 16010, operation);
    assertInstanceOf("EPSG::16010", Conversion.class, operation);
    assertNull("sourceCRS", operation.getSourceCRS());
    assertNull("targetCRS", operation.getTargetCRS());
    assertNull("transform", operation.getMathTransform());
    /*
     * Fetch the "WGS 72 / UTM zone 10N" projected CRS.
     * The operation associated to this CRS should now define the source and target CRS.
     */
    final ProjectedCRS crs = factory.createProjectedCRS("32210");
    final CoordinateOperation projection = crs.getConversionFromBase();
    assertEpsgNameAndIdentifierEqual("WGS 72 / UTM zone 10N", 32210, crs);
    assertEpsgNameAndIdentifierEqual("UTM zone 10N", 16010, projection);
    assertNotSame("The defining conversion and the actual conversion should differ since the "
            + "actual conversion should have semi-axis length values.", projection, operation);
    assertInstanceOf("EPSG::16010", CylindricalProjection.class, projection);
    assertNotNull("sourceCRS", projection.getSourceCRS());
    assertNotNull("targetCRS", projection.getTargetCRS());
    assertNotNull("transform", projection.getMathTransform());
    /*
     * Compare the conversion obtained directly with the conversion obtained
     * indirectly through a projected CRS. Both should use the same method.
     */
    final OperationMethod copMethod = ((SingleOperation) operation) .getMethod();
    final OperationMethod crsMethod = ((SingleOperation) projection).getMethod();
    assertEpsgNameAndIdentifierEqual("Transverse Mercator", 9807, copMethod);
    assertEpsgNameAndIdentifierEqual("Transverse Mercator", 9807, crsMethod);
    try {
        assertSame("Conversion method", copMethod, crsMethod);
        assertSame("Conversion method", copMethod, factory.createOperationMethod("9807"));
    } catch (AssertionError error) {
        out.println("The following contains more information about a JUnit test failure.");
        out.println("See the JUnit report for the stack trace. Below is a cache dump.");
        out.println("See the operation method EPSG:9807 and compare with:");
        out.print  ("  - Method obtained directly:   "); out.println(System.identityHashCode(copMethod));
        out.print  ("  - Method obtained indirectly: "); out.println(System.identityHashCode(crsMethod));
        out.println("Content of EPSGFactory cache:");
        factory.printCacheContent(out);
        throw error;
    }
}