swift
elevationplane.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2016 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
7 #include "misc/pq/length.h"
9 
10 using namespace swift::misc::aviation;
11 using namespace swift::misc::physical_quantities;
12 
13 namespace swift::misc::geo
14 {
15  QString CElevationPlane::convertToQString(bool i18n) const
16  {
17  const QString coordinate = CCoordinateGeodetic::toQString(i18n);
18  return QStringLiteral("%1 radius: %2").arg(coordinate, m_radius.valueRoundedWithUnit(2, i18n));
19  }
20 
21  CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, const ICoordinateGeodetic &rangeCoordinate)
22  : CCoordinateGeodetic(coordinate)
23  {
24  this->setRadiusOrMinimumRadius(this->calculateGreatCircleDistance(rangeCoordinate));
25  }
26 
28  : CCoordinateGeodetic(coordinate), m_radius(radius)
29  {}
30 
32  const CLength &radius)
33  : CCoordinateGeodetic(coordinate), m_radius(radius)
34  {
35  this->setGeodeticHeight(altitude);
36  }
37 
38  CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, double altitudeMSLft, const CLength &radius)
39  : CCoordinateGeodetic(coordinate), m_radius(radius)
40  {
41  this->setGeodeticHeight(CAltitude(altitudeMSLft, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
42  }
43 
44  CElevationPlane::CElevationPlane(double latDeg, double lngDeg, double altitudeMSLft, const CLength &radius)
45  : CCoordinateGeodetic(latDeg, lngDeg, altitudeMSLft), m_radius(radius)
46  {
47  Q_ASSERT_X(!std::isnan(altitudeMSLft), Q_FUNC_INFO, "elv.nan");
48  }
49 
50  CElevationPlane::CElevationPlane(const CLatitude &lat, const CLongitude &lng, const CAltitude &altitude,
51  const CLength &radius)
52  : CCoordinateGeodetic(lat, lng, altitude), m_radius(radius)
53  {
54  Q_ASSERT_X(altitude.isMeanSeaLevel(), Q_FUNC_INFO, "Need MSL");
55  }
56 
58  {
59  if (m_radius.isNull() || m_radius < CElevationPlane::singlePointRadius())
60  {
62  }
63  return m_radius;
64  }
65 
67  {
68  m_radius = ((radius.isNull() || radius < CElevationPlane::singlePointRadius())) ?
70  radius;
71  }
72 
74  {
75  if (m_radius.isNull() || m_radius < CElevationPlane::singlePointRadius())
76  {
78  }
79  }
80 
82  {
83  if (offset.isNull() || offset.isZeroEpsilonConsidered()) { return; }
84  const CAltitude newAlt = this->getAltitude().withOffset(offset);
85  this->setGeodeticHeight(newAlt);
86  }
87 
89  {
90  if (unit.isNull() || this->getAltitudeUnit().isNull()) { return; }
91  if (this->getAltitudeUnit() == unit) { return; }
92  this->setGeodeticHeight(this->getAltitude().switchedUnit(unit));
93  }
94 
96  {
97  return (isWithinRange(coordinate)) ? geodeticHeight() : CAltitude::null();
98  }
99 
101  {
102  CAltitude a = this->geodeticHeight();
103  a.switchUnit(unit);
104  return a;
105  }
106 
107  double CElevationPlane::getAltitudeValue(const CLengthUnit &unit) const { return this->getAltitude().value(unit); }
108 
109  bool CElevationPlane::isNull() const { return m_radius.isNull() || CCoordinateGeodetic::isNull(); }
110 
112  {
113  if (coordinate.isNull()) { return false; }
114  if (this->isNull()) { return false; }
115  const CLength d = this->calculateGreatCircleDistance(coordinate);
116  const bool inRange = (m_radius >= d);
117  return inRange;
118  }
119 
120  bool CElevationPlane::isWithinRange(const ICoordinateGeodetic &coordinate, const CLength &radius) const
121  {
122  if (coordinate.isNull()) { return false; }
123  if (radius.isNull()) { return false; }
124  if (this->isNull()) { return false; }
125  const CLength d = this->calculateGreatCircleDistance(coordinate);
126  const bool inRange = (radius >= d);
127  return inRange;
128  }
129 
131 
133 
135 
137  {
138  if (index.isMyself()) { return QVariant::fromValue(*this); }
139  const ColumnIndex i = index.frontCasted<ColumnIndex>();
140  switch (i)
141  {
142  case IndexRadius: return m_radius.propertyByIndex(index.copyFrontRemoved());
143  default: break;
144  }
146  }
147 
148  void CElevationPlane::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
149  {
150  if (index.isMyself())
151  {
152  (*this) = variant.value<CElevationPlane>();
153  return;
154  }
155  const ColumnIndex i = index.frontCasted<ColumnIndex>();
156  switch (i)
157  {
158  case IndexRadius: m_radius.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
159  default: CCoordinateGeodetic::setPropertyByIndex(index, variant); break;
160  }
161  }
162 
164  {
165  Q_UNUSED(index)
166  return this->getAltitude().compare(elevationPlane.getAltitude());
167  }
168 
169  // distance per second distance per 5 secs (taxi speeds)
170  // 100km/h 27,8m/s 10kts 51m/5secs
171  // 50km/h 13,9m/s 20kts 102m/5secs
172  // 100kts 51,4m/s
174  {
175  static const CLength l(50.0, CLengthUnit::m());
176  return l;
177  }
178 
180  {
181  static const CLength l(500.0, CLengthUnit::m());
182  return l;
183  }
184 
186  {
187  static const CLength l(1000.0, CLengthUnit::m());
188  return l;
189  }
190 
192  {
193  static const CElevationPlane p;
194  return p;
195  }
196 } // namespace swift::misc::geo
Non-owning reference to a CPropertyIndex with a subset of its features.
Q_REQUIRED_RESULT CPropertyIndexRef copyFrontRemoved() const
Copy with first element removed.
CastType frontCasted() const
First element casted to given type, usually the PropertIndex enum.
bool isMyself() const
Myself index, used with nesting.
Altitude as used in aviation, can be AGL or MSL altitude.
Definition: altitude.h:52
bool isMeanSeaLevel() const
MSL Mean sea level?
Definition: altitude.h:139
CAltitude withOffset(const CLength &offset) const
Altitude with offset.
Definition: altitude.cpp:61
CAltitude & switchUnit(const physical_quantities::CLengthUnit &newUnit)
Value in switched unit.
Definition: altitude.cpp:71
int compare(const CAltitude &otherAltitude) const
Return negative, zero, or positive if a is less than, equal to, or greater than b.
Definition: altitude.cpp:399
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
virtual const aviation::CAltitude & geodeticHeight() const
Height, ellipsoidal or geodetic height (used in GPS)
virtual bool isNull() const
Is null?
void setGeodeticHeight(const aviation::CAltitude &height)
Set height (ellipsoidal or geodetic height)
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Plane of same elevation, can be a single point or larger area (e.g. airport)
void setMinorAirportRadius()
Treat as elevation of a small airport.
static const physical_quantities::CLength & singlePointRadius()
Radius for single point.
static const physical_quantities::CLength & majorAirportRadius()
Radius for major airport.
void addAltitudeOffset(const physical_quantities::CLength &offset)
Add offset to altitude.
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
void switchAltitudeUnit(const physical_quantities::CLengthUnit &unit)
Switch altitude unit.
const aviation::CAltitude & getAltitude() const
Altitude (synonym for geodetic height)
bool isWithinRange(const ICoordinateGeodetic &coordinate) const
Check if elevation is within radius and can be used.
virtual bool isNull() const
Existing value?
const aviation::CAltitude & getAltitudeIfWithinRadius(const ICoordinateGeodetic &coordinate) const
Altitude when within radius, else null.
const physical_quantities::CLengthUnit & getAltitudeUnit() const
Altitude (synonym for geodetic height) unit.
void setRadiusOrMinimumRadius(const physical_quantities::CLength &radius)
Radius or minimum CElevationPlane::singlePointRadius.
void fixRadius()
Set minimum radius if not having radius.
static const physical_quantities::CLength & minorAirportRadius()
Radius for minor airport.
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
double getAltitudeValue(const physical_quantities::CLengthUnit &unit) const
Altitude (synonym for geodetic height)
const physical_quantities::CLength & getRadiusOrMinimumRadius() const
Radius or minimum radius.
CElevationPlane()
Default constructor.
aviation::CAltitude getAltitudeInUnit(const physical_quantities::CLengthUnit &unit) const
Altitude (synonym for geodetic height)
static const CElevationPlane & null()
NULL plane.
void setMajorAirportRadius()
Treat as elevation of a small airport.
int comparePropertyByIndex(CPropertyIndexRef index, const CElevationPlane &elevationPlane) const
Compare for index.
void setSinglePointRadius()
Treat as single point as obtained from simulator.
Geodetic coordinate, a position in 3D space relative to the reference geoid.
physical_quantities::CLength calculateGreatCircleDistance(const ICoordinateGeodetic &otherCoordinate) const
Great circle distance.
virtual bool isNull() const
Is null, means vector x, y, z == 0.
Physical unit length (length)
Definition: length.h:18
Specialized class for distance units (meter, foot, nautical miles).
Definition: units.h:95
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
double value(MU unit) const
Value in given unit.
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
bool isZeroEpsilonConsidered() const
Quantity value <= epsilon.