diff --git a/gpxsee.pro b/gpxsee.pro
index 0b117c8d..d1db4a9e 100644
--- a/gpxsee.pro
+++ b/gpxsee.pro
@@ -118,6 +118,7 @@ HEADERS += src/common/config.h \
src/GUI/pngexportdialog.h \
src/GUI/timezoneinfo.h \
src/GUI/passwordedit.h \
+ src/data/gpsdumpparser.h \
src/data/style.h \
src/data/twonavparser.h \
src/map/ENC/attributes.h \
@@ -338,6 +339,7 @@ SOURCES += src/main.cpp \
src/GUI/pngexportdialog.cpp \
src/GUI/projectioncombobox.cpp \
src/GUI/passwordedit.cpp \
+ src/data/gpsdumpparser.cpp \
src/data/twonavparser.cpp \
src/map/ENC/atlasdata.cpp \
src/map/ENC/mapdata.cpp \
diff --git a/pkg/linux/gpxsee.desktop b/pkg/linux/gpxsee.desktop
index 2db957a9..46c397f7 100644
--- a/pkg/linux/gpxsee.desktop
+++ b/pkg/linux/gpxsee.desktop
@@ -16,4 +16,4 @@ Icon=gpxsee
Terminal=false
Type=Application
Categories=Graphics;Viewer;Education;Geography;Maps;Sports;Qt
-MimeType=application/gpx+xml;application/vnd.garmin.tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/vnd.groundspeak.loc+xml;application/vnd.sigma.slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/vnd.suunto.sml+xml;image/jpeg;text/csv;application/vnd.garmin.img;application/vnd.garmin.jnx;application/vnd.garmin.gmap+xml;image/vnd.maptech.kap;application/vnd.oziexplorer.map;application/vnd.mapbox.mbtiles;application/vnd.twonav.rmap;application/vnd.trekbuddy.tba;application/vnd.gpxsee.map+xml;application/x-tar;image/tiff;application/vnd.google-earth.kmz;application/vnd.alpinequest.aqm;application/vnd.cgtk.gemf;application/vnd.rmaps.sqlite;application/vnd.osmdroid.sqlite;application/vnd.mapsforge.map;application/vnd.tomtom.ov2;application/vnd.tomtom.itn;application/vnd.esri.wld;application/vnd.onmove.omd;application/vnd.onmove.ghp;application/vnd.memory-map.qct;application/vnd.twonav.trk;application/vnd.twonav.rte;application/vnd.twonav.wpt;application/vnd.orux.map+xml;application/vnd.iho.s57-data;application/vnd.iho.s57-catalogue
+MimeType=application/gpx+xml;application/vnd.garmin.tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/vnd.groundspeak.loc+xml;application/vnd.sigma.slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/vnd.suunto.sml+xml;image/jpeg;text/csv;application/vnd.garmin.img;application/vnd.garmin.jnx;application/vnd.garmin.gmap+xml;image/vnd.maptech.kap;application/vnd.oziexplorer.map;application/vnd.mapbox.mbtiles;application/vnd.twonav.rmap;application/vnd.trekbuddy.tba;application/vnd.gpxsee.map+xml;application/x-tar;image/tiff;application/vnd.google-earth.kmz;application/vnd.alpinequest.aqm;application/vnd.cgtk.gemf;application/vnd.rmaps.sqlite;application/vnd.osmdroid.sqlite;application/vnd.mapsforge.map;application/vnd.tomtom.ov2;application/vnd.tomtom.itn;application/vnd.esri.wld;application/vnd.onmove.omd;application/vnd.onmove.ghp;application/vnd.memory-map.qct;application/vnd.twonav.trk;application/vnd.twonav.rte;application/vnd.twonav.wpt;application/vnd.orux.map+xml;application/vnd.iho.s57-data;application/vnd.iho.s57-catalogue;application/vnd.gpsdump.wpt
diff --git a/pkg/linux/gpxsee.xml b/pkg/linux/gpxsee.xml
index a346a170..3e1fffa5 100644
--- a/pkg/linux/gpxsee.xml
+++ b/pkg/linux/gpxsee.xml
@@ -177,6 +177,16 @@
+
+ GPSDump Waypoint File
+
+
+
+
+
+
+
+
diff --git a/src/data/data.cpp b/src/data/data.cpp
index 5d513feb..9f9327f3 100644
--- a/src/data/data.cpp
+++ b/src/data/data.cpp
@@ -21,6 +21,7 @@
#include "itnparser.h"
#include "onmoveparsers.h"
#include "twonavparser.h"
+#include "gpsdumpparser.h"
#include "data.h"
@@ -46,6 +47,7 @@ static ITNParser itn;
static OMDParser omd;
static GHPParser ghp;
static TwoNavParser twonav;
+static GPSDumpParser gpsdump;
static QMultiMap parsers()
{
@@ -78,6 +80,7 @@ static QMultiMap parsers()
map.insert("trk", &twonav);
map.insert("rte", &twonav);
map.insert("wpt", &twonav);
+ map.insert("wpt", &gpsdump);
return map;
}
@@ -174,6 +177,7 @@ QString Data::formats()
+ qApp->translate("Data", "SML files") + " (*.sml);;"
+ qApp->translate("Data", "TCX files") + " (*.tcx);;"
+ qApp->translate("Data", "TwoNav files") + " (*.rte *.trk *.wpt);;"
+ + qApp->translate("Data", "GPSDump files") + " (*.wpt);;"
+ qApp->translate("Data", "All files") + " (*)";
}
diff --git a/src/data/gpsdumpparser.cpp b/src/data/gpsdumpparser.cpp
new file mode 100644
index 00000000..bb22fc2f
--- /dev/null
+++ b/src/data/gpsdumpparser.cpp
@@ -0,0 +1,161 @@
+#include
+#include "map/pcs.h"
+#include "map/gcs.h"
+#include "map/utm.h"
+#include "gpsdumpparser.h"
+
+static double dms2dd(const QStringList &dms)
+{
+ bool ok;
+
+ int deg = dms.at(1).toInt(&ok);
+ if (!ok)
+ return NAN;
+ int min = dms.at(2).toInt(&ok);
+ if (!ok)
+ return NAN;
+ double sec = dms.at(3).toDouble(&ok);
+ if (!ok)
+ return NAN;
+
+ return deg + min/60.0 + sec/3600.0;
+}
+
+static double parseLon(const QString &str)
+{
+ QStringList dms(str.split(' '));
+ if (dms.size() < 4)
+ return NAN;
+
+ double dd = dms2dd(dms);
+ if (std::isnan(dd))
+ return NAN;
+
+ if (dms.at(0) == 'W')
+ return -dd;
+ else if (dms.at(0) == 'E')
+ return dd;
+ else
+ return NAN;
+}
+
+static double parseLat(const QString &str)
+{
+ QStringList dms(str.split(' '));
+ if (dms.size() < 4)
+ return NAN;
+
+ double dd = dms2dd(dms);
+ if (std::isnan(dd))
+ return NAN;
+
+ if (dms.at(0) == 'S')
+ return -dd;
+ else if (dms.at(0) == 'N')
+ return dd;
+ else
+ return NAN;
+}
+
+static Coordinates parseGEO(const QString &lat, const QString &lon)
+{
+ return Coordinates(parseLon(lon), parseLat(lat));
+}
+
+static Coordinates parseUTM(const QString &zone, const QString &easting,
+ const QString &northing)
+{
+ bool ok;
+
+ int z = zone.left(zone.size() - 1).toInt(&ok);
+ if (!ok)
+ return Coordinates();
+ if (zone.right(1) < 'N')
+ z = -z;
+
+ int x = easting.toInt(&ok);
+ if (!ok)
+ return Coordinates();
+ int y = northing.toInt(&ok);
+ if (!ok)
+ return Coordinates();
+
+ Projection proj(PCS(GCS::WGS84(), Conversion(9807, UTM::setup(z), 9001)));
+
+ return proj.xy2ll(PointD(x, y));
+}
+
+bool GPSDumpParser::parse(QFile *file, QList &tracks,
+ QList &routes, QList &polygons, QVector &waypoints)
+{
+ Q_UNUSED(tracks);
+ Q_UNUSED(routes);
+ Q_UNUSED(polygons);
+
+ _errorLine = 1;
+ _errorString.clear();
+ Type type = Unknown;
+ QRegularExpression dm("[ ]{2,}");
+
+ while (!file->atEnd()) {
+ QByteArray ba(file->readLine(4096).trimmed());
+
+ if (_errorLine == 1) {
+ if (ba == "$FormatGEO")
+ type = GEO;
+ else if (ba == "$FormatUTM")
+ type = UTM;
+ else {
+ _errorString = "Not a GPSDump waypoint file";
+ return false;
+ }
+ } else if (!ba.isEmpty()) {
+ QString line(ba);
+ QStringList fields(line.split(dm));
+ Coordinates c;
+ double ele = NAN;
+ QString desc;
+ bool ok;
+
+ if (type == UTM) {
+ if (fields.size() < 5) {
+ _errorString = "Parse error";
+ return false;
+ }
+
+ c = parseUTM(fields.at(1), fields.at(2), fields.at(3));
+ ele = fields.at(4).toDouble(&ok);
+ if (fields.size() > 5)
+ desc = fields.at(5);
+ } else {
+ if (fields.size() < 4) {
+ _errorString = "Parse error";
+ return false;
+ }
+
+ c = parseGEO(fields.at(1), fields.at(2));
+ ele = fields.at(3).toDouble(&ok);
+ if (fields.size() > 4)
+ desc = fields.at(4);
+ }
+
+ if (!c.isValid()) {
+ _errorString = "Invalid coordinates";
+ return false;
+ }
+
+ Waypoint w(c);
+ w.setName(fields.at(0));
+ if (ok)
+ w.setElevation(ele);
+ if (!desc.isEmpty())
+ w.setDescription(desc);
+
+ waypoints.append(w);
+ }
+
+ _errorLine++;
+ }
+
+ return true;
+}
diff --git a/src/data/gpsdumpparser.h b/src/data/gpsdumpparser.h
new file mode 100644
index 00000000..f9ae1f80
--- /dev/null
+++ b/src/data/gpsdumpparser.h
@@ -0,0 +1,27 @@
+#ifndef GPSDUMPPARSER_H
+#define GPSDUMPPARSER_H
+
+#include "parser.h"
+
+class GPSDumpParser : public Parser
+{
+public:
+ GPSDumpParser() : _errorLine(0) {}
+
+ bool parse(QFile *file, QList &tracks, QList &routes,
+ QList &polygons, QVector &waypoints);
+ QString errorString() const {return _errorString;}
+ int errorLine() const {return _errorLine;}
+
+private:
+ enum Type {
+ Unknown,
+ GEO,
+ UTM
+ };
+
+ int _errorLine;
+ QString _errorString;
+};
+
+#endif // GPSDUMPPARSER_H