OSGeo / PROJ

PROJ - Cartographic Projections and Coordinate Transformations Library
https://proj.org
Other
1.74k stars 785 forks source link

Examples for the C++ API #3593

Closed vmartinlac closed 1 year ago

vmartinlac commented 1 year ago

Hello,

I would like to use the C++ API instead of the C api but the entry cost is high : there are no examples for using the C++ API and the documentation is sparse.

Best regards,

Victor

dbs4261 commented 1 year ago

Same Ive spent 3 days figuring out parsing and the need for dynamic casts everywhere. And now Im stuck on how to actually apply the transformation to some data.

mitjap commented 1 year ago

And now Im stuck on how to actually apply the transformation to some data.

Here it is. https://github.com/OSGeo/PROJ/blame/9.2/include/proj/coordinateoperation.hpp#L150

// virtual void transform(...) = 0;  TODO

Joking aside, we've also been figuring out what is with C++ and lack of all examples. Is this API actually ready to use in production or is still a beta for the last 5 years? As fas as I can tell C++ lacks THE MOST IMPORTANT part of this library, to actually do any transformation. There is a work around to parse operation to WKT and parse it using C api, and use that for transformation. I'm afraid this lead to loss of information as proj_trans can not do improved selection of alternative operations based on the coord location.

Is the C++ API considered mature at this point? I'd love to hear from someone who has experience with it.

rouault commented 1 year ago

@mitjap Indeed the coordinate transformation part is not implemented currently in the C++ API. The reason is that other C/C++ popular open source projects that leverage PROJ (GDAL, GRASS GIS, QGIS, PostGIS, etc.) only use the C API, because that's the one that has always been available and C API tend to be more stable than C++ one (at least from an ABI perspective), although PROJ C++ API has been fairly stable since 6.0. So indeed currently you need to use the combo proj_create() / proj_trans(). Using WKT should be very faithful of CRS created through the C++ API. If you don't want to rely on automatic operation selection by proj_trans(), you can get precise control of the operation to use by using the proj_create_operations() + proj_list_get_count() + proj_list_get() API.

Adding support in the C++ class for the transform() method should be doable for a motivated contributor. It would probably involve exporting the operation as a PROJ pipeline and instanciate it a PJ* object with proj_create() with that pipeline string.

mitjap commented 1 year ago

@rouault Thank you for explaining the state of C++ API. Maybe something similar can be added to C++ documentation as a note?

TheDoubleB commented 1 year ago

On that note, there already is a function that creates a PJ * from a BaseObjectNNPtr (whichever derivative it might be): static PJ *pj_obj_create(PJ_CONTEXT *ctx, const BaseObjectNNPtr &objIn). Unfortunately, it is marked static within PROJ/src/iso19111/c_api.cpp file, which makes it impossible to reach even with extern declaration in your own project.

My question is whether this function or a function with same functionality could be exposed to the outside to bridge the shortcomings of C++ API and to avoid the rather convoluted steps: IWKTExportable::exportToWKT() -> proj_create_from_wkt() -> proj_trans() ?

mitjap commented 1 year ago

Thank you @rouault. This will be very helpful.