[Proj] A re-rationalized API for PROJ.4

Mikael Rittri Mikael.Rittri at carmenta.com
Mon Nov 14 04:02:45 PST 2016


I just want to say that, although I personally will probably not bother to change to the new API, I have always found the traditional source code of Proj.4 difficult to read, and I am happy to see a new enthusiastic group of developers taking care of Proj.4.  The period of stagnation a few years ago was unfortunate.

Mikael Rittri
Carmenta
Sweden
http://www.carmenta.com<http://www.carmenta.com/>

________________________________
From: proj-bounces at lists.maptools.org [mailto:proj-bounces at lists.maptools.org] On Behalf Of Kristian Evers
Sent: Thursday, November 03, 2016 3:41 PM
To: PROJ.4 and general Projections Discussions
Subject: [Proj] A re-rationalized API for PROJ.4

Hello everybody,

I want to direct your attention to the work Thomas Knudsen is doing on a new and more homogenous API for PROJ.4. Thomas presented his first ideas about a new API earlier this year when talk about transformation pipelines first started. Since then the initial pipeline pull request has been withdrawn and the changes needed to make transformation pipelines happen are broken into smaller more logical chunks. A new API being one of those smaller chunks. Before anyone gets their knickers in a twist, let me just stress the fact that this DOES NOT change the behavior of the old API (projects.h/proj_api.h), it merely adds a cleaner interface that will make usage of PROJ.4 a lot easier in the future.
Thomas has already typed up a description of his work but until now it has only been available on the GitHub page. This is his introduction to the new API:

The original proj API (defined in projects.h) has grown organically
over the years, but it has also grown somewhat messy.

The same has happened with the newer high level API (defined in
proj_api.h): To support various historical objectives, proj_api.h
contains a rather complex combination of conditional defines and
typedefs. Probably for good (historical) reasons, which are not
always evident from today's perspective.

This is an evolving attempt at creating a re-rationalized API
with primary design goals focused on sanitizing the namespaces.
Hence, all symbols exposed are being moved to the pj_ namespace,
while all data types are being moved to the PJ_ namespace.

Please note that this API is *orthogonal* to  the previous APIs:
Apart from some inclusion guards, projects.h and proj_api.h are not
touched - if you do not include proj.h, the projects and proj_api
APIs should work as they always have.

A few implementation details:

Apart from the namespacing efforts, I'm trying to eliminate three
proj_api elements, which I have found especially confusing.

FIRST and foremost, I try to avoid typedef'ing away pointer
semantics. I agree that it can be occasionally useful, but I
prefer having the pointer nature of function arguments being
explicitly visible.

Hence, projCtx has been replaced by PJ_CONTEXT *.

SECOND, I try to eliminate cases of information hiding implemented
by redefining data types to void pointers.

I prefer using a combination of forward declarations and typedefs.
Hence:
    typedef void *projCtx;
Has been replaced by:
    struct projCtx_t;
    typedef struct projCtx_t PJ_CONTEXT;
This makes it possible for the calling program to know that the
PJ_CONTEXT data type exists, and handle pointers to that data type
without having any idea about its internals.

(obviously, in this example, struct projCtx_t should also be moved
to struct pj_ctx some day...)

THIRD, I try to eliminate implicit type punning. Hence this API
introduces the OBSERVATION data type, for generic coordinate and
ancillary data handling.

It includes the PJ_SPATIOTEMPORAL and PJ_TRIPLET unions
making it possible to make explicit the previously used
"implicit type punning", where a XY is turned into a LP by
re#defining both as UV, behind the back of the user.

The bare essentials API presented here follows the PROJ.4
convention of sailing the coordinate to be reprojected, up on
the stack ("call by value"), and symmetrically returning the
result on the stack. Although the OBSERVATION object is 4 times
as large as the traditional XY and LP objects, timing results
have shown the overhead to be very reasonable.

See pj_proj_test.c for an example of how to use the API.

The pull request is found at https://github.com/OSGeo/proj.4/pull/445 and the example code can be found here: https://github.com/busstoptaktik/proj.4/blob/pipeline_plus_api/examples/pj_proj_test.c

Please share your thoughts on the new API that Thomas has been working on. There has already been some discussion about how to expose the thread-contexts of the PJ-objects. In the current incarnation they are somewhat hidden to the user compared the what's in proj_api.h. On top of that, Thomas and I have personally discussed the projFileAPI which does not seem to be used outside of PROJ.4 itself (at least nothing shows up on google, closed source we have no idea about). Is this something people actually need?

/Kristian
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/proj/attachments/20161114/518edd11/attachment.html>


More information about the Proj mailing list