From fec376c3eb0e17443c4338f217b70278247973df Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Thu, 28 Mar 2019 11:24:43 +0100 Subject: Docs: Clarify axis ordering used in proj_trans_generic() --- docs/source/development/reference/functions.rst | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'docs/source/development') diff --git a/docs/source/development/reference/functions.rst b/docs/source/development/reference/functions.rst index 4052ff82..0066c3a2 100644 --- a/docs/source/development/reference/functions.rst +++ b/docs/source/development/reference/functions.rst @@ -221,10 +221,16 @@ Coordinate transformation 3. of length one, i.e. a constant, which will be treated as a fully populated array of that constant value + .. note:: Even though he coordinate components are named :c:data:`x`, :c:data:`y`, + :c:data:`z` and :c:data:`t`, axis ordering of the to and from CRS + is respected. Transformations exhibit the same behaviour + as if they were gathered in a :c:type:`PJ_COORD` struct. + + The strides, :c:data:`sx`, :c:data:`sy`, :c:data:`sz`, :c:data:`st`, represent the step length, in bytes, between consecutive elements of the corresponding array. This makes it possible for - :c:func:`proj_transform` to handle transformation of a large class of application + :c:func:`proj_trans_generic` to handle transformation of a large class of application specific data structures, without necessarily understanding the data structure format, as in: @@ -250,21 +256,22 @@ Coordinate transformation 0, 0 /* and the time is the constant 0.00 s */ ); - This is similar to the inner workings of the deprecated pj_transform function, but the - stride functionality has been generalized to work for any size of basic unit, - not just a fixed number of doubles. + This is similar to the inner workings of the deprecated :c:func:`pj_transform` + function, but the stride functionality has been generalized to work for any + size of basic unit, not just a fixed number of doubles. In most cases, the stride will be identical for x, y, z, and t, since they will - typically be either individual arrays (stride = sizeof(double)), or strided - views into an array of application specific data structures (stride = sizeof (...)). + typically be either individual arrays (``stride = sizeof(double)``), or strided + views into an array of application specific data structures (``stride = sizeof (...)``). But in order to support cases where :c:data:`x`, :c:data:`y`, :c:data:`z`, and :c:data:`t` come from heterogeneous sources, individual strides, :c:data:`sx`, :c:data:`sy`, :c:data:`sz`, :c:data:`st`, are used. - .. note:: Since :c:func:`proj_transform` does its work *in place*, this means that even the - supposedly constants (i.e. length 1 arrays) will return from the call in altered - state. Hence, remember to reinitialize between repeated calls. + .. note:: Since :c:func:`proj_trans_generic` does its work *in place*, + this means that even the supposedly constants (i.e. length 1 arrays) + will return from the call in altered state. Hence, remember to + reinitialize between repeated calls. :param PJ* P: Transformation object :param `direction`: Transformation direction -- cgit v1.2.3 From 2a0ad3d42c7342ee060791aba01f70f058238dce Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 2 Apr 2019 12:59:55 +0200 Subject: Docs: Clarify that angular in proj_angular_input/output means radians --- docs/source/development/reference/functions.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/source/development') diff --git a/docs/source/development/reference/functions.rst b/docs/source/development/reference/functions.rst index 0066c3a2..00653ad9 100644 --- a/docs/source/development/reference/functions.rst +++ b/docs/source/development/reference/functions.rst @@ -638,23 +638,23 @@ Various .. c:function:: int proj_angular_input (PJ *P, enum PJ_DIRECTION dir) - Check if a operation expects angular input. + Check if a operation expects input in radians or not. :param `P`: Transformation object :type `P`: const PJ* :param `direction`: Starting direction of transformation :type `direction`: PJ_DIRECTION - :returns: :c:type:`int` 1 if angular input is expected, otherwise 0 + :returns: :c:type:`int` 1 if input units is expected in radians, otherwise 0 .. c:function:: int proj_angular_output (PJ *P, enum PJ_DIRECTION dir) - Check if an operation returns angular output. + Check if an operation returns output in radians or not. :param `P`: Transformation object :type `P`: const PJ* :param `direction`: Starting direction of transformation :type `direction`: PJ_DIRECTION - :returns: :c:type:`int` 1 if angular output is returned, otherwise 0 + :returns: :c:type:`int` 1 if output units is expected in radians, otherwise 0 C API for ISO-19111 functionality +++++++++++++++++++++++++++++++++ -- cgit v1.2.3 From 79bb57eecdd7b6cdf0bc34a1cf1705aa9456043d Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 9 Apr 2019 15:08:32 +0200 Subject: DOC: update line numbers in dev quickstart example --- docs/source/development/quickstart.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'docs/source/development') diff --git a/docs/source/development/quickstart.rst b/docs/source/development/quickstart.rst index 960cddbf..267270fb 100644 --- a/docs/source/development/quickstart.rst +++ b/docs/source/development/quickstart.rst @@ -35,7 +35,7 @@ this in detail. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 48 + :lines: 49 :dedent: 4 Next we create the ``PJ`` transformation object ``P`` with the function @@ -51,7 +51,7 @@ details. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 50-52 + :lines: 51-53 :dedent: 4 PROJ uses it's own data structures for handling coordinates. Here we use a @@ -62,17 +62,17 @@ for further details. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 56 + :lines: 57 :dedent: 4 -The coordinate defined above is transformed with ``proj_trans_coord``. For this +The coordinate defined above is transformed with ``proj_trans``. For this a ``PJ`` object, a transformation direction (either forward or inverse) and the coordinate is needed. The transformed coordinate is returned in ``b``. Here the forward (``PJ_FWD``) transformation from geodetic to UTM is made. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 59-60 + :lines: 60-61 :dedent: 4 The inverse transformation (UTM to geodetic) is done similar to above, @@ -80,14 +80,14 @@ this time using ``PJ_INV`` as the direction. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 61-62 + :lines: 62-63 :dedent: 4 Before ending the program the allocated memory needs to be released again: .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 65-66 + :lines: 66-67 :dedent: 4 -- cgit v1.2.3 From fb125618fd18f112ed6f37662b021d07a602ff90 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Wed, 10 Apr 2019 11:38:23 +0200 Subject: DOC: add sphinx links to reference in dev quickstart (#1420) --- docs/source/development/quickstart.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'docs/source/development') diff --git a/docs/source/development/quickstart.rst b/docs/source/development/quickstart.rst index 267270fb..b6c5d17c 100644 --- a/docs/source/development/quickstart.rst +++ b/docs/source/development/quickstart.rst @@ -28,7 +28,7 @@ See the :doc:`reference for more info on data types `. :lines: 43-45 :dedent: 4 -For use in multi-threaded programs the ``PJ_CONTEXT`` threading-context is used. +For use in multi-threaded programs the :c:type:`PJ_CONTEXT` threading-context is used. In this particular example it is not needed, but for the sake of completeness it created here. The section on :doc:`threads ` discusses this in detail. @@ -38,15 +38,15 @@ this in detail. :lines: 49 :dedent: 4 -Next we create the ``PJ`` transformation object ``P`` with the function -``proj_create``. ``proj_create`` takes the threading context ``C`` created above, -and a proj-string that defines the desired transformation. Here we transform -from geodetic coordinate to UTM zone 32N. +Next we create the :c:type:`PJ` transformation object ``P`` with the function +:c:func:`proj_create`. :c:func:`proj_create` takes the threading context ``C`` +created above, and a proj-string that defines the desired transformation. +Here we transform from geodetic coordinate to UTM zone 32N. It is recommended to create one threading-context per thread used by the program. -This ensures that all ``PJ`` objects created in the same context will be sharing -resources such as error-numbers and loaded grids. -In case the creation of the ``PJ`` object fails an error message is displayed and -the program returns. See :doc:`errorhandling` for further +This ensures that all :c:type:`PJ` objects created in the same context will be +sharing resources such as error-numbers and loaded grids. +In case the creation of the :c:type:`PJ` object fails an error message is +displayed and the program returns. See :doc:`errorhandling` for further details. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c @@ -55,9 +55,9 @@ details. :dedent: 4 PROJ uses it's own data structures for handling coordinates. Here we use a -``PJ_COORD`` which is easily assigned with the function ``proj_coord``. Note -that the input values are converted to radians with ``proj_torad``. This is -necessary since PROJ is using radians internally. See :doc:`transformations` +:c:type:`PJ_COORD` which is easily assigned with the function :c:func:`proj_coord`. +Note that the input values are converted to radians with :c:func:`proj_torad`. +This is necessary since PROJ is using radians internally. See :doc:`transformations` for further details. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c @@ -65,10 +65,10 @@ for further details. :lines: 57 :dedent: 4 -The coordinate defined above is transformed with ``proj_trans``. For this -a ``PJ`` object, a transformation direction (either forward or inverse) and the -coordinate is needed. The transformed coordinate is returned in ``b``. -Here the forward (``PJ_FWD``) transformation from geodetic to UTM is made. +The coordinate defined above is transformed with :c:func:`proj_trans`. For this +a :c:type:`PJ` object, a transformation direction (either forward or inverse) +and the coordinate is needed. The transformed coordinate is returned in ``b``. +Here the forward (:c:type:`PJ_FWD`) transformation from geodetic to UTM is made. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c @@ -76,7 +76,7 @@ Here the forward (``PJ_FWD``) transformation from geodetic to UTM is made. :dedent: 4 The inverse transformation (UTM to geodetic) is done similar to above, -this time using ``PJ_INV`` as the direction. +this time using :c:type:`PJ_INV` as the direction. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c -- cgit v1.2.3 From a8080f3f17f96449a6c706bfed9ab3d7f9a75e5b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 19 Apr 2019 22:53:31 +0200 Subject: Doc: update quickstart with PROJ 6 API (fixes #1403) --- docs/source/development/quickstart.rst | 91 ++++++++++++++++++++----- docs/source/development/reference/functions.rst | 19 ++++++ 2 files changed, 94 insertions(+), 16 deletions(-) (limited to 'docs/source/development') diff --git a/docs/source/development/quickstart.rst b/docs/source/development/quickstart.rst index b6c5d17c..d53d98fd 100644 --- a/docs/source/development/quickstart.rst +++ b/docs/source/development/quickstart.rst @@ -25,7 +25,7 @@ See the :doc:`reference for more info on data types `. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 43-45 + :lines: 43-46 :dedent: 4 For use in multi-threaded programs the :c:type:`PJ_CONTEXT` threading-context is used. @@ -35,13 +35,43 @@ this in detail. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 49 + :lines: 50 :dedent: 4 Next we create the :c:type:`PJ` transformation object ``P`` with the function -:c:func:`proj_create`. :c:func:`proj_create` takes the threading context ``C`` -created above, and a proj-string that defines the desired transformation. -Here we transform from geodetic coordinate to UTM zone 32N. +:c:func:`proj_create_crs_to_crs`. :c:func:`proj_create_crs_to_crs` takes the threading context ``C`` +created above, a string that describes the source coordinate reference system (CRS), +a string that describes the target CRS and an optional description of the area of +use. +The strings for the source or target CRS may be PROJ strings (``+proj=longlat +datum=WGS84``), +CRS identified by their code (``EPSG:4326`` or ``urn:ogc:def:crs:EPSG::4326``) or +by a well-known text (WKT) string ( +:: + + GEOGCRS["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]], + USAGE[ + SCOPE["unknown"], + AREA["World"], + BBOX[-90,-180,90,180]], + ID["EPSG",4326]] + +). +The use of PROJ strings to describe a CRS is considered as legacy (one of the +main weakness of PROJ strings is their inability to describe a geodetic datum, +other than the few ones hardcoded in the ``+datum`` parameter). +Here we transform from geographic coordinates to UTM zone 32N. It is recommended to create one threading-context per thread used by the program. This ensures that all :c:type:`PJ` objects created in the same context will be sharing resources such as error-numbers and loaded grids. @@ -51,43 +81,72 @@ details. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 51-53 + :lines: 52-60 :dedent: 4 -PROJ uses it's own data structures for handling coordinates. Here we use a +:c:func:`proj_create_crs_to_crs` creates a transformation object, which accepts +coordinates expressed in the units and axis order of the definition of the +source CRS, and return transformed coordinates in the units and axis order of +the definition of the target CRS. +For almost most geographic CRS, the units will be in most cases degrees (in +rare cases, such as EPSG:4807 / NTF (Paris), this can be grads). For geographic +CRS defined by the EPSG authority, the order of coordinates is latitude first, +longitude second. When using a PROJ string, on contrary the order will be +longitude first, latitude second. +For projected CRS, the units may vary (metre, us-foot, etc..). For projected +CRS defined by the EPSG authority, and with EAST / NORTH directions, the order +might be easting first, northing second, or the reverse. When using a PROJ string, +the order will be easting first, northing second, except if the ``+axis`` +parameter modifies it. + +If for the needs of your software, you want +a uniform axis order (and thus do not care about axis order mandated by the +authority defining the CRS), the :c:func:`proj_normalize_for_visualization` +function can be used to modify the PJ* object returned by +:c:func:`proj_create_crs_to_crs` so that it accepts as input and returns as +output coordinates using the traditional GIS order, that is longitude, latitude +(followed by elevation, time) for geographic CRS and easting, northing for most +projected CRS. + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 65-71 + :dedent: 4 + +PROJ uses its own data structures for handling coordinates. Here we use a :c:type:`PJ_COORD` which is easily assigned with the function :c:func:`proj_coord`. -Note that the input values are converted to radians with :c:func:`proj_torad`. -This is necessary since PROJ is using radians internally. See :doc:`transformations` -for further details. +When using +proj=longlat, the order of coordinates is longitude, latitude, +and values are expressed in degrees. If you used instead a EPSG geographic CRS, +like EPSG:4326 (WGS84), it would be latitude, longitude. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 57 + :lines: 76 :dedent: 4 The coordinate defined above is transformed with :c:func:`proj_trans`. For this a :c:type:`PJ` object, a transformation direction (either forward or inverse) and the coordinate is needed. The transformed coordinate is returned in ``b``. -Here the forward (:c:type:`PJ_FWD`) transformation from geodetic to UTM is made. +Here the forward (:c:type:`PJ_FWD`) transformation from geographic to UTM is made. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 60-61 + :lines: 79-80 :dedent: 4 -The inverse transformation (UTM to geodetic) is done similar to above, +The inverse transformation (UTM to geographic) is done similar to above, this time using :c:type:`PJ_INV` as the direction. .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 62-63 + :lines: 81-82 :dedent: 4 Before ending the program the allocated memory needs to be released again: .. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c :language: c - :lines: 66-67 + :lines: 85-86 :dedent: 4 diff --git a/docs/source/development/reference/functions.rst b/docs/source/development/reference/functions.rst index 00653ad9..319face3 100644 --- a/docs/source/development/reference/functions.rst +++ b/docs/source/development/reference/functions.rst @@ -144,6 +144,25 @@ paragraph for more details. :type `area`: PJ_AREA :returns: :c:type:`PJ*` +.. c:function:: PJ *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ* obj) + + .. versionadded:: 6.1.0 + + Returns a PJ* object whose axis order is the one expected for + visualization purposes. + + The input object must be a coordinate operation, that has been created with + proj_create_crs_to_crs(). + If the axis order of its source or target CRS is northing,easting, then an + axis swap operation will be inserted. + + The returned :c:type:`PJ`-pointer should be deallocated with :c:func:`proj_destroy`. + + :param PJ_CONTEXT* ctx: Threading context. + :param `obj`: Object of type CoordinateOperation + :returns: :c:type:`PJ*` + + .. c:function:: PJ* proj_destroy(PJ *P) Deallocate a :c:type:`PJ` transformation object. -- cgit v1.2.3 From c7417323daf1323e6ecad6cc1ba9c116397d8b00 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 19 Apr 2019 23:23:35 +0200 Subject: Doc: add a PROJ 4 -> 6 migration (fixes #1407) --- docs/source/development/migration.rst | 187 ++++++++++++++++++++++++++++++---- 1 file changed, 168 insertions(+), 19 deletions(-) (limited to 'docs/source/development') diff --git a/docs/source/development/migration.rst b/docs/source/development/migration.rst index 99143f20..df622ecb 100644 --- a/docs/source/development/migration.rst +++ b/docs/source/development/migration.rst @@ -1,5 +1,150 @@ .. _API_migration: +================================================================================ +Version 4 to 6 API Migration +================================================================================ + +This is a transition guide for developers wanting to migrate their code to use +PROJ version 6. + +Code example +############################################################################### + +The difference between the old and new API is shown here with a few examples. Below +we implement the same program with the two different API's. The program reads +input longitude and latitude from the command line and convert them to +projected coordinates with the Mercator projection. + +We start by writing the program for PROJ 4: + +.. code-block:: C + + #include + + main(int argc, char **argv) { + projPJ pj_merc, pj_latlong; + double x, y; + + if (!(pj_longlat = pj_init_plus("+proj=longlat +ellps=clrk66")) ) + return 1; + if (!(pj_merc = pj_init_plus("+proj=merc +datum=clrk66 +lat_ts=33")) ) + return 1; + + while (scanf("%lf %lf", &x, &y) == 2) { + x *= DEG_TO_RAD; /* longitude */ + y *= DEG_TO_RAD; /* latitude */ + p = pj_transform(pj_longlat, pj_merc, 1, 1, &x, &y, NULL ); + printf("%.2f\t%.2f\n", x, y); + } + + pj_free(pj_longlat); + pj_free(pj_merc); + + return 0; + } + +The same program implemented using PROJ 6: + +.. code-block:: C + + #include + + main(int argc, char **argv) { + PJ *P; + PJ_COORD c; + + /* NOTE: the use of PROJ strings to describe CRS is strongly discouraged */ + /* in PROJ 6, as PROJ strings are a poor way of describing a CRS, and */ + /* more precise its geodetic datum. */ + /* Use of codes provided by authorities (such as "EPSG:4326", etc...) */ + /* or WKT strings will bring the full power of the "transformation */ + /* engine" used by PROJ to determine the best transformation(s) between */ + /* two CRS. */ + P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, + "+proj=longlat +ellps=clrs66", + "+proj=merc +ellps=clrk66 +lat_ts=33", + NULL); + if (P==0) + return 1; + + { + /* For that particular use case, this is not needed. */ + /* proj_normalize_for_visualization() ensures that the coordinate */ + /* order expected and returned by proj_trans() will be longitude, */ + /* latitude for geographic CRS, and easting, northing for projected */ + /* CRS. If instead of using PROJ strings as above, "EPSG:XXXX" codes */ + /* had been used, this might had been necessary. */ + PJ* P_for_GIS = proj_normalize_for_visualization(C, P); + if( 0 == P_for_GIS ) { + proj_destroy(P); + return 1; + } + proj_destroy(P); + P = P_for_GIS; + } + + while (scanf("%lf %lf", &c.lp.lam, &c.lp.phi) == 2) { + /* No need to convert to radian */ + c = proj_trans(P, PJ_FWD, c); + printf("%.2f\t%.2f\n", c.xy.x, c.xy.y); + } + + proj_destroy(P); + } + + +Function mapping from old to new API +############################################################################### + ++---------------------------------------+-------------------------------------------------+ +| Old API functions | New API functions | ++=======================================+=================================================+ +| pj_fwd | :c:func:`proj_trans` | ++---------------------------------------+-------------------------------------------------+ +| pj_inv | :c:func:`proj_trans` | ++---------------------------------------+-------------------------------------------------+ +| pj_fwd3 | :c:func:`proj_trans` | ++---------------------------------------+-------------------------------------------------+ +| pj_inv3 | :c:func:`proj_trans` | ++---------------------------------------+-------------------------------------------------+ +| pj_transform | :c:func:`proj_create_crs_to_crs` + | +| | (:c:func:`proj_normalize_for_visualization` +) | +| | :c:func:`proj_trans`, | +| | :c:func:`proj_trans_array` or | +| | :c:func:`proj_trans_generic` | ++---------------------------------------+-------------------------------------------------+ +| pj_init | :c:func:`proj_create` / | +| | :c:func:`proj_create_crs_to_crs` | ++---------------------------------------+-------------------------------------------------+ +| pj_init | :c:func:`proj_create` / | +| | :c:func:`proj_create_crs_to_crs` | ++---------------------------------------+-------------------------------------------------+ +| pj_free | :c:func:`proj_destroy` | ++---------------------------------------+-------------------------------------------------+ +| pj_is_latlong | :c:func:`proj_get_type` | ++---------------------------------------+-------------------------------------------------+ +| pj_is_geocent | :c:func:`proj_get_type` | ++---------------------------------------+-------------------------------------------------+ +| pj_get_def | :c:func:`proj_pj_info` | ++---------------------------------------+-------------------------------------------------+ +| pj_latlong_from_proj | *No direct equivalent*, but can be accomplished | +| | by chaining :c:func:`proj_create`, | +| | :c:func:`proj_crs_get_horizontal_datum` and | +| | :c:func:`proj_create_geographic_crs_from_datum` | ++---------------------------------------+-------------------------------------------------+ +| pj_set_finder | :c:func:`proj_context_set_file_finder` | ++---------------------------------------+-------------------------------------------------+ +| pj_set_searchpath | :c:func:`proj_context_set_search_paths` | ++---------------------------------------+-------------------------------------------------+ +| pj_deallocate_grids | *No equivalent* | ++---------------------------------------+-------------------------------------------------+ +| pj_strerrno | *No equivalent* | ++---------------------------------------+-------------------------------------------------+ +| pj_get_errno_ref | :c:func:`proj_errno` | ++---------------------------------------+-------------------------------------------------+ +| pj_get_release | :c:func:`proj_info` | ++---------------------------------------+-------------------------------------------------+ + ================================================================================ Version 4 to 5 API Migration ================================================================================ @@ -66,7 +211,7 @@ Code example The difference between the old and new API is shown here with a few examples. Below we implement the same program with the two different API's. The program reads -input latitude and longitude from the command line and convert them to +input longitude and latitude from the command line and convert them to projected coordinates with the Mercator projection. We start by writing the program for PROJ v. 4: @@ -76,21 +221,24 @@ We start by writing the program for PROJ v. 4: #include main(int argc, char **argv) { - projPJ pj_merc, pj_latlong; + projPJ pj_merc, pj_longlat; double x, y; - if (!(pj_merc = pj_init_plus("+proj=merc +ellps=clrk66 +lat_ts=33")) ) + if (!(pj_longlat = pj_init_plus("+proj=longlat +ellps=clrk66")) ) return 1; - if (!(pj_latlong = pj_init_plus("+proj=latlong +ellps=clrk66")) ) + if (!(pj_merc = pj_init_plus("+proj=merc +ellps=clrk66 +lat_ts=33")) ) return 1; while (scanf("%lf %lf", &x, &y) == 2) { - x *= DEG_TO_RAD; - y *= DEG_TO_RAD; - p = pj_transform(pj_latlong, pj_merc, 1, 1, &x, &y, NULL ); + x *= DEG_TO_RAD; /* longitude */ + y *= DEG_TO_RAD; /* latitude */ + p = pj_transform(pj_longlat, pj_merc, 1, 1, &x, &y, NULL ); printf("%.2f\t%.2f\n", x, y); } + pj_free(pj_longlat); + pj_free(pj_merc); + return 0; } @@ -115,6 +263,7 @@ The same program implemented using PROJ v. 5: printf("%.2f\t%.2f\n", c.xy.x, c.xy.y); } + proj_destroy(P); } Looking at the two different programs, there's a few immediate @@ -155,27 +304,27 @@ Function mapping from old to new API +---------------------------------------+---------------------------------------+ | Old API functions | New API functions | +=======================================+=======================================+ -| pj_fwd | proj_trans | +| pj_fwd | :c:func:`proj_trans` | +---------------------------------------+---------------------------------------+ -| pj_inv | proj_trans | +| pj_inv | :c:func:`proj_trans` | +---------------------------------------+---------------------------------------+ -| pj_fwd3 | proj_trans | +| pj_fwd3 | :c:func:`proj_trans` | +---------------------------------------+---------------------------------------+ -| pj_inv3 | proj_trans | +| pj_inv3 | :c:func:`proj_trans` | +---------------------------------------+---------------------------------------+ | pj_transform | proj_trans_array or proj_trans_generic| +---------------------------------------+---------------------------------------+ -| pj_init | proj_create | +| pj_init | :c:func:`proj_create` | +---------------------------------------+---------------------------------------+ -| pj_init_plus | proj_create | +| pj_init_plus | :c:func:`proj_create` | +---------------------------------------+---------------------------------------+ -| pj_free | proj_destroy | +| pj_free | :c:func:`proj_destroy` | +---------------------------------------+---------------------------------------+ -| pj_is_latlong | proj_angular_output | +| pj_is_latlong | :c:func:`proj_angular_output` | +---------------------------------------+---------------------------------------+ -| pj_is_geocent | proj_angular_outout | +| pj_is_geocent | :c:func:`proj_angular_output` | +---------------------------------------+---------------------------------------+ -| pj_get_def | proj_pj_info | +| pj_get_def | :c:func:`proj_pj_info` | +---------------------------------------+---------------------------------------+ | pj_latlong_from_proj | *No equivalent* | +---------------------------------------+---------------------------------------+ @@ -187,7 +336,7 @@ Function mapping from old to new API +---------------------------------------+---------------------------------------+ | pj_strerrno | *No equivalent* | +---------------------------------------+---------------------------------------+ -| pj_get_errno_ref | proj_errno | +| pj_get_errno_ref | :c:func:`proj_errno` | +---------------------------------------+---------------------------------------+ -| pj_get_release | proj_info | +| pj_get_release | :c:func:`proj_info` | +---------------------------------------+---------------------------------------+ -- cgit v1.2.3 From 292807eee9e1194175b64cb5c0a9f0b432352abc Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 22 Apr 2019 20:05:36 +0200 Subject: proj_create(): add support for compoundCRS and concatenatedOperation named from their components Support following syntaxes: - OGC URN combining references for compoundCRS: e.g. "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717" - its GDAL shortcut: e.g. "EPSG:2393+5717" - OGC URN combining references for concatenated operations: e.g. "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618" --- docs/source/development/reference/functions.rst | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'docs/source/development') diff --git a/docs/source/development/reference/functions.rst b/docs/source/development/reference/functions.rst index 00653ad9..aa177b31 100644 --- a/docs/source/development/reference/functions.rst +++ b/docs/source/development/reference/functions.rst @@ -29,9 +29,17 @@ paragraph for more details. .. c:function:: PJ* proj_create(PJ_CONTEXT *ctx, const char *definition) - Create a transformation object, or a CRS object, from a proj-string, - a WKT string, or object code (like "EPSG:4326", "urn:ogc:def:crs:EPSG::4326", - "urn:ogc:def:coordinateOperation:EPSG::1671"). + Create a transformation object, or a CRS object, from: + + - a proj-string, + - a WKT string, + - an object code (like "EPSG:4326", "urn:ogc:def:crs:EPSG::4326", + "urn:ogc:def:coordinateOperation:EPSG::1671"), + - a OGC URN combining references for compound coordinate reference systems + (e.g "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717" or custom abbreviated + syntax "EPSG:2393+5717"), + - a OGC URN combining references for concatenated operations + (e.g. "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618") Example call: @@ -110,7 +118,8 @@ paragraph for more details. - the name of a CRS as found in the PROJ database, e.g "WGS84", "NAD27", etc. - - more generally any string accepted by :c:func:`proj_create` + - more generally any string accepted by :c:func:`proj_create` representing + a CRS An "area of use" can be specified in area. When it is supplied, the more accurate transformation between two given systems can be chosen. -- cgit v1.2.3