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

Kristian Evers kreve at sdfe.dk
Tue Dec 18 05:10:53 PST 2018


Thanks for the clarification, Even. 

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

I absolutely understand this. Especially while working on a separate branch it would
have been a pain in the ass to try to use the same structure.

> 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++.

Since we require compilation with a C++ compiler now it is too far-fetched an idea
to compile everything as C++. It would be interesting to see if this is possible without
too much extra work.

> 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 guess that modification of proj_create-functions wouldn't take too much work
since most is already done in the C++ parts of the code. We still have to keep
pj_init() and friends alive for a little while longer. Will that pose a problem or
can all the work be delegate to PROJStringParser::createFromPROJString() ?

In case of the technical objects, could that be handled by using the recently
proposed "noop" operation? 

> 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++.

This was my initial probably-easy-to-implement way of combining the two
structs. But if a proper merge of the two can be done fairly simple I think
that is worth considering. It is my belief that having just one form of
"transformation object" makes for a better API. I realize that making that
happen requires significant work. I am willing to help with this to the best of
my abilities. I should also have some time to spare in the beginning of the
new year.

/Kristian

-----Oprindelig meddelelse-----
Fra: Even Rouault <even.rouault at spatialys.com> 
Sendt: 17. december 2018 22:17
Til: proj at lists.osgeo.org
Cc: Kristian Evers <kreve at sdfe.dk>
Emne: Re: [PROJ] What's the difference between PJ and PJ_OBJ?

> 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