[PROJ] What's the difference between PJ and PJ_OBJ?

Even Rouault even.rouault at spatialys.com
Mon Dec 17 13:16:33 PST 2018


> I am slowly working my way through the new additions to the C API and the
> C++ code
> that is backing it and once in a while a question pops up. This
> time regarding the PJ_OBJ struct. Basically I am struggling to understand
> how it differs from the PJ struct? 

PJ is struct PJconsts which is the core C structure for all coordinate 
operations used by the traditional C code

PJ_OBJ is a smallish C++ struct/class that essentially wraps a 
IdentifiedObjectNNPtr C++ object, that is a non-null shared pointer to a 
IdentifiedObject (+ some caching of results of getters)
The IdentifiedObject class is one of the top-most class in the ISO19111 class 
hiearchy from which derived all CRS classes, all CoordinateOperation classes 
and datum-related objects (Ellipsoid, Datum, PrimeMeridian)

> From a user viewpoint that is. I get
> that it is probably simpler to keep the C++ parts separated from the C
> parts as much as possible but is that the only reason why they are two
> different datatypes? 

To be honest, I didn't attempt to reconcile both datatypes, wanting to avoid 
messing too much in the existing code.

Thinking a bit about it, one could consider to move the few members of PJ_OBJ 
into struct PJconsts, but they are C++ objects, so that would mean that struct 
PJconsts would become also a C++ struct, and all C code including it should be 
C++ code. So basically all .c files in PROJ should be renamed to .cpp, hoping 
that they compile fine in C++.

Beyond that, the existing functions that return a PJ* pointer don't 
instanciate a IdentifiedObject, so code in c_api.cpp should be ready to find a 
null object it, whereas currently it is by construction always not-null, and 
act appropriately (mostly error out). But potentially, one could modify 
proj_create(), proj_create_argv() and proj_create_crs_to_crs() to instanciate 
a corresponding C++ object (the one returned by 
PROJStringParser::createFromPROJString() typically)

Conversely, not all PJ_OBJ objects can be converted in a meaningful struct 
PJconsts (for example "technical objects", like datums, ellipsoid, or "exotic" 
CRS like TemporalCRS, ParametricCRS, etc...), so in some cases one would need 
to use some default/dummy content

> I’ve noticed that PJ_CONTEXT has got a pointer to an
> optional C++ struct (projCppContext), 

This is somewhat a hack, but we need to attach the C++ DatabaseContext object 
to the PJ_CONTEXT.

> why was this approach not chosen for
> PJ/PC_CONTEXT?

You meant PJ vs PJ_OBJ I guess.
Indeed, instead of just merging PJ_OBJ into struct PJconsts, one could make 
struct PJconsts have a PJ_OBJ* pointer. That should solve the issue I 
mentionned with existing C code having to be "converted" to C++.

What would remain valid is the non-equality of concepts between PJ and PJ_OBJ.

Even

-- 
Spatialys - Geospatial professional services
http://www.spatialys.com


More information about the PROJ mailing list