diff options
Diffstat (limited to '_sources/development')
21 files changed, 2918 insertions, 0 deletions
diff --git a/_sources/development/bindings.rst.txt b/_sources/development/bindings.rst.txt new file mode 100644 index 00000000..c2d13077 --- /dev/null +++ b/_sources/development/bindings.rst.txt @@ -0,0 +1,63 @@ +.. _bindings: + +******************************************************************************** +Language bindings +******************************************************************************** + +PROJ bindings are available for a number of different development platforms. + +Python +====== +`pyproj <https://pypi.python.org/pypi/pyproj>`_: +Python interface (wrapper for PROJ) + +Ruby +======= + +`proj4rb <https://github.com/cfis/proj4rb>`_: +Bindings for PROJ in ruby + +Rust +======= + +`proj <https://github.com/georust/proj>`_: +Rust bindings for the latest stable version of PROJ + +Go (Golang) +=========== +`go-proj <https://github.com/everystreet/go-proj>`_: +Go bindings and idiomatic wrapper for PROJ + +Julia +===== +`Proj4.jl <https://github.com/JuliaGeo/Proj4.jl>`_: +Julia bindings and idiomatic wrapper for PROJ. + +TCL +======== +`proj4tcl <http://wiki.tcl.tk/41270>`_: +Bindings for PROJ in tcl (critcl source) + +MySQL +===== + +`fProj4 <https://sourceforge.net/projects/mysqlscientific/files/fPROJ4/>`_: +Bindings for PROJ in MySQL + +Excel +======== + +`proj.xll <https://github.com/jbuonagurio/proj.xll>`_: +Excel add-in for PROJ map projections + +Visual Basic +================== + +`PROJ VB Wrappers <http://ftp.dfg.ca.gov/Public/BDB/Tools/proj4/proj_api.zip>`_: +By Eric G. Miller. + +Fortran +======= + +`Fortran-Proj <https://gitlab.com/likeno/fortran-proj>`_: +Bindings for PROJ in Fortran (By João Macedo @likeno) diff --git a/_sources/development/cmake.rst.txt b/_sources/development/cmake.rst.txt new file mode 100644 index 00000000..d1bbf42c --- /dev/null +++ b/_sources/development/cmake.rst.txt @@ -0,0 +1,38 @@ +.. _cmake: + +******************************************************************************** +Using PROJ in CMake projects +******************************************************************************** + +The recommended way to use the PROJ library in a CMake project is to +link to the imported library target ``PROJ::proj`` provided by +the CMake configuration which comes with the library. Typical usage is: + +.. code:: + + find_package(PROJ CONFIG REQUIRED) + + target_link_libraries(MyApp PRIVATE PROJ::proj) + +By adding the imported library target ``PROJ::proj`` to the +target link libraries, CMake will also pass the include directories to +the compiler. + +The CMake command ``find_package`` will look for the configuration in a +number of places. The lookup can be adjusted for all packages by setting +the cache variable or environment variable ``CMAKE_PREFIX_PATH``. In +particular, CMake will consult (and set) the cache variable +``PROJ_DIR``. + +The old CMake name for the PROJ project was "PROJ4" and the switch to +the name "PROJ" was made with version 7.0. So if you expect your +package to work with pre-7.0 versions of PROJ, you will need to use + +.. code:: + + find_package(PROJ4) + target_link_libraries(MyApp PRIVATE ${PROJ4_LIBRARIES}) + include_directories(${PROJ4_INCLUDE_DIRS}) + +This will also find version 7.0. This use of the PROJ4 name will be +phased out at some point. diff --git a/_sources/development/errorhandling.rst.txt b/_sources/development/errorhandling.rst.txt new file mode 100644 index 00000000..021d2fb7 --- /dev/null +++ b/_sources/development/errorhandling.rst.txt @@ -0,0 +1,65 @@ +.. _errorhandling: + +================================================================================ +Error handling +================================================================================ + +PROJ maintains an internal error state, which is local to a +:c:type:`PJ_CONTEXT` thread context. + +See :doc:`quickstart` for more information about how to create and use a thread +context object. + +If you receive an abnormal return from a PROJ API function (e.g. a NULL +pointer) you may wish to discover more information about the error. + +In this case you can make a call to :c:func:`proj_context_errno`, passing in +your thread context. This will return an integer error code. + +If the error code is zero, the last PROJ operation was deemed successful and no +error has been detected. + +If the error code is non-zero, an error has been detected. You can pass your +thread context together with this error code to +:c:func:`proj_context_errno_string` to retrieve a string describing the error +condition. + +A basic example showing how a C program might catch and report errors follows: + +.. code-block:: c + :caption: errorhandling.c + :linenos: + + #include <stdio.h> + #include <proj.h> + + int main (void) { + PJ_CONTEXT *c; + PJ *p; + int errno; + const char *errstr; + + c = proj_context_create(); + p = proj_create_crs_to_crs(c, "EPSG:4326", "EPSG:3857", NULL); + + if (p == 0) { + /* Something is wrong, let's try to get details ... */ + errno = proj_context_errno(c); + if (errno == 0) { + /* This should be impossible. */ + fprintf(stderr, "Failed to create transformation, reason unknown.\n"); + } else { + errstr = proj_context_errno_string(c, errno); + fprintf(stderr, "Failed to create transformation: %s.\n", errstr); + } + proj_context_destroy(c); + return 1; + } + + /* transformation object is valid, do work ... */ + + proj_destroy(p); + proj_context_destroy(c); + + return 0; + } diff --git a/_sources/development/index.rst.txt b/_sources/development/index.rst.txt new file mode 100644 index 00000000..06e1d36a --- /dev/null +++ b/_sources/development/index.rst.txt @@ -0,0 +1,47 @@ +.. _development: + +================================================================================ +Development +================================================================================ + +These pages are primarily focused towards developers either contributing to the +PROJ project or using the library in their own software. + + +.. toctree:: + :maxdepth: 1 + + quickstart + transformations + errorhandling + reference/index + cmake + bindings + migration + +The source code for PROJ is maintained in a +`git repository on GitHub <https://github.com/OSGeo/PROJ>`_. +Additionally, a collection of PROJ-compatible transformation grids +are maintained in a `separate git repository <https://github.com/OSGeo/proj-datumgrid>`_. + +.. attention:: + + The :file:`projects.h` header and the functions related to it is considered + deprecated from version 5.0.0 and onwards. The header has been removed + PROJ in version 6.0.0 released February 1st 2019. + +.. attention:: + + The nmake build system on Windows is on longer supported in + version 6.0.0 on onwards. Use CMake instead. + +.. attention:: + + The :file:`proj_api.h` header and the functions related to it is + considered deprecated from version 5.0.0 and onwards. The header has been + removed in version 8.0.0 released March 1st 2021. + +.. attention:: + + With the introduction of PROJ 5, behavioural changes has been made to + existing functionality. Consult :ref:`differences` for the details. diff --git a/_sources/development/migration.rst.txt b/_sources/development/migration.rst.txt new file mode 100644 index 00000000..4c0113e5 --- /dev/null +++ b/_sources/development/migration.rst.txt @@ -0,0 +1,387 @@ +.. _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 <proj_api.h> + + main(int argc, char **argv) { + projPJ pj_merc, pj_longlat; + double x, y; + int p; + + 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 <proj.h> + + main(int argc, char **argv) { + PJ *P; + PJ_COORD c, c_out; + + /* 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(PJ_DEFAULT_CTX, P); + if( 0 == P_for_GIS ) { + proj_destroy(P); + return 1; + } + proj_destroy(P); + P = P_for_GIS; + } + + /* For reliable geographic <--> geocentric conversions, z shall not */ + /* be some random value. Also t shall be initialized to HUGE_VAL to */ + /* allow for proper selection of time-dependent operations if one of */ + /* the CRS is dynamic. */ + c.lpzt.z = 0.0; + c.lpzt.t = HUGE_VAL; + + while (scanf("%lf %lf", &c.lpzt.lam, &c.lpzt.phi) == 2) { + /* No need to convert to radian */ + c_out = proj_trans(P, PJ_FWD, c); + printf("%.2f\t%.2f\n", c_out.xy.x, c_out.xy.y); + } + + proj_destroy(P); + + return 0; + } + + +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` | +| | or :c:func:`proj_create_crs_to_crs_from_pj` + | +| | (: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` | ++---------------------------------------+-------------------------------------------------+ + + +Backward incompatibilities +############################################################################### + +Access to the :file:`proj_api.h` is still possible but requires to define the +``ACCEPT_USE_OF_DEPRECATED_PROJ_API_H`` macro. + +The emulation of the now deprecated ``+init=epsg:XXXX`` syntax in PROJ 6 is not +fully compatible with previous versions. + +In particular, when used with the ``pj_transform()`` function, no datum shift term +(``towgs84``, ``nadgrids``, ``geoidgrids``) will be added during the expansion of the +``+init=epsg:XXXX`` string to ``+proj=YYYY ....``. If you still uses ``pj_transform()`` +and want datum shift to be applied, then you need to provide a fully expanded +string with appropriate ``towgs84``, ``nadgrids`` or ``geoidgrids`` terms to ``pj_init()``. + +To use the ``+init=epsg:XXXX`` syntax with :c:func:`proj_create` and then +:c:func:`proj_create_crs_to_crs`, ``proj_context_use_proj4_init_rules(ctx, TRUE)`` +or the ``PROJ_USE_PROJ4_INIT_RULES=YES`` environment variable must have been +previously set. In that context, datum shift will be researched. However they +might be different than with PROJ 4 or PROJ 5, since a "late-binding" approach +will be used (that is trying to find as much as possible the most direct +transformation between the source and target datum), whereas PROJ 4 or PROJ 5 +used an "early-binding" approach consisting in always going to EPSG:4326 / WGS 84. + + +Feedback from downstream projects on the PROJ 6 migration +############################################################################### + +* `PROJ 6 adoption by Spatialite <https://www.gaia-gis.it/fossil/libspatialite/wiki?name=PROJ.6>`_ + +* `On GDA2020, PROJ 6 and QGIS: Lessons learnt and recommendations for handling GDA2020 within geospatial software development <https://www.icsm.gov.au/sites/default/files/North%20Road%20Handling%20GDA2020%20within%20Geospatial%20Software%20Development.pdf>`_ + +================================================================================ +Version 4 to 5 API Migration +================================================================================ + +This is a transition guide for developers wanting to migrate their code to use +PROJ version 5. + + +Background +############################################################################### + +Before we go on, a bit of background is needed. The new API takes a different +view of the world than the old because it is needed in order to obtain high +accuracy transformations. The old API is constructed in such a way that any transformation +between two coordinate reference systems *must* pass through the ill-defined +WGS84 reference frame, using it as a hub. The new API does away with this limitation to +transformations in PROJ. It is still possible to do that type of transformations +but in many cases there will be a better alternative. + +The world view represented by the old API is always sufficient if all you care about is +meter level accuracy - and in many cases it will provide much higher accuracy +than that. But the view that “WGS84 is the *true* foundation of the world, and +everything else can be transformed natively to and from WGS84” is inherently flawed. + +First and foremost because any time WGS84 is mentioned, you should ask yourself +“Which of the six WGS84 realizations are we talking about here?”. + +Second, because for many (especially legacy) systems, it may not be straightforward +to transform to WGS84 (or actually ITRF-something, ETRS-something or NAD-something +which appear to be the practical meaning of the term WGS84 in everyday PROJ related +work), while centimeter-level accurate transformations may exist between pairs of +older systems. + +The concept of a hub reference frame (“datum”) is not inherently bad, but in many +cases you need to handle and select that datum with more care than the old API allows. +The primary aim of the new API is to allow just that. And to do that, you must realize +that the world is inherently 4 dimensional. You may in many cases assume one or more of +the coordinates to be constant, but basically, to obtain geodetic accuracy transformations, +you need to work in 4 dimensions. + +Now, having described the background for introducing the new API, let's try to show +how to use it. First note that in order to go from system A to system B, the old API +starts by doing an **inverse** transformation from system A to WGS84, then does a +**forward** transformation from WGS84 to system B. + +With :program:`cs2cs` being the command line interface to the old API, and +:program:`cct` being the same for the new, this example of doing the same +thing in both world views will should give an idea of the differences: + +:: + + $ echo 300000 6100000 | cs2cs +proj=utm +zone=33 +ellps=GRS80 +to +proj=utm +zone=32 +ellps=GRS80 + 683687.87 6099299.66 0.00 + + + $ echo 300000 6100000 0 0 | cct +proj=pipeline +step +inv +proj=utm +zone=33 +ellps=GRS80 +step +proj=utm +zone=32 +ellps=GRS80 + 683687.8667 6099299.6624 0.0000 0.0000 + +Lookout for the ``+inv`` in the first ``+step``, indicating an inverse transform. + + +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 v. 4: + +.. code-block:: C + + #include <proj_api.h> + + main(int argc, char **argv) { + projPJ pj_merc, pj_longlat; + double x, y; + + if (!(pj_longlat = pj_init_plus("+proj=longlat +ellps=clrk66")) ) + return 1; + 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; /* 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 v. 5: + +.. code-block:: C + + #include <proj.h> + + main(int argc, char **argv) { + PJ *P; + PJ_COORD c; + + P = proj_create(PJ_DEFAULT_CTX, "+proj=merc +ellps=clrk66 +lat_ts=33"); + if (P==0) + return 1; + + while (scanf("%lf %lf", &c.lp.lam, &c.lp.phi) == 2) { + c.lp.lam = proj_torad(c.lp.lam); + c.lp.phi = proj_torad(c.lp.phi); + c = proj_trans(P, PJ_FWD, c); + 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 +differences that catches the eye. First off, the included header file describing +the API has changed from ``proj_api.h`` to simply ``proj.h``. All functions in ``proj.h`` +belongs to the ``proj_`` namespace. + +With the new API also comes new datatypes. E.g. the transformation object ``projPJ`` +which has been changed to a pointer of type ``PJ``. This is done to highlight the +actual nature of the object, instead of hiding it away behind a typedef. New data +types for handling coordinates have also been introduced. In the above example we +use the ``PJ_COORD``, which is a union of various types. The benefit of this is that +it is possible to use the various structs in the union to communicate what state +the data is in at different points in the program. For instance as in the above +example where the coordinate is read from STDIN as a geodetic coordinate, +communicated to the reader of the code by using the ``c.lp`` struct. +After it has been projected we print it to STDOUT by accessing the individual +elements in ``c.xy`` to illustrate that the coordinate is now in projected space. +Data types are prefixed with `PJ_`. + +The final, and perhaps biggest, change is that the fundamental concept of +transformations in PROJ are now handled in a single transformation object (``PJ``) +and not by stating the source and destination systems as previously. It is of +course still possible to do just that, but the transformation object now +captures the whole transformation from source to destination in one. In the +example with the old API the source system is described as +``+proj=latlon +ellps=clrk66`` and the destination system is described as +``+proj=merc +ellps=clrk66 +lat_ts=33``. Since the Mercator projection accepts +geodetic coordinates as its input, the description of the source in this case +is superfluous. We use that to our advantage in the new API and simply state +the destination. This is simple at a glance, but is actually a big conceptual +change. We are now focused on the path between two systems instead of what the +source and destination systems are. + +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_trans_array` or | +| | :c:func:`proj_trans_generic` | ++---------------------------------------+---------------------------------------+ +| ``pj_init`` | :c:func:`proj_create` | ++---------------------------------------+---------------------------------------+ +| ``pj_init_plus`` | :c:func:`proj_create` | ++---------------------------------------+---------------------------------------+ +| ``pj_free`` | :c:func:`proj_destroy` | ++---------------------------------------+---------------------------------------+ +| ``pj_is_latlong`` | :c:func:`proj_angular_output` | ++---------------------------------------+---------------------------------------+ +| ``pj_is_geocent`` | :c:func:`proj_angular_output` | ++---------------------------------------+---------------------------------------+ +| ``pj_get_def`` | :c:func:`proj_pj_info` | ++---------------------------------------+---------------------------------------+ +| ``pj_latlong_from_proj`` | *No equivalent* | ++---------------------------------------+---------------------------------------+ +| ``pj_set_finder`` | *No equivalent* | ++---------------------------------------+---------------------------------------+ +| ``pj_set_searchpath`` | *No equivalent* | ++---------------------------------------+---------------------------------------+ +| ``pj_deallocate_grids`` | *No equivalent* | ++---------------------------------------+---------------------------------------+ +| ``pj_strerrno`` | *No equivalent* | ++---------------------------------------+---------------------------------------+ +| ``pj_get_errno_ref`` | :c:func:`proj_errno` | ++---------------------------------------+---------------------------------------+ +| ``pj_get_release`` | :c:func:`proj_info` | ++---------------------------------------+---------------------------------------+ diff --git a/_sources/development/quickstart.rst.txt b/_sources/development/quickstart.rst.txt new file mode 100644 index 00000000..5be85641 --- /dev/null +++ b/_sources/development/quickstart.rst.txt @@ -0,0 +1,200 @@ +.. _dev_quickstart: + +================================================================================ +Quick start +================================================================================ + +This is a short introduction to the PROJ API. In the following section we +create a simple program that transforms a geodetic coordinate to UTM and back +again. The program is explained a few lines at a time. The complete program can +be seen at the end of the section. + +See the following sections for more in-depth descriptions of different parts of +the PROJ API or consult the :doc:`API reference <reference/index>` for specifics. + +Before the PROJ API can be used it is necessary to include the :file:`proj.h` header +file. Here :file:`stdio.h` is also included so we can print some text to the screen: + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 39-40 + +Let's declare a few variables that'll be used later in the program. Each variable +will be discussed below. +See the :doc:`reference for more info on data types <reference/datatypes>`. + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 43-46 + :dedent: 4 + +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 we demonstrate its use here. + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 50 + :dedent: 4 + +Next we create the :c:type:`PJ` transformation object ``P`` with the function +:c:func:`proj_create_crs_to_crs`. + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 52-60 + :dedent: 4 + +Here we have set up a transformation from geographic coordinates to UTM zone +32N. + +:c:func:`proj_create_crs_to_crs` takes as its arguments: + +- 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. + +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. + +If you are sure that ``P`` will only be used by a single program thread, you +may pass ``NULL`` for the threading context. This will assign the default +thread context to ``P``. + +The strings for the source and target CRS may be any of: + +- PROJ strings, e.g. ``+proj=longlat +datum=WGS84 +type=crs``, +- CRS identified by their code, e.g. ``EPSG:4326`` or + ``urn:ogc:def:crs:EPSG::4326``, or +- a well-known text (WKT) string, e.g.: + +:: + + 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]] + +.. warning:: + + The use of PROJ strings to describe a CRS is not recommended. One of the + main weaknesses of PROJ strings is their inability to describe a geodetic + datum, other than the few ones hardcoded in the ``+datum`` parameter. + +:c:func:`proj_create_crs_to_crs` will return a pointer to a :c:type:`PJ` +object, or a null pointer in the case of an error. The details of the error +can be retrieved using :c:func:`proj_context_errno`. See :doc:`errorhandling` +for further details. + +Now that we have a normalized transformation object in ``P``, we can use it +with :c:func:`proj_trans` to transform coordinates from the source CRS to the +target CRS, but first we will discuss the interpretation of coordinates. + +By default, a :c:type:`PJ` transformation object accepts coordinates expressed +in the units and axis order of the source CRS, and returns transformed +coordinates in the units and axis order of the target CRS. + +For most geographic CRS, the units will be in 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, the order is the reverse; 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 you prefer to work with a uniform axis order, regardless of the axis orders +mandated by the source and target CRS, you can use the +:c:func:`proj_normalize_for_visualization` function. + +:c:func:`proj_normalize_for_visualization` takes a threading context and an +existing :c:type:`PJ` object, and generates from it a new :c:type:`PJ` that +accepts as input and returns as output coordinates using the traditional GIS +order. That is, longitude followed by latitude, optionally followed by +elevation and time for geographic CRS, and easting followed by northing for +most projected CRS. + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 65-71 + :dedent: 4 + +Next we create a :c:type:`PJ_COORD` coordinate object, using the function +:c:func:`proj_coord`. + +The following example creates a coordinate for 55°N 12°E (Copenhagen). + +Because we have normalized the transformation object with +:c:func:`proj_normalize_for_visualization`, the order of coordinates is +longitude followed by latitude, and the units are degrees. + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 76 + :dedent: 4 + +Now we are ready to transform the coordinate into UTM zone 32, using the +function :c:func:`proj_trans`. + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 79-80 + :dedent: 4 + +:c:func:`proj_trans` takes as its arguments: + +- a :c:type:`PJ` transformation object, +- a :c:type:`PJ_DIRECTION` direction, and +- the :c:type:`PJ_COORD` coordinate to transform. + +The direction argument can be one of: + +- ``PJ_FWD`` -- "forward" transformation from source CRS to target CRS. +- ``PJ_IDENT`` -- "identity", return the source coordinate unchanged. +- ``PJ_INV`` -- "inverse" transformation from target CRS to source CRS. + +It returns the new transformed :c:type:`PJ_COORD` coordinate. + +We can perform the transformation in reverse (from UTM zone 32 back to +geographic) as follows: + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 82-83 + :dedent: 4 + +Before ending the program, we need to release the memory allocated to our +objects: + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :lines: 86-87 + :dedent: 4 + + +A complete compilable version of the example code can be seen below: + +.. literalinclude:: ../../../examples/pj_obs_api_mini_demo.c + :language: c + :linenos: + :lines: 39- + diff --git a/_sources/development/reference/cpp/common.rst.txt b/_sources/development/reference/cpp/common.rst.txt new file mode 100644 index 00000000..4e92f6b2 --- /dev/null +++ b/_sources/development/reference/cpp/common.rst.txt @@ -0,0 +1,8 @@ +.. _common: + +common namespace +---------------- + +.. doxygennamespace:: osgeo::proj::common + :project: doxygen_api + :members: diff --git a/_sources/development/reference/cpp/cpp_general.rst.txt b/_sources/development/reference/cpp/cpp_general.rst.txt new file mode 100644 index 00000000..4d27814f --- /dev/null +++ b/_sources/development/reference/cpp/cpp_general.rst.txt @@ -0,0 +1,7 @@ +.. _cpp_general: + +General documentation +--------------------- + +.. doxygenpage:: general_doc + :project: doxygen_api diff --git a/_sources/development/reference/cpp/crs.rst.txt b/_sources/development/reference/cpp/crs.rst.txt new file mode 100644 index 00000000..f8df118e --- /dev/null +++ b/_sources/development/reference/cpp/crs.rst.txt @@ -0,0 +1,8 @@ +.. _crs: + +crs namespace +------------- + +.. doxygennamespace:: osgeo::proj::crs + :project: doxygen_api + :members: diff --git a/_sources/development/reference/cpp/cs.rst.txt b/_sources/development/reference/cpp/cs.rst.txt new file mode 100644 index 00000000..376ae6a6 --- /dev/null +++ b/_sources/development/reference/cpp/cs.rst.txt @@ -0,0 +1,8 @@ +.. _cs: + +cs namespace +------------ + +.. doxygennamespace:: osgeo::proj::cs + :project: doxygen_api + :members: diff --git a/_sources/development/reference/cpp/datum.rst.txt b/_sources/development/reference/cpp/datum.rst.txt new file mode 100644 index 00000000..0a545a68 --- /dev/null +++ b/_sources/development/reference/cpp/datum.rst.txt @@ -0,0 +1,8 @@ +.. _datum: + +datum namespace +--------------- + +.. doxygennamespace:: osgeo::proj::datum + :project: doxygen_api + :members: diff --git a/_sources/development/reference/cpp/index.rst.txt b/_sources/development/reference/cpp/index.rst.txt new file mode 100644 index 00000000..bedfbe52 --- /dev/null +++ b/_sources/development/reference/cpp/index.rst.txt @@ -0,0 +1,19 @@ +.. _cpp: + +================================================================================ +C++ API +================================================================================ + +.. toctree:: + :maxdepth: 1 + + cpp_general + common + util + metadata + cs + datum + crs + operation + io + diff --git a/_sources/development/reference/cpp/io.rst.txt b/_sources/development/reference/cpp/io.rst.txt new file mode 100644 index 00000000..9729af90 --- /dev/null +++ b/_sources/development/reference/cpp/io.rst.txt @@ -0,0 +1,8 @@ +.. _io: + +io namespace +------------ + +.. doxygennamespace:: osgeo::proj::io + :project: doxygen_api + :members: diff --git a/_sources/development/reference/cpp/metadata.rst.txt b/_sources/development/reference/cpp/metadata.rst.txt new file mode 100644 index 00000000..348627e8 --- /dev/null +++ b/_sources/development/reference/cpp/metadata.rst.txt @@ -0,0 +1,8 @@ +.. _metadata: + +metadata namespace +------------------ + +.. doxygennamespace:: osgeo::proj::metadata + :project: doxygen_api + :members: diff --git a/_sources/development/reference/cpp/operation.rst.txt b/_sources/development/reference/cpp/operation.rst.txt new file mode 100644 index 00000000..88096cb8 --- /dev/null +++ b/_sources/development/reference/cpp/operation.rst.txt @@ -0,0 +1,8 @@ +.. _operation: + +operation namespace +------------------- + +.. doxygennamespace:: osgeo::proj::operation + :project: doxygen_api + :members: diff --git a/_sources/development/reference/cpp/util.rst.txt b/_sources/development/reference/cpp/util.rst.txt new file mode 100644 index 00000000..bc9676a4 --- /dev/null +++ b/_sources/development/reference/cpp/util.rst.txt @@ -0,0 +1,8 @@ +.. _util: + +util namespace +-------------- + +.. doxygennamespace:: osgeo::proj::util + :project: doxygen_api + :members: diff --git a/_sources/development/reference/datatypes.rst.txt b/_sources/development/reference/datatypes.rst.txt new file mode 100644 index 00000000..e7b5cca0 --- /dev/null +++ b/_sources/development/reference/datatypes.rst.txt @@ -0,0 +1,999 @@ +.. _datatypes: + +================================================================================ +Data types +================================================================================ + +This section describes the numerous data types in use in PROJ.4. As a rule +of thumb PROJ.4 data types are prefixed with ``PJ_``, or in one particular case, +is simply called :c:type:`PJ`. A few notable exceptions can be traced +back to the very early days of PROJ.4 when the ``PJ_`` prefix was not +consistently used. + +Transformation objects +-------------------------------------------------------------------------------- + +.. c:type:: PJ + + Object containing everything related to a given projection or transformation. + As a user of the PROJ.4 library you are only exposed to pointers to this + object and the contents is hidden behind the public API. :c:type:`PJ` objects + are created with :c:func:`proj_create` and destroyed with + :c:func:`proj_destroy`. + +.. c:type:: PJ_DIRECTION + + Enumeration that is used to convey in which direction a given transformation + should be performed. Used in transformation function call as described in + the section on :ref:`transformation functions <coord_trans_functions>`. + + Forward transformations are defined with the :c: + + .. code-block:: C + + typedef enum proj_direction { + PJ_FWD = 1, /* Forward */ + PJ_IDENT = 0, /* Do nothing */ + PJ_INV = -1 /* Inverse */ + } PJ_DIRECTION; + + .. cpp:enumerator:: PJ_FWD + + Perform transformation in the forward direction. + + .. cpp:enumerator:: PJ_IDENT + + Identity. Do nothing. + + .. cpp:enumerator:: PJ_INV + + Perform transformation in the inverse direction. + +.. c:type:: PJ_CONTEXT + + Context objects enable safe multi-threaded usage of PROJ.4. Each :c:type:`PJ` + object is connected to a context (if not specified, the default context is + used). All operations within a context should be performed in the same thread. + :c:type:`PJ_CONTEXT` objects are created with :c:func:`proj_context_create` + and destroyed with :c:func:`proj_context_destroy`. + + +.. c:type:: PJ_AREA + + .. versionadded:: 6.0.0 + + Opaque object describing an area in which a transformation is performed. + + It is used with :c:func:`proj_create_crs_to_crs` to select the best transformation + between the two input coordinate reference systems. + +2 dimensional coordinates +-------------------------------------------------------------------------------- + +Various 2-dimensional coordinate data types. + +.. c:type:: PJ_LP + + Geodetic coordinate, latitude and longitude. Usually in radians. + + .. code-block:: C + + typedef struct { double lam, phi; } PJ_LP; + + .. c:member:: double PJ_LP.lam + + Longitude. Lambda. + + .. c:member:: double PJ_LP.phi + + Latitude. Phi. + + +.. c:type:: PJ_XY + + 2-dimensional cartesian coordinate. + + .. code-block:: C + + typedef struct { double x, y; } PJ_XY; + + + .. c:member:: double PJ_XY.x + + Easting. + + .. c:member:: double PJ_XY.y + + Northing. + + +.. c:type:: PJ_UV + + 2-dimensional generic coordinate. Usually used when contents can be either + a :c:type:`PJ_XY` or :c:type:`PJ_LP`. + + .. code-block:: C + + typedef struct {double u, v; } PJ_UV; + + + .. c:member:: double PJ_UV.u + + Longitude or easting, depending on use. + + .. c:member:: double PJ_UV.v + + Latitude or northing, depending on use. + + +3 dimensional coordinates +-------------------------------------------------------------------------------- + +The following data types are the 3-dimensional equivalents to the data +types above. + +.. c:type:: PJ_LPZ + + 3-dimensional version of :c:type:`PJ_LP`. Holds longitude, latitude and + a vertical component. + + .. code-block:: C + + typedef struct { double lam, phi, z; } PJ_LPZ; + + .. c:member:: double PJ_LPZ.lam + + Longitude. Lambda. + + .. c:member:: double PJ_LPZ.phi + + Latitude. Phi. + + .. c:member:: double PJ_LPZ.z + + Vertical component. + + +.. c:type:: PJ_XYZ + + Cartesian coordinate in 3 dimensions. Extension of :c:type:`PJ_XY`. + + .. code-block:: C + + typedef struct { double x, y, z; } PJ_XYZ; + + .. c:member:: double PJ_XYZ.x + + Easting or the X component of a 3D cartesian system. + + .. c:member:: double PJ_XYZ.y + + Northing or the Y component of a 3D cartesian system. + + .. c:member:: double PJ_XYZ.z + + Vertical component or the Z component of a 3D cartesian system. + + +.. c:type:: PJ_UVW + + 3-dimensional extension of :c:type:`PJ_UV`. + + .. code-block:: C + + typedef struct {double u, v, w; } PJ_UVW; + + .. c:member:: double PJ_UVW.u + + Longitude or easting, depending on use. + + .. c:member:: double PJ_UVW.v + + Latitude or northing, depending on use. + + .. c:member:: double PJ_UVW.w + + Vertical component. + + +Spatiotemporal coordinate types +-------------------------------------------------------------------------------- + +The following data types are extensions of the triplets above into the time +domain. + + +.. c:type:: PJ_LPZT + + Spatiotemporal version of :c:type:`PJ_LPZ`. + + .. code-block:: C + + typedef struct { + double lam; + double phi; + double z; + double t; + } PJ_LPZT; + + + .. c:member:: double PJ_LPZT.lam + + Longitude. + + .. c:member:: double PJ_LPZT.phi + + Latitude + + .. c:member:: double PJ_LPZT.z + + Vertical component. + + .. c:member:: double PJ_LPZT.t + + Time component. + +.. c:type:: PJ_XYZT + + Generic spatiotemporal coordinate. Useful for e.g. cartesian coordinates with + an attached time-stamp. + + .. code-block:: C + + typedef struct { + double x; + double y; + double z; + double t; + } PJ_XYZT; + + + .. c:member:: double PJ_XYZT.x + + Easting or the X component of a 3D cartesian system. + + .. c:member:: double PJ_XYZT.y + + Northing or the Y component of a 3D cartesian system. + + .. c:member:: double PJ_XYZT.z + + Vertical or the Z component of a 3D cartesian system. + + .. c:member:: double PJ_XYZT.t + + Time component. + + +.. c:type:: PJ_UVWT + + Spatiotemporal version of :c:type:`PJ_UVW`. + + .. code-block:: C + + typedef struct { double u, v, w, t; } PJ_UVWT; + + .. c:member:: double PJ_UVWT.e + + First horizontal component. + + .. c:member:: double PJ_UVWT.n + + Second horizontal component. + + .. c:member:: double PJ_UVWT.w + + Vertical component. + + .. c:member:: double PJ_UVWT.t + + Temporal component. + + +Ancillary types for geodetic computations +-------------------------------------------------------------------------------- + + +.. c:type:: PJ_OPK + + Rotations, for instance three euler angles. + + .. code-block:: C + + typedef struct { double o, p, k; } PJ_OPK; + + .. c:member:: double PJ_OPK.o + + First rotation angle, omega. + + .. c:member:: double PJ_OPK.p + + Second rotation angle, phi. + + .. c:member:: double PJ_OPK.k + + Third rotation angle, kappa. + +.. c:type:: PJ_ENU + + East, north and up components. + + .. code-block:: c + + typedef struct { double e, n, u; } PJ_ENU; + + .. c:member:: double PJ_ENU.e + + East component. + + .. c:member:: double PJ_ENU.n + + North component. + + .. c:member:: double PJ_ENU.u + + Up component. + + +.. c:type:: PJ_GEOD + + Geodesic length, forward and reverse azimuths. + + .. code-block:: C + + typedef struct { double s, a1, a2; } PJ_GEOD; + + .. c:member:: double PJ_GEOD.s + + Geodesic length. + + .. c:member:: double PJ_GEOD.a1 + + Forward azimuth. + + .. c:member:: double PJ_GEOD.a2 + + Reverse azimuth. + + + +Complex coordinate types +-------------------------------------------------------------------------------- + + +.. c:type:: PJ_COORD + + General purpose coordinate union type, applicable in two, three and four dimensions. + This is the default coordinate datatype used in PROJ. + + .. code-block:: C + + typedef union { + double v[4]; + PJ_XYZT xyzt; + PJ_UVWT uvwt; + PJ_LPZT lpzt; + PJ_GEOD geod; + PJ_OPK opk; + PJ_ENU enu; + PJ_XYZ xyz; + PJ_UVW uvw; + PJ_LPZ lpz; + PJ_XY xy; + PJ_UV uv; + PJ_LP lp; + } PJ_COORD ; + + .. c:member:: double v[4] + + Generic four-dimensional vector. + + .. c:member:: PJ_XYZT PJ_COORD.xyzt + + Spatiotemporal cartesian coordinate. + + .. c:member:: PJ_UVWT PJ_COORD.uvwt + + Spatiotemporal generic coordinate. + + .. c:member:: PJ_LPZT PJ_COORD.lpzt + + Longitude, latitude, vertical and time components. + + .. c:member:: PJ_GEOD PJ_COORD.geod + + Geodesic length, forward and reverse azimuths. + + .. c:member:: PJ_OPK PJ_COORD.opk + + Rotations, for instance three euler angles. + + .. c:member:: PJ_ENU PJ_COORD.enu + + East, north and up components. + + .. c:member:: PJ_XYZ PJ_COORD.xyz + + 3-dimensional cartesian coordinate. + + .. c:member:: PJ_UVW PJ_COORD.uvw + + 3-dimensional generic coordinate. + + .. c:member:: PJ_LPZ PJ_COORD.lpz + + Longitude, latitude and vertical component. + + .. c:member:: PJ_XY PJ_COORD.xy + + 2-dimensional cartesian coordinate. + + .. c:member:: PJ_UV PJ_COORD.uv + + 2-dimensional generic coordinate. + + .. c:member:: PJ_LP PJ_COORD.lp + + Longitude and latitude. + + +Projection derivatives +------------------------------------------------------------------------------- + +.. c:type:: PJ_FACTORS + + Various cartographic properties, such as scale factors, angular distortion + and meridian convergence. Calculated with :c:func:`proj_factors`. + + .. code-block:: C + + typedef struct { + double meridional_scale; + double parallel_scale; + double areal_scale; + + double angular_distortion; + double meridian_parallel_angle; + double meridian_convergence; + + double tissot_semimajor; + double tissot_semiminor; + + double dx_dlam; + double dx_dphi; + double dy_dlam; + double dy_dphi; + } PJ_FACTORS; + + .. c:member:: double PJ_FACTORS.meridional_scale + + Meridional scale at coordinate :math:`\left(\lambda,\phi\right)`. + + .. c:member:: double PJ_FACTORS.parallel_scale + + Parallel scale at coordinate :math:`\left(\lambda,\phi\right)`. + + .. c:member:: double PJ_FACTORS.areal_scale + + Areal scale factor at coordinate :math:`\left(\lambda,\phi\right)`. + + .. c:member:: double PJ_FACTORS.angular_distortion + + Angular distortion at coordinate :math:`\left(\lambda,\phi\right)`. + + .. c:member:: double PJ_FACTORS.meridian_parallel_angle + + Meridian/parallel angle, :math:`\theta^\prime`, at coordinate :math:`\left(\lambda,\phi\right)`. + + .. c:member:: double PJ_FACTORS.meridian_convergence + + Meridian convergence at coordinate :math:`\left(\lambda,\phi\right)`. + Sometimes also described as *grid declination*. + + + .. c:member:: double PJ_FACTORS.tissot_semimajor + + Maximum scale factor. + + .. c:member:: double PJ_FACTORS.tissot_semiminor + + Minimum scale factor. + + + .. c:member:: double PJ_FACTORS.dx_dlam + + Partial derivative :math:`\frac{\partial x}{\partial \lambda}` of coordinate + :math:`\left(\lambda,\phi\right)`. + + .. c:member:: double PJ_FACTORS.dy_dlam + + Partial derivative :math:`\frac{\partial y}{\partial \lambda}` of coordinate + :math:`\left(\lambda,\phi\right)`. + + .. c:member:: double PJ_FACTORS.dx_dphi + + Partial derivative :math:`\frac{\partial x}{\partial \phi}` of coordinate + :math:`\left(\lambda,\phi\right)`. + + .. c:member:: double PJ_FACTORS.dy_dphi + + Partial derivative :math:`\frac{\partial y}{\partial \phi}` of coordinate + :math:`\left(\lambda,\phi\right)`. + +List structures +------------------------------------------------------------------------------- + +.. c:type:: PJ_OPERATIONS + + Description a PROJ.4 operation + + .. code-block:: C + + struct PJ_OPERATIONS { + const char *id; /* operation keyword */ + PJ *(*proj)(PJ *); /* operation entry point */ + char * const *descr; /* description text */ + }; + + .. c:member:: const char *id + + Operation keyword. + + .. c:member:: PJ *(*op)(PJ *) + + Operation entry point. + + .. c:member:: char * const * descr + + Description of operation. + + +.. c:type:: PJ_ELLPS + + Description of ellipsoids defined in PROJ.4 + + .. code-block:: C + + struct PJ_ELLPS { + const char *id; + const char *major; + const char *ell; + const char *name; + }; + + .. c:member:: const char *id + + Keyword name of the ellipsoid. + + .. c:member:: const char *major + + Semi-major axis of the ellipsoid, or radius in case of a sphere. + + .. c:member:: const char *ell + + Elliptical parameter, e.g. ``rf=298.257`` or ``b=6356772.2``. + + .. c:member:: const char *name + + Name of the ellipsoid + +.. c:type:: PJ_UNITS + + Distance units defined in PROJ. + + .. code-block:: C + + struct PJ_UNITS { + const char *id; /* units keyword */ + const char *to_meter; /* multiply by value to get meters */ + const char *name; /* comments */ + double factor; /* to_meter factor in actual numbers */ + }; + + .. c:member:: const char *id + + Keyword for the unit. + + .. c:member:: const char *to_meter + + Text representation of the factor that converts a given unit to meters + + .. c:member:: const char *name + + Name of the unit. + + .. c:member:: double factor + + Conversion factor that converts the unit to meters. + +.. c:type:: PJ_PRIME_MERIDIANS + + Prime meridians defined in PROJ. + + .. code-block:: C + + struct PJ_PRIME_MERIDIANS { + const char *id; + const char *defn; + }; + + .. c:member:: const char *id + + Keyword for the prime meridian + + .. c:member:: const char *def + + Offset from Greenwich in DMS format. + +Info structures +------------------------------------------------------------------------------- + +.. c:type:: PJ_INFO + + Struct holding information about the current instance of PROJ. Struct is + populated by :c:func:`proj_info`. + + .. code-block:: C + + typedef struct { + int major; + int minor; + int patch; + const char *release; + const char *version; + const char *searchpath; + } PJ_INFO; + + .. c:member:: const char *PJ_INFO.release + + Release info. Version number and release date, + e.g. "Rel. 4.9.3, 15 August 2016". + + .. c:member:: const char *PJ_INFO.version + + Text representation of the full version number, + e.g. "4.9.3". + + .. c:member:: int PJ_INFO.major + + Major version number. + + .. c:member:: int PJ_INFO.minor + + Minor version number. + + .. c:member:: int PJ_INFO.patch + + Patch level of release. + + .. c:member:: const char PJ_INFO.searchpath + + Search path for PROJ. List of directories separated by + semicolons (Windows) or colons (non-Windows), e.g. + ``C:\\Users\\doctorwho;C:\\OSGeo4W64\\share\\proj``. + Grids and :ref:`init files <init_files>` are looked for in + directories in the search path. + +.. c:type:: PJ_PROJ_INFO + + Struct holding information about a :c:type:`PJ` object. Populated by + :c:func:`proj_pj_info`. The :c:type:`PJ_PROJ_INFO` object provides a + view into the internals of a :c:type:`PJ`, so once the :c:type:`PJ` + is destroyed or otherwise becomes invalid, so does the + :c:type:`PJ_PROJ_INFO` + + .. code-block:: C + + typedef struct { + const char *id; + const char *description; + const char *definition; + int has_inverse; + double accuracy; + } PJ_PROJ_INFO; + + .. c:member:: const char *PJ_PROJ_INFO.id + + Short ID of the operation the :c:type:`PJ` object is based on, that is, + what comes after the ``+proj=`` in a proj-string, e.g. "*merc*". + + .. c:member:: const char *PJ_PROJ_INFO.description + + Long describes of the operation the :c:type:`PJ` object is based on, + e.g. "*Mercator Cyl, Sph&Ell lat_ts=*". + + .. c:member:: const char *PJ_PROJ_INFO.definition + + The proj-string that was used to create the :c:type:`PJ` object with, + e.g. "*+proj=merc +lat_0=24 +lon_0=53 +ellps=WGS84*". + + .. c:member:: int PJ_PROJ_INFO.has_inverse + + 1 if an inverse mapping of the defined operation exists, otherwise 0. + + .. c:member:: double PJ_PROJ_INFO.accuracy + + Expected accuracy of the transformation. -1 if unknown. + +.. c:type:: PJ_GRID_INFO + + Struct holding information about a specific grid in the search path of + PROJ. Populated with the function :c:func:`proj_grid_info`. + + .. code-block:: C + + typedef struct { + char gridname[32]; + char filename[260]; + char format[8]; + LP lowerleft; + LP upperright; + int n_lon, n_lat; + double cs_lon, cs_lat; + } PJ_GRID_INFO; + + .. c:member:: char PJ_GRID_INFO.gridname[32] + + Name of grid, e.g. "*BETA2007.gsb*". + + .. c:member:: char PJ_GRID_INFO + + Full path of grid file, e.g. *"C:\\OSGeo4W64\\share\\proj\\BETA2007.gsb"* + + .. c:member:: char PJ_GRID_INFO.format[8] + + File format of grid file, e.g. "*ntv2*" + + .. c:member:: LP PJ_GRID_INFO.lowerleft + + Geodetic coordinate of lower left corner of grid. + + .. c:member:: LP PJ_GRID_INFO.upperright + + Geodetic coordinate of upper right corner of grid. + + .. c:member:: int PJ_GRID_INFO.n_lon + + Number of grid cells in the longitudinal direction. + + .. c:member:: int PJ_GRID_INFO.n_lat + + Number of grid cells in the latitudinal direction. + + .. c:member:: double PJ_GRID_INFO.cs_lon + + Cell size in the longitudinal direction. In radians. + + .. c:member:: double PJ_GRID_INFO.cs_lat + + Cell size in the latitudinal direction. In radians. + + +.. c:type:: PJ_INIT_INFO + + Struct holding information about a specific init file in the search path of + PROJ. Populated with the function :c:func:`proj_init_info`. + + .. code-block:: C + + typedef struct { + char name[32]; + char filename[260]; + char version[32]; + char origin[32]; + char lastupdate[16]; + } PJ_INIT_INFO; + + .. c:member:: char PJ_INIT_INFO.name[32] + + Name of init file, e.g. "*epsg*". + + .. c:member:: char PJ_INIT_INFO.filename[260] + + Full path of init file, e.g. "*C:\\OSGeo4W64\\share\\proj\\epsg*" + + .. c:member:: char PJ_INIT_INFO.version[32] + + Version number of init file, e.g. "*9.0.0*" + + .. c:member:: char PJ_INIT_INFO.origin[32] + + Originating entity of the init file, e.g. "*EPSG*" + + .. c:member:: char PJ_INIT_INFO.lastupdate + + Date of last update of the init file. + + +.. _error_codes: + +Error codes +----------- + +.. versionadded:: 8.0.0 + +Three classes of errors are defined below. The belonging of a given error +code to a class can bit tested with a binary and test. The error class itself +can be used as an error value in some rare cases where the error does not +fit into a more precise error value. + +Those error codes are still quite generic for a number of them. Details on the +actual errors will be typically logged with the PJ_LOG_ERROR level. + +Errors in class PROJ_ERR_INVALID_OP ++++++++++++++++++++++++++++++++++++ + +.. c:macro:: PROJ_ERR_INVALID_OP + + Class of error codes typically related to coordinate operation initialization, + typically when creating a PJ* object from a PROJ string. + + .. note:: some of them can also be emitted during coordinate transformation, + like PROJ_ERR_INVALID_OP_FILE_NOT_FOUND_OR_INVALID in case the resource loading + is deferred until it is really needed. + +.. c:macro:: PROJ_ERR_INVALID_OP_WRONG_SYNTAX + + Invalid pipeline structure, missing +proj argument, etc. + +.. c:macro:: PROJ_ERR_INVALID_OP_MISSING_ARG + + Missing required operation parameter + +.. c:macro:: PROJ_ERR_INVALID_OP_ILLEGAL_ARG_VALUE + + One of the operation parameter has an illegal value. + +.. c:macro:: PROJ_ERR_INVALID_OP_MUTUALLY_EXCLUSIVE_ARGS + + Mutually exclusive arguments + +.. c:macro:: PROJ_ERR_INVALID_OP_FILE_NOT_FOUND_OR_INVALID + + File not found or with invalid content (particular case of PROJ_ERR_INVALID_OP_ILLEGAL_ARG_VALUE) + +Errors in class PROJ_ERR_COORD_TRANSFM +++++++++++++++++++++++++++++++++++++++ + +.. c:macro:: PROJ_ERR_COORD_TRANSFM + + Class of error codes related to transformation on a specific coordinate. + +.. c:macro:: PROJ_ERR_COORD_TRANSFM_INVALID_COORD + + Invalid input coordinate. e.g. a latitude > 90°. + +.. c:macro:: PROJ_ERR_COORD_TRANSFM_OUTSIDE_PROJECTION_DOMAIN + + Coordinate is outside of the projection domain. e.g. approximate mercator + with \|longitude - lon_0\| > 90°, or iterative convergence method failed. + +.. c:macro:: PROJ_ERR_COORD_TRANSFM_NO_OPERATION + + No operation found, e.g. if no match the required accuracy, or if ballpark transformations + were asked to not be used and they would be only such candidate. + +.. c:macro:: PROJ_ERR_COORD_TRANSFM_OUTSIDE_GRID + + Point to transform falls outside grid/subgrid/TIN. + +.. c:macro:: PROJ_ERR_COORD_TRANSFM_GRID_AT_NODATA + + Point to transform falls in a grid cell that evaluates to nodata. + +Errors in class PROJ_ERR_OTHER +++++++++++++++++++++++++++++++ + +.. c:macro:: PROJ_ERR_OTHER + + Class of error codes that do not fit into one of the above class. + +.. c:macro:: PROJ_ERR_OTHER_API_MISUSE + + Error related to a misuse of PROJ API. + +.. c:macro:: PROJ_ERR_OTHER_NO_INVERSE_OP + + No inverse method available + +.. c:macro:: PROJ_ERR_OTHER_NETWORK_ERROR + + Failure when accessing a network resource. + + +Logging +------------------------------------------------------------------------------- + +.. c:type:: PJ_LOG_LEVEL + + Enum of logging levels in PROJ. Used to set the logging level in PROJ. + Usually using :c:func:`proj_log_level`. + + .. cpp:enumerator:: PJ_LOG_NONE + + Don't log anything. + + .. cpp:enumerator:: PJ_LOG_ERROR + + Log only errors. + + .. cpp:enumerator:: PJ_LOG_DEBUG + + Log errors and additional debug information. + + .. cpp:enumerator:: PJ_LOG_TRACE + + Highest logging level. Log everything including very detailed debug + information. + + .. cpp:enumerator:: PJ_LOG_TELL + + Special logging level that when used in :c:func:`proj_log_level` + will return the current logging level set in PROJ. + + .. versionadded:: 5.1.0 + +.. c:type:: PJ_LOG_FUNC + + Function prototype for the logging function used by PROJ. + Defined as + + .. code-block:: C + + typedef void (*PJ_LOG_FUNCTION)(void *, int, const char *); + + where the first argument (void pointer) references a data structure used by the + calling application, the second argument (int type) is used to set the logging level + and the third argument (const char pointer) is the string that will be logged + by the function. + + + .. versionadded:: 5.1.0 + + +Setting custom I/O functions +------------------------------------------------------------------------------- + +.. versionadded:: 7.0.0 + +.. doxygenstruct:: PROJ_FILE_API + :project: doxygen_api + :members: + +.. doxygentypedef:: PROJ_FILE_HANDLE + :project: doxygen_api + +.. doxygenenum:: PROJ_OPEN_ACCESS + :project: doxygen_api + + +Network related functionality +------------------------------------------------------------------------------- + +.. versionadded:: 7.0.0 + +.. doxygentypedef:: PROJ_NETWORK_HANDLE + :project: doxygen_api + +.. doxygentypedef:: proj_network_open_cbk_type + :project: doxygen_api + +.. doxygentypedef:: proj_network_close_cbk_type + :project: doxygen_api + +.. doxygentypedef:: proj_network_get_header_value_cbk_type + :project: doxygen_api + +.. doxygentypedef:: proj_network_read_range_type + :project: doxygen_api + + +C API for ISO-19111 functionality +------------------------------------------------------------------------------- + +.. doxygengroup:: iso19111_types + :project: doxygen_api + :content-only: + :members: + + diff --git a/_sources/development/reference/functions.rst.txt b/_sources/development/reference/functions.rst.txt new file mode 100644 index 00000000..7a6b37a1 --- /dev/null +++ b/_sources/development/reference/functions.rst.txt @@ -0,0 +1,970 @@ +.. _functions: + +================================================================================ +Functions +================================================================================ + +Threading contexts +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. c:function:: PJ_CONTEXT* proj_context_create(void) + + Create a new threading-context. + + :returns: a new context + +.. c:function:: PJ_CONTEXT* proj_context_clone(PJ_CONTEXT *ctx) + + .. versionadded:: 7.2 + + Create a new threading-context based on an existing context. + + :returns: a new context + +.. c:function:: void proj_context_destroy(PJ_CONTEXT *ctx) + + Deallocate a threading-context. + + :param ctx: Threading context. + :type ctx: :c:type:`PJ_CONTEXT` * + + +Transformation setup +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The objects returned by the functions defined in this section have minimal +interaction with the functions of the +`C API for ISO-19111 functionality`_, and vice versa. See its introduction +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, + - an object code (like "EPSG:4326", "urn:ogc:def:crs:EPSG::4326", + "urn:ogc:def:coordinateOperation:EPSG::1671"), + - an Object name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as + uniqueness is not guaranteed, heuristics are applied to determine the appropriate best match. + - 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") + - a PROJJSON string. The jsonschema is at https://proj.org/schemas/v0.4/projjson.schema.json (*added in 6.2*) + - a compound CRS made from two object names separated with " + ". e.g. "WGS 84 + EGM96 height" (*added in 7.1*) + + Example call: + + .. code-block:: C + + PJ *P = proj_create(0, "+proj=etmerc +lat_0=38 +lon_0=125 +ellps=bessel"); + + If a proj-string contains a +type=crs option, then it is interpreted as + a CRS definition. In particular geographic CRS are assumed to have axis + in the longitude, latitude order and with degree angular unit. The use + of proj-string to describe a CRS is discouraged. It is a legacy means of + conveying CRS descriptions: use of object codes (EPSG:XXXX typically) or + WKT description is recommended for better expressivity. + + If a proj-string does not contain +type=crs, then it is interpreted as a + coordination operation / transformation. + + If creation of the transformation object fails, the function returns `0` and + the PROJ error number is updated. The error number can be read with + :c:func:`proj_errno` or :c:func:`proj_context_errno`. + + The returned :c:type:`PJ`-pointer should be deallocated with :c:func:`proj_destroy`. + + :param ctx: Threading context. + :type ctx: :c:type:`PJ_CONTEXT` * + :param definition: Proj-string of the desired transformation. + :type definition: `const char*` + + +.. c:function:: PJ* proj_create_argv(PJ_CONTEXT *ctx, int argc, char **argv) + + Create a transformation object, or a CRS object, with argc/argv-style initialization. For this + application each parameter in the defining proj-string is an entry in :c:data:`argv`. + + Example call: + + .. code-block:: C + + char *args[3] = {"proj=utm", "zone=32", "ellps=GRS80"}; + PJ* P = proj_create_argv(0, 3, args); + + If there is a type=crs argument, then the arguments are interpreted as + a CRS definition. In particular geographic CRS are assumed to have axis + in the longitude, latitude order and with degree angular unit. + + If there is no type=crs argument, then it is interpreted as a + coordination operation / transformation. + + If creation of the transformation object fails, the function returns `0` and + the PROJ error number is updated. The error number can be read with + :c:func:`proj_errno` or :c:func:`proj_context_errno`. + + The returned :c:type:`PJ`-pointer should be deallocated with :c:func:`proj_destroy`. + + :param ctx: Threading context. + :type ctx: :c:type:`PJ_CONTEXT` * + :param argc: Count of arguments in :c:data:`argv` + :type argc: `int` + :param argv: Array of strings with proj-string parameters, e.g. ``+proj=merc`` + :type argv: `char **` + :returns: :c:type:`PJ` * + +.. c:function:: PJ* proj_create_crs_to_crs(PJ_CONTEXT *ctx, const char *source_crs, const char *target_crs, PJ_AREA *area) + + Create a transformation object that is a pipeline between two known + coordinate reference systems. + + source_crs and target_crs can be : + + - a "AUTHORITY:CODE", like EPSG:25832. When using that syntax for a source + CRS, the created pipeline will expect that the values passed to :c:func:`proj_trans` + respect the axis order and axis unit of the official definition ( + so for example, for EPSG:4326, with latitude first and longitude next, + in degrees). Similarly, when using that syntax for a target CRS, output + values will be emitted according to the official definition of this CRS. + + - a PROJ string, like "+proj=longlat +datum=WGS84". + When using that syntax, the axis order and unit for geographic CRS will + be longitude, latitude, and the unit degrees. + + - 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` 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. + + When no area of use is specific and several coordinate operations are possible + depending on the area of use, this function will internally store those + candidate coordinate operations in the return PJ object. Each subsequent + coordinate transformation done with :c:func:`proj_trans` will then select + the appropriate coordinate operation by comparing the input coordinates with + the area of use of the candidate coordinate operations. + + Example call: + + .. code-block:: C + + PJ *P = proj_create_crs_to_crs(0, "EPSG:25832", "EPSG:25833", 0); + + If creation of the transformation object fails, the function returns `0` and + the PROJ error number is updated. The error number can be read with + :c:func:`proj_errno` or :c:func:`proj_context_errno`. + + + The returned :c:type:`PJ`-pointer should be deallocated with :c:func:`proj_destroy`. + + :param ctx: Threading context. + :type ctx: :c:type:`PJ_CONTEXT` * + :param `source_crs`: Source CRS. + :type `source_crs`: `const char*` + :param `target_crs`: Destination SRS. + :type `target_crs`: `const char*` + :param `area`: Descriptor of the desired area for the transformation. + :type `area`: :c:type:`PJ_AREA` * + :returns: :c:type:`PJ` * + +.. c:function:: PJ* proj_create_crs_to_crs_from_pj(PJ_CONTEXT *ctx, PJ *source_crs, PJ *target_crs, PJ_AREA *area, const char* const *options) + + .. versionadded:: 6.2.0 + + Create a transformation object that is a pipeline between two known + coordinate reference systems. + + This is the same as :c:func:`proj_create_crs_to_crs` except that the source and + target CRS are passed as PJ* objects which must be of the CRS variety. + + :param `options`: a list of NUL terminated options, or NULL. + + The list of supported options is: + + - AUTHORITY=name: to restrict the authority of coordinate operations + looked up in the database. When not specified, coordinate + ``operations from any authority`` will be searched, with the restrictions set + in the authority_to_authority_preference database table related to the authority + of the source/target CRS themselves. + If authority is set to "any", then coordinate operations from any authority will be searched + If authority is a non-empty string different of ``any``, then coordinate operations + will be searched only in that authority namespace (e.g ``EPSG``). + + - ACCURACY=value: to set the minimum desired accuracy (in metres) of the + candidate coordinate operations. + + - ALLOW_BALLPARK=YES/NO: can be set to NO to disallow the use of + :term:`Ballpark transformation` in the candidate coordinate operations. + + - FORCE_OVER=YES/NO: can be set to YES to force the +over flag on the transformation + returned by this function. + +.. doxygenfunction:: proj_normalize_for_visualization + :project: doxygen_api + +.. c:function:: PJ* proj_destroy(PJ *P) + + Deallocate a :c:type:`PJ` transformation object. + + :param `P`: Transformation object + :type `P`: const :c:type:`PJ` * + :returns: :c:type:`PJ` * + +Area of interest +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. versionadded:: 6.0.0 + + +.. c:function:: PJ_AREA* proj_area_create(void) + + Create an area of use. + + Such an area of use is to be passed to :c:func:`proj_create_crs_to_crs` to + specify the area of use for the choice of relevant coordinate operations. + + :returns: :c:type:`PJ_AREA` * to be deallocated with :c:func:`proj_area_destroy` + + +.. c:function:: void proj_area_set_bbox(PJ_AREA *area, double west_lon_degree, double south_lat_degree, double east_lon_degree, double north_lat_degree) + + Set the bounding box of the area of use + + Such an area of use is to be passed to :c:func:`proj_create_crs_to_crs` to + specify the area of use for the choice of relevant coordinate operations. + + In the case of an area of use crossing the antimeridian (longitude +/- 180 degrees), + `west_lon_degree` will be greater than `east_lon_degree`. + + :param `area`: Pointer to an object returned by :c:func:`proj_area_create`. + :param `west_lon_degree`: West longitude, in degrees. In [-180,180] range. + :param `south_lat_degree`: South latitude, in degrees. In [-90,90] range. + :param `east_lon_degree`: East longitude, in degrees. In [-180,180] range. + :param `north_lat_degree`: North latitude, in degrees. In [-90,90] range. + +.. c:function:: void proj_area_destroy(PJ_AREA* area) + + Deallocate a :c:type:`PJ_AREA` object. + + :param PJ_AREA* area + + +.. _coord_trans_functions: + +Coordinate transformation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +.. c:function:: PJ_COORD proj_trans(PJ *P, PJ_DIRECTION direction, PJ_COORD coord) + + Transform a single :c:type:`PJ_COORD` coordinate. + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param `direction`: Transformation direction. + :type `direction`: PJ_DIRECTION + :param coord: Coordinate that will be transformed. + :type coord: :c:type:`PJ_COORD` + :returns: :c:type:`PJ_COORD` + + +.. c:function:: size_t proj_trans_generic(PJ *P, PJ_DIRECTION direction, \ + double *x, size_t sx, size_t nx, \ + double *y, size_t sy, size_t ny, \ + double *z, size_t sz, size_t nz, \ + double *t, size_t st, size_t nt) + + Transform a series of coordinates, where the individual coordinate dimension + may be represented by an array that is either + + 1. fully populated + 2. a null pointer and/or a length of zero, which will be treated as a + fully populated array of zeroes + 3. of length one, i.e. a constant, which will be treated as a fully + populated array of that constant value + + .. note:: Even though the 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 behavior + 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_trans_generic` to handle transformation of a large class of application + specific data structures, without necessarily understanding the data structure + format, as in: + + .. code-block:: C + + typedef struct { + double x, y; + int quality_level; + char surveyor_name[134]; + } XYQS; + + XYQS survey[345]; + double height = 23.45; + size_t stride = sizeof (XYQS); + + ... + + proj_trans_generic ( + P, PJ_INV, + &(survey[0].x), stride, 345, /* We have 345 eastings */ + &(survey[0].y), stride, 345, /* ...and 345 northings. */ + &height, sizeof(double), 1, /* The height is the constant 23.45 m */ + 0, 0, 0 /* and the time is the constant 0.00 s */ + ); + + 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 (...)``). + + 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_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 P: Transformation object + :type P: :c:type:`PJ` * + :param direction: Transformation direction. + :type direction: PJ_DIRECTION + :param x: Array of x-coordinates + :type x: `double *` + :param sx: Step length, in bytes, between consecutive elements of the corresponding array + :type sx: `size_t` + :param nx: Number of elements in the corresponding array + :type nx: `size_t` + :param y: Array of y-coordinates + :type y: `double *` + :param sy: Step length, in bytes, between consecutive elements of the corresponding array + :type sy: `size_t` + :param ny: Number of elements in the corresponding array + :type ny: `size_t` + :param z: Array of z-coordinates + :type z: `double *` + :param sz: Step length, in bytes, between consecutive elements of the corresponding array + :type sz: `size_t` + :param nz: Number of elements in the corresponding array + :type nz: `size_t` + :param t: Array of t-coordinates + :type t: `double *` + :param st: Step length, in bytes, between consecutive elements of the corresponding array + :type st: `size_t` + :param nt: Number of elements in the corresponding array + :type nt: `size_t` + :returns: Number of transformations successfully completed + + + +.. c:function:: int proj_trans_array(PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord) + + Batch transform an array of :c:type:`PJ_COORD`. + + Performs transformation on all points, even if errors occur on some points + (new to 8.0. Previous versions would exit early in case of failure on a given point) + + Individual points that fail to transform will have their components set to + ``HUGE_VAL`` + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param `direction`: Transformation direction. + :type `direction`: PJ_DIRECTION + :param n: Number of coordinates in :c:data:`coord` + :type n: `size_t` + :returns: `int` 0 if all observations are transformed without error, otherwise returns error number. + This error number will be a precise error number if all coordinates that fail to transform + for the same reason, or a generic error code if they fail for different + reasons. + + + +.. doxygenfunction:: proj_trans_bounds + :project: doxygen_api + + +Error reporting +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. c:function:: int proj_errno(PJ *P) + + Get a reading of the current error-state of :c:data:`P`. An non-zero error + codes indicates an error either with the transformation setup or during a + transformation. In cases :c:data:`P` is `0` the error number of the default + context is read. A text representation of the error number can be retrieved + with :c:func:`proj_errno_string`. + + Consult :ref:`error_codes` for the list of error codes (PROJ >= 8.0) + + :param P: Transformation object + :type P: :c:type:`PJ` * + + :returns: `int` + +.. c:function:: int proj_context_errno(PJ_CONTEXT *ctx) + + Get a reading of the current error-state of :c:data:`ctx`. An non-zero error + codes indicates an error either with the transformation setup or during a + transformation. A text representation of the error number can be retrieved + with :c:func:`proj_errno_string`. + + Consult :ref:`error_codes` for the list of error codes (PROJ >= 8.0) + + :param ctx: threading context. + :type ctx: :c:type:`PJ_CONTEXT` * + + :returns: `int` + +.. c:function:: void proj_errno_set(PJ *P, int err) + + Change the error-state of :c:data:`P` to `err`. + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param err: Error number. + :type err: `int` + +.. c:function:: int proj_errno_reset(PJ *P) + + Clears the error number in :c:data:`P`, and bubbles it up to the context. + + Example: + + .. code-block:: C + + void foo (PJ *P) { + int last_errno = proj_errno_reset (P); + + do_something_with_P (P); + + /* failure - keep latest error status */ + if (proj_errno(P)) + return; + /* success - restore previous error status */ + proj_errno_restore (P, last_errno); + return; + } + + :param P: Transformation object + :type P: :c:type:`PJ` * + + :returns: `int` Returns the previous value of the errno, for convenient reset/restore operations. + +.. c:function:: void proj_errno_restore(PJ *P, int err) + + Reduce some mental impedance in the canonical reset/restore use case: + Basically, :c:func:`proj_errno_restore()` is a synonym for + :c:func:`proj_errno_set()`, but the use cases are very different: + *set* indicate an error to higher level user code, *restore* passes previously + set error indicators in case of no errors at this level. + + Hence, although the inner working is identical, we provide both options, + to avoid some rather confusing real world code. + + See usage example under :c:func:`proj_errno_reset` + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param err: Error number. + :type err: `int` + +.. c:function:: const char* proj_errno_string(int err) + + .. versionadded:: 5.1.0 + + Get a text representation of an error number. + + .. deprecated:: This function is potentially thread-unsafe, replaced by :c:func:`proj_context_errno_string`. + + :param err: Error number. + :type err: `int` + + :returns: `const char*` String with description of error. + +.. c:function:: const char* proj_context_errno_string(PJ_CONTEXT* ctx, int err) + + .. versionadded:: 8.0.0 + + Get a text representation of an error number. + + :param ctx: threading context. + :type ctx: :c:type:`PJ_CONTEXT` * + + :param err: Error number. + :type err: `int` + + :returns: `const char*` String with description of error. + +Logging +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. c:function:: PJ_LOG_LEVEL proj_log_level (PJ_CONTEXT *ctx, PJ_LOG_LEVEL level) + + Get and set logging level for a given context. Changes the log level to + :c:data:`level` and returns the previous logging level. If called with + :c:data:`level` set to :c:type:`PJ_LOG_TELL` the function returns the current + logging level without changing it. + + :param ctx: Threading context. + :type ctx: :c:type:`PJ_CONTEXT` * + :param level: New logging level. + :type level: PJ_LOG_LEVEL + + :returns: :c:type:`PJ_LOG_LEVEL` + + .. versionadded:: 5.1.0 + +.. c:function:: void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION logf) + + Override the internal log function of PROJ. + + :param ctx: Threading context. + :type ctx: :c:type:`PJ_CONTEXT` * + :param app_data: Pointer to data structure used by the calling application. + :type app_data: `void *` + :param logf: Log function that overrides the PROJ log function. + :type logf: :c:type:`PJ_LOG_FUNCTION` + + .. versionadded:: 5.1.0 + +Info functions +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. c:function:: PJ_INFO proj_info(void) + + Get information about the current instance of the PROJ library. + + :returns: :c:type:`PJ_INFO` + +.. c:function:: PJ_PROJ_INFO proj_pj_info(const PJ *P) + + Get information about a specific transformation object, :c:data:`P`. + + :param P: Transformation object + :type P: const :c:type:`PJ` * + :returns: :c:type:`PJ_PROJ_INFO` + +.. c:function:: PJ_GRID_INFO proj_grid_info(const char *gridname) + + Get information about a specific grid. + + :param `gridname`: Gridname in the PROJ searchpath + :type `gridname`: `const char*` + :returns: :c:type:`PJ_GRID_INFO` + +.. c:function:: PJ_INIT_INFO proj_init_info(const char *initname) + + Get information about a specific init file. + + :param `initname`: Init file in the PROJ searchpath + :type `initname`: `const char*` + :returns: :c:type:`PJ_INIT_INFO` + +Lists +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. c:function:: const PJ_OPERATIONS* proj_list_operations(void) + + Get a pointer to an array of all operations in PROJ. The last entry + of the returned array is a NULL-entry. The array is statically allocated + and does not need to be freed after use. + + Print a list of all operations in PROJ: + + .. code-block:: C + + PJ_OPERATIONS *ops; + for (ops = proj_list_operations(); ops->id; ++ops) + printf("%s\n", ops->id); + + + :returns: const :c:type:`PJ_OPERATIONS` * + +.. c:function:: const PJ_ELLPS* proj_list_ellps(void) + + Get a pointer to an array of ellipsoids defined in PROJ. The last entry + of the returned array is a NULL-entry. The array is statically allocated + and does not need to be freed after use. + + :returns: const :c:type:`PJ_ELLPS` * + +.. c:function:: const PJ_UNITS* proj_list_units(void) + + Get a pointer to an array of distance units defined in PROJ. The last + entry of the returned array is a NULL-entry. The array is statically + allocated and does not need to be freed after use. + + Note: starting with PROJ 7.1, this function is deprecated by + :cpp:func:`proj_get_units_from_database` + + :returns: const :c:type:`PJ_UNITS` * + +.. c:function:: const PJ_PRIME_MERIDIANS* proj_list_prime_meridians(void) + + Get a pointer to an array of prime meridians defined in PROJ. The last + entry of the returned array is a NULL-entry. The array is statically + allocated and does not need to be freed after use. + + :returns: const :c:type:`PJ_PRIME_MERIDIANS` * + +Distances +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. c:function:: double proj_lp_dist(const PJ *P, PJ_COORD a, PJ_COORD b) + + Calculate geodesic distance between two points in geodetic coordinates. The + calculated distance is between the two points located on the ellipsoid. + + The coordinates in :c:data:`a` and :c:data:`b` needs to be given as longitude + and latitude in radians. Note that the axis order of the :c:data:`P` object + is not taken into account in this function, so even though a CRS object comes + with axis ordering latitude/longitude coordinates used in this function should + be reordered as longitude/latitude. + + :param P: Transformation or CRS object + :type P: const :c:type:`PJ` * + :param PJ_COORD a: Coordinate of first point + :param PJ_COORD b: Coordinate of second point + :returns: `double` Distance between :c:data:`a` and :c:data:`b` in meters. + +.. c:function:: double proj_lpz_dist(const PJ *P, PJ_COORD a, PJ_COORD b) + + Calculate geodesic distance between two points in geodetic coordinates. + Similar to :c:func:`proj_lp_dist` but also takes the height above the ellipsoid + into account. + + The coordinates in :c:data:`a` and :c:data:`b` needs to be given as longitude + and latitude in radians. Note that the axis order of the :c:data:`P` object + is not taken into account in this function, so even though a CRS object comes + with axis ordering latitude/longitude coordinates used in this function should + be reordered as longitude/latitude. + + :param P: Transformation or CRS object + :type P: const :c:type:`PJ` * + :param PJ_COORD a: Coordinate of first point + :param PJ_COORD b: Coordinate of second point + :returns: `double` Distance between :c:data:`a` and :c:data:`b` in meters. + +.. c:function:: double proj_xy_dist(PJ_COORD a, PJ_COORD b) + + Calculate 2-dimensional euclidean between two projected coordinates. + + :param PJ_COORD a: First coordinate + :param PJ_COORD b: Second coordinate + :returns: `double` Distance between :c:data:`a` and :c:data:`b` in meters. + +.. c:function:: double proj_xyz_dist(PJ_COORD a, PJ_COORD b) + + Calculate 3-dimensional euclidean between two projected coordinates. + + :param PJ_COORD a: First coordinate + :param PJ_COORD b: Second coordinate + :returns: `double` Distance between :c:data:`a` and :c:data:`b` in meters. + +.. c:function:: PJ_COORD proj_geod(const PJ *P, PJ_COORD a, PJ_COORD b) + + Calculate the geodesic distance as well as forward and reverse azimuth + between two points on the ellipsoid. + + The coordinates in :c:data:`a` and :c:data:`b` needs to be given as longitude + and latitude in radians. Note that the axis order of the :c:data:`P` object + is not taken into account in this function, so even though a CRS object comes + with axis ordering latitude/longitude coordinates used in this function should + be reordered as longitude/latitude. + + :param P: Transformation or CRS object + :type P: const :c:type:`PJ` * + :param PJ_COORD a: Coordinate of first point + :param PJ_COORD b: Coordinate of second point + :returns: `PJ_COORD` where the first value is the distance between :c:data:`a` + and :c:data:`b` in meters, the second value is the forward azimuth + and the third value is the reverse azimuth. The fourth coordinate + value is unused. + + + +Various +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. c:function:: PJ_COORD proj_coord(double x, double y, double z, double t) + + Initializer for the :c:type:`PJ_COORD` union. The function is + shorthand for the otherwise convoluted assignment. + Equivalent to + + .. code-block:: C + + PJ_COORD c = {{10.0, 20.0, 30.0, 40.0}}; + + or + + .. code-block:: C + + PJ_COORD c; + // Assign using the PJ_XYZT struct in the union + c.xyzt.x = 10.0; + c.xyzt.y = 20.0; + c.xyzt.z = 30.0; + c.xyzt.t = 40.0; + + Since :c:type:`PJ_COORD` is a union of structs, the above assignment can + also be expressed in terms of the other types in the union, e.g. + :c:type:`PJ_UVWT` or :c:type:`PJ_LPZT`. + + + :param x: 1st component in a :c:type:`PJ_COORD` + :type x: `double` + :param y: 2nd component in a :c:type:`PJ_COORD` + :type y: `double` + :param z: 3rd component in a :c:type:`PJ_COORD` + :type z: `double` + :param t: 4th component in a :c:type:`PJ_COORD` + :type t: `double` + :returns: :c:type:`PJ_COORD` + + +.. c:function:: double proj_roundtrip(PJ *P, PJ_DIRECTION direction, int n, PJ_COORD *coord) + + Measure internal consistency of a given transformation. The function + performs :c:data:`n` round trip transformations starting in either + the forward or reverse :c:data:`direction`. Returns the euclidean + distance of the starting point :c:data:`coo` and the resulting + coordinate after :c:data:`n` iterations back and forth. + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param `direction`: Starting direction of transformation + :type `direction`: PJ_DIRECTION + :param n: Number of roundtrip transformations + :type n: `int` + :param coord: Input coordinate + :type coord: :c:type:`PJ_COORD` * + :returns: `double` Distance between original coordinate and the \ + resulting coordinate after :c:data:`n` transformation iterations. + +.. c:function:: PJ_FACTORS proj_factors(PJ *P, PJ_COORD lp) + + Calculate various cartographic properties, such as scale factors, angular + distortion and meridian convergence. Depending on the underlying projection + values will be calculated either numerically (default) or analytically. + + Starting with PROJ 8.2, the P object can be a projected CRS, for example + instantiated from a EPSG CRS code. The factors computed will be those of the + map projection implied by the transformation from the base geographic CRS of + the projected CRS to the projected CRS. + + The input geodetic coordinate lp should be such that lp.lam is the longitude + in radian, and lp.phi the latitude in radian (thus independently of the + definition of the base CRS, if P is a projected CRS). + + The function also calculates the partial derivatives of the given + coordinate. + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param `lp`: Geodetic coordinate + :type `lp`: :c:type:`PJ_COORD` + :returns: :c:type:`PJ_FACTORS` + +.. c:function:: double proj_torad(double angle_in_degrees) + + Convert degrees to radians. + + :param angle_in_degrees: Degrees + :type angle_in_degrees: `double` + :returns: `double` Radians + +.. c:function:: double proj_todeg(double angle_in_radians) + + Convert radians to degrees + + :param angle_in_radians: Radians + :type angle_in_radians: `double` + :returns: `double` Degrees + +.. c:function:: double proj_dmstor(const char *is, char **rs) + + Convert string of degrees, minutes and seconds to radians. + Works similarly to the C standard library function :c:func:`strtod`. + + :param `is`: Value to be converted to radians + :type `is`: `const char*` + :param `rs`: Reference to an already allocated char*, whose value is \ + set by the function to the next character in :c:data:`is` \ + after the numerical value. + +.. c:function:: char *proj_rtodms(char *s, double r, int pos, int neg) + + Convert radians to string representation of degrees, minutes and seconds. + + :param s: Buffer that holds the output string + :type s: `char *` + :param r: Value to convert to dms-representation + :type r: `double` + :param pos: Character denoting positive direction, typically `'N'` or `'E'`. + :type pos: `int` + :param neg: Character denoting negative direction, typically `'S'` or `'W'`. + :type neg: `int` + :returns: `char*` Pointer to output buffer (same as :c:data:`s`) + + +.. c:function:: int proj_angular_input (PJ *P, enum PJ_DIRECTION dir) + + Check if an operation expects input in radians or not. + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param `direction`: Starting direction of transformation + :type `direction`: PJ_DIRECTION + :returns: `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 output in radians or not. + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param `direction`: Starting direction of transformation + :type `direction`: PJ_DIRECTION + :returns: `int` 1 if output units is expected in radians, otherwise 0 + +.. c:function:: int proj_degree_input (PJ *P, enum PJ_DIRECTION dir) + + .. versionadded:: 7.1.0 + + Check if an operation expects input in degrees or not. + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param `direction`: Starting direction of transformation + :type `direction`: PJ_DIRECTION + :returns: `int` 1 if input units is expected in degrees, otherwise 0 + +.. c:function:: int proj_degree_output (PJ *P, enum PJ_DIRECTION dir) + + .. versionadded:: 7.1.0 + + Check if an operation returns output in degrees or not. + + :param P: Transformation object + :type P: :c:type:`PJ` * + :param `direction`: Starting direction of transformation + :type `direction`: PJ_DIRECTION + :returns: `int` 1 if output units is expected in degrees, otherwise 0 + + +Setting custom I/O functions +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. versionadded:: 7.0.0 + +.. doxygenfunction:: proj_context_set_fileapi + :project: doxygen_api + +.. doxygenfunction:: proj_context_set_sqlite3_vfs_name + :project: doxygen_api + +.. doxygenfunction:: proj_context_set_file_finder + :project: doxygen_api + +.. doxygenfunction:: proj_context_set_search_paths + :project: doxygen_api + +.. doxygenfunction:: proj_context_set_ca_bundle_path + :project: doxygen_api + + +Network related functionality +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. versionadded:: 7.0.0 + +.. doxygenfunction:: proj_context_set_network_callbacks + :project: doxygen_api + +.. doxygenfunction:: proj_context_set_enable_network + :project: doxygen_api + +.. doxygenfunction:: proj_context_is_network_enabled + :project: doxygen_api + +.. doxygenfunction:: proj_context_set_url_endpoint + :project: doxygen_api + +.. doxygenfunction:: proj_context_get_url_endpoint + :project: doxygen_api + +.. doxygenfunction:: proj_context_get_user_writable_directory + :project: doxygen_api + +.. doxygenfunction:: proj_grid_cache_set_enable + :project: doxygen_api + +.. doxygenfunction:: proj_grid_cache_set_filename + :project: doxygen_api + +.. doxygenfunction:: proj_grid_cache_set_max_size + :project: doxygen_api + +.. doxygenfunction:: proj_grid_cache_set_ttl + :project: doxygen_api + +.. doxygenfunction:: proj_grid_cache_clear + :project: doxygen_api + +.. doxygenfunction:: proj_is_download_needed + :project: doxygen_api + +.. doxygenfunction:: proj_download_file + :project: doxygen_api + + +Cleanup +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. c:function:: void proj_cleanup() + + .. versionadded:: 6.2.0 + + This function frees global resources (grids, cache of +init files). It + should be called typically before process termination, and *after* having + freed PJ and PJ_CONTEXT objects. + + +C API for ISO-19111 functionality ++++++++++++++++++++++++++++++++++ + +.. versionadded:: 6.0.0 + +The PJ* objects returned by :c:func:`proj_create_from_wkt`, +:c:func:`proj_create_from_database` and other functions in that section +will have generally minimal interaction with the functions declared in the +previous sections (calling those functions on those objects +will either return an error or default/nonsensical values). The exception is +for ISO19111 objects of type CoordinateOperation that can be exported as a +valid PROJ pipeline. In this case, objects will work for example with +:c:func:`proj_trans_generic`. +Conversely, objects returned by :c:func:`proj_create` and :c:func:`proj_create_argv`, +which are not of type CRS (can be tested with :c:func:`proj_is_crs`), +will return an error when used with functions of this section. + +.. doxygengroup:: iso19111_functions + :project: doxygen_api + :content-only: + diff --git a/_sources/development/reference/index.rst.txt b/_sources/development/reference/index.rst.txt new file mode 100644 index 00000000..f04f4b3e --- /dev/null +++ b/_sources/development/reference/index.rst.txt @@ -0,0 +1,13 @@ +.. _reference: + +================================================================================ +Reference +================================================================================ + +.. toctree:: + :maxdepth: 1 + + macros + datatypes + functions + cpp/index.rst diff --git a/_sources/development/reference/macros.rst.txt b/_sources/development/reference/macros.rst.txt new file mode 100644 index 00000000..c25aeed2 --- /dev/null +++ b/_sources/development/reference/macros.rst.txt @@ -0,0 +1,39 @@ +.. _macros: + +================================================================================ +Macros +================================================================================ + +.. c:macro:: PROJ_VERSION_MAJOR + + Major version number, e.g. 8 for PROJ 8.0.1 + +.. c:macro:: PROJ_VERSION_MINOR + + Minor version number, e.g. 0 for PROJ 8.0.1 + +.. c:macro:: PROJ_VERSION_PATCH + + Patch version number, e.g. 1 for PROJ 8.0.1 + +.. c:macro:: PROJ_COMPUTE_VERSION(maj,min,patch) + + .. versionadded:: 8.0.1 + + Compute the version number from the major, minor and patch numbers. + +.. c:macro:: PROJ_VERSION_NUMBER + + .. versionadded:: 8.0.1 + + Total version number, equal to + ``PROJ_COMPUTE_VERSION(PROJ_VERSION_MAJOR, PROJ_VERSION_MINOR, PROJ_VERSION_PATCH)`` + +.. c:macro:: PROJ_AT_LEAST_VERSION(maj,min,patch) + + .. versionadded:: 8.0.1 + + Macro that returns true if the current PROJ version is at least the version + specified by (maj,min,patch) + + Equivalent to ``PROJ_VERSION_NUMBER >= PROJ_COMPUTE_VERSION(maj,min,patch)`` diff --git a/_sources/development/transformations.rst.txt b/_sources/development/transformations.rst.txt new file mode 100644 index 00000000..b03ce368 --- /dev/null +++ b/_sources/development/transformations.rst.txt @@ -0,0 +1,7 @@ +.. _dev_transformations: + +================================================================================ +Transformations +================================================================================ + + |
