New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ST_TransformPipeline #705
Conversation
@rcoup I have a couple of issues with your commit:
It should read:
Availability: 3.4.0 not 3.3.0 I would also reduce down to 1 SQL interface of:
|
@robe2 thanks! Can easily make those changes.
Is this the best example of such a guard, or is there an easier mechanism? |
I agree with Regina about reducing to single signature.
Is the "forward" parameter really needed ?
I mean: can a pipeline not always be expressed differently,
to be backward ? I'm thinking of a function that, taken a pipeline,
returns it's "reverse", so for non-forward you'd do:
SELECT ST_TransformPipeline(
geom,
ST_ReverseTransformPipeline(:pipeline),
:target_srid
);
I keep thinking we should have some Transform _TYPE_ at some point,
to do these things.
…--strk;
|
@rouault can explain better than me, but my understanding is:
|
what is better or not is a master of taste, but it is indeed more straightforward as implementation. That said, |
Our general mechanism is to exclude the test if version is not a specific version. postgis/regress/core/tests.mk.in Line 151 in a17e612
But you'd need to add at the top:
I think this variable is picked up at configure time -- here Line 898 in a17e612
So should just work if you add to the top. @strk am I missing anything here? |
I didn't look at the link (sorry) but just make sure you do get a
specific user error if trying to use the function, something like
"PostGIS was built with proj < $version so this functionlity is not
available, please rebuild" and not something like "function not
found". It's important that the SQL and C functions do exist, for
easier upgrades later (or this is our policy at the moment I think).
|
@rcoup Regarding what @strk said above. We always define the SQL function even when compiling with a lower version, but the safeguard is put in place and stubbed with an error if PostGIS is compiled with a lower version. Such as this -- https://github.com/postgis/postgis/blob/master/postgis/lwgeom_transform.c#L155 https://github.com/postgis/postgis/blob/master/postgis/lwgeom_geos.c#L347 But if I get my wish -- all of this will be unnecessary, cause we'll drop support for Proj < 6.1 so no ifdef will be needed - as noted here: https://lists.osgeo.org/pipermail/postgis-devel/2022-August/029786.html BTW opinions on the vote are welcome from anybody and will sway the PSC decision. |
Ah, I'm only subscribed to postgis-users, so I didn't see this. Certainly makes sense to me: seems unlikely people will want latest-greatest PostGIS from 2022 but aren't prepared to bring along a vaguely modern PROJ (6.1 was released May 2019). Will wait to update this PR until that decision is settled, but if it passes it's probably worth rebasing this on a PROJ-removal PR. I'm happy to do that if I can find some time. |
Feel to me like |
Motion passed. But let me first start removing bots testing with < 6.1 and then we can rerun. |
@rcoup Okay done ripping out support of PROJ < 6.1 and PostgreSQL < 12. So now you can rebase. |
@rcoup Just checking if you are ready to rebase and reapply. As mentioned no need for the conditional proj since we no longer support PROJ < 6.1 for 3.4 |
Thanks for the explanation. Would encoding inverse in the function
name be more elegant then ?
ST_ReverseTransformPipeline() ?
|
d7011f3
to
78f898d
Compare
While the code was there for doing angular unit conversion in ptarray_transform() on both input & output (which is correct and matches proj's `cct` behaviour); converted points were never written back to the coordinate array. In practise this only applies in edge cases - normally with transforms created via proj_crs_to_crs() PROJ does it automatically, but is exercised by the upcoming ST_TransformPipeline() changes.
EPSG/etc define forward pipeline definitions (eg: EPSG:16031), but there's no inverse definitions, and reversing the PROJ pipeline steps in a proj-string pipeline definition will go via a very different codepath in PROJ than changing the pipeline direction (though in general will produce the same result coordinates). Add the concept of a transform direction to the LWPROJ structure. For the existing CRS to CRS conversion used with ST_Transform() we always do a forward transform, but with the new transform pipeline method the user will also have the option to execute inverse pipelines.
There can be reasons to apply a specific CRS transformation pipeline, rather than leaving it to PROJ to select a candidate pipeline based on the source & target CRS. Introduce `lwproj_from_str_pipeline()` to instantiate a LWPROJ operation from a PROJ pipeline definition, using either of these formats: - a defined coordinate operation: `urn:ogc:def:coordinateOperation:AUTHORITY::CODE` - a PROJ pipeline: `+proj=pipeline ...` - concatenated operations: `urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618` - any other pipeline accepted via `proj_create()` Pipelines can be instantiated in a forward (default) or inverse direction. Introduce `lwgeom_transform_pipeline()` to both instantiate and execute such pipeline transformations.
Add the capability to perform CRS transformations using a specific/defined pipeline rather than leaving PROJ to automatically select the transform to use via ST_Transform(). There are two forms of this function: geometry ST_TransformPipeline(geom geometry, pipeline text[, to_srid integer]) geometry ST_InverseTransformPipeline(geom geometry, pipeline text[, to_srid integer]) Returns a new geometry with its coordinates transformed to a different coordinate reference system using a defined coordinate transformation pipeline. Transformation pipelines are defined using any of the following string formats: - `urn:ogc:def:coordinateOperation:AUTHORITY::CODE`. Note that a simple `AUTHORITY:CODE` string does not uniquely identify a coordinate operation: the same code can be used for a CRS definition. - a PROJ pipeline string of the form: `+proj=pipeline ...`. Automatic axis normalisation will not be applied, and if necessary the caller will need to add an additional pipeline step. - concatenated operations of the form: `urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618` The SRID of the input geometry is ignored, and the SRID of the output geometry will be set to zero unless a value is provided via the optional to_srid parameter. When using `ST_TransformPipeline()` the pipeline is executed in a forward direction. Using `ST_InverseTransformPipeline()` the pipeline is executed in the inverse direction.
Use spaces consistently
78f898d
to
f9db6ac
Compare
ok, so
Which leads to a syntax issue in the docs. Easy fix 👍 I can't spot the area in the twisty maze of Makefiles where it's actually ignoring the error. |
Could you please file a trac ticket for the false negative in |
The false success should be fixed with 0090048 |
@strk thanks. I re-added a similar error locally & |
As discussed in Trac #5006, add the ability to use a specific PROJ conversion pipeline instead of the automatically selected one via
ST_Transform()
(proj_crs_to_crs()
).Thanks to @rouault for all his help at the FOSS4G 2022 code sprint getting it working 😃 Commit messages should be relatively self-explanatory.
Transformation pipelines are defined using any of the following string formats:
urn:ogc:def:coordinateOperation:AUTHORITY::CODE
. Note that a simpleAUTHORITY:CODE
string does not uniquely identify a coordinate operation: the same code can be used for a CRS definition.+proj=pipeline ...
. Automatic axis normalisation will not be applied, and if necessary the caller will need to add an additional pipeline step.urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618
The SRID of the input geometry is ignored, and the SRID of the output geometry will be set to zero unless a value is provided via the optional
to_srid
parameter.When using
ST_TransformPipeline()
the pipeline is executed in a forward direction. UsingST_InverseTransformPipeline()
the pipeline is executed in the inverse direction.GDA2020 example from the docs: