Code Monkey home page Code Monkey logo

proj4j's Introduction

Proj4J GitHub Action Status Maven Central

Proj4J is a Java library for converting coordinates between different geospatial coordinate reference systems. It is designed to be compatible with proj.4 parameters and derives some of its implementation from the proj.4 sources.

Proj4J is a project in the LocationTech working group of the Eclipse Foundation.

LocationTech

User Guide

Proj4J artifacts are available on maven central.

!Important! As of 1.2.2 version, proj4-core contains no EPSG Licensed files. In order to make proj4j properly operate, it makes sense to consider proj4-epsg dependency usage.

Using Proj4J with Maven

To include Proj4J in a Maven project, add a dependency block like the following:

<properties>
    <proj4j.version>{latest version}</proj4j.version>
</properties>
<dependency>
    <groupId>org.locationtech.proj4j</groupId>
    <artifactId>proj4j</artifactId>
    <version>${proj4j.version}</version>
</dependency>

where {latest version} refers to the version indicated by the badge above.

Proj4j EPSG

Proj4J-EPSG module distributes a portion of the EPSG dataset. This artifact is released the EPSG database distribution license.

To include Proj4J-EPSG in a Maven project, add a dependency block like the following:

<properties>
    <proj4j.version>{latest version}</proj4j.version>
</properties>
<dependency>
    <groupId>org.locationtech.proj4j</groupId>
    <artifactId>proj4j-epsg</artifactId>
    <version>${proj4j.version}</version>
</dependency>

where {latest version} refers to the version indicated by the badge above.

Using Proj4J with Gradle

To include Proj4J in a Gradle project, add a dependency block like the following:

dependencies {
    implementation 'org.locationtech.proj4j:proj4j:{latest version}'
}

where {latest version} refers to the version indicated by the badge above.

Proj4j EPSG

Proj4J-EPSG module distributes a portion of the EPSG dataset. This artifact is released the EPSG database distribution license.

To include Proj4J-EPSG in a Gradle project, add the following line to the dependency block:

    implementation 'org.locationtech.proj4j:proj4j-epsg:{latest version}'

where {latest version} refers to the version indicated by the badge above.

Basic Usage

The following examples give a quick intro on how to use Proj4J in common use cases.

Transforming coordinates from WGS84 to UTM

Obtaining CRSs by name
CRSFactory crsFactory = new CRSFactory();
CoordinateReferenceSystem WGS84 = crsFactory.createFromName("epsg:4326");
CoordinateReferenceSystem UTM = crsFactory.createFromName("epsg:25833");
Obtaining CRSs using parameters
CRSFactory crsFactory = new CRSFactory();
CoordinateReferenceSystem WGS84 = crsFactory.createFromParameters("WGS84",
    "+proj=longlat +datum=WGS84 +no_defs");
CoordinateReferenceSystem UTM = crsFactory.createFromParameters("UTM",
    "+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");
Transforming coordinates
CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
CoordinateTransform wgsToUtm = ctFactory.createTransform(WGS84, UTM);
// `result` is an output parameter to `transform()`
ProjCoordinate result = new ProjCoordinate();
wgsToUtm.transform(new ProjCoordinate(lon, lat), result);

Building, Testing and installing locally

mvn clean install

Publish to Maven Central

mvn -Dmaven.test.skip=true -Pcentral clean package deploy

For more details see HOWTORELEASE.txt.

Contributing

If you are interested in contributing to Proj4J please read the Contributing Guide.

proj4j's People

Contributors

barthanssens avatar bchapuis avatar bosborn avatar dependabot[bot] avatar dr-jts avatar ea23del avatar echeipesh avatar halset avatar imperio-wxm avatar lossyrob avatar neutius avatar noberasco avatar pomadchin avatar rfecher avatar rhuitl avatar samuelcregan17 avatar scaddenp avatar sebasbaumh avatar sebkur avatar skinkie avatar tuan-nng avatar yaqiang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

proj4j's Issues

Support for polar stereographic with alternate scales

I wasn't able to find user-discussions on the web, so I am posting this question as an issue.

I wish to access a data set built on the polar stereographic with scale set to be true at 75 north. Although it looks like the StereographicAzimuthalProjection class has support (undocumented) for the Universal Polar Stereographic projection (UPS). The UPS has a true scale at about 81.11 N, so it doesn't quite fit my requirements. I suppose I could do a hack, but I was wondering if there was a better way to proceed.

Transformation error from 5514 to 4326

I would like to point out the mistake from ticket #25 again.

The conversion from 4326 to 5514 works correctly, but in the opposite direction (5514 -> 4326) the calculation still returns incorrect values of approx. 24.8299 -59.94829. It doesn't really matter what values I enter, there are always numbers similar to those listed (numbers in distant decimal positions and Z value change).

For example, my code:

CRSFactory crsFactory = new CRSFactory();
CoordinateReferenceSystem t1 = crsFactory.createFromName("epsg:4326");
CoordinateReferenceSystem t2 = crsFactory.createFromName("epsg:5514");
CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
CoordinateTransform tran = ctFactory.createTransform(t2, t1);
ProjCoordinate result_p2 = new ProjCoordinate();
ProjCoordinate vstup=new ProjCoordinate( -743093.7321490766, -1044381.7725184687);
tran.transform(vstup, result_p2);

This code is supposed to return 14.42, 50.075, but it does return 24.82998756399294 -59.94829824087518. Similar result numbers are for any input. Obviously there will be an error somewhere in the transformation equation. It works in one direction, not inversely.

More flexible readEpsgFromParameters function

In case a bit corrupted proj4 string passed (i.e. “+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs”1 instead of the correct “+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs”). The readEpsgFromParameters function returns null. I would expected it to return the WebMercator EPSG code:

val proj4string = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs"
val crsFactory = new CRSCache()
val epsg = crsFactory.readEpsgFromParameters(proj4string) //> null

May be it is possible to make this parser more flexible.

Reference to the discussion: locationtech/geotrellis#3281 (comment)

ntv2 grid support

ntv2 grids, such as ntv2_0.gsb should be supported. ntv2 files are mentioned in Grid.java, but there's no corresponding parser for them.

VN2000 Error Exception in thread "main" java.lang.IllegalStateException: Latitude is out of range: 9738.514891355962

    CRSFactory crsFactory = new CRSFactory();
    CoordinateReferenceSystem WGS84 = crsFactory.createFromParameters("WGS84",
            "+proj=longlat +datum=WGS84 +no_defs");
    CoordinateReferenceSystem UTM = crsFactory.createFromParameters("VN-2000",
            "+proj=longlat +ellps=WGS84 +towgs84=-191.90441429,-39.30318279,-111.45032835,0.00928836,-0.01975479,0.00427372,0.252906278 +no_defs");
    CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
    CoordinateTransform wgsToUtm = ctFactory.createTransform(WGS84, UTM);

// result is an output parameter to transform()
ProjCoordinate result = new ProjCoordinate();
wgsToUtm.transform(new ProjCoordinate(13, 13), result);
System.err.println(result);

What's the maintenance status?

Hi there, I came across this proposal and was wondering if there is still a plan to maintain this library? The repo linked in the proposal is this one by @dwins and it looks like the original is over in the Proj4j organization, but it's getting pretty stale. It seemed to receive a series of updates a couple years ago, but there hasn't been a new release.

Would be great to see a group pick this up again!

Equidistant Azimuthal (ESRI:54032) test failed

The equidistant azimuthal (ESRI:54032) projection test as following:

@Test
public void testEquidistantAzimuthal() {
    checkTransformFromWGS84("ESRI:54032", 120., 40., 8995111.253396044, 8710143.05796729);
}

The test failed with information below:

WGS84(LongLat/WGS84) => ESRI:54032(Equidistant Azimuthal/WGS84)
[120.0, 40.0] -> [5404116.851692142, 5201043.932894523] (expected: [8995111.253396044, 8710143.05796729] tol: 1.0E-4 diff: 3590994.4017039016 )
FAIL
Src CRS: +title=long/lat:WGS84 +proj=longlat +datum=WGS84 +units=degrees
Tgt CRS: +proj=aeqd +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs

1 degree == 1 metre according to units

Because degrees have a value of 1, the following test passes

val degrees = Units.DEGREES
val metres = Units.METRES
val metresPerUnit = Units.convert(1.0, degrees, metres)
assertThat(metresPerUnit, `is`(1.0))

I expected that I could convert a number in metres into the unit of an arbitrary CRS with Units.convert. Instead, it appears from the source that I can only convert similar units, such as metric to metric or imperial to imperial.

Is this the indented behavior?

Develop approach to run PROJ.4 unit tests

It would be great to be able to run all or most of the PROJ.4 unit tests against Proj4J.

It appears that the current testing framework for PROJ.4 uses a custom utility called GIE. This reads a custom format originating in a test utility called GIGS. There are a LOT of unit tests.

Possible approaches:

  1. Port the unit tests to a format which Proj4J can run. This should be a declarative format, for maximum usabliy and ease of maintenance. The current MetaCRS CSV format is too hard to work with IMHO - a better format should be devised. This will also require a transpiler from the GIE format to the Proj4J format.

  2. Develop a test runner that can handle the GIGS/GIE format directly. Hopefully this won't be too hard. The advantage here is that it will be easier to keep the tests in synch with PROJ.4

Note that it is very likely that not all PROJ4 tests will run in Proj4J, due to differences in supported functionality. There will need to be a way to indicate which tests should not be run (or transpiled)

Will there be support for +geoidgrids ? its commonly used for height transformation

Hi.

Our transformation uses Slovakia_ETRS89h_to_Baltic1957.gtx file that should be used as geoidgrid

Will there be support for +geoidgrids soon ? With some python code we can get correct transformations, but maybe because of we cant use .gtx file for transformation using proj4 yet, we are getting height always around 0.17 meters.

our example :

CoordinateReferenceSystem ETRS89 = 
  CRS.createFromParameters(
    "lonlat", 
    "+proj=longlat +ellps=bessel +towgs84=589,76,480,0,0,0,0 +no_defs +nadgrids=Slovakia_JTSK03_to_JTSK.gsb"
  );

CoordinateReferenceSystem SJSTK = 
  CRS.createFromParameters(
    "5514", 
    "+proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 +alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +towgs84=485.021,169.465,483.839,7.786342,4.397554,4.102655,0 +units=m +no_defs +geoidgrids=Slovakia_ETRS89h_to_Baltic1957.gtx"
  ); 

I have imported files correctly, so we can get lon lat correctly, but height is incorrect.

Thanks.

Overriding `hashCode` method when overriding `equals` method

As of pull request #45 the class org.locationtech.proj4j.proj.Projection and ten of its subclasses override the equals method that is inherited from the Object class.

However, the hashCode method is not overridden, and I'm pretty sure that's considered bad practice. This is described in more detail by Joshua Bloch in Item 11 of his book Effective Java, but it boils down to this: if two objects are considered equal by the equals method, they should also return the same value when their respective hashCode method is called.

Overriding equals but not hashCode violates the contract for the hashCode method, and makes instances of this class unusable for collections such as HashMap and HashSet.

Invalid conversion EPSG:5514 - JTSK

I get wrong result for EPSG:5514 - JTSK specified by proj4j parameters. Conversion WGS84 -> JTSK is almost correct except SIGNs. Conversion from JTSK -> WGS84 is WRONG.

JTSK : ProjCoordinate[747963.6497538437 1041493.3287851878 NaN] // negative signs
WGS84: ProjCoordinate[24.834517978270924 -59.948074516468246 NaN] // - wrong should be: 14.346996204306555,50.09465901453681

Values and code example is derived from JavaScript:
http://jsfiddle.net/xiceph/79QHW/1/

proj4js/proj4js#115

    private static final CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
    private static final String JTSK_PARAM_5514 = "+title=Krovak +proj=krovak +lat_0=49.5 +lon_0=24.83333333333333 +alpha=30.28813972222222 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m +towgs84=570.8,85.7,462.8,4.998,1.587,5.261,3.56 +no_defs";
    private static final CoordinateReferenceSystem WGS84 = new CRSFactory().createFromName("epsg:4326");
    private static final CoordinateReferenceSystem JTSK_5514 = new CRSFactory().createFromParameters("JTSK", JTSK_PARAM_5514);

    public static void main(final String[] args) {
        CoordinateTransform transFromWGS84 = ctFactory.createTransform(WGS84, JTSK_5514);
        CoordinateTransform transToWGS84 = ctFactory.createTransform(JTSK_5514, WGS84);
        ProjCoordinate pout = new ProjCoordinate();
        ProjCoordinate srcWGS84 = new ProjCoordinate( 14.346996204306555,50.09465901453681);
        System.out.println("JTSK : " + transFromWGS84.transform(srcWGS84, pout));
        pout = new ProjCoordinate( -747963.64999999851, -1041493.3299999982);
        System.out.println("WGS84: " + transToWGS84.transform(pout, new ProjCoordinate()));
}

WebMercator EPSG code retrieved from proj4 parameters returns a legacy value

The EPSG code of WebMercator projection created from the proj4 string returns a legacy value;
EPSG:3785 instead of EPSG:3857; to reproduce the behavior use the following code:

crsFactory
  .readEpsgFromParameters("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs")

CRSCache Constructors?

The following methods in CRSCache are having the same name as the class, are these constructors returning a result?
I do not know how Java pulls this, but this will not work in many languages!

public class CRSCache {
    .....
    public CRSCache CRSCache() {
        crsCache = new ConcurrentHashMap<>();
        epsgCache = new ConcurrentHashMap<>();
        return this;
    }

    public CRSCache CRSCache(ConcurrentHashMap<String, CoordinateReferenceSystem> crsCache, 
             ConcurrentHashMap<String, String> epsgCache) {
        this.crsCache = crsCache;
        this.epsgCache = epsgCache;
        return this;
    }
    .....
}

LandsatProjection: Inverse?

LandsatProjection indicate support for inverse, but the inverse code is commented out. What is the state of inverse method?

Reprojecting British National Grid (27700) coords to Mercator (3857) using Proj4j

On epsg.io https://epsg.io/transform#s_srs=27700&t_srs=3857&x=327420.9886680&y=690284.5471100 the BNG easting/northing coodinates 327420.988668 690284.547110 reproject correctly to -352695.04 7578309.23. If I attempt to reproject the same coordinates using proj4j (0.1.0) with the following code:

Double easting = 327420.988668;
Double northing = 690284.54711;
CoordinateReferenceSystem BNG = crsFactory.createFromParameters("EPSG:27700", "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs");
CoordinateReferenceSystem MERCATOR = crsFactory.createFromName("EPSG:3857");
CoordinateTransform trans = ctFactory.createTransform(BNG, MERCATOR);
ProjCoordinate in = new ProjCoordinate(easting, northing);
ProjCoordinate out = new ProjCoordinate();
trans.transform(in, out);
log.info(String.format("%s : %s", out.x, out.y));

I get -352695.04030562507 : 7542788.088927755. The Y coord is around 30 miles south of the correct position. If I use version 1.0.0 of proj4j, I get -352535.43434034986 : 7578324.217405743, which is much closer but still around 200 meters out.

Incidently if I reproject first to EPSG:4326 then to EPSG:3857, I get the correct result.

Improve proj4j tests to reflect the recent changes and the moved out EPSG resources

After separating the project into two, we may get some confusing errors; i.e.

java.lang.IllegalStateException: Unable to access CRS file: proj4/nad/epsg
  at org.locationtech.proj4j.io.Proj4FileReader.readParametersFromFile(Proj4FileReader.java:44)
  at org.locationtech.proj4j.io.Proj4FileReader.getParameters(Proj4FileReader.java:119)
  at org.locationtech.proj4j.CRSFactory.createFromName(CRSFactory.java:83)
  at org.apache.calcite.runtime.ProjectionTransformer.<init>(ProjectionTransformer.java:57)
  at org.apache.calcite.runtime.SpatialTypeFunctions.ST_Transform(SpatialTypeFunctions.java:[1196]

This task is to improve error messages and documentation.

cc @bchapuis

Problem with omerc projection e.g. EPSG: 3375

Hi there guys, I am thinking about swapping my app (MapitGIS) to locationtech library, one of my users would like to use projection 3375, however I am running into similar problem as described here:

https://gis.stackexchange.com/questions/261723/proj4js-gives-wrong-result-for-epsg3375

for: 3.06268465621428, 101.70979078430528 (lat,lon)

I am getting 744626.6428051005, -103618.62269607143 result.

Expected: 412597.532715, 338944.957259

Any idea?

Kind Regards,
Andrzej

Use of PROJ string or WKT string is prone to definition ambiguities

We recently faced an issue using PROJ4J as our PROJ String wasn't recognized properly by the PROJ4J parser.

Here is a Scala snippet illustrating the issue

scala> import geotrellis.proj4._
import geotrellis.proj4._

scala> CRS.fromString("+proj=lcc +lat_1=49 +lat_2=77 +lat_0=49 +lon_0=-95 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs")
res1: geotrellis.proj4.CRS = lcc-CS
scala> res1.epsgCode
res2: Option[Int] = Some(3978)

scala> CRS.fromString("+proj=lcc +lat_0=49 +lon_0=-95 +lat_1=49 +lat_2=77 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs")
res3: geotrellis.proj4.CRS = lcc-CS
scala> res3.epsgCode
res4: Option[Int] = None

Above PROJ definitions are corresponding to string representation that are returned respectively from GDAL2 (PROJ4) and GDAL3 (PROJ6/7) utility tools. PROJ4J will only recognized the first one because the current PROJ4J parser seems to perform strict exact string matching in projection lookup and switching parameters ordering is affecting this parsing.

We would recommend avoiding the use of PROJ string or WKT string as it could be prone to definition ambiguities as illustrated above and as also reported in #65.

The expected behavior would be that both representations should resolve as EPSG code 3978 without the need to explicitly maintain various representation of the projection definition.

PROJ6/7 also introduced a new approach for projection definition management (proj.db) that can potentially be leveraged here.

Proj4j should not use the Apache License if it contains the EPSG data set

Proj4j should not use the Apache License while it continues to contain the EPSG data set. The licensing terms are not compatible. Use of the EPSG data set implies the user's acceptance of EPSG's conditions (such as 'no commercial use'), but the Apache License implies that there are no such conditions.

You can't say 'the users should have read the fine print', because the whole point of the Apache License is that there is no fine print.

In Apache Calcite we used Proj4j, and took at face value Proj4j's assertion that it was under the Apache license. In so doing, we have placed our users in legal jeopardy because they may have used Calcite's ST_Transform function for commercial purposes. See CALCITE-5399 for more details.

I think it would be irresponsible for the authors of Proj4j to continue to license under Apache License. Everyone who uses Pro4j is getting a time bomb, and may not know it. (Sure, it sucks that EPSG is not available under an open source license. But you can't hide that fact under a layer of software abstraction.)

May I suggest the following solution. Split the EPSG library into a separate library (jar file) that is NOT under an open source license, say proj4j-data. Keep the rest of the library the same, but make the dependency optional. If the user explicitly downloads proj4j-data and places it on the classpath (thereby signaling their consent to the terms), then proj4j will work as normal. If they do not, pro4j will work in a reduced capacity. Maybe that capacity is massively reduced, I don't know.

Another possible solution. If the discussion on CALCITE-5399, Martin Desruisseaux suggests that Proj4j implements GeoAPI interfaces. If so, downstream projects like Calcite could depend on only those interfaces, and the user could download and "plug in" as an implementation of those interfaces. Calcite would ship with a 'dumb' implementation of those interfaces that did not use the EPSG data set, but would contain instructions on its web site for people to download Proj4j if they agreed with the EPSG conditions.

In release 1.2.0, the pom file contains incorrect version '1.2.0-SNAPSHOT'

In release 1.2.0, the pom file contains incorrect version '1.2.0-SNAPSHOT'. It should be '1.2.0'.

See https://search.maven.org/remotecontent?filepath=org/locationtech/proj4j/proj4j/1.2.0/proj4j-1.2.0.pom and also https://central.sonatype.dev/artifact/org.locationtech.proj4j/proj4j/1.2.0-SNAPSHOT/versions

This caused problems when I tried to upgrade Calcite to use it. See https://github.com/apache/calcite/pull/3001/checks.

Conversion problem from EPSG:2393 to EPSG:4326

Not sure if it's me doing something wrong... When running cs2cs with PROJ I get:

echo 6675487 3385780 0 | cs2cs EPSG:2393 EPSG:4326 -f %.15f
60.174995098323301 24.938895095805286 0.000000000000000

This is correct.

But when I try the same (I assume) with proj4j:

CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
CRSFactory csFactory = new CRSFactory();

CoordinateReferenceSystem crs1 = csFactory.createFromName("EPSG:2393");
CoordinateReferenceSystem crs2 = csFactory.createFromName("EPSG:4326");
CoordinateTransform trans = ctFactory.createTransform(crs1, crs2);

ProjCoordinate p1 = new ProjCoordinate();
ProjCoordinate p2 = new ProjCoordinate();

p1.x = 6675487;
p1.y = 3385780;

trans.transform(p1, p2);

System.out.println(p2.x + ", " + p2.y);

I get:

58.03298223195199, 26.844729418500016

Which is way off. Something wrong with EPSG:2393 proj4j vs proj? I have no experience on this field, just trying to use the library...

Reprojection results seem to be too imprecise

The issue might be the same as #104.

I noticed that transforming coordinates between projections does not give very precise results.

For instance, consider the following projection:

+proj=lcc +lat_1=45.849 +lat_2=45.849 +lat_0=46.0086 +lon_0=11.4 +R=6370

Projecting the point (-472.97925020089707, -94.67829995316788) from this projection to WGS84 should give:

(5.378868945208383, 44.996568013546536)

(which is the result I get from netCDF-java or proj4js)

But it gives:

(5.3891133171636625, 44.99522341452963)

Which is ~0.01 degrees of error on the longitude, and ~0.001 of error on the latitude.

NullPointerException on transform() when using CoordinateReferenceSystem.CS_GEO

Hi,
Were trying to upgrade to this library from lib:proj4j:0.1.0 due to a bug we found that was fixed here.

We have code that transforms from EPSID:3857 to 4326by using CoordinateReferenceSystem.CS_GEO as destination.

However, it seems that in such scenario the code throws NPE on this line, because for CS_GEO projection is null.

I saw that the original code has some TODO's:

//TODO: adjust src Prime Meridian if specified
//TODO: adjust target Prime Meridian if specified

And I suspect that when fixing this TODO there is a missing null check (check if projection is null).

Am I correct? Is it possible to fix that? Should I submit a PR?

How to incorporate proj 5.0 changes?

What should the process be for starting to think about incorporating proj’s 5.0 overall API changes (in addition to the testing changes being addressed by #9)?

It seems like proj4j is going to eventually need to incorporate proj’s new pipeline and some port of the changed API’s functionality to be able to keep up with upstream’s changes, especially as projections start to be redefined with this new process. Is a good starting point to add time in as a fourth variable to projected coordinates and start implementing the various pipeline operations accordingly? Would it be better to make a new object like ProjCoordinate4D for this (replicating proj’s model of new things living in the “PJ_” api), or would it be better to add “t” into the existing ProjCoordinate and feather in that functionality as is?

Updating EPSG database

What should the process be for updating the EPSG database? proj.4 uses version 9.2 here but I'm not sure how that file should be cited in terms of ownership on this project (especially re the Eclipse CLA).

Moreover, using an updated EPSG database causes the test from #3 to fail again. Would it be acceptable to change the test reprojected value to the one generated by converting the point through PostGIS (which itself uses actual proj.4)?

New Zealand Map Grid not working.

  ```

CRSFactory crsf = new CRSFactory();
CoordinateTransformFactory ctf = new CoordinateTransformFactory();
CoordinateReferenceSystem epsg4326 = crsf.createFromName("EPSG:4326");
CoordinateReferenceSystem crs = crsf.createFromName("EPSG:27200)); //NZ Map grid
CoordinateTransform toEPSG4326 = ctf.createTransform(crs,epsg4326);
ProjCoordinate inputPt = new ProjCoordinate(2939247.5, 6752871.3); // should return lon 177.65067, lat -34.3252
ProjCoordinate outputPt = new ProjCoordinate();
toEPSG4326.transform(inputPt, outputPt);


This is throwing error (latitude is out of range). 

Robinson projection (ESRI:54030) test failed

Following test for Robinson projection failed.

    @Test
    public void testRobinson() {
        checkTransform("+proj=latlong +datum=WGS84", -30, 40, "+proj=robin +datum=WGS84", -2612095.95, 4276351.58, 2e-1);
        checkTransformFromWGS84("ESRI:54030", -30., 40., -2612095.954698802, 4276351.583838239);
        checkTransformToWGS84("ESRI:54030", -2612095.954698802, 4276351.583838239, -30., 40., 1E-4);
    }

Provide best-in-class WKT -> Proj4 conversion routines

This may be a naive and ill-informed pipe dream, but it would be nice to have robust conversions from WKT{1|2} to Proj4 in cases where there's no embedded EPSG code. The current conversion routines assume there's an embedded EPSG code to use for Proj4 dictionary lookup. We recently ran into an issue where the WKT had no EPSG code, yet needed Proj4, and came up very short in finding anything out there for the JVM that can do it in a general or comprehensive way (would love to know if there is something!).

Fix Eclipse Jenkins deploy

I was looking for a way to publish snapshot and releases from tag information contained in git history, more or less using information from git describe.

After some googling it looks like having a dynamic version as part of the maven publish process requires a maven lifetime plugin as the version property is special and can't be set by normal maven plugins. This looked like the best bet: https://github.com/jgitver/jgitver-maven-plugin

I added it and configured it for this project here: 40c349b

Using this I was able to publish 1.1.1 to maven central from development machine using mvn clean deploy -P central

Sadly Eclipse Jenkins is unable to load the maven plugins:

This issue is to restore some automatic Jenkins publish to Eclipse repos for this project, ideally generating a version based on git history.

Projection.getEPSGCode() always returns 0

What is the method to get the integer code for a CRS identified by name?

The method getESPGCode() has hardcodes return 0:

    /**
     * Returns the ESPG code for this projection, or 0 if unknown.
     */
    public int getEPSGCode() {
        return 0;
    }

[lines 750-755 of file òrg.locationtech.proj4j.proj.Projection']

Support for constructing CRS from an OGC URN

The recognition of CRS identifiers starting with "urn:" fail. What do I need to do to get support for URN based CRS identifiers?

This example program - using proj4j from maven (org.locationtech.proj4j / proj4j / 1.0.0) - illustrates the problem for use of CRS = urn:ogc:def:crs:EPSG::4326:

import org.locationtech.proj4j.CRSFactory;
import org.locationtech.proj4j.CoordinateReferenceSystem;
import org.locationtech.proj4j.CoordinateTransform;
import org.locationtech.proj4j.CoordinateTransformFactory;
import org.locationtech.proj4j.ProjCoordinate;

public class Test {

	public static void main(String[] args) {

		testExplicitTransform();
		
	}
	
	   public static void testExplicitTransform() {
	        String csName1 = "EPSG:32636";
	        String csName2 = "urn:ogc:def:crs:EPSG::4326";

	        CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
	        CRSFactory csFactory = new CRSFactory();

	        CoordinateReferenceSystem crs1 = csFactory.createFromName(csName1);
	        CoordinateReferenceSystem crs2 = csFactory.createFromName(csName2);

	        System.out.println(csName1 + " unit: " + crs1.getProjection().getUnits());
	        System.out.println(csName2 + " unit: " + crs2.getProjection().getUnits());
	        
	        CoordinateTransform trans = ctFactory.createTransform(crs1, crs2);
	    
	        ProjCoordinate p1 = new ProjCoordinate();
	        ProjCoordinate p2 = new ProjCoordinate();
	        p1.x = 500000;
	        p1.y = 4649776.22482;
	    
	        /*
	         * Transform point
	         */
	        ProjCoordinate px = trans.transform(p1, p2);
	        System.out.println(px.toString());
	}

}

The program ends with this exception:

Exception in thread "main" java.lang.IllegalStateException: Unable to access CRS file: proj4/nad/urn
	at org.locationtech.proj4j.io.Proj4FileReader.readParametersFromFile(Proj4FileReader.java:41)
	at org.locationtech.proj4j.io.Proj4FileReader.getParameters(Proj4FileReader.java:151)
	at org.locationtech.proj4j.CRSFactory.createFromName(CRSFactory.java:82)
	at de.securedimensions.crs.Test.testExplicitTransform(Test.java:25)
	at de.securedimensions.crs.Test.main(Test.java:13)

Projection.initialize() method

The initialization method defined in the base class Projection is not called in this case.
Clearly, classes that extend the base projection class are required to call this method to initialize the projection parameters - by my understanding of the codes.

However, many classes extending the Projection class (like LandsatProjection class) do not provide the default constructor and most likely the initialize() method is never called in such cases.
Are the users supposed to call the initialize() method? If not how about consider making it protected method?

Use of proj's sqlite database

Moving discussion here from #12.

With a broader goal of starting to more closely track changes with proj over the last year or two, proj4j would need to eventually start getting from the .sql files that are now provided in proj upstream to something ingestible here.

One option, as mentioned in #12, would be to start embedding the sqlite database in proj4j as well. The benefit here is to minimize the amount of transformation needed from what proj uses, and the downsides would be to use a heavier dependency that requires a fair bit of native code. It makes sense that the native code is less of an issue for proj, since it's already living in the world of native code.

A second option would to be to more systematically move from what's in the sqlite to a pure-java database. We could think about ingesting the .sql files into an h2 database for proj4j, which would remove the need for native code but would still be a new dependency. The projection and CRS definitions do reference between a bunch of tables now, and I suspect that now that transformations don't always go through WGS84 that once the new functionalities are implemented it'd be hard to write out all the permutations without doing these lookups on the fly.

The last option would be to write out the tables generated by the .sql files into some plain text csvs similar to the existing epsg file and do the lookups on those files instead of a db file, to minimize change from the current methodology. I suspect, though, that this would start to be reinventing a wheel that h2 will do more performantly, which leads me to think that h2 might be the path forward here.

Transforming from "EPSG:4326" to "EPSG:3857" results in precision error

When transforming from WGS 84 "EPSG:4326" to WGS 84 / Pseudo-Mercator "EPSG:3857" with lon = 0.0 and lat = 0.0 the result is x = 0.0 and y = -7.081154551613622E-10.
The correct value for y should be 0.0, but there is a precision error. Apache SIS gives the correct result. The precision error is there with all other lon/lat inputs that I have tried.
I use Java 17 and proj4j 1.3.0.
Is there any explanation on this or plans for a fix?

*2 in stereographic projection near the equator

When I set the base point for stereographic projection on the equator, an unexpected *2 appears in the results compared to the case when the base point is only near the equator.

Example code:

CRSFactory csFactory = new CRSFactory();
CoordinateReferenceSystem STERE0 = csFactory.createFromParameters("STERE", "+proj=stere +lat_0=0.0 +lon_0=0.0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs");
CoordinateReferenceSystem STERE1 = csFactory.createFromParameters("STERE", "+proj=stere +lat_0=0.000001 +lon_0=0.0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs");
CoordinateReferenceSystem WGS84 = csFactory.createFromParameters("WGS84", "+proj=latlong +datum=WGS84 +ellps=WGS84 +no_defs");
CoordinateTransform transformer0 = new CoordinateTransformFactory().createTransform(WGS84, STERE0);
CoordinateTransform transformer1 = new CoordinateTransformFactory().createTransform(WGS84, STERE1);
        
ProjCoordinate pc = new ProjCoordinate(1, 1);
ProjCoordinate result0 = new ProjCoordinate();
ProjCoordinate result1 = new ProjCoordinate();

transformer0.transform(pc, result0);
transformer1.transform(pc, result1);
System.out.println(result0.x + ", " + result0.y);
System.out.println(result1.x + ", " + result1.y);

And the result is:

222627.90213684924, 221171.23231657242
111313.95105169504, 110585.50558411982

I'm not good at projections, but it seems weird for me. In the file
https://github.com/locationtech/proj4j/blob/master/src/main/java/org/locationtech/proj4j/proj/StereographicAzimuthalProjection.java
I can see from line 146:

			case OBLIQUE:
				A = akm1 / (cosphi0 * (1. + sinphi0 * sinX + cosphi0 * cosX * coslam));
				xy.y = A * (cosphi0 * sinX - sinphi0 * cosX * coslam);
				xy.x = A * cosX;
				break;
			case EQUATOR:
				A = 2. * akm1 / (1. + cosX * coslam);
				xy.y = A * sinX;
				xy.x = A * cosX;
				break;

What is that 2* there, and why is it necessary?

(I use version 1.1.0 from maven.)

reprojection from epsg:31370 to epsg:3857 is inaccurate

Hello,

Reprojecting from epsg:31370 to epsg:3857 gives me a substantial error. In the past i have worked around it by first converting to lat/lon and then from lat/lon to epsg:3857.

reference:

from pyproj import Proj, transform
outProj = Proj("+init=EPSG:3857")
inProj = Proj("+init=EPSG:31370")
x,y = (153005.702,  175718.465)
transform(inProj, outProj, x,y)

gives (491082.88112307055, 6602178.34577499)

i then added this test to the proj4j tests (CoordinateTransformTest):

checkTransform("EPSG:31370", 153005.702,  175718.465, "EPSG:3857", 491082.88112307055, 6602178.34577499, 0.01);

which gives

EPSG:31370(Lambert Conformal Conic/User) => EPSG:3857(Mercator/User)
[153005.702, 175718.465] -> [491082.9125899461, 6602178.287684356, 42.83499916549772] (expected: [491082.88112307055, 6602178.34577499] tol: 0.01 diff: 0.05809063371270895 )
FAIL
Src CRS: +proj=lcc +lat_1=51.16666723333333 +lat_2=49.8333339 +lat_0=90 +lon_0=4.367486666666666 +x_0=150000.013 +y_0=5400088.438 +ellps=intl +towgs84=-106.8686,52.2978,-103.7239,0.3366,-0.457,1.8422,-1.2747 +units=m +no_defs 
Tgt CRS: +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs 

First i tought this is identical to #32 but the issue remains with latest master branch.

Thanks!
Frank

No support for vertical keywords such as geoidgrids and vunits

Issue created by @jfbourgon text is ported from here: locationtech/geotrellis#2146

Trying to parse a proj4 string such as the following:

+proj=utm +zone=18 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +geoidgrids=CGG2013n83a.gtx +vunits=m +no_defs"

will raise org.osgeo.proj4j.UnsupportedParameterException

org.osgeo.proj4j.UnsupportedParameterException: vunits parameter is not supported
  at org.osgeo.proj4j.parser.Proj4Keyword.checkUnsupported(Proj4Keyword.java:131)
  at org.osgeo.proj4j.parser.Proj4Keyword.checkUnsupported(Proj4Keyword.java:138)
  at org.osgeo.proj4j.parser.Proj4Parser.parse(Proj4Parser.java:49)
  at org.osgeo.proj4j.CRSFactory.createFromParameters(CRSFactory.java:136)
  at org.osgeo.proj4j.CRSFactory.createFromParameters(CRSFactory.java:114)
  at geotrellis.proj4.CRS$$anon$1.<init>(CRS.scala:43)
  at geotrellis.proj4.CRS$.fromString(CRS.scala:42)

or

org.osgeo.proj4j.UnsupportedParameterException: geoidgrids parameter is not supported
  at org.osgeo.proj4j.parser.Proj4Keyword.checkUnsupported(Proj4Keyword.java:131)
  at org.osgeo.proj4j.parser.Proj4Keyword.checkUnsupported(Proj4Keyword.java:138)
  at org.osgeo.proj4j.parser.Proj4Parser.parse(Proj4Parser.java:49)
  at org.osgeo.proj4j.CRSFactory.createFromParameters(CRSFactory.java:136)
  at org.osgeo.proj4j.CRSFactory.createFromParameters(CRSFactory.java:114)
  at geotrellis.proj4.CRS$$anon$1.<init>(CRS.scala:43)
  at geotrellis.proj4.CRS$.fromString(CRS.scala:42)

Indeed such parameters are not listed in SupportedParameter TreeSet in Proj4Keyword.java

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.