mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Added support for IGC routes (C records)
This commit is contained in:
parent
818fa11fd3
commit
81a9743064
@ -17,65 +17,65 @@ static int str2int(const char *str, size_t len)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool readLat(const char *line, qreal &lat)
|
static bool readLat(const char *data, qreal &lat)
|
||||||
{
|
{
|
||||||
int d = str2int(line + 7, 2);
|
int d = str2int(data, 2);
|
||||||
int mi = str2int(line + 9, 2);
|
int mi = str2int(data + 2, 2);
|
||||||
int mf = str2int(line + 11, 3);
|
int mf = str2int(data + 4, 3);
|
||||||
if (d < 0 || mi < 0 || mf < 0)
|
if (d < 0 || mi < 0 || mf < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!(line[14] == 'N' || line[14] == 'S'))
|
if (!(data[7] == 'N' || data[7] == 'S'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
lat = d + (((qreal)mi + (qreal)mf/1000) / 60);
|
lat = d + (((qreal)mi + (qreal)mf/1000) / 60);
|
||||||
if (lat > 90)
|
if (lat > 90)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (line[14] == 'S')
|
if (data[7] == 'S')
|
||||||
lat = -lat;
|
lat = -lat;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool readLon(const char *line, qreal &lon)
|
static bool readLon(const char *data, qreal &lon)
|
||||||
{
|
{
|
||||||
int d = str2int(line + 15, 3);
|
int d = str2int(data, 3);
|
||||||
int mi = str2int(line + 18, 2);
|
int mi = str2int(data + 3, 2);
|
||||||
int mf = str2int(line + 20, 3);
|
int mf = str2int(data + 5, 3);
|
||||||
if (d < 0 || mi < 0 || mf < 0)
|
if (d < 0 || mi < 0 || mf < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!(line[23] == 'E' || line[23] == 'W'))
|
if (!(data[8] == 'E' || data[8] == 'W'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
lon = d + (((qreal)mi + (qreal)mf/1000) / 60);
|
lon = d + (((qreal)mi + (qreal)mf/1000) / 60);
|
||||||
if (lon > 180)
|
if (lon > 180)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (line[23] == 'W')
|
if (data[8] == 'W')
|
||||||
lon = -lon;
|
lon = -lon;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool readAltitude(const char *line, qreal &ele)
|
static bool readAltitude(const char *data, qreal &ele)
|
||||||
{
|
{
|
||||||
int p;
|
int p;
|
||||||
|
|
||||||
if (!(line[24] == 'A' || line[24] == 'V'))
|
if (!(data[0] == 'A' || data[0] == 'V'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (line[25] == '-')
|
if (data[1] == '-')
|
||||||
p = str2int(line + 26, 4);
|
p = str2int(data + 2, 4);
|
||||||
else
|
else
|
||||||
p = str2int(line + 25, 5);
|
p = str2int(data + 1, 5);
|
||||||
|
|
||||||
int g = str2int(line + 30, 5);
|
int g = str2int(data + 6, 5);
|
||||||
if (p < 0 || g < 0)
|
if (p < 0 || g < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (line[24] == 'A')
|
if (data[0] == 'A')
|
||||||
ele = (qreal)g;
|
ele = (qreal)g;
|
||||||
else
|
else
|
||||||
ele = NAN;
|
ele = NAN;
|
||||||
@ -83,6 +83,20 @@ static bool readAltitude(const char *line, qreal &ele)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool readTimestamp(const char *data, QTime &time)
|
||||||
|
{
|
||||||
|
int h = str2int(data, 2);
|
||||||
|
int m = str2int(data + 2, 2);
|
||||||
|
int s = str2int(data + 4, 2);
|
||||||
|
|
||||||
|
if (h < 0 || m < 0 || s < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
time = QTime(h, m, s);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool readARecord(const char *line, qint64 len)
|
static bool readARecord(const char *line, qint64 len)
|
||||||
{
|
{
|
||||||
if (len < 9 || line[0] != 'A')
|
if (len < 9 || line[0] != 'A')
|
||||||
@ -120,60 +134,82 @@ bool IGCParser::readHRecord(const char *line, qint64 len)
|
|||||||
bool IGCParser::readBRecord(const char *line, qint64 len)
|
bool IGCParser::readBRecord(const char *line, qint64 len)
|
||||||
{
|
{
|
||||||
qreal lat, lon, ele;
|
qreal lat, lon, ele;
|
||||||
QDateTime timestamp;
|
QTime time;
|
||||||
|
|
||||||
|
|
||||||
if (len < 35)
|
if (len < 35)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int h = str2int(line + 1, 2);
|
if (!readTimestamp(line + 1, time)) {
|
||||||
int m = str2int(line + 3, 2);
|
_errorString = "Invalid timestamp";
|
||||||
int s = str2int(line + 5, 2);
|
|
||||||
|
|
||||||
if (h <0 || m < 0 || s < 0) {
|
|
||||||
_errorString = "Invalid timestamp";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QTime time = QTime(h, m, s);
|
|
||||||
if (time < _time)
|
|
||||||
_date.addDays(1);
|
|
||||||
_time = time;
|
|
||||||
timestamp = QDateTime(_date, _time, Qt::UTC);
|
|
||||||
|
|
||||||
if (!readLat(line, lat)) {
|
if (!readLat(line + 7, lat)) {
|
||||||
_errorString = "Invalid latitude";
|
_errorString = "Invalid latitude";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!readLon(line, lon)) {
|
if (!readLon(line + 15, lon)) {
|
||||||
_errorString = "Invalid longitude";
|
_errorString = "Invalid longitude";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!readAltitude(line, ele)) {
|
if (!readAltitude(line + 24, ele)) {
|
||||||
_errorString = "Invalid altitude";
|
_errorString = "Invalid altitude";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (time < _time)
|
||||||
|
_date.addDays(1);
|
||||||
|
_time = time;
|
||||||
|
|
||||||
Trackpoint t(Coordinates(lon, lat));
|
Trackpoint t(Coordinates(lon, lat));
|
||||||
t.setTimestamp(timestamp);
|
t.setTimestamp(QDateTime(_date, _time, Qt::UTC));
|
||||||
t.setElevation(ele);
|
t.setElevation(ele);
|
||||||
_tracks.last().append(t);
|
_tracks.last().append(t);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IGCParser::readCRecord(const char *line, qint64 len)
|
||||||
|
{
|
||||||
|
qreal lat, lon;
|
||||||
|
|
||||||
|
|
||||||
|
if (len < 18)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!readLat(line + 1, lat)) {
|
||||||
|
_errorString = "Invalid latitude";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!readLon(line + 9, lon)) {
|
||||||
|
_errorString = "Invalid longitude";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(lat == 0 && lon == 0)) {
|
||||||
|
QByteArray ba(line + 18, len - 19);
|
||||||
|
|
||||||
|
Waypoint w(Coordinates(lon, lat));
|
||||||
|
w.setName(QString(ba.trimmed()));
|
||||||
|
_routes.last().append(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool IGCParser::loadFile(QFile *file)
|
bool IGCParser::loadFile(QFile *file)
|
||||||
{
|
{
|
||||||
qint64 len;
|
qint64 len;
|
||||||
char line[76 + 2 + 1 + 1];
|
char line[76 + 2 + 1 + 1];
|
||||||
|
bool route = false, track = false;
|
||||||
|
|
||||||
|
|
||||||
_errorLine = 1;
|
_errorLine = 1;
|
||||||
_errorString.clear();
|
_errorString.clear();
|
||||||
|
|
||||||
_tracks.append(TrackData());
|
|
||||||
_time = QTime(0, 0);
|
|
||||||
|
|
||||||
|
|
||||||
while ((len = file->readLine(line, sizeof(line))) > 0) {
|
while ((len = file->readLine(line, sizeof(line))) > 0) {
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
_errorString = "I/O error";
|
_errorString = "I/O error";
|
||||||
@ -192,11 +228,24 @@ bool IGCParser::loadFile(QFile *file)
|
|||||||
if (line[0] == 'H') {
|
if (line[0] == 'H') {
|
||||||
if (!readHRecord(line, len))
|
if (!readHRecord(line, len))
|
||||||
return false;
|
return false;
|
||||||
|
} else if (line[0] == 'C') {
|
||||||
|
if (route) {
|
||||||
|
if (!readCRecord(line, len))
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
route = true;
|
||||||
|
_routes.append(RouteData());
|
||||||
|
}
|
||||||
} else if (line[0] == 'B') {
|
} else if (line[0] == 'B') {
|
||||||
if (_date.isNull()) {
|
if (_date.isNull()) {
|
||||||
_errorString = "Missing date header";
|
_errorString = "Missing date header";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!track) {
|
||||||
|
_tracks.append(TrackData());
|
||||||
|
_time = QTime(0, 0);
|
||||||
|
track = true;
|
||||||
|
}
|
||||||
if (!readBRecord(line, len))
|
if (!readBRecord(line, len))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool readHRecord(const char *line, qint64 len);
|
bool readHRecord(const char *line, qint64 len);
|
||||||
bool readBRecord(const char *line, qint64 len);
|
bool readBRecord(const char *line, qint64 len);
|
||||||
|
bool readCRecord(const char *line, qint64 len);
|
||||||
|
|
||||||
int _errorLine;
|
int _errorLine;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
|
Loading…
Reference in New Issue
Block a user