FlightGear next
QmlPositioned.cxx
Go to the documentation of this file.
1// QmlPositioned.cxx - Expose NavData to Qml
2//
3// Written by James Turner, started April 2018.
4//
5// Copyright (C) 2018 James Turner <james@flightgear.org>
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License as
9// published by the Free Software Foundation; either version 2 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful, but
13// WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15// General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21#include "QmlPositioned.hxx"
22
23#include <QDebug>
24
25#include <simgear/misc/strutils.hxx>
26
28#include <Navaids/navrecord.hxx>
29#include <Airports/airport.hxx>
31#include <Airports/runways.hxx>
32
33using namespace flightgear;
34using namespace simgear::strutils;
35
37 m_data(SGGeod::fromDeg(-9999.0, -9999.0))
38{
39}
40
41QmlGeod::QmlGeod(const SGGeod &geod) :
42 m_data(geod)
43{
44}
45
47{
48 return m_data.getLatitudeDeg();
49}
50
52{
53 return m_data.getLongitudeDeg();
54}
55
57{
58 return m_data.getLatitudeRad();
59}
60
62{
63 return m_data.getLongitudeRad();
64}
65
67{
68 return m_data.getElevationFt();
69}
70
71bool QmlGeod::valid() const
72{
73 return m_data.isValid();
74}
75
77{
78 if (!m_data.isValid())
79 return "<invalid coordinate>";
80
81 LatLonFormat internalFormat = LatLonFormat::DECIMAL_DEGREES;
82 switch (fmt) {
83 case DecimalDegrees: internalFormat = LatLonFormat::DECIMAL_DEGREES; break;
84 case SignedDecimalDegrees: internalFormat = LatLonFormat::SIGNED_DECIMAL_DEGREES; break;
85 }
86
87 const auto s = formatGeodAsString(m_data, internalFormat, DegreeSymbol::UTF8_DEGREE);
88 return QString::fromStdString(s);
89}
90
91double QmlGeod::elevationM() const
92{
93 return m_data.getElevationM();
94}
95
97{
98 if (qFuzzyCompare(m_data.getLatitudeDeg(), latitudeDeg))
99 return;
100
101 m_data.setLatitudeDeg(latitudeDeg);
102 // emit latitudeChanged();
103}
104
106{
107 if (qFuzzyCompare(m_data.getLongitudeDeg(), longitudeDeg))
108 return;
109
110 m_data.setLongitudeDeg(longitudeDeg);
111 // emit longitudeChanged();
112}
113
115{
116 if (qFuzzyCompare(m_data.getLatitudeRad(), latitudeRad))
117 return;
118
119 m_data.setLatitudeRad(latitudeRad);
120 // emit latitudeChanged();
121}
122
124{
125 if (qFuzzyCompare(m_data.getLongitudeRad(), longitudeRad))
126 return;
127
128 m_data.setLongitudeRad(longitudeRad);
129 // emit longitudeChanged();
130}
131
133{
134 if (qFuzzyCompare(m_data.getElevationM(), elevationM))
135 return;
136
137 m_data.setElevationM(elevationM);
138 // emit elevationChanged();
139}
140
142{
143 if (qFuzzyCompare(m_data.getElevationFt(), elevationFt))
144 return;
145
146 m_data.setElevationFt(elevationFt);
147 // emit elevationChanged();
148}
149
151
152QmlPositioned::QmlPositioned(QObject *parent) : QObject(parent)
153{
154
155}
156
161
163{
164 if (!p) {
165 m_pos.clear();
166 } else {
167 m_pos = p;
168 }
169
170 emit infoChanged();
171}
172
174{
175 return m_pos;
176}
177
179{
180 return m_pos.valid();
181}
182
183QString QmlPositioned::ident() const
184{
185 if (!m_pos)
186 return {};
187
188 return QString::fromStdString(m_pos->ident());
189}
190
191QString QmlPositioned::name() const
192{
193 if (!m_pos)
194 return {};
195
196 return QString::fromStdString(m_pos->name());
197}
198
199qlonglong QmlPositioned::guid() const
200{
201 if (!m_pos)
202 return 0;
203
204 return m_pos->guid();
205}
206
208{
209 if (!m_pos)
210 return Invalid;
211
212 return static_cast<Type>(m_pos->type());
213}
214
216{
217 if (m_pos && (m_pos->guid()) == guid)
218 return;
219
221
222 emit guidChanged();
223 emit infoChanged();
224}
225
227{
228 return FGPositioned::isAirportType(m_pos.get());
229}
230
232{
233 return FGPositioned::isRunwayType(m_pos.get());
234}
235
237{
238 return FGPositioned::isNavaidType(m_pos.get());
239}
240
242{
243 if (!m_pos)
244 return nullptr;
245
246 return new QmlGeod(m_pos->geod());
247}
248
250{
252 if (!nav)
253 return 0.0;
254
255 qWarning() << Q_FUNC_INFO << "check me!";
256 return nav->get_freq() / 1000.0;
257}
258
260{
262 if (!nav)
263 return 0.0;
264
265 return nav->get_range();
266}
267
269{
271 if (!nav || !nav->runway())
272 return nullptr;
273
274 return new QmlPositioned(nav->runway());
275}
276
278{
280 if (!nav || !nav->hasDME())
281 return nullptr;
282
283 return new QmlPositioned(flightgear::NavDataCache::instance()->loadById(nav->colocatedDME()));
284}
285
287{
288 FGRunway* runway = fgpositioned_cast<FGRunway>(m_pos);
289 if (runway) {
290 return new QmlPositioned(runway->airport());
291 }
292
293 return nullptr;
294}
295
297{
298 FGRunway* runway = fgpositioned_cast<FGRunway>(m_pos);
299 if (runway) {
300 return runway->headingDeg();
301 }
302
303 return 0.0;
304}
305
307{
308 FGRunway* runway = fgpositioned_cast<FGRunway>(m_pos);
309 if (runway) {
310 return runway->lengthFt();
311 }
312
313 return 0.0;
314}
315
317{
318 return (other && (other->inner() == inner()));
319}
320
322{
323 if (!isAirportType())
324 return false;
325
327 if (!apt)
328 return false;
329
330 return !apt->groundNetwork()->allParkings().empty();
331}
332
334{
335 return p1.inner() == p2.inner();
336}
337
#define p2(x, y)
#define p(x)
bool operator==(const QmlPositioned &p1, const QmlPositioned &p2)
FGGroundNetwork * groundNetwork() const
Definition airport.cxx:1053
const FGParkingList & allParkings() const
int get_freq() const
Definition navrecord.hxx:76
int get_range() const
Definition navrecord.hxx:77
bool hasDME() const
Definition navrecord.cxx:96
PositionedID colocatedDME() const
FGRunwayRef runway() const
Retrieve the runway this navaid is associated with (for ILS/LOC/GS)
Definition navrecord.cxx:58
static bool isRunwayType(FGPositioned *pos)
static bool isAirportType(FGPositioned *pos)
static bool isNavaidType(FGPositioned *pos)
double headingDeg() const
Runway heading in degrees.
double lengthFt() const
FGAirportRef airport() const
Expose an SGGeod as Qml-friendly class.
void setLatitudeDeg(double latitudeDeg)
void setLongitudeDeg(double longitudeDeg)
double elevationM
void setElevationFt(double elevationFt)
SGGeod geod() const
double longitudeDeg
void setLatitudeRad(double latitudeRad)
Q_INVOKABLE QString toString(Format fmt) const
void setLongitudeRad(double longitudeRad)
double elevationFt
@ SignedDecimalDegrees
double latitudeRad
double longitudeRad
double latitudeDeg
void setElevationM(double elevationM)
void infoChanged()
FGPositionedRef inner() const
QmlPositioned * colocatedDME
void setGuid(qlonglong guid)
Q_INVOKABLE bool equals(QmlPositioned *other) const
double navaidFrequencyMHz
void setInner(FGPositionedRef p)
void guidChanged()
QmlPositioned * navaidRunway
QmlPositioned(QObject *parent=nullptr)
QmlPositioned * owningAirport
FGPositionedRef loadById(PositionedID guid)
retrieve an FGPositioned from the cache.
static NavDataCache * instance()
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
Definition Addon.cxx:53
SGSharedPtr< FGPositioned > FGPositionedRef
Definition airways.cxx:49
T * fgpositioned_cast(FGPositioned *p)