Compare commits
101 Commits
Author | SHA1 | Date | |
---|---|---|---|
c0e2597dcc | |||
ff0affc8ec | |||
e38772c9b6 | |||
713876d7a4 | |||
d0e0ea32ab | |||
2529ea9932 | |||
025313edb0 | |||
86dbc58e8e | |||
3117127a3e | |||
76c2da9b50 | |||
39ab3d7a85 | |||
53b34ff24c | |||
00a9adce1e | |||
c4e0ff6435 | |||
40616fb868 | |||
c062a62014 | |||
1000dd3fc1 | |||
50374fc222 | |||
2cc97f8e36 | |||
44aed958a5 | |||
cb2dfd9155 | |||
7d98a797f5 | |||
b17d7eac5f | |||
f24f2abb4d | |||
d9c66c11e0 | |||
1ed2685802 | |||
0483cdb5db | |||
e4c4961e7a | |||
4fbe7f7571 | |||
87c82ec75f | |||
2655091b95 | |||
9b5b422aef | |||
c6e7393df7 | |||
a42280dec3 | |||
4f1c2a7ea3 | |||
93377964d8 | |||
421ab19e7a | |||
01e6053400 | |||
f55e5d639d | |||
306fefe8db | |||
cedaeb1185 | |||
42a39f3eb3 | |||
23400a8c3a | |||
e6fd92266d | |||
321357b74d | |||
897e075505 | |||
932aadee5f | |||
32bf7f0dfa | |||
b539eb8ed8 | |||
741e95cb63 | |||
c161e35379 | |||
d09b937e10 | |||
a1d7689879 | |||
7ff7303eab | |||
5789982024 | |||
0861b0a0b4 | |||
0e735d5726 | |||
308ca9c702 | |||
b1ea38b6ac | |||
428fb934c4 | |||
c4066ef66b | |||
f5523b68a9 | |||
f692e38711 | |||
2d43768f81 | |||
bbfd0d8735 | |||
5dd8dd524a | |||
04c989d3b7 | |||
42f35f95a8 | |||
7861d8f6d8 | |||
9dc9cf9991 | |||
355ddda1e6 | |||
901a44d1e4 | |||
5424b64679 | |||
e4d68de963 | |||
ace03b2003 | |||
97029233e9 | |||
c9a4506cbb | |||
851c64c3ec | |||
7fdc182687 | |||
3e0fb14a75 | |||
ae0604793e | |||
0432665aeb | |||
b7b6a3fe53 | |||
1e3132c9b3 | |||
b4925843c8 | |||
fa55c6d93a | |||
682da37ea6 | |||
a4d91ef17a | |||
7922840b4f | |||
9119ebd2cf | |||
1589fe27e9 | |||
a2e1937e32 | |||
35184abbe7 | |||
9253703a69 | |||
edb3395d95 | |||
39574704b0 | |||
5298110a0e | |||
a1a96e1066 | |||
1c2e1fd5c5 | |||
ae6f91a762 | |||
9a3d81e8de |
@ -1,4 +1,4 @@
|
||||
version: 9.12.{build}
|
||||
version: 10.2.{build}
|
||||
|
||||
configuration:
|
||||
- Release
|
||||
|
24
.github/workflows/linux.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
name: Linux
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: GPXSee
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install qtbase5-dev qtbase5-private-dev qtbase5-dev-tools qt5-qmake qttools5-dev-tools libqt5opengl5-dev qtpositioning5-dev
|
||||
- name: Create localization
|
||||
run: lrelease gpxsee.pro
|
||||
- name: Configure build
|
||||
run: qmake gpxsee.pro
|
||||
- name: Build project
|
||||
run: make -j2
|
@ -4,8 +4,8 @@ GPS log file formats.
|
||||
|
||||
## Features
|
||||
* Opens GPX, TCX, FIT, KML, NMEA, IGC, CUP, SIGMA SLF, Suunto SML, LOC, GeoJSON,
|
||||
OziExplorer (PLT, RTE, WPT), Garmin GPI&CSV, TomTom OV2&ITN, ONmove OMD/GHP and
|
||||
geotagged JPEG files.
|
||||
OziExplorer (PLT, RTE, WPT), Garmin GPI&CSV, TomTom OV2&ITN, ONmove OMD/GHP,
|
||||
TwoNav (TRK, RTE, WPT) and geotagged JPEG files.
|
||||
* User-definable online maps (OpenStreetMap/Google tiles, WMTS, WMS, TMS,
|
||||
QuadTiles).
|
||||
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
|
||||
@ -20,6 +20,7 @@ GPS log file formats.
|
||||
* Print/export to PDF/PNG.
|
||||
* Full-screen mode.
|
||||
* HiDPI/Retina displays & maps support.
|
||||
* Real-time GPS position.
|
||||
* Native GUI for Windows, Mac OS X and Linux.
|
||||
|
||||

|
||||
|
16
gpxsee.pro
@ -3,7 +3,7 @@ unix:!macx {
|
||||
} else {
|
||||
TARGET = GPXSee
|
||||
}
|
||||
VERSION = 9.12
|
||||
VERSION = 10.2
|
||||
|
||||
QT += core \
|
||||
gui \
|
||||
@ -12,7 +12,8 @@ QT += core \
|
||||
sql \
|
||||
concurrent \
|
||||
widgets \
|
||||
printsupport
|
||||
printsupport \
|
||||
positioning
|
||||
greaterThan(QT_MAJOR_VERSION, 5) {
|
||||
QT += openglwidgets \
|
||||
core5compat
|
||||
@ -21,6 +22,9 @@ greaterThan(QT_MAJOR_VERSION, 5) {
|
||||
CONFIG += object_parallel_to_source
|
||||
INCLUDEPATH += ./src
|
||||
HEADERS += src/common/config.h \
|
||||
src/GUI/crosshairitem.h \
|
||||
src/GUI/motioninfoitem.h \
|
||||
src/GUI/pluginparameters.h \
|
||||
src/common/garmin.h \
|
||||
src/common/coordinates.h \
|
||||
src/common/range.h \
|
||||
@ -108,6 +112,7 @@ HEADERS += src/common/config.h \
|
||||
src/GUI/pngexportdialog.h \
|
||||
src/GUI/timezoneinfo.h \
|
||||
src/GUI/passwordedit.h \
|
||||
src/data/twonavparser.h \
|
||||
src/map/proj/polyconic.h \
|
||||
src/map/proj/webmercator.h \
|
||||
src/map/proj/transversemercator.h \
|
||||
@ -238,6 +243,9 @@ HEADERS += src/common/config.h \
|
||||
src/data/geojsonparser.h
|
||||
|
||||
SOURCES += src/main.cpp \
|
||||
src/GUI/crosshairitem.cpp \
|
||||
src/GUI/motioninfoitem.cpp \
|
||||
src/GUI/pluginparameters.cpp \
|
||||
src/common/coordinates.cpp \
|
||||
src/common/rectc.cpp \
|
||||
src/common/range.cpp \
|
||||
@ -305,6 +313,7 @@ SOURCES += src/main.cpp \
|
||||
src/GUI/pngexportdialog.cpp \
|
||||
src/GUI/projectioncombobox.cpp \
|
||||
src/GUI/passwordedit.cpp \
|
||||
src/data/twonavparser.cpp \
|
||||
src/map/proj/polyconic.cpp \
|
||||
src/map/proj/webmercator.cpp \
|
||||
src/map/proj/transversemercator.cpp \
|
||||
@ -488,7 +497,8 @@ win32 {
|
||||
icons/formats/wld.ico \
|
||||
icons/formats/omd.ico \
|
||||
icons/formats/ghp.ico \
|
||||
icons/formats/qct.ico
|
||||
icons/formats/qct.ico \
|
||||
icons/formats/trk.ico
|
||||
DEFINES += _USE_MATH_DEFINES \
|
||||
NOGDI
|
||||
}
|
||||
|
@ -49,6 +49,10 @@
|
||||
<file alias="document-decrypt@2x.png">icons/GUI/document-decrypt.png</file>
|
||||
<file alias="document-encrypt.png">icons/GUI/document-encrypt.png</file>
|
||||
<file alias="document-encrypt@2x.png">icons/GUI/document-encrypt.png</file>
|
||||
<file alias="transform-move.png">icons/GUI/transform-move.png</file>
|
||||
<file alias="transform-move@2x.png">icons/GUI/transform-move@2x.png</file>
|
||||
<file alias="transform-move_32.png">icons/GUI/transform-move_32.png</file>
|
||||
<file alias="transform-move_32@2x.png">icons/GUI/transform-move_32@2x.png</file>
|
||||
</qresource>
|
||||
|
||||
<!-- IMG map style -->
|
||||
|
BIN
icons/GUI/transform-move.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/GUI/transform-move@2x.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
icons/GUI/transform-move_32.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
icons/GUI/transform-move_32@2x.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
@ -28,3 +28,4 @@ wld:#c74c8f
|
||||
omd:#ed09cb
|
||||
ghp:#ed09cb
|
||||
qct:#370642
|
||||
trk:#cccccc
|
||||
|
BIN
icons/formats/trk.icns
Normal file
BIN
icons/formats/trk.ico
Normal file
After Width: | Height: | Size: 298 KiB |
BIN
icons/symbols/Flag, Blue.png
Normal file
After Width: | Height: | Size: 747 B |
BIN
icons/symbols/Flag, Green.png
Normal file
After Width: | Height: | Size: 827 B |
BIN
icons/symbols/Flag, Red.png
Normal file
After Width: | Height: | Size: 724 B |
BIN
icons/symbols/Flag.png
Normal file
After Width: | Height: | Size: 724 B |
Before Width: | Height: | Size: 827 B After Width: | Height: | Size: 747 B |
2365
lang/gpxsee_ko.ts
Normal file
@ -594,6 +594,22 @@
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>trk</string>
|
||||
</array>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>application/vnd.twonav.trk</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>icons/trk.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>TwoNav Track File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
@ -1407,6 +1423,29 @@
|
||||
<string>application/vnd.memory-map.qct</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.twonav.trk</string>
|
||||
<key>UTTypeReferenceURL</key>
|
||||
<string>https://github.com/GPSBabel/gpsbabel/blob/master/deprecated/compegps.cc</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>TwoNav Track File</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>icons/trk.icns</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>trk</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<string>application/vnd.twonav.trk</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
|
@ -14,8 +14,8 @@
|
||||
<ul>
|
||||
<li>Opens GPX, TCX, FIT, KML, IGC, NMEA, SIGMA SLF, Suunto SML, LOC,
|
||||
OziExplorer (PLT, WPT, RTE), GeoJSON, SeeYou CUP,
|
||||
Garmin GPI & CSV, TomTom OV2 & ITN, ONmove OMD/GHP
|
||||
and geotagged JPEG files.</li>
|
||||
Garmin GPI & CSV, TomTom OV2 & ITN, ONmove OMD/GHP,
|
||||
TwoNav (TRK, RTE, WPT) and geotagged JPEG files.</li>
|
||||
<li>User-definable online maps (OpenStreetMap/Google tiles, WMTS,
|
||||
WMS, TMS, QuadTiles).</li>
|
||||
<li>Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
|
||||
@ -30,6 +30,7 @@
|
||||
<li>Print/export to PDF & PNG.</li>
|
||||
<li>Full-screen mode.</li>
|
||||
<li>HiDPI/Retina displays & maps support.</li>
|
||||
<li>Real-time GPS position.</li>
|
||||
</ul>
|
||||
</description>
|
||||
|
||||
@ -98,5 +99,8 @@
|
||||
<mimetype>application/vnd.onmove.omd</mimetype>
|
||||
<mimetype>application/vnd.onmove.ghp</mimetype>
|
||||
<mimetype>application/vnd.memory-map.qct</mimetype>
|
||||
<mimetype>application/vnd.twonav.trk</mimetype>
|
||||
<mimetype>application/vnd.twonav.rte</mimetype>
|
||||
<mimetype>application/vnd.twonav.wpt</mimetype>
|
||||
</mimetypes>
|
||||
</component>
|
||||
|
@ -15,4 +15,4 @@ Icon=gpxsee
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Graphics;Viewer;Education;Geography;Maps;Sports;Qt
|
||||
MimeType=application/gpx+xml;application/vnd.garmin.tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/vnd.groundspeak.loc+xml;application/vnd.sigma.slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/vnd.suunto.sml+xml;image/jpeg;text/csv;application/vnd.garmin.img;application/vnd.garmin.jnx;application/vnd.garmin.gmap+xml;image/vnd.maptech.kap;application/vnd.oziexplorer.map;application/vnd.mapbox.mbtiles;application/vnd.twonav.rmap;application/vnd.trekbuddy.tba;application/vnd.gpxsee.map+xml;application/x-tar;image/tiff;application/vnd.google-earth.kmz;application/vnd.alpinequest.aqm;application/vnd.rmaps.sqlite;application/vnd.mapsforge.map;application/vnd.tomtom.ov2;application/vnd.tomtom.itn;application/vnd.esri.wld
|
||||
MimeType=application/gpx+xml;application/vnd.garmin.tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/vnd.groundspeak.loc+xml;application/vnd.sigma.slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/vnd.suunto.sml+xml;image/jpeg;text/csv;application/vnd.garmin.img;application/vnd.garmin.jnx;application/vnd.garmin.gmap+xml;image/vnd.maptech.kap;application/vnd.oziexplorer.map;application/vnd.mapbox.mbtiles;application/vnd.twonav.rmap;application/vnd.trekbuddy.tba;application/vnd.gpxsee.map+xml;application/x-tar;image/tiff;application/vnd.google-earth.kmz;application/vnd.alpinequest.aqm;application/vnd.rmaps.sqlite;application/vnd.mapsforge.map;application/vnd.tomtom.ov2;application/vnd.tomtom.itn;application/vnd.esri.wld;application/vnd.onmove.omd;application/vnd.onmove.ghp;application/vnd.memory-map.qct;application/vnd.twonav.trk;application/vnd.twonav.rte;application/vnd.twonav.wpt
|
||||
|
@ -156,6 +156,28 @@
|
||||
<glob pattern="*.ghp"/>
|
||||
</mime-type>
|
||||
|
||||
<mime-type type="application/vnd.twonav.trk">
|
||||
<comment>TwoNav Track File</comment>
|
||||
<sub-class-of type="text/plain"/>
|
||||
<generic-icon name="text/plain"/>
|
||||
<glob pattern="*.trk"/>
|
||||
</mime-type>
|
||||
|
||||
<mime-type type="application/vnd.twonav.rte">
|
||||
<comment>TwoNav Route File</comment>
|
||||
<sub-class-of type="text/plain"/>
|
||||
<generic-icon name="text/plain"/>
|
||||
<glob pattern="*.rte"/>
|
||||
</mime-type>
|
||||
|
||||
<mime-type type="application/vnd.twonav.wpt">
|
||||
<comment>TwoNav Waypoint File</comment>
|
||||
<sub-class-of type="text/plain"/>
|
||||
<generic-icon name="text/plain"/>
|
||||
<glob pattern="*.wpt"/>
|
||||
</mime-type>
|
||||
|
||||
|
||||
<!-- Maps -->
|
||||
|
||||
<mime-type type="application/vnd.garmin.img">
|
||||
|
@ -37,7 +37,7 @@ Unicode true
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "9.12"
|
||||
!define VERSION "10.2"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||
@ -178,13 +178,14 @@ Section "GPXSee" SEC_APP
|
||||
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 22
|
||||
!insertmacro FILE_ASSOCIATION_ADD "ghp" "ONmove Log File" 23
|
||||
!insertmacro FILE_ASSOCIATION_ADD "qct" "QuickChart Map File" 24
|
||||
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 25
|
||||
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 25
|
||||
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 26
|
||||
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 27
|
||||
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 28
|
||||
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 29
|
||||
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 30
|
||||
!insertmacro FILE_ASSOCIATION_ADD "trk" "TwoNav Track File" 25
|
||||
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 26
|
||||
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 26
|
||||
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 27
|
||||
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 28
|
||||
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 29
|
||||
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 30
|
||||
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 31
|
||||
|
||||
WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\""
|
||||
WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" ""
|
||||
@ -231,6 +232,7 @@ Section "GPXSee" SEC_APP
|
||||
WriteRegStr HKCR ".omd\OpenWithList" "GPXSee.exe" ""
|
||||
WriteRegStr HKCR ".ghp\OpenWithList" "GPXSee.exe" ""
|
||||
WriteRegStr HKCR ".qct\OpenWithList" "GPXSee.exe" ""
|
||||
WriteRegStr HKCR ".trk\OpenWithList" "GPXSee.exe" ""
|
||||
|
||||
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
||||
|
||||
@ -252,6 +254,9 @@ Section "QT framework" SEC_QT
|
||||
File "Qt6Svg.dll"
|
||||
File "Qt6Widgets.dll"
|
||||
File "Qt6Core5Compat.dll"
|
||||
File "Qt6Positioning.dll"
|
||||
File "Qt6SerialPort.dll"
|
||||
File /r "tls"
|
||||
!else
|
||||
File "Qt5Core.dll"
|
||||
File "Qt5Gui.dll"
|
||||
@ -261,12 +266,15 @@ Section "QT framework" SEC_QT
|
||||
File "Qt5Sql.dll"
|
||||
File "Qt5Svg.dll"
|
||||
File "Qt5Concurrent.dll"
|
||||
File "Qt5Positioning.dll"
|
||||
File "Qt5SerialPort.dll"
|
||||
File /r "printsupport"
|
||||
!endif
|
||||
File /r "platforms"
|
||||
File /r "imageformats"
|
||||
File /r "styles"
|
||||
File /r "sqldrivers"
|
||||
File /r "position"
|
||||
|
||||
SectionEnd
|
||||
|
||||
@ -376,6 +384,7 @@ Section "Uninstall"
|
||||
!insertmacro FILE_ASSOCIATION_REMOVE "omd"
|
||||
!insertmacro FILE_ASSOCIATION_REMOVE "ghp"
|
||||
!insertmacro FILE_ASSOCIATION_REMOVE "qct"
|
||||
!insertmacro FILE_ASSOCIATION_REMOVE "trk"
|
||||
|
||||
DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe"
|
||||
DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe"
|
||||
@ -421,6 +430,7 @@ Section "Uninstall"
|
||||
DeleteRegValue HKCR ".omd\OpenWithList" "GPXSee.exe"
|
||||
DeleteRegValue HKCR ".ghp\OpenWithList" "GPXSee.exe"
|
||||
DeleteRegValue HKCR ".qct\OpenWithList" "GPXSee.exe"
|
||||
DeleteRegValue HKCR ".trk\OpenWithList" "GPXSee.exe"
|
||||
DeleteRegKey HKCR "Applications\GPXSee.exe"
|
||||
|
||||
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
||||
@ -453,4 +463,4 @@ LangString DESC_LOCALIZATION ${LANG_ENGLISH} \
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_MSVC} $(DESC_MSVC)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_APP} $(DESC_APP)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_LOCALIZATION} $(DESC_LOCALIZATION)
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
|
@ -7,10 +7,13 @@
|
||||
CoordinatesItem::CoordinatesItem(QGraphicsItem *parent) : QGraphicsItem(parent)
|
||||
{
|
||||
_format = DecimalDegrees;
|
||||
|
||||
_units = Metric;
|
||||
_ele = NAN;
|
||||
_color = Qt::black;
|
||||
_bgColor = Qt::white;
|
||||
_drawBackground = false;
|
||||
_font.setPixelSize(FONT_SIZE);
|
||||
_font.setFamily(FONT_FAMILY);
|
||||
|
||||
_digitalZoom = 0;
|
||||
|
||||
setAcceptHoverEvents(true);
|
||||
@ -27,24 +30,36 @@ void CoordinatesItem::paint(QPainter *painter,
|
||||
if (!_c.isValid())
|
||||
return;
|
||||
|
||||
if (_drawBackground) {
|
||||
painter->setPen(Qt::NoPen);
|
||||
QColor bc(_bgColor);
|
||||
bc.setAlpha(196);
|
||||
painter->setBrush(QBrush(bc));
|
||||
painter->drawRect(_boundingRect);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
}
|
||||
|
||||
QFontMetrics fm(_font);
|
||||
painter->setFont(_font);
|
||||
painter->setPen(QPen(Qt::black));
|
||||
painter->drawText(0, -fm.descent(), Format::coordinates(_c, _format));
|
||||
painter->setPen(QPen(_color));
|
||||
painter->drawText(0, -fm.descent(), text());
|
||||
|
||||
/*
|
||||
painter->setPen(Qt::red);
|
||||
painter->drawRect(boundingRect());
|
||||
*/
|
||||
//painter->setPen(Qt::red);
|
||||
//painter->drawRect(boundingRect());
|
||||
}
|
||||
|
||||
void CoordinatesItem::setCoordinates(const Coordinates &c)
|
||||
void CoordinatesItem::setCoordinates(const Coordinates &c, qreal elevation)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
|
||||
_c = c;
|
||||
_ele = elevation;
|
||||
|
||||
updateBoundingRect();
|
||||
update();
|
||||
}
|
||||
|
||||
void CoordinatesItem::setFormat(const CoordinatesFormat &format)
|
||||
void CoordinatesItem::setFormat(CoordinatesFormat format)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
|
||||
@ -52,16 +67,54 @@ void CoordinatesItem::setFormat(const CoordinatesFormat &format)
|
||||
updateBoundingRect();
|
||||
}
|
||||
|
||||
void CoordinatesItem::setUnits(Units units)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
|
||||
_units = units;
|
||||
updateBoundingRect();
|
||||
}
|
||||
|
||||
void CoordinatesItem::setDigitalZoom(qreal zoom)
|
||||
{
|
||||
_digitalZoom = zoom;
|
||||
setScale(pow(2, -_digitalZoom));
|
||||
}
|
||||
|
||||
QString CoordinatesItem::text() const
|
||||
{
|
||||
return (std::isnan(_ele))
|
||||
? Format::coordinates(_c, _format)
|
||||
: Format::coordinates(_c, _format) + ", " + Format::elevation(_ele, _units);
|
||||
}
|
||||
|
||||
void CoordinatesItem::updateBoundingRect()
|
||||
{
|
||||
QFontMetrics fm(_font);
|
||||
_boundingRect = fm.tightBoundingRect(Format::coordinates(
|
||||
Coordinates(-180, -90), _format));
|
||||
_boundingRect.moveBottom(-fm.descent());
|
||||
|
||||
QRectF br(fm.tightBoundingRect(text()));
|
||||
QRectF r1(br);
|
||||
QRectF r2(br);
|
||||
r1.moveTop(-fm.ascent());
|
||||
r2.moveBottom(-fm.descent());
|
||||
|
||||
_boundingRect = r1 | r2;
|
||||
}
|
||||
|
||||
void CoordinatesItem::setColor(const QColor &color)
|
||||
{
|
||||
_color = color;
|
||||
update();
|
||||
}
|
||||
|
||||
void CoordinatesItem::setBackgroundColor(const QColor &color)
|
||||
{
|
||||
_bgColor = color;
|
||||
update();
|
||||
}
|
||||
|
||||
void CoordinatesItem::drawBackground(bool draw)
|
||||
{
|
||||
_drawBackground = draw;
|
||||
update();
|
||||
}
|
||||
|
@ -17,18 +17,27 @@ public:
|
||||
|
||||
CoordinatesFormat format() const {return _format;}
|
||||
|
||||
void setCoordinates(const Coordinates &c);
|
||||
void setFormat(const CoordinatesFormat &format);
|
||||
void setCoordinates(const Coordinates &c, qreal elevation = NAN);
|
||||
void setFormat(CoordinatesFormat format);
|
||||
void setUnits(Units units);
|
||||
void setDigitalZoom(qreal zoom);
|
||||
void setColor(const QColor &color);
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void drawBackground(bool draw);
|
||||
|
||||
private:
|
||||
void updateBoundingRect();
|
||||
QString text() const;
|
||||
|
||||
Coordinates _c;
|
||||
qreal _ele;
|
||||
CoordinatesFormat _format;
|
||||
Units _units;
|
||||
QRectF _boundingRect;
|
||||
QFont _font;
|
||||
qreal _digitalZoom;
|
||||
QColor _color, _bgColor;
|
||||
bool _drawBackground;
|
||||
};
|
||||
|
||||
#endif // COORDINATESITEM_H
|
||||
|
45
src/GUI/crosshairitem.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include <QPainter>
|
||||
#include "crosshairitem.h"
|
||||
|
||||
#define SIZE 16
|
||||
#define WIDTH 2
|
||||
|
||||
CrosshairItem::CrosshairItem(QGraphicsItem *parent) : QGraphicsItem(parent)
|
||||
{
|
||||
_color = Qt::red;
|
||||
_digitalZoom = 0;
|
||||
}
|
||||
|
||||
QRectF CrosshairItem::boundingRect() const
|
||||
{
|
||||
return QRectF(-SIZE/2, -SIZE/2, SIZE, SIZE);
|
||||
}
|
||||
|
||||
void CrosshairItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
painter->setPen(QPen(_color, WIDTH));
|
||||
|
||||
painter->drawLine(-SIZE/2, 0, -SIZE/4, 0);
|
||||
painter->drawLine(SIZE/4, 0, SIZE/2, 0);
|
||||
painter->drawLine(0, -SIZE/2, 0, -SIZE/4);
|
||||
painter->drawLine(0, SIZE/4, 0, SIZE/2);
|
||||
|
||||
//painter->drawRect(boundingRect());
|
||||
}
|
||||
|
||||
void CrosshairItem::setDigitalZoom(qreal zoom)
|
||||
{
|
||||
_digitalZoom = zoom;
|
||||
setScale(pow(2, -_digitalZoom));
|
||||
}
|
||||
|
||||
void CrosshairItem::setColor(const QColor &color)
|
||||
{
|
||||
_color = color;
|
||||
update();
|
||||
}
|
30
src/GUI/crosshairitem.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef CROSSHAIRITEM_H
|
||||
#define CROSSHAIRITEM_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include "map/map.h"
|
||||
|
||||
class CrosshairItem : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
CrosshairItem(QGraphicsItem *parent = 0);
|
||||
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget);
|
||||
|
||||
const Coordinates &coordinates() const {return _c;}
|
||||
const QColor &color() const {return _color;}
|
||||
|
||||
void setCoordinates(const Coordinates &c) {_c = c;}
|
||||
void setMap(Map *map) {setPos(map->ll2xy(_c));}
|
||||
void setDigitalZoom(qreal zoom);
|
||||
void setColor(const QColor &color);
|
||||
|
||||
private:
|
||||
Coordinates _c;
|
||||
QColor _color;
|
||||
qreal _digitalZoom;
|
||||
};
|
||||
|
||||
#endif // CROSSHAIRITEM_H
|
163
src/GUI/gui.cpp
@ -25,6 +25,7 @@
|
||||
#include <QScreen>
|
||||
#include <QStyle>
|
||||
#include <QTabBar>
|
||||
#include <QGeoPositionInfoSource>
|
||||
#include "common/programpaths.h"
|
||||
#include "common/downloader.h"
|
||||
#include "data/data.h"
|
||||
@ -327,7 +328,32 @@ void GUI::createActions()
|
||||
_showCoordinatesAction->setMenuRole(QAction::NoRole);
|
||||
_showCoordinatesAction->setCheckable(true);
|
||||
connect(_showCoordinatesAction, &QAction::triggered, _mapView,
|
||||
&MapView::showCoordinates);
|
||||
&MapView::showCursorCoordinates);
|
||||
|
||||
// Position
|
||||
_showPositionAction = new QAction(QIcon(SHOW_POS_ICON),
|
||||
tr("Show position"), this);
|
||||
_showPositionAction->setMenuRole(QAction::NoRole);
|
||||
_showPositionAction->setCheckable(true);
|
||||
_showPositionAction->setEnabled(false);
|
||||
connect(_showPositionAction, &QAction::triggered, _mapView,
|
||||
&MapView::showPosition);
|
||||
_followPositionAction = new QAction(tr("Follow position"), this);
|
||||
_followPositionAction->setMenuRole(QAction::NoRole);
|
||||
_followPositionAction->setCheckable(true);
|
||||
connect(_followPositionAction, &QAction::triggered, _mapView,
|
||||
&MapView::followPosition);
|
||||
_showPositionCoordinatesAction = new QAction(tr("Show coordinates"),
|
||||
this);
|
||||
_showPositionCoordinatesAction->setMenuRole(QAction::NoRole);
|
||||
_showPositionCoordinatesAction->setCheckable(true);
|
||||
connect(_showPositionCoordinatesAction, &QAction::triggered, _mapView,
|
||||
&MapView::showPositionCoordinates);
|
||||
_showMotionInfo = new QAction(tr("Show motion info"), this);
|
||||
_showMotionInfo->setMenuRole(QAction::NoRole);
|
||||
_showMotionInfo->setCheckable(true);
|
||||
connect(_showMotionInfo, &QAction::triggered, _mapView,
|
||||
&MapView::showMotionInfo);
|
||||
|
||||
// Data actions
|
||||
_showTracksAction = new QAction(tr("Show tracks"), this);
|
||||
@ -613,6 +639,13 @@ void GUI::createMenus()
|
||||
demMenu->addAction(_showDEMTilesAction);
|
||||
demMenu->addAction(_downloadDEMAction);
|
||||
|
||||
QMenu *positionMenu = menuBar()->addMenu(tr("Position"));
|
||||
positionMenu->addAction(_showPositionCoordinatesAction);
|
||||
positionMenu->addAction(_showMotionInfo);
|
||||
positionMenu->addAction(_followPositionAction);
|
||||
positionMenu->addSeparator();
|
||||
positionMenu->addAction(_showPositionAction);
|
||||
|
||||
QMenu *settingsMenu = menuBar()->addMenu(tr("&Settings"));
|
||||
QMenu *timeMenu = settingsMenu->addMenu(tr("Time"));
|
||||
timeMenu->addAction(_totalTimeAction);
|
||||
@ -663,6 +696,7 @@ void GUI::createToolBars()
|
||||
_showToolBar->addAction(_showPOIAction);
|
||||
_showToolBar->addAction(_showMapAction);
|
||||
_showToolBar->addAction(_showGraphsAction);
|
||||
_showToolBar->addAction(_showPositionAction);
|
||||
|
||||
_navigationToolBar = addToolBar(tr("Navigation"));
|
||||
_navigationToolBar->setObjectName("Navigation");
|
||||
@ -676,7 +710,7 @@ void GUI::createToolBars()
|
||||
void GUI::createMapView()
|
||||
{
|
||||
_map = new EmptyMap(this);
|
||||
_mapView = new MapView(_map, _poi, this);
|
||||
_mapView = new MapView(_map, _poi, 0, this);
|
||||
_mapView->setSizePolicy(QSizePolicy(QSizePolicy::Ignored,
|
||||
QSizePolicy::Expanding));
|
||||
_mapView->setMinimumHeight(200);
|
||||
@ -1018,6 +1052,19 @@ void GUI::openOptions()
|
||||
SET_VIEW_OPTION(pathAntiAliasing, useAntiAliasing);
|
||||
SET_VIEW_OPTION(useOpenGL, useOpenGL);
|
||||
SET_VIEW_OPTION(sliderColor, setMarkerColor);
|
||||
SET_VIEW_OPTION(crosshairColor, setCrosshairColor);
|
||||
SET_VIEW_OPTION(infoColor, setInfoColor);
|
||||
SET_VIEW_OPTION(infoBackground, drawInfoBackground);
|
||||
|
||||
if (options.plugin != _options.plugin
|
||||
|| options.pluginParams.value(options.plugin)
|
||||
!= _options.pluginParams.value(_options.plugin)) {
|
||||
QGeoPositionInfoSource *source = positionSource(options);
|
||||
_showPositionAction->setEnabled(source != 0);
|
||||
_mapView->setPositionSource(source);
|
||||
delete _positionSource;
|
||||
_positionSource = source;
|
||||
}
|
||||
|
||||
if (options.hidpiMap != _options.hidpiMap)
|
||||
_mapView->setDevicePixelRatio(devicePixelRatioF(),
|
||||
@ -2096,8 +2143,27 @@ void GUI::dropEvent(QDropEvent *event)
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
QGeoPositionInfoSource *GUI::positionSource(const Options &options)
|
||||
{
|
||||
QGeoPositionInfoSource *source;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
source = QGeoPositionInfoSource::createSource(options.plugin, this);
|
||||
#else // QT 5.14
|
||||
source = QGeoPositionInfoSource::createSource(options.plugin,
|
||||
options.pluginParams.value(options.plugin), this);
|
||||
#endif // QT 5.14
|
||||
if (source)
|
||||
source->setPreferredPositioningMethods(
|
||||
QGeoPositionInfoSource::SatellitePositioningMethods);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
void GUI::writeSettings()
|
||||
{
|
||||
int index;
|
||||
|
||||
QSettings settings(qApp->applicationName(), qApp->applicationName());
|
||||
settings.clear();
|
||||
|
||||
@ -2133,8 +2199,8 @@ void GUI::writeSettings()
|
||||
settings.setValue(CURRENT_MAP_SETTING, _map->name());
|
||||
if (_showMapAction->isChecked() != SHOW_MAP_DEFAULT)
|
||||
settings.setValue(SHOW_MAP_SETTING, _showMapAction->isChecked());
|
||||
if (_showCoordinatesAction->isChecked() != SHOW_COORDINATES_DEFAULT)
|
||||
settings.setValue(SHOW_COORDINATES_SETTING,
|
||||
if (_showCoordinatesAction->isChecked() != SHOW_CURSOR_COORDINATES_DEFAULT)
|
||||
settings.setValue(SHOW_CURSOR_COORDINATES_SETTING,
|
||||
_showCoordinatesAction->isChecked());
|
||||
settings.endGroup();
|
||||
|
||||
@ -2165,21 +2231,37 @@ void GUI::writeSettings()
|
||||
settings.setValue(SHOW_POI_ICONS_SETTING,
|
||||
_showPOIIconsAction->isChecked());
|
||||
|
||||
int j = 0;
|
||||
index = 0;
|
||||
QList<QAction*> poiActions(_poisActionGroup->actions());
|
||||
for (int i = 0; i < poiActions.count(); i++) {
|
||||
POIAction *a = static_cast<POIAction*>(poiActions.at(i));
|
||||
if (!a->isChecked()) {
|
||||
if (j == 0)
|
||||
if (index == 0)
|
||||
settings.beginWriteArray(DISABLED_POI_FILE_SETTINGS_PREFIX);
|
||||
settings.setArrayIndex(j++);
|
||||
settings.setArrayIndex(index++);
|
||||
settings.setValue(DISABLED_POI_FILE_SETTING, a->data().toString());
|
||||
}
|
||||
}
|
||||
if (j != 0)
|
||||
if (index != 0)
|
||||
settings.endArray();
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup(POSITION_SETTINGS_GROUP);
|
||||
if (_showPositionAction->isChecked() != SHOW_POSITION_DEFAULT)
|
||||
settings.setValue(SHOW_POSITION_SETTING,
|
||||
_showPositionAction->isChecked());
|
||||
if (_followPositionAction->isChecked() != FOLLOW_POSITION_DEFAULT)
|
||||
settings.setValue(FOLLOW_POSITION_SETTING,
|
||||
_followPositionAction->isChecked());
|
||||
if (_showPositionCoordinatesAction->isChecked()
|
||||
!= SHOW_POSITION_COORDINATES_DEFAULT)
|
||||
settings.setValue(SHOW_POSITION_COORDINATES_SETTING,
|
||||
_showPositionCoordinatesAction->isChecked());
|
||||
if (_showMotionInfo->isChecked() != SHOW_MOTION_INFO_DEFAULT)
|
||||
settings.setValue(SHOW_MOTION_INFO_SETTING,
|
||||
_showMotionInfo->isChecked());
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup(DATA_SETTINGS_GROUP);
|
||||
if (_showTracksAction->isChecked() != SHOW_TRACKS_DEFAULT)
|
||||
settings.setValue(SHOW_TRACKS_SETTING, _showTracksAction->isChecked());
|
||||
@ -2262,6 +2344,12 @@ void GUI::writeSettings()
|
||||
settings.setValue(MAP_OPACITY_SETTING, _options.mapOpacity);
|
||||
if (_options.backgroundColor != BACKGROUND_COLOR_DEFAULT)
|
||||
settings.setValue(BACKGROUND_COLOR_SETTING, _options.backgroundColor);
|
||||
if (_options.crosshairColor != CROSSHAIR_COLOR_DEFAULT)
|
||||
settings.setValue(CROSSHAIR_COLOR_SETTING, _options.crosshairColor);
|
||||
if (_options.infoColor != INFO_COLOR_DEFAULT)
|
||||
settings.setValue(INFO_COLOR_SETTING, _options.infoColor);
|
||||
if (_options.infoBackground != INFO_BACKGROUND_DEFAULT)
|
||||
settings.setValue(INFO_BACKGROUND_SETTING, _options.infoBackground);
|
||||
if (_options.trackWidth != TRACK_WIDTH_DEFAULT)
|
||||
settings.setValue(TRACK_WIDTH_SETTING, _options.trackWidth);
|
||||
if (_options.routeWidth != ROUTE_WIDTH_DEFAULT)
|
||||
@ -2333,6 +2421,22 @@ void GUI::writeSettings()
|
||||
settings.setValue(DEM_USERNAME_SETTING, _options.demUsername);
|
||||
if (_options.demPassword != DEM_PASSWORD_DEFAULT)
|
||||
settings.setValue(DEM_PASSWORD_SETTING, _options.demPassword);
|
||||
// the plugins order is random so always store the value
|
||||
settings.setValue(POSITION_PLUGIN_SETTING, _options.plugin);
|
||||
index = 0;
|
||||
for (QMap<QString, QVariantMap>::const_iterator it
|
||||
= _options.pluginParams.constBegin();
|
||||
it != _options.pluginParams.constEnd(); ++it) {
|
||||
if (!it.value().isEmpty()) {
|
||||
if (index == 0)
|
||||
settings.beginWriteArray(POSITION_PLUGIN_PARAMS_PREFIX);
|
||||
settings.setArrayIndex(index++);
|
||||
settings.setValue(POSITION_PLUGIN_PARAMS_PLUGIN, it.key());
|
||||
settings.setValue(POSITION_PLUGIN_PARAMS_PARAM, it.value());
|
||||
}
|
||||
}
|
||||
if (index != 0)
|
||||
settings.endArray();
|
||||
if (_options.useOpenGL != USE_OPENGL_DEFAULT)
|
||||
settings.setValue(USE_OPENGL_SETTING, _options.useOpenGL);
|
||||
if (_options.enableHTTP2 != ENABLE_HTTP2_DEFAULT)
|
||||
@ -2419,10 +2523,10 @@ void GUI::readSettings(QString &activeMap, QStringList &disabledPOIs)
|
||||
_showMapAction->setChecked(true);
|
||||
else
|
||||
_mapView->showMap(false);
|
||||
if (settings.value(SHOW_COORDINATES_SETTING, SHOW_COORDINATES_DEFAULT)
|
||||
if (settings.value(SHOW_CURSOR_COORDINATES_SETTING, SHOW_CURSOR_COORDINATES_DEFAULT)
|
||||
.toBool()) {
|
||||
_showCoordinatesAction->setChecked(true);
|
||||
_mapView->showCoordinates(true);
|
||||
_mapView->showCursorCoordinates(true);
|
||||
}
|
||||
activeMap = settings.value(CURRENT_MAP_SETTING).toString();
|
||||
settings.endGroup();
|
||||
@ -2577,6 +2681,12 @@ void GUI::readSettings(QString &activeMap, QStringList &disabledPOIs)
|
||||
MAP_OPACITY_DEFAULT).toInt();
|
||||
_options.backgroundColor = settings.value(BACKGROUND_COLOR_SETTING,
|
||||
BACKGROUND_COLOR_DEFAULT).value<QColor>();
|
||||
_options.crosshairColor = settings.value(CROSSHAIR_COLOR_SETTING,
|
||||
CROSSHAIR_COLOR_DEFAULT).value<QColor>();
|
||||
_options.infoColor = settings.value(INFO_COLOR_SETTING,
|
||||
INFO_COLOR_DEFAULT).value<QColor>();
|
||||
_options.infoBackground = settings.value(INFO_BACKGROUND_SETTING,
|
||||
INFO_BACKGROUND_DEFAULT).toBool();
|
||||
_options.trackWidth = settings.value(TRACK_WIDTH_SETTING,
|
||||
TRACK_WIDTH_DEFAULT).toInt();
|
||||
_options.routeWidth = settings.value(ROUTE_WIDTH_SETTING,
|
||||
@ -2645,6 +2755,16 @@ void GUI::readSettings(QString &activeMap, QStringList &disabledPOIs)
|
||||
DEM_USERNAME_DEFAULT).toString();
|
||||
_options.demPassword = settings.value(DEM_PASSWORD_SETTING,
|
||||
DEM_PASSWORD_DEFAULT).toString();
|
||||
_options.plugin = settings.value(POSITION_PLUGIN_SETTING,
|
||||
POSITION_PLUGIN_DEFAULT).toString();
|
||||
size = settings.beginReadArray(POSITION_PLUGIN_PARAMS_PREFIX);
|
||||
for (int i = 0; i < size; i++) {
|
||||
settings.setArrayIndex(i);
|
||||
_options.pluginParams.insert(
|
||||
settings.value(POSITION_PLUGIN_PARAMS_PLUGIN).toString(),
|
||||
settings.value(POSITION_PLUGIN_PARAMS_PARAM).toMap());
|
||||
}
|
||||
settings.endArray();
|
||||
_options.useOpenGL = settings.value(USE_OPENGL_SETTING, USE_OPENGL_DEFAULT)
|
||||
.toBool();
|
||||
_options.enableHTTP2 = settings.value(ENABLE_HTTP2_SETTING,
|
||||
@ -2683,10 +2803,30 @@ void GUI::readSettings(QString &activeMap, QStringList &disabledPOIs)
|
||||
.toString();
|
||||
_options.poiPath = settings.value(POI_PATH_SETTING, POI_PATH_DEFAULT)
|
||||
.toString();
|
||||
settings.endGroup();
|
||||
|
||||
_positionSource = positionSource(_options);
|
||||
_showPositionAction->setEnabled(_positionSource != 0);
|
||||
|
||||
settings.beginGroup(POSITION_SETTINGS_GROUP);
|
||||
if (settings.value(SHOW_POSITION_SETTING, SHOW_POSITION_DEFAULT).toBool())
|
||||
_showPositionAction->trigger();
|
||||
if (settings.value(FOLLOW_POSITION_SETTING, FOLLOW_POSITION_DEFAULT).toBool())
|
||||
_followPositionAction->trigger();
|
||||
if (settings.value(SHOW_POSITION_COORDINATES_SETTING,
|
||||
SHOW_POSITION_COORDINATES_DEFAULT).toBool())
|
||||
_showPositionCoordinatesAction->trigger();
|
||||
if (settings.value(SHOW_MOTION_INFO_SETTING, SHOW_MOTION_INFO_DEFAULT)
|
||||
.toBool())
|
||||
_showMotionInfo->trigger();
|
||||
settings.endGroup();
|
||||
|
||||
_mapView->setPalette(_options.palette);
|
||||
_mapView->setMapOpacity(_options.mapOpacity);
|
||||
_mapView->setBackgroundColor(_options.backgroundColor);
|
||||
_mapView->setCrosshairColor(_options.crosshairColor);
|
||||
_mapView->setInfoColor(_options.infoColor);
|
||||
_mapView->drawInfoBackground(_options.infoBackground);
|
||||
_mapView->setTrackWidth(_options.trackWidth);
|
||||
_mapView->setRouteWidth(_options.routeWidth);
|
||||
_mapView->setAreaWidth(_options.areaWidth);
|
||||
@ -2707,6 +2847,7 @@ void GUI::readSettings(QString &activeMap, QStringList &disabledPOIs)
|
||||
_mapView->setOutputProjection(CRS::projection(_options.outputProjection));
|
||||
_mapView->setInputProjection(CRS::projection(_options.inputProjection));
|
||||
_mapView->setTimeZone(_options.timeZone.zone());
|
||||
_mapView->setPositionSource(_positionSource);
|
||||
|
||||
for (int i = 0; i < _tabs.count(); i++) {
|
||||
_tabs.at(i)->setPalette(_options.palette);
|
||||
@ -2752,8 +2893,6 @@ void GUI::readSettings(QString &activeMap, QStringList &disabledPOIs)
|
||||
_dataDir = _options.dataPath;
|
||||
_mapDir = _options.mapsPath;
|
||||
_poiDir = _options.poiPath;
|
||||
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void GUI::loadInitialMaps(const QString &selected)
|
||||
|
@ -24,6 +24,7 @@ class QAction;
|
||||
class QLabel;
|
||||
class QSplitter;
|
||||
class QPrinter;
|
||||
class QGeoPositionInfoSource;
|
||||
class FileBrowser;
|
||||
class GraphTab;
|
||||
class MapView;
|
||||
@ -157,6 +158,7 @@ private:
|
||||
qreal time() const;
|
||||
qreal movingTime() const;
|
||||
QAction *mapAction(const QString &name);
|
||||
QGeoPositionInfoSource *positionSource(const Options &options);
|
||||
void readSettings(QString &activeMap, QStringList &disabledPOIs);
|
||||
void writeSettings();
|
||||
|
||||
@ -198,6 +200,10 @@ private:
|
||||
QAction *_showPOILabelsAction;
|
||||
QAction *_showPOIIconsAction;
|
||||
QAction *_showMapAction;
|
||||
QAction *_showPositionAction;
|
||||
QAction *_followPositionAction;
|
||||
QAction *_showPositionCoordinatesAction;
|
||||
QAction *_showMotionInfo;
|
||||
QAction *_fullscreenAction;
|
||||
QAction *_loadMapAction;
|
||||
QAction *_loadMapDirAction;
|
||||
@ -253,6 +259,7 @@ private:
|
||||
|
||||
POI *_poi;
|
||||
Map *_map;
|
||||
QGeoPositionInfoSource *_positionSource;
|
||||
DEMLoader *_dem;
|
||||
|
||||
FileBrowser *_browser;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define LAST_FILE_ICON ":/arrow-right-double.png"
|
||||
#define FIRST_FILE_ICON ":/arrow-left-double.png"
|
||||
#define FULLSCREEN_ICON ":/view-fullscreen.png"
|
||||
#define SHOW_POS_ICON ":/transform-move.png"
|
||||
|
||||
// Options dialog icons
|
||||
#define APPEARANCE_ICON ":/format-stroke-color.png"
|
||||
@ -27,6 +28,7 @@
|
||||
#define DATA_ICON ":/view-filter.png"
|
||||
#define MAPS_ICON ":/applications-internet_32.png"
|
||||
#define DEM_ICON ":/view-grid.png"
|
||||
#define POSITION_ICON ":/transform-move_32.png"
|
||||
|
||||
#define SHOW_PWD_ICON ":/document-encrypt.png"
|
||||
#define HIDE_PWD_ICON ":/document-decrypt.png"
|
||||
|
@ -5,8 +5,10 @@
|
||||
#include <QScrollBar>
|
||||
#include <QClipboard>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QGeoPositionInfoSource>
|
||||
#include "data/poi.h"
|
||||
#include "data/data.h"
|
||||
#include "data/dem.h"
|
||||
#include "map/map.h"
|
||||
#include "map/pcs.h"
|
||||
#include "trackitem.h"
|
||||
@ -20,6 +22,8 @@
|
||||
#include "graphicsscene.h"
|
||||
#include "mapaction.h"
|
||||
#include "markerinfoitem.h"
|
||||
#include "crosshairitem.h"
|
||||
#include "motioninfoitem.h"
|
||||
#include "mapview.h"
|
||||
|
||||
|
||||
@ -44,8 +48,8 @@ static void updateZValues(T &items)
|
||||
}
|
||||
|
||||
|
||||
MapView::MapView(Map *map, POI *poi, QWidget *parent)
|
||||
: QGraphicsView(parent)
|
||||
MapView::MapView(Map *map, POI *poi, QGeoPositionInfoSource *source,
|
||||
QWidget *parent) : QGraphicsView(parent)
|
||||
{
|
||||
Q_ASSERT(map != 0);
|
||||
Q_ASSERT(poi != 0);
|
||||
@ -63,10 +67,10 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
|
||||
_mapScale = new ScaleItem();
|
||||
_mapScale->setZValue(2.0);
|
||||
_scene->addItem(_mapScale);
|
||||
_coordinates = new CoordinatesItem();
|
||||
_coordinates->setZValue(2.0);
|
||||
_coordinates->setVisible(false);
|
||||
_scene->addItem(_coordinates);
|
||||
_cursorCoordinates = new CoordinatesItem();
|
||||
_cursorCoordinates->setZValue(2.0);
|
||||
_cursorCoordinates->setVisible(false);
|
||||
_scene->addItem(_cursorCoordinates);
|
||||
|
||||
_outputProjection = PCS::pcs(3857);
|
||||
_inputProjection = GCS::gcs(4326);
|
||||
@ -79,6 +83,25 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
|
||||
_poi = poi;
|
||||
connect(_poi, &POI::pointsChanged, this, &MapView::updatePOI);
|
||||
|
||||
_positionSource = source;
|
||||
if (_positionSource)
|
||||
connect(_positionSource, &QGeoPositionInfoSource::positionUpdated, this,
|
||||
&MapView::updatePosition);
|
||||
_crosshair = new CrosshairItem();
|
||||
_crosshair->setZValue(2.0);
|
||||
_crosshair->setVisible(false);
|
||||
_scene->addItem(_crosshair);
|
||||
|
||||
_positionCoordinates = new CoordinatesItem();
|
||||
_positionCoordinates->setZValue(2.0);
|
||||
_positionCoordinates->setVisible(false);
|
||||
_scene->addItem(_positionCoordinates);
|
||||
|
||||
_motionInfo = new MotionInfoItem();
|
||||
_motionInfo->setZValue(2.0);
|
||||
_motionInfo->setVisible(false);
|
||||
_scene->addItem(_motionInfo);
|
||||
|
||||
_mapOpacity = 1.0;
|
||||
_backgroundColor = Qt::white;
|
||||
_markerColor = Qt::red;
|
||||
@ -106,6 +129,10 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
|
||||
_waypointColor = Qt::black;
|
||||
_poiSize = 8;
|
||||
_poiColor = Qt::black;
|
||||
_followPosition = false;
|
||||
_showPosition = false;
|
||||
_showPositionCoordinates = false;
|
||||
_showMotionInfo = false;
|
||||
|
||||
_deviceRatio = 1.0;
|
||||
_mapRatio = 1.0;
|
||||
@ -125,7 +152,7 @@ void MapView::centerOn(const QPointF &pos)
|
||||
QRectF vr(mapToScene(viewport()->rect()).boundingRect());
|
||||
_res = _map->resolution(vr);
|
||||
_mapScale->setResolution(_res);
|
||||
_coordinates->setCoordinates(Coordinates());
|
||||
_cursorCoordinates->setCoordinates(Coordinates());
|
||||
}
|
||||
|
||||
PathItem *MapView::addTrack(const Track &track)
|
||||
@ -369,6 +396,8 @@ void MapView::rescale()
|
||||
it != _pois.constEnd(); it++)
|
||||
it.value()->setMap(_map);
|
||||
|
||||
_crosshair->setMap(_map);
|
||||
|
||||
updatePOIVisibility();
|
||||
}
|
||||
|
||||
@ -407,19 +436,21 @@ void MapView::setMap(Map *map)
|
||||
_scene->setSceneRect(_map->bounds());
|
||||
|
||||
for (int i = 0; i < _tracks.size(); i++)
|
||||
_tracks.at(i)->setMap(map);
|
||||
_tracks.at(i)->setMap(_map);
|
||||
for (int i = 0; i < _routes.size(); i++)
|
||||
_routes.at(i)->setMap(map);
|
||||
_routes.at(i)->setMap(_map);
|
||||
for (int i = 0; i < _areas.size(); i++)
|
||||
_areas.at(i)->setMap(map);
|
||||
_areas.at(i)->setMap(_map);
|
||||
for (int i = 0; i < _waypoints.size(); i++)
|
||||
_waypoints.at(i)->setMap(map);
|
||||
_waypoints.at(i)->setMap(_map);
|
||||
|
||||
for (POIHash::const_iterator it = _pois.constBegin();
|
||||
it != _pois.constEnd(); it++)
|
||||
it.value()->setMap(_map);
|
||||
updatePOIVisibility();
|
||||
|
||||
_crosshair->setMap(_map);
|
||||
|
||||
QPointF nc = QRectF(_map->ll2xy(cr.topLeft()),
|
||||
_map->ll2xy(cr.bottomRight())).center();
|
||||
centerOn(nc);
|
||||
@ -437,6 +468,20 @@ void MapView::setPOI(POI *poi)
|
||||
updatePOI();
|
||||
}
|
||||
|
||||
void MapView::setPositionSource(QGeoPositionInfoSource *source)
|
||||
{
|
||||
if (_positionSource)
|
||||
disconnect(_positionSource, &QGeoPositionInfoSource::positionUpdated,
|
||||
this, &MapView::updatePosition);
|
||||
if (source)
|
||||
connect(source, &QGeoPositionInfoSource::positionUpdated, this,
|
||||
&MapView::updatePosition);
|
||||
|
||||
_positionSource = source;
|
||||
|
||||
showPosition(_showPosition);
|
||||
}
|
||||
|
||||
void MapView::setGraph(int index)
|
||||
{
|
||||
for (int i = 0; i < _tracks.size(); i++)
|
||||
@ -502,6 +547,8 @@ void MapView::setUnits(Units units)
|
||||
_routes.at(i)->updateTicks();
|
||||
|
||||
_mapScale->setUnits(units);
|
||||
_cursorCoordinates->setUnits(units);
|
||||
_positionCoordinates->setUnits(units);
|
||||
}
|
||||
|
||||
void MapView::setCoordinatesFormat(CoordinatesFormat format)
|
||||
@ -514,7 +561,8 @@ void MapView::setCoordinatesFormat(CoordinatesFormat format)
|
||||
for (int i = 0; i < _routes.count(); i++)
|
||||
_routes.at(i)->updateMarkerInfo();
|
||||
|
||||
_coordinates->setFormat(format);
|
||||
_cursorCoordinates->setFormat(format);
|
||||
_positionCoordinates->setFormat(format);
|
||||
}
|
||||
|
||||
void MapView::setTimeZone(const QTimeZone &zone)
|
||||
@ -557,7 +605,10 @@ void MapView::digitalZoom(int zoom)
|
||||
it.value()->setDigitalZoom(_digitalZoom);
|
||||
|
||||
_mapScale->setDigitalZoom(_digitalZoom);
|
||||
_coordinates->setDigitalZoom(_digitalZoom);
|
||||
_cursorCoordinates->setDigitalZoom(_digitalZoom);
|
||||
_positionCoordinates->setDigitalZoom(_digitalZoom);
|
||||
_motionInfo->setDigitalZoom(_digitalZoom);
|
||||
_crosshair->setDigitalZoom(_digitalZoom);
|
||||
}
|
||||
|
||||
void MapView::zoom(int zoom, const QPoint &pos, bool shift)
|
||||
@ -658,7 +709,7 @@ void MapView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton && event->modifiers() & MODIFIER)
|
||||
QApplication::clipboard()->setText(Format::coordinates(
|
||||
_map->xy2ll(mapToScene(event->pos())), _coordinates->format()));
|
||||
_map->xy2ll(mapToScene(event->pos())), _cursorCoordinates->format()));
|
||||
else
|
||||
QGraphicsView::mousePressEvent(event);
|
||||
}
|
||||
@ -756,10 +807,16 @@ void MapView::clear()
|
||||
_waypoints.clear();
|
||||
|
||||
_scene->removeItem(_mapScale);
|
||||
_scene->removeItem(_coordinates);
|
||||
_scene->removeItem(_cursorCoordinates);
|
||||
_scene->removeItem(_positionCoordinates);
|
||||
_scene->removeItem(_crosshair);
|
||||
_scene->removeItem(_motionInfo);
|
||||
_scene->clear();
|
||||
_scene->addItem(_mapScale);
|
||||
_scene->addItem(_coordinates);
|
||||
_scene->addItem(_cursorCoordinates);
|
||||
_scene->addItem(_positionCoordinates);
|
||||
_scene->addItem(_crosshair);
|
||||
_scene->addItem(_motionInfo);
|
||||
|
||||
_palette.reset();
|
||||
|
||||
@ -910,10 +967,31 @@ void MapView::showPOIIcons(bool show)
|
||||
updatePOIVisibility();
|
||||
}
|
||||
|
||||
void MapView::showCoordinates(bool show)
|
||||
void MapView::showCursorCoordinates(bool show)
|
||||
{
|
||||
_coordinates->setVisible(show);
|
||||
_cursorCoordinates->setVisible(show);
|
||||
setMouseTracking(show);
|
||||
_scene->invalidate();
|
||||
}
|
||||
|
||||
void MapView::showPositionCoordinates(bool show)
|
||||
{
|
||||
_showPositionCoordinates = show;
|
||||
|
||||
if (_crosshair->isVisible())
|
||||
_positionCoordinates->setVisible(show);
|
||||
|
||||
_scene->invalidate();
|
||||
}
|
||||
|
||||
void MapView::showMotionInfo(bool show)
|
||||
{
|
||||
_showMotionInfo = show;
|
||||
|
||||
if (_crosshair->isVisible())
|
||||
_motionInfo->setVisible(show);
|
||||
|
||||
_scene->invalidate();
|
||||
}
|
||||
|
||||
void MapView::showOverlappedPOIs(bool show)
|
||||
@ -1022,6 +1100,10 @@ void MapView::setMapOpacity(int opacity)
|
||||
void MapView::setBackgroundColor(const QColor &color)
|
||||
{
|
||||
_backgroundColor = color;
|
||||
_cursorCoordinates->setBackgroundColor(color);
|
||||
_positionCoordinates->setBackgroundColor(color);
|
||||
_motionInfo->setBackgroundColor(color);
|
||||
|
||||
reloadMap();
|
||||
}
|
||||
|
||||
@ -1053,11 +1135,27 @@ void MapView::paintEvent(QPaintEvent *event)
|
||||
if (_mapScale->pos() != scaleScenePos && !_plot)
|
||||
_mapScale->setPos(scaleScenePos);
|
||||
|
||||
if (_coordinates->isVisible()) {
|
||||
if (_cursorCoordinates->isVisible()) {
|
||||
QPointF coordinatesScenePos = mapToScene(rect().bottomLeft()
|
||||
+ QPoint(COORDINATES_OFFSET, -COORDINATES_OFFSET));
|
||||
if (_coordinates->pos() != coordinatesScenePos && !_plot)
|
||||
_coordinates->setPos(coordinatesScenePos);
|
||||
if (_cursorCoordinates->pos() != coordinatesScenePos && !_plot)
|
||||
_cursorCoordinates->setPos(coordinatesScenePos);
|
||||
}
|
||||
|
||||
if (_positionCoordinates->isVisible()) {
|
||||
QPointF coordinatesScenePos = mapToScene(rect().topLeft()
|
||||
+ QPoint(COORDINATES_OFFSET, COORDINATES_OFFSET
|
||||
+ _positionCoordinates->boundingRect().height()));
|
||||
if (_positionCoordinates->pos() != coordinatesScenePos)
|
||||
_positionCoordinates->setPos(coordinatesScenePos);
|
||||
}
|
||||
|
||||
if (_motionInfo->isVisible()) {
|
||||
QPointF coordinatesScenePos = mapToScene(rect().topRight()
|
||||
+ QPoint(-COORDINATES_OFFSET - _motionInfo->boundingRect().width(),
|
||||
COORDINATES_OFFSET + _motionInfo->boundingRect().height()));
|
||||
if (_motionInfo->pos() != coordinatesScenePos)
|
||||
_motionInfo->setPos(coordinatesScenePos);
|
||||
}
|
||||
|
||||
QGraphicsView::paintEvent(event);
|
||||
@ -1078,15 +1176,17 @@ void MapView::scrollContentsBy(int dx, int dy)
|
||||
|
||||
void MapView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (_coordinates->isVisible())
|
||||
_coordinates->setCoordinates(_map->xy2ll(mapToScene(event->pos())));
|
||||
if (_cursorCoordinates->isVisible()) {
|
||||
Coordinates c(_map->xy2ll(mapToScene(event->pos())));
|
||||
_cursorCoordinates->setCoordinates(c, DEM::elevation(c));
|
||||
}
|
||||
|
||||
QGraphicsView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void MapView::leaveEvent(QEvent *event)
|
||||
{
|
||||
_coordinates->setCoordinates(Coordinates());
|
||||
_cursorCoordinates->setCoordinates(Coordinates());
|
||||
QGraphicsView::leaveEvent(event);
|
||||
}
|
||||
|
||||
@ -1157,6 +1257,8 @@ void MapView::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
||||
it.value()->setMap(_map);
|
||||
updatePOIVisibility();
|
||||
|
||||
_crosshair->setMap(_map);
|
||||
|
||||
QPointF nc = QRectF(_map->ll2xy(cr.topLeft()),
|
||||
_map->ll2xy(cr.bottomRight())).center();
|
||||
centerOn(nc);
|
||||
@ -1206,3 +1308,71 @@ RectC MapView::boundingRect() const
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
void MapView::showPosition(bool show)
|
||||
{
|
||||
_showPosition = show;
|
||||
|
||||
if (!_positionSource) {
|
||||
_crosshair->setVisible(false);
|
||||
_positionCoordinates->setVisible(false);
|
||||
_motionInfo->setVisible(false);
|
||||
} else if (_showPosition) {
|
||||
_crosshair->setVisible(true);
|
||||
if (_showPositionCoordinates)
|
||||
_positionCoordinates->setVisible(true);
|
||||
if (_showMotionInfo)
|
||||
_motionInfo->setVisible(true);
|
||||
_positionSource->startUpdates();
|
||||
} else {
|
||||
_positionSource->stopUpdates();
|
||||
_crosshair->setVisible(false);
|
||||
_positionCoordinates->setVisible(false);
|
||||
_motionInfo->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MapView::followPosition(bool follow)
|
||||
{
|
||||
_followPosition = follow;
|
||||
|
||||
if (follow && _crosshair->isVisible())
|
||||
centerOn(_map->ll2xy(_crosshair->coordinates()));
|
||||
}
|
||||
|
||||
void MapView::updatePosition(const QGeoPositionInfo &pos)
|
||||
{
|
||||
QGeoCoordinate gc(pos.coordinate());
|
||||
if (!gc.isValid())
|
||||
return;
|
||||
|
||||
Coordinates c(gc.longitude(), gc.latitude());
|
||||
_crosshair->setCoordinates(c);
|
||||
_crosshair->setMap(_map);
|
||||
_positionCoordinates->setCoordinates(c, gc.altitude());
|
||||
_motionInfo->setInfo(pos.attribute(QGeoPositionInfo::Direction),
|
||||
pos.attribute(QGeoPositionInfo::GroundSpeed),
|
||||
pos.attribute(QGeoPositionInfo::VerticalSpeed));
|
||||
|
||||
if (_followPosition)
|
||||
centerOn(_map->ll2xy(c));
|
||||
}
|
||||
|
||||
void MapView::setCrosshairColor(const QColor &color)
|
||||
{
|
||||
_crosshair->setColor(color);
|
||||
}
|
||||
|
||||
void MapView::setInfoColor(const QColor &color)
|
||||
{
|
||||
_cursorCoordinates->setColor(color);
|
||||
_positionCoordinates->setColor(color);
|
||||
_motionInfo->setColor(color);
|
||||
}
|
||||
|
||||
void MapView::drawInfoBackground(bool draw)
|
||||
{
|
||||
_cursorCoordinates->drawBackground(draw);
|
||||
_positionCoordinates->drawBackground(draw);
|
||||
_motionInfo->drawBackground(draw);
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "palette.h"
|
||||
|
||||
|
||||
class QGeoPositionInfoSource;
|
||||
class QGeoPositionInfo;
|
||||
class Data;
|
||||
class POI;
|
||||
class Map;
|
||||
@ -35,6 +37,8 @@ class Area;
|
||||
class GraphicsScene;
|
||||
class QTimeZone;
|
||||
class MapAction;
|
||||
class CrosshairItem;
|
||||
class MotionInfoItem;
|
||||
|
||||
class MapView : public QGraphicsView
|
||||
{
|
||||
@ -48,7 +52,8 @@ public:
|
||||
};
|
||||
Q_DECLARE_FLAGS(PlotFlags, Flag)
|
||||
|
||||
MapView(Map *map, POI *poi, QWidget *parent = 0);
|
||||
MapView(Map *map, POI *poi, QGeoPositionInfoSource *source,
|
||||
QWidget *parent = 0);
|
||||
|
||||
QList<PathItem *> loadData(const Data &data);
|
||||
void loadMaps(const QList<MapAction*> &maps);
|
||||
@ -57,6 +62,7 @@ public:
|
||||
void setPalette(const Palette &palette);
|
||||
void setPOI(POI *poi);
|
||||
void setMap(Map *map);
|
||||
void setPositionSource(QGeoPositionInfoSource *source);
|
||||
void setGraph(int index);
|
||||
|
||||
void plot(QPainter *painter, const QRectF &target, qreal scale,
|
||||
@ -66,6 +72,9 @@ public:
|
||||
|
||||
void setUnits(Units units);
|
||||
void setMarkerColor(const QColor &color);
|
||||
void setCrosshairColor(const QColor &color);
|
||||
void setInfoColor(const QColor &color);
|
||||
void drawInfoBackground(bool draw);
|
||||
void setTrackWidth(int width);
|
||||
void setRouteWidth(int width);
|
||||
void setAreaWidth(int width);
|
||||
@ -94,9 +103,11 @@ public:
|
||||
public slots:
|
||||
void showMap(bool show);
|
||||
void showPOI(bool show);
|
||||
void showPosition(bool show);
|
||||
void showPOILabels(bool show);
|
||||
void showPOIIcons(bool show);
|
||||
void showCoordinates(bool show);
|
||||
void showCursorCoordinates(bool show);
|
||||
void showPositionCoordinates(bool show);
|
||||
void showTicks(bool show);
|
||||
void showMarkers(bool show);
|
||||
void showMarkerInfo(MarkerInfoItem::Type type);
|
||||
@ -109,10 +120,13 @@ public slots:
|
||||
void showWaypoints(bool show);
|
||||
void showRouteWaypoints(bool show);
|
||||
void setMarkerPosition(qreal pos);
|
||||
void followPosition(bool follow);
|
||||
void showMotionInfo(bool show);
|
||||
|
||||
private slots:
|
||||
void updatePOI();
|
||||
void reloadMap();
|
||||
void updatePosition(const QGeoPositionInfo &pos);
|
||||
|
||||
private:
|
||||
typedef QHash<SearchPointer<Waypoint>, WaypointItem*> POIHash;
|
||||
@ -148,7 +162,9 @@ private:
|
||||
|
||||
GraphicsScene *_scene;
|
||||
ScaleItem *_mapScale;
|
||||
CoordinatesItem *_coordinates;
|
||||
CoordinatesItem *_cursorCoordinates, *_positionCoordinates;
|
||||
CrosshairItem *_crosshair;
|
||||
MotionInfoItem *_motionInfo;
|
||||
QList<TrackItem*> _tracks;
|
||||
QList<RouteItem*> _routes;
|
||||
QList<WaypointItem*> _waypoints;
|
||||
@ -160,6 +176,7 @@ private:
|
||||
|
||||
Map *_map;
|
||||
POI *_poi;
|
||||
QGeoPositionInfoSource *_positionSource;
|
||||
|
||||
Palette _palette;
|
||||
qreal _mapOpacity;
|
||||
@ -167,9 +184,10 @@ private:
|
||||
|
||||
bool _showMap, _showTracks, _showRoutes, _showAreas, _showWaypoints,
|
||||
_showWaypointLabels, _showPOI, _showPOILabels, _showRouteWaypoints,
|
||||
_showMarkers, _showPathTicks, _showPOIIcons, _showWaypointIcons;
|
||||
_showMarkers, _showPathTicks, _showPOIIcons, _showWaypointIcons,
|
||||
_showPosition, _showPositionCoordinates, _showMotionInfo;
|
||||
MarkerInfoItem::Type _markerInfoType;
|
||||
bool _overlapPOIs;
|
||||
bool _overlapPOIs, _followPosition;
|
||||
int _trackWidth, _routeWidth, _areaWidth;
|
||||
Qt::PenStyle _trackStyle, _routeStyle, _areaStyle;
|
||||
int _waypointSize, _poiSize;
|
||||
|
160
src/GUI/motioninfoitem.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include <cmath>
|
||||
#include <QFont>
|
||||
#include <QPainter>
|
||||
#include <QLocale>
|
||||
#include <QApplication>
|
||||
#include "font.h"
|
||||
#include "motioninfoitem.h"
|
||||
|
||||
|
||||
#define DEGREE_UNIT QString::fromUtf8("\xC2\xB0")
|
||||
|
||||
MotionInfoItem::MotionInfoItem(QGraphicsItem *parent) : QGraphicsItem(parent)
|
||||
{
|
||||
_units = Metric;
|
||||
_bearing = NAN;
|
||||
_speed = NAN;
|
||||
_verticalSpeed = NAN;
|
||||
_color = Qt::black;
|
||||
_bgColor = Qt::white;
|
||||
_drawBackground = false;
|
||||
_font.setPixelSize(FONT_SIZE);
|
||||
_font.setFamily(FONT_FAMILY);
|
||||
_digitalZoom = 0;
|
||||
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
updateBoundingRect();
|
||||
}
|
||||
|
||||
void MotionInfoItem::paint(QPainter *painter,
|
||||
const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
if (std::isnan(_bearing) && std::isnan(_speed) && std::isnan(_verticalSpeed))
|
||||
return;
|
||||
|
||||
if (_drawBackground) {
|
||||
painter->setPen(Qt::NoPen);
|
||||
QColor bc(_bgColor);
|
||||
bc.setAlpha(196);
|
||||
painter->setBrush(QBrush(bc));
|
||||
painter->drawRect(_boundingRect);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
}
|
||||
|
||||
QFontMetrics fm(_font);
|
||||
painter->setFont(_font);
|
||||
painter->setPen(QPen(_color));
|
||||
painter->drawText(0, -fm.descent(), text());
|
||||
|
||||
//painter->setPen(Qt::red);
|
||||
//painter->drawRect(boundingRect());
|
||||
}
|
||||
|
||||
void MotionInfoItem::setInfo(qreal bearing, qreal speed, qreal verticalSpeed)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
|
||||
_bearing = bearing;
|
||||
_speed = speed;
|
||||
_verticalSpeed = verticalSpeed;
|
||||
|
||||
updateBoundingRect();
|
||||
update();
|
||||
}
|
||||
|
||||
void MotionInfoItem::setUnits(Units units)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
|
||||
_units = units;
|
||||
updateBoundingRect();
|
||||
}
|
||||
|
||||
void MotionInfoItem::setDigitalZoom(qreal zoom)
|
||||
{
|
||||
_digitalZoom = zoom;
|
||||
setScale(pow(2, -_digitalZoom));
|
||||
}
|
||||
|
||||
QString MotionInfoItem::speed(const QLocale &l) const
|
||||
{
|
||||
if (_units == Nautical)
|
||||
return l.toString(MS2KN * _speed) + UNIT_SPACE
|
||||
+ qApp->translate("MotionInfoItem", "kn");
|
||||
else if (_units == Imperial)
|
||||
return l.toString(MS2MIH * _speed) + UNIT_SPACE
|
||||
+ qApp->translate("MotionInfoItem", "mi/h");
|
||||
else
|
||||
return l.toString(MS2KMH * _speed) + UNIT_SPACE
|
||||
+ qApp->translate("MotionInfoItem", "km/h");
|
||||
}
|
||||
|
||||
QString MotionInfoItem::verticalSpeed(const QLocale &l) const
|
||||
{
|
||||
if (_units == Nautical || _units == Imperial)
|
||||
return l.toString(MS2FTMIN * _verticalSpeed) + UNIT_SPACE
|
||||
+ qApp->translate("MotionInfoItem", "ft/min");
|
||||
else
|
||||
return l.toString(MS2MMIN * _verticalSpeed) + UNIT_SPACE
|
||||
+ qApp->translate("MotionInfoItem", "m/min");
|
||||
}
|
||||
|
||||
static QString bearing(qreal val, const QLocale &l)
|
||||
{
|
||||
return l.toString(val) + DEGREE_UNIT;
|
||||
}
|
||||
|
||||
QString MotionInfoItem::text() const
|
||||
{
|
||||
QLocale l(QLocale::system());
|
||||
QString str;
|
||||
|
||||
if (!std::isnan(_bearing))
|
||||
str += bearing(_bearing, l);
|
||||
if (!std::isnan(_speed)) {
|
||||
if (!str.isEmpty())
|
||||
str += ", ";
|
||||
str += speed(l);
|
||||
} if (!std::isnan(_verticalSpeed)) {
|
||||
if (!str.isEmpty())
|
||||
str += ", ";
|
||||
str += verticalSpeed(l);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void MotionInfoItem::updateBoundingRect()
|
||||
{
|
||||
QFontMetrics fm(_font);
|
||||
|
||||
QRectF br(fm.tightBoundingRect(text()));
|
||||
QRectF r1(br);
|
||||
QRectF r2(br);
|
||||
r1.moveTop(-fm.ascent());
|
||||
r2.moveBottom(-fm.descent());
|
||||
|
||||
_boundingRect = r1 | r2;
|
||||
}
|
||||
|
||||
void MotionInfoItem::setColor(const QColor &color)
|
||||
{
|
||||
_color = color;
|
||||
update();
|
||||
}
|
||||
|
||||
void MotionInfoItem::setBackgroundColor(const QColor &color)
|
||||
{
|
||||
_bgColor = color;
|
||||
update();
|
||||
}
|
||||
|
||||
void MotionInfoItem::drawBackground(bool draw)
|
||||
{
|
||||
_drawBackground = draw;
|
||||
update();
|
||||
}
|
38
src/GUI/motioninfoitem.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef MOTIONINFOITEM_H
|
||||
#define MOTIONINFOITEM_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include "units.h"
|
||||
|
||||
class MotionInfoItem : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
MotionInfoItem(QGraphicsItem *parent = 0);
|
||||
|
||||
QRectF boundingRect() const {return _boundingRect;}
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget);
|
||||
|
||||
void setInfo(qreal bearing, qreal speed, qreal verticalSpeed);
|
||||
void setUnits(Units units);
|
||||
void setDigitalZoom(qreal zoom);
|
||||
void setColor(const QColor &color);
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void drawBackground(bool draw);
|
||||
|
||||
private:
|
||||
void updateBoundingRect();
|
||||
QString speed(const QLocale &l) const;
|
||||
QString verticalSpeed(const QLocale &l) const;
|
||||
QString text() const;
|
||||
|
||||
qreal _bearing, _speed, _verticalSpeed;
|
||||
Units _units;
|
||||
QRectF _boundingRect;
|
||||
QFont _font;
|
||||
qreal _digitalZoom;
|
||||
QColor _color, _bgColor;
|
||||
bool _drawBackground;
|
||||
};
|
||||
|
||||
#endif // MOTIONINFOITEM_H
|
@ -13,6 +13,7 @@
|
||||
#include <QLabel>
|
||||
#include <QSysInfo>
|
||||
#include <QButtonGroup>
|
||||
#include <QGeoPositionInfoSource>
|
||||
#include "icons.h"
|
||||
#include "infolabel.h"
|
||||
#include "colorbox.h"
|
||||
@ -22,6 +23,7 @@
|
||||
#include "projectioncombobox.h"
|
||||
#include "dirselectwidget.h"
|
||||
#include "authenticationwidget.h"
|
||||
#include "pluginparameters.h"
|
||||
#include "optionsdialog.h"
|
||||
|
||||
|
||||
@ -39,7 +41,6 @@ static QFrame *line()
|
||||
}
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
|
||||
void OptionsDialog::automaticPauseDetectionSet(bool set)
|
||||
{
|
||||
_pauseInterval->setEnabled(!set);
|
||||
@ -275,10 +276,20 @@ QWidget *OptionsDialog::createAppearancePage()
|
||||
_backgroundColor = new ColorBox();
|
||||
_backgroundColor->setColor(_options.backgroundColor);
|
||||
_backgroundColor->enableAlphaChannel(false);
|
||||
_crosshairColor = new ColorBox();
|
||||
_crosshairColor->setColor(_options.crosshairColor);
|
||||
_infoColor = new ColorBox();
|
||||
_infoColor->setColor(_options.infoColor);
|
||||
_infoBackground = new QCheckBox(tr("Info background"));
|
||||
_infoBackground->setChecked(_options.infoBackground);
|
||||
|
||||
QFormLayout *mapLayout = new QFormLayout();
|
||||
mapLayout->addRow(tr("Background color:"), _backgroundColor);
|
||||
mapLayout->addRow(tr("Map opacity:"), _mapOpacity);
|
||||
mapLayout->addRow(tr("Crosshair color:"), _crosshairColor);
|
||||
mapLayout->addRow(tr("Info color:"), _infoColor);
|
||||
mapLayout->addWidget(_infoBackground);
|
||||
|
||||
QWidget *mapTab = new QWidget();
|
||||
QVBoxLayout *mapTabLayout = new QVBoxLayout();
|
||||
mapTabLayout->addLayout(mapLayout);
|
||||
@ -593,6 +604,39 @@ QWidget *OptionsDialog::createDEMPage()
|
||||
return demPage;
|
||||
}
|
||||
|
||||
QWidget *OptionsDialog::createPositionPage()
|
||||
{
|
||||
QStringList plugins(QGeoPositionInfoSource::availableSources());
|
||||
|
||||
_positionPlugin = new QComboBox();
|
||||
_positionPlugin->addItems(plugins);
|
||||
_positionPlugin->setCurrentIndex(_positionPlugin->findText(_options.plugin));
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
_pluginParameters = new PluginParameters(_positionPlugin->currentText(),
|
||||
_options.pluginParams);
|
||||
connect(_positionPlugin, &QComboBox::currentTextChanged, _pluginParameters,
|
||||
&PluginParameters::setPlugin);
|
||||
#endif // QT 5.14
|
||||
|
||||
QFormLayout *pluginLayout = new QFormLayout();
|
||||
pluginLayout->addRow(tr("Plugin:"), _positionPlugin);
|
||||
|
||||
QVBoxLayout *sourceLayout = new QVBoxLayout();
|
||||
sourceLayout->addLayout(pluginLayout);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
sourceLayout->addWidget(_pluginParameters);
|
||||
#endif // QT 5.14
|
||||
sourceLayout->addStretch();
|
||||
|
||||
QWidget *sourceTab = new QWidget();
|
||||
sourceTab->setLayout(sourceLayout);
|
||||
|
||||
QTabWidget *positionPage = new QTabWidget();
|
||||
positionPage->addTab(sourceTab, tr("Source"));
|
||||
|
||||
return positionPage;
|
||||
}
|
||||
|
||||
QWidget *OptionsDialog::createExportPage()
|
||||
{
|
||||
_wysiwyg = new QRadioButton(tr("WYSIWYG"));
|
||||
@ -741,6 +785,7 @@ OptionsDialog::OptionsDialog(Options &options, Units units, QWidget *parent)
|
||||
pages->addWidget(createDataPage());
|
||||
pages->addWidget(createPOIPage());
|
||||
pages->addWidget(createDEMPage());
|
||||
pages->addWidget(createPositionPage());
|
||||
pages->addWidget(createExportPage());
|
||||
pages->addWidget(createSystemPage());
|
||||
|
||||
@ -752,6 +797,7 @@ OptionsDialog::OptionsDialog(Options &options, Units units, QWidget *parent)
|
||||
new QListWidgetItem(QIcon(DATA_ICON), tr("Data"), menu);
|
||||
new QListWidgetItem(QIcon(POI_ICON), tr("POI"), menu);
|
||||
new QListWidgetItem(QIcon(DEM_ICON), tr("DEM"), menu);
|
||||
new QListWidgetItem(QIcon(POSITION_ICON), tr("Position"), menu);
|
||||
new QListWidgetItem(QIcon(PRINT_EXPORT_ICON), tr("Print & Export"),
|
||||
menu);
|
||||
new QListWidgetItem(QIcon(SYSTEM_ICON), tr("System"), menu);
|
||||
@ -796,6 +842,9 @@ void OptionsDialog::accept()
|
||||
_options.palette.setShift(_colorOffset->value() / 100.0);
|
||||
_options.mapOpacity = _mapOpacity->value();
|
||||
_options.backgroundColor = _backgroundColor->color();
|
||||
_options.crosshairColor = _crosshairColor->color();
|
||||
_options.infoColor = _infoColor->color();
|
||||
_options.infoBackground = _infoBackground->isChecked();
|
||||
_options.trackWidth = _trackWidth->value();
|
||||
_options.trackStyle = (Qt::PenStyle) _trackStyle->itemData(
|
||||
_trackStyle->currentIndex()).toInt();
|
||||
@ -856,6 +905,11 @@ void OptionsDialog::accept()
|
||||
_options.demUsername = _demAuth->username();
|
||||
_options.demPassword = _demAuth->password();
|
||||
|
||||
_options.plugin = _positionPlugin->currentText();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
_options.pluginParams = _pluginParameters->parameters();
|
||||
#endif // QT 5.14
|
||||
|
||||
_options.useOpenGL = _useOpenGL->isChecked();
|
||||
_options.enableHTTP2 = _enableHTTP2->isChecked();
|
||||
_options.pixmapCache = _pixmapCache->value();
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef OPTIONSDIALOG_H
|
||||
#define OPTIONSDIALOG_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QDialog>
|
||||
#include "palette.h"
|
||||
#include "units.h"
|
||||
@ -19,6 +20,7 @@ class PercentSlider;
|
||||
class ProjectionComboBox;
|
||||
class DirSelectWidget;
|
||||
class AuthenticationWidget;
|
||||
class PluginParameters;
|
||||
|
||||
struct Options {
|
||||
// Appearance
|
||||
@ -40,6 +42,9 @@ struct Options {
|
||||
bool graphAntiAliasing;
|
||||
int mapOpacity;
|
||||
QColor backgroundColor;
|
||||
QColor crosshairColor;
|
||||
QColor infoColor;
|
||||
bool infoBackground;
|
||||
// Map
|
||||
int outputProjection;
|
||||
int inputProjection;
|
||||
@ -67,6 +72,9 @@ struct Options {
|
||||
QString demUsername;
|
||||
QString demPassword;
|
||||
bool demAuthorization;
|
||||
// Position
|
||||
QString plugin;
|
||||
QMap<QString, QVariantMap> pluginParams;
|
||||
// System
|
||||
bool useOpenGL;
|
||||
bool enableHTTP2;
|
||||
@ -107,6 +115,7 @@ private:
|
||||
QWidget *createSystemPage();
|
||||
QWidget *createExportPage();
|
||||
QWidget *createDEMPage();
|
||||
QWidget *createPositionPage();
|
||||
|
||||
Options &_options;
|
||||
|
||||
@ -116,6 +125,9 @@ private:
|
||||
PercentSlider *_colorOffset;
|
||||
PercentSlider *_mapOpacity;
|
||||
ColorBox *_backgroundColor;
|
||||
ColorBox *_crosshairColor;
|
||||
ColorBox *_infoColor;
|
||||
QCheckBox *_infoBackground;
|
||||
QSpinBox *_trackWidth;
|
||||
StyleComboBox *_trackStyle;
|
||||
QSpinBox *_routeWidth;
|
||||
@ -163,6 +175,11 @@ private:
|
||||
// DEM
|
||||
QLineEdit *_demURL;
|
||||
AuthenticationWidget *_demAuth;
|
||||
// Position
|
||||
QComboBox *_positionPlugin;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
PluginParameters *_pluginParameters;
|
||||
#endif // QT 5.14
|
||||
// System
|
||||
QSpinBox *_pixmapCache;
|
||||
QSpinBox *_connectionTimeout;
|
||||
|
76
src/GUI/pluginparameters.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include <QFormLayout>
|
||||
#include <QLineEdit>
|
||||
#include "pluginparameters.h"
|
||||
|
||||
static const QMap<QString, QStringList> pluginParams = {
|
||||
{"nmea", {"nmea.source"}},
|
||||
{"serialnmea", {"serialnmea.serial_port"}},
|
||||
{"geoclue2", {"desktopId"}}
|
||||
};
|
||||
|
||||
static void deleteLayout(QLayout *layout)
|
||||
{
|
||||
if (!layout)
|
||||
return;
|
||||
|
||||
while (layout->count() > 0) {
|
||||
QLayoutItem *child = layout->takeAt(0);
|
||||
deleteLayout(child->layout());
|
||||
delete child->widget();
|
||||
delete child;
|
||||
}
|
||||
|
||||
delete layout;
|
||||
}
|
||||
|
||||
PluginParameters::PluginParameters(const QString &plugin,
|
||||
const QMap<QString, QVariantMap> ¶ms, QWidget *parent)
|
||||
: QWidget(parent), _params(params), _plugin(plugin)
|
||||
{
|
||||
setPlugin(plugin);
|
||||
}
|
||||
|
||||
void PluginParameters::setPlugin(const QString &plugin)
|
||||
{
|
||||
saveParameters();
|
||||
|
||||
QStringList params = pluginParams.value(plugin);
|
||||
|
||||
QFormLayout *l = new QFormLayout();
|
||||
for (int i = 0; i < params.size(); i++) {
|
||||
QLineEdit *le = new QLineEdit();
|
||||
le->setObjectName(params.at(i));
|
||||
le->setText(_params[plugin].value(params.at(i)).toString());
|
||||
l->addRow(params.at(i) + ":", le);
|
||||
}
|
||||
|
||||
deleteLayout(layout());
|
||||
setLayout(l);
|
||||
|
||||
_plugin = plugin;
|
||||
}
|
||||
|
||||
const QMap<QString, QVariantMap> &PluginParameters::parameters()
|
||||
{
|
||||
saveParameters();
|
||||
return _params;
|
||||
}
|
||||
|
||||
void PluginParameters::saveParameters()
|
||||
{
|
||||
QVariantMap &map(_params[_plugin]);
|
||||
QFormLayout *l = qobject_cast<QFormLayout*>(layout());
|
||||
if (!l)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < l->rowCount(); i++) {
|
||||
QLayoutItem *li = l->itemAt(i, QFormLayout::FieldRole);
|
||||
QLineEdit *le = qobject_cast<QLineEdit*>(li->widget());
|
||||
if (le) {
|
||||
if (le->text().isEmpty())
|
||||
map.remove(le->objectName());
|
||||
else
|
||||
map.insert(le->objectName(), le->text());
|
||||
}
|
||||
}
|
||||
}
|
27
src/GUI/pluginparameters.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef PLUGINPARAMETERS_H
|
||||
#define PLUGINPARAMETERS_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVariantMap>
|
||||
|
||||
class PluginParameters : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PluginParameters(const QString &plugin,
|
||||
const QMap<QString, QVariantMap> ¶ms, QWidget *parent = 0);
|
||||
|
||||
const QMap<QString, QVariantMap> ¶meters();
|
||||
|
||||
public slots:
|
||||
void setPlugin(const QString &plugin);
|
||||
|
||||
private:
|
||||
void saveParameters();
|
||||
|
||||
QMap<QString, QVariantMap> _params;
|
||||
QString _plugin;
|
||||
};
|
||||
|
||||
#endif // PLUGINPARAMETERS_H
|
@ -3,6 +3,9 @@
|
||||
|
||||
#define IMPERIAL_UNITS() \
|
||||
(QLocale::system().measurementSystem() == QLocale::ImperialSystem)
|
||||
#define POSITION_PLUGIN() \
|
||||
(QGeoPositionInfoSource::availableSources().isEmpty() \
|
||||
? "" : QGeoPositionInfoSource::availableSources().first())
|
||||
|
||||
#define WINDOW_SETTINGS_GROUP "Window"
|
||||
#define WINDOW_GEOMETRY_SETTING "geometry"
|
||||
@ -34,13 +37,23 @@
|
||||
#define CURRENT_MAP_SETTING "map"
|
||||
#define SHOW_MAP_SETTING "show"
|
||||
#define SHOW_MAP_DEFAULT true
|
||||
#define SHOW_COORDINATES_SETTING "coordinates"
|
||||
#define SHOW_COORDINATES_DEFAULT false
|
||||
#define SHOW_CURSOR_COORDINATES_SETTING "coordinates"
|
||||
#define SHOW_CURSOR_COORDINATES_DEFAULT false
|
||||
|
||||
#define POI_SETTINGS_GROUP "POI"
|
||||
#define OVERLAP_POI_SETTING "overlap"
|
||||
#define OVERLAP_POI_DEFAULT false
|
||||
|
||||
#define POSITION_SETTINGS_GROUP "Position"
|
||||
#define SHOW_POSITION_SETTING "show"
|
||||
#define SHOW_POSITION_DEFAULT false
|
||||
#define FOLLOW_POSITION_SETTING "follow"
|
||||
#define FOLLOW_POSITION_DEFAULT true
|
||||
#define SHOW_POSITION_COORDINATES_SETTING "coordinates"
|
||||
#define SHOW_POSITION_COORDINATES_DEFAULT true
|
||||
#define SHOW_MOTION_INFO_SETTING "motionInfo"
|
||||
#define SHOW_MOTION_INFO_DEFAULT true
|
||||
|
||||
#define SHOW_POI_ICONS_SETTING "icons"
|
||||
#define SHOW_POI_ICONS_DEFAULT true
|
||||
#define SHOW_POI_LABELS_SETTING "labels"
|
||||
@ -119,6 +132,12 @@
|
||||
#define MAP_OPACITY_DEFAULT 100
|
||||
#define BACKGROUND_COLOR_SETTING "backgroundColor"
|
||||
#define BACKGROUND_COLOR_DEFAULT QColor(Qt::white)
|
||||
#define CROSSHAIR_COLOR_SETTING "crosshairColor"
|
||||
#define CROSSHAIR_COLOR_DEFAULT QColor(Qt::red)
|
||||
#define INFO_COLOR_SETTING "infoColor"
|
||||
#define INFO_COLOR_DEFAULT QColor(Qt::black)
|
||||
#define INFO_BACKGROUND_SETTING "infoBackground"
|
||||
#define INFO_BACKGROUND_DEFAULT false
|
||||
#define TRACK_WIDTH_SETTING "trackWidth"
|
||||
#define TRACK_WIDTH_DEFAULT 3
|
||||
#define ROUTE_WIDTH_SETTING "routeWidth"
|
||||
@ -179,13 +198,18 @@
|
||||
#define POI_RADIUS_SETTING "poiRadius"
|
||||
#define POI_RADIUS_DEFAULT (int)(IMPERIAL_UNITS() ? MIINM : KMINM)
|
||||
#define DEM_URL_SETTING "demURL"
|
||||
#define DEM_URL_DEFAULT ""
|
||||
#define DEM_URL_DEFAULT "http://dem.gpxsee.org/$lat/$lat$lon.hgt.zip"
|
||||
#define DEM_AUTH_SETTING "demAuthentication"
|
||||
#define DEM_AUTH_DEFAULT false
|
||||
#define DEM_USERNAME_SETTING "demUsername"
|
||||
#define DEM_USERNAME_DEFAULT ""
|
||||
#define DEM_PASSWORD_SETTING "demPassword"
|
||||
#define DEM_PASSWORD_DEFAULT ""
|
||||
#define POSITION_PLUGIN_SETTING "positionPlugin"
|
||||
#define POSITION_PLUGIN_DEFAULT POSITION_PLUGIN()
|
||||
#define POSITION_PLUGIN_PARAMS_PREFIX "pluginParameters"
|
||||
#define POSITION_PLUGIN_PARAMS_PLUGIN "plugin"
|
||||
#define POSITION_PLUGIN_PARAMS_PARAM "parameters"
|
||||
#define USE_OPENGL_SETTING "useOpenGL"
|
||||
#define USE_OPENGL_DEFAULT false
|
||||
#define ENABLE_HTTP2_SETTING "enableHTTP2"
|
||||
|
@ -7,26 +7,28 @@ enum Units {
|
||||
Nautical
|
||||
};
|
||||
|
||||
#define M2KM 0.001000000000 // m -> km
|
||||
#define M2MI 0.000621371192 // m -> mi
|
||||
#define M2NMI 0.000539956803 // m -> nmi
|
||||
#define M2FT 3.280839900000 // m -> ft
|
||||
#define MS2KMH 3.600000000000 // m/s -> km/h
|
||||
#define MS2MIH 2.236936290000 // m/s -> mi/h
|
||||
#define MS2KN 1.943844490000 // m/s -> kn
|
||||
#define FT2MI 0.000189393939 // ft -> mi
|
||||
#define MM2IN 0.039370100000 // mm -> in
|
||||
#define MM2CM 0.100000000000 // mm -> cm
|
||||
#define H2S 0.000277777778 // h -> s
|
||||
#define MIN2S 0.016666666667 // min -> s
|
||||
#define M2KM 0.001000000000 // m -> km
|
||||
#define M2MI 0.000621371192 // m -> mi
|
||||
#define M2NMI 0.000539956803 // m -> nmi
|
||||
#define M2FT 3.280839900000 // m -> ft
|
||||
#define MS2KMH 3.600000000000 // m/s -> km/h
|
||||
#define MS2MIH 2.236936290000 // m/s -> mi/h
|
||||
#define MS2KN 1.943844490000 // m/s -> kn
|
||||
#define MS2FTMIN 196.8503937008 // m/s -> ft/min
|
||||
#define MS2MMIN 60.00000000000 // m/s -> m/min
|
||||
#define FT2MI 0.000189393939 // ft -> mi
|
||||
#define MM2IN 0.039370100000 // mm -> in
|
||||
#define MM2CM 0.100000000000 // mm -> cm
|
||||
#define H2S 0.000277777778 // h -> s
|
||||
#define MIN2S 0.016666666667 // min -> s
|
||||
|
||||
#define KMINM 1000.0 // 1 km in m
|
||||
#define MIINFT 5280.0 // 1 mi in ft
|
||||
#define NMIINFT 6076.11549 // 1 nm in ft
|
||||
#define MIINM 1609.344 // 1 mi in m
|
||||
#define NMIINM 1852.0 // 1 nmi in m
|
||||
#define MININS 60.0 // 1 min in s
|
||||
#define HINS 3600.0 // 1 hins
|
||||
#define KMINM 1000.0 // 1 km in m
|
||||
#define MIINFT 5280.0 // 1 mi in ft
|
||||
#define NMIINFT 6076.11549 // 1 nm in ft
|
||||
#define MIINM 1609.344 // 1 mi in m
|
||||
#define NMIINM 1852.0 // 1 nmi in m
|
||||
#define MININS 60.0 // 1 min in s
|
||||
#define HINS 3600.0 // 1 hins
|
||||
|
||||
#define C2FS 1.8 // Celsius to Farenheit - scale
|
||||
#define C2FO 32.0 // Celsius to Farenheit - offset
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <QApplication>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QLineF>
|
||||
#include "gpxparser.h"
|
||||
#include "tcxparser.h"
|
||||
#include "csvparser.h"
|
||||
@ -20,6 +19,7 @@
|
||||
#include "ov2parser.h"
|
||||
#include "itnparser.h"
|
||||
#include "onmoveparsers.h"
|
||||
#include "twonavparser.h"
|
||||
#include "data.h"
|
||||
|
||||
|
||||
@ -44,10 +44,11 @@ static OV2Parser ov2;
|
||||
static ITNParser itn;
|
||||
static OMDParser omd;
|
||||
static GHPParser ghp;
|
||||
static TwoNavParser twonav;
|
||||
|
||||
static QMap<QString, Parser*> parsers()
|
||||
static QMultiMap<QString, Parser*> parsers()
|
||||
{
|
||||
QMap<QString, Parser*> map;
|
||||
QMultiMap<QString, Parser*> map;
|
||||
|
||||
map.insert("gpx", &gpx);
|
||||
map.insert("tcx", &tcx);
|
||||
@ -72,11 +73,14 @@ static QMap<QString, Parser*> parsers()
|
||||
map.insert("itn", &itn);
|
||||
map.insert("omd", &omd);
|
||||
map.insert("ghp", &ghp);
|
||||
map.insert("trk", &twonav);
|
||||
map.insert("rte", &twonav);
|
||||
map.insert("wpt", &twonav);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
QMap<QString, Parser*> Data::_parsers = parsers();
|
||||
QMultiMap<QString, Parser*> Data::_parsers = parsers();
|
||||
|
||||
void Data::processData(QList<TrackData> &trackData, QList<RouteData> &routeData)
|
||||
{
|
||||
@ -101,16 +105,21 @@ Data::Data(const QString &fileName, bool tryUnknown)
|
||||
return;
|
||||
}
|
||||
|
||||
QMap<QString, Parser*>::iterator it;
|
||||
if ((it = _parsers.find(fi.suffix().toLower())) != _parsers.end()) {
|
||||
if (it.value()->parse(&file, trackData, routeData, _polygons,
|
||||
_waypoints)) {
|
||||
processData(trackData, routeData);
|
||||
_valid = true;
|
||||
return;
|
||||
} else {
|
||||
_errorLine = it.value()->errorLine();
|
||||
_errorString = it.value()->errorString();
|
||||
QMultiMap<QString, Parser*>::iterator it;
|
||||
QString suffix(fi.suffix().toLower());
|
||||
if ((it = _parsers.find(suffix)) != _parsers.end()) {
|
||||
while (it != _parsers.end() && it.key() == suffix) {
|
||||
if (it.value()->parse(&file, trackData, routeData, _polygons,
|
||||
_waypoints)) {
|
||||
processData(trackData, routeData);
|
||||
_valid = true;
|
||||
return;
|
||||
} else {
|
||||
_errorLine = it.value()->errorLine();
|
||||
_errorString = it.value()->errorString();
|
||||
}
|
||||
file.reset();
|
||||
++it;
|
||||
}
|
||||
} else if (tryUnknown) {
|
||||
for (it = _parsers.begin(); it != _parsers.end(); it++) {
|
||||
@ -155,16 +164,21 @@ QString Data::formats()
|
||||
+ qApp->translate("Data", "SLF files") + " (*.slf);;"
|
||||
+ qApp->translate("Data", "SML files") + " (*.sml);;"
|
||||
+ qApp->translate("Data", "TCX files") + " (*.tcx);;"
|
||||
+ qApp->translate("Data", "TwoNav files") + " (*.rte *.trk *.wpt);;"
|
||||
+ qApp->translate("Data", "All files") + " (*)";
|
||||
}
|
||||
|
||||
QStringList Data::filter()
|
||||
{
|
||||
QStringList filter;
|
||||
QString last;
|
||||
|
||||
for (QMap<QString, Parser*>::iterator it = _parsers.begin();
|
||||
it != _parsers.end(); it++)
|
||||
filter << "*." + it.key();
|
||||
for (QMultiMap<QString, Parser*>::iterator it = _parsers.begin();
|
||||
it != _parsers.end(); it++) {
|
||||
if (it.key() != last)
|
||||
filter << "*." + it.key();
|
||||
last = it.key();
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define DATA_H
|
||||
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QMultiMap>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include "waypoint.h"
|
||||
@ -39,7 +39,7 @@ private:
|
||||
QList<Area> _polygons;
|
||||
QVector<Waypoint> _waypoints;
|
||||
|
||||
static QMap<QString, Parser*> _parsers;
|
||||
static QMultiMap<QString, Parser*> _parsers;
|
||||
};
|
||||
|
||||
#endif // DATA_H
|
||||
|
@ -223,6 +223,22 @@ bool FITParser::readField(CTX &ctx, Field *field, QVariant &val, bool &valid)
|
||||
case 0: // enum
|
||||
VAL(quint8, 0xffU);
|
||||
break;
|
||||
case 3:
|
||||
case 0x83: // sint16
|
||||
VAL(qint16, 0x7fffU);
|
||||
break;
|
||||
case 4:
|
||||
case 0x84: // uint16
|
||||
VAL(quint16, 0xffffU);
|
||||
break;
|
||||
case 5:
|
||||
case 0x85: // sint32
|
||||
VAL(qint32, 0x7fffffffU);
|
||||
break;
|
||||
case 6:
|
||||
case 0x86: // uint32
|
||||
VAL(quint32, 0xffffffffU);
|
||||
break;
|
||||
case 7: // UTF8 nul terminated string
|
||||
{QByteArray ba(ctx.file->read(field->size));
|
||||
ctx.len -= field->size;
|
||||
@ -230,18 +246,6 @@ bool FITParser::readField(CTX &ctx, Field *field, QVariant &val, bool &valid)
|
||||
val = ret ? ba : QString();
|
||||
valid = !ba.isEmpty();}
|
||||
break;
|
||||
case 0x83: // sint16
|
||||
VAL(qint16, 0x7fffU);
|
||||
break;
|
||||
case 0x84: // uint16
|
||||
VAL(quint16, 0xffffU);
|
||||
break;
|
||||
case 0x85: // sint32
|
||||
VAL(qint32, 0x7fffffffU);
|
||||
break;
|
||||
case 0x86: // uint32
|
||||
VAL(quint32, 0xffffffffU);
|
||||
break;
|
||||
default:
|
||||
ret = skipValue(ctx, field->size);
|
||||
valid = false;
|
||||
|
223
src/data/twonavparser.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
#include "common/textcodec.h"
|
||||
#include "map/gcs.h"
|
||||
#include "twonavparser.h"
|
||||
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
#define SKIP_EMPTY QString::SkipEmptyParts
|
||||
#else // Qt 5.14
|
||||
#define SKIP_EMPTY Qt::SkipEmptyParts
|
||||
#endif
|
||||
|
||||
static double lon(const QString &str)
|
||||
{
|
||||
QStringList l(str.split(QChar(0xBA)));
|
||||
if (l.size() < 2)
|
||||
return NAN;
|
||||
|
||||
bool ok;
|
||||
double val = l.at(0).toDouble(&ok);
|
||||
if (!ok)
|
||||
return NAN;
|
||||
|
||||
if (l.at(1) == "W")
|
||||
return -val;
|
||||
else if (l.at(1) == "E")
|
||||
return val;
|
||||
else
|
||||
return NAN;
|
||||
}
|
||||
|
||||
static double lat(const QString &str)
|
||||
{
|
||||
QStringList l(str.split(QChar(0xBA)));
|
||||
if (l.size() < 2)
|
||||
return NAN;
|
||||
|
||||
bool ok;
|
||||
double val = l.at(0).toDouble(&ok);
|
||||
if (!ok)
|
||||
return NAN;
|
||||
|
||||
if (l.at(1) == "S")
|
||||
return -val;
|
||||
else if (l.at(1) == "N")
|
||||
return val;
|
||||
else
|
||||
return NAN;
|
||||
}
|
||||
|
||||
static QDateTime timestamp(const QString &dateStr, const QString &timeStr)
|
||||
{
|
||||
QLocale l("C");
|
||||
|
||||
QDate date(l.toDate(dateStr, "dd-MMM-yy"));
|
||||
if (date.isValid())
|
||||
date = date.addYears(100);
|
||||
else {
|
||||
date = l.toDate(dateStr, "dd-MMM-yyyy");
|
||||
if (!date.isValid())
|
||||
return QDateTime();
|
||||
}
|
||||
|
||||
QTime time(l.toTime(timeStr, "H:m:s.z"));
|
||||
if (!time.isValid()) {
|
||||
time = l.toTime(timeStr, "H:m:s");
|
||||
if (!time.isValid())
|
||||
return QDateTime();
|
||||
}
|
||||
|
||||
return QDateTime(date, time);
|
||||
}
|
||||
|
||||
bool TwoNavParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
QList<RouteData> &routes, QList<Area> &polygons,
|
||||
QVector<Waypoint> &waypoints)
|
||||
{
|
||||
Q_UNUSED(polygons);
|
||||
TextCodec codec;
|
||||
GCS gcs;
|
||||
bool ok, route = false, track = false, waypoint = false;
|
||||
|
||||
_errorLine = 1;
|
||||
_errorString.clear();
|
||||
|
||||
quint8 bom[3];
|
||||
if (file->peek((char*)bom, sizeof(bom)) == sizeof(bom)
|
||||
&& bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) {
|
||||
file->seek(3);
|
||||
codec = TextCodec(65001);
|
||||
}
|
||||
|
||||
while (!file->atEnd()) {
|
||||
QByteArray line(file->readLine().trimmed());
|
||||
if (!line.size())
|
||||
continue;
|
||||
|
||||
switch (line.at(0)) {
|
||||
case 'B':
|
||||
{line.remove(0, 1);
|
||||
QByteArray encoding(line.trimmed());
|
||||
if (encoding == "UTF-8")
|
||||
codec = TextCodec(65001);
|
||||
else {
|
||||
_errorString = "Invalid/unknown encoding";
|
||||
return false;
|
||||
}}
|
||||
break;
|
||||
case 'G':
|
||||
{line.remove(0, 1);
|
||||
QString datum(line.trimmed());
|
||||
gcs = GCS::gcs(datum);
|
||||
if (gcs.isNull()) {
|
||||
_errorString = "Invalid/unknown datum";
|
||||
return false;
|
||||
}}
|
||||
break;
|
||||
case 'U':
|
||||
{line.remove(0, 1);
|
||||
QByteArray cs(line.trimmed());
|
||||
if (cs != "1") {
|
||||
_errorString = "Invalid/unknown coordinate system";
|
||||
return false;
|
||||
}}
|
||||
break;
|
||||
case 'T':
|
||||
{QStringList list(codec.toString(line).split(' ', SKIP_EMPTY));
|
||||
if (list.size() < 4) {
|
||||
_errorString = "Parse error";
|
||||
return false;
|
||||
}
|
||||
Coordinates c(lon(list.at(3)), lat(list.at(2)));
|
||||
if (!c.isValid()) {
|
||||
_errorString = "Invalid coordinates";
|
||||
return false;
|
||||
}
|
||||
|
||||
Trackpoint t(gcs.toWGS84(c));
|
||||
|
||||
if (list.size() > 5) {
|
||||
QDateTime ts(timestamp(list.at(4), list.at(5)));
|
||||
if (ts.isValid())
|
||||
t.setTimestamp(ts);
|
||||
}
|
||||
if (list.size() > 7) {
|
||||
qreal elevation = list.at(7).toDouble(&ok);
|
||||
if (!ok) {
|
||||
_errorString = "Invalid altitude";
|
||||
return false;
|
||||
}
|
||||
t.setElevation(elevation);
|
||||
}
|
||||
|
||||
if (!track) {
|
||||
tracks.append(TrackData());
|
||||
tracks.last().append(SegmentData());
|
||||
track = true;
|
||||
}
|
||||
|
||||
tracks.last().last().append(t);}
|
||||
break;
|
||||
case 'W':
|
||||
{QStringList list(codec.toString(line).split(' ', SKIP_EMPTY));
|
||||
if (list.size() < 5) {
|
||||
_errorString = "Parse error";
|
||||
return false;
|
||||
}
|
||||
Coordinates c(lon(list.at(4)), lat(list.at(3)));
|
||||
if (!c.isValid()) {
|
||||
_errorString = "Invalid coordinates";
|
||||
return false;
|
||||
}
|
||||
|
||||
Waypoint w(gcs.toWGS84(c));
|
||||
QString name(list.at(1));
|
||||
w.setName(name.replace('_', ' ').trimmed());
|
||||
|
||||
if (list.size() > 6) {
|
||||
QDateTime ts(timestamp(list.at(5), list.at(6)));
|
||||
if (ts.isValid())
|
||||
w.setTimestamp(ts);
|
||||
}
|
||||
if (list.size() > 7) {
|
||||
qreal elevation = list.at(7).toDouble(&ok);
|
||||
if (!ok) {
|
||||
_errorString = "Invalid altitude";
|
||||
return false;
|
||||
}
|
||||
w.setElevation(elevation);
|
||||
}
|
||||
if (list.size() > 8)
|
||||
w.setDescription(list.mid(8).join(' '));
|
||||
|
||||
if (route)
|
||||
routes.last().append(w);
|
||||
else {
|
||||
waypoints.append(w);
|
||||
waypoint = true;
|
||||
}}
|
||||
break;
|
||||
case 'w':
|
||||
{line.remove(0, 1);
|
||||
QStringList list(codec.toString(line).split(','));
|
||||
if (list.size() && waypoints.size())
|
||||
waypoints.last().setSymbol(list.at(0).trimmed());}
|
||||
break;
|
||||
case 'R':
|
||||
{QStringList list(codec.toString(line).split(','));
|
||||
routes.append(RouteData());
|
||||
if (list.size() > 1)
|
||||
routes.last().setName(list.at(1));
|
||||
route = true;}
|
||||
break;
|
||||
}
|
||||
|
||||
_errorLine++;
|
||||
}
|
||||
|
||||
if (!(waypoint | route | track)) {
|
||||
_errorString = "No valid data found";
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
21
src/data/twonavparser.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef TWONAVPARSER_H
|
||||
#define TWONAVPARSER_H
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
class TwoNavParser : public Parser
|
||||
{
|
||||
public:
|
||||
TwoNavParser() : _errorLine(0) {}
|
||||
|
||||
bool parse(QFile *file, QList<TrackData> &tracks, QList<RouteData> &routes,
|
||||
QList<Area> &polygons, QVector<Waypoint> &waypoints);
|
||||
QString errorString() const {return _errorString;}
|
||||
int errorLine() const {return _errorLine;}
|
||||
|
||||
private:
|
||||
QString _errorString;
|
||||
int _errorLine;
|
||||
};
|
||||
|
||||
#endif // TWONAVPARSER_H
|
@ -27,6 +27,9 @@ QPair<qreal, qreal> Waypoint::elevations() const
|
||||
|
||||
void Waypoint::loadSymbolIcons(const QString &dir)
|
||||
{
|
||||
if (dir.isEmpty())
|
||||
return;
|
||||
|
||||
QDir d(dir);
|
||||
QFileInfoList files(d.entryInfoList(QDir::Files | QDir::Readable));
|
||||
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
|
||||
_data.resize(1U<<subFile->blockBits());
|
||||
_file.setFileName(subFile->fileName());
|
||||
_file.open(QIODevice::ReadOnly);
|
||||
_file.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -40,7 +40,7 @@ void TextPointItem::setPos(const QPoint &point, bool padding)
|
||||
QPainterPath shape;
|
||||
QRect iconRect;
|
||||
|
||||
if (_img) {
|
||||
if (_img && !_img->isNull()) {
|
||||
QSize s(_img->size() / _img->devicePixelRatioF());
|
||||
int xOffset = padding ? s.width() : s.width() / 2;
|
||||
iconRect = QRect(QPoint(point.x() - xOffset, point.y()
|
||||
@ -57,7 +57,7 @@ void TextPointItem::setPos(const QPoint &point, bool padding)
|
||||
|
||||
void TextPointItem::paint(QPainter *painter) const
|
||||
{
|
||||
if (_img) {
|
||||
if (_img && !_img->isNull()) {
|
||||
QSize s(_img->size() / _img->devicePixelRatioF());
|
||||
painter->drawImage(QPoint(_rect.left(), _rect.center().y()
|
||||
- s.height()/2), *_img);
|
||||
|