SkillAgentSearch skills...

CrsTransformations

Coordinate Reference System Transformations. This is a "JVM library" implemented with Kotlin, but usable from e.g. Java/Kotlin/Scala/Groovy/Jython/JRuby (see the sample code). Most of the test code is written with Java, and the third-part libraries used from Kotlin are also implemented with Java.

Install / Use

/learn @TomasJohansson/CrsTransformations

README

License Notice

Notice that the "core" library with the adapter API and general code is released with MIT License.
However, the adapter implementations libraries are licensed in the same way as the adapted libraries which is specified in separate "LICENSE_NOTICE" files (in the adapter base directories) for each such implementation.

Information about this Coordinate Reference System Transformations library

This Kotlin/Java/JVM project is intended for transforming coordinates between different coordinate reference systems (CRS).
The code has been implemented with Kotlin but the tests (and the generated constants in the subproject "crs-transformation-constants") are implemented with Java.
There is sample code for the following JVM languages (tested with Windows 10 and the language versions specified below):

The third-part libraries (the adaptee's below) are Java libraries.
Versions of Java and Kotlin: Java 8 and Kotlin 1.8.0
(in the release 2.0.1 but since then the Kotlin version might have been upgraded in this git repository)

Known problems

Android/GeoTools problem

The GeoTools adapter CrsTransformationAdapterGeoTools i.e. the implementation using GeoTools does not work for Android.
As you can see in the implementation, it uses the methods "CRS.decode" and "CRS.findMathTransform" in the class org.geotools.referencing.CRS which is currently coupled with dependencies to the Java GUI libraries "awt" and "swing" (java.awt.geom.Point2D , java.awt.geom.Rectangle2D, javax.swing.event.ChangeEvent , javax.swing.event.ChangeListener)

Jython/GeoTools problem

The GeoTools adapter does not work when using Jython, as mentioned in the comments in the Jython sample file sample_code/jython/CrsTransformation.py

GeoTools and the Maven Central repository

GeoTools does not seem to release all needed artifacts to "Maven Central" and therefore you should add another repository in your gradle or maven configuration file.
The currently documented repository URL for GeoTools is:
https://repo.osgeo.org/repository/geotools-releases/
(according to https://github.com/geotools/geotools/blob/main/pom.xml and https://mvnrepository.com/repos/geotools-releases)
but also this URL:
https://repo.osgeo.org/repository/release/
(according to https://docs.geotools.org/latest/userguide/build/maven/repositories.html)
("currently" = 2023-01-07 when the above three URL's github.com/mvnrepository.com/geotools.org, were checked)

See the below sections Gradle configuration and Maven configuration regarding how to configure the above GeoTools repository.

If you are using Scala/SBT you can see the resolvers configuration in the file sample_code/scala/build.sbt.
If you are using Ant/Ivy you can see the resolvers configuration in the file sample_code/ivy_dependencies/ivysettings.xml

Usage

The methods for transforming coordinates are defined in the interface CrsTransformationAdapter.
There are ten classes implementing the interface. Six 'leafs' and four 'composites'.
Each leaf adapter is using some adaptee library for the implementation.
The four 'composites' are using the leafs like this:

  • Median (transform with many leafs and use the median latitude/longitude result as the aggregated result)
  • Average (transform with many leafs and use the average latitude/longitude result as the aggregated result)
  • Weighted average (transform with many leafs and use the weighted average latitude/longitude result as the aggregated result)
  • First success (iterate a list of leafs and try to transform until some result seem to have succeeded)

Java:

        // The interface with ten implementations as illustrated below
        CrsTransformationAdapter crsTransformationAdapter;
        // The interface is defined in the library "crs-transformation-adapter-core" with this full name:
        // com.programmerare.crsTransformations.CrsTransformationAdapter        

        // The six 'Leaf' implementations:

        // Library "crs-transformation-adapter-impl-proj4j", class:
        // com.programmerare.crsTransformationAdapterProj4J.CrsTransformationAdapterProj4J;
        crsTransformationAdapter = new CrsTransformationAdapterProj4J();

        // Library "crs-transformation-adapter-impl-proj4jlocationtech", class:
        // com.programmerare.crsTransformationAdapterProj4jLocationtech.CrsTransformationAdapterProj4jLocationtech;
        crsTransformationAdapter = new CrsTransformationAdapterProj4jLocationtech();
        
        // Library "crs-transformation-adapter-impl-orbisgis", class:
        // com.programmerare.crsTransformationAdapterOrbisgisCTS.CrsTransformationAdapterOrbisgisCTS;        
        crsTransformationAdapter = new CrsTransformationAdapterOrbisgisCTS();

        // Library "crs-transformation-adapter-impl-nga", class:
        // com.programmerare.crsTransformationAdapterNgaGeoInt.CrsTransformationAdapterNgaGeoInt;
        crsTransformationAdapter = new CrsTransformationAdapterNgaGeoInt();

        // Library "crs-transformation-adapter-impl-geotools", class:
        // com.programmerare.crsTransformationAdapterGeoTools.CrsTransformationAdapterGeoTools;        
        crsTransformationAdapter = new CrsTransformationAdapterGeoTools();

        // Library "crs-transformation-adapter-impl-goober", class:
        // com.programmerare.crsTransformationAdapterGooberCTL.CrsTransformationAdapterGooberCTL;        
        crsTransformationAdapter = new CrsTransformationAdapterGooberCTL();
        // - - - - - - - - - - - -

        // The four 'Composite' implementations below are all located in the library
        // "crs-transformation-adapter-core" and the factory class is:
        // com.programmerare.crsTransformations.compositeTransformations.CrsTransformationAdapterCompositeFactory

        crsTransformationAdapter = CrsTransformationAdapterCompositeFactory.createCrsTransformationMedian();

        crsTransformationAdapter = CrsTransformationAdapterCompositeFactory.createCrsTransformationAverage();

        crsTransformationAdapter = CrsTransformationAdapterCompositeFactory.createCrsTransformationFirstSuccess();

        // All of the above three factory methods without any parameter will try to use as many of the six 'leaf' 
        // implementations as are available at the class path (e.g. are included as dependencies with Gradle or Maven).
        // All above three factory methods are also overloaded with methods taking 
        // a parameter 'List<CrsTransformationAdapter>' if you prefer to explicit define which 'leafs' to use.

        // The fourth 'Composite' below does not have any overloaded method without parameter 
        // but if you want to use a result created as a weighted average then the weights need 
        // to be specified per leaf implementation as in the example below.

        crsTransformationAdapter = CrsTransformationAdapterCompositeFactory.createCrsTransformationWeightedAverage(Arrays.asList(
            CrsTransformationAdapterWeight.createFromInstance(new CrsTransformationAdapterProj4J(), 1.0),
            CrsTransformationAdapterWe
View on GitHub
GitHub Stars4
CategoryDevelopment
Updated8mo ago
Forks2

Languages

Kotlin

Security Score

82/100

Audited on Jul 14, 2025

No findings