mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-27 21:24:47 +01:00
parent
932aadee5f
commit
321357b74d
@ -112,6 +112,7 @@ HEADERS += src/common/config.h \
|
|||||||
src/GUI/pngexportdialog.h \
|
src/GUI/pngexportdialog.h \
|
||||||
src/GUI/timezoneinfo.h \
|
src/GUI/timezoneinfo.h \
|
||||||
src/GUI/passwordedit.h \
|
src/GUI/passwordedit.h \
|
||||||
|
src/data/twonavparser.h \
|
||||||
src/map/proj/polyconic.h \
|
src/map/proj/polyconic.h \
|
||||||
src/map/proj/webmercator.h \
|
src/map/proj/webmercator.h \
|
||||||
src/map/proj/transversemercator.h \
|
src/map/proj/transversemercator.h \
|
||||||
@ -312,6 +313,7 @@ SOURCES += src/main.cpp \
|
|||||||
src/GUI/pngexportdialog.cpp \
|
src/GUI/pngexportdialog.cpp \
|
||||||
src/GUI/projectioncombobox.cpp \
|
src/GUI/projectioncombobox.cpp \
|
||||||
src/GUI/passwordedit.cpp \
|
src/GUI/passwordedit.cpp \
|
||||||
|
src/data/twonavparser.cpp \
|
||||||
src/map/proj/polyconic.cpp \
|
src/map/proj/polyconic.cpp \
|
||||||
src/map/proj/webmercator.cpp \
|
src/map/proj/webmercator.cpp \
|
||||||
src/map/proj/transversemercator.cpp \
|
src/map/proj/transversemercator.cpp \
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QLineF>
|
|
||||||
#include "gpxparser.h"
|
#include "gpxparser.h"
|
||||||
#include "tcxparser.h"
|
#include "tcxparser.h"
|
||||||
#include "csvparser.h"
|
#include "csvparser.h"
|
||||||
@ -20,6 +19,7 @@
|
|||||||
#include "ov2parser.h"
|
#include "ov2parser.h"
|
||||||
#include "itnparser.h"
|
#include "itnparser.h"
|
||||||
#include "onmoveparsers.h"
|
#include "onmoveparsers.h"
|
||||||
|
#include "twonavparser.h"
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
|
|
||||||
|
|
||||||
@ -44,10 +44,11 @@ static OV2Parser ov2;
|
|||||||
static ITNParser itn;
|
static ITNParser itn;
|
||||||
static OMDParser omd;
|
static OMDParser omd;
|
||||||
static GHPParser ghp;
|
static GHPParser ghp;
|
||||||
|
static TwoNavParser twonav;
|
||||||
|
|
||||||
static QMap<QString, Parser*> parsers()
|
static QMultiMap<QString, Parser*> parsers()
|
||||||
{
|
{
|
||||||
QMap<QString, Parser*> map;
|
QMultiMap<QString, Parser*> map;
|
||||||
|
|
||||||
map.insert("gpx", &gpx);
|
map.insert("gpx", &gpx);
|
||||||
map.insert("tcx", &tcx);
|
map.insert("tcx", &tcx);
|
||||||
@ -72,11 +73,14 @@ static QMap<QString, Parser*> parsers()
|
|||||||
map.insert("itn", &itn);
|
map.insert("itn", &itn);
|
||||||
map.insert("omd", &omd);
|
map.insert("omd", &omd);
|
||||||
map.insert("ghp", &ghp);
|
map.insert("ghp", &ghp);
|
||||||
|
map.insert("trk", &twonav);
|
||||||
|
map.insert("rte", &twonav);
|
||||||
|
map.insert("wpt", &twonav);
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, Parser*> Data::_parsers = parsers();
|
QMultiMap<QString, Parser*> Data::_parsers = parsers();
|
||||||
|
|
||||||
void Data::processData(QList<TrackData> &trackData, QList<RouteData> &routeData)
|
void Data::processData(QList<TrackData> &trackData, QList<RouteData> &routeData)
|
||||||
{
|
{
|
||||||
@ -101,16 +105,21 @@ Data::Data(const QString &fileName, bool tryUnknown)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, Parser*>::iterator it;
|
QMultiMap<QString, Parser*>::iterator it;
|
||||||
if ((it = _parsers.find(fi.suffix().toLower())) != _parsers.end()) {
|
QString suffix(fi.suffix().toLower());
|
||||||
if (it.value()->parse(&file, trackData, routeData, _polygons,
|
if ((it = _parsers.find(suffix)) != _parsers.end()) {
|
||||||
_waypoints)) {
|
while (it != _parsers.end() && it.key() == suffix) {
|
||||||
processData(trackData, routeData);
|
if (it.value()->parse(&file, trackData, routeData, _polygons,
|
||||||
_valid = true;
|
_waypoints)) {
|
||||||
return;
|
processData(trackData, routeData);
|
||||||
} else {
|
_valid = true;
|
||||||
_errorLine = it.value()->errorLine();
|
return;
|
||||||
_errorString = it.value()->errorString();
|
} else {
|
||||||
|
_errorLine = it.value()->errorLine();
|
||||||
|
_errorString = it.value()->errorString();
|
||||||
|
}
|
||||||
|
file.reset();
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
} else if (tryUnknown) {
|
} else if (tryUnknown) {
|
||||||
for (it = _parsers.begin(); it != _parsers.end(); it++) {
|
for (it = _parsers.begin(); it != _parsers.end(); it++) {
|
||||||
@ -137,6 +146,7 @@ QString Data::formats()
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
qApp->translate("Data", "Supported files") + " (" + filter().join(" ") + ");;"
|
qApp->translate("Data", "Supported files") + " (" + filter().join(" ") + ");;"
|
||||||
|
+ qApp->translate("Data", "TwoNav files") + " (*.rte *.trk *.wpt);;"
|
||||||
+ qApp->translate("Data", "CSV files") + " (*.csv);;"
|
+ qApp->translate("Data", "CSV files") + " (*.csv);;"
|
||||||
+ qApp->translate("Data", "CUP files") + " (*.cup);;"
|
+ qApp->translate("Data", "CUP files") + " (*.cup);;"
|
||||||
+ qApp->translate("Data", "FIT files") + " (*.fit);;"
|
+ qApp->translate("Data", "FIT files") + " (*.fit);;"
|
||||||
@ -162,7 +172,7 @@ QStringList Data::filter()
|
|||||||
{
|
{
|
||||||
QStringList filter;
|
QStringList filter;
|
||||||
|
|
||||||
for (QMap<QString, Parser*>::iterator it = _parsers.begin();
|
for (QMultiMap<QString, Parser*>::iterator it = _parsers.begin();
|
||||||
it != _parsers.end(); it++)
|
it != _parsers.end(); it++)
|
||||||
filter << "*." + it.key();
|
filter << "*." + it.key();
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define DATA_H
|
#define DATA_H
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMap>
|
#include <QMultiMap>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include "waypoint.h"
|
#include "waypoint.h"
|
||||||
@ -39,7 +39,7 @@ private:
|
|||||||
QList<Area> _polygons;
|
QList<Area> _polygons;
|
||||||
QVector<Waypoint> _waypoints;
|
QVector<Waypoint> _waypoints;
|
||||||
|
|
||||||
static QMap<QString, Parser*> _parsers;
|
static QMultiMap<QString, Parser*> _parsers;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DATA_H
|
#endif // DATA_H
|
||||||
|
217
src/data/twonavparser.cpp
Normal file
217
src/data/twonavparser.cpp
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
#include "common/textcodec.h"
|
||||||
|
#include "map/gcs.h"
|
||||||
|
#include "twonavparser.h"
|
||||||
|
|
||||||
|
static double lon(const QString &str)
|
||||||
|
{
|
||||||
|
QStringList l(str.split(QChar(0xBA)));
|
||||||
|
if (l.size() < 2)
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
double val = l.at(0).toDouble(&ok);
|
||||||
|
if (!ok)
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
if (l.at(1) == "W")
|
||||||
|
return -val;
|
||||||
|
else if (l.at(1) == "E")
|
||||||
|
return val;
|
||||||
|
else
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double lat(const QString &str)
|
||||||
|
{
|
||||||
|
QStringList l(str.split(QChar(0xBA)));
|
||||||
|
if (l.size() < 2)
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
double val = l.at(0).toDouble(&ok);
|
||||||
|
if (!ok)
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
if (l.at(1) == "S")
|
||||||
|
return -val;
|
||||||
|
else if (l.at(1) == "N")
|
||||||
|
return val;
|
||||||
|
else
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QDateTime timestamp(const QString &dateStr, const QString &timeStr)
|
||||||
|
{
|
||||||
|
QLocale l("C");
|
||||||
|
|
||||||
|
QDate date(l.toDate(dateStr, "dd-MMM-yy"));
|
||||||
|
if (date.isValid())
|
||||||
|
date = date.addYears(100);
|
||||||
|
else {
|
||||||
|
date = l.toDate(dateStr, "dd-MMM-yyyy");
|
||||||
|
if (!date.isValid())
|
||||||
|
return QDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTime time(l.toTime(timeStr, "H:m:s.z"));
|
||||||
|
if (!time.isValid()) {
|
||||||
|
time = l.toTime(timeStr, "H:m:s");
|
||||||
|
if (!time.isValid())
|
||||||
|
return QDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QDateTime(date, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TwoNavParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||||
|
QList<RouteData> &routes, QList<Area> &polygons,
|
||||||
|
QVector<Waypoint> &waypoints)
|
||||||
|
{
|
||||||
|
Q_UNUSED(polygons);
|
||||||
|
TextCodec codec;
|
||||||
|
GCS gcs;
|
||||||
|
bool ok, route = false, track = false, waypoint = false;
|
||||||
|
|
||||||
|
_errorLine = 1;
|
||||||
|
_errorString.clear();
|
||||||
|
|
||||||
|
quint8 bom[3];
|
||||||
|
if (file->peek((char*)bom, sizeof(bom)) == sizeof(bom)
|
||||||
|
&& bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) {
|
||||||
|
file->seek(3);
|
||||||
|
codec = TextCodec(65001);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!file->atEnd()) {
|
||||||
|
QByteArray line(file->readLine().trimmed());
|
||||||
|
if (!line.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (line.at(0)) {
|
||||||
|
case 'B':
|
||||||
|
{line.remove(0, 1);
|
||||||
|
QByteArray encoding(line.trimmed());
|
||||||
|
if (encoding == "UTF-8")
|
||||||
|
codec = TextCodec(65001);
|
||||||
|
else {
|
||||||
|
_errorString = "Invalid/unknown encoding";
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
{line.remove(0, 1);
|
||||||
|
QString datum(line.trimmed());
|
||||||
|
gcs = GCS::gcs(datum);
|
||||||
|
if (gcs.isNull()) {
|
||||||
|
_errorString = "Invalid/unknown datum";
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
{line.remove(0, 1);
|
||||||
|
QByteArray cs(line.trimmed());
|
||||||
|
if (cs != "1") {
|
||||||
|
_errorString = "Invalid/unknown coordinate system";
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
{QStringList list(codec.toString(line).split(' ',
|
||||||
|
Qt::SkipEmptyParts));
|
||||||
|
if (list.size() < 4) {
|
||||||
|
_errorString = "Parse error";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Coordinates c(lon(list.at(3)), lat(list.at(2)));
|
||||||
|
if (!c.isValid()) {
|
||||||
|
_errorString = "Invalid coordinates";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Trackpoint t(gcs.toWGS84(c));
|
||||||
|
|
||||||
|
if (list.size() > 5) {
|
||||||
|
QDateTime ts(timestamp(list.at(4), list.at(5)));
|
||||||
|
if (!ts.isValid()) {
|
||||||
|
_errorString = "Invalid date/time";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
t.setTimestamp(ts);
|
||||||
|
}
|
||||||
|
if (list.size() > 7) {
|
||||||
|
qreal elevation = list.at(7).toDouble(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
_errorString = "Invalid altitude";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
t.setElevation(elevation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!track) {
|
||||||
|
tracks.append(TrackData());
|
||||||
|
tracks.last().append(SegmentData());
|
||||||
|
track = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracks.last().last().append(t);}
|
||||||
|
break;
|
||||||
|
case 'W':
|
||||||
|
{QStringList list(codec.toString(line).split(' ',
|
||||||
|
Qt::SkipEmptyParts));
|
||||||
|
if (list.size() < 5) {
|
||||||
|
_errorString = "Parse error";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Coordinates c(lon(list.at(4)), lat(list.at(3)));
|
||||||
|
if (!c.isValid()) {
|
||||||
|
_errorString = "Invalid coordinates";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Waypoint w(gcs.toWGS84(c));
|
||||||
|
w.setName(list.at(1));
|
||||||
|
|
||||||
|
if (list.size() > 6) {
|
||||||
|
QDateTime ts(timestamp(list.at(5), list.at(6)));
|
||||||
|
if (!ts.isValid()) {
|
||||||
|
_errorString = "Invalid date/time";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
w.setTimestamp(ts);
|
||||||
|
}
|
||||||
|
if (list.size() > 7) {
|
||||||
|
qreal elevation = list.at(7).toDouble(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
_errorString = "Invalid altitude";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
w.setElevation(elevation);
|
||||||
|
}
|
||||||
|
if (list.size() > 8)
|
||||||
|
w.setDescription(list.mid(8).join(' '));
|
||||||
|
|
||||||
|
if (route)
|
||||||
|
routes.last().append(w);
|
||||||
|
else {
|
||||||
|
waypoints.append(w);
|
||||||
|
waypoint = true;
|
||||||
|
}}
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
{QStringList list(codec.toString(line).split(',',
|
||||||
|
Qt::SkipEmptyParts));
|
||||||
|
routes.append(RouteData());
|
||||||
|
routes.last().setName(list.at(1));
|
||||||
|
route = true;}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_errorLine++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(waypoint | route | track)) {
|
||||||
|
_errorString = "No valid data found";
|
||||||
|
return false;
|
||||||
|
} else
|
||||||
|
return true;
|
||||||
|
}
|
21
src/data/twonavparser.h
Normal file
21
src/data/twonavparser.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef TWONAVPARSER_H
|
||||||
|
#define TWONAVPARSER_H
|
||||||
|
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
class TwoNavParser : public Parser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TwoNavParser() : _errorLine(0) {}
|
||||||
|
|
||||||
|
bool parse(QFile *file, QList<TrackData> &tracks, QList<RouteData> &routes,
|
||||||
|
QList<Area> &polygons, QVector<Waypoint> &waypoints);
|
||||||
|
QString errorString() const {return _errorString;}
|
||||||
|
int errorLine() const {return _errorLine;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString _errorString;
|
||||||
|
int _errorLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TWONAVPARSER_H
|
Loading…
Reference in New Issue
Block a user