Files
qt6-migration-pipeline/Lts/Common/LtsCoordinate/lts_coordinate.cpp
T

179 lines
3.8 KiB
C++
Executable File

#include "lts_coordinate.h"
#include <QLineF>
namespace LtsCoordTrans
{
static long s_conversion_counter = 0;
std::function<double(double, double, double, bool*)> LtsCoordinate::m_getElevationCB;
void LtsCoordinate::setElevationCallback(const elevationCbFunc &elevationCB)
{
m_getElevationCB = elevationCB;
}
bool LtsCoordinate::hasElevationCallback()
{
return m_getElevationCB != nullptr;
}
double LtsCoordinate::elevationAt(double defaultElevation, bool *bIsCovered) const
{
if (!bIsCovered)
if (!std::isnan(m_elevation))
return m_elevation;
if (m_getElevationCB)
m_elevation = m_getElevationCB(m_geo.lon(), m_geo.lat(), defaultElevation, bIsCovered);
return m_elevation;
}
void LtsCoordinate::setZValueAccordingElevation(double defaultElevation)
{
m_geo.z(elevationAt(defaultElevation));
}
double LtsCoordinate::elevationAt(const LtsCoordinate &coordinate, double defaultElevation, bool *bIsCovered)
{
return coordinate.elevationAt(defaultElevation, bIsCovered);
}
void LtsCoordinate::replaceZValueByElevationIfValue(double zValueToBeReplaced, double defaultElevation)
{
if ((std::isnan(zValueToBeReplaced) && std::isnan(m_geo.z())) ||
qFuzzyCompare(m_geo.z(), zValueToBeReplaced))
setZValueAccordingElevation(defaultElevation);
}
double LtsCoordinate::angleDegreeUtm2D(const LtsCoordinate &coord1, const LtsCoordinate &coord2)
{
const LtsCoordTrans::UtmCoordinate &utm1 = coord1.utmCoordinate();
const LtsCoordTrans::UtmCoordinate &utm2 = coord2.utmCoordinateDiffZone(utm1.zone);
const QPointF& offsetUtm = utm2.toPoint() - utm1.toPoint();
QLineF poly(QPointF(), offsetUtm);
const double angle = poly.angle();
return fmod(angle+90.0, 360);
}
const UtmCoordinate &LtsCoordinate::utmCoordinateInternal(int zone) const
{
if (zone == -1)
{
if (!hasUtm())
convertGeoToUtm();
return m_utm2D;
}
utmCoordinateDiffZone(zone);
return m_utm2D_differentZone;
}
void LtsCoordinate::convertGeoToUtm() const
{
int zone = -1;
if (std::isnan(m_geo.lon()) || std::isnan(m_geo.lat()))
{
fprintf(stderr, "Error while fromGeographic, value is NaN\n");
m_utm2D = LtsCoordTrans::UtmCoordinate();
return;
}
#ifdef LTS_DEBUG
++s_conversion_counter;
#endif
m_utm2D = LtsCoordTrans::UtmCoordinate::fromGeographic(m_geo.lon(), m_geo.lat(), zone);
Q_ASSERT_X(m_utm2D.zone > 0, "LtsCoordinate", "zone has to be set");
}
QString LtsCoordinate::mgrs(int prec, bool withSpaces) const
{
utmCoordinateInternal();
QString tmp = m_utm2D.mgrs(prec, withSpaces);
return tmp;
}
QString LtsCoordinate::mgrsWithZ(int prec, bool withSpaces) const
{
double ele = elevationAt();
QString tmp = mgrs(prec, withSpaces) + QStringLiteral(" z=") + QString::number(ele, 'f', 2);
return tmp;
}
QString LtsCoordinate::toString(bool fullAndExpensive) const
{
if (fullAndExpensive)
{
utmCoordinateInternal();
elevationAt();
}
std::ostringstream stream;
stream << "LtsCoordinate(m_geo=" << m_geo
<< ", m_utm2D.x " << m_utm2D.x << ", m_utm2D.y " << m_utm2D.y << ", m_utm2D.zone " << m_utm2D.zone;
if (!qFuzzyIsNull(m_utm2D.x) || !qFuzzyIsNull(m_utm2D.y))
stream << ", m_utm2D.mgrs '" << m_utm2D.mgrs().toUtf8().constData() << "'";
stream << ", elevation " << std::fixed << std::setprecision(3) << m_elevation
<< ")";
return QString::fromStdString(stream.str());
}
void LtsCoordinate::resetConversionCounter()
{
s_conversion_counter = 0;
}
long LtsCoordinate::getConversionCounter()
{
return s_conversion_counter;
}
std::ostream &operator<<(std::ostream &stream, const LtsCoordinate &value)
{
stream << value.toString().toStdString();
return stream;
}
}