locationtech / proj4j

Java port of the Proj.4 library for coordinate reprojection
Other
190 stars 73 forks source link

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

Open metasim opened 5 years ago

metasim commented 5 years ago

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!).

echeipesh commented 5 years ago

Obviously GDAL does this somehow. But besides that I would love to identify a couple of reference resources that look like they can be used to do this in a principled way.

Potentially this is an good opportunity for GSoC project.

vpipkt commented 4 years ago

It's my understanding that recent versions of GDAL now have a binary dependency on PROJ version 6. Which seems to answer the question of how GDAL does it...

This announcement describes some high level things about PROJ 6. There is an ISO spec and OGC spec that PROJ 6 implements. Of interest also, there is a sqlite database defining the projections. That database is installed with PROJ binaries.

metasim commented 4 years ago

I don't know how much of an issue it is any more with caching, but the text file parsing that used to happen for constructing the lookup tables was quite slow. A SQLlite approach would be much faster, and allow us to keep up with the official database more easily.

willcohen commented 4 years ago

More discussion on this in #53. There are some concerns with sqlite and its not being pure java. On my own I've started trying out an approach to this but it's not nearly put together enough for a pull request -- it's fairly straightforward to copy the .sql files from upstream on some kind of version release cadence, and then have maven's build for proj4j just build its own version of the database first. From there, it seems like all of the SQL queries proj implements are located in one place, though modeling that OGC spec mentioned above would be a fair bit of work. It might make sense to wait until EPSG changes to model v10, though that seems to be on a delayed timeline.

metasim commented 4 years ago

@willcohen Is this not sufficient? Or does it require a native sqlite installation (I couldn't tell from the README)?

https://github.com/xerial/sqlite-jdbc

The .jar file contains some native libraries:

Screen Shot 2020-01-08 at 11 14 52 AM
willcohen commented 4 years ago

I think the use of native code in sqlite-jdbc is a main concern here, since proj4j is a pure java reimplementation of proj.

It does lead to a thought experiment -- if we're going to the trouble to embed native code for JDBC for this library, why don't we just build a native version of proj for as many platforms as possible, just like sqlite-jdbc, and embed that into a java library using JNI as a wrapper? On the other hand, if proj4j is the pure-java version of proj, we need to be reimplementing everything piece by piece, which might mean something like h2 or derby.

vpipkt commented 4 years ago

@willcohen very interesting

willcohen commented 4 years ago

When proj appears on the classpath, it looks like this project implements a JNI approach. For this reason, it may be that that library is better suited to handle this native case.

bosborn commented 3 years ago

I wrote a Coordinate Reference Systems library to parse CRS WKT 1 and 2. Recently added a CRS to PROJ / PROJ.4 parser as well.

Example to use with this library:

// String wkt = ...
CoordinateReferenceSystem crs = null;
CRS crsObject = CRSReader.read(wkt);
if (crsObject != null) {
    String params = ProjParser.paramsText(crsObject);
    if (params != null) {
        crs = CRSParser.getCRSFactory().createFromParameters(crsObject.getName(), params);
    }
}