From 6a941566cbe4f17fd0016b83d3ee724b139b721a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Sun, 9 May 2021 22:39:39 +0200 Subject: [PATCH] Added support for TomTom OV2 files --- gpxsee.pro | 2 ++ pkg/appdata.xml | 1 + pkg/gpxsee.desktop | 2 +- pkg/gpxsee.xml | 6 ++++ src/data/data.cpp | 5 ++- src/data/ov2parser.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++ src/data/ov2parser.h | 17 ++++++++++ 7 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 src/data/ov2parser.cpp create mode 100644 src/data/ov2parser.h diff --git a/gpxsee.pro b/gpxsee.pro index 00f3cbf1..3b3e849e 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -91,6 +91,7 @@ HEADERS += src/common/config.h \ src/GUI/font.h \ src/GUI/areaitem.h \ src/data/link.h \ + src/data/ov2parser.h \ src/map/IMG/bitmapline.h \ src/map/IMG/bitstream.h \ src/map/IMG/deltastream.h \ @@ -277,6 +278,7 @@ SOURCES += src/main.cpp \ src/GUI/gearratiographitem.cpp \ src/GUI/mapview.cpp \ src/GUI/areaitem.cpp \ + src/data/ov2parser.cpp \ src/data/waypoint.cpp \ src/map/IMG/bitmapline.cpp \ src/map/IMG/bitstream.cpp \ diff --git a/pkg/appdata.xml b/pkg/appdata.xml index 4bcbde7a..1bdf8389 100644 --- a/pkg/appdata.xml +++ b/pkg/appdata.xml @@ -91,5 +91,6 @@ application/vnd.alpinequest.aqm application/vnd.rmaps.sqlite application/vnd.mapsforge.map + application/vnd.tomtom.ov2 diff --git a/pkg/gpxsee.desktop b/pkg/gpxsee.desktop index bbabed13..1de15fb1 100644 --- a/pkg/gpxsee.desktop +++ b/pkg/gpxsee.desktop @@ -15,4 +15,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.rmaps.sqlite;application/vnd.mapsforge.map +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.rmaps.sqlite;application/vnd.mapsforge.map;application/vnd.tomtom.ov2 diff --git a/pkg/gpxsee.xml b/pkg/gpxsee.xml index 3af26fb0..7e4ced25 100644 --- a/pkg/gpxsee.xml +++ b/pkg/gpxsee.xml @@ -128,6 +128,12 @@ + + TomTom POI File + + + + diff --git a/src/data/data.cpp b/src/data/data.cpp index fad7d48f..09ceb90b 100644 --- a/src/data/data.cpp +++ b/src/data/data.cpp @@ -17,7 +17,7 @@ #include "cupparser.h" #include "gpiparser.h" #include "smlparser.h" -#include "map/map.h" +#include "ov2parser.h" #include "data.h" @@ -38,6 +38,7 @@ static EXIFParser exif; static CUPParser cup; static GPIParser gpi; static SMLParser sml; +static OV2Parser ov2; static QMap parsers() { @@ -62,6 +63,7 @@ static QMap parsers() map.insert("cup", &cup); map.insert("gpi", &gpi); map.insert("sml", &sml); + map.insert("ov2", &ov2); return map; } @@ -138,6 +140,7 @@ QString Data::formats() + qApp->translate("Data", "KML files") + " (*.kml);;" + qApp->translate("Data", "LOC files") + " (*.loc);;" + qApp->translate("Data", "NMEA files") + " (*.nmea);;" + + qApp->translate("Data", "OV2 files") + " (*.ov2);;" + qApp->translate("Data", "OziExplorer files") + " (*.plt *.rte *.wpt);;" + qApp->translate("Data", "SLF files") + " (*.slf);;" + qApp->translate("Data", "SML files") + " (*.sml);;" diff --git a/src/data/ov2parser.cpp b/src/data/ov2parser.cpp new file mode 100644 index 00000000..5a30e739 --- /dev/null +++ b/src/data/ov2parser.cpp @@ -0,0 +1,71 @@ +#include +#include "common/textcodec.h" +#include "ov2parser.h" + +bool OV2Parser::parse(QFile *file, QList &tracks, + QList &routes, QList &polygons, QVector &waypoints) +{ + Q_UNUSED(tracks); + Q_UNUSED(routes); + Q_UNUSED(polygons); + QDataStream stream(file); + quint8 type; + quint32 len; + qint32 lon, lat; + QByteArray ba; + TextCodec codec(1252); + + stream.setByteOrder(QDataStream::LittleEndian); + + while (!stream.atEnd()) { + stream >> type; + switch (type) { + case 0: + stream >> len; + if (stream.status() != QDataStream::Ok || len < 5) { + _errorString = "Corrupted deleted record"; + return false; + } + stream.skipRawData(len - 5); + break; + case 1: + if (stream.skipRawData(20) < 20) { + _errorString = "Corrupted skipper record"; + return false; + } + break; + case 2: + case 3: + {stream >> len >> lon >> lat; + if (stream.status() != QDataStream::Ok || len < 13) { + _errorString = "Corrupted POI record"; + return false; + } + ba.resize(len - 13); + if (stream.readRawData(ba.data(), ba.size()) != ba.size()) { + _errorString = "Corrupted POI record"; + return false; + } + if (lon < -18000000 || lon > 18000000 + || lat < -9000000 || lat > 9000000) { + _errorString = "Invalid POI coordinates"; + return false; + } + Waypoint wp(Coordinates(lon/1e5, lat/1e5)); + if (type == 2) + wp.setName(codec.toString(ba)); + else { + QList parts(ba.split('\0')); + wp.setName(codec.toString(parts.at(0))); + } + waypoints.append(wp);} + break; + default: + _errorString = QString("%1: invalid/unknown record type") + .arg(type); + return false; + } + } + + return true; +} diff --git a/src/data/ov2parser.h b/src/data/ov2parser.h new file mode 100644 index 00000000..207b8fd2 --- /dev/null +++ b/src/data/ov2parser.h @@ -0,0 +1,17 @@ +#ifndef OV2PARSER_H +#define OV2PARSER_H + +#include "parser.h" + +class OV2Parser : public Parser +{ + bool parse(QFile *file, QList &tracks, QList &routes, + QList &polygons, QVector &waypoints); + QString errorString() const {return _errorString;} + int errorLine() const {return 0;} + +private: + QString _errorString; +}; + +#endif // OV2PARSER_H