How to make CoordinateTransformer nullable in PROJ library

37 views Asked by At

I'm using C++ PROJ library to convert points between different coordinate reference systems. I have a simple class that wraps all the PROJ boilerplate and exposes a single method to transform coordinates.

I'm trying to reuse CoordinateTransformer between conversions but I can't figure out a way to store it inside a class instance.

I've tried adding two fields

CoordinateTransformerNNPtr transformerHorizontal;
CoordinateTransformerNNPtr transformerVertical;

and assigning transformers in the constructor on my class (see code below), but it doesn't work presumably because CoordinateTransformerNNPtr is a CoordinateTransformerPtr wrapped into util::nn which doesn't allow having a nullable pointer inside it. The problem is that when instanciating my class I don't have anything to store in these fields, so they have to be nullable.

The error with my current code is Constructor for 'LidarCoordinateDecoder' must explicitly initialize the member 'transformerHorizontal' which does not have a default constructor.

The reason why I'm trying to reuse CoordinateTransformer is to improve performance.

My code:

class LidarCoordinateDecoder {
private:
    CoordinateOperationPtr transformationHorizontal;
    CoordinateOperationPtr transformationVertical;
    PJ_CONTEXT *context;
    CoordinateTransformerNNPtr transformerHorizontal;
    CoordinateTransformerNNPtr transformerVertical;

public:
    LidarCoordinateDecoder(int epsgHorizontal, int epsgVertical) {
        auto dbContext = DatabaseContext::create();
        auto authFactory = AuthorityFactory::create(dbContext, std::string());
        auto authFactoryEPSG = AuthorityFactory::create(dbContext, "EPSG");

        auto sourceHorizontalCRS = authFactoryEPSG->createCoordinateReferenceSystem(std::to_string(epsgHorizontal));
        auto sourceVerticalCRS = authFactoryEPSG->createCoordinateReferenceSystem(std::to_string(epsgVertical));

        auto targetHorizontalCRS = authFactoryEPSG->createCoordinateReferenceSystem("4326");
        auto targetVerticalCRS = authFactoryEPSG->createCoordinateReferenceSystem("5773");

        transformationHorizontal = CoordinateOperationFactory::create()->createOperation(sourceHorizontalCRS, targetHorizontalCRS);
        transformationVertical = CoordinateOperationFactory::create()->createOperation(sourceVerticalCRS, targetVerticalCRS);

        transformerHorizontal = transformationHorizontal->coordinateTransformer(context);
        transformerVertical = transformationVertical->coordinateTransformer(context);

        context = proj_context_create();
    }

    std::tuple<double, double, double> convert(double x, double y, double elevation) {
        PJ_COORD c = {{x, y, 0, 0}};
        c = transformerHorizontal->transform(c);

        double lat = c.v[0];
        double lon = c.v[1];

        c = {{c.v[0], c.v[1], elevation, 0}};
        c = transformerVertical->transform(c);

        return std::make_tuple(lat, lon, c.v[2]);
    }

    ~LidarCoordinateDecoder() = default;
};
0

There are 0 answers