Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Artifact ID: | 867805dc96b44c47401e129bd153ecd8cfa77312 |
---|---|
Page Name: | PROJ.6 |
Date: | 2019-04-18 11:24:09 |
Original User: | sandro |
Parent: | 77c182367a4de26550f848eb57fecba3c67c4139 (diff) |
Next | 4ee31141e6ccd09c642304e64c5e159891268240 |
Content
Introduction
PROJ is a well-known library for performing conversions between cartographic projections.It's universally supported by almost all open source GIS-oriented applications and packages, so there is no need to waste time in futher presentations.
We just need a bit of history to fully understand the current state-of-the-art:
Timeline:
- Very few users and developers do really realize how ancient is PROJ, and how far in time it started moving its first steps.
- in 1980 (about 40 years ago) Gerald Evenden started working on the very first PROJ version, and at the time it was a Ratfor program.
- in 1985 the code was completely rewritten in C to run on UNIX systems, and it was named PROJ.2.
- in 1990 was released an updated version named PROJ.3
- in 1994 a more advanced version was released, and it was obviously named PROJ.4
- in 1995 Evenden stopped any further development activity and the project become inactive for several years.
- in 2000 Frank Warmerdam bacame the new maintainer and released version 4.4
- After this reborn the revitalized project continued to be regularly maintained, but no further relevant improvements were introduced.
PROJ.4 just continued its very placid evolution in a substantially conservative way.
Short conclusion: the fourth version of PROJ (aka PROJ.4) lasted for about two decades, a very uncommon situation.
And a full generation of developers and users become sincerly convinced that PROJ.4 was the real name of the library.
The revolution comes
Timeline:- in 2018 Even Rouault, Kristian Evers and others start developing a revolutionized PROJ supporting many relevant innovations.
PROJ.5 is intended to be the first preliminary step of a more complex evolution schema. - on March 2019 a more mature version is released, and it's PROJ.6
- Next year (2020) PROJ.7 is expected to be released, and it will fully complete the transition between the old and new architectures.
Note: the whole transition implies many relevant changes, so that a deeply revised API will be required. In other words, the old PROJ.4 and the new PROJ.7 will support two different APIs, thus abruptly breaking cross-version compatibility.
This is an umpleasant new, because it practically means that all software modules depending on PROJ (this including SpatiaLite) will require a not at all trivial rewrite in order to fulfill the new API requirements.
But when you consider that's the first time in its very long life that PROJ requires an extra effrot in order to introduce so many useful innovations, this unexpected API breakage looks fully justified and absolutely reasonable.
More details about the API breakage:
- PROJ.5 started introducing the new API, but was still able to support the old traditional API without any complaint.
- PROJ.6 have depreceted the old traditional API.
It still continues to be reluctanctly supported, but the library requires to be compiled by explicitly defining a -DACCEPT_USE_OF_DEPRECATED_PROJ_API_H=1 directive in order to effectively enable this option. - and finally the next-to-come PROJ.7 will completely get rid of the old API.
What's new in PROJ.6
Fully supporting ISO-19111:2019 WKT
Old versions of PROJ (including PROJ.4) required to define each CRS (Coordinate Reference System) by a corresponding proj-string. The following table exemplifies the case of few CRSes:SRID | CRS Name | proj-string |
---|---|---|
3003 | Monte Mario / Italy zone 1 | +proj=tmerc +lat_0=0 +lon_0=9 +k=0.9996 +x_0=1500000 +y_0=0 +ellps=intl +towgs84=-104.1,-49.1,-9.9,0.971,-2.917,0.714,-11.68 +units=m +no_defs |
4326 | WGS 84 | +proj=longlat +datum=WGS84 +no_defs |
32632 | WGS 84 / UTM zone 32N | +proj=utm +zone=32 +datum=WGS84 +units=m +no_defs |
New versions of PROJ (starting since PROJ.6) still continue to support the old proj-strings, but the preferred notation for defining any CRS is now conformant to the ISO-19111:2019 international standard
(OGC Abstract Specification Topic 2: “Referencing By Coordinates”).
The following table exemplifies the same CRSes as above in the ISO WKT notation:
SRID | 3003 | 4326 | 32632 |
---|---|---|---|
CRS Name | Monte Mario / Italy zone 1 | WGS 84 | WGS 84 / UTM zone 32N |
ISO-2018 WKT | PROJCRS["Monte Mario / Italy zone 1", BASEGEODCRS["Monte Mario", DATUM["Monte Mario",<br> ELLIPSOID["International 1924",6378388,297, LENGTHUNIT["metre",1]]], PRIMEM["Greenwich",0, ANGLEUNIT["degree",0.0174532925199433]]], CONVERSION["Italy zone 1", METHOD["Transverse Mercator", ID["EPSG",9807]], PARAMETER["Latitude of natural origin",0, ANGLEUNIT["degree",0.0174532925199433], ID["EPSG",8801]], PARAMETER["Longitude of natural origin",9, ANGLEUNIT["degree",0.0174532925199433], ID["EPSG",8802]], PARAMETER["Scale factor at natural origin",0.9996, SCALEUNIT["unity",1], ID["EPSG",8805]], PARAMETER["False easting",1500000, LENGTHUNIT["metre",1], ID["EPSG",8806]], PARAMETER["False northing",0, LENGTHUNIT["metre",1], ID["EPSG",8807]]], CS[Cartesian,2], AXIS["easting (X)",east, ORDER[1], LENGTHUNIT["metre",1]], AXIS["northing (Y)",north, ORDER[2],<br> LENGTHUNIT["metre",1]], AREA["Italy - west of 12°E"], BBOX[36.53,5.94,47.04,12], ID["EPSG",3003]] |
GEODCRS["WGS 84", DATUM["World Geodetic System 1984", ELLIPSOID["WGS 84",6378137,298.257223563, LENGTHUNIT["metre",1]]], PRIMEM["Greenwich",0, ANGLEUNIT["degree",0.0174532925199433]], CS[ellipsoidal,2], AXIS["geodetic latitude (Lat)",north, ORDER[1], ANGLEUNIT["degree",0.0174532925199433]], AXIS["geodetic longitude (Lon)",east, ORDER[2], ANGLEUNIT["degree",0.0174532925199433]], AREA["World"], BBOX[-90,-180,90,180], ID["EPSG",4326]] |
PROJCRS["WGS 84 / UTM zone 32N", BASEGEODCRS["WGS 84", DATUM["World Geodetic System 1984", ELLIPSOID["WGS 84",6378137,298.257223563, LENGTHUNIT["metre",1]]], PRIMEM["Greenwich",0, ANGLEUNIT["degree",0.0174532925199433]]], CONVERSION["UTM zone 32N", METHOD["Transverse Mercator", ID["EPSG",9807]], PARAMETER["Latitude of natural origin",0, ANGLEUNIT["degree",0.0174532925199433], ID["EPSG",8801]], PARAMETER["Longitude of natural origin",9, ANGLEUNIT["degree",0.0174532925199433], ID["EPSG",8802]], PARAMETER["Scale factor at natural origin",0.9996, SCALEUNIT["unity",1], ID["EPSG",8805]], PARAMETER["False easting",500000, LENGTHUNIT["metre",1], ID["EPSG",8806]], PARAMETER["False northing",0, LENGTHUNIT["metre",1], ID["EPSG",8807]]], CS[Cartesian,2], AXIS["(E)",east, ORDER[1], LENGTHUNIT["metre",1]], AXIS["(N)",north, ORDER[2], LENGTHUNIT["metre",1]], AREA["World - N hemisphere - 6°E to 12°E - by country"], BBOX[0,6,84,12], ID["EPSG",32632]] |
As you can easily notice, the two notations are profoundly different. The old proj-string notation is extremely concise and rough, whilst the new ISO-WKT is verbose but exhaustive, detailed and precise.
There is no possible match: ISO-KWT is clearly superior and more sophisticated under any possible aspect.
Not at all surprisingly, coordinate transformations based on ISO-WKT definitions (instead of proj-strings) are usually expected to be more accurate.
And that's not all; the old proj-strings weren't formally defined by any standard, and only PROJ, GDAL and few other FLOSS / GFOSS implementations could understand them.
At the opposite, the new ISO-WKT is formally defined by an international standard, and many free and proprietary implementations could understand them.
Transformation pipelines
There is a second astonishing improvement supported by PROJ.6, that are transformation pipelines.When using a pipeline you can freely define any complex geodetic transformation by chaining together many elementary steps such as conversion, transformation, projection, axis swap and so on.
A pipeline is conceptually similar to a UNIX shell script, with a dataflow regularly proceding forward from step to step until producing the final result.
The following is a practial example of a pipeline corresponding to a transformation from NAD27 to NAD83,
+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=hgridshift +grids=conus +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1
The private SQLite database supporting PROJ.6
Starting since PROJ.6 the PROJ library requires an external SQLite database containing all definitions about supported CRSes, Ellipsoids, Prime Meridians, Unit of Measure, Transformations and so on.Many of the new advanced PROJ's API will fail if such database is not available.
In order to learn more about the many interesting cool new features supported by PROJ.6 please consult the original documentation |
---|
SpatiaLite-5.0.0 supporting PROJ.6
Existing SQL functions affected by PROJ.6
New auxiliary SQL functions specifically supporting PROJ.6
SQL Function | Supported arguments | Description |
---|---|---|
PROJ_GetLastErrorMsg( void ) : String | None | Will return the most recent error message returned by PROJ (if any). NULL will be returned if there is no curently pending PROJ error. |
PROJ_GetDatabasePath( void : String) | None | Will return the currently set pathname leading to the private PROJ's SQLite database. NULL will be returned if there is no private PROJ's SQLite database currently connected. |
PROJ_SetDatabasePath ( new_path String ) : String |
|
Will change the currently set pathname leading to the private PROJ's SQLite database. NULL will be returned if the passed path is invalid, otherwise the path of the currently set private PROJ's SQLite database will be returned. |
PROJ_AsWKT ( auth_name String , auth_srid Integer ) : String PROJ_AsWKT ( auth_name String , auth_srid Integer , wkt_style String ) : String PROJ_AsWKT ( auth_name String , auth_srid Integer , wkt_style String , indented Boolean ) : String PROJ_AsWKT ( auth_name String , auth_srid Integer , wkt_style String , indented Boolean , indentation Integer ) : String |
|
Will return the WKT expression corresponding to a given CRS; the definitions will be taken directly from the private PROJ's own database. NULL will be returned on failure or on invalid arguments. |
PROJ_GuessSridFromWKT ( wkt_expr String ) : Integer |
|
Will possibly return the SRID value corresponding to a given WKT expression defining a CRS. -1 will be returned if no CRS supported by PROJ.6 matches the WKT expression. NULL will be returned on invalid argument. |
PROJ_GuessSridFromSHP ( filename String ) : Integer |
|
Will possibly return the SRID value corresponding to the CRS defined by the .PRJ member of the Shapefile. -1 will be returned if no CRS supported by PROJ.6 matches PRJ member of the Shapefile. NULL will be returned on invalid argument. Please note well: this SQL function opend the door to many potential security issues, and thus is always disabled by default. Explicitly setting the environment variable SPATIALITE_SECURITY=relaxed is absolutely required in order to enable this function. |
Note: all the above SQL Functions will be available only when Spatialite-5.0.0 has been built against PROJ.6 (or any subsequent version). If SpatiaLite-5.0.0 has been built instead against any previosus version (as e.g. PROJ.4) any attempt to call one of these SQL Functions will simply return a no such function SQL error. |
Practical examples:
SELECT PROJ_GetDatabasePath(); -- retieving the currently set PROJ's own database ------------------------------ /usr/local/share/proj/proj.db SELECT PROJ_SetDatabasePath('/home/sandro/not_existing_proj.db'); -- non existing database ------------------------------ NULL SELECT PROJ_GetLastErrorMsg(); -- retieving the failure cause ------------------------------ proj_context_set_database_path: Open of /home/sandro/not_existing_proj.db failed SELECT PROJ_SetDatabasePath('/home/sandro/valid_proj.db'); -- valid database ------------------------------ /home/sandro/valid_proj.db SELECT PROJ_AsWKT('EPSG', 4326); -- default settings: ISO-2018 style, indented with indentation 4 ------------------------------ GEODCRS["WGS 84", DATUM["World Geodetic System 1984", ELLIPSOID["WGS 84",6378137,298.257223563, LENGTHUNIT["metre",1]]], PRIMEM["Greenwich",0, ANGLEUNIT["degree",0.0174532925199433]], CS[ellipsoidal,2], AXIS["geodetic latitude (Lat)",north, ORDER[1], ANGLEUNIT["degree",0.0174532925199433]], AXIS["geodetic longitude (Lon)",east, ORDER[2], ANGLEUNIT["degree",0.0174532925199433]], AREA["World"], BBOX[-90,-180,90,180], ID["EPSG",4326]] SELECT PROJ_AsWKT('EPSG', 4326, 'ESRI', 0, 0); -- ESRI style, monolithic line ------------------------------ GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
back