mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-23 13:55:36 +08:00
refactor: clang format line length
This commit is contained in:
@@ -19,15 +19,15 @@ SWIFT_DEFINE_VALUEOBJECT_MIXINS(swift::misc::geo, CCoordinateGeodetic)
|
||||
|
||||
namespace swift::misc::geo
|
||||
{
|
||||
ICoordinateGeodetic::~ICoordinateGeodetic()
|
||||
{}
|
||||
ICoordinateGeodetic::~ICoordinateGeodetic() {}
|
||||
|
||||
QString CCoordinateGeodetic::convertToQString(bool i18n) const
|
||||
{
|
||||
return ICoordinateGeodetic::convertToQString(i18n);
|
||||
}
|
||||
|
||||
CCoordinateGeodetic CCoordinateGeodetic::fromWgs84(const QString &latitudeWgs84, const QString &longitudeWgs84, const CAltitude &geodeticHeight)
|
||||
CCoordinateGeodetic CCoordinateGeodetic::fromWgs84(const QString &latitudeWgs84, const QString &longitudeWgs84,
|
||||
const CAltitude &geodeticHeight)
|
||||
{
|
||||
const CLatitude lat = CLatitude::fromWgs84(latitudeWgs84);
|
||||
const CLongitude lon = CLongitude::fromWgs84(longitudeWgs84);
|
||||
@@ -48,15 +48,20 @@ namespace swift::misc::geo
|
||||
|
||||
const QVector3D v1 = coordinate1.normalVector();
|
||||
const QVector3D v2 = coordinate2.normalVector();
|
||||
Q_ASSERT_X(std::isfinite(v1.x()) && std::isfinite(v1.y()) && std::isfinite(v1.z()), Q_FUNC_INFO, "Distance calculation: v1 non-finite argument");
|
||||
Q_ASSERT_X(std::isfinite(v2.x()) && std::isfinite(v2.y()) && std::isfinite(v2.z()), Q_FUNC_INFO, "Distance calculation: v2 non-finite argument");
|
||||
Q_ASSERT_X(std::isfinite(v1.x()) && std::isfinite(v1.y()) && std::isfinite(v1.z()), Q_FUNC_INFO,
|
||||
"Distance calculation: v1 non-finite argument");
|
||||
Q_ASSERT_X(std::isfinite(v2.x()) && std::isfinite(v2.y()) && std::isfinite(v2.z()), Q_FUNC_INFO,
|
||||
"Distance calculation: v2 non-finite argument");
|
||||
|
||||
const float d = earthRadiusMeters * std::atan2(QVector3D::crossProduct(v1, v2).length(), QVector3D::dotProduct(v1, v2));
|
||||
const float d =
|
||||
earthRadiusMeters * std::atan2(QVector3D::crossProduct(v1, v2).length(), QVector3D::dotProduct(v1, v2));
|
||||
|
||||
SWIFT_VERIFY_X(!std::isnan(d), Q_FUNC_INFO, "Distance calculation: NaN in result");
|
||||
if (std::isnan(d))
|
||||
{
|
||||
CLogMessage().debug(u"Distance calculation: NaN in result (given arguments %1 %2 %3; %4 %5 %6)") << static_cast<double>(v1.x()) << static_cast<double>(v1.y()) << static_cast<double>(v1.z()) << static_cast<double>(v2.x()) << static_cast<double>(v2.y()) << static_cast<double>(v2.z());
|
||||
CLogMessage().debug(u"Distance calculation: NaN in result (given arguments %1 %2 %3; %4 %5 %6)")
|
||||
<< static_cast<double>(v1.x()) << static_cast<double>(v1.y()) << static_cast<double>(v1.z())
|
||||
<< static_cast<double>(v2.x()) << static_cast<double>(v2.y()) << static_cast<double>(v2.z());
|
||||
return CLength::null();
|
||||
}
|
||||
return { static_cast<double>(d), CLengthUnit::m() };
|
||||
@@ -65,7 +70,8 @@ namespace swift::misc::geo
|
||||
CAngle calculateBearing(const ICoordinateGeodetic &coordinate1, const ICoordinateGeodetic &coordinate2)
|
||||
{
|
||||
if (coordinate1.isNull() || coordinate2.isNull()) { return CAngle::null(); }
|
||||
// if (coordinate1.equalNormalVectorDouble(coordinate2)) { return CAngle(0, CAngleUnit::defaultUnit()); } // null or 0?
|
||||
// if (coordinate1.equalNormalVectorDouble(coordinate2)) { return CAngle(0, CAngleUnit::defaultUnit()); } //
|
||||
// null or 0?
|
||||
static const QVector3D northPole { 0, 0, 1 };
|
||||
const QVector3D c1 = QVector3D::crossProduct(coordinate1.normalVector(), coordinate2.normalVector());
|
||||
const QVector3D c2 = QVector3D::crossProduct(coordinate1.normalVector(), northPole);
|
||||
@@ -81,7 +87,8 @@ namespace swift::misc::geo
|
||||
return static_cast<double>(coordinate1.normalVector().distanceToPoint(coordinate2.normalVector()));
|
||||
}
|
||||
|
||||
double calculateEuclideanDistanceSquared(const ICoordinateGeodetic &coordinate1, const ICoordinateGeodetic &coordinate2)
|
||||
double calculateEuclideanDistanceSquared(const ICoordinateGeodetic &coordinate1,
|
||||
const ICoordinateGeodetic &coordinate2)
|
||||
{
|
||||
return static_cast<double>((coordinate1.normalVector() - coordinate2.normalVector()).lengthSquared());
|
||||
}
|
||||
@@ -150,19 +157,25 @@ namespace swift::misc::geo
|
||||
return QVariant::fromValue(m);
|
||||
}
|
||||
|
||||
int ICoordinateGeodetic::comparePropertyByIndex(CPropertyIndexRef index, const ICoordinateGeodetic &compareValue) const
|
||||
int ICoordinateGeodetic::comparePropertyByIndex(CPropertyIndexRef index,
|
||||
const ICoordinateGeodetic &compareValue) const
|
||||
{
|
||||
if (!index.isMyself())
|
||||
{
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexLatitude: return this->latitude().comparePropertyByIndex(index.copyFrontRemoved(), compareValue.latitude());
|
||||
case IndexLongitude: return this->longitude().comparePropertyByIndex(index.copyFrontRemoved(), compareValue.longitude());
|
||||
case IndexLatitude:
|
||||
return this->latitude().comparePropertyByIndex(index.copyFrontRemoved(), compareValue.latitude());
|
||||
case IndexLongitude:
|
||||
return this->longitude().comparePropertyByIndex(index.copyFrontRemoved(), compareValue.longitude());
|
||||
case IndexLatitudeAsString: return this->latitudeAsString().compare(compareValue.latitudeAsString());
|
||||
case IndexLongitudeAsString: return this->longitudeAsString().compare(compareValue.longitudeAsString());
|
||||
case IndexGeodeticHeight: return this->geodeticHeight().comparePropertyByIndex(index.copyFrontRemoved(), compareValue.geodeticHeight());
|
||||
case IndexGeodeticHeightAsString: return this->geodeticHeightAsString().compare(compareValue.geodeticHeightAsString());
|
||||
case IndexGeodeticHeight:
|
||||
return this->geodeticHeight().comparePropertyByIndex(index.copyFrontRemoved(),
|
||||
compareValue.geodeticHeight());
|
||||
case IndexGeodeticHeightAsString:
|
||||
return this->geodeticHeightAsString().compare(compareValue.geodeticHeightAsString());
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -176,7 +189,12 @@ namespace swift::misc::geo
|
||||
{
|
||||
const CLatitude lat = this->latitude();
|
||||
const CLongitude lng = this->longitude();
|
||||
return QStringLiteral("Geodetic: {%1/%2, %3/%4, %5}").arg(lat.valueRoundedWithUnit(CAngleUnit::deg(), 6, i18n), lat.valueRoundedWithUnit(CAngleUnit::rad(), 6, i18n), lng.valueRoundedWithUnit(CAngleUnit::deg(), 6, i18n), lng.valueRoundedWithUnit(CAngleUnit::rad(), 6, i18n), this->geodeticHeight().valueRoundedWithUnit(CLengthUnit::ft(), 2, i18n));
|
||||
return QStringLiteral("Geodetic: {%1/%2, %3/%4, %5}")
|
||||
.arg(lat.valueRoundedWithUnit(CAngleUnit::deg(), 6, i18n),
|
||||
lat.valueRoundedWithUnit(CAngleUnit::rad(), 6, i18n),
|
||||
lng.valueRoundedWithUnit(CAngleUnit::deg(), 6, i18n),
|
||||
lng.valueRoundedWithUnit(CAngleUnit::rad(), 6, i18n),
|
||||
this->geodeticHeight().valueRoundedWithUnit(CLengthUnit::ft(), 2, i18n));
|
||||
}
|
||||
|
||||
bool ICoordinateGeodetic::isNaNVector() const
|
||||
@@ -213,8 +231,7 @@ namespace swift::misc::geo
|
||||
bool ICoordinateGeodetic::isValidVector(const std::array<double, 3> &v)
|
||||
{
|
||||
constexpr double l = 1.00001; // because of interpolation
|
||||
return v[0] <= l && v[1] <= l && v[2] <= l &&
|
||||
v[0] >= -l && v[1] >= -l && v[2] >= -l;
|
||||
return v[0] <= l && v[1] <= l && v[2] <= l && v[0] >= -l && v[1] >= -l && v[2] >= -l;
|
||||
}
|
||||
|
||||
int CCoordinateGeodetic::clampVector()
|
||||
@@ -258,9 +275,8 @@ namespace swift::misc::geo
|
||||
QVariant CCoordinateGeodetic::propertyByIndex(swift::misc::CPropertyIndexRef index) const
|
||||
{
|
||||
if (index.isMyself()) { return QVariant::fromValue(*this); }
|
||||
return (ICoordinateGeodetic::canHandleIndex(index)) ?
|
||||
ICoordinateGeodetic::propertyByIndex(index) :
|
||||
CValueObject::propertyByIndex(index);
|
||||
return (ICoordinateGeodetic::canHandleIndex(index)) ? ICoordinateGeodetic::propertyByIndex(index) :
|
||||
CValueObject::propertyByIndex(index);
|
||||
}
|
||||
|
||||
void CCoordinateGeodetic::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
|
||||
@@ -284,7 +300,8 @@ namespace swift::misc::geo
|
||||
}
|
||||
}
|
||||
|
||||
int CCoordinateGeodetic::comparePropertyByIndex(CPropertyIndexRef index, const CCoordinateGeodetic &compareValue) const
|
||||
int CCoordinateGeodetic::comparePropertyByIndex(CPropertyIndexRef index,
|
||||
const CCoordinateGeodetic &compareValue) const
|
||||
{
|
||||
return ICoordinateGeodetic::canHandleIndex(index) ?
|
||||
ICoordinateGeodetic::comparePropertyByIndex(index, compareValue) :
|
||||
@@ -296,22 +313,30 @@ namespace swift::misc::geo
|
||||
this->setNormalVector(normalVector);
|
||||
}
|
||||
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(const CLatitude &latitude, const CLongitude &longitude) : CCoordinateGeodetic(latitude, longitude, CAltitude::null())
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(const CLatitude &latitude, const CLongitude &longitude)
|
||||
: CCoordinateGeodetic(latitude, longitude, CAltitude::null())
|
||||
{
|
||||
// void
|
||||
}
|
||||
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(const CLatitude &latitude, const CLongitude &longitude, const CAltitude &geodeticHeight) : m_x(latitude.cos() * longitude.cos()),
|
||||
m_y(latitude.cos() * longitude.sin()),
|
||||
m_z(latitude.sin()),
|
||||
m_geodeticHeight(geodeticHeight)
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(const CLatitude &latitude, const CLongitude &longitude,
|
||||
const CAltitude &geodeticHeight)
|
||||
: m_x(latitude.cos() * longitude.cos()), m_y(latitude.cos() * longitude.sin()), m_z(latitude.sin()),
|
||||
m_geodeticHeight(geodeticHeight)
|
||||
{}
|
||||
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(double latitudeDegrees, double longitudeDegrees) : CCoordinateGeodetic({ latitudeDegrees, CAngleUnit::deg() }, { longitudeDegrees, CAngleUnit::deg() }, { 0, nullptr }) {}
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(double latitudeDegrees, double longitudeDegrees)
|
||||
: CCoordinateGeodetic({ latitudeDegrees, CAngleUnit::deg() }, { longitudeDegrees, CAngleUnit::deg() },
|
||||
{ 0, nullptr })
|
||||
{}
|
||||
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(double latitudeDegrees, double longitudeDegrees, double heightFeet) : CCoordinateGeodetic({ latitudeDegrees, CAngleUnit::deg() }, { longitudeDegrees, CAngleUnit::deg() }, { heightFeet, CLengthUnit::ft() }) {}
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(double latitudeDegrees, double longitudeDegrees, double heightFeet)
|
||||
: CCoordinateGeodetic({ latitudeDegrees, CAngleUnit::deg() }, { longitudeDegrees, CAngleUnit::deg() },
|
||||
{ heightFeet, CLengthUnit::ft() })
|
||||
{}
|
||||
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(const ICoordinateGeodetic &coordinate) : m_geodeticHeight(coordinate.geodeticHeight())
|
||||
CCoordinateGeodetic::CCoordinateGeodetic(const ICoordinateGeodetic &coordinate)
|
||||
: m_geodeticHeight(coordinate.geodeticHeight())
|
||||
{
|
||||
this->setNormalVector(coordinate.normalVectorDouble());
|
||||
}
|
||||
@@ -319,7 +344,10 @@ namespace swift::misc::geo
|
||||
CCoordinateGeodetic CCoordinateGeodetic::calculatePosition(const CLength &distance, const CAngle &relBearing) const
|
||||
{
|
||||
if (this->isNull()) { return CCoordinateGeodetic::null(); }
|
||||
if (distance.isNull() || distance.isNegativeWithEpsilonConsidered() || relBearing.isNull()) { return CCoordinateGeodetic::null(); }
|
||||
if (distance.isNull() || distance.isNegativeWithEpsilonConsidered() || relBearing.isNull())
|
||||
{
|
||||
return CCoordinateGeodetic::null();
|
||||
}
|
||||
if (distance.isZeroEpsilonConsidered()) { return *this; }
|
||||
|
||||
// http://www.movable-type.co.uk/scripts/latlong.html#destPoint
|
||||
@@ -331,7 +359,8 @@ namespace swift::misc::geo
|
||||
const double bearingRad = relBearing.value(CAngleUnit::rad());
|
||||
const double distRatio = distance.value(CLengthUnit::m()) / earthRadiusMeters;
|
||||
|
||||
const double newLatRad = asin(sin(startLatRad) * cos(distRatio) + cos(startLatRad) * sin(distRatio) * cos(bearingRad));
|
||||
const double newLatRad =
|
||||
asin(sin(startLatRad) * cos(distRatio) + cos(startLatRad) * sin(distRatio) * cos(bearingRad));
|
||||
double newLngRad = 0;
|
||||
|
||||
constexpr double epsilon = 1E-06;
|
||||
@@ -340,7 +369,8 @@ namespace swift::misc::geo
|
||||
else
|
||||
{
|
||||
// λ1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(φ1), Math.cos(d/R)-Math.sin(φ1)*Math.sin(φ2));
|
||||
newLngRad = startLngRad + atan2(sin(bearingRad) * sin(distRatio) * cos(startLatRad), cos(distRatio) - sin(startLatRad) * sin(newLatRad));
|
||||
newLngRad = startLngRad + atan2(sin(bearingRad) * sin(distRatio) * cos(startLatRad),
|
||||
cos(distRatio) - sin(startLatRad) * sin(newLatRad));
|
||||
newLngRad = fmod(newLngRad + 3 * M_PI, 2 * M_PI) - M_PI; // normalize +-180deg
|
||||
}
|
||||
|
||||
@@ -364,27 +394,14 @@ namespace swift::misc::geo
|
||||
|
||||
QVector3D CCoordinateGeodetic::normalVector() const
|
||||
{
|
||||
return {
|
||||
static_cast<float>(m_x),
|
||||
static_cast<float>(m_y),
|
||||
static_cast<float>(m_z)
|
||||
};
|
||||
return { static_cast<float>(m_x), static_cast<float>(m_y), static_cast<float>(m_z) };
|
||||
}
|
||||
|
||||
std::array<double, 3> CCoordinateGeodetic::normalVectorDouble() const
|
||||
{
|
||||
return { { m_x, m_y, m_z } };
|
||||
}
|
||||
std::array<double, 3> CCoordinateGeodetic::normalVectorDouble() const { return { { m_x, m_y, m_z } }; }
|
||||
|
||||
void CCoordinateGeodetic::setLatitude(const CLatitude &latitude)
|
||||
{
|
||||
this->setLatLong(latitude, this->longitude());
|
||||
}
|
||||
void CCoordinateGeodetic::setLatitude(const CLatitude &latitude) { this->setLatLong(latitude, this->longitude()); }
|
||||
|
||||
void CCoordinateGeodetic::setLatitudeFromWgs84(const QString &wgs)
|
||||
{
|
||||
this->setLatitude(CLatitude::fromWgs84(wgs));
|
||||
}
|
||||
void CCoordinateGeodetic::setLatitudeFromWgs84(const QString &wgs) { this->setLatitude(CLatitude::fromWgs84(wgs)); }
|
||||
|
||||
void CCoordinateGeodetic::setLongitude(const CLongitude &longitude)
|
||||
{
|
||||
@@ -409,10 +426,7 @@ namespace swift::misc::geo
|
||||
this->setLongitudeFromWgs84(longitude);
|
||||
}
|
||||
|
||||
void CCoordinateGeodetic::setGeodeticHeightToNull()
|
||||
{
|
||||
this->setGeodeticHeight(CAltitude::null());
|
||||
}
|
||||
void CCoordinateGeodetic::setGeodeticHeightToNull() { this->setGeodeticHeight(CAltitude::null()); }
|
||||
|
||||
void CCoordinateGeodetic::setNormalVector(const std::array<double, 3> &normalVector)
|
||||
{
|
||||
@@ -434,7 +448,8 @@ namespace swift::misc::geo
|
||||
return m_relativeDistance;
|
||||
}
|
||||
|
||||
CLength ICoordinateWithRelativePosition::calculcateAndUpdateRelativeDistanceAndBearing(const ICoordinateGeodetic &position)
|
||||
CLength
|
||||
ICoordinateWithRelativePosition::calculcateAndUpdateRelativeDistanceAndBearing(const ICoordinateGeodetic &position)
|
||||
{
|
||||
m_relativeDistance = geo::calculateGreatCircleDistance(*this, position);
|
||||
m_relativeBearing = geo::calculateBearing(*this, position);
|
||||
@@ -477,16 +492,25 @@ namespace swift::misc::geo
|
||||
}
|
||||
}
|
||||
|
||||
int ICoordinateWithRelativePosition::comparePropertyByIndex(CPropertyIndexRef index, const ICoordinateWithRelativePosition &compareValue) const
|
||||
int
|
||||
ICoordinateWithRelativePosition::comparePropertyByIndex(CPropertyIndexRef index,
|
||||
const ICoordinateWithRelativePosition &compareValue) const
|
||||
{
|
||||
if (ICoordinateGeodetic::canHandleIndex(index)) { return ICoordinateGeodetic::comparePropertyByIndex(index, compareValue); }
|
||||
if (ICoordinateGeodetic::canHandleIndex(index))
|
||||
{
|
||||
return ICoordinateGeodetic::comparePropertyByIndex(index, compareValue);
|
||||
}
|
||||
if (!index.isMyself())
|
||||
{
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexRelativeBearing: return m_relativeBearing.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getRelativeBearing());
|
||||
case IndexRelativeDistance: return m_relativeDistance.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getRelativeDistance());
|
||||
case IndexRelativeBearing:
|
||||
return m_relativeBearing.comparePropertyByIndex(index.copyFrontRemoved(),
|
||||
compareValue.getRelativeBearing());
|
||||
case IndexRelativeDistance:
|
||||
return m_relativeDistance.comparePropertyByIndex(index.copyFrontRemoved(),
|
||||
compareValue.getRelativeDistance());
|
||||
default:
|
||||
const QString m = QString("no property, index ").append(index.toQString());
|
||||
Q_ASSERT_X(false, Q_FUNC_INFO, m.toLocal8Bit().constData());
|
||||
@@ -499,13 +523,11 @@ namespace swift::misc::geo
|
||||
|
||||
QString ICoordinateWithRelativePosition::convertToQString(bool i18n) const
|
||||
{
|
||||
return m_relativeBearing.toQString(i18n) % u' ' %
|
||||
m_relativeDistance.toQString(i18n) % u' ' %
|
||||
return m_relativeBearing.toQString(i18n) % u' ' % m_relativeDistance.toQString(i18n) % u' ' %
|
||||
ICoordinateGeodetic::convertToQString(i18n);
|
||||
}
|
||||
|
||||
ICoordinateWithRelativePosition::ICoordinateWithRelativePosition()
|
||||
{}
|
||||
ICoordinateWithRelativePosition::ICoordinateWithRelativePosition() {}
|
||||
|
||||
bool ICoordinateWithRelativePosition::canHandleIndex(CPropertyIndexRef index)
|
||||
{
|
||||
|
||||
@@ -110,14 +110,16 @@ namespace swift::misc
|
||||
bool hasMSLGeodeticHeight() const { return this->geodeticHeight().hasMeanSeaLevelValue(); }
|
||||
|
||||
//! Is null, means vector x, y, z == 0
|
||||
//! \remark this is a default implementation, concrete implementations of ICoordinateGeodetic might override it
|
||||
//! \remark this is a default implementation, concrete implementations of ICoordinateGeodetic might override
|
||||
//! it
|
||||
virtual bool isNull() const { return this->normalVector().isNull(); }
|
||||
|
||||
//! Great circle distance
|
||||
physical_quantities::CLength calculateGreatCircleDistance(const ICoordinateGeodetic &otherCoordinate) const;
|
||||
|
||||
//! Object within range?
|
||||
bool isWithinRange(const ICoordinateGeodetic &otherCoordinate, const physical_quantities::CLength &range) const;
|
||||
bool isWithinRange(const ICoordinateGeodetic &otherCoordinate,
|
||||
const physical_quantities::CLength &range) const;
|
||||
|
||||
//! Initial bearing
|
||||
physical_quantities::CAngle calculateBearing(const ICoordinateGeodetic &otherCoordinate) const;
|
||||
@@ -147,18 +149,23 @@ namespace swift::misc
|
||||
};
|
||||
|
||||
//! Great circle distance between points
|
||||
SWIFT_MISC_EXPORT physical_quantities::CLength calculateGreatCircleDistance(const ICoordinateGeodetic &coordinate1, const ICoordinateGeodetic &coordinate2);
|
||||
SWIFT_MISC_EXPORT physical_quantities::CLength
|
||||
calculateGreatCircleDistance(const ICoordinateGeodetic &coordinate1, const ICoordinateGeodetic &coordinate2);
|
||||
|
||||
//! Initial bearing
|
||||
SWIFT_MISC_EXPORT physical_quantities::CAngle calculateBearing(const ICoordinateGeodetic &coordinate1, const ICoordinateGeodetic &coordinate2);
|
||||
SWIFT_MISC_EXPORT physical_quantities::CAngle calculateBearing(const ICoordinateGeodetic &coordinate1,
|
||||
const ICoordinateGeodetic &coordinate2);
|
||||
|
||||
//! Euclidean distance between normal vectors
|
||||
SWIFT_MISC_EXPORT double calculateEuclideanDistance(const ICoordinateGeodetic &coordinate1, const ICoordinateGeodetic &coordinate2);
|
||||
SWIFT_MISC_EXPORT double calculateEuclideanDistance(const ICoordinateGeodetic &coordinate1,
|
||||
const ICoordinateGeodetic &coordinate2);
|
||||
|
||||
//! Euclidean distance squared between normal vectors, use for more efficient sorting by distance
|
||||
SWIFT_MISC_EXPORT double calculateEuclideanDistanceSquared(const ICoordinateGeodetic &coordinate1, const ICoordinateGeodetic &coordinate2);
|
||||
SWIFT_MISC_EXPORT double calculateEuclideanDistanceSquared(const ICoordinateGeodetic &coordinate1,
|
||||
const ICoordinateGeodetic &coordinate2);
|
||||
|
||||
//! Interface (actually more an abstract class) of coordinates and relative position to something (normally own aircraft)
|
||||
//! Interface (actually more an abstract class) of coordinates and relative position to something (normally own
|
||||
//! aircraft)
|
||||
class SWIFT_MISC_EXPORT ICoordinateWithRelativePosition : public ICoordinateGeodetic
|
||||
{
|
||||
public:
|
||||
@@ -191,7 +198,8 @@ namespace swift::misc
|
||||
physical_quantities::CLength calculcateAndUpdateRelativeDistance(const geo::ICoordinateGeodetic &position);
|
||||
|
||||
//! Calculcate distance and bearing to plane, set it, and return distance
|
||||
physical_quantities::CLength calculcateAndUpdateRelativeDistanceAndBearing(const geo::ICoordinateGeodetic &position);
|
||||
physical_quantities::CLength
|
||||
calculcateAndUpdateRelativeDistanceAndBearing(const geo::ICoordinateGeodetic &position);
|
||||
|
||||
//! \copydoc mixin::Index::propertyByIndex
|
||||
QVariant propertyByIndex(CPropertyIndexRef index) const;
|
||||
@@ -200,7 +208,8 @@ namespace swift::misc
|
||||
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant);
|
||||
|
||||
//! \copydoc mixin::Index::comparePropertyByIndex
|
||||
int comparePropertyByIndex(CPropertyIndexRef index, const ICoordinateWithRelativePosition &compareValue) const;
|
||||
int comparePropertyByIndex(CPropertyIndexRef index,
|
||||
const ICoordinateWithRelativePosition &compareValue) const;
|
||||
|
||||
//! \copydoc mixin::String::toQString
|
||||
QString convertToQString(bool i18n = false) const;
|
||||
@@ -217,14 +226,19 @@ namespace swift::misc
|
||||
};
|
||||
|
||||
//! Geodetic coordinate
|
||||
class SWIFT_MISC_EXPORT CCoordinateGeodetic : public CValueObject<CCoordinateGeodetic>, public ICoordinateGeodetic
|
||||
class SWIFT_MISC_EXPORT CCoordinateGeodetic :
|
||||
public CValueObject<CCoordinateGeodetic>,
|
||||
public ICoordinateGeodetic
|
||||
{
|
||||
public:
|
||||
//! Default constructor (null coordinate)
|
||||
CCoordinateGeodetic() {}
|
||||
|
||||
//! Constructor by normal vector
|
||||
CCoordinateGeodetic(const QVector3D &normal) : m_x(static_cast<double>(normal.x())), m_y(static_cast<double>(normal.y())), m_z(static_cast<double>(normal.z())) {}
|
||||
CCoordinateGeodetic(const QVector3D &normal)
|
||||
: m_x(static_cast<double>(normal.x())), m_y(static_cast<double>(normal.y())),
|
||||
m_z(static_cast<double>(normal.z()))
|
||||
{}
|
||||
|
||||
//! Constructor by normal vector
|
||||
CCoordinateGeodetic(const std::array<double, 3> &normalVector);
|
||||
@@ -233,7 +247,8 @@ namespace swift::misc
|
||||
CCoordinateGeodetic(const CLatitude &latitude, const CLongitude &longitude);
|
||||
|
||||
//! Constructor by latitude/longitude/height (or altitude)
|
||||
CCoordinateGeodetic(const CLatitude &latitude, const CLongitude &longitude, const aviation::CAltitude &geodeticHeight);
|
||||
CCoordinateGeodetic(const CLatitude &latitude, const CLongitude &longitude,
|
||||
const aviation::CAltitude &geodeticHeight);
|
||||
|
||||
//! Constructor by double values, but no geodetic height
|
||||
CCoordinateGeodetic(double latitudeDegrees, double longitudeDegrees);
|
||||
@@ -245,7 +260,8 @@ namespace swift::misc
|
||||
CCoordinateGeodetic(const ICoordinateGeodetic &coordinate);
|
||||
|
||||
//! Calculate a position in distance/bearing
|
||||
CCoordinateGeodetic calculatePosition(const physical_quantities::CLength &distance, const physical_quantities::CAngle &relBearing) const;
|
||||
CCoordinateGeodetic calculatePosition(const physical_quantities::CLength &distance,
|
||||
const physical_quantities::CAngle &relBearing) const;
|
||||
|
||||
//! \copydoc ICoordinateGeodetic::latitude
|
||||
virtual CLatitude latitude() const override;
|
||||
@@ -331,11 +347,13 @@ namespace swift::misc
|
||||
virtual bool isNull() const override
|
||||
{
|
||||
if (m_geodeticHeight.isNull()) { return true; }
|
||||
return math::CMathUtils::epsilonZeroLimits(m_x) && math::CMathUtils::epsilonZeroLimits(m_y) && math::CMathUtils::epsilonZeroLimits(m_z);
|
||||
return math::CMathUtils::epsilonZeroLimits(m_x) && math::CMathUtils::epsilonZeroLimits(m_y) &&
|
||||
math::CMathUtils::epsilonZeroLimits(m_z);
|
||||
}
|
||||
|
||||
//! Coordinate by WGS84 position data
|
||||
static CCoordinateGeodetic fromWgs84(const QString &latitudeWgs84, const QString &longitudeWgs84, const aviation::CAltitude &geodeticHeight = {});
|
||||
static CCoordinateGeodetic fromWgs84(const QString &latitudeWgs84, const QString &longitudeWgs84,
|
||||
const aviation::CAltitude &geodeticHeight = {});
|
||||
|
||||
//! null coordinate
|
||||
static const CCoordinateGeodetic &null();
|
||||
|
||||
@@ -12,18 +12,22 @@ SWIFT_DEFINE_SEQUENCE_MIXINS(swift::misc::geo, CCoordinateGeodetic, CCoordinateG
|
||||
|
||||
namespace swift::misc::geo
|
||||
{
|
||||
CCoordinateGeodeticList::CCoordinateGeodeticList()
|
||||
CCoordinateGeodeticList::CCoordinateGeodeticList() {}
|
||||
|
||||
CCoordinateGeodeticList::CCoordinateGeodeticList(const CSequence<CCoordinateGeodetic> &other)
|
||||
: CSequence<CCoordinateGeodetic>(other)
|
||||
{}
|
||||
|
||||
CCoordinateGeodeticList::CCoordinateGeodeticList(const CSequence<CCoordinateGeodetic> &other) : CSequence<CCoordinateGeodetic>(other)
|
||||
{}
|
||||
|
||||
CElevationPlane CCoordinateGeodeticList::averageGeodeticHeight(const CCoordinateGeodetic &reference, const CLength &range, const CLength &maxDeviation, int minValues, int sufficentValues) const
|
||||
CElevationPlane CCoordinateGeodeticList::averageGeodeticHeight(const CCoordinateGeodetic &reference,
|
||||
const CLength &range, const CLength &maxDeviation,
|
||||
int minValues, int sufficentValues) const
|
||||
{
|
||||
if (this->size() < minValues) { return CElevationPlane::null(); } // no chance to succeed
|
||||
|
||||
QList<double> valuesInFt;
|
||||
const CCoordinateGeodeticList sorted = this->findWithGeodeticMSLHeight().findWithinRange(reference, range).sortedByEuclideanDistanceSquared(reference);
|
||||
const CCoordinateGeodeticList sorted = this->findWithGeodeticMSLHeight()
|
||||
.findWithinRange(reference, range)
|
||||
.sortedByEuclideanDistanceSquared(reference);
|
||||
if (sorted.size() < minValues) { return CElevationPlane::null(); }
|
||||
|
||||
// we know all values have MSL and are within range
|
||||
|
||||
@@ -40,7 +40,11 @@ namespace swift::misc::geo
|
||||
CCoordinateGeodeticList(const CSequence<CCoordinateGeodetic> &other);
|
||||
|
||||
//! Average height within range and having an height
|
||||
CElevationPlane averageGeodeticHeight(const CCoordinateGeodetic &reference, const physical_quantities::CLength &range, const physical_quantities::CLength &maxDeviation = physical_quantities::CLength(1.0, physical_quantities::CLengthUnit::m()), int minValues = 3, int sufficentValues = 5) const;
|
||||
CElevationPlane
|
||||
averageGeodeticHeight(const CCoordinateGeodetic &reference, const physical_quantities::CLength &range,
|
||||
const physical_quantities::CLength &maxDeviation =
|
||||
physical_quantities::CLength(1.0, physical_quantities::CLengthUnit::m()),
|
||||
int minValues = 3, int sufficentValues = 5) const;
|
||||
};
|
||||
} // namespace swift::misc::geo
|
||||
|
||||
|
||||
@@ -99,17 +99,10 @@ namespace swift::misc::geo
|
||||
const QString cap = match.captured(0);
|
||||
switch (c++)
|
||||
{
|
||||
case 0:
|
||||
deg = cap.toInt(&ok);
|
||||
break;
|
||||
case 1:
|
||||
min = cap.toInt(&ok);
|
||||
break;
|
||||
case 2:
|
||||
sec = cap.toDouble(&ok);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 0: deg = cap.toInt(&ok); break;
|
||||
case 1: min = cap.toInt(&ok); break;
|
||||
case 2: sec = cap.toDouble(&ok); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
Q_UNUSED(ok); // ok for debugging purposes
|
||||
|
||||
@@ -18,43 +18,56 @@ namespace swift::misc::geo
|
||||
return QStringLiteral("%1 radius: %2").arg(coordinate, m_radius.valueRoundedWithUnit(2, i18n));
|
||||
}
|
||||
|
||||
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, const ICoordinateGeodetic &rangeCoordinate) : CCoordinateGeodetic(coordinate)
|
||||
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, const ICoordinateGeodetic &rangeCoordinate)
|
||||
: CCoordinateGeodetic(coordinate)
|
||||
{
|
||||
this->setRadiusOrMinimumRadius(this->calculateGreatCircleDistance(rangeCoordinate));
|
||||
}
|
||||
|
||||
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, const CLength &radius) : CCoordinateGeodetic(coordinate), m_radius(radius)
|
||||
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, const CLength &radius)
|
||||
: CCoordinateGeodetic(coordinate), m_radius(radius)
|
||||
{}
|
||||
|
||||
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, const CAltitude &altitude, const CLength &radius) : CCoordinateGeodetic(coordinate), m_radius(radius)
|
||||
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, const CAltitude &altitude,
|
||||
const CLength &radius)
|
||||
: CCoordinateGeodetic(coordinate), m_radius(radius)
|
||||
{
|
||||
this->setGeodeticHeight(altitude);
|
||||
}
|
||||
|
||||
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, double altitudeMSLft, const CLength &radius) : CCoordinateGeodetic(coordinate), m_radius(radius)
|
||||
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, double altitudeMSLft, const CLength &radius)
|
||||
: CCoordinateGeodetic(coordinate), m_radius(radius)
|
||||
{
|
||||
this->setGeodeticHeight(CAltitude(altitudeMSLft, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
|
||||
}
|
||||
|
||||
CElevationPlane::CElevationPlane(double latDeg, double lngDeg, double altitudeMSLft, const CLength &radius) : CCoordinateGeodetic(latDeg, lngDeg, altitudeMSLft), m_radius(radius)
|
||||
CElevationPlane::CElevationPlane(double latDeg, double lngDeg, double altitudeMSLft, const CLength &radius)
|
||||
: CCoordinateGeodetic(latDeg, lngDeg, altitudeMSLft), m_radius(radius)
|
||||
{
|
||||
Q_ASSERT_X(!std::isnan(altitudeMSLft), Q_FUNC_INFO, "elv.nan");
|
||||
}
|
||||
|
||||
CElevationPlane::CElevationPlane(const CLatitude &lat, const CLongitude &lng, const CAltitude &altitude, const CLength &radius) : CCoordinateGeodetic(lat, lng, altitude), m_radius(radius)
|
||||
CElevationPlane::CElevationPlane(const CLatitude &lat, const CLongitude &lng, const CAltitude &altitude,
|
||||
const CLength &radius)
|
||||
: CCoordinateGeodetic(lat, lng, altitude), m_radius(radius)
|
||||
{
|
||||
Q_ASSERT_X(altitude.isMeanSeaLevel(), Q_FUNC_INFO, "Need MSL");
|
||||
}
|
||||
|
||||
const CLength &CElevationPlane::getRadiusOrMinimumRadius() const
|
||||
{
|
||||
if (m_radius.isNull() || m_radius < CElevationPlane::singlePointRadius()) { return CElevationPlane::singlePointRadius(); }
|
||||
if (m_radius.isNull() || m_radius < CElevationPlane::singlePointRadius())
|
||||
{
|
||||
return CElevationPlane::singlePointRadius();
|
||||
}
|
||||
return m_radius;
|
||||
}
|
||||
|
||||
void CElevationPlane::setRadiusOrMinimumRadius(const CLength &radius)
|
||||
{
|
||||
m_radius = ((radius.isNull() || radius < CElevationPlane::singlePointRadius())) ? CElevationPlane::singlePointRadius() : radius;
|
||||
m_radius = ((radius.isNull() || radius < CElevationPlane::singlePointRadius())) ?
|
||||
CElevationPlane::singlePointRadius() :
|
||||
radius;
|
||||
}
|
||||
|
||||
void CElevationPlane::fixRadius()
|
||||
@@ -91,15 +104,9 @@ namespace swift::misc::geo
|
||||
return a;
|
||||
}
|
||||
|
||||
double CElevationPlane::getAltitudeValue(const CLengthUnit &unit) const
|
||||
{
|
||||
return this->getAltitude().value(unit);
|
||||
}
|
||||
double CElevationPlane::getAltitudeValue(const CLengthUnit &unit) const { return this->getAltitude().value(unit); }
|
||||
|
||||
bool CElevationPlane::isNull() const
|
||||
{
|
||||
return m_radius.isNull() || CCoordinateGeodetic::isNull();
|
||||
}
|
||||
bool CElevationPlane::isNull() const { return m_radius.isNull() || CCoordinateGeodetic::isNull(); }
|
||||
|
||||
bool CElevationPlane::isWithinRange(const ICoordinateGeodetic &coordinate) const
|
||||
{
|
||||
@@ -120,20 +127,11 @@ namespace swift::misc::geo
|
||||
return inRange;
|
||||
}
|
||||
|
||||
void CElevationPlane::setSinglePointRadius()
|
||||
{
|
||||
m_radius = singlePointRadius();
|
||||
}
|
||||
void CElevationPlane::setSinglePointRadius() { m_radius = singlePointRadius(); }
|
||||
|
||||
void CElevationPlane::setMinorAirportRadius()
|
||||
{
|
||||
m_radius = minorAirportRadius();
|
||||
}
|
||||
void CElevationPlane::setMinorAirportRadius() { m_radius = minorAirportRadius(); }
|
||||
|
||||
void CElevationPlane::setMajorAirportRadius()
|
||||
{
|
||||
m_radius = majorAirportRadius();
|
||||
}
|
||||
void CElevationPlane::setMajorAirportRadius() { m_radius = majorAirportRadius(); }
|
||||
|
||||
QVariant CElevationPlane::propertyByIndex(swift::misc::CPropertyIndexRef index) const
|
||||
{
|
||||
|
||||
@@ -42,16 +42,19 @@ namespace swift::misc::geo
|
||||
CElevationPlane(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &radius);
|
||||
|
||||
//! Plane at given coordinates with radius and altitude
|
||||
CElevationPlane(const ICoordinateGeodetic &coordinate, const aviation::CAltitude &altitude, const physical_quantities::CLength &radius);
|
||||
CElevationPlane(const ICoordinateGeodetic &coordinate, const aviation::CAltitude &altitude,
|
||||
const physical_quantities::CLength &radius);
|
||||
|
||||
//! Plane at given coordinates with radius and altitude
|
||||
CElevationPlane(const ICoordinateGeodetic &coordinate, double altitudeMSLft, const physical_quantities::CLength &radius);
|
||||
CElevationPlane(const ICoordinateGeodetic &coordinate, double altitudeMSLft,
|
||||
const physical_quantities::CLength &radius);
|
||||
|
||||
//! Plane at given coordinates with radius and altitude
|
||||
CElevationPlane(double latDeg, double lngDeg, double altitudeMSLft, const physical_quantities::CLength &radius);
|
||||
|
||||
//! Plane at given coordinates with radius and altitude
|
||||
CElevationPlane(const CLatitude &lat, const CLongitude &lng, const aviation::CAltitude &altitude, const physical_quantities::CLength &radius);
|
||||
CElevationPlane(const CLatitude &lat, const CLongitude &lng, const aviation::CAltitude &altitude,
|
||||
const physical_quantities::CLength &radius);
|
||||
|
||||
//! Constructors from CCoordinateGeodetic
|
||||
using CCoordinateGeodetic::CCoordinateGeodetic;
|
||||
|
||||
@@ -29,29 +29,29 @@ namespace swift::misc::geo
|
||||
//! Find 0..n objects within range of given coordinate
|
||||
//! \param coordinate other position
|
||||
//! \param range within range of other position
|
||||
CONTAINER findWithinRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
|
||||
CONTAINER findWithinRange(const ICoordinateGeodetic &coordinate,
|
||||
const physical_quantities::CLength &range) const
|
||||
{
|
||||
return this->container().findBy([&](const OBJ &geoObj) {
|
||||
return calculateGreatCircleDistance(geoObj, coordinate) <= range;
|
||||
});
|
||||
return this->container().findBy(
|
||||
[&](const OBJ &geoObj) { return calculateGreatCircleDistance(geoObj, coordinate) <= range; });
|
||||
}
|
||||
|
||||
//! Find 0..n objects outside range of given coordinate
|
||||
//! \param coordinate other position
|
||||
//! \param range outside range of other position
|
||||
CONTAINER findOutsideRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
|
||||
CONTAINER findOutsideRange(const ICoordinateGeodetic &coordinate,
|
||||
const physical_quantities::CLength &range) const
|
||||
{
|
||||
return this->container().findBy([&](const OBJ &geoObj) {
|
||||
return calculateGreatCircleDistance(geoObj, coordinate) > range;
|
||||
});
|
||||
return this->container().findBy(
|
||||
[&](const OBJ &geoObj) { return calculateGreatCircleDistance(geoObj, coordinate) > range; });
|
||||
}
|
||||
|
||||
//! Find first in range
|
||||
OBJ findFirstWithinRangeOrDefault(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
|
||||
OBJ findFirstWithinRangeOrDefault(const ICoordinateGeodetic &coordinate,
|
||||
const physical_quantities::CLength &range) const
|
||||
{
|
||||
return this->container().findFirstByOrDefault([&](const OBJ &geoObj) {
|
||||
return calculateGreatCircleDistance(geoObj, coordinate) <= range;
|
||||
});
|
||||
return this->container().findFirstByOrDefault(
|
||||
[&](const OBJ &geoObj) { return calculateGreatCircleDistance(geoObj, coordinate) <= range; });
|
||||
}
|
||||
|
||||
//! Elements with geodetic height (only MSL)
|
||||
@@ -61,7 +61,8 @@ namespace swift::misc::geo
|
||||
}
|
||||
|
||||
//! Any object in range?
|
||||
bool containsObjectInRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
|
||||
bool containsObjectInRange(const ICoordinateGeodetic &coordinate,
|
||||
const physical_quantities::CLength &range) const
|
||||
{
|
||||
return this->container().containsBy([&](const OBJ &geoObj) {
|
||||
const physical_quantities::CLength d = coordinate.calculateGreatCircleDistance(geoObj);
|
||||
@@ -70,7 +71,8 @@ namespace swift::misc::geo
|
||||
}
|
||||
|
||||
//! Any object in range?
|
||||
bool containsObjectOutsideRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
|
||||
bool containsObjectOutsideRange(const ICoordinateGeodetic &coordinate,
|
||||
const physical_quantities::CLength &range) const
|
||||
{
|
||||
return this->container().containsBy([&](const OBJ &geoObj) {
|
||||
const physical_quantities::CLength d = coordinate.calculateGreatCircleDistance(geoObj);
|
||||
@@ -81,23 +83,21 @@ namespace swift::misc::geo
|
||||
//! Any NULL position?
|
||||
bool containsNullPosition() const
|
||||
{
|
||||
return this->container().containsBy([&](const ICoordinateGeodetic &geoObj) {
|
||||
return geoObj.isNull();
|
||||
});
|
||||
return this->container().containsBy([&](const ICoordinateGeodetic &geoObj) { return geoObj.isNull(); });
|
||||
}
|
||||
|
||||
//! Any NULL position or NULL height
|
||||
bool containsNullPositionOrHeight() const
|
||||
{
|
||||
return this->container().containsBy([&](const ICoordinateGeodetic &geoObj) {
|
||||
return geoObj.isNull() || geoObj.isGeodeticHeightNull();
|
||||
});
|
||||
return this->container().containsBy(
|
||||
[&](const ICoordinateGeodetic &geoObj) { return geoObj.isNull() || geoObj.isGeodeticHeightNull(); });
|
||||
}
|
||||
|
||||
//! Find min/max/average height
|
||||
MinMaxAverageHeight findMinMaxAverageHeight() const
|
||||
{
|
||||
MinMaxAverageHeight stats { aviation::CAltitude::null(), aviation::CAltitude::null(), aviation::CAltitude::null(), 0 };
|
||||
MinMaxAverageHeight stats { aviation::CAltitude::null(), aviation::CAltitude::null(),
|
||||
aviation::CAltitude::null(), 0 };
|
||||
if (this->container().isEmpty()) { return stats; } // avoid div by zero
|
||||
int count = 0;
|
||||
double avgFt = 0;
|
||||
@@ -117,7 +117,11 @@ namespace swift::misc::geo
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count > 0) { std::get<2>(stats) = aviation::CAltitude(avgFt / count, aviation::CAltitude::MeanSeaLevel, physical_quantities::CLengthUnit::ft()); }
|
||||
if (count > 0)
|
||||
{
|
||||
std::get<2>(stats) = aviation::CAltitude(avgFt / count, aviation::CAltitude::MeanSeaLevel,
|
||||
physical_quantities::CLengthUnit::ft());
|
||||
}
|
||||
std::get<3>(stats) = count;
|
||||
return stats;
|
||||
}
|
||||
@@ -170,7 +174,8 @@ namespace swift::misc::geo
|
||||
CONTAINER findClosest(int number, const ICoordinateGeodetic &coordinate) const
|
||||
{
|
||||
CONTAINER closest = this->container().partiallySorted(number, [&](const OBJ &a, const OBJ &b) {
|
||||
return calculateEuclideanDistanceSquared(a, coordinate) < calculateEuclideanDistanceSquared(b, coordinate);
|
||||
return calculateEuclideanDistanceSquared(a, coordinate) <
|
||||
calculateEuclideanDistanceSquared(b, coordinate);
|
||||
});
|
||||
closest.truncate(number);
|
||||
return closest;
|
||||
@@ -180,14 +185,16 @@ namespace swift::misc::geo
|
||||
CONTAINER findFarthest(int number, const ICoordinateGeodetic &coordinate) const
|
||||
{
|
||||
CONTAINER farthest = this->container().partiallySorted(number, [&](const OBJ &a, const OBJ &b) {
|
||||
return calculateEuclideanDistanceSquared(a, coordinate) > calculateEuclideanDistanceSquared(b, coordinate);
|
||||
return calculateEuclideanDistanceSquared(a, coordinate) >
|
||||
calculateEuclideanDistanceSquared(b, coordinate);
|
||||
});
|
||||
farthest.truncate(number);
|
||||
return farthest;
|
||||
}
|
||||
|
||||
//! Find closest within range to the given coordinate
|
||||
OBJ findClosestWithinRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
|
||||
OBJ findClosestWithinRange(const ICoordinateGeodetic &coordinate,
|
||||
const physical_quantities::CLength &range) const
|
||||
{
|
||||
OBJ closest;
|
||||
physical_quantities::CLength distance = physical_quantities::CLength::null();
|
||||
@@ -208,7 +215,8 @@ namespace swift::misc::geo
|
||||
void sortByEuclideanDistanceSquared(const ICoordinateGeodetic &coordinate)
|
||||
{
|
||||
this->container().sort([&](const OBJ &a, const OBJ &b) {
|
||||
return calculateEuclideanDistanceSquared(a, coordinate) < calculateEuclideanDistanceSquared(b, coordinate);
|
||||
return calculateEuclideanDistanceSquared(a, coordinate) <
|
||||
calculateEuclideanDistanceSquared(b, coordinate);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -222,20 +230,13 @@ namespace swift::misc::geo
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
IGeoObjectList()
|
||||
{}
|
||||
IGeoObjectList() {}
|
||||
|
||||
//! Container
|
||||
const CONTAINER &container() const
|
||||
{
|
||||
return static_cast<const CONTAINER &>(*this);
|
||||
}
|
||||
const CONTAINER &container() const { return static_cast<const CONTAINER &>(*this); }
|
||||
|
||||
//! Container
|
||||
CONTAINER &container()
|
||||
{
|
||||
return static_cast<CONTAINER &>(*this);
|
||||
}
|
||||
CONTAINER &container() { return static_cast<CONTAINER &>(*this); }
|
||||
};
|
||||
|
||||
//! List of objects with geo coordinates.
|
||||
@@ -246,24 +247,24 @@ namespace swift::misc::geo
|
||||
//! Calculate distances, then sort by range
|
||||
void sortByRange(const ICoordinateGeodetic &position, bool updateValues)
|
||||
{
|
||||
if (updateValues)
|
||||
{
|
||||
this->calculcateAndUpdateRelativeDistanceAndBearing(position);
|
||||
}
|
||||
this->container().sort([&](const OBJ &a, const OBJ &b) { return a.getRelativeDistance() < b.getRelativeDistance(); });
|
||||
if (updateValues) { this->calculcateAndUpdateRelativeDistanceAndBearing(position); }
|
||||
this->container().sort(
|
||||
[&](const OBJ &a, const OBJ &b) { return a.getRelativeDistance() < b.getRelativeDistance(); });
|
||||
}
|
||||
|
||||
//! If distance is already set, just sort container
|
||||
//! \remark requires calculcateAndUpdateRelativeDistanceAndBearing
|
||||
void sortByDistanceToReferencePosition()
|
||||
{
|
||||
this->container().sort([&](const OBJ &a, const OBJ &b) { return a.getRelativeDistance() < b.getRelativeDistance(); });
|
||||
this->container().sort(
|
||||
[&](const OBJ &a, const OBJ &b) { return a.getRelativeDistance() < b.getRelativeDistance(); });
|
||||
}
|
||||
|
||||
//! Sort the first n closest objects
|
||||
void partiallySortByDistanceToReferencePosition(int number)
|
||||
{
|
||||
this->container().partiallySort(number, [&](const OBJ &a, const OBJ &b) { return a.getRelativeDistance() < b.getRelativeDistance(); });
|
||||
this->container().partiallySort(
|
||||
number, [&](const OBJ &a, const OBJ &b) { return a.getRelativeDistance() < b.getRelativeDistance(); });
|
||||
}
|
||||
|
||||
//! Get n closest objects
|
||||
@@ -278,28 +279,24 @@ namespace swift::misc::geo
|
||||
}
|
||||
|
||||
//! Calculate distances, remove if outside range
|
||||
void removeIfOutsideRange(const ICoordinateGeodetic &position, const physical_quantities::CLength &maxDistance, bool updateValues)
|
||||
void removeIfOutsideRange(const ICoordinateGeodetic &position, const physical_quantities::CLength &maxDistance,
|
||||
bool updateValues)
|
||||
{
|
||||
this->container().removeIf([&](OBJ &geoObj) {
|
||||
return updateValues ?
|
||||
geoObj.calculcateAndUpdateRelativeDistanceAndBearing(position) > maxDistance :
|
||||
geoObj.calculateGreatCircleDistance(position) > maxDistance;
|
||||
return updateValues ? geoObj.calculcateAndUpdateRelativeDistanceAndBearing(position) > maxDistance :
|
||||
geoObj.calculateGreatCircleDistance(position) > maxDistance;
|
||||
});
|
||||
}
|
||||
|
||||
//! Calculate distances
|
||||
void calculcateAndUpdateRelativeDistanceAndBearing(const ICoordinateGeodetic &position)
|
||||
{
|
||||
for (OBJ &geoObj : this->container())
|
||||
{
|
||||
geoObj.calculcateAndUpdateRelativeDistanceAndBearing(position);
|
||||
}
|
||||
for (OBJ &geoObj : this->container()) { geoObj.calculcateAndUpdateRelativeDistanceAndBearing(position); }
|
||||
}
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
IGeoObjectWithRelativePositionList()
|
||||
{}
|
||||
IGeoObjectWithRelativePositionList() {}
|
||||
};
|
||||
} // namespace swift::misc::geo
|
||||
|
||||
|
||||
@@ -42,32 +42,32 @@ namespace swift::misc::geo
|
||||
|
||||
QString CKmlUtils::asPoint(const ICoordinateGeodetic &coordinate, const KMLSettings &settings)
|
||||
{
|
||||
return u"<Point><coordinates>" %
|
||||
CKmlUtils::asRawCoordinates(coordinate, settings.withAltitude) %
|
||||
u"</coordinates>" %
|
||||
(settings.extrude ? u"<extrude>1</extrude>" : u"") %
|
||||
(settings.withAltitude && !settings.altitudeMode.isEmpty() ? u"<altitudeMode>" % settings.altitudeMode % "</altitudeMode>" : QString()) %
|
||||
return u"<Point><coordinates>" % CKmlUtils::asRawCoordinates(coordinate, settings.withAltitude) %
|
||||
u"</coordinates>" % (settings.extrude ? u"<extrude>1</extrude>" : u"") %
|
||||
(settings.withAltitude && !settings.altitudeMode.isEmpty() ?
|
||||
u"<altitudeMode>" % settings.altitudeMode % "</altitudeMode>" :
|
||||
QString()) %
|
||||
u"</Point>";
|
||||
}
|
||||
|
||||
QString CKmlUtils::asPlacemark(
|
||||
const QString &name, const QString &description,
|
||||
const ICoordinateGeodetic &coordinate, const KMLSettings &settings)
|
||||
QString CKmlUtils::asPlacemark(const QString &name, const QString &description,
|
||||
const ICoordinateGeodetic &coordinate, const KMLSettings &settings)
|
||||
{
|
||||
return u"<Placemark>" %
|
||||
asPoint(coordinate, settings) %
|
||||
return u"<Placemark>" % asPoint(coordinate, settings) %
|
||||
(name.isEmpty() ? QString() : u"<name>" % name.toHtmlEscaped() % u"</name>") %
|
||||
(description.isEmpty() ? QString() : u"<description>" % description.toHtmlEscaped() % u"</description>") %
|
||||
(description.isEmpty() ? QString() :
|
||||
u"<description>" % description.toHtmlEscaped() % u"</description>") %
|
||||
u"</Placemark>";
|
||||
}
|
||||
|
||||
QString CKmlUtils::asLineString(const QString &coordinatesRaw, const CKmlUtils::KMLSettings &settings)
|
||||
{
|
||||
return u"<LineString>" %
|
||||
(settings.withAltitude && !settings.altitudeMode.isEmpty() ? u"<altitudeMode>" % settings.altitudeMode % "</altitudeMode>" : QString()) %
|
||||
(settings.withAltitude && !settings.altitudeMode.isEmpty() ?
|
||||
u"<altitudeMode>" % settings.altitudeMode % "</altitudeMode>" :
|
||||
QString()) %
|
||||
(settings.tessellate ? u"<tessellate>1</tessellate>" : u"") %
|
||||
(settings.extrude ? u"<extrude>1</extrude>" : u"") %
|
||||
CKmlUtils::wrapAsKmlCoordinates(coordinatesRaw) %
|
||||
(settings.extrude ? u"<extrude>1</extrude>" : u"") % CKmlUtils::wrapAsKmlCoordinates(coordinatesRaw) %
|
||||
u"</LineString>";
|
||||
}
|
||||
} // namespace swift::misc::geo
|
||||
|
||||
@@ -25,8 +25,7 @@ namespace swift::misc::geo
|
||||
struct KMLSettings
|
||||
{
|
||||
//! Ctor
|
||||
KMLSettings(bool withAltitude, bool extrude) : withAltitude(withAltitude), extrude(extrude)
|
||||
{}
|
||||
KMLSettings(bool withAltitude, bool extrude) : withAltitude(withAltitude), extrude(extrude) {}
|
||||
|
||||
//! @{
|
||||
//! Setting members
|
||||
@@ -50,7 +49,8 @@ namespace swift::misc::geo
|
||||
static QString asPoint(const geo::ICoordinateGeodetic &coordinate, const KMLSettings &settings);
|
||||
|
||||
//! As KML placemark
|
||||
static QString asPlacemark(const QString &name, const QString &description, const geo::ICoordinateGeodetic &coordinate, const KMLSettings &settings);
|
||||
static QString asPlacemark(const QString &name, const QString &description,
|
||||
const geo::ICoordinateGeodetic &coordinate, const KMLSettings &settings);
|
||||
|
||||
//! As KML line
|
||||
static QString asLineString(const QString &coordinatesRaw, const KMLSettings &settings);
|
||||
|
||||
@@ -38,10 +38,7 @@ namespace swift::misc::geo
|
||||
QString convertToQString(bool i18n = false) const
|
||||
{
|
||||
QString s(CEarthAngle::convertToQString(i18n));
|
||||
if (!this->isZeroEpsilonConsidered())
|
||||
{
|
||||
s.append(this->isNegativeWithEpsilonConsidered() ? " S" : " N");
|
||||
}
|
||||
if (!this->isZeroEpsilonConsidered()) { s.append(this->isNegativeWithEpsilonConsidered() ? " S" : " N"); }
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,10 +38,7 @@ namespace swift::misc::geo
|
||||
QString convertToQString(bool i18n = false) const
|
||||
{
|
||||
QString s(CEarthAngle::convertToQString(i18n));
|
||||
if (!this->isZeroEpsilonConsidered())
|
||||
{
|
||||
s.append(this->isNegativeWithEpsilonConsidered() ? " W" : " E");
|
||||
}
|
||||
if (!this->isZeroEpsilonConsidered()) { s.append(this->isNegativeWithEpsilonConsidered() ? " W" : " E"); }
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user