Enroute Flight Navigation
A navigation app for VFR pilots
TrafficDataSource_OgnParser.h
1/***************************************************************************
2 * Copyright (C) 2021-2025 by Stefan Kebekus *
3 * stefan.kebekus@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#pragma once
22
23#include <QGeoCoordinate>
24#include <QStringView>
25
26#include "TrafficFactorAircraftType.h"
27#include "units/Angle.h"
28#include "units/Speed.h"
29
30using namespace Qt::Literals::StringLiterals;
31
32namespace Traffic::Ogn {
33Q_NAMESPACE
34struct OgnMessage;
35
50public:
51 static void parseAprsisMessage(OgnMessage& ognMessage);
52 static QString formatLoginString(QStringView callSign,
53 const QGeoCoordinate &receiveLocation,
54 unsigned int receiveRadius,
55 QStringView appName,
56 QStringView appVersion);
57 static QString formatPositionReport(QStringView callSign,
58 const QGeoCoordinate &coordinate,
59 double course,
60 double speed,
61 double altitude,
62 Traffic::AircraftType aircraftType);
63
64private:
65 static QString formatFilter(const QGeoCoordinate &receiveLocation, unsigned int receiveRadius);
66 static QString formatLatitude(double latitude);
67 static QString formatLongitude(double longitude);
68 static QString calculatePassword(QStringView callSign);
69 static double decodeLatitude(QStringView nmeaLatitude, QChar latitudeDirection, QChar latEnhancement);
70 static double decodeLongitude(QStringView nmeaLongitude, QChar longitudeDirection, QChar lonEnhancement);
71 static void parseTrafficReport(OgnMessage &ognMessage, QStringView header, QStringView body);
72 static void parseCommentMessage(OgnMessage& ognMessage);
73 static void parseStatusMessage(OgnMessage &ognMessage, QStringView header, QStringView body);
74};
75
76enum class OgnMessageType
77{
78 UNKNOWN,
79 TRAFFIC_REPORT,
80 COMMENT,
81 STATUS,
82 WEATHER,
83};
84Q_ENUM_NS(OgnMessageType);
85
86// see http://wiki.glidernet.org/wiki:ogn-flavoured-aprs
87enum class OgnAddressType
88{
89 UNKNOWN = 0,
90 ICAO = 1,
91 FLARM = 2,
92 OGN_TRACKER = 3,
93};
94Q_ENUM_NS(OgnAddressType);
95
96enum class OgnSymbol
97{
98 UNKNOWN,
99 GLIDER,
100 HELICOPTER,
101 PARACHUTE,
102 AIRCRAFT,
103 JET,
104 BALLOON,
105 STATIC_OBJECT,
106 UAV,
107 WEATHERSTATION,
108};
109Q_ENUM_NS(OgnSymbol);
110
111struct OgnMessage
112{
113 QString sentence; // e.g. "FLRDDE626>APRS,qAS,EGHL:/074548h5111.32N/00102.04W'086/007/A=000607 id0ADDE626 -019fpm +0.0rot 5.5dB 3e -4.3kHz"
114 OgnMessageType type = OgnMessageType::UNKNOWN; // e.g. OgnMessageType::TRAFFIC_REPORT
115
116 QStringView sourceId; // like ENROUTE12345
117 QStringView timestamp; // hhmmss
118 QGeoCoordinate coordinate;
119 OgnSymbol symbol = OgnSymbol::UNKNOWN; // the symbol that should be shown on the map, typically Aircraft.
120
121 Units::Angle course; // course
122 Units::Speed speed; // speed
123 QStringView aircraftID; // aircraft ID, e.g. "id0ADDE626"
124 double verticalSpeed = {}; // in m/s
125 QStringView rotationRate; // like "+0.0rot"
126 QStringView signalStrength; // like "5.5dB"
127 QStringView errorCount; // like "3e"
128 QStringView frequencyOffset;// like "-4.3kHz"
129 QStringView squawk; // like "sq2244"
130 QStringView flightlevel; // like "FL350.00"
131 QStringView flightnumber; // Flight number, e.g., "DLH2AV" or "SRR6119"
132 QStringView gpsInfo; // like "gps:0.0"
133 Traffic::AircraftType aircraftType = Traffic::AircraftType::unknown; // e.g., "Glider", "Tow Plane", etc.
134 OgnAddressType addressType = OgnAddressType::UNKNOWN; // e.g., "ICAO", "FLARM", "OGN Tracker"
135 QStringView address; // like "4D21C2"
136 bool stealthMode = false; // true if the aircraft shall be hidden
137 bool noTrackingFlag = false;// true if the aircraft shall not be tracked
138
139 uint32_t wind_direction = {}; // degree 0..359
140 uint32_t wind_speed = {}; // m/s
141 uint32_t wind_gust_speed = {}; // m/s
142 uint32_t temperature = {}; // degree C
143 uint32_t humidity = {}; // percent
144 double pressure = {}; // hPa
145
146 void reset()
147 {
148 sentence.clear();
149 type = OgnMessageType::UNKNOWN;
150 sourceId.truncate(0);
151 timestamp.truncate(0);
152 coordinate = QGeoCoordinate();
153 symbol = OgnSymbol::UNKNOWN;
154 course = {};
155 speed = {};
156 aircraftID.truncate(0);
157 verticalSpeed = 0.0;
158 rotationRate.truncate(0);
159 signalStrength.truncate(0);
160 errorCount.truncate(0);
161 frequencyOffset.truncate(0);
162 squawk.truncate(0);
163 flightlevel.truncate(0);
164 flightnumber.truncate(0);
165 gpsInfo.truncate(0);
166 aircraftType = Traffic::AircraftType::unknown;
167 addressType = OgnAddressType::UNKNOWN;
168 address.truncate(0);
169 stealthMode = false;
170 noTrackingFlag = false;
171 wind_direction = 0;
172 wind_speed = 0;
173 wind_gust_speed = 0;
174 temperature = 0;
175 humidity = 0;
176 pressure = 0.0;
177 }
178};
179}
Parser for OGN glidernet.org traffic receiver.