namespace mrpt::topography

namespace topography {

// typedefs

typedef mrpt::math::TPoint3D TUTMCoords;
typedef mrpt::math::TPoint3D TGeocentricCoords;

// structs

struct TCoords;
struct TDatum10Params;
struct TDatum1DTransf;
struct TDatum7Params;
struct TDatum7Params_TOPCON;
struct TDatumHelmert2D;
struct TDatumHelmert2D_TOPCON;
struct TDatumHelmert3D;
struct TDatumHelmert3D_TOPCON;
struct TDatumTransfInterpolation;
struct TEllipsoid;
struct TGeodeticCoords;
struct TPathFromRTKInfo;

// global functions

void geodeticToENU_WGS84(const TGeodeticCoords& in_coords, mrpt::math::TPoint3D& out_ENU_point, const TGeodeticCoords& in_coords_origin);

void ENUToGeocentric(
    const mrpt::math::TPoint3D& in_ENU_point,
    const TGeodeticCoords& in_coords_origin,
    TGeocentricCoords& out_coords,
    const TEllipsoid& ellip
    );

void geocentricToENU_WGS84(const mrpt::math::TPoint3D& in_geocentric_point, mrpt::math::TPoint3D& out_ENU_point, const TGeodeticCoords& in_coords_origin);

void geocentricToENU_WGS84(
    const std::vector<mrpt::math::TPoint3D>& in_geocentric_points,
    std::vector<mrpt::math::TPoint3D>& out_ENU_points,
    const TGeodeticCoords& in_coords_origin
    );

void geodeticToGeocentric_WGS84(const TGeodeticCoords& in_coords, mrpt::math::TPoint3D& out_point);
void geodeticToGeocentric(const TGeodeticCoords& in_coords, TGeocentricCoords& out_point, const TEllipsoid& ellip);
void geocentricToGeodetic(const TGeocentricCoords& in_point, TGeodeticCoords& out_coords, const TEllipsoid& ellip = TEllipsoid::Ellipsoid_WGS84());
void transform7params(const mrpt::math::TPoint3D& in_point, const TDatum7Params& in_datum, mrpt::math::TPoint3D& out_point);
void transform7params_TOPCON(const mrpt::math::TPoint3D& in_point, const TDatum7Params_TOPCON& in_datum, mrpt::math::TPoint3D& out_point);
void transform10params(const mrpt::math::TPoint3D& in_point, const TDatum10Params& in_datum, mrpt::math::TPoint3D& out_point);
void transformHelmert2D(const mrpt::math::TPoint2D& p, const TDatumHelmert2D& d, mrpt::math::TPoint2D& o);
void transformHelmert2D_TOPCON(const mrpt::math::TPoint2D& p, const TDatumHelmert2D_TOPCON& d, mrpt::math::TPoint2D& o);
void transformHelmert3D(const mrpt::math::TPoint3D& p, const TDatumHelmert3D& d, mrpt::math::TPoint3D& o);
void transformHelmert3D_TOPCON(const mrpt::math::TPoint3D& p, const TDatumHelmert3D_TOPCON& d, mrpt::math::TPoint3D& o);
void transform1D(const mrpt::math::TPoint3D& p, const TDatum1DTransf& d, mrpt::math::TPoint3D& o);
void transfInterpolation(const mrpt::math::TPoint3D& p, const TDatumTransfInterpolation& d, mrpt::math::TPoint3D& o);

void UTMToGeodetic(
    double X,
    double Y,
    int zone,
    char hem,
    double& out_lon,
    double& out_lat,
    const TEllipsoid& ellip = TEllipsoid::Ellipsoid_WGS84()
    );

void UTMToGeodetic(
    const TUTMCoords& UTMCoords,
    int zone,
    char hem,
    TGeodeticCoords& GeodeticCoords,
    const TEllipsoid& ellip = TEllipsoid::Ellipsoid_WGS84()
    );

void GeodeticToUTM(
    double in_latitude_degrees,
    double in_longitude_degrees,
    double& out_UTM_x,
    double& out_UTM_y,
    int& out_UTM_zone,
    char& out_UTM_latitude_band,
    const TEllipsoid& ellip = TEllipsoid::Ellipsoid_WGS84()
    );

void geodeticToUTM(
    const TGeodeticCoords& GeodeticCoords,
    TUTMCoords& UTMCoords,
    int& UTMZone,
    char& UTMLatitudeBand,
    const TEllipsoid& ellip = TEllipsoid::Ellipsoid_WGS84()
    );

void GeodeticToUTM(
    const TGeodeticCoords& GeodeticCoords,
    TUTMCoords& UTMCoords,
    int& UTMZone,
    char& UTMLatitudeBand,
    const TEllipsoid& ellip = TEllipsoid::Ellipsoid_WGS84()
    );

void ENU_axes_from_WGS84(
    double in_longitude_reference_degrees,
    double in_latitude_reference_degrees,
    double in_height_reference_meters,
    mrpt::math::TPose3D& out_ENU,
    bool only_angles = false
    );

void ENU_axes_from_WGS84(const TGeodeticCoords& in_coords, mrpt::math::TPose3D& out_ENU, bool only_angles = false);

bool operator == (
    const TCoords& a,
    const TCoords& o
    );

bool operator != (
    const TCoords& a,
    const TCoords& o
    );

std::ostream& operator << (
    std::ostream& out,
    const TCoords& o
    );

bool operator == (
    const TGeodeticCoords& a,
    const TGeodeticCoords& o
    );

bool operator != (
    const TGeodeticCoords& a,
    const TGeodeticCoords& o
    );

void path_from_rtk_gps(
    mrpt::poses::CPose3DInterpolator& robot_path,
    const mrpt::obs::CRawlog& rawlog,
    size_t rawlog_first,
    size_t rawlog_last,
    bool isGUI = false,
    bool disableGPSInterp = false,
    int path_smooth_filter_size = 2,
    TPathFromRTKInfo* outInfo = nullptr
    );

void registerAllClasses_mrpt_topography();

} // namespace topography