From f1b52c7005a6cab7c593cff43058e35b80d580da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Fri, 17 Jan 2025 07:37:49 +0100 Subject: [PATCH 1/9] Version++ --- .appveyor.yml | 2 +- gpxsee.pro | 2 +- pkg/windows/gpxsee64.nsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 0447e3b5..d062ec65 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -version: 13.34.{build} +version: 13.35.{build} configuration: - Release diff --git a/gpxsee.pro b/gpxsee.pro index c4bfd6d3..9c512cca 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -3,7 +3,7 @@ unix:!macx:!android { } else { TARGET = GPXSee } -VERSION = 13.34 +VERSION = 13.35 QT += core \ diff --git a/pkg/windows/gpxsee64.nsi b/pkg/windows/gpxsee64.nsi index 494559e6..3e743e22 100644 --- a/pkg/windows/gpxsee64.nsi +++ b/pkg/windows/gpxsee64.nsi @@ -37,7 +37,7 @@ Unicode true ; The name of the installer Name "GPXSee" ; Program version -!define VERSION "13.34" +!define VERSION "13.35" ; The file to write OutFile "GPXSee-${VERSION}_x64.exe" From 335df85faece022aab0b69d0dc4ca27f6c5a9db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Fri, 17 Jan 2025 07:38:31 +0100 Subject: [PATCH 2/9] Code cleanup --- src/map/IMG/demtree.cpp | 10 ++++++++++ src/map/IMG/demtree.h | 2 ++ src/map/IMG/rastertile.cpp | 18 +++++++----------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/map/IMG/demtree.cpp b/src/map/IMG/demtree.cpp index b8863181..d94df078 100644 --- a/src/map/IMG/demtree.cpp +++ b/src/map/IMG/demtree.cpp @@ -111,3 +111,13 @@ double DEMTree::elevation(const Coordinates &c) const return ele; } + +MatrixD DEMTree::elevation(const MatrixC &m) const +{ + MatrixD ret(m.h(), m.w()); + + for (int i = 0; i < m.size(); i++) + ret.at(i) = elevation(m.at(i)); + + return ret; +} diff --git a/src/map/IMG/demtree.h b/src/map/IMG/demtree.h index 9e78b302..86ff7139 100644 --- a/src/map/IMG/demtree.h +++ b/src/map/IMG/demtree.h @@ -2,6 +2,7 @@ #define IMG_DEMTREE_H #include "common/rtree.h" +#include "map/matrix.h" #include "mapdata.h" namespace IMG { @@ -11,6 +12,7 @@ public: DEMTree(const QList &tiles); double elevation(const Coordinates &c) const; + MatrixD elevation(const MatrixC &m) const; private: typedef RTree Tree; diff --git a/src/map/IMG/rastertile.cpp b/src/map/IMG/rastertile.cpp index af8d51a3..be67893b 100644 --- a/src/map/IMG/rastertile.cpp +++ b/src/map/IMG/rastertile.cpp @@ -483,22 +483,18 @@ MatrixD RasterTile::elevation(int extend) const if (_data->hasDEM()) { RectC rect; - QList tiles; - for (int i = 0; i < ll.size(); i++) rect = rect.united(ll.at(i)); - // Extra margin for always including the next DEM tile on the map tile - // edges (the DEM tile resolution is usally 0.5-15% of the map tile) + /* Extra margin for always including the next DEM tile on the map tile + edges (the DEM tile resolution is usally 0.5-15% of the map tile) */ double factor = 6 - (_zoom - 24) * 1.7; - _data->elevations(_file, rect.adjusted(0, 0, rect.width() / factor, - -rect.height() / factor), _zoom, &tiles); + RectC br(rect.adjusted(0, 0, rect.width() / factor, -rect.height() + / factor)); - DEMTree tree(tiles); - MatrixD m(ll.h(), ll.w()); - for (int i = 0; i < ll.size(); i++) - m.at(i) = tree.elevation(ll.at(i)); + QList tiles; + _data->elevations(_file, br, _zoom, &tiles); - return m; + return DEMTree(tiles).elevation(ll); } else return DEM::elevation(ll); } From 9cd82319e90918e7e2e4aa8d99109fb3bcc65fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Mon, 20 Jan 2025 23:26:58 +0100 Subject: [PATCH 3/9] Cosmetics --- src/map/maplist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map/maplist.cpp b/src/map/maplist.cpp index bcc1dac2..30fe6dbe 100644 --- a/src/map/maplist.cpp +++ b/src/map/maplist.cpp @@ -63,7 +63,7 @@ MapList::ParserMap MapList::parsers() return map; } -MapList::ParserMap MapList::_parsers = parsers(); +MapList::ParserMap MapList::_parsers = MapList::parsers(); Map *MapList::loadFile(const QString &path, const Projection &proj, bool *isDir) { From 0ed630dd20575568a513a9e900035eaafec76ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Mon, 20 Jan 2025 23:27:44 +0100 Subject: [PATCH 4/9] Added support for geo URIs (RFC 5870) --- src/GUI/gui.cpp | 40 +++++++++++++++++++++++++++++ src/GUI/gui.h | 1 + src/data/data.cpp | 64 +++++++++++++++++++++++++++++++++++++++++++++++ src/data/data.h | 1 + 4 files changed, 106 insertions(+) diff --git a/src/GUI/gui.cpp b/src/GUI/gui.cpp index 5102305e..627a0484 100644 --- a/src/GUI/gui.cpp +++ b/src/GUI/gui.cpp @@ -1069,6 +1069,16 @@ void GUI::openDir() bool GUI::openFile(const QString &fileName, bool tryUnknown, int &showError) { + QUrl url(fileName); + if (url.scheme() == "geo") { + if (loadURL(url, showError)) { + _fileActionGroup->setEnabled(true); + _reloadFileAction->setEnabled(false); + return true; + } else if (showError) + return false; + } + QFileInfo fi(fileName); QString canonicalFileName(fi.canonicalFilePath()); @@ -1099,6 +1109,36 @@ bool GUI::openFile(const QString &fileName, bool tryUnknown, int &showError) return true; } +bool GUI::loadURL(const QUrl &url, int &showError) +{ + Data data(url); + + if (data.isValid()) { + loadData(data); + return true; + } else { + if (showError) { + QString error = tr("Error loading geo URI:") + "\n" + url.toString() + + ": " + data.errorString(); + + if (showError > 1) { + QMessageBox message(QMessageBox::Critical, APP_NAME, error, + QMessageBox::Ok, this); + QCheckBox checkBox(tr("Don't show again")); + message.setCheckBox(&checkBox); + message.exec(); + if (checkBox.isChecked()) + showError = 0; + } else + QMessageBox::critical(this, APP_NAME, error); + } else + qWarning("%s: %s", qUtf8Printable(url.toString()), + qUtf8Printable(data.errorString())); + + return false; + } +} + bool GUI::loadFile(const QString &fileName, bool tryUnknown, int &showError) { Data data(fileName, tryUnknown); diff --git a/src/GUI/gui.h b/src/GUI/gui.h index 3b3dd7cc..f8020de7 100644 --- a/src/GUI/gui.h +++ b/src/GUI/gui.h @@ -158,6 +158,7 @@ private: #endif // Q_OS_ANDROID bool openPOIFile(const QString &fileName); bool loadFile(const QString &fileName, bool tryUnknown, int &showError); + bool loadURL(const QUrl &url, int &showError); void loadData(const Data &data); bool loadMapNode(const TreeNode &node, MapAction *&action, const QList &existingActions, int &showError); diff --git a/src/data/data.cpp b/src/data/data.cpp index e9b7a888..c88bec56 100644 --- a/src/data/data.cpp +++ b/src/data/data.cpp @@ -2,6 +2,7 @@ #include #include #include "common/util.h" +#include "map/crs.h" #include "gpxparser.h" #include "tcxparser.h" #include "csvparser.h" @@ -154,6 +155,69 @@ Data::Data(const QString &fileName, bool tryUnknown) } } +Data::Data(const QUrl &url) +{ + bool caOk, cbOk, ccOk; + Coordinates c; + Projection proj; + + _valid = false; + + QStringList parts(url.path().split(';')); + if (parts.size() < 1) { + _errorString = "Syntax error"; + return; + } + QStringList coords(parts.at(0).split(',')); + if (coords.size() < 2 || coords.size() > 3) { + _errorString = "Syntax error"; + return; + } + double ca = coords.at(0).toDouble(&caOk); + double cb = coords.at(1).toDouble(&cbOk); + double cc = NAN; + if (!(caOk && cbOk)) { + _errorString = "Invalid coordinates"; + return; + } + if (coords.size() > 2) { + cc = coords.at(2).toDouble(&ccOk); + if (!ccOk) { + _errorString = "Invalid elevation"; + return; + } + } + + if (parts.size() > 1) { + QStringList crsp(parts.at(1).split('=')); + if (crsp.size() != 2) { + _errorString = "Syntax error"; + return; + } + if (!crsp.at(0).compare("crs", Qt::CaseInsensitive)) { + if (crsp.at(1).compare("wgs84", Qt::CaseInsensitive)) { + proj = CRS::projection(crsp.at(1)); + if (!proj.isValid()) { + _errorString = "Unknown CRS"; + return; + } + } + } + } + + c = proj.isValid() ? proj.xy2ll(PointD(ca, cb)) : Coordinates(cb, ca); + if (!c.isValid()) { + _errorString = "Invalid coordinates"; + return; + } + + Waypoint w(c); + w.setElevation(cc); + _waypoints.append(w); + + _valid = true; +} + QString Data::formats() { return diff --git a/src/data/data.h b/src/data/data.h index 257f6263..0e27bd9a 100644 --- a/src/data/data.h +++ b/src/data/data.h @@ -14,6 +14,7 @@ class Data { public: Data(const QString &fileName, bool tryUnknown = true); + Data(const QUrl &url); bool isValid() const {return _valid;} const QString &errorString() const {return _errorString;} From 46ea3dd25700fb409985c4e0e6ef965af6983ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Mon, 20 Jan 2025 23:45:11 +0100 Subject: [PATCH 5/9] geo URI linux desktop integration --- pkg/linux/gpxsee.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/linux/gpxsee.desktop b/pkg/linux/gpxsee.desktop index 5a054997..31300673 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;application/vnd.gpsdump.wpt;application/vnd.gpstuner.gmi +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 From 3dd21ade1939e586f2399dbfbc81c8aabac94ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Mon, 20 Jan 2025 23:45:36 +0100 Subject: [PATCH 6/9] geo URI MacOS desktop integration --- pkg/mac/Info.plist | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/mac/Info.plist b/pkg/mac/Info.plist index 802b934a..6b25c4a1 100644 --- a/pkg/mac/Info.plist +++ b/pkg/mac/Info.plist @@ -738,6 +738,20 @@ + CFBundleURLTypes + + + CFBundleURLSchemes + + geo + + CFBundleURLName + org.geouri.geo + CFBundleTypeRole + Viewer + + + UTImportedTypeDeclarations From e27bc437fa99ed5d5a81021df792f4b19730e56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Tue, 21 Jan 2025 05:34:26 +0100 Subject: [PATCH 7/9] geo URI Windows desktop integration --- pkg/windows/gpxsee64.nsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pkg/windows/gpxsee64.nsi b/pkg/windows/gpxsee64.nsi index 3e743e22..99591ef5 100644 --- a/pkg/windows/gpxsee64.nsi +++ b/pkg/windows/gpxsee64.nsi @@ -18,6 +18,18 @@ DeleteRegKey HKCR ".${EXT}" !macroend +; URI association +!macro URI_ASSOCIATION_ADD PROTO DESC + WriteRegStr HKCR "${PROTO}" "" "${DESC}" + WriteRegStr HKCR "${PROTO}" "URL Protocol" "" + WriteRegStr HKCR "${PROTO}\DefaultIcon" "" "$INSTDIR\GPXSee.exe,0" + WriteRegStr HKCR "${PROTO}\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\"" +!macroend + +!macro URI_ASSOCIATION_REMOVE PROTO + DeleteRegKey HKCR "${PROTO}" +!macroend + ; Translations !macro LOCALIZATION LANG CODE Section "${LANG}" @@ -200,6 +212,8 @@ Section "GPXSee" SEC_APP !insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 33 !insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 34 + !insertmacro URI_ASSOCIATION_ADD "geo" "geo URI" + WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\"" WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" "" WriteRegStr HKCR ".tcx\OpenWithList" "GPXSee.exe" "" @@ -426,6 +440,8 @@ Section "Uninstall" !insertmacro FILE_ASSOCIATION_REMOVE "000" !insertmacro FILE_ASSOCIATION_REMOVE "031" + !insertmacro URI_ASSOCIATION_REMOVE "geo" + DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".kml\OpenWithList" "GPXSee.exe" From db2d81042b77eb7586048e5c739895f679501759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Tue, 21 Jan 2025 06:20:37 +0100 Subject: [PATCH 8/9] Use the common URL:$protocol naming scheme --- pkg/windows/gpxsee64.nsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/windows/gpxsee64.nsi b/pkg/windows/gpxsee64.nsi index 99591ef5..38b9e872 100644 --- a/pkg/windows/gpxsee64.nsi +++ b/pkg/windows/gpxsee64.nsi @@ -19,8 +19,8 @@ !macroend ; URI association -!macro URI_ASSOCIATION_ADD PROTO DESC - WriteRegStr HKCR "${PROTO}" "" "${DESC}" +!macro URI_ASSOCIATION_ADD PROTO + WriteRegStr HKCR "${PROTO}" "" "URL:${PROTO}" WriteRegStr HKCR "${PROTO}" "URL Protocol" "" WriteRegStr HKCR "${PROTO}\DefaultIcon" "" "$INSTDIR\GPXSee.exe,0" WriteRegStr HKCR "${PROTO}\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\"" @@ -212,7 +212,7 @@ Section "GPXSee" SEC_APP !insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 33 !insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 34 - !insertmacro URI_ASSOCIATION_ADD "geo" "geo URI" + !insertmacro URI_ASSOCIATION_ADD "geo" WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\"" WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" "" From 213ab73ceb8c05c45a891570fbc853db60283177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Tue, 21 Jan 2025 21:45:49 +0100 Subject: [PATCH 9/9] Properly handle axis order in geo URIs --- src/data/data.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/data/data.cpp b/src/data/data.cpp index c88bec56..30dc5add 100644 --- a/src/data/data.cpp +++ b/src/data/data.cpp @@ -158,8 +158,7 @@ Data::Data(const QString &fileName, bool tryUnknown) Data::Data(const QUrl &url) { bool caOk, cbOk, ccOk; - Coordinates c; - Projection proj; + Projection proj(GCS::WGS84()); _valid = false; @@ -205,7 +204,9 @@ Data::Data(const QUrl &url) } } - c = proj.isValid() ? proj.xy2ll(PointD(ca, cb)) : Coordinates(cb, ca); + CoordinateSystem::AxisOrder ao = proj.coordinateSystem().axisOrder(); + PointD p(ao == CoordinateSystem::XY ? PointD(ca, cb) : PointD(cb, ca)); + Coordinates c(proj.xy2ll(p)); if (!c.isValid()) { _errorString = "Invalid coordinates"; return;