1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-06-07 18:53:02 +02:00

Compare commits

...

7 Commits

Author SHA1 Message Date
0e329f4b22 Added Velocitek VTK Windows desktop integration 2025-03-16 17:53:00 +01:00
2041cc7ff5 Added Velocitek VTK files Linux desktop integration 2025-03-16 17:37:37 +01:00
8169015f70 Added missing trunk roads names 2025-03-16 17:32:36 +01:00
28f55b7e0d Added support for Velocitek VTK files 2025-03-16 17:17:09 +01:00
912a00c80e Cosmetics 2025-03-16 17:15:33 +01:00
8de6bbe4fb Fixed maximal speed info
Display the maximum of all primary graphs, not the maximum of all graphs.
2025-03-16 17:14:14 +01:00
f34d6b0540 Fixed wrong oneway icon filename 2025-03-16 17:11:13 +01:00
15 changed files with 285 additions and 16 deletions

View File

@ -403,7 +403,7 @@
<rule e="way" k="*" v="*" zoom-min="14">
<pathText fill="#000000" font-size="10" k="name" priority="-5" stroke="#FFFFFF" stroke-width="2"/>
<rule e="way" k="oneway" v="yes|true|1" zoom-min="16">
<lineSymbol priority="-50" src=":/symbols/arrow.svg" symbol-width="16" symbol-height="8"/>
<lineSymbol priority="-50" src=":/symbols/oneway.svg" symbol-width="16" symbol-height="8"/>
</rule>
</rule>
</rule>
@ -428,6 +428,12 @@
<line stroke="#f7d9a6" stroke-width="1" stroke-linecap="butt"/>
</rule>
</rule>
<rule e="way" k="*" v="*" zoom-min="14">
<pathText fill="#000000" font-size="10" k="name" priority="-3" stroke="#FFFFFF" stroke-width="2"/>
<rule e="way" k="oneway" v="yes|true|1" zoom-min="16">
<lineSymbol priority="-50" src=":/symbols/oneway.svg" symbol-width="16" symbol-height="8"/>
</rule>
</rule>
</rule>
<rule e="way" k="highway" v="motorway|motorway_link">
<rule e="way" k="tunnel" v="~|false|no">

View File

@ -118,6 +118,7 @@ HEADERS += src/common/config.h \
src/data/style.h \
src/data/twonavparser.h \
src/data/txtparser.h \
src/data/vtkparser.h \
src/map/ENC/data.h \
src/map/IMG/light.h \
src/map/downloader.h \
@ -346,6 +347,7 @@ SOURCES += src/main.cpp \
src/GUI/projectioncombobox.cpp \
src/GUI/passwordedit.cpp \
src/data/txtparser.cpp \
src/data/vtkparser.cpp \
src/map/downloader.cpp \
src/map/demloader.cpp \
src/map/ENC/atlasdata.cpp \
@ -561,7 +563,8 @@ win32 {
icons/formats/trk.ico \
icons/formats/gemf.ico \
icons/formats/000.ico \
icons/formats/031.ico
icons/formats/031.ico \
icons/formats/vtk.ico
DEFINES += _USE_MATH_DEFINES \
NOGDI
}

View File

@ -32,3 +32,4 @@ trk:#cccccc
gemf:#147085
000:#000000
031:#000000
vtk:#632433

BIN
icons/formats/vtk.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

View File

@ -15,8 +15,8 @@
<li>Opens GPX, TCX, FIT, KML, IGC, NMEA, SIGMA SLF, Suunto SML, LOC,
OziExplorer (PLT, WPT, RTE), GeoJSON, SeeYou CUP,
Garmin GPI &amp; CSV, TomTom OV2 &amp; ITN, ONmove OMD/GHP,
TwoNav (TRK, RTE, WPT), GPSDump WPT, 70mai GPS logs and
geotagged JPEG files.</li>
TwoNav (TRK, RTE, WPT), GPSDump WPT, Velocitek VTK,
70mai GPS logs and geotagged JPEG files.</li>
<li>Opens geo URIs (RFC 5870).</li>
<li>User-definable online maps (OpenStreetMap/Google tiles, WMTS,
WMS, TMS, QuadTiles).</li>
@ -114,6 +114,7 @@
<mimetype>application/vnd.gpsdump.wpt</mimetype>
<mimetype>application/vnd.gpstuner.gmi</mimetype>
<mimetype>application/vnd.70mai.txt</mimetype>
<mimetype>application/vnd.velocitek.vtk</mimetype>
<mimetype>x-scheme-handler/geo</mimetype>
</mimetypes>
</component>

View File

@ -16,4 +16,4 @@ Icon=gpxsee
Terminal=false
Type=Application
Categories=Graphics;Viewer;Education;Geography;Maps;Sports;Qt
MimeType=x-scheme-handler/geo;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;application/vnd.gpstuner.gmi;application/vnd.70mai.txt
MimeType=x-scheme-handler/geo;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;application/vnd.gpstuner.gmi;application/vnd.70mai.txt;application/vnd.velocitek.vtk

View File

@ -198,6 +198,13 @@
<glob pattern="*.txt"/>
</mime-type>
<mime-type type="application/vnd.velocitek.vtk">
<comment>Velocitek VTK File</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application/octet-stream"/>
<glob pattern="*.vtk"/>
</mime-type>
<!-- Maps -->
<mime-type type="application/vnd.garmin.img">

View File

@ -204,13 +204,14 @@ Section "GPXSee" SEC_APP
!insertmacro FILE_ASSOCIATION_ADD "gemf" "GEMF Map File" 26
!insertmacro FILE_ASSOCIATION_ADD "000" "IHO S-57 Electronic Navigation Chart" 27
!insertmacro FILE_ASSOCIATION_ADD "031" "IHO S-57 Electronic Navigation Catalogue" 28
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 29
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 29
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 30
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 31
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 32
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 33
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 34
!insertmacro FILE_ASSOCIATION_ADD "vtk" "Velocitek VTK File" 29
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 30
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 30
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 31
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 32
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 33
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 34
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 35
!insertmacro URI_ASSOCIATION_ADD "geo"
@ -266,6 +267,7 @@ Section "GPXSee" SEC_APP
WriteRegStr HKCR ".000\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".031\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".txt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".vtk\OpenWithList" "GPXSee.exe" ""
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
@ -440,6 +442,7 @@ Section "Uninstall"
!insertmacro FILE_ASSOCIATION_REMOVE "gemf"
!insertmacro FILE_ASSOCIATION_REMOVE "000"
!insertmacro FILE_ASSOCIATION_REMOVE "031"
!insertmacro FILE_ASSOCIATION_REMOVE "vtk"
!insertmacro URI_ASSOCIATION_REMOVE "geo"
@ -494,6 +497,7 @@ Section "Uninstall"
DeleteRegValue HKCR ".000\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".031\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".txt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".vtk\OpenWithList" "GPXSee.exe"
DeleteRegKey HKCR "Applications\GPXSee.exe"
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'

View File

@ -64,6 +64,7 @@ GraphItem *SpeedGraph::loadGraph(const Graph &graph, const Track &track,
if (primary) {
_avg.append(QPointF(track.distance(), gi->avg()));
_mavg.append(QPointF(track.distance(), gi->mavg()));
_max.append(QPointF(track.distance(), gi->max()));
}
return gi;
@ -117,6 +118,16 @@ qreal SpeedGraph::avg() const
return (sum / w);
}
qreal SpeedGraph::max() const
{
qreal mv = 0;
for (int i = 0; i < _max.size(); i++)
mv = qMax(mv, _max.at(i).y());
return mv;
}
void SpeedGraph::clear()
{
qDeleteAll(_tracks);
@ -124,6 +135,7 @@ void SpeedGraph::clear()
_avg.clear();
_mavg.clear();
_max.clear();
GraphTab::clear();
}

View File

@ -26,12 +26,13 @@ private:
GraphItem *loadGraph(const Graph &graph, const Track &track,
const QColor &color, bool primary);
qreal avg() const;
qreal max() const {return bounds().bottom();}
qreal max() const;
void setYUnits();
void setInfo();
QVector<QPointF> _avg;
QVector<QPointF> _mavg;
QVector<QPointF> _max;
Units _units;
TimeType _timeType;

View File

@ -24,6 +24,7 @@
#include "twonavparser.h"
#include "gpsdumpparser.h"
#include "txtparser.h"
#include "vtkparser.h"
#include "data.h"
@ -51,6 +52,7 @@ static GHPParser ghp;
static TwoNavParser twonav;
static GPSDumpParser gpsdump;
static TXTParser txt;
static VTKParser vtk;
static QMultiMap<QString, Parser*> parsers()
{
@ -85,6 +87,7 @@ static QMultiMap<QString, Parser*> parsers()
map.insert("wpt", &twonav);
map.insert("wpt", &gpsdump);
map.insert("txt", &txt);
map.insert("vtk", &vtk);
return map;
}
@ -245,6 +248,7 @@ QString Data::formats()
+ qApp->translate("Data", "SML files") + " (*.sml);;"
+ qApp->translate("Data", "TCX files") + " (*.tcx);;"
+ qApp->translate("Data", "70mai GPS log files") + " (*.txt);;"
+ qApp->translate("Data", "VTK files") + " (*.vtk);;"
+ qApp->translate("Data", "TwoNav files") + " (*.rte *.trk *.wpt);;"
+ qApp->translate("Data", "GPSDump files") + " (*.wpt);;"
+ qApp->translate("Data", "All files") + " (*)";

View File

@ -467,8 +467,7 @@ bool FITParser::parseHeader(CTX &ctx)
}
bool FITParser::parse(QFile *file, QList<TrackData> &tracks,
QList<RouteData> &routes,
QList<Area> &polygons, QVector<Waypoint> &waypoints)
QList<RouteData> &routes, QList<Area> &polygons, QVector<Waypoint> &waypoints)
{
Q_UNUSED(routes);
Q_UNUSED(polygons);

View File

@ -4,7 +4,6 @@
#include <QXmlStreamReader>
#include "parser.h"
class TCXParser : public Parser
{
public:

214
src/data/vtkparser.cpp Normal file
View File

@ -0,0 +1,214 @@
#include <QtEndian>
#include <QTimeZone>
#include "vtkparser.h"
#define TYPE(tag) (tag & 0x07)
#define FIELD(tag) (tag >> 3)
#define VARINT 0
#define I64 1
#define LEN 2
#define I32 5
struct CTX
{
CTX(const QByteArray &ba)
: bp(ba.constData()), be(bp + ba.size()), tag(0) {}
const char *bp;
const char *be;
quint32 tag;
};
static inline qint32 zigzag32decode(quint32 value)
{
return static_cast<qint32>((value >> 1u) ^ static_cast<quint32>(
-static_cast<qint32>(value & 1u)));
}
template<typename T>
static bool varint(CTX &ctx, T &val)
{
unsigned int shift = 0;
val = 0;
while (ctx.bp < ctx.be) {
val |= ((quint8)*ctx.bp & 0x7F) << shift;
shift += 7;
if (!((quint8)*ctx.bp++ & 0x80))
return true;
}
return false;
}
static bool length(CTX &ctx, qint32 &val)
{
if (TYPE(ctx.tag) != LEN)
return false;
if (!varint(ctx, val))
return false;
return (val >= 0);
}
static bool skip(CTX &ctx)
{
qint32 len = 0;
switch (TYPE(ctx.tag)) {
case VARINT:
return varint(ctx, len);
case I64:
len = 8;
break;
case LEN:
if (!varint(ctx, len) || len < 0)
return false;
break;
case I32:
len = 4;
break;
default:
return false;
}
if (ctx.bp + len > ctx.be)
return false;
ctx.bp += len;
return true;
}
static bool trackpoint(CTX &ctx, Trackpoint &t)
{
qint32 len, lon = 0xFFFFFFF, lat = 0xFFFFFFF;
quint32 val, seconds = 0, centiSeconds = 0, speed = 0;
if (!length(ctx, len))
return false;
const char *ee = ctx.bp + len;
if (ee > ctx.be)
return false;
while (ctx.bp < ee) {
if (!varint(ctx, ctx.tag))
return false;
switch (FIELD(ctx.tag)) {
case 1:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, seconds))
return false;
break;
case 2:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, centiSeconds))
return false;
break;
case 3:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, val))
return false;
lat = zigzag32decode(val);
break;
case 4:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, val))
return false;
lon = zigzag32decode(val);
break;
case 5:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, speed))
return false;
break;
default:
if (!skip(ctx))
return false;
}
}
t.setCoordinates(Coordinates(lon / 1e7, lat / 1e7));
t.setTimestamp(QDateTime::fromMSecsSinceEpoch(
((qint64)seconds * 1000) + ((qint64)centiSeconds * 10),
QTimeZone::utc()));
t.setSpeed(speed / 5.1444);
return (ctx.bp == ee);
}
static bool record(CTX &ctx, Trackpoint &t)
{
while (ctx.bp < ctx.be) {
if (!varint(ctx, ctx.tag))
return false;
switch (FIELD(ctx.tag)) {
case 1:
if (!trackpoint(ctx, t))
return false;
break;
default:
if (!skip(ctx))
return false;
}
}
return (ctx.bp == ctx.be);
}
bool VTKParser::parse(QFile *file, QList<TrackData> &tracks,
QList<RouteData> &routes, QList<Area> &polygons, QVector<Waypoint> &waypoints)
{
Q_UNUSED(routes);
Q_UNUSED(polygons);
Q_UNUSED(waypoints);
qint64 len;
quint16 recordLen;
QByteArray ba;
SegmentData segment;
Trackpoint t;
_errorString = "";
while (true) {
len = file->read((char*)&recordLen, 2);
if (len < 0) {
_errorString = "I/O error";
return false;
} else if (len == 0)
break;
recordLen = qFromLittleEndian(recordLen);
ba.resize(recordLen);
if (file->read(ba.data(), ba.size()) != ba.size()) {
_errorString = "Error reading VTK record";
return false;
}
CTX ctx(ba);
t.setCoordinates(Coordinates());
if (!record(ctx, t)) {
_errorString = "Invalid VTK record";
return false;
} else {
if (t.coordinates().isValid())
segment.append(t);
else if (!t.coordinates().isNull()) {
_errorString = "Invalid VTK record coordinates";
return false;
}
}
}
tracks.append(segment);
return true;
}

18
src/data/vtkparser.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef VTKPARSER_H
#define VTKPARSER_H
#include "parser.h"
class VTKParser : public Parser
{
public:
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 0;}
private:
QString _errorString;
};
#endif // VTKPARSER_H