1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-08 00:04:27 +02:00

Compare commits

...

149 Commits
7.37 ... 8.1

Author SHA1 Message Date
4cb369d2f3 Merge branch 'origin/master' into Weblate. 2021-01-01 12:52:00 +01:00
f7b44b64b0 Fixed broken graph info layout 2021-01-01 12:51:39 +01:00
895b2219c5 Merge branch 'origin/master' into Weblate. 2020-12-31 15:45:18 +01:00
0ec265e4ea Version++ 2020-12-31 15:45:03 +01:00
d9e5fc6a74 Merge branch 'origin/master' into Weblate. 2020-12-31 14:03:55 +01:00
c3f345c7f9 Added support for ZIPed DEM files 2020-12-31 14:03:30 +01:00
1f9bff6a9b Merge branch 'origin/master' into Weblate. 2020-12-30 09:26:41 +01:00
7e39a34d0e Fixed typo 2020-12-30 09:26:26 +01:00
a941a7315e Merge branch 'origin/master' into Weblate. 2020-12-29 18:36:59 +01:00
cf4f9b6f98 Fixed digital zoom on OS X 2020-12-29 18:36:23 +01:00
3d89d0d7da Merge branch 'origin/master' into Weblate. 2020-12-29 15:17:54 +01:00
9b3ed7ef1d Fixed Qt6 Release build 2020-12-29 15:17:31 +01:00
796107b1ab Merge branch 'origin/master' into Weblate. 2020-12-29 01:05:40 +01:00
a7e9c95ba2 Updated minimal required Qt version
Luckily for wretches using Debian systems, the minimal Qt version is 5.11, not 5.12
2020-12-29 01:05:36 +01:00
cd54d2d952 Merge branch 'origin/master' into Weblate. 2020-12-28 16:09:15 +01:00
bafbb825fc Fixed TimeZoneInfo QVariant loading/saving in QT6 2020-12-28 16:08:36 +01:00
031ed4907c Merge branch 'origin/master' into Weblate. 2020-12-28 14:45:51 +01:00
7cdbad3e79 Translated using Weblate (Hungarian)
Currently translated at 100.0% (388 of 388 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-12-28 14:45:51 +01:00
b62ec2429a Translated using Weblate (Turkish)
Currently translated at 100.0% (388 of 388 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-12-28 14:45:50 +01:00
10032000b1 Translated using Weblate (Russian)
Currently translated at 100.0% (388 of 388 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-12-28 14:45:50 +01:00
fd19d9c5a4 Translated using Weblate (Finnish)
Currently translated at 100.0% (388 of 388 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-12-28 14:45:50 +01:00
60bb42d708 Translated missing strings 2020-12-28 14:45:25 +01:00
6201ba1c67 Cosmetics 2020-12-28 14:42:16 +01:00
85d6357cb9 Added missing HiDPI mode support 2020-12-28 14:05:51 +01:00
26cbbee135 Added KMZ mimetype 2020-12-28 11:19:44 +01:00
e200d1597d Consistently use HTTPS 2020-12-28 11:13:40 +01:00
cd46a9cb0a Fixed screenshots links 2020-12-28 11:11:00 +01:00
1ba1ae498c Added Esperanto localization 2020-12-27 19:39:41 +01:00
31429b6344 Translated using Weblate (Swedish)
Currently translated at 100.0% (388 of 388 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-12-27 06:32:19 +01:00
5719cb5a35 Merge branch 'origin/master' into Weblate. 2020-12-27 02:49:08 +01:00
73aab44848 Localization update 2020-12-27 02:48:47 +01:00
e2360f8fb2 Merge branch 'origin/master' into Weblate. 2020-12-27 00:16:20 +01:00
08fc8ff6c4 Fixed cut&paste error 2020-12-27 00:15:41 +01:00
78d6ae6838 Merge branch 'origin/master' into Weblate. 2020-12-27 00:14:49 +01:00
0ae55e1511 Improved projection settings layout 2020-12-27 00:14:28 +01:00
e0be482d65 Merge branch 'origin/master' into Weblate. 2020-12-27 00:01:23 +01:00
4f22c50510 Properly handle return values 2020-12-27 00:00:59 +01:00
3bc5adec73 Merge branch 'origin/master' into Weblate. 2020-12-26 19:57:42 +01:00
a17110782a Added KMZ maps info 2020-12-26 19:57:25 +01:00
1d5f5ccffd Merge branch 'origin/master' into Weblate. 2020-12-26 19:54:21 +01:00
e1e3800f72 Use the same icons for KML and KMZ
(soon we are out of colors anyway...)
2020-12-26 19:53:23 +01:00
a1a67fd03f Merge branch 'origin/master' into Weblate. 2020-12-26 14:46:20 +01:00
b12eef7366 Use a better data descriptions 2020-12-26 14:45:38 +01:00
a3071eb022 Merge branch 'origin/master' into Weblate. 2020-12-26 14:30:35 +01:00
821790fa91 Code cleanup 2020-12-26 14:30:18 +01:00
4d0cf66925 Merge branch 'origin/master' into Weblate. 2020-12-26 00:41:13 +01:00
598d21077e Translated using Weblate (Esperanto)
Currently translated at 95.0% (367 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/eo/
2020-12-26 00:41:13 +01:00
763d634934 Translated using Weblate (Swedish)
Currently translated at 100.0% (386 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-12-26 00:41:11 +01:00
336f3741d8 Cosmetics 2020-12-26 00:40:57 +01:00
b6357cfab6 Merge branch 'origin/master' into Weblate. 2020-12-25 19:50:49 +01:00
248695ac04 Added KMZ maps info 2020-12-25 19:50:46 +01:00
ab4944b296 Merge branch 'origin/master' into Weblate. 2020-12-25 19:48:10 +01:00
d116508d73 Added Windows and Linux KMZ desktop integration 2020-12-25 19:47:37 +01:00
efec3ce4f4 Merge branch 'origin/master' into Weblate. 2020-12-25 18:42:28 +01:00
23c7d8e585 Translated using Weblate (Ukrainian)
Currently translated at 97.9% (378 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-12-25 18:42:28 +01:00
ec86692ea9 Translated using Weblate (Russian)
Currently translated at 100.0% (386 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-12-25 18:42:28 +01:00
3237146b78 Translated using Weblate (Finnish)
Currently translated at 100.0% (386 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-12-25 18:42:28 +01:00
fbf81e8861 Added Esperanto localization stub 2020-12-25 18:42:12 +01:00
5bf9ee7bec Translated using Weblate (Czech)
Currently translated at 100.0% (386 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/cs/
2020-12-25 16:17:22 +01:00
652d6cf97c Removed obsolete/duplicit entries 2020-12-25 16:05:51 +01:00
a36068c207 Merge remote-tracking branch 'weblate/master' 2020-12-25 16:00:01 +01:00
8e5fcfa0b2 Translated using Weblate (Norwegian Bokmål)
Currently translated at 98.9% (382 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2020-12-25 15:12:09 +01:00
f1375fb7f8 Translated using Weblate (Finnish)
Currently translated at 100.0% (386 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-12-25 15:12:09 +01:00
c98315a7b7 Updated localizations with fixed typo 2020-12-25 15:11:51 +01:00
b90dfc963f Translated using Weblate (Norwegian Bokmål)
Currently translated at 97.6% (377 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2020-12-25 11:08:06 +01:00
a7bbfb0995 Merge branch 'origin/master' into Weblate. 2020-12-25 09:13:20 +01:00
eca7ca44ee Translated using Weblate (Ukrainian)
Currently translated at 97.4% (376 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-12-25 09:13:20 +01:00
56a68689b4 Translated using Weblate (Russian)
Currently translated at 100.0% (386 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-12-25 09:13:20 +01:00
16e7de8a0d Translated using Weblate (Finnish)
Currently translated at 98.9% (382 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-12-25 09:13:20 +01:00
977ba58570 Fixed typo 2020-12-25 09:13:11 +01:00
0d8e46cad0 Translated using Weblate (Turkish)
Currently translated at 100.0% (386 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-12-24 21:28:56 +01:00
14cf94d393 Translated using Weblate (Hungarian)
Currently translated at 100.0% (386 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-12-24 21:28:55 +01:00
88763ba1ca Translated using Weblate (Swedish)
Currently translated at 100.0% (386 of 386 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-12-24 21:20:47 +01:00
d74693327d Localization update 2020-12-24 16:34:32 +01:00
dde8e9a22c Make the source projection of JNX and KMZ maps selectable 2020-12-24 16:33:17 +01:00
50d4ca1690 Added missing devel package 2020-12-24 00:06:29 +01:00
07894f3a55 Various KMZ map fixes 2020-12-23 23:05:12 +01:00
86dd6ed772 Fixed typos 2020-12-22 22:50:46 +01:00
d01a5a7e42 Added support for KMZ maps 2020-12-22 22:32:07 +01:00
97bea8c56c Added support for Qt6
Removed support for Qt4 and Qt5 < 5.12
2020-12-22 22:09:09 +01:00
b5972c8328 Added BSB charts support info 2020-12-16 00:25:31 +01:00
4fd0ca0b11 Added polyconic projection license info 2020-12-16 00:15:57 +01:00
84d5673e17 Merge branch 'origin/master' into Weblate. 2020-12-15 21:51:38 +01:00
e40836e6bb Added missing file associations + icons 2020-12-15 21:51:08 +01:00
88aef38f9d Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-12-15 02:29:30 +01:00
7d8dcec88b Try to break even less bounding box transformations 2020-12-14 22:06:59 +01:00
561d8362a9 Fixed projection comparison 2020-12-14 22:04:50 +01:00
7f9fde76e9 Merge branch 'origin/master' into Weblate. 2020-12-13 19:41:17 +01:00
239e571358 Provide propper map bounds for overviews 2020-12-13 19:40:09 +01:00
44b28e3d4d Merge branch 'origin/master' into Weblate. 2020-12-12 10:20:19 +01:00
4cef089c81 A more robust RectC to RectD algorithm 2020-12-12 10:19:48 +01:00
05ac5ccedb Merge branch 'origin/master' into Weblate. 2020-12-10 22:02:22 +01:00
22fb6071f7 Refactoring 2020-12-10 22:02:09 +01:00
2c78772a67 Merge branch 'origin/master' into Weblate. 2020-12-10 01:09:42 +01:00
0f03ef4af7 Yet another map load crash fix 2020-12-10 01:09:23 +01:00
351cc49ec9 Merge branch 'origin/master' into Weblate. 2020-12-09 23:08:07 +01:00
743a937f41 Fixed crashing async map loading
fixes #331
2020-12-09 23:07:05 +01:00
033225502f Merge branch 'origin/master' into Weblate. 2020-12-08 21:30:37 +01:00
75b8b9eab0 Upadte linux file associations 2020-12-08 21:30:17 +01:00
e76e7b71ed Check for duplicit map loads 2020-12-08 21:29:20 +01:00
41ea07d020 Merge branch 'origin/master' into Weblate. 2020-12-08 01:13:05 +01:00
4bad086152 Enable maps drag&drop 2020-12-08 01:12:39 +01:00
8be088be0a Merge branch 'origin/master' into Weblate. 2020-12-08 01:01:57 +01:00
73021bec01 Added "Open with GPXSee" associations 2020-12-08 01:01:26 +01:00
7584116168 Removed cut&paste remains 2020-12-08 00:59:18 +01:00
59b734c402 Cosmetics 2020-12-08 00:58:01 +01:00
8168d52f09 Merge branch 'origin/master' into Weblate. 2020-12-06 23:32:07 +01:00
74796e3e41 Only trigger the last maploaded 2020-12-06 23:31:45 +01:00
676024854a Merge branch 'origin/master' into Weblate. 2020-12-06 19:18:14 +01:00
10e1b5c4fb Open map files passed as program arguments
closes #327
2020-12-06 19:17:09 +01:00
54570ed97e Merge branch 'origin/master' into Weblate. 2020-12-06 13:05:35 +01:00
07fa377e38 Remove the weired file lists copies
It used to be written in the Qt4 documentation to iterate over a copy, but
there is aparently no real reason doing that...
2020-12-06 13:03:32 +01:00
2b8c3f64ac Only trigger the last loaded map 2020-12-06 12:53:39 +01:00
a60cccb57e Merge branch 'origin/master' into Weblate. 2020-12-06 00:12:05 +01:00
c2e50e5213 Use a smooth digital zoom 2020-12-06 00:11:47 +01:00
0ea8e008c2 Merge branch 'origin/master' into Weblate. 2020-12-05 12:26:33 +01:00
082435c83d Translated using Weblate (Hungarian)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-12-05 12:26:33 +01:00
e63ad7a244 Make the maps submenus work with large amount of items 2020-12-05 12:25:59 +01:00
32a4365543 Merge branch 'origin/master' into Weblate. 2020-12-04 00:26:20 +01:00
abd1dc2450 Added support for polyconic projections 2020-12-04 00:25:57 +01:00
5674534efd Merge branch 'origin/master' into Weblate. 2020-12-03 21:15:19 +01:00
33287f9d76 Translated using Weblate (Hungarian)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-12-03 21:15:18 +01:00
1dfe84c4af Translated using Weblate (Ukrainian)
Currently translated at 98.4% (377 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-12-03 21:15:18 +01:00
7fe8d204bc Translated using Weblate (Turkish)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-12-03 21:15:18 +01:00
5080247e10 Translated using Weblate (Russian)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-12-03 21:15:18 +01:00
13d6c7c643 Translated using Weblate (Finnish)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-12-03 21:15:17 +01:00
547d7a5f23 Fix the POI search algorithm
(At least so, that it does not trigger the rtree assert. The whole RectC logic
has to be fixed to properly handle poles/dateline "overflows")
2020-12-03 21:12:41 +01:00
9e03d85b7a Fixed actions logic 2020-12-03 20:58:22 +01:00
b811132394 Translated using Weblate (Swedish)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-12-03 06:51:47 +01:00
ca33328d99 Merge branch 'origin/master' into Weblate. 2020-12-03 00:11:58 +01:00
41c8a4d935 Version++ 2020-12-03 00:11:49 +01:00
acd09400be Localization update 2020-12-03 00:10:24 +01:00
16bfd593c7 Merge branch 'origin/master' into Weblate. 2020-12-02 23:58:59 +01:00
9e70a1ffbb Added the "Load map dir" feature 2020-12-02 23:58:11 +01:00
1b590fbf76 Merge branch 'origin/master' into Weblate. 2020-12-02 20:51:37 +01:00
8d52dbf59f Fixed issue with Mercator projections 2020-12-02 20:51:19 +01:00
c6fd32fc61 Merge branch 'origin/master' into Weblate. 2020-12-01 20:17:58 +01:00
af6082425e Propper map size must be known from the start 2020-12-01 20:17:19 +01:00
785123f005 Merge branch 'origin/master' into Weblate. 2020-12-01 19:04:34 +01:00
df3ee11f42 Properly handle skewed charts 2020-12-01 19:03:58 +01:00
6af1ff35ab Merge branch 'origin/master' into Weblate. 2020-11-28 20:34:53 +01:00
8423fc1230 Remove the untested and broken NOS stuff 2020-11-28 20:34:25 +01:00
a62d84da67 Merge branch 'origin/master' into Weblate. 2020-11-28 14:50:31 +01:00
2431f432d4 Use the right Mercator 2020-11-28 14:50:10 +01:00
6c4ebc40ca Merge branch 'origin/master' into Weblate. 2020-11-28 14:48:55 +01:00
0cc6908b30 Fixed broken projection comparsion
+ refactoring/code cleanup
2020-11-28 14:48:20 +01:00
becf57e4eb Merge branch 'origin/master' into Weblate. 2020-11-27 01:12:51 +01:00
96733883cb Added support for BSB charts maps 2020-11-27 01:11:50 +01:00
973c086029 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-11-25 17:29:14 +01:00
158 changed files with 12084 additions and 6112 deletions

View File

@ -1,21 +1,21 @@
version: 7.37.{build}
version: 8.1.{build}
configuration:
- Release
image:
- Visual Studio 2017
- Visual Studio 2019
environment:
NSISDIR: C:\Program Files (x86)\NSIS
matrix:
- QTDIR: C:\Qt\5.13\msvc2017
- QTDIR: C:\Qt\5.15\msvc2019
NSI: gpxsee.nsi
VCVARS: vcvars32.bat
OPENSSLDIR: C:\OpenSSL-v111-Win32\bin
LIBCRYPTO: libssl-1_1.dll
LIBSSL: libcrypto-1_1.dll
- QTDIR: C:\Qt\5.13\msvc2017_64
- QTDIR: C:\Qt\5.15\msvc2019_64
NSI: gpxsee64.nsi
VCVARS: vcvars64.bat
OPENSSLDIR: C:\OpenSSL-v111-Win64\bin
@ -26,7 +26,7 @@ install:
- cmd: >-
set PATH=%QTDIR%\bin;%NSISDIR%;%PATH%
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\"%VCVARS%
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\"%VCVARS%
build_script:
- cmd: >-

View File

@ -4,13 +4,15 @@ os:
- linux
- osx
dist: focal
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install qt; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libqt4-dev libqt4-opengl-dev; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install qtbase5-dev qtbase5-private-dev libqt5opengl5-dev qttools5-dev-tools; fi
script:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then PATH=/usr/local/opt/qt/bin/:${PATH}; fi

View File

@ -4,7 +4,7 @@ GPXSee is a Qt-based GPS log file viewer and analyzer that supports all common G
## Features
* Opens GPX, TCX, FIT, KML, NMEA, IGC, CUP, SIGMA SLF, Suunto SML, LOC, GeoJSON, OziExplorer (PLT, RTE, WPT), Garmin GPI&CSV and geotagged JPEG files.
* User-definable online maps (OpenStreetMap/Google tiles, WMTS, WMS, TMS, QuadTiles).
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases, Garmin IMG/GMAP & JNX maps, TwoNav RMaps, GeoTIFF images).
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases, Garmin IMG/GMAP & JNX maps, TwoNav RMaps, GeoTIFF images, BSB charts, KMZ maps).
* Elevation, speed, heart rate, cadence, power, temperature and gear ratio/shifts graphs.
* Support for DEM files (SRTM HGT).
* Support for multiple tracks in one view.
@ -18,8 +18,8 @@ GPXSee is a Qt-based GPS log file viewer and analyzer that supports all common G
## Build
Build requirements:
* Qt 4.8 or QT 5.x (Qt >= 5.10.1 recommended for all features)
* C++03 or newer compiler (tested: msvc2015, gcc >= 4.8, clang/Apple LLVM version 8.1.0)
* Qt5 >= 5.11 or Qt 6.x
* C++11 or newer compiler (tested: msvc2017, gcc 7.5.0, clang/Apple LLVM version 10.0.0)
Build steps:
```shell
@ -51,6 +51,7 @@ licenses:
* [Mapbox Maki icons](icons/POI) - CC0
* [RTree implementation](src/common/rtree.h) - Public domain
* [Albers](src/map/albersequal.cpp), [Geocentric](src/map/geocentric.cpp), [LCC](src/map/lambertconic.cpp),
[Mercator](src/map/mercator.cpp), [Polar Stereographic](src/map/polarstereographic.cpp)
and [Transverse Mercator](src/map/transversemercator.cpp) projections - NIMA Source Code Disclaimer
[Mercator](src/map/mercator.cpp), [Polar Stereographic](src/map/polarstereographic.cpp),
[Polyconic](src/map/polyconic.cpp) and [Transverse Mercator](src/map/transversemercator.cpp)
projections - NIMA Source Code Disclaimer
* [Projection parameters CSV files](pkg/csv) - BSD/EPSG/Public domain

View File

@ -3,32 +3,32 @@ unix:!macx {
} else {
TARGET = GPXSee
}
VERSION = 7.37
VERSION = 8.1
QT += core \
gui \
gui-private \
network \
sql \
concurrent
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets
QT += printsupport
}
lessThan(QT_MAJOR_VERSION, 5) {QT += opengl}
equals(QT_MAJOR_VERSION, 5) : lessThan(QT_MINOR_VERSION, 4) {QT += opengl}
concurrent \
widgets \
printsupport
greaterThan(QT_MAJOR_VERSION, 5) {QT += openglwidgets}
INCLUDEPATH += ./src
HEADERS += src/common/config.h \
src/GUI/axislabelitem.h \
src/GUI/graphicsscene.h \
src/GUI/mapaction.h \
src/GUI/mapitem.h \
src/GUI/marginswidget.h \
src/GUI/planeitem.h \
src/GUI/popup.h \
src/common/garmin.h \
src/common/staticassert.h \
src/common/coordinates.h \
src/common/range.h \
src/common/rectc.h \
src/common/textcodec.h \
src/common/wgs84.h \
src/common/util.h \
src/common/rtree.h \
@ -56,7 +56,6 @@ HEADERS += src/common/config.h \
src/GUI/heartrategraph.h \
src/GUI/trackinfo.h \
src/GUI/fileselectwidget.h \
src/GUI/margins.h \
src/GUI/temperaturegraph.h \
src/GUI/graphtab.h \
src/GUI/trackitem.h \
@ -72,7 +71,6 @@ HEADERS += src/common/config.h \
src/GUI/optionsdialog.h \
src/GUI/colorbox.h \
src/GUI/stylecombobox.h \
src/GUI/opengl.h \
src/GUI/timetype.h \
src/GUI/percentslider.h \
src/GUI/elevationgraphitem.h \
@ -84,7 +82,6 @@ HEADERS += src/common/config.h \
src/GUI/gearratiographitem.h \
src/GUI/oddspinbox.h \
src/GUI/settings.h \
src/GUI/cpuarch.h \
src/GUI/searchpointer.h \
src/GUI/mapview.h \
src/GUI/font.h \
@ -103,6 +100,10 @@ HEADERS += src/common/config.h \
src/map/IMG/rastertile.h \
src/map/IMG/textpathitem.h \
src/map/IMG/textpointitem.h \
src/map/bsbmap.h \
src/map/invalidmap.h \
src/map/kmzmap.h \
src/map/polyconic.h \
src/map/projection.h \
src/map/ellipsoid.h \
src/map/datum.h \
@ -203,14 +204,19 @@ HEADERS += src/common/config.h \
src/data/address.h \
src/data/smlparser.h \
src/GUI/pdfexportdialog.h \
src/GUI/pngexportdialog.h
src/GUI/pngexportdialog.h \
src/data/geojsonparser.h \
src/GUI/timezoneinfo.h
SOURCES += src/main.cpp \
src/GUI/axislabelitem.cpp \
src/GUI/mapitem.cpp \
src/GUI/marginswidget.cpp \
src/GUI/popup.cpp \
src/common/coordinates.cpp \
src/common/rectc.cpp \
src/common/range.cpp \
src/common/textcodec.cpp \
src/common/util.cpp \
src/common/greatcircle.cpp \
src/common/programpaths.cpp \
@ -271,11 +277,14 @@ SOURCES += src/main.cpp \
src/map/IMG/rastertile.cpp \
src/map/IMG/textpathitem.cpp \
src/map/IMG/textpointitem.cpp \
src/map/bsbmap.cpp \
src/map/kmzmap.cpp \
src/map/maplist.cpp \
src/map/onlinemap.cpp \
src/map/downloader.cpp \
src/map/emptymap.cpp \
src/map/ozimap.cpp \
src/map/polyconic.cpp \
src/map/tar.cpp \
src/map/atlas.cpp \
src/map/ozf.cpp \
@ -354,19 +363,11 @@ SOURCES += src/main.cpp \
src/data/gpiparser.cpp \
src/data/smlparser.cpp \
src/GUI/pdfexportdialog.cpp \
src/GUI/pngexportdialog.cpp
greaterThan(QT_MAJOR_VERSION, 4) {
HEADERS += src/data/geojsonparser.h
SOURCES += src/data/geojsonparser.cpp
}
equals(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 4) {
HEADERS += src/GUI/timezoneinfo.h
}
src/GUI/pngexportdialog.cpp \
src/data/geojsonparser.cpp
DEFINES += APP_VERSION=\\\"$$VERSION\\\" \
QT_NO_DEPRECATED_WARNINGS
DEFINES *= QT_USE_QSTRINGBUILDER
RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_en.ts \
@ -384,7 +385,8 @@ TRANSLATIONS = lang/gpxsee_en.ts \
lang/gpxsee_pt_BR.ts \
lang/gpxsee_uk.ts \
lang/gpxsee_hu.ts \
lang/gpxsee_it.ts
lang/gpxsee_it.ts \
lang/gpxsee_eo.ts
macx {
ICON = icons/app/gpxsee.icns
@ -425,7 +427,13 @@ macx {
icons/formats/json.icns \
icons/formats/cup.icns \
icons/formats/gpi.icns \
icons/formats/sml.icns
icons/formats/sml.icns \
icons/formats/img.icns \
icons/formats/jnx.icns \
icons/formats/kap.icns \
icons/formats/mbts.icns \
icons/formats/rmap.icns \
icons/formats/tba.icns
QMAKE_BUNDLE_DATA += locale maps icons csv
}
@ -445,7 +453,14 @@ win32 {
icons/formats/json.ico \
icons/formats/cup.ico \
icons/formats/gpi.ico \
icons/formats/sml.ico
icons/formats/sml.ico \
icons/formats/img.ico \
icons/formats/jnx.ico \
icons/formats/kap.ico \
icons/formats/map.ico \
icons/formats/mbts.ico \
icons/formats/rmap.ico \
icons/formats/tba.ico
DEFINES += _USE_MATH_DEFINES \
NOGDI
}

BIN
icons/formats/img.icns Normal file

Binary file not shown.

BIN
icons/formats/img.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

BIN
icons/formats/jnx.icns Normal file

Binary file not shown.

BIN
icons/formats/jnx.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

BIN
icons/formats/kap.icns Normal file

Binary file not shown.

BIN
icons/formats/kap.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

BIN
icons/formats/map.icns Normal file

Binary file not shown.

BIN
icons/formats/map.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

BIN
icons/formats/mbts.icns Normal file

Binary file not shown.

BIN
icons/formats/mbts.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

BIN
icons/formats/rmap.icns Normal file

Binary file not shown.

BIN
icons/formats/rmap.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

View File

@ -13,3 +13,10 @@ slf:#881199
cup:#20a810
gpi:#fca314
sml:#6434eb
img:#cf0a0a
jnx:#aeff00
kap:#080045
map:#f6ff00
mbts:#ff0062
rmap:#145cba
tba:#367050

BIN
icons/formats/tba.icns Normal file

Binary file not shown.

BIN
icons/formats/tba.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2083
lang/gpxsee_eo.ts Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/tcx+xml</string>
<string>application/vnd.garmin.tcx+xml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/tcx.icns</string>
@ -67,6 +67,22 @@
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>kmz</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.google-earth.kmz</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/kml.icns</string>
<key>CFBundleTypeName</key>
<string>KML geographic compressed data</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
@ -74,7 +90,7 @@
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/loc+xml</string>
<string>application/vnd.groundspeak.loc+xml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/loc.icns</string>
@ -90,7 +106,7 @@
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/slf+xml</string>
<string>application/vnd.sigma.slf+xml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/slf.icns</string>
@ -250,7 +266,7 @@
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/sml+xml</string>
<string>application/vnd.suunto.sml+xml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/sml.icns</string>
@ -259,6 +275,193 @@
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>jpeg</string>
<string>jpg</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>image/jpeg</string>
</array>
<key>CFBundleTypeName</key>
<string>JPEG Image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>csv</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>text/csv</string>
</array>
<key>CFBundleTypeName</key>
<string>Comma-Separated Values (CSV) Files</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>img</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.garmin.img</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/img.icns</string>
<key>CFBundleTypeName</key>
<string>Garmin IMG Map</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>gmap</string>
<string>gmapi</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.garmin.gmap</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/img.icns</string>
<key>CFBundleTypeName</key>
<string>Garmin Map Product File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>jnx</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.garmin.jnx</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/jnx.icns</string>
<key>CFBundleTypeName</key>
<string>Garmin JNX Map</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>kap</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.maptech.kap</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/kap.icns</string>
<key>CFBundleTypeName</key>
<string>BSB Nautical Charts</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>map</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.oziexplorer.map</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/map.icns</string>
<key>CFBundleTypeName</key>
<string>OziExplorer Map File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>rmap</string>
<string>rtmap</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.twonav.rmap</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/rmap.icns</string>
<key>CFBundleTypeName</key>
<string>TwoNav Raster Map File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>tba</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.trekbuddy.tba</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/tba.icns</string>
<key>CFBundleTypeName</key>
<string>TrekBuddy Atlas</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>mbtiles</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.mapbox.mbtiles</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/mbts.icns</string>
<key>CFBundleTypeName</key>
<string>MBTiles Map File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>tiff</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>image/tiff</string>
</array>
<key>CFBundleTypeName</key>
<string>GeoTIFF Image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>xml</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.gpxsee.map+xml</string>
</array>
<key>CFBundleTypeName</key>
<string>GPXSee Map Definition File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>UTImportedTypeDeclarations</key>
@ -302,7 +505,7 @@
<string>tcx</string>
</array>
<key>public.mime-type</key>
<string>application/tcx+xml</string>
<string>application/vnd.garmin.tcx+xml</string>
</dict>
</dict>
<dict>
@ -326,6 +529,27 @@
<string>application/vnd.google-earth.kml+xml</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.google.kmz</string>
<key>UTTypeReferenceURL</key>
<string>https://developers.google.com/kml/documentation/kmlreference</string>
<key>UTTypeDescription</key>
<string>KML geographic compressed data</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.archive</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>kmz</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.google-earth.kmz</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.geocaching.loc</string>
@ -344,7 +568,7 @@
<string>loc</string>
</array>
<key>public.mime-type</key>
<string>application/loc+xml</string>
<string>application/vnd.groundspeak.loc+xml</string>
</dict>
</dict>
<dict>
@ -365,7 +589,7 @@
<string>slf</string>
</array>
<key>public.mime-type</key>
<string>application/slf+xml</string>
<string>application/vnd.sigma.slf+xml</string>
</dict>
</dict>
<dict>
@ -575,7 +799,269 @@
<string>sml</string>
</array>
<key>public.mime-type</key>
<string>application/sml+xml</string>
<string>application/vnd.suunto.sml+xml</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>public.jpeg</string>
<key>UTTypeReferenceURL</key>
<string>http://www.w3.org/Graphics/JPEG/</string>
<key>UTTypeDescription</key>
<string>JPEG Image</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.image</string>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>jpeg</string>
<string>jpg</string>
</array>
<key>public.mime-type</key>
<string>image/jpeg</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>public.csv</string>
<key>UTTypeReferenceURL</key>
<string>https://tools.ietf.org/html/rfc4180</string>
<key>UTTypeDescription</key>
<string>Comma-Separated Values (CSV) Files</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>csv</string>
</array>
<key>public.mime-type</key>
<string>text/csv</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.garmin.img</string>
<key>UTTypeReferenceURL</key>
<string>https://sourceforge.net/projects/garmin-img/</string>
<key>UTTypeDescription</key>
<string>Garmin IMG map</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>img</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.garmin.img</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.garmin.jnx</string>
<key>UTTypeReferenceURL</key>
<string>http://whiter.brinkster.net/en/JNX.shtml</string>
<key>UTTypeDescription</key>
<string>Garmin JNX Map</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>jnx</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.garmin.jnx</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.garmin.gmap</string>
<key>UTTypeReferenceURL</key>
<string>https://sourceforge.net/projects/garmin-img/</string>
<key>UTTypeDescription</key>
<string>Garmin Map Product File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>xml</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.garmin.gmap</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.maptech.kap</string>
<key>UTTypeReferenceURL</key>
<string>http://libbsb.sourceforge.net/bsb_file_format.html</string>
<key>UTTypeDescription</key>
<string>BSB Nautical Charts</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.image</string>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>kap</string>
</array>
<key>public.mime-type</key>
<string>image/vnd.maptech.kap</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.oziexplorer3.map</string>
<key>UTTypeReferenceURL</key>
<string>https://www.oziexplorer3.com/eng/help/map_file_format.html</string>
<key>UTTypeDescription</key>
<string>OziExplorer Map File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>map</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.oziexplorer.map</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.mapbox.mbtiles</string>
<key>UTTypeReferenceURL</key>
<string>https://github.com/mapbox/mbtiles-spec</string>
<key>UTTypeDescription</key>
<string>MBTiles Map File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>mbtiles</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.mapbox.mbtiles</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.twonav.rmap</string>
<key>UTTypeReferenceURL</key>
<string>https://wiki.openstreetmap.org/wiki/TwoNav_RMAP</string>
<key>UTTypeDescription</key>
<string>TwoNav Raster Map File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>rmap</string>
<string>rtmap</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.twonav.rmap</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>net.trekbuddy.tba</string>
<key>UTTypeReferenceURL</key>
<string>https://github.com/kruhc/trekbuddy</string>
<key>UTTypeDescription</key>
<string>TrekBuddy Atlas</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>tba</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.trekbuddy.tba</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>public.tiff</string>
<key>UTTypeReferenceURL</key>
<string>https://www.adobe.io/open/standards/TIFF.html</string>
<key>UTTypeDescription</key>
<string>TIFF Image</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.image</string>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>tiff</string>
<string>tif</string>
</array>
<key>public.mime-type</key>
<string>image/tiff</string>
</dict>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>org.gpxsee.map</string>
<key>UTTypeReferenceURL</key>
<string>http://www.gpxsee.org/map/1.4/</string>
<key>UTTypeDescription</key>
<string>GPXSee Map Definition File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>xml</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.gpxsee.map+xml</string>
</dict>
</dict>
</array>

View File

@ -18,13 +18,14 @@
<li>User-definable online maps (OpenStreetMap/Google tiles, WMTS,
WMS, TMS, QuadTiles).</li>
<li>Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
TwoNav RMaps, Garmin IMG &amp; JNX, GeoTIFF images).</li>
TwoNav RMaps, Garmin IMG &amp; JNX maps, GeoTIFF images,
BSB nautical charts, KMZ maps).</li>
<li>Elevation, speed, heart rate, cadence, power, temperature and
gear ratio graphs.</li>
<li>Support for multiple tracks in one view.</li>
<li>Support for POI files.</li>
<li>Support for DEM files (SRTM HGT).</li>
<li>Print/export to PDF.</li>
<li>Print/export to PDF &amp; PNG.</li>
<li>Full-screen mode.</li>
<li>HiDPI/Retina displays &amp; maps support.</li>
</ul>
@ -32,10 +33,10 @@
<screenshots>
<screenshot type="default">
<image>http://www.gpxsee.org/gallery/lin1.png</image>
<image>https://www.gpxsee.org/gallery/linux.png</image>
</screenshot>
<screenshot>
<image>http://www.gpxsee.org/gallery/lin2.png</image>
<image>https://www.gpxsee.org/gallery/poi2.png</image>
</screenshot>
</screenshots>
@ -48,7 +49,7 @@
<category>DataVisualization</category>
</categories>
<url type="homepage">http://www.gpxsee.org</url>
<url type="homepage">https://www.gpxsee.org</url>
<launchable type="desktop-id">gpxsee.desktop</launchable>
@ -58,7 +59,7 @@
<mimetypes>
<mimetype>application/gpx+xml</mimetype>
<mimetype>application/tcx+xml</mimetype>
<mimetype>application/vnd.garmin.tcx+xml</mimetype>
<mimetype>application/vnd.ant.fit</mimetype>
<mimetype>application/vnd.google-earth.kml+xml</mimetype>
<mimetype>application/vnd.fai.igc</mimetype>
@ -66,11 +67,25 @@
<mimetype>application/vnd.oziexplorer.plt</mimetype>
<mimetype>application/vnd.oziexplorer.rte</mimetype>
<mimetype>application/vnd.oziexplorer.wpt</mimetype>
<mimetype>application/loc+xml</mimetype>
<mimetype>application/slf+xml</mimetype>
<mimetype>application/vnd.groundspeak.loc+xml</mimetype>
<mimetype>application/vnd.sigma.slf+xml</mimetype>
<mimetype>application/geo+json</mimetype>
<mimetype>application/vnd.naviter.seeyou.cup</mimetype>
<mimetype>application/vnd.garmin.gpi</mimetype>
<mimetype>application/sml+xml</mimetype>
<mimetype>application/vnd.suunto.sml+xml</mimetype>
<mimetype>image/jpeg</mimetype>
<mimetype>text/csv</mimetype>
<mimetype>application/vnd.garmin.img</mimetype>
<mimetype>application/vnd.garmin.jnx</mimetype>
<mimetype>application/vnd.garmin.gmap+xml</mimetype>
<mimetype>image/vnd.maptech.kap</mimetype>
<mimetype>application/vnd.oziexplorer.map</mimetype>
<mimetype>application/vnd.mapbox.mbtiles</mimetype>
<mimetype>application/vnd.twonav.rmap</mimetype>
<mimetype>application/vnd.trekbuddy.tba</mimetype>
<mimetype>application/vnd.gpxsee.map+xml</mimetype>
<mimetype>application/x-tar</mimetype>
<mimetype>image/tiff</mimetype>
<mimetype>application/vnd.google-earth.kmz</mimetype>
</mimetypes>
</component>

View File

@ -1887,6 +1887,7 @@ CI1971 / Chatham Islands Map Grid,5518,4672,5517,9001,9807,4500,8801,-44,9110,88
CI1979 / Chatham Islands Map Grid,5519,4673,5517,9001,9807,4500,8801,-44,9110,8802,-176.3,9110,8805,1,9201,8806,350000,9001,8807,650000,9001,,,,,,
DHDN / 3-degree Gauss-Kruger zone 1,5520,4314,16261,9001,9807,4530,8801,0,9102,8802,3,9102,8805,1,9201,8806,1500000,9001,8807,0,9001,,,,,,
WGS 84 / Gabon TM 2011,5523,4326,5522,9001,9807,4499,8801,0,9102,8802,11.3,9110,8805,0.9996,9201,8806,1500000,9001,8807,5500000,9001,,,,,,
SAD69(96) / Brazil Polyconic,5530,5527,19941,9001,9818,4499,8801,0,9102,8802,-54,9102,8806,5000000,9001,8807,10000000,9001,,,,,,,,,
SAD69(96) / UTM zone 21S,5531,5527,16121,9001,9807,4400,8801,0,9102,8802,-57,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
SAD69(96) / UTM zone 22S,5532,4618,16122,9001,9807,4400,8801,0,9102,8802,-51,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
SAD69(96) / UTM zone 23S,5533,5527,16123,9001,9807,4400,8801,0,9102,8802,-45,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
@ -1970,6 +1971,7 @@ SAD69(96) / UTM zone 18S,5875,5527,16118,9001,9807,4400,8801,0,9102,8802,-75,910
SAD69(96) / UTM zone 19S,5876,5527,16119,9001,9807,4400,8801,0,9102,8802,-69,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
SAD69(96) / UTM zone 20S,5877,5527,16120,9001,9807,4400,8801,0,9102,8802,-63,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
Cadastre 1997 / UTM zone 38S,5879,4475,16138,9001,9807,4400,8801,0,9102,8802,45,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
SIRGAS 2000 / Brazil Polyconic,5880,4674,19941,9001,9818,4499,8801,0,9102,8802,-54,9102,8806,5000000,9001,8807,10000000,9001,,,,,,,,,
WGS 84 / EPSG Arctic Regional zone A1,5921,4326,5906,9001,9802,4400,8821,81.19020136,9110,8822,-111,9102,8823,85,9102,8824,77,9102,8826,0,9001,8827,0,9001,,,
WGS 84 / EPSG Arctic Regional zone A2,5922,4326,5907,9001,9802,4400,8821,81.19020136,9110,8822,-39,9102,8823,85,9102,8824,77,9102,8826,0,9001,8827,0,9001,,,
WGS 84 / EPSG Arctic Regional zone A3,5923,4326,5908,9001,9802,4400,8821,81.19020136,9110,8822,33,9102,8823,85,9102,8824,77,9102,8826,0,9001,8827,0,9001,,,
@ -3046,6 +3048,8 @@ Pulkovo 1942 / Gauss-Kruger 32N,28492,4284,16332,9001,9807,4530,8801,0,9102,8802
Qatar 1974 / Qatar National Grid,28600,4285,19919,9001,9807,4400,8801,24.27,9110,8802,51.13,9110,8805,0.99999,9201,8806,200000,9001,8807,300000,9001,,,,,,
Amersfoort / RD Old,28991,4289,19913,9001,9809,4499,8801,52.0922178,9110,8802,5.23155,9110,8805,0.9999079,9201,8806,0,9001,8807,0,9001,,,,,,
Amersfoort / RD New,28992,4289,19914,9001,9809,4499,8801,52.0922178,9110,8802,5.23155,9110,8805,0.9999079,9201,8806,155000,9001,8807,463000,9001,,,,,,
SAD69 / Brazil Polyconic,29100,4291,19941,9001,9818,4499,8801,0,9102,8802,-54,9102,8806,5000000,9001,8807,10000000,9001,,,,,,,,,
SAD69 / Brazil Polyconic,29101,4618,19941,9001,9818,4499,8801,0,9102,8802,-54,9102,8806,5000000,9001,8807,10000000,9001,,,,,,,,,
SAD69 / UTM zone 18N,29118,4291,16018,9001,9807,4400,8801,0,9102,8802,-75,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,,,,
SAD69 / UTM zone 19N,29119,4291,16019,9001,9807,4400,8801,0,9102,8802,-69,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,,,,
SAD69 / UTM zone 20N,29120,4291,16020,9001,9807,4400,8801,0,9102,8802,-63,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,,,,

Can't render this file because it is too large.

View File

@ -15,4 +15,4 @@ Icon=gpxsee
Terminal=false
Type=Application
Categories=Graphics;Viewer;Education;Geography;Maps;Sports;Qt;
MimeType=application/gpx+xml;application/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/loc+xml;application/slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/sml+xml;
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;

View File

@ -7,7 +7,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "7.37"
!define VERSION "8.1"
; The file to write
OutFile "GPXSee-${VERSION}.exe"
@ -109,14 +109,6 @@ Section "GPXSee" SEC_APP
; Associate file formats
DetailPrint "Associating file types..."
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 8
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 9
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 10
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 11
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 12
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 13
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 14
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 15
!insertmacro FILE_ASSOCIATION_ADD "wpt" "OziExplorer Waypoint File" 1
!insertmacro FILE_ASSOCIATION_ADD "loc" "Geocaching.com Waypoint File" 2
!insertmacro FILE_ASSOCIATION_ADD "slf" "Sigma Log File" 3
@ -124,6 +116,57 @@ Section "GPXSee" SEC_APP
!insertmacro FILE_ASSOCIATION_ADD "cup" "SeeYou CUP File" 5
!insertmacro FILE_ASSOCIATION_ADD "gpi" "Garmin POI File" 6
!insertmacro FILE_ASSOCIATION_ADD "sml" "Suunto Markup Language" 7
!insertmacro FILE_ASSOCIATION_ADD "img" "Garmin IMG Map" 8
!insertmacro FILE_ASSOCIATION_ADD "jnx" "Garmin JNX Map" 9
!insertmacro FILE_ASSOCIATION_ADD "kap" "BSB Nautical Chart" 10
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 11
!insertmacro FILE_ASSOCIATION_ADD "map" "OziExplorer Map File" 12
!insertmacro FILE_ASSOCIATION_ADD "mbtiles" "MBTiles Map File" 13
!insertmacro FILE_ASSOCIATION_ADD "rmap" "TwoNav Raster Map File" 14
!insertmacro FILE_ASSOCIATION_ADD "tba" "TrekBuddy Atlas" 15
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 16
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 17
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 17
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 18
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 19
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 20
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 21
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 22
WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\""
WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tcx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".fit\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".igc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".nmea\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".plt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rte\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".wpt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".loc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".slf\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".geojson\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".cup\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".gpi\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".sml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".csv\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".json\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpeg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".img\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jnx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".map\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".mbtiles\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rtmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tar\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tba\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tif\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tiff\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".xml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kmz\OpenWithList" "GPXSee.exe" ""
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd
@ -176,6 +219,7 @@ SectionEnd
SectionGroup "Localization" SEC_LOCALIZATION
!insertmacro LOCALIZATION "Czech" "cs"
!insertmacro LOCALIZATION "Danish" "da"
!insertmacro LOCALIZATION "Esperanto" "eo"
!insertmacro LOCALIZATION "Finnish" "fi"
!insertmacro LOCALIZATION "French" "fr"
!insertmacro LOCALIZATION "German" "de"
@ -210,7 +254,7 @@ Section "Uninstall"
Delete "$SMPROGRAMS\$StartMenuFolder\*.*"
RMDir "$SMPROGRAMS\$StartMenuFolder"
; Remove GPX file association
; Remove file associations
!insertmacro FILE_ASSOCIATION_REMOVE "gpx"
!insertmacro FILE_ASSOCIATION_REMOVE "tcx"
!insertmacro FILE_ASSOCIATION_REMOVE "kml"
@ -226,6 +270,49 @@ Section "Uninstall"
!insertmacro FILE_ASSOCIATION_REMOVE "cup"
!insertmacro FILE_ASSOCIATION_REMOVE "gpi"
!insertmacro FILE_ASSOCIATION_REMOVE "sml"
!insertmacro FILE_ASSOCIATION_REMOVE "img"
!insertmacro FILE_ASSOCIATION_REMOVE "jnx"
!insertmacro FILE_ASSOCIATION_REMOVE "kap"
!insertmacro FILE_ASSOCIATION_REMOVE "map"
!insertmacro FILE_ASSOCIATION_REMOVE "mbtiles"
!insertmacro FILE_ASSOCIATION_REMOVE "rmap"
!insertmacro FILE_ASSOCIATION_REMOVE "tba"
!insertmacro FILE_ASSOCIATION_REMOVE "kmz"
DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".fit\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".igc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".nmea\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".plt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rte\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".wpt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".loc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".slf\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".geojson\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".cup\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".gpi\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".sml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".csv\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".json\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpeg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".img\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jnx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".map\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".mbtiles\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rtmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tar\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tba\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tif\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tiff\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".xml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kmz\OpenWithList" "GPXSee.exe"
DeleteRegKey HKCR "Applications\GPXSee.exe"
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd

View File

@ -1,35 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<!-- Data files -->
<mime-type type="application/gpx+xml">
<comment>GPS Exchange Format</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.topografix.com/GPX/1/0" localName="gpx"/>
<root-XML namespaceURI="http://www.topografix.com/GPX/1/1" localName="gpx"/>
<glob pattern="*.gpx"/>
</mime-type>
<mime-type type="application/tcx+xml">
<mime-type type="application/vnd.garmin.tcx+xml">
<comment>Training Center XML</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" localName="TrainingCenterDatabase"/>
<glob pattern="*.tcx"/>
</mime-type>
<mime-type type="application/kml+xml">
<mime-type type="application/vnd.google-earth.kml+xml">
<comment>Keyhole Markup Language</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.opengis.net/kml/2.2" localName="kml"/>
<glob pattern="*.kml"/>
</mime-type>
<mime-type type="application/loc+xml">
<mime-type type="application/vnd.groundspeak.loc+xml">
<comment>Geocaching.com Waypoint File</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<glob pattern="*.loc"/>
</mime-type>
<mime-type type="application/slf+xml">
<mime-type type="application/vnd.sigma.slf+xml">
<comment>Sigma Log Format</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
@ -40,6 +46,9 @@
<comment>Flexible and Interoperable Data Transfer</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application-octet-stream"/>
<magic>
<match type="string" offset="8" value=".FIT"/>
</magic>
<glob pattern="*.fit"/>
</mime-type>
@ -61,6 +70,9 @@
<comment>OziExplorer Track Point File</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="OziExplorer Track Point File"/>
</magic>
<glob pattern="*.plt"/>
</mime-type>
@ -68,6 +80,9 @@
<comment>OziExplorer Route File</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="OziExplorer Route File"/>
</magic>
<glob pattern="*.rte"/>
</mime-type>
@ -75,6 +90,9 @@
<comment>OziExplorer Waypoint File</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="OziExplorer Waypoint File"/>
</magic>
<glob pattern="*.wpt"/>
</mime-type>
@ -96,13 +114,110 @@
<comment>Garmin POI File</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application/octet-stream"/>
<magic>
<match type="string" offset="8" value="GRMREC"/>
</magic>
<glob pattern="*.gpi"/>
</mime-type>
<mime-type type="application/sml+xml">
<mime-type type="application/vnd.suunto.sml+xml">
<comment>Suunto Markup Language</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.suunto.com/schemas/sml" localName="sml"/>
<glob pattern="*.sml"/>
</mime-type>
<!-- Maps -->
<mime-type type="application/vnd.garmin.img">
<comment>Garmin IMG Map</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application-octet-stream"/>
<magic>
<match type="string" offset="16" value="DSKIMG"/>
</magic>
<glob pattern="*.img"/>
</mime-type>
<mime-type type="application/vnd.garmin.jnx">
<comment>Garmin JNX Map</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application-octet-stream"/>
<glob pattern="*.jnx"/>
</mime-type>
<mime-type type="application/vnd.garmin.gmap+xml">
<comment>Garmin Map Product File</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.garmin.com/xmlschemas/MapProduct/v1" localName="MapProduct"/>
<root-XML namespaceURI="http://www.garmin.com/xmlschemas/MapProduct/v2" localName="MapProduct"/>
<glob pattern="*.xml"/>
</mime-type>
<mime-type type="image/vnd.maptech.kap">
<comment>BSB Nautical Chart</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.kap"/>
</mime-type>
<mime-type type="application/vnd.oziexplorer.map">
<comment>OziExplorer Map File</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="OziExplorer Map Data File"/>
</magic>
<glob pattern="*.map"/>
</mime-type>
<mime-type type="application/vnd.mapbox.mbtiles">
<comment>MBTiles Map File</comment>
<sub-class-of type="application/vnd.sqlite3"/>
<generic-icon name="application/octet-stream"/>
<glob pattern="*.mbtiles"/>
</mime-type>
<mime-type type="application/vnd.twonav.rmap">
<comment>TwoNav Raster Map File</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application/octet-stream"/>
<magic>
<match type="string" offset="0" value="CompeGPSRasterImage"/>
</magic>
<glob pattern="*.rmap"/>
<glob pattern="*.rtmap"/>
</mime-type>
<mime-type type="application/vnd.trekbuddy.tba">
<comment>TrekBuddy Atlas</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="Atlas 1.0"/>
</magic>
<glob pattern="*.tba"/>
</mime-type>
<mime-type type="application/vnd.gpxsee.map+xml">
<comment>GPXSee Map Definition File</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.0" localName="map"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.1" localName="map"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.2" localName="map"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.3" localName="map"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.4" localName="map"/>
<glob pattern="*.xml"/>
</mime-type>
<mime-type type="application/vnd.google-earth.kmz">
<comment>KML geographic compressed data</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="application/zip"/>
<glob pattern="*.kmz"/>
</mime-type>
</mime-info>

View File

@ -7,7 +7,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "7.37"
!define VERSION "8.1"
; The file to write
OutFile "GPXSee-${VERSION}_x64.exe"
@ -116,14 +116,6 @@ Section "GPXSee" SEC_APP
; Associate file formats
DetailPrint "Associating file types..."
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 8
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 9
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 10
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 11
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 12
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 13
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 14
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 15
!insertmacro FILE_ASSOCIATION_ADD "wpt" "OziExplorer Waypoint File" 1
!insertmacro FILE_ASSOCIATION_ADD "loc" "Geocaching.com Waypoint File" 2
!insertmacro FILE_ASSOCIATION_ADD "slf" "Sigma Log File" 3
@ -131,6 +123,57 @@ Section "GPXSee" SEC_APP
!insertmacro FILE_ASSOCIATION_ADD "cup" "SeeYou CUP File" 5
!insertmacro FILE_ASSOCIATION_ADD "gpi" "Garmin POI File" 6
!insertmacro FILE_ASSOCIATION_ADD "sml" "Suunto Markup Language" 7
!insertmacro FILE_ASSOCIATION_ADD "img" "Garmin IMG Map" 8
!insertmacro FILE_ASSOCIATION_ADD "jnx" "Garmin JNX Map" 9
!insertmacro FILE_ASSOCIATION_ADD "kap" "BSB Nautical Chart" 10
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 11
!insertmacro FILE_ASSOCIATION_ADD "map" "OziExplorer Map File" 12
!insertmacro FILE_ASSOCIATION_ADD "mbtiles" "MBTiles Map File" 13
!insertmacro FILE_ASSOCIATION_ADD "rmap" "TwoNav Raster Map File" 14
!insertmacro FILE_ASSOCIATION_ADD "tba" "TrekBuddy Atlas" 15
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 16
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 17
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 17
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 18
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 19
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 20
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 21
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 22
WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\""
WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tcx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".fit\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".igc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".nmea\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".plt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rte\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".wpt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".loc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".slf\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".geojson\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".cup\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".gpi\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".sml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".csv\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".json\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpeg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".img\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jnx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".map\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".mbtiles\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rtmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tar\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tba\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tif\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tiff\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".xml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kmz\OpenWithList" "GPXSee.exe" ""
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd
@ -183,6 +226,7 @@ SectionEnd
SectionGroup "Localization" SEC_LOCALIZATION
!insertmacro LOCALIZATION "Czech" "cs"
!insertmacro LOCALIZATION "Danish" "da"
!insertmacro LOCALIZATION "Esperanto" "eo"
!insertmacro LOCALIZATION "Finnish" "fi"
!insertmacro LOCALIZATION "French" "fr"
!insertmacro LOCALIZATION "German" "de"
@ -218,7 +262,7 @@ Section "Uninstall"
Delete "$SMPROGRAMS\$StartMenuFolder\*.*"
RMDir "$SMPROGRAMS\$StartMenuFolder"
; Remove File associations
; Remove file associations
!insertmacro FILE_ASSOCIATION_REMOVE "gpx"
!insertmacro FILE_ASSOCIATION_REMOVE "tcx"
!insertmacro FILE_ASSOCIATION_REMOVE "kml"
@ -234,6 +278,49 @@ Section "Uninstall"
!insertmacro FILE_ASSOCIATION_REMOVE "cup"
!insertmacro FILE_ASSOCIATION_REMOVE "gpi"
!insertmacro FILE_ASSOCIATION_REMOVE "sml"
!insertmacro FILE_ASSOCIATION_REMOVE "img"
!insertmacro FILE_ASSOCIATION_REMOVE "jnx"
!insertmacro FILE_ASSOCIATION_REMOVE "kap"
!insertmacro FILE_ASSOCIATION_REMOVE "map"
!insertmacro FILE_ASSOCIATION_REMOVE "mbtiles"
!insertmacro FILE_ASSOCIATION_REMOVE "rmap"
!insertmacro FILE_ASSOCIATION_REMOVE "tba"
!insertmacro FILE_ASSOCIATION_REMOVE "kmz"
DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".fit\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".igc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".nmea\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".plt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rte\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".wpt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".loc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".slf\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".geojson\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".cup\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".gpi\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".sml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".csv\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".json\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpeg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".img\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jnx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".map\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".mbtiles\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rtmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tar\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tba\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tif\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tiff\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".xml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kmz\OpenWithList" "GPXSee.exe"
DeleteRegKey HKCR "Applications\GPXSee.exe"
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd

View File

@ -6,6 +6,7 @@
#include <QNetworkAccessManager>
#include <QLibraryInfo>
#include <QSettings>
#include <QSurfaceFormat>
#include "common/programpaths.h"
#include "common/config.h"
#include "map/downloader.h"
@ -13,9 +14,9 @@
#include "map/gcs.h"
#include "map/pcs.h"
#include "data/dem.h"
#include "opengl.h"
#include "gui.h"
#include "settings.h"
#include "mapaction.h"
#include "app.h"
@ -29,18 +30,18 @@ App::App(int &argc, char **argv) : QApplication(argc, argv)
setApplicationVersion(APP_VERSION);
QTranslator *gpxsee = new QTranslator(this);
gpxsee->load(QLocale::system(), "gpxsee", "_",
ProgramPaths::translationsDir());
installTranslator(gpxsee);
if (gpxsee->load(QLocale::system(), "gpxsee", "_",
ProgramPaths::translationsDir()))
installTranslator(gpxsee);
QTranslator *qt = new QTranslator(this);
#if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
qt->load(QLocale::system(), "qt", "_", ProgramPaths::translationsDir());
if (qt->load(QLocale::system(), "qt", "_", ProgramPaths::translationsDir()))
#else // Q_OS_WIN32 || Q_OS_MAC
qt->load(QLocale::system(), "qt", "_", QLibraryInfo::location(
QLibraryInfo::TranslationsPath));
if (qt->load(QLocale::system(), "qt", "_", QLibraryInfo::location(
QLibraryInfo::TranslationsPath)))
#endif // Q_OS_WIN32 || Q_OS_MAC
installTranslator(qt);
installTranslator(qt);
#ifdef Q_OS_MAC
setAttribute(Qt::AA_DontShowIconsInMenus);
@ -51,17 +52,18 @@ App::App(int &argc, char **argv) : QApplication(argc, argv)
"QThreadStorage: Thread X exited after QThreadStorage Y destroyed" */
Downloader::setNetworkManager(new QNetworkAccessManager(this));
DEM::setDir(ProgramPaths::demDir());
OPENGL_SET_FORMAT(4, 8);
QSurfaceFormat fmt;
fmt.setStencilBufferSize(8);
fmt.setSamples(4);
QSurfaceFormat::setDefaultFormat(fmt);
loadDatums();
loadPCSs();
QSettings settings(qApp->applicationName(), qApp->applicationName());
settings.beginGroup(OPTIONS_SETTINGS_GROUP);
#ifdef ENABLE_HTTP2
Downloader::enableHTTP2(settings.value(ENABLE_HTTP2_SETTING,
ENABLE_HTTP2_DEFAULT).toBool());
#endif // ENABLE_HTTP2
Downloader::setTimeout(settings.value(CONNECTION_TIMEOUT_SETTING,
CONNECTION_TIMEOUT_DEFAULT).toInt());
settings.endGroup();
@ -76,11 +78,25 @@ App::~App()
int App::run()
{
MapAction *lastReady = 0;
QStringList args(arguments());
_gui->show();
QStringList args(arguments());
for (int i = 1; i < args.count(); i++)
_gui->openFile(args.at(i));
for (int i = 1; i < args.count(); i++) {
if (!_gui->openFile(args.at(i), true)) {
MapAction *a;
if (!_gui->loadMap(args.at(i), a, true))
_gui->openFile(args.at(i), false);
else {
if (a)
lastReady = a;
}
}
}
if (lastReady)
lastReady->trigger();
return exec();
}
@ -89,7 +105,18 @@ bool App::event(QEvent *event)
{
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent *e = static_cast<QFileOpenEvent *>(event);
return _gui->openFile(e->file());
if (!_gui->openFile(e->file(), true)) {
MapAction *a;
if (!_gui->loadMap(e->file(), a, true))
return _gui->openFile(e->file(), false);
else {
if (a)
a->trigger();
return true;
}
} else
return true;
}
return QApplication::event(event);

View File

@ -5,6 +5,7 @@
#include <QGraphicsSceneMouseEvent>
#include "map/map.h"
#include "popup.h"
#include "tooltip.h"
#include "areaitem.h"
@ -22,7 +23,7 @@ QString AreaItem::info() const
}
AreaItem::AreaItem(const Area &area, Map *map, GraphicsItem *parent)
: GraphicsItem(parent), _area(area)
: PlaneItem(parent), _area(area)
{
_map = map;
_digitalZoom = 0;
@ -158,7 +159,6 @@ void AreaItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
Q_UNUSED(event);
_pen.setWidthF((_width + 1) * pow(2, -_digitalZoom));
setZValue(zValue() + 1.0);
update();
}
@ -167,12 +167,5 @@ void AreaItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Q_UNUSED(event);
_pen.setWidthF(_width * pow(2, -_digitalZoom));
setZValue(zValue() - 1.0);
update();
}
void AreaItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
Popup::show(event->screenPos(), info(), event->widget());
QGraphicsItem::mousePressEvent(event);
}

View File

@ -2,12 +2,9 @@
#define AREAITEM_H
#include "data/area.h"
#include "graphicsscene.h"
#include "tooltip.h"
#include "planeitem.h"
class Map;
class AreaItem : public GraphicsItem
class AreaItem : public PlaneItem
{
public:
AreaItem(const Area &area, Map *map, GraphicsItem *parent = 0);
@ -19,6 +16,7 @@ public:
const Area &area() const {return _area;}
RectC bounds() const {return _area.boundingRect();}
void setMap(Map *map);
void setColor(const QColor &color);
@ -27,17 +25,15 @@ public:
void setStyle(Qt::PenStyle style);
void setDigitalZoom(int zoom);
virtual QString info() const;
QString info() const;
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
private:
QPainterPath painterPath(const Polygon &polygon);
void updatePainterPath();
ToolTip toolTip() const;
Area _area;
Map *_map;

View File

@ -55,7 +55,8 @@ void ColorBox::mousePressEvent(QMouseEvent *event)
if (event->button() != Qt::LeftButton)
return;
QColorDialog::ColorDialogOptions options = _alpha
? QColorDialog::ShowAlphaChannel : (QColorDialog::ColorDialogOptions)0;
? QColorDialog::ColorDialogOptions(QColorDialog::ShowAlphaChannel)
: QColorDialog::ColorDialogOptions();
QColor color = QColorDialog::getColor(_color, this, QString(), options);
if (color.isValid()) {
_color = color;

View File

@ -1,42 +0,0 @@
#ifndef CPUARCH_H
#define CPUARCH_H
#include <QtGlobal>
#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
#if defined(__arm64__)
#define CPU_ARCH_STR "arm64"
#elif defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM)
#define CPU_ARCH_STR "arm"
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) \
|| defined(_M_X64)
#define CPU_ARCH_STR "x86_64"
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
#define CPU_ARCH_STR "i386"
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
#define CPU_ARCH_STR "ia64"
#elif defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
#define CPU_ARCH_STR "mips64"
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
#define CPU_ARCH_STR "mips"
#elif defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
#define CPU_ARCH_STR "power64"
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \
|| defined(_M_MPPC) || defined(_M_PPC)
#define CPU_ARCH_STR "power"
#else
#define CPU_ARCH_STR "unknown"
#endif
#define CPU_ARCH QString(CPU_ARCH_STR)
#else // QT_VERSION < 5.4
#include <QSysInfo>
#define CPU_ARCH QSysInfo::buildCpuArchitecture()
#endif // QT_VERSION < 5.4
#endif // CPUARCH_H

View File

@ -24,7 +24,7 @@ FileSelectWidget::FileSelectWidget(QWidget *parent) : QWidget(parent)
connect(_button, SIGNAL(clicked()), this, SLOT(browse()));
QHBoxLayout *layout = new QHBoxLayout();
layout->setMargin(0);
layout->setContentsMargins(QMargins());
layout->addWidget(_edit);
layout->addWidget(_button);
setLayout(layout);

View File

@ -6,8 +6,8 @@
#include <QGraphicsSimpleTextItem>
#include <QPalette>
#include <QLocale>
#include <QOpenGLWidget>
#include "data/graph.h"
#include "opengl.h"
#include "axisitem.h"
#include "axislabelitem.h"
#include "slideritem.h"
@ -351,23 +351,31 @@ void GraphView::wheelEvent(QWheelEvent *e)
{
static int deg = 0;
deg += e->delta() / 8;
deg += e->angleDelta().y() / 8;
if (qAbs(deg) < 15)
return;
deg = 0;
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
QPointF pos = mapToScene(e->pos());
#else // QT 5.15
QPointF pos = mapToScene(e->position().toPoint());
#endif // QT 5.15
QRectF gr(_grid->boundingRect());
QPointF r(pos.x() / gr.width(), pos.y() / gr.height());
_zoom = (e->delta() > 0) ? _zoom * 1.25 : qMax(_zoom / 1.25, 1.0);
_zoom = (e->angleDelta().y() > 0) ? _zoom * 1.25 : qMax(_zoom / 1.25, 1.0);
redraw();
QRectF ngr(_grid->boundingRect());
QPointF npos(mapFromScene(QPointF(r.x() * ngr.width(),
r.y() * ngr.height())));
QScrollBar *sb = horizontalScrollBar();
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
sb->setSliderPosition(sb->sliderPosition() + npos.x() - e->pos().x());
#else // QT 5.15
sb->setSliderPosition(sb->sliderPosition() + npos.x() - e->position().x());
#endif // QT 5.15
QGraphicsView::wheelEvent(e);
}
@ -456,8 +464,8 @@ void GraphView::updateSliderInfo()
'f', _precision) + UNIT_SPACE + _yUnits);
if (cardinal && cardinal->secondaryGraph()) {
qreal delta = y - cardinal->secondaryGraph()->yAtX(_sliderPos);
yText += " " + QChar(0x0394) + l.toString(-delta * _yScale + _yOffset,
'f', _precision) + UNIT_SPACE + _yUnits;
yText += QString(" ") + QChar(0x0394) + l.toString(-delta * _yScale
+ _yOffset, 'f', _precision) + UNIT_SPACE + _yUnits;
}
_sliderInfo->setText(xText, yText);
}
@ -537,7 +545,7 @@ void GraphView::setGraphWidth(int width)
void GraphView::useOpenGL(bool use)
{
if (use)
setViewport(new OPENGL_WIDGET);
setViewport(new QOpenGLWidget);
else
setViewport(new QWidget);
}

View File

@ -1,4 +1,3 @@
#include "common/config.h"
#include <QApplication>
#include <QSplitter>
#include <QVBoxLayout>
@ -23,10 +22,8 @@
#include <QMimeData>
#include <QUrl>
#include <QPixmapCache>
#ifdef ENABLE_HIDPI
#include <QWindow>
#include <QScreen>
#endif // ENABLE_HIDPI
#include <QStyle>
#include "common/programpaths.h"
#include "data/data.h"
@ -47,10 +44,10 @@
#include "mapview.h"
#include "trackinfo.h"
#include "filebrowser.h"
#include "cpuarch.h"
#include "graphtab.h"
#include "graphitem.h"
#include "pathitem.h"
#include "mapitem.h"
#include "mapaction.h"
#include "gui.h"
@ -130,11 +127,17 @@ void GUI::createMapActions()
if (mapDir.isNull())
return;
QString unused;
QList<Map*> maps(MapList::loadMaps(mapDir, unused));
QList<Map*> maps(MapList::loadMaps(mapDir));
for (int i = 0; i < maps.count(); i++) {
MapAction *a = createMapAction(maps.at(i));
connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized()));
Map *map = maps.at(i);
if (map->isValid()) {
MapAction *a = createMapAction(map);
connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized()));
} else {
qWarning("%s: %s", qPrintable(map->path()),
qPrintable(map->errorString()));
delete map;
}
}
}
@ -159,7 +162,7 @@ void GUI::mapInitialized()
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else {
qWarning("%s: %s", qPrintable(map->name()), qPrintable(map->errorString()));
qWarning("%s: %s", qPrintable(map->path()), qPrintable(map->errorString()));
action->deleteLater();
}
}
@ -167,8 +170,13 @@ void GUI::mapInitialized()
void GUI::createPOIFilesActions()
{
_poiFilesSignalMapper = new QSignalMapper(this);
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
connect(_poiFilesSignalMapper, SIGNAL(mapped(int)), this,
SLOT(poiFileChecked(int)));
#else // QT 5.15
connect(_poiFilesSignalMapper, SIGNAL(mappedInt(int)), this,
SLOT(poiFileChecked(int)));
#endif // QT 5.15
for (int i = 0; i < _poi->files().count(); i++)
createPOIFileAction(_poi->files().at(i));
@ -306,10 +314,14 @@ void GUI::createActions()
this);
_loadMapAction->setMenuRole(QAction::NoRole);
connect(_loadMapAction, SIGNAL(triggered()), this, SLOT(loadMap()));
_loadMapDirAction = new QAction(QIcon(OPEN_FILE_ICON),
tr("Load map directory..."), this);
_loadMapDirAction->setMenuRole(QAction::NoRole);
connect(_loadMapDirAction, SIGNAL(triggered()), this, SLOT(loadMapDir()));
_clearMapCacheAction = new QAction(tr("Clear tile cache"), this);
_clearMapCacheAction->setEnabled(false);
_clearMapCacheAction->setMenuRole(QAction::NoRole);
connect(_clearMapCacheAction, SIGNAL(triggered()), _mapView,
connect(_clearMapCacheAction, SIGNAL(triggered()), this,
SLOT(clearMapCache()));
_nextMapAction = new QAction(tr("Next map"), this);
_nextMapAction->setMenuRole(QAction::NoRole);
@ -519,6 +531,7 @@ void GUI::createMenus()
_mapMenu->addActions(_mapsActionGroup->actions());
_mapsEnd = _mapMenu->addSeparator();
_mapMenu->addAction(_loadMapAction);
_mapMenu->addAction(_loadMapDirAction);
_mapMenu->addAction(_clearMapCacheAction);
_mapMenu->addSeparator();
_mapMenu->addAction(_showCoordinatesAction);
@ -679,8 +692,8 @@ void GUI::about()
msgBox.setWindowTitle(tr("About GPXSee"));
msgBox.setText("<h2>" + QString(APP_NAME) + "</h2><p><p>" + tr("Version %1")
.arg(QString(APP_VERSION) + " (" + CPU_ARCH + ", Qt " + QT_VERSION_STR
+ ")") + "</p>");
.arg(QString(APP_VERSION) + " (" + QSysInfo::buildCpuArchitecture()
+ ", Qt " + QT_VERSION_STR + ")") + "</p>");
msgBox.setInformativeText("<table width=\"300\"><tr><td>"
+ tr("GPXSee is distributed under the terms of the GNU General Public "
"License version 3. For more info about GPXSee visit the project "
@ -759,101 +772,45 @@ void GUI::paths()
void GUI::openFile()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open file"),
_dataDir, Data::formats());
QStringList list = files;
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open file"),
_dataDir, Data::formats()));
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
openFile(*it);
if (!list.isEmpty())
_dataDir = QFileInfo(list.first()).path();
for (int i = 0; i < files.size(); i++)
openFile(files.at(i));
if (!files.isEmpty())
_dataDir = QFileInfo(files.last()).path();
}
bool GUI::openFile(const QString &fileName)
bool GUI::openFile(const QString &fileName, bool silent)
{
if (fileName.isEmpty() || _files.contains(fileName))
return false;
if (loadFile(fileName)) {
_files.append(fileName);
_browser->setCurrent(fileName);
_fileActionGroup->setEnabled(true);
_navigationActionGroup->setEnabled(true);
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
if (_files.contains(fileName))
return true;
} else {
if (_files.isEmpty())
_fileActionGroup->setEnabled(false);
if (!loadFile(fileName, silent))
return false;
}
_files.append(fileName);
_browser->setCurrent(fileName);
_fileActionGroup->setEnabled(true);
// Explicitly enable the reload action as it may be disabled by loadMapDir()
_reloadFileAction->setEnabled(true);
_navigationActionGroup->setEnabled(true);
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
return true;
}
bool GUI::loadFile(const QString &fileName)
bool GUI::loadFile(const QString &fileName, bool silent)
{
Data data(fileName);
QList<QList<GraphItem*> > graphs;
QList<PathItem*> paths;
Data data(fileName, !silent);
if (data.isValid()) {
for (int i = 0; i < data.tracks().count(); i++) {
const Track &track = data.tracks().at(i);
_trackDistance += track.distance();
_time += track.time();
_movingTime += track.movingTime();
#ifdef ENABLE_TIMEZONES
const QDateTime date = track.date().toTimeZone(
_options.timeZone.zone());
#else // ENABLE_TIMEZONES
const QDateTime &date = track.date();
#endif // ENABLE_TIMEZONES
if (_dateRange.first.isNull() || _dateRange.first > date)
_dateRange.first = date;
if (_dateRange.second.isNull() || _dateRange.second < date)
_dateRange.second = date;
}
_trackCount += data.tracks().count();
for (int i = 0; i < data.routes().count(); i++)
_routeDistance += data.routes().at(i).distance();
_routeCount += data.routes().count();
_waypointCount += data.waypoints().count();
_areaCount += data.areas().count();
if (_pathName.isNull()) {
if (data.tracks().count() == 1 && !data.routes().count())
_pathName = data.tracks().first().name();
else if (data.routes().count() == 1 && !data.tracks().count())
_pathName = data.routes().first().name();
} else
_pathName = QString();
for (int i = 0; i < _tabs.count(); i++)
graphs.append(_tabs.at(i)->loadData(data));
if (updateGraphTabs())
_splitter->refresh();
paths = _mapView->loadData(data);
for (int i = 0; i < paths.count(); i++) {
const PathItem *pi = paths.at(i);
for (int j = 0; j < graphs.count(); j++) {
const GraphItem *gi = graphs.at(j).at(i);
if (!gi)
continue;
connect(gi, SIGNAL(sliderPositionChanged(qreal)), pi,
SLOT(moveMarker(qreal)));
connect(pi, SIGNAL(selected(bool)), gi, SLOT(hover(bool)));
connect(gi, SIGNAL(selected(bool)), pi, SLOT(hover(bool)));
}
}
loadData(data);
return true;
} else {
} else if (!silent) {
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
@ -865,25 +822,78 @@ bool GUI::loadFile(const QString &fileName)
error.append("\n" + tr("Line: %1").arg(data.errorLine()));
QMessageBox::critical(this, APP_NAME, error);
return false;
} else
return false;
}
void GUI::loadData(const Data &data)
{
QList<QList<GraphItem*> > graphs;
QList<PathItem*> paths;
for (int i = 0; i < data.tracks().count(); i++) {
const Track &track = data.tracks().at(i);
_trackDistance += track.distance();
_time += track.time();
_movingTime += track.movingTime();
const QDateTime date = track.date().toTimeZone(_options.timeZone.zone());
if (_dateRange.first.isNull() || _dateRange.first > date)
_dateRange.first = date;
if (_dateRange.second.isNull() || _dateRange.second < date)
_dateRange.second = date;
}
_trackCount += data.tracks().count();
for (int i = 0; i < data.routes().count(); i++)
_routeDistance += data.routes().at(i).distance();
_routeCount += data.routes().count();
_waypointCount += data.waypoints().count();
_areaCount += data.areas().count();
if (_pathName.isNull()) {
if (data.tracks().count() == 1 && !data.routes().count())
_pathName = data.tracks().first().name();
else if (data.routes().count() == 1 && !data.tracks().count())
_pathName = data.routes().first().name();
} else
_pathName = QString();
for (int i = 0; i < _tabs.count(); i++)
graphs.append(_tabs.at(i)->loadData(data));
if (updateGraphTabs())
_splitter->refresh();
paths = _mapView->loadData(data);
for (int i = 0; i < paths.count(); i++) {
const PathItem *pi = paths.at(i);
for (int j = 0; j < graphs.count(); j++) {
const GraphItem *gi = graphs.at(j).at(i);
if (!gi)
continue;
connect(gi, SIGNAL(sliderPositionChanged(qreal)), pi,
SLOT(moveMarker(qreal)));
connect(pi, SIGNAL(selected(bool)), gi, SLOT(hover(bool)));
connect(gi, SIGNAL(selected(bool)), pi, SLOT(hover(bool)));
}
}
}
void GUI::openPOIFile()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open POI file"),
_poiDir, Data::formats());
QStringList list = files;
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open POI file"),
_poiDir, Data::formats()));
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
openPOIFile(*it);
if (!list.isEmpty())
_poiDir = QFileInfo(list.first()).path();
for (int i = 0; i < files.size(); i++)
openPOIFile(files.at(i));
if (!files.isEmpty())
_poiDir = QFileInfo(files.last()).path();
}
bool GUI::openPOIFile(const QString &fileName)
{
if (fileName.isEmpty() || _poi->files().contains(fileName))
return false;
if (_poi->files().contains(fileName))
return true;
if (_poi->loadFile(fileName)) {
_mapView->showPOI(true);
@ -963,7 +973,8 @@ void GUI::openOptions()
SET_VIEW_OPTION(pathAntiAliasing, useAntiAliasing);
SET_VIEW_OPTION(useOpenGL, useOpenGL);
SET_VIEW_OPTION(sliderColor, setMarkerColor);
SET_VIEW_OPTION(projection, setProjection);
SET_VIEW_OPTION(outputProjection, setOutputProjection);
SET_VIEW_OPTION(inputProjection, setInputProjection);
SET_TAB_OPTION(palette, setPalette);
SET_TAB_OPTION(graphWidth, setGraphWidth);
@ -1000,23 +1011,18 @@ void GUI::openOptions()
if (options.connectionTimeout != _options.connectionTimeout)
Downloader::setTimeout(options.connectionTimeout);
#ifdef ENABLE_HTTP2
if (options.enableHTTP2 != _options.enableHTTP2)
Downloader::enableHTTP2(options.enableHTTP2);
#endif // ENABLE_HTTP2
#ifdef ENABLE_HIDPI
if (options.hidpiMap != _options.hidpiMap)
_mapView->setDevicePixelRatio(devicePixelRatioF(),
options.hidpiMap ? devicePixelRatioF() : 1.0);
#endif // ENABLE_HIDPI
#ifdef ENABLE_TIMEZONES
if (options.timeZone != _options.timeZone) {
_mapView->setTimeZone(options.timeZone.zone());
_dateRange.first = _dateRange.first.toTimeZone(options.timeZone.zone());
_dateRange.second = _dateRange.second.toTimeZone(options.timeZone.zone());
}
#endif // ENABLE_TIMEZONES
if (reload)
reloadFiles();
@ -1044,12 +1050,9 @@ void GUI::exportPDFFile()
printer.setCreator(QString(APP_NAME) + QString(" ")
+ QString(APP_VERSION));
printer.setResolution(_pdfExport.resolution);
printer.setOrientation(_pdfExport.orientation);
printer.setPageLayout(QPageLayout(QPageSize(_pdfExport.paperSize),
_pdfExport.orientation, _pdfExport.margins, QPageLayout::Millimeter));
printer.setOutputFileName(_pdfExport.fileName);
printer.setPaperSize(_pdfExport.paperSize);
printer.setPageMargins(_pdfExport.margins.left(), _pdfExport.margins.top(),
_pdfExport.margins.right(), _pdfExport.margins.bottom(),
QPrinter::Millimeter);
plot(&printer);
}
@ -1227,7 +1230,7 @@ void GUI::plotMainPage(QPainter *painter, const QRectF &rect, qreal ratio,
sc = 1;
}
MapView::PlotFlags flags = MapView::NoFlags;
MapView::PlotFlags flags;
if (_options.hiresPrint)
flags |= MapView::HiRes;
if (expand)
@ -1427,45 +1430,73 @@ void GUI::showGraphSliderInfo(bool show)
void GUI::loadMap()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open map file"),
_mapDir, MapList::formats());
QStringList list = files;
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open map file"),
_mapDir, MapList::formats()));
MapAction *a, *lastReady = 0;
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
loadMap(*it);
if (!list.isEmpty())
_mapDir = QFileInfo(list.first()).path();
for (int i = 0; i < files.size(); i++) {
if (loadMap(files.at(i), a) && a)
lastReady = a;
}
if (!files.isEmpty())
_mapDir = QFileInfo(files.last()).path();
if (lastReady)
lastReady->trigger();
}
bool GUI::loadMap(const QString &fileName)
static MapAction *findMapAction(const QList<QAction*> &mapActions,
const Map *map)
{
// On OS X fileName may be a directory!
if (fileName.isEmpty())
return false;
QString error;
QList<Map*> maps = MapList::loadMaps(fileName, error);
if (maps.isEmpty()) {
error = tr("Error loading map:") + "\n\n"
+ fileName + "\n\n" + error;
QMessageBox::critical(this, APP_NAME, error);
return false;
for (int i = 0; i < mapActions.count(); i++) {
const Map *m = mapActions.at(i)->data().value<Map*>();
if (map->path() == m->path())
return static_cast<MapAction*>(mapActions.at(i));
}
return 0;
}
bool GUI::loadMap(const QString &fileName, MapAction *&action, bool silent)
{
QList<Map*> maps(MapList::loadMaps(fileName));
QList<QAction*> existingActions(_mapsActionGroup->actions());
MapAction *lastReady = 0;
bool valid = false;
for (int i = 0; i < maps.size(); i++) {
Map *map = maps.at(i);
MapAction *a = createMapAction(map);
_mapMenu->insertAction(_mapsEnd, a);
if (map->isReady()) {
a->trigger();
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded()));
MapAction *a;
if (!(a = findMapAction(existingActions, map))) {
if (!map->isValid()) {
if (!silent)
QMessageBox::critical(this, APP_NAME,
tr("Error loading map:") + "\n\n" + map->path() + "\n\n"
+ map->errorString());
delete map;
} else {
valid = true;
a = createMapAction(map);
_mapMenu->insertAction(_mapsEnd, a);
if (map->isReady()) {
lastReady = a;
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded()));
}
} else {
valid = true;
map = a->data().value<Map*>();
if (map->isReady())
lastReady = a;
}
}
return true;
action = lastReady;
return valid;
}
void GUI::mapLoaded()
@ -1478,13 +1509,94 @@ void GUI::mapLoaded()
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else {
QString error = tr("Error loading map:") + "\n\n"
+ map->name() + "\n\n" + map->errorString();
QString error = tr("Error loading map:") + "\n\n" + map->path() + "\n\n"
+ map->errorString();
QMessageBox::critical(this, APP_NAME, error);
action->deleteLater();
}
}
void GUI::mapLoadedDir()
{
MapAction *action = static_cast<MapAction*>(QObject::sender());
Map *map = action->data().value<Map*>();
if (map->isValid()) {
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
QList<MapAction*> actions;
actions.append(action);
_mapView->loadMaps(actions);
} else {
QString error = tr("Error loading map:") + "\n\n" + map->path() + "\n\n"
+ map->errorString();
QMessageBox::critical(this, APP_NAME, error);
action->deleteLater();
}
}
void GUI::loadMapDir()
{
QString dir(QFileDialog::getExistingDirectory(this,
tr("Select map directory"), _mapDir, QFileDialog::ShowDirsOnly));
if (dir.isEmpty())
return;
QList<Map*> maps(MapList::loadMaps(dir));
QList<MapAction*> actions;
QList<QAction*> existingActions(_mapsActionGroup->actions());
QFileInfo fi(dir);
QMenu *menu = new QMenu(fi.fileName());
for (int i = 0; i < maps.size(); i++) {
Map *map = maps.at(i);
MapAction *a;
if (!(a = findMapAction(existingActions, map))) {
if (!map->isValid()) {
QMessageBox::critical(this, APP_NAME, tr("Error loading map:")
+ "\n\n" + map->path() + "\n\n" + map->errorString());
delete map;
} else {
a = createMapAction(map);
menu->addAction(a);
if (map->isReady()) {
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
actions.append(a);
} else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoadedDir()));
}
} else {
map = a->data().value<Map*>();
if (map->isReady())
actions.append(a);
}
}
_mapView->loadMaps(actions);
if (menu->isEmpty())
delete menu;
else {
menu->setStyleSheet("QMenu { menu-scrollable: 1; }");
_mapMenu->insertMenu(_mapsEnd, menu);
}
_mapDir = fi.absolutePath();
_areaCount += maps.size();
_fileActionGroup->setEnabled(true);
_reloadFileAction->setEnabled(false);
}
void GUI::clearMapCache()
{
if (QMessageBox::question(this, APP_NAME,
tr("Clear the map tile cache?")) == QMessageBox::Yes)
_mapView->clearMapCache();
}
void GUI::updateStatusBarInfo()
{
if (_files.count() == 0)
@ -1535,7 +1647,7 @@ void GUI::nextMap()
if (!checked)
return;
QList<QAction*> maps = _mapsActionGroup->actions();
QList<QAction*> maps(_mapsActionGroup->actions());
for (int i = 1; i < maps.size(); i++) {
int next = (maps.indexOf(checked) + i) % maps.count();
if (maps.at(next)->isEnabled()) {
@ -1551,7 +1663,7 @@ void GUI::prevMap()
if (!checked)
return;
QList<QAction*> maps = _mapsActionGroup->actions();
QList<QAction*> maps(_mapsActionGroup->actions());
for (int i = 1; i < maps.size(); i++) {
int prev = (maps.indexOf(checked) + maps.count() - i) % maps.count();
if (maps.at(prev)->isEnabled()) {
@ -1777,9 +1889,25 @@ void GUI::dragEnterEvent(QDragEnterEvent *event)
void GUI::dropEvent(QDropEvent *event)
{
QList<QUrl> urls = event->mimeData()->urls();
for (int i = 0; i < urls.size(); i++)
openFile(urls.at(i).toLocalFile());
MapAction *lastReady = 0;
QList<QUrl> urls(event->mimeData()->urls());
for (int i = 0; i < urls.size(); i++) {
QString file(urls.at(i).toLocalFile());
if (!openFile(file, true)) {
MapAction *a;
if (!loadMap(file, a, true))
openFile(file, false);
else {
if (a)
lastReady = a;
}
}
}
if (lastReady)
lastReady->trigger();
event->acceptProposedAction();
}
@ -1988,21 +2116,17 @@ void GUI::writeSettings()
if (_options.showSecondarySpeed != SHOW_SECONDARY_SPEED_DEFAULT)
settings.setValue(SHOW_SECONDARY_SPEED_SETTING,
_options.showSecondarySpeed);
#ifdef ENABLE_TIMEZONES
if (_options.timeZone != TimeZoneInfo())
settings.setValue(TIME_ZONE_SETTING, QVariant::fromValue(
_options.timeZone));
#endif // ENABLE_TIMEZONES
if (_options.useSegments != USE_SEGMENTS_DEFAULT)
settings.setValue(USE_SEGMENTS_SETTING, _options.useSegments);
if (_options.poiRadius != POI_RADIUS_DEFAULT)
settings.setValue(POI_RADIUS_SETTING, _options.poiRadius);
if (_options.useOpenGL != USE_OPENGL_DEFAULT)
settings.setValue(USE_OPENGL_SETTING, _options.useOpenGL);
#ifdef ENABLE_HTTP2
if (_options.enableHTTP2 != ENABLE_HTTP2_DEFAULT)
settings.setValue(ENABLE_HTTP2_SETTING, _options.enableHTTP2);
#endif // ENABLE_HTTP2
if (_options.pixmapCache != PIXMAP_CACHE_DEFAULT)
settings.setValue(PIXMAP_CACHE_SETTING, _options.pixmapCache);
if (_options.connectionTimeout != CONNECTION_TIMEOUT_DEFAULT)
@ -2026,12 +2150,12 @@ void GUI::writeSettings()
_options.separateGraphPage);
if (_options.sliderColor != SLIDER_COLOR_DEFAULT)
settings.setValue(SLIDER_COLOR_SETTING, _options.sliderColor);
if (_options.projection != PROJECTION_DEFAULT)
settings.setValue(PROJECTION_SETTING, _options.projection);
#ifdef ENABLE_HIDPI
if (_options.outputProjection != OUTPUT_PROJECTION_DEFAULT)
settings.setValue(OUTPUT_PROJECTION_SETTING, _options.outputProjection);
if (_options.inputProjection != INPUT_PROJECTION_DEFAULT)
settings.setValue(INPUT_PROJECTION_SETTING, _options.outputProjection);
if (_options.hidpiMap != HIDPI_MAP_DEFAULT)
settings.setValue(HIDPI_MAP_SETTING, _options.hidpiMap);
#endif // ENABLE_HIDPI
settings.endGroup();
}
@ -2187,11 +2311,11 @@ void GUI::readSettings()
settings.endGroup();
settings.beginGroup(PDF_EXPORT_SETTINGS_GROUP);
_pdfExport.orientation = (QPrinter::Orientation) settings.value(
_pdfExport.orientation = (QPageLayout::Orientation) settings.value(
PAPER_ORIENTATION_SETTING, PAPER_ORIENTATION_DEFAULT).toInt();
_pdfExport.resolution = settings.value(RESOLUTION_SETTING,
RESOLUTION_DEFAULT).toInt();
_pdfExport.paperSize = (QPrinter::PaperSize) settings.value(
_pdfExport.paperSize = (QPageSize::PageSizeId) settings.value(
PAPER_SIZE_SETTING, PAPER_SIZE_DEFAULT).toInt();
qreal ml = settings.value(PDF_MARGIN_LEFT_SETTING, PDF_MARGIN_LEFT_DEFAULT)
.toReal();
@ -2201,7 +2325,7 @@ void GUI::readSettings()
PDF_MARGIN_RIGHT_DEFAULT).toReal();
qreal mb = settings.value(PDF_MARGIN_BOTTOM_SETTING,
PDF_MARGIN_BOTTOM_DEFAULT).toReal();
_pdfExport.margins = MarginsF(ml, mt, mr, mb);
_pdfExport.margins = QMarginsF(ml, mt, mr, mb);
_pdfExport.fileName = settings.value(PDF_FILENAME_SETTING,
PDF_FILENAME_DEFAULT).toString();
settings.endGroup();
@ -2286,9 +2410,7 @@ void GUI::readSettings()
_options.showSecondarySpeed = settings.value(
SHOW_SECONDARY_SPEED_SETTING,
SHOW_SECONDARY_SPEED_DEFAULT).toBool();
#ifdef ENABLE_TIMEZONES
_options.timeZone = settings.value(TIME_ZONE_SETTING).value<TimeZoneInfo>();
#endif // ENABLE_TIMEZONES
_options.useSegments = settings.value(USE_SEGMENTS_SETTING,
USE_SEGMENTS_DEFAULT).toBool();
_options.automaticPause = settings.value(AUTOMATIC_PAUSE_SETTING,
@ -2299,10 +2421,8 @@ void GUI::readSettings()
.toInt();
_options.useOpenGL = settings.value(USE_OPENGL_SETTING, USE_OPENGL_DEFAULT)
.toBool();
#ifdef ENABLE_HTTP2
_options.enableHTTP2 = settings.value(ENABLE_HTTP2_SETTING,
ENABLE_HTTP2_DEFAULT).toBool();
#endif // ENABLE_HTTP2
_options.pixmapCache = settings.value(PIXMAP_CACHE_SETTING,
PIXMAP_CACHE_DEFAULT).toInt();
_options.connectionTimeout = settings.value(CONNECTION_TIMEOUT_SETTING,
@ -2325,12 +2445,12 @@ void GUI::readSettings()
SEPARATE_GRAPH_PAGE_DEFAULT).toBool();
_options.sliderColor = settings.value(SLIDER_COLOR_SETTING,
SLIDER_COLOR_DEFAULT).value<QColor>();
_options.projection = settings.value(PROJECTION_SETTING, PROJECTION_DEFAULT)
.toInt();
#ifdef ENABLE_HIDPI
_options.outputProjection = settings.value(OUTPUT_PROJECTION_SETTING,
OUTPUT_PROJECTION_DEFAULT).toInt();
_options.inputProjection = settings.value(INPUT_PROJECTION_SETTING,
INPUT_PROJECTION_DEFAULT).toInt();
_options.hidpiMap = settings.value(HIDPI_MAP_SETTING, HIDPI_MAP_SETTING)
.toBool();
#endif // ENABLE_HIDPI
_mapView->setPalette(_options.palette);
_mapView->setMapOpacity(_options.mapOpacity);
@ -2350,14 +2470,11 @@ void GUI::readSettings()
_mapView->setMarkerColor(_options.sliderColor);
if (_options.useOpenGL)
_mapView->useOpenGL(true);
#ifdef ENABLE_HIDPI
_mapView->setDevicePixelRatio(devicePixelRatioF(),
_options.hidpiMap ? devicePixelRatioF() : 1.0);
#endif // ENABLE_HIDPI
_mapView->setProjection(_options.projection);
#ifdef ENABLE_TIMEZONES
_mapView->setOutputProjection(_options.outputProjection);
_mapView->setInputProjection(_options.inputProjection);
_mapView->setTimeZone(_options.timeZone.zone());
#endif // ENABLE_TIMEZONES
for (int i = 0; i < _tabs.count(); i++) {
_tabs.at(i)->setPalette(_options.palette);
@ -2397,7 +2514,7 @@ void GUI::readSettings()
QAction *GUI::mapAction(const QString &name)
{
QList<QAction *> maps = _mapsActionGroup->actions();
QList<QAction *> maps(_mapsActionGroup->actions());
// Last map
for (int i = 0; i < maps.count(); i++) {
@ -2448,20 +2565,17 @@ void GUI::show()
{
QMainWindow::show();
#ifdef ENABLE_HIDPI
QWindow *w = windowHandle();
connect(w->screen(), SIGNAL(logicalDotsPerInchChanged(qreal)), this,
SLOT(logicalDotsPerInchChanged(qreal)));
connect(w, SIGNAL(screenChanged(QScreen*)), this,
SLOT(screenChanged(QScreen*)));
#endif // ENABLE_HIDPI
_mapView->fitContentToSize();
}
void GUI::screenChanged(QScreen *screen)
{
#ifdef ENABLE_HIDPI
_mapView->setDevicePixelRatio(devicePixelRatioF(),
_options.hidpiMap ? devicePixelRatioF() : 1.0);
@ -2469,17 +2583,12 @@ void GUI::screenChanged(QScreen *screen)
SLOT(logicalDotsPerInchChanged(qreal)));
connect(screen, SIGNAL(logicalDotsPerInchChanged(qreal)), this,
SLOT(logicalDotsPerInchChanged(qreal)));
#else // ENABLE_HIDPI
Q_UNUSED(screen);
#endif // ENABLE_HIDPI
}
void GUI::logicalDotsPerInchChanged(qreal dpi)
{
Q_UNUSED(dpi)
#ifdef ENABLE_HIDPI
_mapView->setDevicePixelRatio(devicePixelRatioF(),
_options.hidpiMap ? devicePixelRatioF() : 1.0);
#endif // ENBLE_HIDPI
}

View File

@ -30,6 +30,7 @@ class Map;
class POI;
class QScreen;
class MapAction;
class Data;
class GUI : public QMainWindow
{
@ -38,7 +39,9 @@ class GUI : public QMainWindow
public:
GUI();
bool openFile(const QString &fileName);
bool openFile(const QString &fileName, bool silent = false);
bool loadMap(const QString &fileName, MapAction *&action,
bool silent = false);
void show();
private slots:
@ -62,9 +65,11 @@ private slots:
void showTracks(bool show);
void showRoutes(bool show);
void loadMap();
void loadMapDir();
void nextMap();
void prevMap();
void openOptions();
void clearMapCache();
void mapChanged();
void graphChanged(int);
@ -91,6 +96,7 @@ private slots:
void logicalDotsPerInchChanged(qreal dpi);
void mapLoaded();
void mapLoadedDir();
void mapInitialized();
private:
@ -117,8 +123,8 @@ private:
void createBrowser();
bool openPOIFile(const QString &fileName);
bool loadFile(const QString &fileName);
bool loadMap(const QString &fileName);
bool loadFile(const QString &fileName, bool silent = false);
void loadData(const Data &data);
void updateStatusBarInfo();
void updateWindowTitle();
void updateNavigationActions();
@ -172,6 +178,7 @@ private:
QAction *_showMapAction;
QAction *_fullscreenAction;
QAction *_loadMapAction;
QAction *_loadMapDirAction;
QAction *_clearMapCacheAction;
QAction *_showGraphsAction;
QAction *_showGraphGridAction;

View File

@ -18,9 +18,9 @@ void InfoItem::updateBoundingRect()
for (QList<KV<QString, QString> >::const_iterator i = _list.constBegin();
i != _list.constEnd(); i++) {
width += fm.width(i->key() + ": ");
width += fm.width(i->value()) + ((i == _list.constEnd() - 1)
? 0 : PADDING);
width += fm.horizontalAdvance(i->key() + ": " + i->value());
if (i != _list.constEnd() - 1)
width += PADDING;
}
_boundingRect = QRectF(0, 0, width, _list.isEmpty() ? 0 : fm.height());
@ -39,12 +39,11 @@ void InfoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
for (QList<KV<QString, QString> >::const_iterator i = _list.constBegin();
i != _list.constEnd(); i++) {
painter->drawText(width, fm.height() - fm.descent(), i->key() + ": ");
width += fm.width(i->key() + ": ");
painter->drawText(width, fm.height() - fm.descent(), i->value());
width += fm.width(i->value()) + ((i == _list.constEnd() - 1)
? 0 : PADDING);
QString text(i->key() + ": " + i->value());
painter->drawText(width, fm.height() - fm.descent(), text);
width += fm.horizontalAdvance(text);
if (i != _list.constEnd() - 1) {
width += PADDING;
painter->save();
painter->setPen(Qt::gray);
painter->drawLine(width - PADDING/2, fm.descent(),

230
src/GUI/mapitem.cpp Normal file
View File

@ -0,0 +1,230 @@
#include <cmath>
#include <QCursor>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include "map/map.h"
#include "mapaction.h"
#include "popup.h"
#include "tooltip.h"
#include "mapitem.h"
static void growLeft(Map *map, const Coordinates &c, QRectF &rect)
{
QPointF p(map->ll2xy(c));
if (p.x() < rect.left())
rect.setLeft(p.x());
}
static void growRight(Map *map, const Coordinates &c, QRectF &rect)
{
QPointF p(map->ll2xy(c));
if (p.x() > rect.right())
rect.setRight(p.x());
}
static void growTop(Map *map, const Coordinates &c, QRectF &rect)
{
QPointF p(map->ll2xy(c));
if (p.y() > rect.top())
rect.setTop(p.y());
}
static void growBottom(Map *map, const Coordinates &c, QRectF &rect)
{
QPointF p(map->ll2xy(c));
if (p.y() < rect.bottom())
rect.setBottom(p.y());
}
static QRectF bbox(const RectC &rect, Map *map, int samples = 100)
{
if (!rect.isValid())
return QRectF();
double dx = rect.width() / samples;
double dy = rect.height() / samples;
QPointF tl(map->ll2xy(rect.topLeft()));
QPointF br(map->ll2xy(rect.bottomRight()));
QRectF prect(tl, br);
for (int i = 0; i <= samples; i++) {
double x = remainder(rect.left() + i * dx, 360.0);
growTop(map, Coordinates(x, rect.bottom()), prect);
growBottom(map, Coordinates(x, rect.top()), prect);
}
for (int i = 0; i <= samples; i++) {
double y = rect.bottom() + i * dy;
growLeft(map, Coordinates(rect.left(), y), prect);
growRight(map, Coordinates(rect.right(), y), prect);
}
return prect;
}
QString MapItem::info() const
{
ToolTip tt;
if (!_name.isEmpty())
tt.insert(tr("Name"), _name);
if (!_fileName.isEmpty())
tt.insert(tr("File"), _fileName);
return tt.toString();
}
MapItem::MapItem(MapAction *action, Map *map, GraphicsItem *parent)
: PlaneItem(parent)
{
Map *src = action->data().value<Map*>();
Q_ASSERT(map->isReady());
_name = src->name();
_fileName = src->path();
_bounds = src->llBounds();
connect(this, SIGNAL(triggered()), action, SLOT(trigger()));
_map = map;
_digitalZoom = 0;
_width = 2;
_opacity = 0.5;
QBrush brush(Qt::SolidPattern);
_pen = QPen(brush, _width);
updatePainterPath();
setCursor(Qt::ArrowCursor);
setAcceptHoverEvents(true);
}
void MapItem::updatePainterPath()
{
_painterPath = QPainterPath();
QRectF r(bbox(_bounds, _map));
if (r.left() > r.right()) {
QRectF r1(bbox(RectC(_bounds.topLeft(),
Coordinates(180, _bounds.bottomRight().lat())), _map));
QRectF r2(bbox(RectC(Coordinates(-180, _bounds.topLeft().lat()),
_bounds.bottomRight()), _map));
_painterPath.addRect(r1);
_painterPath.addRect(r2);
} else
_painterPath.addRect(r);
}
void MapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
painter->setPen(_width ? _pen : QPen(Qt::NoPen));
painter->drawPath(_painterPath);
painter->fillPath(_painterPath, _brush);
//QPen p = QPen(QBrush(Qt::red), 0);
//painter->setPen(p);
//painter->drawRect(boundingRect());
}
void MapItem::setMap(Map *map)
{
prepareGeometryChange();
_map = map;
updatePainterPath();
}
void MapItem::setColor(const QColor &color)
{
if (_pen.color() == color)
return;
QColor bc(color);
bc.setAlphaF(_opacity * color.alphaF());
_pen.setColor(color);
_brush = QBrush(bc);
update();
}
void MapItem::setOpacity(qreal opacity)
{
if (_opacity == opacity)
return;
_opacity = opacity;
QColor bc(_pen.color());
bc.setAlphaF(_opacity * _pen.color().alphaF());
_brush = QBrush(bc);
update();
}
void MapItem::setWidth(qreal width)
{
if (_width == width)
return;
prepareGeometryChange();
_width = width;
_pen.setWidthF(_width * pow(2, -_digitalZoom));
}
void MapItem::setStyle(Qt::PenStyle style)
{
if (_pen.style() == style)
return;
_pen.setStyle(style);
update();
}
void MapItem::setDigitalZoom(int zoom)
{
if (_digitalZoom == zoom)
return;
prepareGeometryChange();
_digitalZoom = zoom;
_pen.setWidthF(_width * pow(2, -_digitalZoom));
}
void MapItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
Q_UNUSED(event);
_pen.setWidthF((_width + 1) * pow(2, -_digitalZoom));
update();
}
void MapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
Q_UNUSED(event);
_pen.setWidthF(_width * pow(2, -_digitalZoom));
update();
}
void MapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
Q_UNUSED(event);
emit triggered();
}

57
src/GUI/mapitem.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef MAPITEM_H
#define MAPITEM_H
#include "planeitem.h"
class MapAction;
class MapItem : public QObject, public PlaneItem
{
Q_OBJECT
public:
MapItem(MapAction *action, Map *map, GraphicsItem *parent = 0);
QPainterPath shape() const {return _painterPath;}
QRectF boundingRect() const {return _painterPath.boundingRect();}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
RectC bounds() const {return _bounds;}
void setMap(Map *map);
void setColor(const QColor &color);
void setOpacity(qreal opacity);
void setWidth(qreal width);
void setStyle(Qt::PenStyle style);
void setDigitalZoom(int zoom);
QString info() const;
signals:
void triggered();
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
private:
void updatePainterPath();
RectC _bounds;
QString _name;
QString _fileName;
Map *_map;
int _digitalZoom;
qreal _width;
QPen _pen;
QBrush _brush;
qreal _opacity;
QPainterPath _painterPath;
};
#endif // MAPITEM_H

View File

@ -4,19 +4,21 @@
#include <QApplication>
#include <QScrollBar>
#include <QClipboard>
#include <QOpenGLWidget>
#include "data/poi.h"
#include "data/data.h"
#include "map/map.h"
#include "map/pcs.h"
#include "opengl.h"
#include "trackitem.h"
#include "routeitem.h"
#include "waypointitem.h"
#include "areaitem.h"
#include "scaleitem.h"
#include "coordinatesitem.h"
#include "mapitem.h"
#include "keys.h"
#include "graphicsscene.h"
#include "mapaction.h"
#include "mapview.h"
@ -27,6 +29,20 @@
#define COORDINATES_OFFSET SCALE_OFFSET
template<typename T>
static void updateZValues(T &items)
{
for (int i = 0; i < items.size(); i++) {
const QGraphicsItem *ai = items.at(i);
for (int j = 0; j < items.size(); j++) {
QGraphicsItem *aj = items[j];
if (aj->boundingRect().contains(ai->boundingRect()))
aj->setZValue(qMin(ai->zValue() - 1, aj->zValue()));
}
}
}
MapView::MapView(Map *map, POI *poi, QWidget *parent)
: QGraphicsView(parent)
{
@ -39,7 +55,7 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setRenderHint(QPainter::Antialiasing, true);
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
setResizeAnchor(QGraphicsView::AnchorViewCenter);
setAcceptDrops(false);
@ -51,10 +67,12 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
_coordinates->setVisible(false);
_scene->addItem(_coordinates);
_projection = PCS::pcs(3857);
_outputProjection = PCS::pcs(3857);
_inputProjection = GCS::gcs(4326);
_map = map;
_map->load();
_map->setProjection(_projection);
_map->setOutputProjection(_outputProjection);
_map->setInputProjection(_inputProjection);
connect(_map, SIGNAL(tilesLoaded()), this, SLOT(reloadMap()));
_poi = poi;
@ -85,10 +103,8 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
_poiSize = 8;
_poiColor = Qt::black;
#ifdef ENABLE_HIDPI
_deviceRatio = 1.0;
_mapRatio = 1.0;
#endif // ENABLE_HIDPI
_opengl = false;
_plot = false;
_digitalZoom = 0;
@ -170,18 +186,19 @@ void MapView::addArea(const Area &area)
}
AreaItem *ai = new AreaItem(area, _map);
_areas.append(ai);
_ar |= ai->area().boundingRect();
ai->setColor(_palette.nextColor());
ai->setWidth(_areaWidth);
ai->setStyle(_areaStyle);
ai->setOpacity(_areaOpacity);
ai->setDigitalZoom(_digitalZoom);
ai->setVisible(_showAreas);
_scene->addItem(ai);
_ar |= ai->bounds();
_areas.append(ai);
if (_showAreas)
addPOI(_poi->points(ai->area()));
addPOI(_poi->points(ai->bounds()));
}
void MapView::addWaypoints(const QVector<Waypoint> &waypoints)
@ -205,6 +222,26 @@ void MapView::addWaypoints(const QVector<Waypoint> &waypoints)
}
}
MapItem *MapView::addMap(MapAction *map)
{
MapItem *mi = new MapItem(map, _map);
mi->setColor(_palette.nextColor());
mi->setWidth(_areaWidth);
mi->setStyle(_areaStyle);
mi->setOpacity(_areaOpacity);
mi->setDigitalZoom(_digitalZoom);
mi->setVisible(_showAreas);
_scene->addItem(mi);
_ar |= mi->bounds();
_areas.append(mi);
if (_showAreas)
addPOI(_poi->points(mi->bounds()));
return mi;
}
QList<PathItem *> MapView::loadData(const Data &data)
{
QList<PathItem *> paths;
@ -227,18 +264,37 @@ QList<PathItem *> MapView::loadData(const Data &data)
else
updatePOIVisibility();
if (!data.areas().isEmpty())
updateZValues(_areas);
centerOn(contentCenter());
return paths;
}
void MapView::loadMaps(const QList<MapAction *> &maps)
{
int zoom = _map->zoom();
for (int i = 0; i < maps.size(); i++)
addMap(maps.at(i));
if (fitMapZoom() != zoom)
rescale();
else
updatePOIVisibility();
updateZValues(_areas);
centerOn(contentCenter());
}
int MapView::fitMapZoom() const
{
RectC br = _tr | _rr | _wr | _ar;
return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN),
br.isNull() ? RectC(_map->xy2ll(_map->bounds().topLeft()),
_map->xy2ll(_map->bounds().bottomRight())) : br);
br.isNull() ? _map->llBounds() : br);
}
QPointF MapView::contentCenter() const
@ -315,10 +371,9 @@ void MapView::setMap(Map *map)
_map = map;
_map->load();
_map->setProjection(_projection);
#ifdef ENABLE_HIDPI
_map->setOutputProjection(_outputProjection);
_map->setInputProjection(_inputProjection);
_map->setDevicePixelRatio(_deviceRatio, _mapRatio);
#endif // ENABLE_HIDPI
connect(_map, SIGNAL(tilesLoaded()), this, SLOT(reloadMap()));
digitalZoom(0);
@ -373,7 +428,7 @@ void MapView::updatePOI()
addPOI(_poi->points(_routes.at(i)->path()));
if (_showAreas)
for (int i = 0; i < _areas.size(); i++)
addPOI(_poi->points(_areas.at(i)->area()));
addPOI(_poi->points(_areas.at(i)->bounds()));
if (_showWaypoints)
for (int i = 0; i< _waypoints.size(); i++)
addPOI(_poi->points(_waypoints.at(i)->waypoint()));
@ -424,12 +479,8 @@ void MapView::setCoordinatesFormat(CoordinatesFormat format)
void MapView::setTimeZone(const QTimeZone &zone)
{
#ifdef ENABLE_TIMEZONES
WaypointItem::setTimeZone(zone);
PathItem::setTimeZone(zone);
#else // ENABLE_TIMEZONES
Q_UNUSED(zone);
#endif // ENABLE_TIMEZONES
}
void MapView::clearMapCache()
@ -464,10 +515,8 @@ void MapView::digitalZoom(int zoom)
_coordinates->setDigitalZoom(_digitalZoom);
}
void MapView::zoom(int zoom, const QPoint &pos)
void MapView::zoom(int zoom, const QPoint &pos, bool shift)
{
bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier;
if (_digitalZoom) {
if (((_digitalZoom > 0 && zoom > 0) && (!shift || _digitalZoom
>= MAX_DIGITAL_ZOOM)) || ((_digitalZoom < 0 && zoom < 0) && (!shift
@ -493,27 +542,42 @@ void MapView::zoom(int zoom, const QPoint &pos)
void MapView::wheelEvent(QWheelEvent *event)
{
static int deg = 0;
bool shift = (event->modifiers() & MODIFIER) ? true : false;
// Shift inverts the wheel axis on OS X, so use scrolling in both axes for
// the zoom.
int delta = event->angleDelta().y()
? event->angleDelta().y() : event->angleDelta().x();
deg += event->delta() / 8;
deg += delta / 8;
if (qAbs(deg) < 15)
return;
deg = 0;
zoom((event->delta() > 0) ? 1 : -1, event->pos());
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
zoom((delta > 0) ? 1 : -1, event->pos(), shift);
#else // QT 5.15
zoom((delta > 0) ? 1 : -1, event->position().toPoint(), shift);
#endif // QT 5.15
}
void MapView::mouseDoubleClickEvent(QMouseEvent *event)
{
bool shift = (event->modifiers() & MODIFIER) ? true : false;
QGraphicsView::mouseDoubleClickEvent(event);
if (event->isAccepted())
return;
if (event->button() != Qt::LeftButton && event->button() != Qt::RightButton)
return;
zoom((event->button() == Qt::LeftButton) ? 1 : -1, event->pos());
zoom((event->button() == Qt::LeftButton) ? 1 : -1, event->pos(), shift);
}
void MapView::keyPressEvent(QKeyEvent *event)
{
int z;
bool shift = (event->modifiers() & MODIFIER) ? true : false;
QPoint pos = viewport()->rect().center();
if (event->key() == ZOOM_IN)
@ -533,7 +597,7 @@ void MapView::keyPressEvent(QKeyEvent *event)
return;
}
zoom(z, pos);
zoom(z, pos, shift);
}
void MapView::keyReleaseEvent(QKeyEvent *event)
@ -566,9 +630,7 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
// Enter plot mode
setUpdatesEnabled(false);
_plot = true;
#ifdef ENABLE_HIDPI
_map->setDevicePixelRatio(_deviceRatio, 1.0);
#endif // ENABLE_HIDPI
// Compute sizes & ratios
orig = viewport()->rect();
@ -635,9 +697,7 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
_mapScale->setPos(origPos);
// Exit plot mode
#ifdef ENABLE_HIDPI
_map->setDevicePixelRatio(_deviceRatio, _mapRatio);
#endif // ENABLE_HIDPI
_plot = false;
setUpdatesEnabled(true);
}
@ -959,7 +1019,7 @@ void MapView::useOpenGL(bool use)
_opengl = use;
if (use)
setViewport(new OPENGL_WIDGET);
setViewport(new QOpenGLWidget);
else
setViewport(new QWidget);
}
@ -986,7 +1046,6 @@ void MapView::reloadMap()
void MapView::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
{
#ifdef ENABLE_HIDPI
if (_deviceRatio == deviceRatio && _mapRatio == mapRatio)
return;
@ -1019,26 +1078,40 @@ void MapView::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
centerOn(nc);
reloadMap();
#else // ENABLE_HIDPI
Q_UNUSED(deviceRatio);
Q_UNUSED(mapRatio);
#endif // ENABLE_HIDPI
}
void MapView::setProjection(int id)
void MapView::setOutputProjection(int id)
{
const PCS *pcs;
const GCS *gcs;
Coordinates center = _map->xy2ll(mapToScene(viewport()->rect().center()));
if ((pcs = PCS::pcs(id)))
_projection = Projection(pcs);
_outputProjection = Projection(pcs);
else if ((gcs = GCS::gcs(id)))
_projection = Projection(gcs);
_outputProjection = Projection(gcs);
else
qWarning("%d: Unknown PCS/GCS id", id);
_map->setProjection(_projection);
_map->setOutputProjection(_outputProjection);
rescale();
centerOn(_map->ll2xy(center));
}
void MapView::setInputProjection(int id)
{
const PCS *pcs;
const GCS *gcs;
Coordinates center = _map->xy2ll(mapToScene(viewport()->rect().center()));
if ((pcs = PCS::pcs(id)))
_inputProjection = Projection(pcs);
else if ((gcs = GCS::gcs(id)))
_inputProjection = Projection(gcs);
else
qWarning("%d: Unknown PCS/GCS id", id);
_map->setInputProjection(_inputProjection);
rescale();
centerOn(_map->ll2xy(center));
}

View File

@ -29,10 +29,12 @@ class ScaleItem;
class CoordinatesItem;
class PathItem;
class GraphItem;
class AreaItem;
class PlaneItem;
class MapItem;
class Area;
class GraphicsScene;
class QTimeZone;
class MapAction;
class MapView : public QGraphicsView
{
@ -49,6 +51,7 @@ public:
MapView(Map *map, POI *poi, QWidget *parent = 0);
QList<PathItem *> loadData(const Data &data);
void loadMaps(const QList<MapAction*> &maps);
void setPalette(const Palette &palette);
void setPOI(POI *poi);
@ -95,7 +98,8 @@ public slots:
void setCoordinatesFormat(CoordinatesFormat format);
void setTimeZone(const QTimeZone &zone);
void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
void setProjection(int id);
void setOutputProjection(int id);
void setInputProjection(int id);
void fitContentToSize();
@ -108,6 +112,7 @@ private:
PathItem *addTrack(const Track &track);
PathItem *addRoute(const Route &route);
MapItem *addMap(MapAction *map);
void addArea(const Area &area);
void addWaypoints(const QVector<Waypoint> &waypoints);
void addPOI(const QList<Waypoint> &waypoints);
@ -118,7 +123,7 @@ private:
QPointF contentCenter() const;
void rescale();
void centerOn(const QPointF &pos);
void zoom(int zoom, const QPoint &pos);
void zoom(int zoom, const QPoint &pos, bool shift);
void digitalZoom(int zoom);
void updatePOIVisibility();
void skipColor() {_palette.nextColor();}
@ -140,7 +145,7 @@ private:
QList<TrackItem*> _tracks;
QList<RouteItem*> _routes;
QList<WaypointItem*> _waypoints;
QList<AreaItem*> _areas;
QList<PlaneItem*> _areas;
POIHash _pois;
RectC _tr, _rr, _wr, _ar;
@ -151,7 +156,7 @@ private:
Palette _palette;
qreal _mapOpacity;
Projection _projection;
Projection _outputProjection, _inputProjection;
bool _showMap, _showTracks, _showRoutes, _showAreas, _showWaypoints,
_showWaypointLabels, _showPOI, _showPOILabels, _showRouteWaypoints,
@ -167,10 +172,8 @@ private:
bool _plot;
QCursor _cursor;
#ifdef ENABLE_HIDPI
qreal _deviceRatio;
qreal _mapRatio;
#endif // ENABLE_HIDPI
bool _opengl;
};

View File

@ -1,44 +0,0 @@
#ifndef MARGINS_H
#define MARGINS_H
#include <QtGlobal>
#include <QDebug>
class MarginsF
{
public:
MarginsF() {_left = 0; _top = 0; _right = 0; _bottom = 0;}
MarginsF(qreal left, qreal top, qreal right, qreal bottom)
{_left = left, _top = top; _right = right; _bottom = bottom;}
qreal left() const {return _left;}
qreal top() const {return _top;}
qreal right() const {return _right;}
qreal bottom() const {return _bottom;}
private:
qreal _left, _top, _right, _bottom;
};
inline MarginsF operator*(const MarginsF &margins, qreal factor)
{
return MarginsF(margins.left() * factor, margins.top() * factor,
margins.right() * factor, margins.bottom() * factor);
}
inline MarginsF operator/(const MarginsF &margins, qreal factor)
{
return MarginsF(margins.left() / factor, margins.top() / factor,
margins.right() / factor, margins.bottom() / factor);
}
#ifndef QT_NO_DEBUG
inline QDebug operator<<(QDebug dbg, const MarginsF &margins)
{
dbg.nospace() << "MarginsF(" << margins.left() << ", " << margins.top()
<< ", " << margins.right() << margins.bottom() << ")";
return dbg.space();
}
#endif // QT_NO_DEBUG
#endif // MARGINS_H

View File

@ -75,7 +75,7 @@ MarginsFWidget::MarginsFWidget(QWidget *parent) : QWidget(parent)
setLayout(layout);
}
void MarginsFWidget::setValue(const MarginsF &value)
void MarginsFWidget::setValue(const QMarginsF &value)
{
_top->setValue(value.top());
_bottom->setValue(value.bottom());
@ -104,8 +104,8 @@ void MarginsFWidget::setSingleStep(qreal step)
_right->setSingleStep(step);
}
MarginsF MarginsFWidget::value() const
QMarginsF MarginsFWidget::value() const
{
return MarginsF(_left->value(), _top->value(), _right->value(),
return QMarginsF(_left->value(), _top->value(), _right->value(),
_bottom->value());
}

View File

@ -3,7 +3,6 @@
#include <QWidget>
#include <QMargins>
#include "margins.h"
class QSpinBox;
class QDoubleSpinBox;
@ -33,8 +32,8 @@ class MarginsFWidget : public QWidget
public:
MarginsFWidget(QWidget *parent = 0);
MarginsF value() const;
void setValue(const MarginsF &value);
QMarginsF value() const;
void setValue(const QMarginsF &value);
void setUnits(const QString &units);
void setSingleStep(qreal step);

View File

@ -1,28 +0,0 @@
#include <QtGlobal>
#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
#include <QGLWidget>
#include <QGLFormat>
#else
#include <QOpenGLWidget>
#include <QSurfaceFormat>
#endif
#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
#define OPENGL_WIDGET QGLWidget
#else
#define OPENGL_WIDGET QOpenGLWidget
#endif
#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
#define OPENGL_SET_FORMAT(samples, stencilBuffer) \
{QGLFormat fmt; \
fmt.setStencilBufferSize(stencilBuffer); \
fmt.setSamples(samples); \
QGLFormat::setDefaultFormat(fmt);}
#else
#define OPENGL_SET_FORMAT(samples, stencilBuffer) \
{QSurfaceFormat fmt; \
fmt.setStencilBufferSize(stencilBuffer); \
fmt.setSamples(samples); \
QSurfaceFormat::setDefaultFormat(fmt);}
#endif

View File

@ -46,19 +46,53 @@ void OptionsDialog::automaticPauseDetectionSet(bool set)
QWidget *OptionsDialog::createMapPage()
{
_projection = new LimitedComboBox(200);
int last = -1;
_outputProjection = new LimitedComboBox(200);
QList<KV<int, QString> > projections(GCS::list() + PCS::list());
qSort(projections);
std::sort(projections.begin(), projections.end());
for (int i = 0; i < projections.size(); i++) {
QString text = QString::number(projections.at(i).key()) + " - "
+ projections.at(i).value();
_projection->addItem(text, QVariant(projections.at(i).key()));
const KV<int, QString> &proj = projections.at(i);
// There may be same EPSG codes with different names
if (proj.key() == last)
continue;
else
last = proj.key();
QString text = QString::number(proj.key()) + " - " + proj.value();
_outputProjection->addItem(text, QVariant(proj.key()));
}
_projection->setCurrentIndex(_projection->findData(_options.projection));
_outputProjection->setCurrentIndex(_outputProjection->findData(
_options.outputProjection));
_inputProjection = new LimitedComboBox(200);
last = -1;
for (int i = 0; i < projections.size(); i++) {
const KV<int, QString> &proj = projections.at(i);
// There may be same EPSG codes with different names
if (proj.key() == last)
continue;
else
last = proj.key();
if (proj.key() == 4326 || proj.key() == 3857) {
QString text = QString::number(proj.key()) + " - " + proj.value();
_inputProjection->addItem(text, QVariant(proj.key()));
}
}
_inputProjection->setCurrentIndex(_inputProjection->findData(
_options.inputProjection));
QLabel *inInfo = new QLabel(tr("Select the proper projection of"
" JNX and KMZ maps. Both EPSG:3857 and EPSG:4326 projected maps"
" exist and there is no projection info in the map file."));
QLabel *outInfo = new QLabel(tr("Select the desired projection of IMG"
" maps. The projection must be valid for the whole map area."));
QFont f = inInfo->font();
f.setPointSize(f.pointSize() - 1);
inInfo->setWordWrap(true);
outInfo->setWordWrap(true);
inInfo->setFont(f);
outInfo->setFont(f);
#ifdef ENABLE_HIDPI
_hidpi = new QRadioButton(tr("High-resolution"));
_lodpi = new QRadioButton(tr("Standard"));
if (_options.hidpiMap)
@ -69,24 +103,39 @@ QWidget *OptionsDialog::createMapPage()
"The map is sharp but map objects are small/hard to read."));
QLabel *llo = new QLabel(tr("Non-HiDPI maps are loaded such as they are. "
"Map objects have the expected size but the map is blurry."));
QFont f = lhi->font();
f.setPointSize(f.pointSize() - 1);
lhi->setWordWrap(true);
llo->setWordWrap(true);
lhi->setFont(f);
llo->setFont(f);
#endif // ENABLE_HIDPI
QFormLayout *vectorLayout = new QFormLayout();
vectorLayout->addRow(tr("Projection:"), _projection);
QVBoxLayout *inLayout = new QVBoxLayout();
inLayout->addWidget(_inputProjection);
inLayout->addWidget(inInfo);
QVBoxLayout *outLayout = new QVBoxLayout();
outLayout->addWidget(_outputProjection);
outLayout->addWidget(outInfo);
#ifndef Q_OS_MAC
QGroupBox *inBox = new QGroupBox(tr("Input"));
inBox->setLayout(inLayout);
QGroupBox *outBox = new QGroupBox(tr("Output"));
outBox->setLayout(outLayout);
#endif // Q_OS_MAC
QWidget *vectorMapsTab = new QWidget();
QVBoxLayout *vectorMapsTabLayout = new QVBoxLayout();
vectorMapsTabLayout->addLayout(vectorLayout);
vectorMapsTabLayout->addStretch();
vectorMapsTab->setLayout(vectorMapsTabLayout);
QWidget *projectionTab = new QWidget();
QVBoxLayout *projectionTabLayout = new QVBoxLayout();
#ifdef Q_OS_MAC
projectionTabLayout->addWidget(new QLabel(tr("Input:")));
projectionTabLayout->addLayout(inLayout);
projectionTabLayout->addWidget(line());
projectionTabLayout->addWidget(new QLabel(tr("Output:")));
projectionTabLayout->addLayout(outLayout);
#else // Q_OS_MAC
projectionTabLayout->addWidget(inBox);
projectionTabLayout->addWidget(outBox);
#endif // Q_OS_MAC
projectionTabLayout->addStretch();
projectionTab->setLayout(projectionTabLayout);
#ifdef ENABLE_HIDPI
QVBoxLayout *hidpiTabLayout = new QVBoxLayout();
hidpiTabLayout->addWidget(_lodpi);
hidpiTabLayout->addWidget(llo);
@ -97,13 +146,10 @@ QWidget *OptionsDialog::createMapPage()
QWidget *hidpiTab = new QWidget();
hidpiTab->setLayout(hidpiTabLayout);
#endif // ENABLE_HIDPI
QTabWidget *mapPage = new QTabWidget();
mapPage->addTab(vectorMapsTab, tr("Vector maps"));
#ifdef ENABLE_HIDPI
mapPage->addTab(projectionTab, tr("Projection"));
mapPage->addTab(hidpiTab, tr("HiDPI display mode"));
#endif // ENABLE_HIDPI
return mapPage;
}
@ -416,7 +462,6 @@ QWidget *OptionsDialog::createDataPage()
_showSecondaryElevation = new QCheckBox(tr("Show secondary elevation"));
_showSecondaryElevation->setChecked(_options.showSecondaryElevation);
#ifdef ENABLE_TIMEZONES
_utcZone = new QRadioButton(tr("UTC"));
_systemZone = new QRadioButton(tr("System"));
_customZone = new QRadioButton(tr("Custom"));
@ -437,7 +482,6 @@ QWidget *OptionsDialog::createDataPage()
QHBoxLayout *customZoneLayout = new QHBoxLayout();
customZoneLayout->addSpacing(20);
customZoneLayout->addWidget(_timeZone);
#endif // ENABLE_TIMEZONES
_useSegments = new QCheckBox(tr("Use segments"));
_useSegments->setChecked(_options.useSegments);
@ -462,7 +506,6 @@ QWidget *OptionsDialog::createDataPage()
elevationOptions->addWidget(_dataDEMElevation);
elevationOptions->addWidget(_showSecondaryElevation);
#ifdef ENABLE_TIMEZONES
QButtonGroup *timeZoneGroup = new QButtonGroup(this);
timeZoneGroup->addButton(_utcZone);
timeZoneGroup->addButton(_systemZone);
@ -472,15 +515,12 @@ QWidget *OptionsDialog::createDataPage()
zoneOptions->addWidget(_systemZone);
zoneOptions->addWidget(_customZone);
zoneOptions->addItem(customZoneLayout);
#endif // ENABLE_TIMEZONES
QFormLayout *formLayout = new QFormLayout();
formLayout->addRow(tr("Speed:"), speedOptions);
formLayout->addRow(tr("Elevation:"), elevationOptions);
#ifdef ENABLE_TIMEZONES
formLayout->addRow(tr("Time zone:"), zoneOptions);
#endif // ENABLE_TIMEZONES
QFormLayout *segmentsLayout = new QFormLayout();
segmentsLayout->addWidget(_useSegments);
@ -492,9 +532,7 @@ QWidget *OptionsDialog::createDataPage()
#else // Q_OS_MAC
QFormLayout *speedLayout = new QFormLayout();
QFormLayout *elevationLayout = new QFormLayout();
#ifdef ENABLE_TIMEZONES
QFormLayout *timeZoneLayout = new QFormLayout();
#endif // ENABLE_TIMEZONES
QFormLayout *segmentsLayout = new QFormLayout();
speedLayout->addWidget(_computedSpeed);
@ -511,7 +549,6 @@ QWidget *OptionsDialog::createDataPage()
QGroupBox *elevationBox = new QGroupBox(tr("Elevation"));
elevationBox->setLayout(elevationLayout);
#ifdef ENABLE_TIMEZONES
timeZoneLayout->addWidget(_utcZone);
timeZoneLayout->addWidget(_systemZone);
timeZoneLayout->addWidget(_customZone);
@ -519,15 +556,12 @@ QWidget *OptionsDialog::createDataPage()
QGroupBox *timeZoneBox = new QGroupBox(tr("Time zone"));
timeZoneBox->setLayout(timeZoneLayout);
#endif // ENABLE_TIMEZONES
segmentsLayout->addWidget(_useSegments);
sourceTabLayout->addWidget(speedBox);
sourceTabLayout->addWidget(elevationBox);
#ifdef ENABLE_TIMEZONES
sourceTabLayout->addWidget(timeZoneBox);
#endif // ENABLE_TIMEZONES
sourceTabLayout->addLayout(segmentsLayout);
#endif // Q_OS_MAC
sourceTabLayout->addStretch();
@ -648,10 +682,8 @@ QWidget *OptionsDialog::createSystemPage()
{
_useOpenGL = new QCheckBox(tr("Use OpenGL"));
_useOpenGL->setChecked(_options.useOpenGL);
#ifdef ENABLE_HTTP2
_enableHTTP2 = new QCheckBox(tr("Enable HTTP/2"));
_enableHTTP2->setChecked(_options.enableHTTP2);
#endif // ENABLE_HTTP2
_pixmapCache = new QSpinBox();
_pixmapCache->setMinimum(16);
@ -670,9 +702,7 @@ QWidget *OptionsDialog::createSystemPage()
formLayout->addRow(tr("Connection timeout:"), _connectionTimeout);
QFormLayout *checkboxLayout = new QFormLayout();
#ifdef ENABLE_HTTP2
checkboxLayout->addWidget(_enableHTTP2);
#endif // ENABLE_HTTP2
checkboxLayout->addWidget(_useOpenGL);
QWidget *systemTab = new QWidget();
@ -764,11 +794,11 @@ void OptionsDialog::accept()
_options.sliderColor = _sliderColor->color();
_options.graphAntiAliasing = _graphAA->isChecked();
_options.projection = _projection->itemData(_projection->currentIndex())
.toInt();
#ifdef ENABLE_HIDPI
_options.outputProjection = _outputProjection->itemData(
_outputProjection->currentIndex()).toInt();
_options.inputProjection = _inputProjection->itemData(
_inputProjection->currentIndex()).toInt();
_options.hidpiMap = _hidpi->isChecked();
#endif // ENABLE_HIDPI
_options.elevationFilter = _elevationFilter->value();
_options.speedFilter = _speedFilter->value();
@ -787,13 +817,11 @@ void OptionsDialog::accept()
_options.dataUseDEM = _dataDEMElevation->isChecked();
_options.showSecondaryElevation = _showSecondaryElevation->isChecked();
_options.showSecondarySpeed = _showSecondarySpeed->isChecked();
#ifdef ENABLE_TIMEZONES
_options.timeZone.setType(_utcZone->isChecked()
? TimeZoneInfo::UTC : _systemZone->isChecked()
? TimeZoneInfo::System : TimeZoneInfo::Custom);
_options.timeZone.setCustomZone(QTimeZone(_timeZone->currentText()
.toLatin1()));
#endif // ENABLE_TIMEZONES
_options.useSegments = _useSegments->isChecked();
qreal poiRadius = (_units == Imperial)
@ -803,9 +831,7 @@ void OptionsDialog::accept()
_options.poiRadius = poiRadius;
_options.useOpenGL = _useOpenGL->isChecked();
#ifdef ENABLE_HTTP2
_options.enableHTTP2 = _enableHTTP2->isChecked();
#endif // ENABLE_HTTP2
_options.pixmapCache = _pixmapCache->value();
_options.connectionTimeout = _connectionTimeout->value();

View File

@ -2,12 +2,9 @@
#define OPTIONSDIALOG_H
#include <QDialog>
#include "common/config.h"
#include "palette.h"
#include "units.h"
#ifdef ENABLE_TIMEZONES
#include "timezoneinfo.h"
#endif // ENABLE_TIMEZONES
class ColorBox;
class StyleComboBox;
@ -42,10 +39,9 @@ struct Options {
int mapOpacity;
QColor backgroundColor;
// Map
int projection;
#ifdef ENABLE_HIDPI
int outputProjection;
int inputProjection;
bool hidpiMap;
#endif // ENABLE_HIDPI
// Data
int elevationFilter;
int speedFilter;
@ -60,17 +56,13 @@ struct Options {
bool dataUseDEM;
bool showSecondaryElevation;
bool showSecondarySpeed;
#ifdef ENABLE_TIMEZONES
TimeZoneInfo timeZone;
#endif // ENABLE_TIMEZONES
bool useSegments;
// POI
int poiRadius;
// System
bool useOpenGL;
#ifdef ENABLE_HTTP2
bool enableHTTP2;
#endif // ENABLE_HTTP2
int pixmapCache;
int connectionTimeout;
// Print/Export
@ -129,11 +121,10 @@ private:
ColorBox *_sliderColor;
QCheckBox *_graphAA;
// Map
LimitedComboBox *_projection;
#ifdef ENABLE_HIDPI
LimitedComboBox *_outputProjection;
LimitedComboBox *_inputProjection;
QRadioButton *_hidpi;
QRadioButton *_lodpi;
#endif // ENABLE_HIDPI
// Data
OddSpinBox *_elevationFilter;
OddSpinBox *_speedFilter;
@ -151,12 +142,10 @@ private:
QRadioButton *_dataDEMElevation;
QCheckBox *_showSecondaryElevation;
QCheckBox *_showSecondarySpeed;
#ifdef ENABLE_TIMEZONES
QRadioButton *_utcZone;
QRadioButton *_systemZone;
QRadioButton *_customZone;
QComboBox *_timeZone;
#endif // ENABLE_TIMEZONES
QCheckBox *_useSegments;
// POI
QDoubleSpinBox *_poiRadius;
@ -164,9 +153,7 @@ private:
QSpinBox *_pixmapCache;
QSpinBox *_connectionTimeout;
QCheckBox *_useOpenGL;
#ifdef ENABLE_HTTP2
QCheckBox *_enableHTTP2;
#endif // ENABLE_HTTP2
// Print/Export
QRadioButton *_wysiwyg;
QRadioButton *_hires;

View File

@ -24,8 +24,13 @@ public:
{return !(*this == other);}
private:
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
qreal _h, _s, _v, _a, _shift;
qreal _state;
#else // QT6
float _h, _s, _v, _a, _shift;
float _state;
#endif // QT6
};
#ifndef QT_NO_DEBUG

View File

@ -22,9 +22,7 @@ static inline unsigned segments(qreal distance)
}
Units PathItem::_units = Metric;
#ifdef ENABLE_TIMEZONES
QTimeZone PathItem::_timeZone = QTimeZone::utc();
#endif // ENABLE_TIMEZONES
PathItem::PathItem(const Path &path, Map *map, QGraphicsItem *parent)
: GraphicsItem(parent), _path(path), _map(map)
@ -68,14 +66,22 @@ void PathItem::addSegment(const Coordinates &c1, const Coordinates &c2)
QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() + 360,
c2.lat()));
QLineF dl(QPointF(180, -90), QPointF(180, 90));
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
l.intersect(dl, &p);
#else // QT 5.15
l.intersects(dl, &p);
#endif // QT 5.15
_painterPath.lineTo(_map->ll2xy(Coordinates(180, p.y())));
_painterPath.moveTo(_map->ll2xy(Coordinates(-180, p.y())));
} else {
QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() - 360,
c2.lat()));
QLineF dl(QPointF(-180, -90), QPointF(-180, 90));
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
l.intersect(dl, &p);
#else // QT 5.15
l.intersects(dl, &p);
#endif // QT 5.15
_painterPath.lineTo(_map->ll2xy(Coordinates(-180, p.y())));
_painterPath.moveTo(_map->ll2xy(Coordinates(180, p.y())));
}

View File

@ -1,12 +1,9 @@
#ifndef PATHITEM_H
#define PATHITEM_H
#include "common/config.h"
#include <QGraphicsObject>
#include <QPen>
#ifdef ENABLE_TIMEZONES
#include <QTimeZone>
#endif // ENABLE_TIMEZONES
#include "data/path.h"
#include "markeritem.h"
#include "units.h"
@ -43,9 +40,7 @@ public:
void updateTicks();
static void setUnits(Units units) {_units = units;}
#ifdef ENABLE_TIMEZONES
static void setTimeZone(const QTimeZone &zone) {_timeZone = zone;}
#endif // ENABLE_TIMEZONES
public slots:
void moveMarker(qreal distance);
@ -60,9 +55,7 @@ protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
static Units _units;
#ifdef ENABLE_TIMEZONES
static QTimeZone _timeZone;
#endif // ENABLE_TIMEZONES
private:
const PathSegment *segment(qreal x) const;

View File

@ -24,18 +24,18 @@ PDFExportDialog::PDFExportDialog(PDFExport &exp, Units units, QWidget *parent)
_fileSelect->setFile(_export.fileName);
_paperSize = new QComboBox();
_paperSize->addItem("A2", QPrinter::A2);
_paperSize->addItem("A3", QPrinter::A3);
_paperSize->addItem("A4", QPrinter::A4);
_paperSize->addItem("A5", QPrinter::A5);
_paperSize->addItem("A6", QPrinter::A6);
_paperSize->addItem("B3", QPrinter::B3);
_paperSize->addItem("B4", QPrinter::B4);
_paperSize->addItem("B5", QPrinter::B5);
_paperSize->addItem("B6", QPrinter::B6);
_paperSize->addItem("Tabloid", QPrinter::Tabloid);
_paperSize->addItem("Legal", QPrinter::Legal);
_paperSize->addItem("Letter", QPrinter::Letter);
_paperSize->addItem("A2", QPageSize::PageSizeId::A2);
_paperSize->addItem("A3", QPageSize::PageSizeId::A3);
_paperSize->addItem("A4", QPageSize::PageSizeId::A4);
_paperSize->addItem("A5", QPageSize::PageSizeId::A5);
_paperSize->addItem("A6", QPageSize::PageSizeId::A6);
_paperSize->addItem("B3", QPageSize::PageSizeId::B3);
_paperSize->addItem("B4", QPageSize::PageSizeId::B4);
_paperSize->addItem("B5", QPageSize::PageSizeId::B5);
_paperSize->addItem("B6", QPageSize::PageSizeId::B6);
_paperSize->addItem("Tabloid", QPageSize::PageSizeId::Tabloid);
_paperSize->addItem("Legal", QPageSize::PageSizeId::Legal);
_paperSize->addItem("Letter", QPageSize::PageSizeId::Letter);
if ((index = _paperSize->findData(_export.paperSize)) >= 0)
_paperSize->setCurrentIndex(index);
@ -51,7 +51,7 @@ PDFExportDialog::PDFExportDialog(PDFExport &exp, Units units, QWidget *parent)
QHBoxLayout *orientationLayout = new QHBoxLayout();
orientationLayout->addWidget(_portrait);
orientationLayout->addWidget(_landscape);
if (_export.orientation == QPrinter::Portrait)
if (_export.orientation == QPageLayout::Orientation::Portrait)
_portrait->setChecked(true);
else
_landscape->setChecked(true);
@ -116,9 +116,9 @@ void PDFExportDialog::accept()
return;
}
QPrinter::Orientation orientation = _portrait->isChecked()
? QPrinter::Portrait : QPrinter::Landscape;
QPrinter::PaperSize paperSize = static_cast<QPrinter::PaperSize>
QPageLayout::Orientation orientation = _portrait->isChecked()
? QPageLayout::Orientation::Portrait : QPageLayout::Orientation::Landscape;
QPageSize::PageSizeId paperSize = static_cast<QPageSize::PageSizeId>
(_paperSize->itemData(_paperSize->currentIndex()).toInt());
int resolution = _resolution->itemData(_resolution->currentIndex()).toInt();

View File

@ -3,7 +3,6 @@
#include <QDialog>
#include <QPrinter>
#include "margins.h"
#include "units.h"
class QComboBox;
@ -14,9 +13,9 @@ class MarginsFWidget;
struct PDFExport
{
QString fileName;
QPrinter::PaperSize paperSize;
QPrinter::Orientation orientation;
MarginsF margins;
QPageSize::PageSizeId paperSize;
QPageLayout::Orientation orientation;
QMarginsF margins;
int resolution;
};

24
src/GUI/planeitem.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef PLANEITEM_H
#define PLANEITEM_H
#include "common/rectc.h"
#include "graphicsscene.h"
class Map;
class PlaneItem : public GraphicsItem
{
public:
PlaneItem(GraphicsItem *parent = 0) : GraphicsItem(parent) {}
virtual RectC bounds() const = 0;
virtual void setMap(Map *map) = 0;
virtual void setColor(const QColor &color) = 0;
virtual void setOpacity(qreal opacity) = 0;
virtual void setWidth(qreal width) = 0;
virtual void setStyle(Qt::PenStyle style) = 0;
virtual void setDigitalZoom(int zoom) = 0;
};
#endif // PLANEITEM_H

View File

@ -3,7 +3,6 @@
#include <QDialog>
#include <QMargins>
#include "margins.h"
class FileSelectWidget;
class MarginsWidget;

View File

@ -4,9 +4,12 @@
#include <QStyleOptionFrame>
#include <QLabel>
#include <QMouseEvent>
#include <QApplication>
#include <QDesktopWidget>
#include <QBasicTimer>
#include <QScreen>
#include <QApplication>
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
#include <QDesktopWidget>
#endif // QT 5.15
#include "popup.h"
@ -36,10 +39,7 @@ PopupLabel *PopupLabel::_instance = 0;
PopupLabel::PopupLabel(const QString &text, QWidget *parent)
: QLabel(text, parent, Qt::ToolTip | Qt::BypassGraphicsProxyWidget
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
| Qt::WindowDoesNotAcceptFocus
#endif // QT5
)
| Qt::WindowDoesNotAcceptFocus)
{
delete _instance;
_instance = this;
@ -74,7 +74,7 @@ void PopupLabel::paintEvent(QPaintEvent *event)
{
QStylePainter p(this);
QStyleOptionFrame opt;
opt.init(this);
opt.initFrom(this);
p.drawPrimitive(QStyle::PE_PanelTipLabel, opt);
p.end();
QLabel::paintEvent(event);
@ -125,7 +125,11 @@ bool PopupLabel::eventFilter(QObject *o, QEvent *ev)
void PopupLabel::place(const QPoint &pos, QWidget *w)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
QRect screen = QApplication::desktop()->screenGeometry(w);
#else // QT 5.15
QRect screen = w->screen()->geometry();
#endif // QT 5.15
QPoint p(pos.x() + 2, pos.y() + 16);
if (p.x() + width() > screen.x() + screen.width())

View File

@ -68,10 +68,11 @@
#define PDF_EXPORT_SETTINGS_GROUP "Export"
#define PAPER_ORIENTATION_SETTING "orientation"
#define PAPER_ORIENTATION_DEFAULT QPrinter::Portrait
#define PAPER_ORIENTATION_DEFAULT QPageLayout::Orientation::Portrait
#define PAPER_SIZE_SETTING "size"
#define PAPER_SIZE_DEFAULT (IMPERIAL_UNITS() ? QPrinter::Letter \
: QPrinter::A4)
#define PAPER_SIZE_DEFAULT (IMPERIAL_UNITS() \
? QPageSize::PageSizeId::Letter \
: QPageSize::PageSizeId::A4)
#define PDF_MARGIN_LEFT_SETTING "marginLeft"
#define PDF_MARGIN_LEFT_DEFAULT 5 /* mm */
#define PDF_MARGIN_TOP_SETTING "marginTop"
@ -199,8 +200,10 @@
#define SEPARATE_GRAPH_PAGE_DEFAULT false
#define SLIDER_COLOR_SETTING "sliderColor"
#define SLIDER_COLOR_DEFAULT QColor(Qt::red)
#define PROJECTION_SETTING "projection"
#define PROJECTION_DEFAULT 3857
#define OUTPUT_PROJECTION_SETTING "outputProjection"
#define OUTPUT_PROJECTION_DEFAULT 3857
#define INPUT_PROJECTION_SETTING "inputProjection"
#define INPUT_PROJECTION_DEFAULT 4326
#define HIDPI_MAP_SETTING "HiDPIMap"
#define HIDPI_MAP_DEFAULT true

View File

@ -18,7 +18,7 @@ void SliderInfoItem::updateBoundingRect()
{
QFontMetrics fm(_font);
qreal width = qMax(fm.width(_x), fm.width(_y));
qreal width = qMax(fm.boundingRect(_x).width(), fm.boundingRect(_y).width());
qreal height = 2 * fm.height() - 2*fm.descent();
_boundingRect = (_side == Right)
@ -35,16 +35,16 @@ void SliderInfoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem
QRectF rx, ry;
qreal width = qMax(fm.width(_x), fm.width(_y));
qreal width = qMax(fm.boundingRect(_x).width(), fm.boundingRect(_y).width());
if (_side == Right) {
ry = QRectF(SIZE, -fm.height() + fm.descent(), fm.width(_y),
ry = QRectF(SIZE, -fm.height() + fm.descent(), fm.boundingRect(_y).width(),
fm.height() - fm.descent());
rx = QRectF(SIZE, 0, fm.width(_x), fm.height()
rx = QRectF(SIZE, 0, fm.boundingRect(_x).width(), fm.height()
- fm.descent());
} else {
ry = QRectF(-(width + SIZE), -fm.height() + fm.descent(), fm.width(_y),
fm.height() - fm.descent());
rx = QRectF(-(width + SIZE), 0, fm.width(_x), fm.height()
ry = QRectF(-(width + SIZE), -fm.height() + fm.descent(),
fm.boundingRect(_y).width(), fm.height() - fm.descent());
rx = QRectF(-(width + SIZE), 0, fm.boundingRect(_x).width(), fm.height()
- fm.descent());
}

View File

@ -3,6 +3,7 @@
#include <QTimeZone>
#include <QDataStream>
#include <QDebug>
class TimeZoneInfo
{
@ -42,6 +43,7 @@ public:
private:
friend QDataStream& operator<<(QDataStream &out, const TimeZoneInfo &info);
friend QDataStream& operator>>(QDataStream &in, TimeZoneInfo &info);
friend QDebug operator<<(QDebug dbg, const TimeZoneInfo &info);
Type _type;
QTimeZone _customZone;
@ -66,4 +68,12 @@ inline QDataStream &operator>>(QDataStream &in, TimeZoneInfo &info)
return in;
}
// Required in Qt6 even in release builds
inline QDebug operator<<(QDebug dbg, const TimeZoneInfo &info)
{
dbg.nospace() << "TimeZoneInfo(" << static_cast<int>(info._type)
<< ", " << info._customZone << ")";
return dbg.space();
}
#endif // TIMEZONEINFO_H

View File

@ -8,6 +8,7 @@
QString TrackItem::info() const
{
ToolTip tt;
QLocale l;
if (!_name.isEmpty())
tt.insert(tr("Name"), _name);
@ -22,13 +23,7 @@ QString TrackItem::info() const
if (_movingTime > 0)
tt.insert(tr("Moving time"), Format::timeSpan(_movingTime));
if (!_date.isNull())
tt.insert(tr("Date"),
#ifdef ENABLE_TIMEZONES
_date.toTimeZone(_timeZone)
#else // ENABLE_TIMEZONES
_date
#endif // ENABLE_TIMEZONES
.toString(Qt::SystemLocaleShortDate));
tt.insert(tr("Date"), l.toString(_date.toTimeZone(_timeZone)));
if (!_links.isEmpty()) {
QString links;
for (int i = 0; i < _links.size(); i++) {

View File

@ -16,13 +16,12 @@
Units WaypointItem::_units = Metric;
CoordinatesFormat WaypointItem::_format = DecimalDegrees;
#ifdef ENABLE_TIMEZONES
QTimeZone WaypointItem::_timeZone = QTimeZone::utc();
#endif // ENABLE_TIMEZONES
QString WaypointItem::info() const
{
ToolTip tt;
QLocale l;
if (!_waypoint.name().isEmpty())
tt.insert(qApp->translate("WaypointItem", "Name"), _waypoint.name());
@ -37,12 +36,8 @@ QString WaypointItem::info() const
}
if (_waypoint.timestamp().isValid())
tt.insert(qApp->translate("WaypointItem", "Date"),
#ifdef ENABLE_TIMEZONES
_waypoint.timestamp().toTimeZone(_timeZone)
#else // ENABLE_TIMEZONES
_waypoint.timestamp()
#endif // ENABLE_TIMEZONES
.toString(Qt::SystemLocaleShortDate));
l.toString(_waypoint.timestamp().toTimeZone(_timeZone),
QLocale::ShortFormat));
if (!_waypoint.description().isEmpty())
tt.insert(qApp->translate("WaypointItem", "Description"),
_waypoint.description());

View File

@ -1,13 +1,10 @@
#ifndef WAYPOINTITEM_H
#define WAYPOINTITEM_H
#include "common/config.h"
#include <cmath>
#include <QGraphicsItem>
#include <QFont>
#ifdef ENABLE_TIMEZONES
#include <QTimeZone>
#endif // ENABLE_TIMEZONES
#include "data/waypoint.h"
#include "map/map.h"
#include "units.h"
@ -38,9 +35,7 @@ public:
static void setUnits(Units units) {_units = units;}
static void setCoordinatesFormat(CoordinatesFormat format)
{_format = format;}
#ifdef ENABLE_TIMEZONES
static void setTimeZone(const QTimeZone &zone) {_timeZone = zone;}
#endif // ENABLE_TIMEZONES
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
@ -60,9 +55,7 @@ private:
static Units _units;
static CoordinatesFormat _format;
#ifdef ENABLE_TIMEZONES
static QTimeZone _timeZone;
#endif // ENABLE_TIMEZONES
};
#endif // WAYPOINTITEM_H

View File

@ -6,20 +6,4 @@
#define APP_NAME "GPXSee"
#define APP_HOMEPAGE "http://www.gpxsee.org"
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 1)
#define ENABLE_HTTP2
#endif // QT >= 5.10.1
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
#define ENABLE_HIDPI
#endif // QT >= 5.6
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#define ENABLE_GEOJSON
#endif // QT >= 5.0
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
#define ENABLE_TIMEZONES
#endif // QT >= 5.5
#endif /* CONFIG_H */

View File

@ -1,5 +1,6 @@
#include <QtGlobal>
#include <QDir>
#include <QStandardPaths>
#include "programpaths.h"
@ -16,119 +17,6 @@
#define TYP_FILE "style.typ"
#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
#include <QApplication>
#if defined(Q_OS_WIN32)
#define USER_DIR QDir::homePath() + QString("/AppData/Roaming/") \
+ qApp->applicationName()
#define GLOBAL_DIR QApplication::applicationDirPath()
#elif defined(Q_OS_MAC)
#define USER_DIR QDir::homePath() \
+ QString("/Library/Application Support/") \
+ qApp->applicationName()
#define GLOBAL_DIR QApplication::applicationDirPath() \
+ QString("/../Resources")
#else
#define USER_DIR QDir::homePath() + QString("/.local/share/") \
+ qApp->applicationName()
#define GLOBAL_DIR QString(PREFIX "/share/") + qApp->applicationName()
#endif
static QString dir(const QString &dirName, bool writable = false)
{
QDir userDir(QDir(USER_DIR).filePath(dirName));
if (writable || userDir.exists())
return userDir.absolutePath();
else {
QDir globalDir(QDir(GLOBAL_DIR).filePath(dirName));
if (globalDir.exists())
return globalDir.absolutePath();
else
return QString();
}
}
static QString file(const QString &path, const QString &fileName)
{
if (path.isNull())
return QString();
QFileInfo fi(QDir(path).filePath(fileName));
return fi.exists() ? fi.absoluteFilePath() : QString();
}
QString ProgramPaths::mapDir(bool writable)
{
return dir(MAP_DIR, writable);
}
QString ProgramPaths::poiDir(bool writable)
{
return dir(POI_DIR, writable);
}
QString ProgramPaths::csvDir(bool writable)
{
return dir(CSV_DIR, writable);
}
QString ProgramPaths::demDir(bool writable)
{
return dir(DEM_DIR, writable);
}
QString ProgramPaths::styleDir(bool writable)
{
return dir(STYLE_DIR, writable);
}
QString ProgramPaths::tilesDir()
{
#if defined(Q_OS_WIN32)
return QDir::homePath() + QString("/AppData/Local/")
+ qApp->applicationName() + QString("/cache/") + QString(TILES_DIR);
#elif defined(Q_OS_MAC)
return QDir::homePath() + QString("/Library/Caches/")
+ qApp->applicationName() + QString("/" TILES_DIR);
#else
return QDir::homePath() + QString("/.cache/") + qApp->applicationName()
+ QString("/" TILES_DIR);
#endif
}
QString ProgramPaths::translationsDir()
{
return dir(TRANSLATIONS_DIR);
}
QString ProgramPaths::ellipsoidsFile()
{
return file(dir(CSV_DIR), ELLIPSOID_FILE);
}
QString ProgramPaths::gcsFile()
{
return file(dir(CSV_DIR), GCS_FILE);
}
QString ProgramPaths::pcsFile()
{
return file(dir(CSV_DIR), PCS_FILE);
}
QString ProgramPaths::typFile()
{
return file(dir(STYLE_DIR), TYP_FILE);
}
#else // QT_VERSION < 5
#include <QStandardPaths>
QString ProgramPaths::mapDir(bool writable)
{
if (writable)
@ -214,5 +102,3 @@ QString ProgramPaths::typFile()
return QStandardPaths::locate(QStandardPaths::AppDataLocation,
STYLE_DIR "/" TYP_FILE, QStandardPaths::LocateFile);
}
#endif // QT_VERSION < 5

View File

@ -1,3 +1,4 @@
#include <cmath>
#include "wgs84.h"
#include "rectc.h"
@ -6,6 +7,16 @@
#define MIN_LON deg2rad(-180.0)
#define MAX_LON deg2rad(180.0)
static inline double WLON(double lon)
{
return remainder(lon, 360.0);
}
static inline double LLAT(double lat)
{
return (lat < 0.0) ? qMax(lat, -90.0) : qMin(lat, 90.0);
}
RectC::RectC(const Coordinates &center, double radius)
{
double radDist = radius / WGS84_RADIUS;
@ -151,6 +162,12 @@ RectC RectC::united(const Coordinates &c) const
return RectC(Coordinates(l, t), Coordinates(r, b));
}
RectC RectC::adjusted(double lon1, double lat1, double lon2, double lat2) const
{
return RectC(Coordinates(WLON(_tl.lon() + lon1), LLAT(_tl.lat() + lat1)),
Coordinates(WLON(_br.lon() + lon2), LLAT(_br.lat() + lat2)));
}
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const RectC &rect)
{

View File

@ -16,7 +16,7 @@ public:
{return _tl.isNull() && _br.isNull();}
bool isValid() const
{return (_tl.isValid() && _br.isValid()
&& _tl.lat() > _br.lat() && _tl.lon() < _br.lon());}
&& _tl.lat() != _br.lat() && _tl.lon() != _br.lon());}
Coordinates topLeft() const {return _tl;}
Coordinates bottomRight() const {return _br;}
@ -24,14 +24,18 @@ public:
{return Coordinates((_tl.lon() + _br.lon()) / 2.0,
(_tl.lat() + _br.lat()) / 2.0);}
double width() const
{
double res = right() - left();
return (left() > right()) ? 360.0 - res : res;
}
double height() const {return (top() - bottom());}
double top() const {return _tl.lat();}
double bottom() const {return _br.lat();}
double left() const {return _tl.lon();}
double right() const {return _br.lon();}
double width() const {return (right() - left());}
double height() const {return (top() - bottom());}
void setLeft(double val) {_tl.rlon() = val;}
void setRight(double val) {_br.rlon() = val;}
void setTop(double val) {_tl.rlat() = val;}
@ -43,6 +47,7 @@ public:
RectC &operator&=(const RectC &r) {*this = *this & r; return *this;}
RectC united(const Coordinates &c) const;
RectC adjusted(double lon1, double lat1, double lon2, double lat2) const;
bool intersects(const RectC &r) const
{return (right() >= r.left() && bottom() <= r.top() && left() <= r.right()

View File

@ -1,11 +0,0 @@
#ifndef ASSERT_H
#define ASSERT_H
template<bool> struct CompileTimeAssert;
template<> struct CompileTimeAssert <true> {};
#define STATIC_ASSERT(e) \
(CompileTimeAssert <(e) != 0>())
#endif // ASSERT_H

214
src/common/textcodec.cpp Normal file
View File

@ -0,0 +1,214 @@
#include <QVector>
#include "textcodec.h"
static const char32_t cp1250[] = {
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
};
static const char32_t cp1251[] = {
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
};
static const char32_t cp1252[] = {
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};
static const char32_t cp1253[] = {
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
};
static const char32_t cp1254[] = {
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
};
static const char32_t cp1255[] = {
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
};
static const char32_t cp1256[] = {
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643,
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2,
};
static const char32_t cp1257[] = {
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9,
};
TextCodec::TextCodec() : _table(cp1252)
{
}
TextCodec::TextCodec(int codepage)
{
switch (codepage) {
case 65001:
_table = 0;
break;
case 1250:
_table = cp1250;
break;
case 1251:
_table = cp1251;
break;
case 1253:
_table = cp1253;
break;
case 1254:
_table = cp1254;
break;
case 1255:
_table = cp1255;
break;
case 1256:
_table = cp1256;
break;
case 1257:
_table = cp1257;
break;
default:
_table = cp1252;
}
}
QString TextCodec::toString(const QByteArray &ba) const
{
if (_table)
return from8bCp(ba);
else
return QString::fromUtf8(ba);
}
QString TextCodec::from8bCp(const QByteArray &ba) const
{
QVector<char32_t> ucs4(ba.size());
for (int i = 0; i < ba.size(); i++) {
quint8 c = (quint8)ba.at(i);
if (c < 0x80)
ucs4[i] = (char32_t)c;
else
ucs4[i] = _table[c - 0x80];
}
return QString::fromUcs4(ucs4.constData(), ucs4.size());
}

20
src/common/textcodec.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef TEXTCODEC_H
#define TEXTCODEC_H
#include <QString>
class TextCodec
{
public:
TextCodec();
TextCodec(int codepage);
QString toString(const QByteArray &ba) const;
private:
QString from8bCp(const QByteArray &ba) const;
const char32_t *_table;
};
#endif // TEXTCODEC_H

View File

@ -8,6 +8,19 @@
class Area : public QList<Polygon>
{
public:
Area() {}
Area(const RectC &rect)
{
Polygon polygon;
QVector<Coordinates> v(4);
v[0] = Coordinates(rect.left(), rect.top());
v[1] = Coordinates(rect.right(), rect.top());
v[2] = Coordinates(rect.right(), rect.bottom());
v[3] = Coordinates(rect.left(), rect.bottom());
polygon.append(v);
append(polygon);
}
const QString& name() const {return _name;}
const QString& description() const {return _desc;}
void setName(const QString &name) {_name = name;}

View File

@ -2,7 +2,6 @@
#include <QFile>
#include <QFileInfo>
#include <QLineF>
#include "common/config.h"
#include "gpxparser.h"
#include "tcxparser.h"
#include "csvparser.h"
@ -13,13 +12,12 @@
#include "oziparsers.h"
#include "locparser.h"
#include "slfparser.h"
#ifdef ENABLE_GEOJSON
#include "geojsonparser.h"
#endif // ENABLE_GEOJSON
#include "exifparser.h"
#include "cupparser.h"
#include "gpiparser.h"
#include "smlparser.h"
#include "map/map.h"
#include "data.h"
@ -35,9 +33,7 @@ static WPTParser wpt;
static RTEParser rte;
static LOCParser loc;
static SLFParser slf;
#ifdef ENABLE_GEOJSON
static GeoJSONParser geojson;
#endif // ENABLE_GEOJSON
static EXIFParser exif;
static CUPParser cup;
static GPIParser gpi;
@ -59,10 +55,8 @@ static QMap<QString, Parser*> parsers()
map.insert("rte", &rte);
map.insert("loc", &loc);
map.insert("slf", &slf);
#ifdef ENABLE_GEOJSON
map.insert("json", &geojson);
map.insert("geojson", &geojson);
#endif // ENABLE_GEOJSON
map.insert("jpeg", &exif);
map.insert("jpg", &exif);
map.insert("cup", &cup);
@ -82,7 +76,7 @@ void Data::processData(QList<TrackData> &trackData, QList<RouteData> &routeData)
_routes.append(Route(routeData.at(i)));
}
Data::Data(const QString &fileName)
Data::Data(const QString &fileName, bool tryUnknown)
{
QFile file(fileName);
QFileInfo fi(fileName);
@ -108,7 +102,7 @@ Data::Data(const QString &fileName)
_errorLine = it.value()->errorLine();
_errorString = it.value()->errorString();
}
} else {
} else if (tryUnknown) {
for (it = _parsers.begin(); it != _parsers.end(); it++) {
if (it.value()->parse(&file, trackData, routeData, _polygons,
_waypoints)) {
@ -136,9 +130,7 @@ QString Data::formats()
+ qApp->translate("Data", "CSV files") + " (*.csv);;"
+ qApp->translate("Data", "CUP files") + " (*.cup);;"
+ qApp->translate("Data", "FIT files") + " (*.fit);;"
#ifdef ENABLE_GEOJSON
+ qApp->translate("Data", "GeoJSON files") + " (*.geojson *.json);;"
#endif // ENABLE_GEOJSON
+ qApp->translate("Data", "GPI files") + " (*.gpi);;"
+ qApp->translate("Data", "GPX files") + " (*.gpx);;"
+ qApp->translate("Data", "IGC files") + " (*.igc);;"

View File

@ -10,11 +10,10 @@
#include "route.h"
#include "parser.h"
class Data
{
public:
Data(const QString &fileName);
Data(const QString &fileName, bool full = true);
bool isValid() const {return _valid;}
const QString &errorString() const {return _errorString;}

View File

@ -1,11 +1,21 @@
/*
WARNING: This code uses internal Qt API - the QZipReader class for reading
ZIP files - and things may break if Qt changes the API. For Qt5 this is not
a problem as we can "see the future" now and there are no changes in all
the supported Qt5 versions up to the last one (5.15). In Qt6 the class
might change or even disappear in the future, but this is very unlikely
as there were no changes for several years and The Qt Company's policy
is: "do not invest any resources into any desktop related stuff unless
absolutely necessary". There is an issue (QTBUG-3897) since the year 2009 to
include the ZIP reader into the public API, which aptly illustrates the
effort The Qt Company is willing to make about anything desktop related...
*/
#include <QtEndian>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QtCore/qmath.h>
#else // QT5
#include <QtMath>
#endif // QT5
#include <QDir>
#include <QFile>
#include <private/qzipreader_p.h>
#include "common/coordinates.h"
#include "dem.h"
@ -59,15 +69,19 @@ static qreal height(const Coordinates &c, const QByteArray *data)
QString DEM::_dir;
QCache<DEM::Key, QByteArray> DEM::_data;
QString DEM::fileName(const Key &key)
QString DEM::baseName(const Key &key)
{
const char ns = (key.lat() >= 0) ? 'N' : 'S';
const char ew = (key.lon() >= 0) ? 'E' : 'W';
QString basename = QString("%1%2%3%4.hgt").arg(ns)
return QString("%1%2%3%4.hgt").arg(ns)
.arg(qAbs(key.lat()), 2, 10, QChar('0')).arg(ew)
.arg(qAbs(key.lon()), 3, 10, QChar('0'));
return QDir(_dir).absoluteFilePath(basename);
}
QString DEM::fileName(const QString &baseName)
{
return QDir(_dir).absoluteFilePath(baseName);
}
void DEM::setDir(const QString &path)
@ -84,17 +98,29 @@ qreal DEM::elevation(const Coordinates &c)
QByteArray *ba = _data[k];
if (!ba) {
QFile file(fileName(k));
if (!file.open(QIODevice::ReadOnly)) {
qWarning("%s: %s", qPrintable(file.fileName()),
qPrintable(file.errorString()));
_data.insert(k, new QByteArray());
return NAN;
} else {
ba = new QByteArray(file.readAll());
QString bn(baseName(k));
QString fn(fileName(bn));
QString zn(fn + ".zip");
if (QFileInfo::exists(zn)) {
QZipReader zip(zn, QIODevice::ReadOnly);
ba = new QByteArray(zip.fileData(bn));
qreal ele = height(c, ba);
_data.insert(k, ba);
return ele;
} else {
QFile file(fn);
if (!file.open(QIODevice::ReadOnly)) {
qWarning("%s: %s", qPrintable(file.fileName()),
qPrintable(file.errorString()));
_data.insert(k, new QByteArray());
return NAN;
} else {
ba = new QByteArray(file.readAll());
qreal ele = height(c, ba);
_data.insert(k, ba);
return ele;
}
}
} else
return height(c, ba);

View File

@ -27,7 +27,8 @@ private:
int _lon, _lat;
};
static QString fileName(const Key &key);
static QString baseName(const Key &key);
static QString fileName(const QString &baseName);
static QString _dir;
static QCache<Key, QByteArray> _data;

View File

@ -1,5 +1,4 @@
#include <QtEndian>
#include "common/staticassert.h"
#include "fitparser.h"
@ -174,7 +173,7 @@ bool FITParser::parseDefinitionMessage(CTX &ctx, quint8 header)
// definition records
def->fields = new Field[def->numFields];
for (i = 0; i < def->numFields; i++) {
STATIC_ASSERT(sizeof(def->fields[i]) == 3);
static_assert(sizeof(def->fields[i]) == 3, "Invalid Field alignment");
if (!readData(ctx.file, (char*)&(def->fields[i]),
sizeof(def->fields[i])))
return false;
@ -188,7 +187,7 @@ bool FITParser::parseDefinitionMessage(CTX &ctx, quint8 header)
def->devFields = new Field[def->numDevFields];
for (i = 0; i < def->numDevFields; i++) {
STATIC_ASSERT(sizeof(def->devFields[i]) == 3);
static_assert(sizeof(def->fields[i]) == 3, "Invalid Field alignment");
if (!readData(ctx.file, (char*)&(def->devFields[i]),
sizeof(def->devFields[i])))
return false;
@ -326,8 +325,8 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
} else if (def->globalId == COURSE_POINT) {
switch (field->id) {
case 1:
waypoint.setTimestamp(QDateTime::fromTime_t(val.toUInt()
+ 631065600));
waypoint.setTimestamp(QDateTime::fromSecsSinceEpoch(val.toUInt()
+ 631065600, Qt::UTC));
break;
case 2:
waypoint.rcoordinates().setLat(
@ -362,8 +361,8 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
}
} else if (def->globalId == RECORD_MESSAGE) {
if (ctx.trackpoint.coordinates().isValid()) {
ctx.trackpoint.setTimestamp(QDateTime::fromTime_t(ctx.timestamp
+ 631065600));
ctx.trackpoint.setTimestamp(QDateTime::fromSecsSinceEpoch(ctx.timestamp
+ 631065600, Qt::UTC));
ctx.trackpoint.setRatio(ctx.ratio);
ctx.segment.append(ctx.trackpoint);
ctx.trackpoint = Trackpoint();
@ -411,7 +410,7 @@ bool FITParser::parseHeader(CTX &ctx)
quint16 crc;
qint64 len;
STATIC_ASSERT(sizeof(hdr) == 12);
static_assert(sizeof(hdr) == 12, "Invalid FileHeader alignment");
len = ctx.file->read((char*)&hdr, sizeof(hdr));
if (len < 0) {
_errorString = "I/O error";

View File

@ -1,6 +1,5 @@
#include <cstring>
#include <QDataStream>
#include <QTextCodec>
#include <QtEndian>
#include <QUrl>
#include <QIODevice>
@ -8,10 +7,9 @@
#include <QBuffer>
#include <QImageReader>
#include <QCryptographicHash>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#include <QTemporaryDir>
#endif // QT_VERSION >= 5
#include "common/garmin.h"
#include "common/textcodec.h"
#include "gpiparser.h"
@ -115,59 +113,76 @@ qint64 CryptDevice::readData(char *data, qint64 maxSize)
}
static qint32 readInt24(QDataStream &stream)
class DataStream : public QDataStream
{
public:
DataStream(QIODevice *d) : QDataStream(d) {}
void setCodepage(quint16 codepage) {_codec = TextCodec(codepage);}
quint16 readString(QString &str);
qint32 readInt24();
quint8 readRecordHeader(RecordHeader &hdr);
quint32 readTranslatedObjects(QList<TranslatedString> &objects);
quint32 skipRecord();
quint16 nextHeaderType();
private:
TextCodec _codec;
};
quint16 DataStream::readString(QString &str)
{
quint16 len;
*this >> len;
QByteArray ba;
ba.resize(len);
readRawData(ba.data(), len);
str = _codec.toString(ba);
return len + 2;
}
qint32 DataStream::readInt24()
{
unsigned char data[3];
quint32 val;
stream.readRawData((char*)data, sizeof(data));
readRawData((char*)data, sizeof(data));
val = data[0] | ((quint32)data[1]) << 8 | ((quint32)data[2]) << 16;
return (val > 0x7FFFFF) ? (val & 0x7FFFFF) - 0x800000 : val;
}
static quint16 nextHeaderType(QDataStream &stream)
quint16 DataStream::nextHeaderType()
{
quint16 type = 0;
if (stream.device()->peek((char*)&type, sizeof(type))
< (qint64)sizeof(type)) {
stream.setStatus(QDataStream::ReadCorruptData);
if (device()->peek((char*)&type, sizeof(type)) < (qint64)sizeof(type)) {
setStatus(QDataStream::ReadCorruptData);
return 0xFFFF;
} else
return qFromLittleEndian(type);
}
static quint8 readRecordHeader(QDataStream &stream, RecordHeader &hdr)
quint8 DataStream::readRecordHeader(RecordHeader &hdr)
{
stream >> hdr.type >> hdr.flags >> hdr.size;
*this >> hdr.type >> hdr.flags >> hdr.size;
if (hdr.flags & 0xA)
stream >> hdr.extra;
*this >> hdr.extra;
return (hdr.flags & 0xA) ? 12 : 8;
}
static quint32 skipRecord(QDataStream &stream)
quint32 DataStream::skipRecord()
{
RecordHeader rh;
quint8 rs = readRecordHeader(stream, rh);
stream.skipRawData(rh.size);
quint8 rs = readRecordHeader(rh);
skipRawData(rh.size);
return rs + rh.size;
}
static quint16 readString(QDataStream &stream, QTextCodec *codec, QString &str)
{
quint16 len;
stream >> len;
QByteArray ba;
ba.resize(len);
stream.readRawData(ba.data(), len);
str = codec ? codec->toUnicode(ba) : QString::fromLatin1(ba);
return len + 2;
}
static quint32 readTranslatedObjects(QDataStream &stream, QTextCodec *codec,
QList<TranslatedString> &objects)
quint32 DataStream::readTranslatedObjects(QList<TranslatedString> &objects)
{
qint32 size = 0, ret;
char lang[3];
@ -175,34 +190,35 @@ static quint32 readTranslatedObjects(QDataStream &stream, QTextCodec *codec,
memset(lang, 0, sizeof(lang));
objects.clear();
stream >> size;
*this >> size;
ret = size + 4;
while (stream.status() == QDataStream::Ok && size > 0) {
while (status() == QDataStream::Ok && size > 0) {
QString str;
stream.readRawData(lang, sizeof(lang) - 1);
size -= readString(stream, codec, str) + 2;
readRawData(lang, sizeof(lang) - 1);
size -= readString(str) + 2;
objects.append(TranslatedString(lang, str));
}
if (size < 0)
stream.setStatus(QDataStream::ReadCorruptData);
setStatus(QDataStream::ReadCorruptData);
return ret;
}
static quint32 readFprsRecord(QDataStream &stream)
static quint32 readFprsRecord(DataStream &stream)
{
RecordHeader rh;
quint16 s1;
quint8 rs, s2, s3, s4;
rs = readRecordHeader(stream, rh);
rs = stream.readRecordHeader(rh);
stream >> s1 >> s2 >> s3 >> s4;
return rs + 5;
}
static quint32 readFileDataRecord(QDataStream &stream, QTextCodec *codec)
static quint32 readFileDataRecord(DataStream &stream)
{
RecordHeader rh;
quint32 ds, s1;
@ -210,11 +226,11 @@ static quint32 readFileDataRecord(QDataStream &stream, QTextCodec *codec)
quint8 rs;
QList<TranslatedString> obj;
rs = readRecordHeader(stream, rh);
rs = stream.readRecordHeader(rh);
stream >> s1 >> s2 >> s3;
ds = 8;
ds += readTranslatedObjects(stream, codec, obj);
ds += readTranslatedObjects(stream, codec, obj);
ds += stream.readTranslatedObjects(obj);
ds += stream.readTranslatedObjects(obj);
if (s1 & 0x10) {
quint8 ss1, ss2;
@ -231,7 +247,7 @@ static quint32 readFileDataRecord(QDataStream &stream, QTextCodec *codec)
}
if (s1 & 0x400) {
QString str;
ds += readString(stream, codec, str);
ds += stream.readString(str);
}
if (s1 & 0x400000) {
quint16 ss1;
@ -251,16 +267,15 @@ static quint32 readFileDataRecord(QDataStream &stream, QTextCodec *codec)
return rs + rh.size;
}
static quint32 readDescription(QDataStream &stream, QTextCodec *codec,
Waypoint &waypoint)
static quint32 readDescription(DataStream &stream, Waypoint &waypoint)
{
RecordHeader rh;
quint8 rs;
quint32 ds;
QList<TranslatedString> obj;
rs = readRecordHeader(stream, rh);
ds = readTranslatedObjects(stream, codec, obj);
rs = stream.readRecordHeader(rh);
ds = stream.readTranslatedObjects(obj);
if (!obj.isEmpty())
waypoint.setDescription(obj.first().str());
@ -270,24 +285,23 @@ static quint32 readDescription(QDataStream &stream, QTextCodec *codec,
return rs + rh.size;
}
static quint32 readNotes(QDataStream &stream, QTextCodec *codec,
Waypoint &waypoint)
static quint32 readNotes(DataStream &stream, Waypoint &waypoint)
{
RecordHeader rh;
quint8 rs, s1;
quint32 ds = 1;
rs = readRecordHeader(stream, rh);
rs = stream.readRecordHeader(rh);
stream >> s1;
if (s1 & 0x1) {
QList<TranslatedString> obj;
ds += readTranslatedObjects(stream, codec, obj);
ds += stream.readTranslatedObjects(obj);
if (!obj.isEmpty())
waypoint.setComment(obj.first().str());
}
if (s1 & 0x2) {
QString str;
ds += readString(stream, codec, str);
ds += stream.readString(str);
if (!str.isEmpty())
waypoint.setComment(str);
}
@ -298,8 +312,7 @@ static quint32 readNotes(QDataStream &stream, QTextCodec *codec,
return rs + rh.size;
}
static quint32 readContact(QDataStream &stream, QTextCodec *codec,
Waypoint &waypoint)
static quint32 readContact(DataStream &stream, Waypoint &waypoint)
{
RecordHeader rh;
quint8 rs;
@ -308,25 +321,25 @@ static quint32 readContact(QDataStream &stream, QTextCodec *codec,
QString str;
QList<TranslatedString> obj;
rs = readRecordHeader(stream, rh);
rs = stream.readRecordHeader(rh);
stream >> flags;
if (flags & 0x1) // phone
ds += readString(stream, codec, str);
ds += stream.readString(str);
if (flags & 0x2) // phone2
ds += readString(stream, codec, str);
ds += stream.readString(str);
if (flags & 0x4) // fax
ds += readString(stream, codec, str);
ds += stream.readString(str);
if (flags & 0x8) // mail
ds += readString(stream, codec, str);
ds += stream.readString(str);
if (flags & 0x10) { // web
ds += readString(stream, codec, str);
ds += stream.readString(str);
QUrl url(str);
waypoint.addLink(Link(url.scheme().isEmpty()
? "http://" + str : str, str));
}
if (flags & 0x20) // unknown
ds += readTranslatedObjects(stream, codec, obj);
ds += stream.readTranslatedObjects(obj);
if (ds != rh.size)
stream.setStatus(QDataStream::ReadCorruptData);
@ -334,8 +347,7 @@ static quint32 readContact(QDataStream &stream, QTextCodec *codec,
return rs + rh.size;
}
static quint32 readAddress(QDataStream &stream, QTextCodec *codec,
Waypoint &waypoint)
static quint32 readAddress(DataStream &stream, Waypoint &waypoint)
{
RecordHeader rh;
quint8 rs;
@ -345,35 +357,35 @@ static quint32 readAddress(QDataStream &stream, QTextCodec *codec,
QString str;
Address addr;
rs = readRecordHeader(stream, rh);
rs = stream.readRecordHeader(rh);
stream >> flags;
if (flags & 0x1) {
ds += readTranslatedObjects(stream, codec, obj);
ds += stream.readTranslatedObjects(obj);
if (!obj.isEmpty())
addr.setCity(obj.first().str());
}
if (flags & 0x2) {
ds += readTranslatedObjects(stream, codec, obj);
ds += stream.readTranslatedObjects(obj);
if (!obj.isEmpty())
addr.setCountry(obj.first().str());
}
if (flags & 0x4) {
ds += readTranslatedObjects(stream, codec, obj);
ds += stream.readTranslatedObjects(obj);
if (!obj.isEmpty())
addr.setState(obj.first().str());
}
if (flags & 0x8) {
ds += readString(stream, codec, str);
ds += stream.readString(str);
addr.setPostalCode(str);
}
if (flags & 0x10) {
ds += readTranslatedObjects(stream, codec, obj);
ds += stream.readTranslatedObjects(obj);
if (!obj.isEmpty())
addr.setStreet(obj.first().str());
}
if (flags & 0x20) // unknown
ds += readString(stream, codec, str);
ds += stream.readString(str);
waypoint.setAddress(addr);
@ -383,21 +395,20 @@ static quint32 readAddress(QDataStream &stream, QTextCodec *codec,
return rs + rh.size;
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
static const QTemporaryDir &tempDir()
{
static QTemporaryDir dir;
return dir;
}
static quint32 readImageInfo(QDataStream &stream, Waypoint &waypoint,
static quint32 readImageInfo(DataStream &stream, Waypoint &waypoint,
const QString &fileName, int &imgId)
{
RecordHeader rh;
quint8 rs, s1;
quint32 size;
rs = readRecordHeader(stream, rh);
rs = stream.readRecordHeader(rh);
stream >> s1 >> size;
QByteArray ba;
@ -424,7 +435,6 @@ static quint32 readImageInfo(QDataStream &stream, Waypoint &waypoint,
return rs + rh.size;
}
#endif // QT_VERSION >= 5
static int speed(quint8 flags)
{
@ -450,7 +460,7 @@ static int speed(quint8 flags)
}
}
static quint32 readCamera(QDataStream &stream, QVector<Waypoint> &waypoints,
static quint32 readCamera(DataStream &stream, QVector<Waypoint> &waypoints,
QList<Area> &polygons)
{
RecordHeader rh;
@ -459,18 +469,18 @@ static quint32 readCamera(QDataStream &stream, QVector<Waypoint> &waypoints,
quint32 ds = 15;
rs = readRecordHeader(stream, rh);
top = readInt24(stream);
right = readInt24(stream);
bottom = readInt24(stream);
left = readInt24(stream);
rs = stream.readRecordHeader(rh);
top = stream.readInt24();
right = stream.readInt24();
bottom = stream.readInt24();
left = stream.readInt24();
stream >> flags >> type >> s7;
if (s7) {
quint32 skip = s7 + 2 + s7/4;
stream.skipRawData(skip);
lat = readInt24(stream);
lon = readInt24(stream);
lat = stream.readInt24();
lon = stream.readInt24();
ds += skip + 6;
} else {
quint8 s8;
@ -478,22 +488,15 @@ static quint32 readCamera(QDataStream &stream, QVector<Waypoint> &waypoints,
stream >> s8;
quint32 skip = 3 + s8 + s8/4;
stream.skipRawData(skip);
lat = readInt24(stream);
lon = readInt24(stream);
lat = stream.readInt24();
lon = stream.readInt24();
ds += skip + 16;
}
waypoints.append(Coordinates(toWGS24(lon), toWGS24(lat)));
Area area;
Polygon polygon;
QVector<Coordinates> v(4);
v[0] = Coordinates(toWGS24(left), toWGS24(top));
v[1] = Coordinates(toWGS24(right), toWGS24(top));
v[2] = Coordinates(toWGS24(right), toWGS24(bottom));
v[3] = Coordinates(toWGS24(left), toWGS24(bottom));
polygon.append(v);
area.append(polygon);
Area area(RectC(Coordinates(toWGS24(left), toWGS24(top)),
Coordinates(toWGS24(right), toWGS24(bottom))));
switch (type) {
case 8:
@ -520,8 +523,8 @@ static quint32 readCamera(QDataStream &stream, QVector<Waypoint> &waypoints,
return rs + rh.size;
}
static quint32 readPOI(QDataStream &stream, QTextCodec *codec,
QVector<Waypoint> &waypoints, const QString &fileName, int &imgId)
static quint32 readPOI(DataStream &stream, QVector<Waypoint> &waypoints,
const QString &fileName, int &imgId)
{
RecordHeader rh;
quint8 rs;
@ -530,37 +533,35 @@ static quint32 readPOI(QDataStream &stream, QTextCodec *codec,
quint16 s3;
QList<TranslatedString> obj;
rs = readRecordHeader(stream, rh);
rs = stream.readRecordHeader(rh);
stream >> lat >> lon >> s3;
stream.skipRawData(s3);
ds = 10 + s3;
ds += readTranslatedObjects(stream, codec, obj);
ds += stream.readTranslatedObjects(obj);
waypoints.append(Waypoint(Coordinates(toWGS32(lon), toWGS32(lat))));
if (!obj.isEmpty())
waypoints.last().setName(obj.first().str());
while (stream.status() == QDataStream::Ok && ds < rh.size) {
switch(nextHeaderType(stream)) {
switch(stream.nextHeaderType()) {
case 10:
ds += readDescription(stream, codec, waypoints.last());
ds += readDescription(stream, waypoints.last());
break;
case 11:
ds += readAddress(stream, codec, waypoints.last());
ds += readAddress(stream, waypoints.last());
break;
case 12:
ds += readContact(stream, codec, waypoints.last());
ds += readContact(stream, waypoints.last());
break;
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
case 13:
ds += readImageInfo(stream, waypoints.last(), fileName, imgId);
break;
#endif // QT_VERSION >= 5
case 14:
ds += readNotes(stream, codec, waypoints.last());
ds += readNotes(stream, waypoints.last());
break;
default:
ds += skipRecord(stream);
ds += stream.skipRecord();
}
}
@ -570,9 +571,8 @@ static quint32 readPOI(QDataStream &stream, QTextCodec *codec,
return rs + rh.size;
}
static quint32 readSpatialIndex(QDataStream &stream, QTextCodec *codec,
QVector<Waypoint> &waypoints, QList<Area> &polygons, const QString &fileName,
int &imgId)
static quint32 readSpatialIndex(DataStream &stream, QVector<Waypoint> &waypoints,
QList<Area> &polygons, const QString &fileName, int &imgId)
{
RecordHeader rh;
quint32 ds, s5;
@ -580,25 +580,25 @@ static quint32 readSpatialIndex(QDataStream &stream, QTextCodec *codec,
quint16 s6;
quint8 rs;
rs = readRecordHeader(stream, rh);
rs = stream.readRecordHeader(rh);
stream >> top >> right >> bottom >> left >> s5 >> s6;
stream.skipRawData(s6);
ds = 22 + s6;
if (rh.flags & 0x8) {
while (stream.status() == QDataStream::Ok && ds < rh.size) {
switch(nextHeaderType(stream)) {
switch(stream.nextHeaderType()) {
case 2:
ds += readPOI(stream, codec, waypoints, fileName, imgId);
ds += readPOI(stream, waypoints, fileName, imgId);
break;
case 8:
ds += readSpatialIndex(stream, codec, waypoints, polygons,
ds += readSpatialIndex(stream, waypoints, polygons,
fileName, imgId);
break;
case 19:
ds += readCamera(stream, waypoints, polygons);
break;
default:
ds += skipRecord(stream);
ds += stream.skipRecord();
}
}
}
@ -609,24 +609,23 @@ static quint32 readSpatialIndex(QDataStream &stream, QTextCodec *codec,
return rs + rh.size;
}
static void readPOIDatabase(QDataStream &stream, QTextCodec *codec,
QVector<Waypoint> &waypoints, QList<Area> &polygons, const QString &fileName,
int &imgId)
static void readPOIDatabase(DataStream &stream, QVector<Waypoint> &waypoints,
QList<Area> &polygons, const QString &fileName, int &imgId)
{
RecordHeader rh;
QList<TranslatedString> obj;
quint32 ds;
readRecordHeader(stream, rh);
ds = readTranslatedObjects(stream, codec, obj);
ds += readSpatialIndex(stream, codec, waypoints, polygons, fileName, imgId);
stream.readRecordHeader(rh);
ds = stream.readTranslatedObjects(obj);
ds += readSpatialIndex(stream, waypoints, polygons, fileName, imgId);
if (rh.flags & 0x8) {
while (stream.status() == QDataStream::Ok && ds < rh.size) {
switch(nextHeaderType(stream)) {
switch(stream.nextHeaderType()) {
case 5: // symbol
case 7: // category
default:
ds += skipRecord(stream);
ds += stream.skipRecord();
}
}
}
@ -635,26 +634,26 @@ static void readPOIDatabase(QDataStream &stream, QTextCodec *codec,
stream.setStatus(QDataStream::ReadCorruptData);
}
bool GPIParser::readData(QDataStream &stream, QTextCodec *codec,
QVector<Waypoint> &waypoints, QList<Area> &polygons, const QString &fileName)
bool GPIParser::readData(DataStream &stream, QVector<Waypoint> &waypoints,
QList<Area> &polygons, const QString &fileName)
{
int imgId = 0;
while (stream.status() == QDataStream::Ok) {
switch (nextHeaderType(stream)) {
switch (stream.nextHeaderType()) {
case 0x09: // POI database
readPOIDatabase(stream, codec, waypoints, polygons, fileName,
readPOIDatabase(stream, waypoints, polygons, fileName,
imgId);
break;
case 0xffff: // EOF
skipRecord(stream);
stream.skipRecord();
if (stream.status() == QDataStream::Ok)
return true;
break;
case 0x16: // route
case 0x15: // info header
default:
skipRecord(stream);
stream.skipRecord();
}
}
@ -663,7 +662,7 @@ bool GPIParser::readData(QDataStream &stream, QTextCodec *codec,
return false;
}
bool GPIParser::readGPIHeader(QDataStream &stream, QTextCodec **codec)
bool GPIParser::readGPIHeader(DataStream &stream)
{
RecordHeader rh;
char m1[6], m2[2];
@ -671,22 +670,16 @@ bool GPIParser::readGPIHeader(QDataStream &stream, QTextCodec **codec)
quint8 s2, s3;
quint32 ds;
readRecordHeader(stream, rh);
stream.readRecordHeader(rh);
stream.readRawData(m1, sizeof(m1));
stream.readRawData(m2, sizeof(m2));
stream >> codepage >> s2 >> s3;
ds = sizeof(m1) + sizeof(m2) + 4;
if (codepage == 65001)
*codec = QTextCodec::codecForName("UTF-8");
else if (codepage == 0)
*codec = 0;
else
*codec = QTextCodec::codecForName(QString("CP%1").arg(codepage)
.toLatin1());
stream.setCodepage(codepage);
if (s2 & 0x10)
ds += readFileDataRecord(stream, *codec);
ds += readFileDataRecord(stream);
if (stream.status() != QDataStream::Ok || ds != rh.size) {
_errorString = "Invalid GPI header";
@ -695,7 +688,7 @@ bool GPIParser::readGPIHeader(QDataStream &stream, QTextCodec **codec)
return true;
}
bool GPIParser::readFileHeader(QDataStream &stream, quint32 &ebs)
bool GPIParser::readFileHeader(DataStream &stream, quint32 &ebs)
{
RecordHeader rh;
quint32 ds, s7;
@ -703,7 +696,7 @@ bool GPIParser::readFileHeader(QDataStream &stream, quint32 &ebs)
quint8 s5, s6, s8, s9;
char magic[6];
readRecordHeader(stream, rh);
stream.readRecordHeader(rh);
stream.readRawData(magic, sizeof(magic));
if (memcmp(magic, "GRMREC", sizeof(magic))) {
_errorString = "Not a GPI file";
@ -729,21 +722,19 @@ bool GPIParser::parse(QFile *file, QList<TrackData> &tracks,
{
Q_UNUSED(tracks);
Q_UNUSED(routes);
QDataStream stream(file);
QTextCodec *codec = 0;
DataStream stream(file);
quint32 ebs;
stream.setByteOrder(QDataStream::LittleEndian);
if (!readFileHeader(stream, ebs) || !readGPIHeader(stream, &codec))
if (!readFileHeader(stream, ebs) || !readGPIHeader(stream))
return false;
if (ebs) {
CryptDevice dev(stream.device(), 0xf870b5, ebs);
QDataStream cryptStream(&dev);
DataStream cryptStream(&dev);
cryptStream.setByteOrder(QDataStream::LittleEndian);
return readData(cryptStream, codec, waypoints, polygons,
file->fileName());
return readData(cryptStream, waypoints, polygons, file->fileName());
} else
return readData(stream, codec, waypoints, polygons, file->fileName());
return readData(stream, waypoints, polygons, file->fileName());
}

View File

@ -3,8 +3,7 @@
#include "parser.h"
class QDataStream;
class QTextCodec;
class DataStream;
class GPIParser : public Parser
{
@ -15,11 +14,10 @@ public:
int errorLine() const {return 0;}
private:
bool readFileHeader(QDataStream &stream, quint32 &ebs);
bool readGPIHeader(QDataStream &stream, QTextCodec **codec);
bool readData(QDataStream &stream, QTextCodec *codec,
QVector<Waypoint> &waypoints, QList<Area> &polygons,
const QString &fileName);
bool readFileHeader(DataStream &stream, quint32 &ebs);
bool readGPIHeader(DataStream &stream);
bool readData(DataStream &stream, QVector<Waypoint> &waypoints,
QList<Area> &polygons, const QString &fileName);
QString _errorString;
};

View File

@ -41,23 +41,14 @@ Link GPXParser::link()
Coordinates GPXParser::coordinates()
{
bool res;
qreal lon, lat;
const QXmlStreamAttributes &attr = _reader.attributes();
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
lon = attr.value("lon").toString().toDouble(&res);
#else // QT_VERSION < 5
lon = attr.value("lon").toDouble(&res);
#endif // QT_VERSION < 5
qreal lon = attr.value("lon").toDouble(&res);
if (!res || (lon < -180.0 || lon > 180.0)) {
_reader.raiseError("Invalid longitude");
return Coordinates();
}
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
lat = attr.value("lat").toString().toDouble(&res);
#else // QT_VERSION < 5
lat = attr.value("lat").toDouble(&res);
#endif // QT_VERSION < 5
qreal lat = attr.value("lat").toDouble(&res);
if (!res || (lat < -90.0 || lat > 90.0)) {
_reader.raiseError("Invalid latitude");
return Coordinates();

View File

@ -44,11 +44,7 @@ bool KMLParser::coord(Trackpoint &trackpoint)
if (c > 2)
return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val[c] = QString(vp, cp - vp).toDouble(&res);
#else // QT_VERSION < 5
val[c] = QStringRef(&data, vp - sp, cp - vp).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
return false;
@ -90,11 +86,7 @@ bool KMLParser::pointCoordinates(Waypoint &waypoint)
if (c > 1)
return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val[c] = QString(vp, cp - vp).toDouble(&res);
#else // QT_VERSION < 5
val[c] = QStringRef(&data, vp - sp, cp - vp).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
return false;
@ -104,11 +96,7 @@ bool KMLParser::pointCoordinates(Waypoint &waypoint)
if (c < 1)
return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val[c] = QString(vp, cp - vp).toDouble(&res);
#else // QT_VERSION < 5
val[c] = QStringRef(&data, vp - sp, cp - vp).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
return false;
@ -148,11 +136,7 @@ bool KMLParser::lineCoordinates(SegmentData &segment)
if (c > 1)
return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val[c] = QString(vp, cp - vp).toDouble(&res);
#else // QT_VERSION < 5
val[c] = QStringRef(&data, vp - sp, cp - vp).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
return false;
@ -162,11 +146,7 @@ bool KMLParser::lineCoordinates(SegmentData &segment)
if (c < 1 || c > 2)
return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val[c] = QString(vp, cp - vp).toDouble(&res);
#else // QT_VERSION < 5
val[c] = QStringRef(&data, vp - sp, cp - vp).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
return false;
@ -207,11 +187,7 @@ bool KMLParser::polygonCoordinates(QVector<Coordinates> &points)
if (c > 1)
return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val[c] = QString(vp, cp - vp).toDouble(&res);
#else // QT_VERSION < 5
val[c] = QStringRef(&data, vp - sp, cp - vp).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
return false;
@ -221,11 +197,7 @@ bool KMLParser::polygonCoordinates(QVector<Coordinates> &points)
if (c < 1 || c > 2)
return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val[c] = QString(vp, cp - vp).toDouble(&res);
#else // QT_VERSION < 5
val[c] = QStringRef(&data, vp - sp, cp - vp).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
return false;
@ -417,7 +389,7 @@ void KMLParser::schemaData(SegmentData &segment, int start)
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("SimpleArrayData")) {
QXmlStreamAttributes attr = _reader.attributes();
QStringRef name = attr.value("name");
QString name(attr.value("name").toString());
if (name == QLatin1String("Heartrate"))
heartRate(segment, start);

View File

@ -3,23 +3,14 @@
Coordinates LOCParser::coordinates()
{
bool res;
qreal lon, lat;
const QXmlStreamAttributes &attr = _reader.attributes();
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
lon = attr.value("lon").toString().toDouble(&res);
#else // QT_VERSION < 5
lon = attr.value("lon").toDouble(&res);
#endif // QT_VERSION < 5
qreal lon = attr.value("lon").toDouble(&res);
if (!res || (lon < -180.0 || lon > 180.0)) {
_reader.raiseError("Invalid longitude");
return Coordinates();
}
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
lat = attr.value("lat").toString().toDouble(&res);
#else // QT_VERSION < 5
lat = attr.value("lat").toDouble(&res);
#endif // QT_VERSION < 5
qreal lat = attr.value("lat").toDouble(&res);
if (!res || (lat < -90.0 || lat > 90.0)) {
_reader.raiseError("Invalid latitude");
return Coordinates();

View File

@ -80,12 +80,25 @@ void POI::search(const RectC &rect, QSet<int> &set) const
{
qreal min[2], max[2];
min[0] = rect.topLeft().lon();
min[1] = rect.bottomRight().lat();
max[0] = rect.bottomRight().lon();
max[1] = rect.topLeft().lat();
if (rect.left() > rect.right()) {
min[0] = rect.topLeft().lon();
min[1] = rect.bottomRight().lat();
max[0] = 180.0;
max[1] = rect.topLeft().lat();
_tree.Search(min, max, cb, &set);
_tree.Search(min, max, cb, &set);
min[0] = -180.0;
min[1] = rect.bottomRight().lat();
max[0] = rect.bottomRight().lon();
max[1] = rect.topLeft().lat();
_tree.Search(min, max, cb, &set);
} else {
min[0] = rect.topLeft().lon();
min[1] = rect.bottomRight().lat();
max[0] = rect.bottomRight().lon();
max[1] = rect.topLeft().lat();
_tree.Search(min, max, cb, &set);
}
}
QList<Waypoint> POI::points(const Path &path) const
@ -130,16 +143,10 @@ QList<Waypoint> POI::points(const Waypoint &point) const
{
QList<Waypoint> ret;
QSet<int> set;
qreal min[2], max[2];
QSet<int>::const_iterator it;
RectC br(point.coordinates(), _radius);
min[0] = br.topLeft().lon();
min[1] = br.bottomRight().lat();
max[0] = br.bottomRight().lon();
max[1] = br.topLeft().lat();
_tree.Search(min, max, cb, &set);
search(br, set);
for (it = set.constBegin(); it != set.constEnd(); ++it)
ret.append(_data.at(*it));
@ -147,22 +154,15 @@ QList<Waypoint> POI::points(const Waypoint &point) const
return ret;
}
QList<Waypoint> POI::points(const Area &area) const
QList<Waypoint> POI::points(const RectC &rect) const
{
QList<Waypoint> ret;
qreal min[2], max[2];
QSet<int> set;
QSet<int>::const_iterator it;
RectC br(area.boundingRect());
double offset = rad2deg(_radius / WGS84_RADIUS);
min[0] = br.topLeft().lon() - offset;
min[1] = br.bottomRight().lat() - offset;
max[0] = br.bottomRight().lon() + offset;
max[1] = br.topLeft().lat() + offset;
_tree.Search(min, max, cb, &set);
RectC br(rect.adjusted(-offset, offset, offset, -offset));
search(br, set);
for (it = set.constBegin(); it != set.constEnd(); ++it)
ret.append(_data.at(*it));

View File

@ -9,7 +9,6 @@
#include "waypoint.h"
class Path;
class Area;
class RectC;
class POI : public QObject
@ -29,7 +28,7 @@ public:
QList<Waypoint> points(const Path &path) const;
QList<Waypoint> points(const Waypoint &point) const;
QList<Waypoint> points(const Area &area) const;
QList<Waypoint> points(const RectC &rect) const;
const QStringList &files() const {return _files;}
void enableFile(const QString &fileName, bool enable);

View File

@ -15,11 +15,7 @@ bool SLFParser::data(const QXmlStreamAttributes &attr, const char *name,
if (!attr.hasAttribute(name))
return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val = attr.value(name).toString().toDouble(&res);
#else // QT_VERSION < 5
val = attr.value(name).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
_reader.raiseError("Invalid " + QString(name));

View File

@ -31,7 +31,7 @@ static qreal avg(const QVector<qreal> &v)
static qreal median(QVector<qreal> &v)
{
qSort(v.begin(), v.end());
std::sort(v.begin(), v.end());
return v.at(v.size() / 2);
}

View File

@ -1,18 +1,16 @@
#include "common/config.h"
#ifdef ENABLE_TIMEZONES
#include "GUI/timezoneinfo.h"
#endif // ENABLE_TIMEZONES
#include "GUI/app.h"
#include "GUI/timezoneinfo.h"
int main(int argc, char *argv[])
{
#ifdef ENABLE_HIDPI
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif // ENABLE_HIDPI
#ifdef ENABLE_TIMEZONES
qRegisterMetaTypeStreamOperators<TimeZoneInfo>("TimeZoneInfo");
#endif // ENABLE_TIMEZONES
#else // QT6
qRegisterMetaType<TimeZoneInfo>("TimeZoneInfo");
#endif // QT6
App app(argc, argv);
return app.run();

View File

@ -1,10 +1,6 @@
#include <QPainter>
#include <QImage>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QtCore/qmath.h>
#else // QT5
#include <QtMath>
#endif // QT5
#include "bitmapline.h"

Some files were not shown because too many files have changed in this diff Show More