/
maptypes.h
1061 lines (855 loc) · 28.6 KB
/
maptypes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*****************************************************************************
* Copyright 2015-2019 Alexander Barthel alex@littlenavmap.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef LITTLENAVMAP_MAPTYPES_H
#define LITTLENAVMAP_MAPTYPES_H
#include "geo/pos.h"
#include "geo/rect.h"
#include "geo/line.h"
#include "fs/fspaths.h"
#include "common/mapflags.h"
#include "geo/linestring.h"
#include "fs/sc/simconnectuseraircraft.h"
#include "fs/weather/weathertypes.h"
#include "fs/common/xpgeometry.h"
#include <QColor>
#include <QString>
class OptionData;
namespace proc {
struct MapProcedurePoint;
}
/*
* Maptypes are mostly filled from database tables and are used to pass airport, navaid and more information
* around in the program. The types are kept primitive (no inheritance no vtable) for performance reasons.
* Units are usually feet. Type string are as they appear in the database.
*/
namespace map {
/* Initialize all text that are translateable after loading the translation files */
void initTranslateableTexts();
// =====================================================================
struct PosCourse
{
PosCourse()
: course(INVALID_COURSE_VALUE)
{
}
explicit PosCourse(atools::geo::Pos posParam, float courseParam = INVALID_COURSE_VALUE)
: pos(posParam), course(courseParam)
{
}
atools::geo::Pos pos;
float course;
bool isCourseValid() const
{
return course < INVALID_COURSE_VALUE;
}
bool isValid() const
{
return pos.isValid();
}
};
// =====================================================================
/* Primitive id type combo that is hashable */
struct MapObjectRef
{
int id;
map::MapObjectTypes type;
bool operator==(const map::MapObjectRef& other) const;
bool operator!=(const map::MapObjectRef& other) const;
};
int qHash(const map::MapObjectRef& type);
typedef QVector<MapObjectRef> MapObjectRefList;
/* Convert type from nav_search table to enum */
map::MapObjectTypes navTypeToMapObjectType(const QString& navType);
bool navTypeTacan(const QString& navType);
bool navTypeVortac(const QString& navType);
/* Check surface attributes */
bool isHardSurface(const QString& surface);
bool isWaterSurface(const QString& surface);
bool isSoftSurface(const QString& surface);
// =====================================================================
/* Base struct for all map objects covering id and position
* Position is used to check for validity, i.e. not initialized objects
* Object type can be NONE if no polymorphism is needed */
struct MapBase
{
MapBase(map::MapObjectType type)
: objType(type)
{
}
int id;
atools::geo::Pos position;
/* Use simple type information to avoid vtable and RTTI overhead. Avoid QFlags here. */
map::MapObjectType objType;
bool isValid() const
{
return position.isValid();
}
const atools::geo::Pos& getPosition() const
{
return position;
}
int getId() const
{
return id;
}
template<typename TYPE>
const TYPE *asType(map::MapObjectTypes type) const
{
if(objType == type)
return static_cast<const TYPE *>(this);
else
return nullptr;
}
};
// =====================================================================
/* Airport type not including runways (have to queried separately) */
/* Database id airport.airport_id */
struct MapAirport
: public MapBase
{
MapAirport() : MapBase(map::AIRPORT)
{
}
QString ident, /* ICAO ident*/ name, region;
int longestRunwayLength = 0, longestRunwayHeading = 0, transitionAltitude = 0;
int rating = -1;
map::MapAirportFlags flags = AP_NONE;
float magvar = 0; /* Magnetic variance - positive is east, negative is west */
bool navdata, /* true if source is third party nav database, false if source is simulator data */
xplane; /* true if data source is X-Plane */
int towerFrequency = 0, atisFrequency = 0, awosFrequency = 0, asosFrequency = 0, unicomFrequency = 0;
atools::geo::Pos towerCoords;
atools::geo::Rect bounding;
int routeIndex = -1;
bool closed() const;
bool hard() const;
bool soft() const;
bool water() const;
bool lighted() const;
bool helipad() const;
bool softOnly() const;
bool waterOnly() const;
bool helipadOnly() const;
bool noRunways() const;
bool tower() const;
bool addon() const;
bool is3d() const;
bool anyFuel() const;
bool complete() const;
bool towerObject() const;
bool apron() const;
bool taxiway() const;
bool parking() const;
bool als() const;
bool vasi() const;
bool fence() const;
bool closedRunways() const;
bool procedure() const;
/* Check if airport should be drawn empty */
bool emptyDraw() const;
bool emptyDraw(const OptionData& od) const;
/* Check if airport has any scenery elements */
bool empty() const;
/*
* @param objectTypes Map display configuration flags
* @return true if this airport is visible on map
*/
bool isVisible(map::MapObjectTypes objectTypes) const;
};
// =====================================================================
/* Airport runway. All dimensions are feet */
/* Datbase id is runway.runway_id */
struct MapRunway
: public MapBase
{
MapRunway() : MapBase(map::NONE)
{
}
QString surface, shoulder, primaryName, secondaryName, edgeLight;
int length /* ft */, primaryEndId, secondaryEndId;
float heading, patternAlt;
int width,
primaryOffset, secondaryOffset, /* part of the runway length */
primaryBlastPad, secondaryBlastPad, primaryOverrun, secondaryOverrun; /* not part of the runway length all in ft */
atools::geo::Pos primaryPosition, secondaryPosition;
/* Used by AirportQuery::getRunways */
int airportId;
bool primaryClosed, secondaryClosed; /* true if ends have closed markings */
bool isValid() const
{
return position.isValid();
}
bool isHard() const
{
return isHardSurface(surface);
}
bool isWater() const
{
return isWaterSurface(surface);
}
bool isSoft() const
{
return isSoftSurface(surface);
}
bool isLighted() const
{
return !edgeLight.isEmpty();
}
const atools::geo::Pos& getPosition() const
{
return position;
}
};
// =====================================================================
/* Airport runway end. All dimensions are feet */
/* Database id is runway_end.runway_end_id */
struct MapRunwayEnd
: public MapBase
{
MapRunwayEnd() : MapBase(map::RUNWAYEND)
{
}
QString name, leftVasiType, rightVasiType, pattern;
float heading, leftVasiPitch = 0.f, rightVasiPitch = 0.f;
bool secondary;
bool navdata; /* true if source is third party nav database, false if source is simulator data */
};
// =====================================================================
/* Apron including full geometry */
struct MapApron
: public MapBase
{
MapApron() : MapBase(map::NONE)
{
}
/* FSX/P3D simple geometry */
atools::geo::LineString vertices;
/* X-Plane complex geometry including curves and holes */
atools::fs::common::XpGeo geometry;
QString surface;
bool drawSurface;
};
// =====================================================================
/* Taxiway segment */
struct MapTaxiPath
{
atools::geo::Pos start, end;
QString surface, name;
int width; /* feet */
bool drawSurface, closed;
bool isValid() const
{
return start.isValid();
}
int getId() const
{
return -1;
}
};
// =====================================================================
/* Gate, GA ramp, cargo ramps, etc. */
/* database id parking.parking_id */
struct MapParking
: public MapBase
{
MapParking() : MapBase(map::PARKING)
{
}
QString type, name, airlineCodes /* Comma separated list of airline codes */;
int airportId /* database id airport.airport_id */;
int number, /* -1 for X-Plane style free names. Otherwise FSX/P3D number */
radius, heading;
bool jetway;
};
// =====================================================================
/* Start position (runway, helipad or parking */
/* database id start.start_id */
struct MapStart
: public MapBase
{
MapStart() : MapBase(map::NONE)
{
}
QString type /* RUNWAY, HELIPAD or WATER */, runwayName /* not empty if this is a runway start */;
int airportId /* database id airport.airport_id */;
int heading, helipadNumber /* -1 if not a helipad otherwise sequence number as it appeared in the BGL */;
};
// =====================================================================
/* Airport helipad */
struct MapHelipad
: public MapBase
{
MapHelipad() : MapBase(map::HELIPAD)
{
}
QString surface, type, runwayName;
int startId, airportId, length, width, heading, start;
bool closed, transparent;
};
// =====================================================================
/* VOR station */
/* database id vor.vor_id */
struct MapVor
: public MapBase
{
MapVor() : MapBase(map::VOR)
{
}
QString ident, region, type /* HIGH, LOW, TERMINAL */, name /*, airportIdent*/;
float magvar;
int frequency /* MHz * 1000 */, range /* nm */;
QString channel;
int routeIndex = -1; /* Filled by the get nearest methods for building the context menu */
bool dmeOnly, hasDme, tacan, vortac;
QString getFrequencyOrChannel() const
{
if(frequency > 0)
return QString::number(frequency);
else
return channel;
}
};
// =====================================================================
/* NDB station */
/* database id ndb.ndb_id */
struct MapNdb
: public MapBase
{
MapNdb() : MapBase(map::NDB)
{
}
QString ident, region, type /* HH, H, COMPASS_POINT, etc. */, name /*, airportIdent*/;
float magvar;
int frequency /* kHz * 100 */, range /* nm */;
int routeIndex = -1; /* Filled by the get nearest methods for building the context menu */
};
// =====================================================================
/* database waypoint.waypoint_id */
struct MapWaypoint
: public MapBase
{
MapWaypoint() : MapBase(map::WAYPOINT)
{
}
float magvar;
QString ident, region, type /* NAMED, UNAMED, etc. *//*, airportIdent*/;
int routeIndex = -1; /* Filled by the get nearest methods for building the context menu */
bool hasVictorAirways = false, hasJetAirways = false;
};
/* Waypoint or intersection */
struct MapAirwayWaypoint
{
map::MapWaypoint waypoint;
int airwayId, airwayFragmentId, seqNum;
};
// =====================================================================
/* User defined waypoint of a flight plan */
/* Id is Sequence number as it was added to the flight plan */
struct MapUserpointRoute
: public MapBase
{
MapUserpointRoute() : MapBase(map::USERPOINTROUTE)
{
}
QString name;
float magvar;
int routeIndex = -1; /* Filled by the get nearest methods for building the context menu */
};
// =====================================================================
/* User defined waypoint from the user database */
struct MapUserpoint
: public MapBase
{
MapUserpoint() : MapBase(map::USERPOINT)
{
}
QString name, ident, region, type, description, tags;
bool temp = false;
};
// =====================================================================
/* Logbook entry */
struct MapLogbookEntry
: public MapBase
{
MapLogbookEntry() : MapBase(map::LOGBOOK)
{
}
QString departureName, departureIdent, departureRunway,
destinationName, destinationIdent, destinationRunway,
description, simulator, aircraftType,
aircraftRegistration, routeFile, perfFile;
float distance, distanceGc;
atools::geo::Pos departurePos, destinationPos;
map::MapAirport departure, destination;
atools::geo::Rect bounding() const
{
atools::geo::Rect rect(departurePos);
rect.extend(destinationPos);
return rect;
}
bool isDestAndDepartPosValid() const
{
return departurePos.isValid() && destinationPos.isValid();
}
};
// Airways =====================================================================
/* Airway type */
enum MapAirwayType
{
NO_AIRWAY,
VICTOR,
JET,
BOTH
};
enum MapAirwayDirection
{
/* 0 = both, 1 = forward only (from -> to), 2 = backward only (to -> from) */
DIR_BOTH = 0,
DIR_FORWARD = 1,
DIR_BACKWARD = 2
};
/* Airway segment */
struct MapAirway
: public MapBase
{
MapAirway() : MapBase(map::AIRWAY)
{
}
QString name;
map::MapAirwayType type;
int fromWaypointId, toWaypointId /* all database ids */;
MapAirwayDirection direction;
int minAltitude, maxAltitude /* feet */,
sequence /* segment sequence in airway */,
fragment /* fragment number of disconnected airways with the same name */;
atools::geo::Pos from, to;
atools::geo::Rect bounding; /* pre calculated using from and to */
};
// =====================================================================
/* Marker beacon */
/* database id marker.marker_id */
struct MapMarker
: public MapBase
{
MapMarker() : MapBase(map::MARKER)
{
}
QString type, ident;
int heading;
};
// =====================================================================
/* ILS */
/* database id ils.ils_id */
struct MapIls
: public MapBase
{
MapIls() : MapBase(map::ILS)
{
}
QString ident, name, region;
float magvar, slope, heading, width;
int frequency /* MHz * 1000 */, range /* nm */;
atools::geo::Pos pos1, pos2, posmid; /* drawing positions for the feather */
atools::geo::Rect bounding;
bool hasDme;
atools::geo::LineString boundary() const;
};
// =====================================================================
/* Airspace boundary */
struct MapAirspace
: public MapBase
{
MapAirspace() : MapBase(map::AIRSPACE)
{
}
int minAltitude, maxAltitude;
QString name, /* Airspace name or callsign for online ATC */
comName, comType, minAltitudeType, maxAltitudeType,
multipleCode /* A-Z if duplicates exist */,
restrictiveDesignation /* Number or name to display together with type on the map only for restricted airspaces*/,
restrictiveType /* Type of restricted airspace */,
timeCode;
/* timeCode: C active continuously, including holidays - H active continuously, excluding holidays -
* N active not continuously - time not known - NULL active times announced by Notams
* U Unknown - do not display value */
QVector<int> comFrequencies;
map::MapAirspaceTypes type;
map::MapAirspaceSources src;
map::MapAirspaceId combinedId() const
{
return {id, src};
}
bool isOnline() const
{
return src & map::AIRSPACE_SRC_ONLINE;
}
bool isSim() const
{
return src & map::AIRSPACE_SRC_SIM;
}
bool isNav() const
{
return src & map::AIRSPACE_SRC_NAV;
}
bool isUser() const
{
return src & map::AIRSPACE_SRC_USER;
}
atools::geo::Rect bounding;
};
// =====================================================================
/* Mixed search result for e.g. queries on a bounding rectangle for map display or for all get nearest methods */
struct MapSearchResult
{
QList<MapAirport> airports;
QSet<int> airportIds; /* Ids used to deduplicate when merging highlights and nearest */
QList<MapRunwayEnd> runwayEnds;
QList<MapAirport> towers;
QList<MapParking> parkings;
QList<MapHelipad> helipads;
QList<MapWaypoint> waypoints;
QSet<int> waypointIds; /* Ids used to deduplicate */
QList<MapVor> vors;
QSet<int> vorIds; /* Ids used to deduplicate */
QList<MapNdb> ndbs;
QSet<int> ndbIds; /* Ids used to deduplicate */
QList<MapMarker> markers;
QList<MapIls> ils;
QList<MapAirway> airways;
QList<MapAirspace> airspaces;
/* User defined route points */
QList<MapUserpointRoute> userPointsRoute;
/* User defined waypoints */
QList<MapUserpoint> userpoints;
QSet<int> userpointIds; /* Ids used to deduplicate */
/* Logbook entries */
QList<MapLogbookEntry> logbookEntries;
QList<atools::fs::sc::SimConnectAircraft> aiAircraft;
atools::fs::sc::SimConnectUserAircraft userAircraft;
QList<atools::fs::sc::SimConnectAircraft> onlineAircraft;
QSet<int> onlineAircraftIds; /* Ids used to deduplicate */
atools::geo::Pos windPos;
/* true if none of the types exists in this result */
bool isEmpty(const map::MapObjectTypes& types = map::ALL) const;
/* Number of map objects for the given types */
int getTotalSize(const map::MapObjectTypes& types = map::ALL) const;
/* Get id and type from the result. Vector of types defines priority. true if something was found.
* id is set to -1 if nothing was found. */
bool getIdAndType(int& id, MapObjectTypes& type, const QVector<MapObjectTypes>& types) const;
/* Remove the given types only */
void clear(const MapObjectTypes& types = map::ALL);
void clearAllButFirst(const MapObjectTypes& types = map::ALL);
/* Give online airspaces/centers priority */
void moveOnlineAirspacesToFront();
map::MapSearchResult moveOnlineAirspacesToFront() const;
bool hasAirports() const
{
return !airports.isEmpty();
}
bool hasAirways() const
{
return !airways.isEmpty();
}
bool hasVor() const
{
return !vors.isEmpty();
}
bool hasNdb() const
{
return !ndbs.isEmpty();
}
bool hasUserpoints() const
{
return !userpoints.isEmpty();
}
bool hasIls() const
{
return !ils.isEmpty();
}
bool hasRunwayEnd() const
{
return !runwayEnds.isEmpty();
}
bool hasWaypoints() const
{
return !waypoints.isEmpty();
}
bool hasAirspaces() const
{
return !airspaces.isEmpty();
}
/* Special methods for the online and navdata airspaces which are stored mixed */
bool hasSimNavUserAirspaces() const;
bool hasOnlineAirspaces() const;
void clearNavdataAirspaces();
void clearOnlineAirspaces();
MapAirspace *firstSimNavUserAirspace();
MapAirspace *firstOnlineAirspace();
int numSimNavUserAirspaces() const;
int numOnlineAirspaces() const;
QList<MapAirspace> getSimNavUserAirspaces() const;
QList<MapAirspace> getOnlineAirspaces() const;
private:
template<typename T>
void clearAllButFirst(QList<T>& list);
};
QDebug operator<<(QDebug out, const map::MapSearchResult& record);
// =====================================================================
/* Mixed search result using inherited objects, Does not support aircraft objects */
struct MapSearchResultMixed
{
MapSearchResultMixed()
{
}
~MapSearchResultMixed()
{
qDeleteAll(vector);
}
/* Add all result objects to list */
void addFromResult(const map::MapSearchResult& result, const MapObjectTypes& types = map::ALL);
/* Sort objects by distance to given position from closest to farthest */
void sortByDistance(const atools::geo::Pos& pos, bool sortNearToFar);
/* Remove all objects which are more far away from pos than max distance */
void filterByDistance(const atools::geo::Pos& pos, float maxDistanceNm);
/* Disallow write access to vector */
const QVector<const map::MapBase *>& getVector() const
{
return vector;
}
template<typename TYPE>
void addCopy(const TYPE& obj)
{
vector.append(new TYPE(obj));
}
template<typename TYPE>
void addCopyAll(const QList<TYPE>& list)
{
for(const TYPE& obj : list)
addCopy(obj);
}
private:
QVector<const map::MapBase *> vector;
};
// =====================================================================
/* Range rings marker. Can be converted to QVariant */
struct RangeMarker
{
QString text; /* Text to display like VOR name and frequency */
QVector<int> ranges; /* Range ring list (nm) */
atools::geo::Pos center;
MapObjectTypes type; /* VOR, NDB, AIRPORT, etc. - used to determine color */
bool isValid() const
{
return center.isValid();
}
const atools::geo::Pos& getPosition() const
{
return center;
}
};
QDataStream& operator>>(QDataStream& dataStream, map::RangeMarker& obj);
QDataStream& operator<<(QDataStream& dataStream, const map::RangeMarker& obj);
// =====================================================================
/* Distance measurement line. Can be converted to QVariant */
struct DistanceMarker
{
QString text; /* Text to display like VOR name and frequency */
QColor color; /* Line color depends on origin (airport or navaid type */
atools::geo::Pos from, to;
float magvar;
bool isRhumbLine;
bool isValid() const
{
return from.isValid();
}
const atools::geo::Pos& getPosition() const
{
return to;
}
};
QDataStream& operator>>(QDataStream& dataStream, map::DistanceMarker& obj);
QDataStream& operator<<(QDataStream& dataStream, const map::DistanceMarker& obj);
// =====================================================================
/* All information for complete traffic pattern structure */
struct TrafficPattern
{
QString airportIcao, runwayName;
QColor color;
bool turnRight,
base45Degree /* calculate base turn from 45 deg after threshold */,
showEntryExit /* Entry and exit indicators */;
int runwayLength; /* ft Does not include displaced threshold */
float downwindDistance, baseDistance; /* NM */
float heading; /* degree true final course*/
float magvar;
atools::geo::Pos position; /* Threshold position (end of final) and runway altitude MSL */
bool isValid() const
{
return position.isValid();
}
const atools::geo::Pos& getPosition() const
{
return position;
}
};
QDataStream& operator>>(QDataStream& dataStream, map::TrafficPattern& obj);
QDataStream& operator<<(QDataStream& dataStream, const map::TrafficPattern& obj);
// =====================================================================
/* All information for a hold */
struct Hold
{
QString navIdent; /* Only for display purposes */
map::MapObjectTypes navType;
QColor color;
bool turnLeft; /* Standard is right */
float minutes, speedKts; /* Used to calculate segment length - speed in knots */
float courseTrue; /* degree true inbound course to fix */
float magvar; /* Taken from environment or navaid */
atools::geo::Pos position; /* Hold reference position and altitude */
float magHeading() const;
float distance() const
{
return speedKts * minutes / 60.f;
}
bool isValid() const
{
return position.isValid();
}
const atools::geo::Pos& getPosition() const
{
return position;
}
};
QDataStream& operator>>(QDataStream& dataStream, map::Hold& obj);
QDataStream& operator<<(QDataStream& dataStream, const map::Hold& obj);
// =====================================================================
/* Stores last METARs to avoid unneeded updates in widget */
struct WeatherContext
{
atools::fs::weather::MetarResult fsMetar, ivaoMetar, noaaMetar;
bool isAsDeparture = false, isAsDestination = false;
QString asMetar, asType, vatsimMetar, ident;
bool isEmpty() const
{
return fsMetar.isEmpty() && asMetar.isEmpty() && noaaMetar.isEmpty() && vatsimMetar.isEmpty() &&
ivaoMetar.isEmpty();
}
};
QDebug operator<<(QDebug out, const map::WeatherContext& record);
// =====================================================================================
/* Database type strings to GUI strings and map objects to display strings */
QString navTypeName(const QString& type);
const QString& navTypeNameVor(const QString& type);
const QString& navTypeNameVorLong(const QString& type);
const QString& navTypeNameNdb(const QString& type);
const QString& navTypeNameWaypoint(const QString& type);
QString ilsText(const map::MapIls& ils);
QString ilsType(const MapIls& ils);
QString ilsTextShort(const MapIls& ils);
QString ilsTextShort(QString ident, QString name, bool gs, bool dme);
QString edgeLights(const QString& type);
QString patternDirection(const QString& type);
const QString& navName(const QString& type);
const QString& surfaceName(const QString& surface);
const QString& parkingGateName(const QString& gate);
const QString& parkingRampName(const QString& ramp);
const QString& parkingTypeName(const QString& type);
const QString& parkingName(const QString& name);
QString parkingNameNumberType(const map::MapParking& parking);
QString startType(const map::MapStart& start);
/* Split runway name into parts and return true if name matches a runway number */
bool runwayNameSplit(const QString& name, int *number = nullptr, QString *designator = nullptr);
bool runwayNameSplit(const QString& name, QString *number = nullptr, QString *designator = nullptr);
/* Get the closes matching runway name from the list of airport runways or empty if none */
QString runwayBestFit(const QString& procRunwayName, const QStringList& airportRunwayNames);
/* Gives all variants of the runway (+1 and -1) plus the original one as the first in the list */
QStringList runwayNameVariants(QString name);
/* Gives all variants of the runway (+1 and -1) plus the original one as the first in the list for an
* ARINC name like N32 or I19-Y */
QStringList arincNameNameVariants(const QString& name);
/* Compare runway numbers fuzzy */
bool runwayAlmostEqual(const QString& name1, const QString& name2);
/* Parking name from PLN to database name */
const QString& parkingDatabaseName(const QString& name);
/* Get short name for a parking spot */
QString parkingShortName(const QString& name);
/* Parking description as needed in the PLN files */
QString parkingNameForFlightplan(const MapParking& parking);
const QString& airspaceTypeToString(map::MapAirspaceTypes type);
const QString& airspaceFlagToString(map::MapAirspaceFlags type);
const QString& airspaceRemark(map::MapAirspaceTypes type);
int airspaceDrawingOrder(map::MapAirspaceTypes type);
QString airspaceSourceText(map::MapAirspaceSources src);
map::MapAirspaceTypes airspaceTypeFromDatabase(const QString& type);
const QString& airspaceTypeToDatabase(map::MapAirspaceTypes type);
QString airwayTypeToShortString(map::MapAirwayType type);
QString airwayTypeToString(map::MapAirwayType type);
MapAirwayType airwayTypeFromString(const QString& typeStr);
QString comTypeName(const QString& type);
QString airportText(const map::MapAirport& airport, int elideName = 1000);
QString airportTextShort(const map::MapAirport& airport);