You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@sis.apache.org by Michael Arneson <mi...@geotoolkit.net> on 2020/01/27 17:10:15 UTC

Retrieve WGS 84 transforms for CRS conversion

I am trying to find the wgs 84 transform codes between two crs (defined
method getWgs84TransformsFromCrs in attached file Wgs84TransformUtil.java)

I am also trying to find the specified CoordinateOperation between two crs'
by looking at the transform code  (defined method getCoordinateTransform in
attached file Wgs84TransformUtil.java).

Is there a simpler way to do this without having to know that a
CoordinateOperation is a ConcatenatedOperation and looking through all the
SingleOperations.

Additionally, I noticed that my code doesn't work if I changed
the following lines
        CoordinateReferenceSystem fromCrs = CRS.forCode(fromEpsg);
        CoordinateReferenceSystem toCrs = CRS.forCode("EPSG:4326");
to
        CoordinateReferenceSystem originalFromCrs= CRS.forCode(fromEpsg);
        CoordinateReferenceSystem originalToCrs= CRS.forCode("EPSG:4326");
        CoordinateReferenceSystem fromCrs= AbstractCRS.castOrCopy(
originalFromCrs ).forConvention(AxesConvention.DISPLAY_ORIENTED);
        CoordinateReferenceSystem toCrs= AbstractCRS.castOrCopy(
originalToCrs ).forConvention(AxesConvention.DISPLAY_ORIENTED);

Is there a way to get the transform codes between two
CoordinateReferenceSystems when using  AxesConvention.DISPLAY_ORIENTED?
The reason I ask this is it would be ideal for the MathTransform.transform
call to be returned in the order of Longitude, Latitude or x, y.

Thanks,
-- 
*Michael Arneson*

*Software Engineer*



*Office:* +1 (713) 975-7434

michael.arneson@int.com

*INT *| *Empowering Visualization*

Re: Retrieve WGS 84 transforms for CRS conversion

Posted by Martin Desruisseaux <ma...@geomatys.com>.
Hello Michael

There is a few tips that may simplify some code. Instead of:

    CoordinateReferenceSystem toCrs = CRS.forCode("EPSG:4326");
    AbstractCRS displayOrientedToCrs = AbstractCRS.castOrCopy(toCrs).forConvention(AxesConvention.DISPLAY_ORIENTED);

The following convenience method can be used:

    CoordinateReferenceSystem toCrs = CommonCRS.WGS84.normalizedGeographic();

Javadoc: 
http://sis.apache.org/apidocs/org/apache/sis/referencing/CommonCRS.html

------------------------------------------------------------------------

Instead of the work done in ExtentUtil.getExtentFromAreaOfUse(…), the 
following can be used. That method has the advantage to work in 
n-dimension, to take curvatures in account as illustrated in javadoc, to 
handle the anti-meridian, and to handle the polar special cases too:

    GeneralEnvelope env = new GeneralEnvelope(fromCRS);
    env.setRange(0, minX, maxX);
    env.setRange(1, minY, maxY);
    // More dimensions could be set too, if any.
    Envelope result = Envelopes.transform(env, toCRS);
    GeographicBoundingBox asBBox = new DefaultGeographicBoundingBox(result);

Javadoc: 
http://sis.apache.org/apidocs/org/apache/sis/geometry/Envelopes.html

------------------------------------------------------------------------

Instead of Wgs84TransformUtil.getEpsgTransformCode(…), the following can 
be used. Note: a future SIS version may use java.util.Optional, but that 
would be a 2.0 series of SIS (all 1.x versions will keep current API).

    Identifier id = IdentifiedObjects.getIdentifier​(crs, Citations.EPSG);
    if (id != null) {
         String code = id.getCode();
    }

Javadoc: 
http://sis.apache.org/apidocs/org/apache/sis/referencing/IdentifiedObjects.html 
— see also if lookupEPSG may be useful.

------------------------------------------------------------------------

Instead of Wgs84TransformUtil.getCoordinateTransform(…), the following 
may be faster:

    CoordinateOperationAuthorityFactory opFactory = (CoordinateOperationAuthorityFactory) CRS.getAuthorityFactory​("EPSG");
    CoordinateOperation op = opFactory.createCoordinateOperation(wgs84TransformCode);

Javadoc: 
http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/operation/CoordinateOperationAuthorityFactory.html 
— see also if createFromCoordinateReferenceSystemCodes may be of useful.

------------------------------------------------------------------------

Instead of Wgs84TransformUtil.getBoundingBoxFromTransformation(…), the 
following can be used:

    GeographicBoundingBox box = CRS.getGeographicBoundingBox​(transformation);

Javadoc: http://sis.apache.org/apidocs/org/apache/sis/referencing/CRS.html

------------------------------------------------------------------------

Le 27/01/2020 à 18:10, Michael Arneson a écrit :

> I am also trying to find the specified CoordinateOperation between two 
> crs' by looking at the transform code (defined method 
> getCoordinateTransform in attached file Wgs84TransformUtil.java). Is 
> there a simpler way to do this without having to know that a 
> CoordinateOperation is a ConcatenatedOperation and looking through all 
> the SingleOperations.
>
It depends. If you have the source and target CRS defined by EPSG codes, 
then the above-cited createFromCoordinateReferenceSystemCodes method be 
better suited. Otherwise the current code is more general. About looking 
at the SingleOperations, I'm not sure what information is desired 
exactly. The EPSG code of a SingleOperation may describe just one step 
of the transformation between two CRS. That step may not be sufficient 
for describing the transformation between the two CRS, even when 
ignoring axis reordering. The EPSG database has transformations defined 
by 2 or more steps.


> Is there a way to get the transform codes between two 
> CoordinateReferenceSystems when using AxesConvention.DISPLAY_ORIENTED?
>
You may try the following (omitting the checks for null return values 
for simplicity):

    IdentifiedObjectFinder finder = IdentifiedObjects.newFinder(null);
    finder.setIgnoringAxes(true);
    CoordinateReferenceSystem sourceEPSG = (CoordinateReferenceSystem) finder.findSingleton(sourceCRS);
    CoordinateReferenceSystem targetEPSG = (CoordinateReferenceSystem) finder.findSingleton(targetCRS);
    CoordinateOperation op = CRS.findOperation(sourceEPSG, targetEPSG);

In above example IdentifiedObjectFinder is used for searching CRS in the 
EPSG database equivalent to the given CRS, ignoring axis order. The CRS 
found can now be used for searching the CoordinateOperation in EPSG 
database again. Ideally Apache SIS should do those steps itself. If you 
have a code reproducing the problem, it may be worth to create a JIRA issue.

     Regards,

         Martin