mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-07-08 00:04:27 +02:00
Compare commits
96 Commits
Author | SHA1 | Date | |
---|---|---|---|
a24d55025f | |||
04ddcecb70 | |||
dc9a600a6e | |||
c365de130b | |||
d3558198ca | |||
acc69f5c3d | |||
7a900f2252 | |||
dad76a4e89 | |||
e28e69b248 | |||
7fffd6a161 | |||
c4fd82e5a0 | |||
fa08c0dbea | |||
070eff2115 | |||
20a4870904 | |||
1bb9908936 | |||
36555b3140 | |||
6564fb36ab | |||
1a3356b8fe | |||
7ad64922c9 | |||
64a8ec1b84 | |||
0a75298b2b | |||
99be5699af | |||
cdb641b204 | |||
f57bd48840 | |||
c2abf2c146 | |||
a5a2070ccc | |||
ed7cb1beb1 | |||
37d832bc7f | |||
c322bf9f68 | |||
2705ffbbfe | |||
e8962dd50f | |||
b37e32d622 | |||
2b1d0d2189 | |||
33e3471ca3 | |||
bf55f1e07d | |||
37a0eec48f | |||
fcaacb4b6a | |||
f9c593e6d1 | |||
37e07accd4 | |||
a7117361be | |||
548c03d543 | |||
1addb1118d | |||
ae64ef9d83 | |||
3d16cf2500 | |||
609ac0c57a | |||
a70c6f0f24 | |||
3ad0c89511 | |||
1497d42bd5 | |||
a4906e7d01 | |||
f56dfd95e3 | |||
2bda7ba714 | |||
940bd0511e | |||
30518cebc0 | |||
696bc50ba1 | |||
b91358a6bd | |||
94eab9fba0 | |||
44b98754d7 | |||
8451178808 | |||
7eedcc083e | |||
cd32b21aca | |||
e1bda86b35 | |||
967e307be9 | |||
7cf1e3e1a5 | |||
0f44feebb1 | |||
ecb82952f6 | |||
ab6ea84255 | |||
0b2d610a34 | |||
f67eaa8dec | |||
2a619aa0ef | |||
dd292bc995 | |||
680104fec3 | |||
b72a9e67fe | |||
24b7b9d996 | |||
7965f2ff34 | |||
5f5b391cd9 | |||
faed6fc203 | |||
38b62c0121 | |||
f26f8a95ac | |||
1297db26f6 | |||
2ee955172d | |||
a11b926a98 | |||
70b5371a6e | |||
d07b6c6a9d | |||
c9a62e8b61 | |||
aa3579c0be | |||
297177ad41 | |||
0e9720f68b | |||
c1f36e5fbb | |||
a20fd3e474 | |||
aba78f3baa | |||
2f24bb5462 | |||
c1fdb21fad | |||
6bea3b7ebf | |||
a7efa80e8f | |||
4e9faf3a23 | |||
d4e153d10f |
@ -1,4 +1,4 @@
|
|||||||
version: 7.10.{build}
|
version: 7.15.{build}
|
||||||
configuration: Release
|
configuration: Release
|
||||||
platform: Any CPU
|
platform: Any CPU
|
||||||
environment:
|
environment:
|
||||||
|
@ -9,7 +9,7 @@ before_install:
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install qt; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install qt; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libqt4-dev; fi
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libqt4-dev libqt4-opengl-dev; fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then PATH=/usr/local/opt/qt/bin/:${PATH}; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then PATH=/usr/local/opt/qt/bin/:${PATH}; fi
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
GPXSee is a Qt-based GPS log file viewer and analyzer that supports all common GPS log file formats.
|
GPXSee is a Qt-based GPS log file viewer and analyzer that supports all common GPS log file formats.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* Opens GPX, TCX, FIT, KML, IGC, NMEA, SLF, LOC, GeoJSON, OziExplorer (PLT, RTE, WPT), Garmin CSV and geotagged JPEG files.
|
* Opens GPX, TCX, FIT, KML, NMEA, IGC, CUP, SLF, LOC, GeoJSON, OziExplorer (PLT, RTE, WPT), Garmin CSV and geotagged JPEG files.
|
||||||
* User-definable online maps (OpenStreetMap/Google tiles, WMTS, WMS, TMS, QuadTiles).
|
* User-definable online maps (OpenStreetMap/Google tiles, WMTS, WMS, TMS, QuadTiles).
|
||||||
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases, Garmin IMG & JNX maps, TwoNav RMaps, GeoTIFF images).
|
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases, Garmin IMG & JNX maps, TwoNav RMaps, GeoTIFF images).
|
||||||
* Elevation, speed, heart rate, cadence, power, temperature and gear ratio/shifts graphs.
|
* Elevation, speed, heart rate, cadence, power, temperature and gear ratio/shifts graphs.
|
||||||
|
19
gpxsee.pro
19
gpxsee.pro
@ -3,7 +3,7 @@ unix:!macx {
|
|||||||
} else {
|
} else {
|
||||||
TARGET = GPXSee
|
TARGET = GPXSee
|
||||||
}
|
}
|
||||||
VERSION = 7.10
|
VERSION = 7.15
|
||||||
|
|
||||||
QT += core \
|
QT += core \
|
||||||
gui \
|
gui \
|
||||||
@ -181,7 +181,9 @@ HEADERS += src/common/config.h \
|
|||||||
src/GUI/limitedcombobox.h \
|
src/GUI/limitedcombobox.h \
|
||||||
src/GUI/pathtickitem.h \
|
src/GUI/pathtickitem.h \
|
||||||
src/map/IMG/textitem.h \
|
src/map/IMG/textitem.h \
|
||||||
src/map/IMG/label.h
|
src/map/IMG/label.h \
|
||||||
|
src/data/csv.h \
|
||||||
|
src/data/cupparser.h
|
||||||
SOURCES += src/main.cpp \
|
SOURCES += src/main.cpp \
|
||||||
src/common/coordinates.cpp \
|
src/common/coordinates.cpp \
|
||||||
src/common/rectc.cpp \
|
src/common/rectc.cpp \
|
||||||
@ -312,14 +314,17 @@ SOURCES += src/main.cpp \
|
|||||||
src/map/IMG/style.cpp \
|
src/map/IMG/style.cpp \
|
||||||
src/map/IMG/netfile.cpp \
|
src/map/IMG/netfile.cpp \
|
||||||
src/GUI/pathtickitem.cpp \
|
src/GUI/pathtickitem.cpp \
|
||||||
src/map/IMG/textitem.cpp
|
src/map/IMG/textitem.cpp \
|
||||||
|
src/data/csv.cpp \
|
||||||
|
src/data/cupparser.cpp
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||||
HEADERS += src/data/geojsonparser.h
|
HEADERS += src/data/geojsonparser.h
|
||||||
SOURCES += src/data/geojsonparser.cpp
|
SOURCES += src/data/geojsonparser.cpp
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
|
DEFINES += APP_VERSION=\\\"$$VERSION\\\" \
|
||||||
|
QT_NO_DEPRECATED_WARNINGS
|
||||||
DEFINES *= QT_USE_QSTRINGBUILDER
|
DEFINES *= QT_USE_QSTRINGBUILDER
|
||||||
|
|
||||||
RESOURCES += gpxsee.qrc
|
RESOURCES += gpxsee.qrc
|
||||||
@ -370,7 +375,8 @@ macx {
|
|||||||
icons/formats/wpt.icns \
|
icons/formats/wpt.icns \
|
||||||
icons/formats/loc.icns \
|
icons/formats/loc.icns \
|
||||||
icons/formats/slf.icns \
|
icons/formats/slf.icns \
|
||||||
icons/formats/json.icns
|
icons/formats/json.icns \
|
||||||
|
icons/formats/cup.icns
|
||||||
QMAKE_BUNDLE_DATA += locale maps icons csv
|
QMAKE_BUNDLE_DATA += locale maps icons csv
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +393,8 @@ win32 {
|
|||||||
icons/formats/wpt.ico \
|
icons/formats/wpt.ico \
|
||||||
icons/formats/loc.ico \
|
icons/formats/loc.ico \
|
||||||
icons/formats/slf.ico \
|
icons/formats/slf.ico \
|
||||||
icons/formats/json.ico
|
icons/formats/json.ico \
|
||||||
|
icons/formats/cup.ico
|
||||||
DEFINES += _USE_MATH_DEFINES \
|
DEFINES += _USE_MATH_DEFINES \
|
||||||
NOGDI
|
NOGDI
|
||||||
}
|
}
|
||||||
|
BIN
icons/formats/cup.icns
Normal file
BIN
icons/formats/cup.icns
Normal file
Binary file not shown.
BIN
icons/formats/cup.ico
Normal file
BIN
icons/formats/cup.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 304 KiB |
@ -10,3 +10,4 @@ tcx:#ffcc00
|
|||||||
wpt:#66ff00
|
wpt:#66ff00
|
||||||
loc:#556677
|
loc:#556677
|
||||||
slf:#881199
|
slf:#881199
|
||||||
|
cup:#20a810
|
||||||
|
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
1456
lang/gpxsee_en.ts
1456
lang/gpxsee_en.ts
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
1860
lang/gpxsee_pt_PT.ts
Normal file
1860
lang/gpxsee_pt_PT.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
@ -211,6 +211,22 @@
|
|||||||
<key>CFBundleTypeRole</key>
|
<key>CFBundleTypeRole</key>
|
||||||
<string>Viewer</string>
|
<string>Viewer</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleTypeExtensions</key>
|
||||||
|
<array>
|
||||||
|
<string>cup</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleTypeMIMETypes</key>
|
||||||
|
<array>
|
||||||
|
<string>application/vnd.naviter.seeyou.cup</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleTypeIconFile</key>
|
||||||
|
<string>icons/cup.icns</string>
|
||||||
|
<key>CFBundleTypeName</key>
|
||||||
|
<string>SeeYou CUP File</string>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>Viewer</string>
|
||||||
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
|
|
||||||
<key>UTImportedTypeDeclarations</key>
|
<key>UTImportedTypeDeclarations</key>
|
||||||
@ -467,6 +483,27 @@
|
|||||||
<string>application/geo+json</string>
|
<string>application/geo+json</string>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>com.naviter.seeyou.cup</string>
|
||||||
|
<key>UTTypeReferenceURL</key>
|
||||||
|
<string>http://www.naviter.com</string>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>SeeYou CUP File</string>
|
||||||
|
<key>UTTypeConformsTo</key>
|
||||||
|
<array>
|
||||||
|
<string>public.data</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeTagSpecification</key>
|
||||||
|
<dict>
|
||||||
|
<key>public.filename-extension</key>
|
||||||
|
<array>
|
||||||
|
<string>cup</string>
|
||||||
|
</array>
|
||||||
|
<key>public.mime-type</key>
|
||||||
|
<string>application/vnd.naviter.seeyou.cup</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
<p>Features:</p>
|
<p>Features:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Opens GPX, TCX, FIT, KML, IGC, NMEA, SLF, LOC, OziExplorer (PLT,
|
<li>Opens GPX, TCX, FIT, KML, IGC, NMEA, SLF, LOC, OziExplorer (PLT,
|
||||||
WPT, RTE), GeoJSON, Garmin CSV and geotagged JPEG files.</li>
|
WPT, RTE), GeoJSON, SeeYou CUP, Garmin CSV and geotagged
|
||||||
|
JPEG files.</li>
|
||||||
<li>User-definable online maps (OpenStreetMap/Google tiles, WMTS,
|
<li>User-definable online maps (OpenStreetMap/Google tiles, WMTS,
|
||||||
WMS, TMS).</li>
|
WMS, TMS).</li>
|
||||||
<li>Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
|
<li>Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
|
||||||
@ -67,5 +68,6 @@
|
|||||||
<mimetype>application/loc+xml</mimetype>
|
<mimetype>application/loc+xml</mimetype>
|
||||||
<mimetype>application/slf+xml</mimetype>
|
<mimetype>application/slf+xml</mimetype>
|
||||||
<mimetype>application/geo+json</mimetype>
|
<mimetype>application/geo+json</mimetype>
|
||||||
|
<mimetype>application/vnd.naviter.seeyou.cup</mimetype>
|
||||||
</mimetypes>
|
</mimetypes>
|
||||||
</component>
|
</component>
|
||||||
|
@ -11,4 +11,4 @@ Icon=gpxsee
|
|||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Graphics;Viewer;Education;Geography;Maps;Sports;Qt;
|
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;
|
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;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
; The name of the installer
|
; The name of the installer
|
||||||
Name "GPXSee"
|
Name "GPXSee"
|
||||||
; Program version
|
; Program version
|
||||||
!define VERSION "7.10"
|
!define VERSION "7.15"
|
||||||
|
|
||||||
; The file to write
|
; The file to write
|
||||||
OutFile "GPXSee-${VERSION}.exe"
|
OutFile "GPXSee-${VERSION}.exe"
|
||||||
@ -106,18 +106,19 @@ Section "GPXSee" SEC_APP
|
|||||||
|
|
||||||
; Associate file formats
|
; Associate file formats
|
||||||
DetailPrint "Associating file types..."
|
DetailPrint "Associating file types..."
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 5
|
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 6
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 6
|
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 7
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 7
|
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 8
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 8
|
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 9
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 9
|
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 10
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 data" 10
|
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 data" 11
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 11
|
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 12
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 12
|
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 13
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "wpt" "OziExplorer Waypoint File" 1
|
!insertmacro FILE_ASSOCIATION_ADD "wpt" "OziExplorer Waypoint File" 1
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "loc" "Geocaching.com Waypoint File" 2
|
!insertmacro FILE_ASSOCIATION_ADD "loc" "Geocaching.com Waypoint File" 2
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "slf" "Sigma Log File" 3
|
!insertmacro FILE_ASSOCIATION_ADD "slf" "Sigma Log File" 3
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "geojson" "GeoJSON" 4
|
!insertmacro FILE_ASSOCIATION_ADD "geojson" "GeoJSON" 4
|
||||||
|
!insertmacro FILE_ASSOCIATION_ADD "cup" "SeeYou CUP file" 5
|
||||||
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
||||||
|
|
||||||
SectionEnd
|
SectionEnd
|
||||||
@ -227,6 +228,7 @@ Section "Uninstall"
|
|||||||
!insertmacro FILE_ASSOCIATION_REMOVE "loc"
|
!insertmacro FILE_ASSOCIATION_REMOVE "loc"
|
||||||
!insertmacro FILE_ASSOCIATION_REMOVE "slf"
|
!insertmacro FILE_ASSOCIATION_REMOVE "slf"
|
||||||
!insertmacro FILE_ASSOCIATION_REMOVE "geojson"
|
!insertmacro FILE_ASSOCIATION_REMOVE "geojson"
|
||||||
|
!insertmacro FILE_ASSOCIATION_REMOVE "cup"
|
||||||
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
||||||
|
|
||||||
SectionEnd
|
SectionEnd
|
||||||
@ -257,4 +259,4 @@ LangString DESC_LOCALIZATION ${LANG_ENGLISH} \
|
|||||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_MSVC} $(DESC_MSVC)
|
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_MSVC} $(DESC_MSVC)
|
||||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_APP} $(DESC_APP)
|
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_APP} $(DESC_APP)
|
||||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_LOCALIZATION} $(DESC_LOCALIZATION)
|
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_LOCALIZATION} $(DESC_LOCALIZATION)
|
||||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
@ -84,4 +84,11 @@
|
|||||||
<generic-icon name="text-plain"/>
|
<generic-icon name="text-plain"/>
|
||||||
<glob pattern="*.geojson"/>
|
<glob pattern="*.geojson"/>
|
||||||
</mime-type>
|
</mime-type>
|
||||||
|
|
||||||
|
<mime-type type="application/vnd.naviter.seeyou.cup">
|
||||||
|
<comment>SeeYou CUP File</comment>
|
||||||
|
<sub-class-of type="text/plain"/>
|
||||||
|
<generic-icon name="text-plain"/>
|
||||||
|
<glob pattern="*.cup"/>
|
||||||
|
</mime-type>
|
||||||
</mime-info>
|
</mime-info>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
; The name of the installer
|
; The name of the installer
|
||||||
Name "GPXSee"
|
Name "GPXSee"
|
||||||
; Program version
|
; Program version
|
||||||
!define VERSION "7.10"
|
!define VERSION "7.15"
|
||||||
|
|
||||||
; The file to write
|
; The file to write
|
||||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||||
@ -113,18 +113,19 @@ Section "GPXSee" SEC_APP
|
|||||||
|
|
||||||
; Associate file formats
|
; Associate file formats
|
||||||
DetailPrint "Associating file types..."
|
DetailPrint "Associating file types..."
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 5
|
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 6
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 6
|
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 7
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 7
|
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 8
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 8
|
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 9
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 9
|
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 10
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 data" 10
|
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 data" 11
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 11
|
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 12
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 12
|
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 13
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "wpt" "OziExplorer Waypoint File" 1
|
!insertmacro FILE_ASSOCIATION_ADD "wpt" "OziExplorer Waypoint File" 1
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "loc" "Geocaching.com Waypoint File" 2
|
!insertmacro FILE_ASSOCIATION_ADD "loc" "Geocaching.com Waypoint File" 2
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "slf" "Sigma Log File" 3
|
!insertmacro FILE_ASSOCIATION_ADD "slf" "Sigma Log File" 3
|
||||||
!insertmacro FILE_ASSOCIATION_ADD "geojson" "GeoJSON" 4
|
!insertmacro FILE_ASSOCIATION_ADD "geojson" "GeoJSON" 4
|
||||||
|
!insertmacro FILE_ASSOCIATION_ADD "cup" "SeeYou CUP file" 5
|
||||||
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
||||||
|
|
||||||
SectionEnd
|
SectionEnd
|
||||||
@ -230,6 +231,7 @@ Section "Uninstall"
|
|||||||
!insertmacro FILE_ASSOCIATION_REMOVE "loc"
|
!insertmacro FILE_ASSOCIATION_REMOVE "loc"
|
||||||
!insertmacro FILE_ASSOCIATION_REMOVE "slf"
|
!insertmacro FILE_ASSOCIATION_REMOVE "slf"
|
||||||
!insertmacro FILE_ASSOCIATION_REMOVE "geojson"
|
!insertmacro FILE_ASSOCIATION_REMOVE "geojson"
|
||||||
|
!insertmacro FILE_ASSOCIATION_REMOVE "cup"
|
||||||
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
||||||
|
|
||||||
SectionEnd
|
SectionEnd
|
||||||
@ -260,4 +262,4 @@ LangString DESC_LOCALIZATION ${LANG_ENGLISH} \
|
|||||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_MSVC} $(DESC_MSVC)
|
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_MSVC} $(DESC_MSVC)
|
||||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_APP} $(DESC_APP)
|
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_APP} $(DESC_APP)
|
||||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_LOCALIZATION} $(DESC_LOCALIZATION)
|
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_LOCALIZATION} $(DESC_LOCALIZATION)
|
||||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
@ -153,3 +153,21 @@ void AreaItem::setDigitalZoom(int zoom)
|
|||||||
_digitalZoom = zoom;
|
_digitalZoom = zoom;
|
||||||
_pen.setWidthF(_width * pow(2, -_digitalZoom));
|
_pen.setWidthF(_width * pow(2, -_digitalZoom));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AreaItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event);
|
||||||
|
|
||||||
|
_pen.setWidthF((_width + 1) * pow(2, -_digitalZoom));
|
||||||
|
setZValue(zValue() + 1.0);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AreaItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event);
|
||||||
|
|
||||||
|
_pen.setWidthF(_width * pow(2, -_digitalZoom));
|
||||||
|
setZValue(zValue() - 1.0);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
@ -27,6 +27,9 @@ public:
|
|||||||
void setDigitalZoom(int zoom);
|
void setDigitalZoom(int zoom);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
||||||
|
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
||||||
|
|
||||||
QPainterPath painterPath(const Polygon &polygon);
|
QPainterPath painterPath(const Polygon &polygon);
|
||||||
void updatePainterPath();
|
void updatePainterPath();
|
||||||
QString toolTip() const;
|
QString toolTip() const;
|
||||||
|
@ -30,7 +30,7 @@ private:
|
|||||||
Ticks::Ticks(double minValue, double maxValue, int maxCount)
|
Ticks::Ticks(double minValue, double maxValue, int maxCount)
|
||||||
{
|
{
|
||||||
double range = niceNum(maxValue - minValue, false);
|
double range = niceNum(maxValue - minValue, false);
|
||||||
_d = niceNum(range / maxCount, true);
|
_d = niceNum(range / maxCount, false);
|
||||||
_min = ceil(minValue / _d) * _d;
|
_min = ceil(minValue / _d) * _d;
|
||||||
_max = floor(maxValue / _d) * _d;
|
_max = floor(maxValue / _d) * _d;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,11 @@ CadenceGraph::CadenceGraph(QWidget *parent) : GraphTab(parent)
|
|||||||
setSliderPrecision(1);
|
setSliderPrecision(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CadenceGraph::~CadenceGraph()
|
||||||
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
}
|
||||||
|
|
||||||
void CadenceGraph::setInfo()
|
void CadenceGraph::setInfo()
|
||||||
{
|
{
|
||||||
if (_showTracks) {
|
if (_showTracks) {
|
||||||
@ -36,23 +41,28 @@ QList<GraphItem*> CadenceGraph::loadData(const Data &data)
|
|||||||
const Graph &graph = track.cadence();
|
const Graph &graph = track.cadence();
|
||||||
|
|
||||||
if (!graph.isValid()) {
|
if (!graph.isValid()) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
} else {
|
} else {
|
||||||
CadenceGraphItem *gi = new CadenceGraphItem(graph, _graphType);
|
CadenceGraphItem *gi = new CadenceGraphItem(graph, _graphType,
|
||||||
GraphView::addGraph(gi);
|
_width, _palette.nextColor());
|
||||||
|
|
||||||
|
_tracks.append(gi);
|
||||||
|
if (_showTracks)
|
||||||
|
addGraph(gi);
|
||||||
|
|
||||||
_avg.append(QPointF(track.distance(), gi->avg()));
|
_avg.append(QPointF(track.distance(), gi->avg()));
|
||||||
graphs.append(gi);
|
graphs.append(gi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.routes().count(); i++) {
|
for (int i = 0; i < data.routes().count(); i++) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.areas().count(); i++)
|
for (int i = 0; i < data.areas().count(); i++)
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
redraw();
|
redraw();
|
||||||
@ -75,6 +85,9 @@ qreal CadenceGraph::avg() const
|
|||||||
|
|
||||||
void CadenceGraph::clear()
|
void CadenceGraph::clear()
|
||||||
{
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
_tracks.clear();
|
||||||
|
|
||||||
_avg.clear();
|
_avg.clear();
|
||||||
|
|
||||||
GraphTab::clear();
|
GraphTab::clear();
|
||||||
@ -84,7 +97,13 @@ void CadenceGraph::showTracks(bool show)
|
|||||||
{
|
{
|
||||||
_showTracks = show;
|
_showTracks = show;
|
||||||
|
|
||||||
showGraph(show);
|
for (int i = 0; i < _tracks.size(); i++) {
|
||||||
|
if (show)
|
||||||
|
addGraph(_tracks.at(i));
|
||||||
|
else
|
||||||
|
removeGraph(_tracks.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
@ -3,18 +3,20 @@
|
|||||||
|
|
||||||
#include "graphtab.h"
|
#include "graphtab.h"
|
||||||
|
|
||||||
|
class CadenceGraphItem;
|
||||||
|
|
||||||
class CadenceGraph : public GraphTab
|
class CadenceGraph : public GraphTab
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CadenceGraph(QWidget *parent = 0);
|
CadenceGraph(QWidget *parent = 0);
|
||||||
|
~CadenceGraph();
|
||||||
|
|
||||||
QString label() const {return tr("Cadence");}
|
QString label() const {return tr("Cadence");}
|
||||||
QList<GraphItem*> loadData(const Data &data);
|
QList<GraphItem*> loadData(const Data &data);
|
||||||
void clear();
|
void clear();
|
||||||
void showTracks(bool show);
|
void showTracks(bool show);
|
||||||
void showRoutes(bool show) {Q_UNUSED(show);}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qreal avg() const;
|
qreal avg() const;
|
||||||
@ -24,6 +26,7 @@ private:
|
|||||||
QVector<QPointF> _avg;
|
QVector<QPointF> _avg;
|
||||||
|
|
||||||
bool _showTracks;
|
bool _showTracks;
|
||||||
|
QList<CadenceGraphItem *> _tracks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CADENCEGRAPH_H
|
#endif // CADENCEGRAPH_H
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
|
|
||||||
CadenceGraphItem::CadenceGraphItem(const Graph &graph, GraphType type,
|
CadenceGraphItem::CadenceGraphItem(const Graph &graph, GraphType type,
|
||||||
QGraphicsItem *parent) : GraphItem(graph, type, parent)
|
int width, const QColor &color, QGraphicsItem *parent)
|
||||||
|
: GraphItem(graph, type, width, color, parent)
|
||||||
{
|
{
|
||||||
setToolTip(toolTip());
|
setToolTip(toolTip());
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ class CadenceGraphItem : public GraphItem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CadenceGraphItem(const Graph &graph, GraphType type,
|
CadenceGraphItem(const Graph &graph, GraphType type, int width,
|
||||||
QGraphicsItem *parent = 0);
|
const QColor &color, QGraphicsItem *parent = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString toolTip() const;
|
QString toolTip() const;
|
||||||
|
@ -8,26 +8,18 @@
|
|||||||
|
|
||||||
static qreal nMin(qreal a, qreal b)
|
static qreal nMin(qreal a, qreal b)
|
||||||
{
|
{
|
||||||
if (!std::isnan(a) && !std::isnan(b))
|
if (std::isnan(a))
|
||||||
return qMin(a, b);
|
return std::isnan(b) ? NAN : b;
|
||||||
else if (!std::isnan(a))
|
|
||||||
return a;
|
|
||||||
else if (!std::isnan(b))
|
|
||||||
return b;
|
|
||||||
else
|
else
|
||||||
return NAN;
|
return std::isnan(b) ? a : qMin(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal nMax(qreal a, qreal b)
|
static qreal nMax(qreal a, qreal b)
|
||||||
{
|
{
|
||||||
if (!std::isnan(a) && !std::isnan(b))
|
if (std::isnan(a))
|
||||||
return qMax(a, b);
|
return std::isnan(b) ? NAN : b;
|
||||||
else if (!std::isnan(a))
|
|
||||||
return a;
|
|
||||||
else if (!std::isnan(b))
|
|
||||||
return b;
|
|
||||||
else
|
else
|
||||||
return NAN;
|
return std::isnan(b) ? a : qMax(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElevationGraph::ElevationGraph(QWidget *parent) : GraphTab(parent)
|
ElevationGraph::ElevationGraph(QWidget *parent) : GraphTab(parent)
|
||||||
@ -49,6 +41,12 @@ ElevationGraph::ElevationGraph(QWidget *parent) : GraphTab(parent)
|
|||||||
setMinYRange(50.0);
|
setMinYRange(50.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ElevationGraph::~ElevationGraph()
|
||||||
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
qDeleteAll(_routes);
|
||||||
|
}
|
||||||
|
|
||||||
void ElevationGraph::setInfo()
|
void ElevationGraph::setInfo()
|
||||||
{
|
{
|
||||||
if (std::isnan(max()) || std::isnan(min()))
|
if (std::isnan(max()) || std::isnan(min()))
|
||||||
@ -70,19 +68,28 @@ void ElevationGraph::setInfo()
|
|||||||
GraphItem *ElevationGraph::loadGraph(const Graph &graph, Type type)
|
GraphItem *ElevationGraph::loadGraph(const Graph &graph, Type type)
|
||||||
{
|
{
|
||||||
if (!graph.isValid()) {
|
if (!graph.isValid()) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElevationGraphItem *gi = new ElevationGraphItem(graph, _graphType);
|
ElevationGraphItem *gi = new ElevationGraphItem(graph, _graphType, _width,
|
||||||
GraphView::addGraph(gi, type);
|
_palette.nextColor());
|
||||||
|
gi->setUnits(_units);
|
||||||
|
|
||||||
if (type == Track) {
|
if (type == Track) {
|
||||||
|
_tracks.append(gi);
|
||||||
|
if (_showTracks)
|
||||||
|
addGraph(gi);
|
||||||
|
|
||||||
_trackAscent += gi->ascent();
|
_trackAscent += gi->ascent();
|
||||||
_trackDescent += gi->descent();
|
_trackDescent += gi->descent();
|
||||||
_trackMax = nMax(_trackMax, gi->max());
|
_trackMax = nMax(_trackMax, gi->max());
|
||||||
_trackMin = nMin(_trackMin, gi->min());
|
_trackMin = nMin(_trackMin, gi->min());
|
||||||
} else {
|
} else {
|
||||||
|
_routes.append(gi);
|
||||||
|
if (_showRoutes)
|
||||||
|
addGraph(gi);
|
||||||
|
|
||||||
_routeAscent += gi->ascent();
|
_routeAscent += gi->ascent();
|
||||||
_routeDescent += gi->descent();
|
_routeDescent += gi->descent();
|
||||||
_routeMax = nMax(_routeMax, gi->max());
|
_routeMax = nMax(_routeMax, gi->max());
|
||||||
@ -101,7 +108,7 @@ QList<GraphItem*> ElevationGraph::loadData(const Data &data)
|
|||||||
for (int i = 0; i < data.routes().count(); i++)
|
for (int i = 0; i < data.routes().count(); i++)
|
||||||
graphs.append(loadGraph(data.routes().at(i).elevation(), Route));
|
graphs.append(loadGraph(data.routes().at(i).elevation(), Route));
|
||||||
for (int i = 0; i < data.areas().count(); i++)
|
for (int i = 0; i < data.areas().count(); i++)
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
redraw();
|
redraw();
|
||||||
@ -111,6 +118,11 @@ QList<GraphItem*> ElevationGraph::loadData(const Data &data)
|
|||||||
|
|
||||||
void ElevationGraph::clear()
|
void ElevationGraph::clear()
|
||||||
{
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
_tracks.clear();
|
||||||
|
qDeleteAll(_routes);
|
||||||
|
_routes.clear();
|
||||||
|
|
||||||
_trackAscent = 0;
|
_trackAscent = 0;
|
||||||
_routeAscent = 0;
|
_routeAscent = 0;
|
||||||
_trackDescent = 0;
|
_trackDescent = 0;
|
||||||
@ -142,12 +154,23 @@ void ElevationGraph::setUnits(Units units)
|
|||||||
GraphView::setUnits(units);
|
GraphView::setUnits(units);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElevationGraph::showItems(const QList<ElevationGraphItem *> &list,
|
||||||
|
bool show)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
if (show)
|
||||||
|
addGraph(list.at(i));
|
||||||
|
else
|
||||||
|
removeGraph(list.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ElevationGraph::showTracks(bool show)
|
void ElevationGraph::showTracks(bool show)
|
||||||
{
|
{
|
||||||
_showTracks = show;
|
_showTracks = show;
|
||||||
|
|
||||||
|
showItems(_tracks, show);
|
||||||
setInfo();
|
setInfo();
|
||||||
showGraph(show, Track);
|
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
@ -156,7 +179,7 @@ void ElevationGraph::showRoutes(bool show)
|
|||||||
{
|
{
|
||||||
_showRoutes = show;
|
_showRoutes = show;
|
||||||
|
|
||||||
showGraph(show, Route);
|
showItems(_routes, show);
|
||||||
setInfo();
|
setInfo();
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
@ -3,12 +3,15 @@
|
|||||||
|
|
||||||
#include "graphtab.h"
|
#include "graphtab.h"
|
||||||
|
|
||||||
|
class ElevationGraphItem;
|
||||||
|
|
||||||
class ElevationGraph : public GraphTab
|
class ElevationGraph : public GraphTab
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ElevationGraph(QWidget *parent = 0);
|
ElevationGraph(QWidget *parent = 0);
|
||||||
|
~ElevationGraph();
|
||||||
|
|
||||||
QString label() const {return tr("Elevation");}
|
QString label() const {return tr("Elevation");}
|
||||||
QList<GraphItem*> loadData(const Data &data);
|
QList<GraphItem*> loadData(const Data &data);
|
||||||
@ -29,6 +32,7 @@ private:
|
|||||||
void setInfo();
|
void setInfo();
|
||||||
|
|
||||||
GraphItem *loadGraph(const Graph &graph, Type type);
|
GraphItem *loadGraph(const Graph &graph, Type type);
|
||||||
|
void showItems(const QList<ElevationGraphItem *> &list, bool show);
|
||||||
|
|
||||||
qreal _trackAscent, _trackDescent;
|
qreal _trackAscent, _trackDescent;
|
||||||
qreal _routeAscent, _routeDescent;
|
qreal _routeAscent, _routeDescent;
|
||||||
@ -36,6 +40,7 @@ private:
|
|||||||
qreal _trackMin, _routeMin;
|
qreal _trackMin, _routeMin;
|
||||||
|
|
||||||
bool _showTracks, _showRoutes;
|
bool _showTracks, _showRoutes;
|
||||||
|
QList<ElevationGraphItem *> _tracks, _routes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ELEVATIONGRAPH_H
|
#endif // ELEVATIONGRAPH_H
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
|
|
||||||
ElevationGraphItem::ElevationGraphItem(const Graph &graph, GraphType type,
|
ElevationGraphItem::ElevationGraphItem(const Graph &graph, GraphType type,
|
||||||
QGraphicsItem *parent) : GraphItem(graph, type, parent)
|
int width, const QColor &color, QGraphicsItem *parent)
|
||||||
|
: GraphItem(graph, type, width, color, parent)
|
||||||
{
|
{
|
||||||
_min = GraphItem::min();
|
_min = GraphItem::min();
|
||||||
_max = GraphItem::max();
|
_max = GraphItem::max();
|
||||||
|
@ -8,8 +8,8 @@ class ElevationGraphItem : public GraphItem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ElevationGraphItem(const Graph &graph, GraphType type,
|
ElevationGraphItem(const Graph &graph, GraphType type, int width,
|
||||||
QGraphicsItem *parent = 0);
|
const QColor &color, QGraphicsItem *parent = 0);
|
||||||
|
|
||||||
qreal ascent() const {return _ascent;}
|
qreal ascent() const {return _ascent;}
|
||||||
qreal descent() const {return _descent;}
|
qreal descent() const {return _descent;}
|
||||||
|
@ -14,6 +14,11 @@ GearRatioGraph::GearRatioGraph(QWidget *parent) : GraphTab(parent)
|
|||||||
setSliderPrecision(2);
|
setSliderPrecision(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GearRatioGraph::~GearRatioGraph()
|
||||||
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
}
|
||||||
|
|
||||||
void GearRatioGraph::setInfo()
|
void GearRatioGraph::setInfo()
|
||||||
{
|
{
|
||||||
if (_showTracks) {
|
if (_showTracks) {
|
||||||
@ -37,11 +42,15 @@ QList<GraphItem*> GearRatioGraph::loadData(const Data &data)
|
|||||||
const Graph &graph = data.tracks().at(i).ratio();
|
const Graph &graph = data.tracks().at(i).ratio();
|
||||||
|
|
||||||
if (!graph.isValid()) {
|
if (!graph.isValid()) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
} else {
|
} else {
|
||||||
GearRatioGraphItem *gi = new GearRatioGraphItem(graph, _graphType);
|
GearRatioGraphItem *gi = new GearRatioGraphItem(graph, _graphType,
|
||||||
GraphView::addGraph(gi);
|
_width, _palette.nextColor());
|
||||||
|
|
||||||
|
_tracks.append(gi);
|
||||||
|
if (_showTracks)
|
||||||
|
addGraph(gi);
|
||||||
|
|
||||||
for (QMap<qreal, qreal>::const_iterator it = gi->map().constBegin();
|
for (QMap<qreal, qreal>::const_iterator it = gi->map().constBegin();
|
||||||
it != gi->map().constEnd(); ++it)
|
it != gi->map().constEnd(); ++it)
|
||||||
@ -51,12 +60,12 @@ QList<GraphItem*> GearRatioGraph::loadData(const Data &data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.routes().count(); i++) {
|
for (int i = 0; i < data.routes().count(); i++) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.areas().count(); i++)
|
for (int i = 0; i < data.areas().count(); i++)
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
redraw();
|
redraw();
|
||||||
@ -70,10 +79,7 @@ qreal GearRatioGraph::top() const
|
|||||||
|
|
||||||
for (QMap<qreal, qreal>::const_iterator it = _map.constBegin();
|
for (QMap<qreal, qreal>::const_iterator it = _map.constBegin();
|
||||||
it != _map.constEnd(); ++it) {
|
it != _map.constEnd(); ++it) {
|
||||||
if (it == _map.constBegin()) {
|
if (std::isnan(val) || it.value() > val) {
|
||||||
val = it.value();
|
|
||||||
key = it.key();
|
|
||||||
} else if (it.value() > val) {
|
|
||||||
val = it.value();
|
val = it.value();
|
||||||
key = it.key();
|
key = it.key();
|
||||||
}
|
}
|
||||||
@ -84,6 +90,9 @@ qreal GearRatioGraph::top() const
|
|||||||
|
|
||||||
void GearRatioGraph::clear()
|
void GearRatioGraph::clear()
|
||||||
{
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
_tracks.clear();
|
||||||
|
|
||||||
_map.clear();
|
_map.clear();
|
||||||
|
|
||||||
GraphTab::clear();
|
GraphTab::clear();
|
||||||
@ -93,7 +102,13 @@ void GearRatioGraph::showTracks(bool show)
|
|||||||
{
|
{
|
||||||
_showTracks = show;
|
_showTracks = show;
|
||||||
|
|
||||||
showGraph(show);
|
for (int i = 0; i < _tracks.size(); i++) {
|
||||||
|
if (show)
|
||||||
|
addGraph(_tracks.at(i));
|
||||||
|
else
|
||||||
|
removeGraph(_tracks.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
@ -4,12 +4,15 @@
|
|||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include "graphtab.h"
|
#include "graphtab.h"
|
||||||
|
|
||||||
|
class GearRatioGraphItem;
|
||||||
|
|
||||||
class GearRatioGraph : public GraphTab
|
class GearRatioGraph : public GraphTab
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GearRatioGraph(QWidget *parent = 0);
|
GearRatioGraph(QWidget *parent = 0);
|
||||||
|
~GearRatioGraph();
|
||||||
|
|
||||||
QString label() const {return tr("Gear ratio");}
|
QString label() const {return tr("Gear ratio");}
|
||||||
QList<GraphItem*> loadData(const Data &data);
|
QList<GraphItem*> loadData(const Data &data);
|
||||||
@ -25,6 +28,7 @@ private:
|
|||||||
QMap<qreal, qreal> _map;
|
QMap<qreal, qreal> _map;
|
||||||
|
|
||||||
bool _showTracks;
|
bool _showTracks;
|
||||||
|
QList<GearRatioGraphItem*> _tracks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GEARRATIOGRAPH_H
|
#endif // GEARRATIOGRAPH_H
|
||||||
|
@ -5,21 +5,27 @@
|
|||||||
|
|
||||||
|
|
||||||
GearRatioGraphItem::GearRatioGraphItem(const Graph &graph, GraphType type,
|
GearRatioGraphItem::GearRatioGraphItem(const Graph &graph, GraphType type,
|
||||||
QGraphicsItem *parent) : GraphItem(graph, type, parent), _top(NAN)
|
int width, const QColor &color, QGraphicsItem *parent)
|
||||||
|
: GraphItem(graph, type, width, color, parent)
|
||||||
{
|
{
|
||||||
qreal val = NAN;
|
for (int i = 0; i < graph.size(); i++) {
|
||||||
|
const GraphSegment &segment = graph.at(i);
|
||||||
for (QMap<qreal, qreal>::const_iterator it = _map.constBegin();
|
for (int j = 1; j < segment.size(); j++) {
|
||||||
it != _map.constEnd(); ++it) {
|
qreal dx = segment.at(j).s() - segment.at(j-1).s();
|
||||||
if (it == _map.constBegin()) {
|
_map.insert(segment.at(j).y(), _map.value(segment.at(j).y()) + dx);
|
||||||
val = it.value();
|
|
||||||
_top = it.key();
|
|
||||||
} else if (it.value() > val) {
|
|
||||||
val = it.value();
|
|
||||||
_top = it.key();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qreal key = NAN, val = NAN;
|
||||||
|
for (QMap<qreal, qreal>::const_iterator it = _map.constBegin();
|
||||||
|
it != _map.constEnd(); ++it) {
|
||||||
|
if (std::isnan(val) || it.value() > val) {
|
||||||
|
val = it.value();
|
||||||
|
key = it.key();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_top = key;
|
||||||
|
|
||||||
setToolTip(toolTip());
|
setToolTip(toolTip());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ class GearRatioGraphItem : public GraphItem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GearRatioGraphItem(const Graph &graph, GraphType type,
|
GearRatioGraphItem(const Graph &graph, GraphType type, int width,
|
||||||
QGraphicsItem *parent = 0);
|
const QColor &color, QGraphicsItem *parent = 0);
|
||||||
|
|
||||||
qreal top() const {return _top;}
|
qreal top() const {return _top;}
|
||||||
|
|
||||||
|
@ -2,30 +2,25 @@
|
|||||||
#include "graphitem.h"
|
#include "graphitem.h"
|
||||||
|
|
||||||
|
|
||||||
GraphItem::GraphItem(const Graph &graph, GraphType type, QGraphicsItem *parent)
|
GraphItem::GraphItem(const Graph &graph, GraphType type, int width,
|
||||||
|
const QColor &color, QGraphicsItem *parent)
|
||||||
: QGraphicsObject(parent), _graph(graph), _type(type)
|
: QGraphicsObject(parent), _graph(graph), _type(type)
|
||||||
{
|
{
|
||||||
Q_ASSERT(_graph.isValid());
|
Q_ASSERT(_graph.isValid());
|
||||||
|
|
||||||
_id = 0;
|
_pen = QPen(color, width);
|
||||||
_width = 1;
|
_sx = 0; _sy = 0;
|
||||||
_pen = QPen(Qt::black, _width);
|
|
||||||
_sx = 1.0; _sy = 1.0;
|
|
||||||
_time = _graph.hasTime();
|
_time = _graph.hasTime();
|
||||||
|
|
||||||
setZValue(2.0);
|
setZValue(2.0);
|
||||||
|
|
||||||
updatePath();
|
|
||||||
updateShape();
|
|
||||||
updateBounds();
|
|
||||||
|
|
||||||
setAcceptHoverEvents(true);
|
setAcceptHoverEvents(true);
|
||||||
|
|
||||||
|
updateBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphItem::updateShape()
|
void GraphItem::updateShape()
|
||||||
{
|
{
|
||||||
QPainterPathStroker s;
|
QPainterPathStroker s;
|
||||||
s.setWidth(_width + 1);
|
s.setWidth(_pen.width() + 1);
|
||||||
_shape = s.createStroke(_path);
|
_shape = s.createStroke(_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +49,6 @@ void GraphItem::setGraphType(GraphType type)
|
|||||||
|
|
||||||
_type = type;
|
_type = type;
|
||||||
updatePath();
|
updatePath();
|
||||||
updateShape();
|
|
||||||
updateBounds();
|
updateBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,12 +63,11 @@ void GraphItem::setColor(const QColor &color)
|
|||||||
|
|
||||||
void GraphItem::setWidth(int width)
|
void GraphItem::setWidth(int width)
|
||||||
{
|
{
|
||||||
if (width == _width)
|
if (width == _pen.width())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
prepareGeometryChange();
|
prepareGeometryChange();
|
||||||
|
|
||||||
_width = width;
|
|
||||||
_pen.setWidth(width);
|
_pen.setWidth(width);
|
||||||
|
|
||||||
updateShape();
|
updateShape();
|
||||||
@ -170,10 +163,10 @@ void GraphItem::emitSliderPositionChanged(qreal pos)
|
|||||||
void GraphItem::hover(bool hover)
|
void GraphItem::hover(bool hover)
|
||||||
{
|
{
|
||||||
if (hover) {
|
if (hover) {
|
||||||
_pen.setWidth(_width + 1);
|
_pen.setWidth(_pen.width() + 1);
|
||||||
setZValue(zValue() + 1.0);
|
setZValue(zValue() + 1.0);
|
||||||
} else {
|
} else {
|
||||||
_pen.setWidth(_width);
|
_pen.setWidth(_pen.width() - 1);
|
||||||
setZValue(zValue() - 1.0);
|
setZValue(zValue() - 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,23 +182,30 @@ void GraphItem::setScale(qreal sx, qreal sy)
|
|||||||
|
|
||||||
_sx = sx; _sy = sy;
|
_sx = sx; _sy = sy;
|
||||||
updatePath();
|
updatePath();
|
||||||
updateShape();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphItem::updatePath()
|
void GraphItem::updatePath()
|
||||||
{
|
{
|
||||||
_path = QPainterPath();
|
if (_sx == 0 && _sy == 0)
|
||||||
|
|
||||||
if (_type == Time && !_time)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < _graph.size(); i++) {
|
prepareGeometryChange();
|
||||||
const GraphSegment &segment = _graph.at(i);
|
|
||||||
|
|
||||||
_path.moveTo(segment.first().x(_type) * _sx, -segment.first().y() * _sy);
|
_path = QPainterPath();
|
||||||
for (int i = 1; i < segment.size(); i++)
|
|
||||||
_path.lineTo(segment.at(i).x(_type) * _sx, -segment.at(i).y() * _sy);
|
if (!(_type == Time && !_time)) {
|
||||||
|
for (int i = 0; i < _graph.size(); i++) {
|
||||||
|
const GraphSegment &segment = _graph.at(i);
|
||||||
|
|
||||||
|
_path.moveTo(segment.first().x(_type) * _sx, -segment.first().y()
|
||||||
|
* _sy);
|
||||||
|
for (int i = 1; i < segment.size(); i++)
|
||||||
|
_path.lineTo(segment.at(i).x(_type) * _sx, -segment.at(i).y()
|
||||||
|
* _sy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateShape();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphItem::updateBounds()
|
void GraphItem::updateBounds()
|
||||||
@ -286,7 +286,7 @@ void GraphItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
Q_UNUSED(event);
|
||||||
|
|
||||||
_pen.setWidthF(_width + 1);
|
_pen.setWidth(_pen.width() + 1);
|
||||||
setZValue(zValue() + 1.0);
|
setZValue(zValue() + 1.0);
|
||||||
update();
|
update();
|
||||||
|
|
||||||
@ -297,7 +297,7 @@ void GraphItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
Q_UNUSED(event);
|
||||||
|
|
||||||
_pen.setWidthF(_width);
|
_pen.setWidth(_pen.width() - 1);
|
||||||
setZValue(zValue() - 1.0);
|
setZValue(zValue() - 1.0);
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@ class GraphItem : public QGraphicsObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GraphItem(const Graph &graph, GraphType type, QGraphicsItem *parent = 0);
|
GraphItem(const Graph &graph, GraphType type, int width, const QColor &color,
|
||||||
|
QGraphicsItem *parent = 0);
|
||||||
virtual ~GraphItem() {}
|
virtual ~GraphItem() {}
|
||||||
|
|
||||||
QPainterPath shape() const {return _shape;}
|
QPainterPath shape() const {return _shape;}
|
||||||
@ -27,8 +28,6 @@ public:
|
|||||||
|
|
||||||
void setScale(qreal sx, qreal sy);
|
void setScale(qreal sx, qreal sy);
|
||||||
void setGraphType(GraphType type);
|
void setGraphType(GraphType type);
|
||||||
int id() const {return _id;}
|
|
||||||
void setId(int id) {_id = id;}
|
|
||||||
void setColor(const QColor &color);
|
void setColor(const QColor &color);
|
||||||
void setWidth(int width);
|
void setWidth(int width);
|
||||||
virtual void setUnits(Units units) {Q_UNUSED(units);}
|
virtual void setUnits(Units units) {Q_UNUSED(units);}
|
||||||
@ -55,17 +54,13 @@ private:
|
|||||||
void updateShape();
|
void updateShape();
|
||||||
void updateBounds();
|
void updateBounds();
|
||||||
|
|
||||||
int _id;
|
|
||||||
QPen _pen;
|
|
||||||
int _width;
|
|
||||||
|
|
||||||
Graph _graph;
|
Graph _graph;
|
||||||
GraphType _type;
|
GraphType _type;
|
||||||
|
|
||||||
QPainterPath _path;
|
QPainterPath _path;
|
||||||
QPainterPath _shape;
|
QPainterPath _shape;
|
||||||
QRectF _bounds;
|
QRectF _bounds;
|
||||||
qreal _sx, _sy;
|
qreal _sx, _sy;
|
||||||
|
QPen _pen;
|
||||||
|
|
||||||
bool _time;
|
bool _time;
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QPaintEngine>
|
#include <QScrollBar>
|
||||||
#include <QPaintDevice>
|
|
||||||
#include <QGraphicsSimpleTextItem>
|
#include <QGraphicsSimpleTextItem>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
@ -64,6 +63,8 @@ GraphView::GraphView(QWidget *parent)
|
|||||||
_units = Metric;
|
_units = Metric;
|
||||||
_graphType = Distance;
|
_graphType = Distance;
|
||||||
_xLabel = tr("Distance");
|
_xLabel = tr("Distance");
|
||||||
|
|
||||||
|
_zoom = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphView::~GraphView()
|
GraphView::~GraphView()
|
||||||
@ -74,8 +75,6 @@ GraphView::~GraphView()
|
|||||||
delete _info;
|
delete _info;
|
||||||
delete _grid;
|
delete _grid;
|
||||||
delete _message;
|
delete _message;
|
||||||
|
|
||||||
qDeleteAll(_graphs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::createXLabel()
|
void GraphView::createXLabel()
|
||||||
@ -166,14 +165,7 @@ void GraphView::setGraphType(GraphType type)
|
|||||||
for (int i = 0; i < _graphs.count(); i++) {
|
for (int i = 0; i < _graphs.count(); i++) {
|
||||||
GraphItem *gi = _graphs.at(i);
|
GraphItem *gi = _graphs.at(i);
|
||||||
gi->setGraphType(type);
|
gi->setGraphType(type);
|
||||||
if (!_hide.contains(gi->id())) {
|
_bounds |= gi->bounds();
|
||||||
if (gi->bounds().width() > 0)
|
|
||||||
addItem(gi);
|
|
||||||
else
|
|
||||||
removeItem(gi);
|
|
||||||
}
|
|
||||||
if (gi->scene() == _scene)
|
|
||||||
_bounds |= gi->bounds();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == Distance)
|
if (type == Distance)
|
||||||
@ -195,29 +187,31 @@ void GraphView::showSliderInfo(bool show)
|
|||||||
_sliderInfo->setVisible(show);
|
_sliderInfo->setVisible(show);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::addGraph(GraphItem *graph, int id)
|
void GraphView::addGraph(GraphItem *graph)
|
||||||
{
|
{
|
||||||
QColor color(_palette.nextColor());
|
|
||||||
color.setAlpha(255);
|
|
||||||
|
|
||||||
graph->setUnits(_units);
|
|
||||||
graph->setId(id);
|
|
||||||
graph->setColor(color);
|
|
||||||
graph->setWidth(_width);
|
|
||||||
|
|
||||||
connect(this, SIGNAL(sliderPositionChanged(qreal)), graph,
|
connect(this, SIGNAL(sliderPositionChanged(qreal)), graph,
|
||||||
SLOT(emitSliderPositionChanged(qreal)));
|
SLOT(emitSliderPositionChanged(qreal)));
|
||||||
|
|
||||||
_graphs.append(graph);
|
_graphs.append(graph);
|
||||||
|
_scene->addItem(graph);
|
||||||
|
_bounds |= graph->bounds();
|
||||||
|
|
||||||
if (!_hide.contains(id)) {
|
setXUnits();
|
||||||
_visible.append(graph);
|
}
|
||||||
if (graph->bounds().width() > 0) {
|
|
||||||
_scene->addItem(graph);
|
void GraphView::removeGraph(GraphItem *graph)
|
||||||
_bounds |= graph->bounds();
|
{
|
||||||
}
|
disconnect(this, SIGNAL(sliderPositionChanged(qreal)), graph,
|
||||||
setXUnits();
|
SLOT(emitSliderPositionChanged(qreal)));
|
||||||
}
|
|
||||||
|
_graphs.removeOne(graph);
|
||||||
|
_scene->removeItem(graph);
|
||||||
|
|
||||||
|
_bounds = QRectF();
|
||||||
|
for (int i = 0; i < _graphs.count(); i++)
|
||||||
|
_bounds |= _graphs.at(i)->bounds();
|
||||||
|
|
||||||
|
setXUnits();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::removeItem(QGraphicsItem *item)
|
void GraphView::removeItem(QGraphicsItem *item)
|
||||||
@ -232,29 +226,6 @@ void GraphView::addItem(QGraphicsItem *item)
|
|||||||
_scene->addItem(item);
|
_scene->addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::showGraph(bool show, int id)
|
|
||||||
{
|
|
||||||
if (show)
|
|
||||||
_hide.remove(id);
|
|
||||||
else
|
|
||||||
_hide.insert(id);
|
|
||||||
|
|
||||||
_visible.clear();
|
|
||||||
_bounds = QRectF();
|
|
||||||
for (int i = 0; i < _graphs.count(); i++) {
|
|
||||||
GraphItem *gi = _graphs.at(i);
|
|
||||||
if (_hide.contains(gi->id()))
|
|
||||||
removeItem(gi);
|
|
||||||
else {
|
|
||||||
_visible.append(gi);
|
|
||||||
if (gi->bounds().width() > 0) {
|
|
||||||
addItem(gi);
|
|
||||||
_bounds |= gi->bounds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF GraphView::bounds() const
|
QRectF GraphView::bounds() const
|
||||||
{
|
{
|
||||||
QRectF br(_bounds);
|
QRectF br(_bounds);
|
||||||
@ -313,9 +284,10 @@ void GraphView::redraw(const QSizeF &size)
|
|||||||
sx = (size.width() - (my.width() + mx.width())) / r.width();
|
sx = (size.width() - (my.width() + mx.width())) / r.width();
|
||||||
sy = (size.height() - (mx.height() + my.height())
|
sy = (size.height() - (mx.height() + my.height())
|
||||||
- _info->boundingRect().height()) / r.height();
|
- _info->boundingRect().height()) / r.height();
|
||||||
|
sx *= _zoom;
|
||||||
|
|
||||||
for (int i = 0; i < _visible.size(); i++)
|
for (int i = 0; i < _graphs.size(); i++)
|
||||||
_visible.at(i)->setScale(sx, sy);
|
_graphs.at(i)->setScale(sx, sy);
|
||||||
|
|
||||||
QPointF p(r.left() * sx, r.top() * sy);
|
QPointF p(r.left() * sx, r.top() * sy);
|
||||||
QSizeF s(r.width() * sx, r.height() * sy);
|
QSizeF s(r.width() * sx, r.height() * sy);
|
||||||
@ -360,6 +332,40 @@ void GraphView::mousePressEvent(QMouseEvent *e)
|
|||||||
QGraphicsView::mousePressEvent(e);
|
QGraphicsView::mousePressEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphView::wheelEvent(QWheelEvent *e)
|
||||||
|
{
|
||||||
|
static int deg = 0;
|
||||||
|
|
||||||
|
deg += e->delta() / 8;
|
||||||
|
if (qAbs(deg) < 15)
|
||||||
|
return;
|
||||||
|
deg = 0;
|
||||||
|
|
||||||
|
QPointF pos = mapToScene(e->pos());
|
||||||
|
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);
|
||||||
|
redraw();
|
||||||
|
|
||||||
|
QRectF ngr(_grid->boundingRect());
|
||||||
|
QPointF npos(mapFromScene(QPointF(r.x() * ngr.width(),
|
||||||
|
r.y() * ngr.height())));
|
||||||
|
QScrollBar *sb = horizontalScrollBar();
|
||||||
|
sb->setSliderPosition(sb->sliderPosition() + npos.x() - e->pos().x());
|
||||||
|
|
||||||
|
QGraphicsView::wheelEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphView::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
QRectF viewRect(mapToScene(rect()).boundingRect());
|
||||||
|
_info->setPos(QPointF(viewRect.left() + (viewRect.width()
|
||||||
|
- _info->boundingRect().width())/2.0, _info->pos().y()));
|
||||||
|
|
||||||
|
QGraphicsView::paintEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void GraphView::plot(QPainter *painter, const QRectF &target, qreal scale)
|
void GraphView::plot(QPainter *painter, const QRectF &target, qreal scale)
|
||||||
{
|
{
|
||||||
QSizeF canvas = QSizeF(target.width() / scale, target.height() / scale);
|
QSizeF canvas = QSizeF(target.width() / scale, target.height() / scale);
|
||||||
@ -376,54 +382,45 @@ void GraphView::plot(QPainter *painter, const QRectF &target, qreal scale)
|
|||||||
|
|
||||||
void GraphView::clear()
|
void GraphView::clear()
|
||||||
{
|
{
|
||||||
|
_graphs.clear();
|
||||||
|
|
||||||
_slider->clear();
|
_slider->clear();
|
||||||
_info->clear();
|
_info->clear();
|
||||||
|
|
||||||
qDeleteAll(_graphs);
|
|
||||||
_graphs.clear();
|
|
||||||
_visible.clear();
|
|
||||||
_palette.reset();
|
_palette.reset();
|
||||||
|
|
||||||
_bounds = QRectF();
|
_bounds = QRectF();
|
||||||
_sliderPos = 0;
|
_sliderPos = 0;
|
||||||
|
_zoom = 1.0;
|
||||||
|
|
||||||
_scene->setSceneRect(0, 0, 0, 0);
|
_scene->setSceneRect(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::updateSliderPosition()
|
void GraphView::updateSliderPosition()
|
||||||
{
|
{
|
||||||
if (bounds().width() <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_sliderPos <= bounds().right() && _sliderPos >= bounds().left()) {
|
if (_sliderPos <= bounds().right() && _sliderPos >= bounds().left()) {
|
||||||
_slider->setPos((_sliderPos / bounds().width())
|
_slider->setPos((_sliderPos / bounds().width())
|
||||||
* _slider->area().width(), _slider->area().bottom());
|
* _slider->area().width(), _slider->area().bottom());
|
||||||
_slider->setVisible(!_visible.isEmpty());
|
_slider->setVisible(true);
|
||||||
|
updateSliderInfo();
|
||||||
} else {
|
} else {
|
||||||
_slider->setPos(_slider->area().left(), _slider->area().bottom());
|
_slider->setPos(_slider->area().left(), _slider->area().bottom());
|
||||||
_slider->setVisible(false);
|
_slider->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_slider->isVisible())
|
|
||||||
updateSliderInfo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::updateSliderInfo()
|
void GraphView::updateSliderInfo()
|
||||||
{
|
{
|
||||||
QLocale l(QLocale::system());
|
QLocale l(QLocale::system());
|
||||||
qreal r, y;
|
qreal r = 0, y = 0;
|
||||||
|
|
||||||
|
if (_graphs.count() == 1) {
|
||||||
if (_visible.count() > 1) {
|
QRectF br(_graphs.first()->bounds());
|
||||||
r = 0;
|
|
||||||
y = 0;
|
|
||||||
} else {
|
|
||||||
QRectF br(_visible.first()->bounds());
|
|
||||||
if (br.height() < _minYRange)
|
if (br.height() < _minYRange)
|
||||||
br.adjust(0, -(_minYRange/2 - br.height()/2), 0,
|
br.adjust(0, -(_minYRange/2 - br.height()/2), 0,
|
||||||
_minYRange/2 - br.height()/2);
|
_minYRange/2 - br.height()/2);
|
||||||
|
|
||||||
y = _visible.first()->yAtX(_sliderPos);
|
y = _graphs.first()->yAtX(_sliderPos);
|
||||||
r = (y - br.bottom()) / br.height();
|
r = (y - br.bottom()) / br.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,7 +432,7 @@ void GraphView::updateSliderInfo()
|
|||||||
_sliderInfo->setPos(QPointF(0, _slider->boundingRect().height() * r));
|
_sliderInfo->setPos(QPointF(0, _slider->boundingRect().height() * r));
|
||||||
_sliderInfo->setText(_graphType == Time ? Format::timeSpan(_sliderPos,
|
_sliderInfo->setText(_graphType == Time ? Format::timeSpan(_sliderPos,
|
||||||
bounds().width() > 3600) : l.toString(_sliderPos * _xScale, 'f', 1)
|
bounds().width() > 3600) : l.toString(_sliderPos * _xScale, 'f', 1)
|
||||||
+ UNIT_SPACE + _xUnits, (_visible.count() > 1) ? QString()
|
+ UNIT_SPACE + _xUnits, (_graphs.count() > 1) ? QString()
|
||||||
: l.toString(-y * _yScale + _yOffset, 'f', _precision) + UNIT_SPACE
|
: l.toString(-y * _yScale + _yOffset, 'f', _precision) + UNIT_SPACE
|
||||||
+ _yUnits);
|
+ _yUnits);
|
||||||
}
|
}
|
||||||
@ -455,7 +452,7 @@ void GraphView::emitSliderPositionChanged(const QPointF &pos)
|
|||||||
|
|
||||||
void GraphView::setSliderPosition(qreal pos)
|
void GraphView::setSliderPosition(qreal pos)
|
||||||
{
|
{
|
||||||
if (_visible.isEmpty())
|
if (_graphs.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_sliderPos = pos;
|
_sliderPos = pos;
|
||||||
@ -483,11 +480,8 @@ void GraphView::setPalette(const Palette &palette)
|
|||||||
_palette = palette;
|
_palette = palette;
|
||||||
_palette.reset();
|
_palette.reset();
|
||||||
|
|
||||||
for (int i = 0; i < _graphs.count(); i++) {
|
for (int i = 0; i < _graphs.count(); i++)
|
||||||
QColor color(_palette.nextColor());
|
_graphs.at(i)->setColor(_palette.nextColor());
|
||||||
color.setAlpha(255);
|
|
||||||
_graphs.at(i)->setColor(color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::setGraphWidth(int width)
|
void GraphView::setGraphWidth(int width)
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
~GraphView();
|
~GraphView();
|
||||||
|
|
||||||
bool isEmpty() const {return _graphs.isEmpty();}
|
bool isEmpty() const {return _graphs.isEmpty();}
|
||||||
const QList<KV> &info() const {return _info->info();}
|
const QList<KV<QString, QString> > &info() const {return _info->info();}
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void plot(QPainter *painter, const QRectF &target, qreal scale);
|
void plot(QPainter *painter, const QRectF &target, qreal scale);
|
||||||
@ -46,9 +46,9 @@ signals:
|
|||||||
void sliderPositionChanged(qreal);
|
void sliderPositionChanged(qreal);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addGraph(GraphItem *graph, int id = 0);
|
void addGraph(GraphItem *graph);
|
||||||
|
void removeGraph(GraphItem *graph);
|
||||||
|
|
||||||
void showGraph(bool show, int id = 0);
|
|
||||||
void setGraphType(GraphType type);
|
void setGraphType(GraphType type);
|
||||||
void setUnits(Units units);
|
void setUnits(Units units);
|
||||||
|
|
||||||
@ -68,12 +68,11 @@ protected:
|
|||||||
void redraw();
|
void redraw();
|
||||||
void addInfo(const QString &key, const QString &value);
|
void addInfo(const QString &key, const QString &value);
|
||||||
void clearInfo();
|
void clearInfo();
|
||||||
void skipColor() {_palette.nextColor();}
|
|
||||||
|
|
||||||
void changeEvent(QEvent *e);
|
|
||||||
|
|
||||||
QList<GraphItem*> _graphs;
|
|
||||||
GraphType _graphType;
|
GraphType _graphType;
|
||||||
|
Units _units;
|
||||||
|
Palette _palette;
|
||||||
|
int _width;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void emitSliderPositionChanged(const QPointF &pos);
|
void emitSliderPositionChanged(const QPointF &pos);
|
||||||
@ -91,15 +90,9 @@ private:
|
|||||||
|
|
||||||
void resizeEvent(QResizeEvent *e);
|
void resizeEvent(QResizeEvent *e);
|
||||||
void mousePressEvent(QMouseEvent *e);
|
void mousePressEvent(QMouseEvent *e);
|
||||||
|
void wheelEvent(QWheelEvent *e);
|
||||||
Units _units;
|
void changeEvent(QEvent *e);
|
||||||
qreal _xScale, _yScale;
|
void paintEvent(QPaintEvent *event);
|
||||||
qreal _yOffset;
|
|
||||||
QString _xUnits, _yUnits;
|
|
||||||
QString _xLabel, _yLabel;
|
|
||||||
int _precision;
|
|
||||||
qreal _minYRange;
|
|
||||||
qreal _sliderPos;
|
|
||||||
|
|
||||||
QGraphicsScene *_scene;
|
QGraphicsScene *_scene;
|
||||||
|
|
||||||
@ -109,12 +102,19 @@ private:
|
|||||||
InfoItem *_info;
|
InfoItem *_info;
|
||||||
GridItem *_grid;
|
GridItem *_grid;
|
||||||
QGraphicsSimpleTextItem *_message;
|
QGraphicsSimpleTextItem *_message;
|
||||||
|
QList<GraphItem*> _graphs;
|
||||||
|
|
||||||
QList<GraphItem*> _visible;
|
|
||||||
QSet<int> _hide;
|
|
||||||
QRectF _bounds;
|
QRectF _bounds;
|
||||||
Palette _palette;
|
qreal _sliderPos;
|
||||||
int _width;
|
|
||||||
|
qreal _xScale, _yScale;
|
||||||
|
qreal _yOffset;
|
||||||
|
QString _xUnits, _yUnits;
|
||||||
|
QString _xLabel, _yLabel;
|
||||||
|
int _precision;
|
||||||
|
qreal _minYRange;
|
||||||
|
|
||||||
|
qreal _zoom;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GRAPHVIEW_H
|
#endif // GRAPHVIEW_H
|
||||||
|
@ -1066,7 +1066,7 @@ void GUI::statistics()
|
|||||||
|
|
||||||
text.append("<tr><th colspan=\"2\">" + tab->label() + "</th></tr>");
|
text.append("<tr><th colspan=\"2\">" + tab->label() + "</th></tr>");
|
||||||
for (int j = 0; j < tab->info().size(); j++) {
|
for (int j = 0; j < tab->info().size(); j++) {
|
||||||
const KV &kv = tab->info().at(j);
|
const KV<QString, QString> &kv = tab->info().at(j);
|
||||||
text.append("<tr><td>" + kv.key() + ":</td><td>" + kv.value()
|
text.append("<tr><td>" + kv.key() + ":</td><td>" + kv.value()
|
||||||
+ "</td></tr>");
|
+ "</td></tr>");
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,11 @@ HeartRateGraph::HeartRateGraph(QWidget *parent) : GraphTab(parent)
|
|||||||
setSliderPrecision(0);
|
setSliderPrecision(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HeartRateGraph::~HeartRateGraph()
|
||||||
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
}
|
||||||
|
|
||||||
void HeartRateGraph::setInfo()
|
void HeartRateGraph::setInfo()
|
||||||
{
|
{
|
||||||
if (_showTracks) {
|
if (_showTracks) {
|
||||||
@ -36,23 +41,28 @@ QList<GraphItem*> HeartRateGraph::loadData(const Data &data)
|
|||||||
const Graph &graph = track.heartRate();
|
const Graph &graph = track.heartRate();
|
||||||
|
|
||||||
if (!graph.isValid()) {
|
if (!graph.isValid()) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
} else {
|
} else {
|
||||||
HeartRateGraphItem *gi = new HeartRateGraphItem(graph, _graphType);
|
HeartRateGraphItem *gi = new HeartRateGraphItem(graph, _graphType,
|
||||||
GraphView::addGraph(gi);
|
_width, _palette.nextColor());
|
||||||
|
|
||||||
|
_tracks.append(gi);
|
||||||
|
if (_showTracks)
|
||||||
|
addGraph(gi);
|
||||||
|
|
||||||
_avg.append(QPointF(track.distance(), gi->avg()));
|
_avg.append(QPointF(track.distance(), gi->avg()));
|
||||||
graphs.append(gi);
|
graphs.append(gi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.routes().count(); i++) {
|
for (int i = 0; i < data.routes().count(); i++) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.areas().count(); i++)
|
for (int i = 0; i < data.areas().count(); i++)
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
redraw();
|
redraw();
|
||||||
@ -75,6 +85,9 @@ qreal HeartRateGraph::avg() const
|
|||||||
|
|
||||||
void HeartRateGraph::clear()
|
void HeartRateGraph::clear()
|
||||||
{
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
_tracks.clear();
|
||||||
|
|
||||||
_avg.clear();
|
_avg.clear();
|
||||||
|
|
||||||
GraphTab::clear();
|
GraphTab::clear();
|
||||||
@ -84,7 +97,13 @@ void HeartRateGraph::showTracks(bool show)
|
|||||||
{
|
{
|
||||||
_showTracks = show;
|
_showTracks = show;
|
||||||
|
|
||||||
showGraph(show);
|
for (int i = 0; i < _tracks.size(); i++) {
|
||||||
|
if (show)
|
||||||
|
addGraph(_tracks.at(i));
|
||||||
|
else
|
||||||
|
removeGraph(_tracks.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
@ -3,12 +3,15 @@
|
|||||||
|
|
||||||
#include "graphtab.h"
|
#include "graphtab.h"
|
||||||
|
|
||||||
|
class HeartRateGraphItem;
|
||||||
|
|
||||||
class HeartRateGraph : public GraphTab
|
class HeartRateGraph : public GraphTab
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HeartRateGraph(QWidget *parent = 0);
|
HeartRateGraph(QWidget *parent = 0);
|
||||||
|
~HeartRateGraph();
|
||||||
|
|
||||||
QString label() const {return tr("Heart rate");}
|
QString label() const {return tr("Heart rate");}
|
||||||
QList<GraphItem*> loadData(const Data &data);
|
QList<GraphItem*> loadData(const Data &data);
|
||||||
@ -23,6 +26,7 @@ private:
|
|||||||
QVector<QPointF> _avg;
|
QVector<QPointF> _avg;
|
||||||
|
|
||||||
bool _showTracks;
|
bool _showTracks;
|
||||||
|
QList<HeartRateGraphItem*> _tracks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HEARTRATEGRAPH_H
|
#endif // HEARTRATEGRAPH_H
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
|
|
||||||
HeartRateGraphItem::HeartRateGraphItem(const Graph &graph, GraphType type,
|
HeartRateGraphItem::HeartRateGraphItem(const Graph &graph, GraphType type,
|
||||||
QGraphicsItem *parent) : GraphItem(graph, type, parent)
|
int width, const QColor &color, QGraphicsItem *parent)
|
||||||
|
: GraphItem(graph, type, width, color, parent)
|
||||||
{
|
{
|
||||||
setToolTip(toolTip());
|
setToolTip(toolTip());
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ class HeartRateGraphItem : public GraphItem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HeartRateGraphItem(const Graph &graph, GraphType type,
|
HeartRateGraphItem(const Graph &graph, GraphType type, int width,
|
||||||
QGraphicsItem *parent = 0);
|
const QColor &color, QGraphicsItem *parent = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString toolTip() const;
|
QString toolTip() const;
|
||||||
|
@ -16,7 +16,7 @@ void InfoItem::updateBoundingRect()
|
|||||||
QFontMetrics fm(_font);
|
QFontMetrics fm(_font);
|
||||||
qreal width = 0;
|
qreal width = 0;
|
||||||
|
|
||||||
for (QList<KV>::const_iterator i = _list.constBegin();
|
for (QList<KV<QString, QString> >::const_iterator i = _list.constBegin();
|
||||||
i != _list.constEnd(); i++) {
|
i != _list.constEnd(); i++) {
|
||||||
width += fm.width(i->key() + ": ");
|
width += fm.width(i->key() + ": ");
|
||||||
width += fm.width(i->value()) + ((i == _list.constEnd() - 1)
|
width += fm.width(i->value()) + ((i == _list.constEnd() - 1)
|
||||||
@ -37,7 +37,7 @@ void InfoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|||||||
painter->setFont(_font);
|
painter->setFont(_font);
|
||||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
|
||||||
for (QList<KV>::const_iterator i = _list.constBegin();
|
for (QList<KV<QString, QString> >::const_iterator i = _list.constBegin();
|
||||||
i != _list.constEnd(); i++) {
|
i != _list.constEnd(); i++) {
|
||||||
painter->drawText(width, fm.height() - fm.descent(), i->key() + ": ");
|
painter->drawText(width, fm.height() - fm.descent(), i->key() + ": ");
|
||||||
width += fm.width(i->key() + ": ");
|
width += fm.width(i->key() + ": ");
|
||||||
@ -61,7 +61,7 @@ void InfoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|||||||
|
|
||||||
void InfoItem::insert(const QString &key, const QString &value)
|
void InfoItem::insert(const QString &key, const QString &value)
|
||||||
{
|
{
|
||||||
KV kv(key, value);
|
KV<QString, QString> kv(key, value);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
prepareGeometryChange();
|
prepareGeometryChange();
|
||||||
|
@ -14,7 +14,7 @@ public:
|
|||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||||
QWidget *widget);
|
QWidget *widget);
|
||||||
|
|
||||||
const QList<KV> &info() const {return _list;}
|
const QList<KV<QString, QString> > &info() const {return _list;}
|
||||||
|
|
||||||
void insert(const QString &key, const QString &value);
|
void insert(const QString &key, const QString &value);
|
||||||
void clear();
|
void clear();
|
||||||
@ -23,7 +23,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void updateBoundingRect();
|
void updateBoundingRect();
|
||||||
|
|
||||||
QList<KV> _list;
|
QList<KV<QString, QString> > _list;
|
||||||
QRectF _boundingRect;
|
QRectF _boundingRect;
|
||||||
QFont _font;
|
QFont _font;
|
||||||
};
|
};
|
||||||
|
@ -255,17 +255,18 @@ QPointF MapView::contentCenter() const
|
|||||||
|
|
||||||
void MapView::updatePOIVisibility()
|
void MapView::updatePOIVisibility()
|
||||||
{
|
{
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it, jt;
|
|
||||||
|
|
||||||
if (!_showPOI)
|
if (!_showPOI)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->show();
|
it.value()->show();
|
||||||
|
|
||||||
if (!_overlapPOIs) {
|
if (!_overlapPOIs) {
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++) {
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
for (jt = _pois.constBegin(); jt != _pois.constEnd(); jt++) {
|
it != _pois.constEnd(); it++) {
|
||||||
|
for (POIHash::const_iterator jt = _pois.constBegin();
|
||||||
|
jt != _pois.constEnd(); jt++) {
|
||||||
if (it.value()->isVisible() && jt.value()->isVisible()
|
if (it.value()->isVisible() && jt.value()->isVisible()
|
||||||
&& it != jt && it.value()->collidesWithItem(jt.value()))
|
&& it != jt && it.value()->collidesWithItem(jt.value()))
|
||||||
jt.value()->hide();
|
jt.value()->hide();
|
||||||
@ -288,8 +289,8 @@ void MapView::rescale()
|
|||||||
for (int i = 0; i < _waypoints.size(); i++)
|
for (int i = 0; i < _waypoints.size(); i++)
|
||||||
_waypoints.at(i)->setMap(_map);
|
_waypoints.at(i)->setMap(_map);
|
||||||
|
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->setMap(_map);
|
it.value()->setMap(_map);
|
||||||
|
|
||||||
updatePOIVisibility();
|
updatePOIVisibility();
|
||||||
@ -339,8 +340,8 @@ void MapView::setMap(Map *map)
|
|||||||
for (int i = 0; i < _waypoints.size(); i++)
|
for (int i = 0; i < _waypoints.size(); i++)
|
||||||
_waypoints.at(i)->setMap(map);
|
_waypoints.at(i)->setMap(map);
|
||||||
|
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->setMap(_map);
|
it.value()->setMap(_map);
|
||||||
updatePOIVisibility();
|
updatePOIVisibility();
|
||||||
|
|
||||||
@ -364,12 +365,10 @@ void MapView::setPOI(POI *poi)
|
|||||||
|
|
||||||
void MapView::updatePOI()
|
void MapView::updatePOI()
|
||||||
{
|
{
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
|
it != _pois.constEnd(); it++)
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++) {
|
|
||||||
_scene->removeItem(it.value());
|
_scene->removeItem(it.value());
|
||||||
delete it.value();
|
qDeleteAll(_pois);
|
||||||
}
|
|
||||||
_pois.clear();
|
_pois.clear();
|
||||||
|
|
||||||
if (_showTracks)
|
if (_showTracks)
|
||||||
@ -426,8 +425,8 @@ void MapView::setUnits(Units units)
|
|||||||
for (int i = 0; i < _waypoints.size(); i++)
|
for (int i = 0; i < _waypoints.size(); i++)
|
||||||
_waypoints.at(i)->setToolTipFormat(_units, _coordinatesFormat);
|
_waypoints.at(i)->setToolTipFormat(_units, _coordinatesFormat);
|
||||||
|
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->setToolTipFormat(_units, _coordinatesFormat);
|
it.value()->setToolTipFormat(_units, _coordinatesFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,8 +444,8 @@ void MapView::setCoordinatesFormat(CoordinatesFormat format)
|
|||||||
for (int i = 0; i < _routes.count(); i++)
|
for (int i = 0; i < _routes.count(); i++)
|
||||||
_routes[i]->setCoordinatesFormat(_coordinatesFormat);
|
_routes[i]->setCoordinatesFormat(_coordinatesFormat);
|
||||||
|
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->setToolTipFormat(_units, _coordinatesFormat);
|
it.value()->setToolTipFormat(_units, _coordinatesFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,8 +460,6 @@ void MapView::clearMapCache()
|
|||||||
|
|
||||||
void MapView::digitalZoom(int zoom)
|
void MapView::digitalZoom(int zoom)
|
||||||
{
|
{
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
|
||||||
|
|
||||||
if (zoom) {
|
if (zoom) {
|
||||||
_digitalZoom += zoom;
|
_digitalZoom += zoom;
|
||||||
scale(pow(2, zoom), pow(2, zoom));
|
scale(pow(2, zoom), pow(2, zoom));
|
||||||
@ -479,7 +476,8 @@ void MapView::digitalZoom(int zoom)
|
|||||||
_areas.at(i)->setDigitalZoom(_digitalZoom);
|
_areas.at(i)->setDigitalZoom(_digitalZoom);
|
||||||
for (int i = 0; i < _waypoints.size(); i++)
|
for (int i = 0; i < _waypoints.size(); i++)
|
||||||
_waypoints.at(i)->setDigitalZoom(_digitalZoom);
|
_waypoints.at(i)->setDigitalZoom(_digitalZoom);
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->setDigitalZoom(_digitalZoom);
|
it.value()->setDigitalZoom(_digitalZoom);
|
||||||
|
|
||||||
_mapScale->setDigitalZoom(_digitalZoom);
|
_mapScale->setDigitalZoom(_digitalZoom);
|
||||||
@ -747,8 +745,8 @@ void MapView::showPOI(bool show)
|
|||||||
{
|
{
|
||||||
_showPOI = show;
|
_showPOI = show;
|
||||||
|
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->setVisible(show);
|
it.value()->setVisible(show);
|
||||||
|
|
||||||
updatePOIVisibility();
|
updatePOIVisibility();
|
||||||
@ -758,8 +756,8 @@ void MapView::showPOILabels(bool show)
|
|||||||
{
|
{
|
||||||
_showPOILabels = show;
|
_showPOILabels = show;
|
||||||
|
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->showLabel(show);
|
it.value()->showLabel(show);
|
||||||
|
|
||||||
updatePOIVisibility();
|
updatePOIVisibility();
|
||||||
@ -852,21 +850,19 @@ void MapView::setWaypointColor(const QColor &color)
|
|||||||
|
|
||||||
void MapView::setPOISize(int size)
|
void MapView::setPOISize(int size)
|
||||||
{
|
{
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
|
||||||
|
|
||||||
_poiSize = size;
|
_poiSize = size;
|
||||||
|
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->setSize(size);
|
it.value()->setSize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapView::setPOIColor(const QColor &color)
|
void MapView::setPOIColor(const QColor &color)
|
||||||
{
|
{
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
|
||||||
|
|
||||||
_poiColor = color;
|
_poiColor = color;
|
||||||
|
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->setColor(color);
|
it.value()->setColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1003,8 +999,8 @@ void MapView::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
|||||||
for (int i = 0; i < _waypoints.size(); i++)
|
for (int i = 0; i < _waypoints.size(); i++)
|
||||||
_waypoints.at(i)->setMap(_map);
|
_waypoints.at(i)->setMap(_map);
|
||||||
|
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
for (POIHash::const_iterator it = _pois.constBegin();
|
||||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
it != _pois.constEnd(); it++)
|
||||||
it.value()->setMap(_map);
|
it.value()->setMap(_map);
|
||||||
updatePOIVisibility();
|
updatePOIVisibility();
|
||||||
|
|
||||||
@ -1021,13 +1017,17 @@ void MapView::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
|||||||
|
|
||||||
void MapView::setProjection(int id)
|
void MapView::setProjection(int id)
|
||||||
{
|
{
|
||||||
Projection projection(PCS::pcs(id));
|
const PCS *pcs;
|
||||||
if (!projection.isValid())
|
const GCS *gcs;
|
||||||
return;
|
|
||||||
|
|
||||||
_projection = projection;
|
|
||||||
|
|
||||||
Coordinates center = _map->xy2ll(mapToScene(viewport()->rect().center()));
|
Coordinates center = _map->xy2ll(mapToScene(viewport()->rect().center()));
|
||||||
|
|
||||||
|
if ((pcs = PCS::pcs(id)))
|
||||||
|
_projection = Projection(pcs);
|
||||||
|
else if ((gcs = GCS::gcs(id)))
|
||||||
|
_projection = Projection(gcs);
|
||||||
|
else
|
||||||
|
qWarning("%d: Unknown PCS/GCS id", id);
|
||||||
|
|
||||||
_map->setProjection(_projection);
|
_map->setProjection(_projection);
|
||||||
rescale();
|
rescale();
|
||||||
centerOn(_map->ll2xy(center));
|
centerOn(_map->ll2xy(center));
|
||||||
|
@ -92,6 +92,8 @@ private slots:
|
|||||||
void reloadMap();
|
void reloadMap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef QHash<SearchPointer<Waypoint>, WaypointItem*> POIHash;
|
||||||
|
|
||||||
PathItem *addTrack(const Track &track);
|
PathItem *addTrack(const Track &track);
|
||||||
PathItem *addRoute(const Route &route);
|
PathItem *addRoute(const Route &route);
|
||||||
void addArea(const Area &area);
|
void addArea(const Area &area);
|
||||||
@ -125,7 +127,7 @@ private:
|
|||||||
QList<RouteItem*> _routes;
|
QList<RouteItem*> _routes;
|
||||||
QList<WaypointItem*> _waypoints;
|
QList<WaypointItem*> _waypoints;
|
||||||
QList<AreaItem*> _areas;
|
QList<AreaItem*> _areas;
|
||||||
QHash<SearchPointer<Waypoint>, WaypointItem*> _pois;
|
POIHash _pois;
|
||||||
|
|
||||||
RectC _tr, _rr, _wr, _ar;
|
RectC _tr, _rr, _wr, _ar;
|
||||||
qreal _res;
|
qreal _res;
|
||||||
|
@ -36,15 +36,18 @@ static QFrame *line()
|
|||||||
}
|
}
|
||||||
#endif // Q_OS_MAC
|
#endif // Q_OS_MAC
|
||||||
|
|
||||||
|
|
||||||
QWidget *OptionsDialog::createMapPage()
|
QWidget *OptionsDialog::createMapPage()
|
||||||
{
|
{
|
||||||
_projection = new LimitedComboBox(200);
|
_projection = new LimitedComboBox(200);
|
||||||
QList<PCS::Info> projections(PCS::pcsList());
|
|
||||||
|
QList<KV<int, QString> > projections(GCS::list() + PCS::list());
|
||||||
qSort(projections);
|
qSort(projections);
|
||||||
|
|
||||||
for (int i = 0; i < projections.size(); i++) {
|
for (int i = 0; i < projections.size(); i++) {
|
||||||
QString text = QString::number(projections.at(i).id()) + " - "
|
QString text = QString::number(projections.at(i).key()) + " - "
|
||||||
+ projections.at(i).name();
|
+ projections.at(i).value();
|
||||||
_projection->addItem(text, QVariant(projections.at(i).id()));
|
_projection->addItem(text, QVariant(projections.at(i).key()));
|
||||||
}
|
}
|
||||||
_projection->setCurrentIndex(_projection->findData(_options->projection));
|
_projection->setCurrentIndex(_projection->findData(_options->projection));
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ PercentSlider::PercentSlider(QWidget *parent) : QWidget(parent)
|
|||||||
_label->setAlignment(Qt::AlignRight);
|
_label->setAlignment(Qt::AlignRight);
|
||||||
_label->setText(format(_slider->value()));
|
_label->setText(format(_slider->value()));
|
||||||
|
|
||||||
connect(_slider, SIGNAL(sliderMoved(int)), this, SLOT(updateLabel(int)));
|
connect(_slider, SIGNAL(valueChanged(int)), this, SLOT(updateLabel(int)));
|
||||||
|
|
||||||
QHBoxLayout *layout = new QHBoxLayout();
|
QHBoxLayout *layout = new QHBoxLayout();
|
||||||
layout->addWidget(_slider);
|
layout->addWidget(_slider);
|
||||||
|
@ -14,6 +14,11 @@ PowerGraph::PowerGraph(QWidget *parent) : GraphTab(parent)
|
|||||||
setSliderPrecision(1);
|
setSliderPrecision(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PowerGraph::~PowerGraph()
|
||||||
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
}
|
||||||
|
|
||||||
void PowerGraph::setInfo()
|
void PowerGraph::setInfo()
|
||||||
{
|
{
|
||||||
if (_showTracks) {
|
if (_showTracks) {
|
||||||
@ -36,23 +41,27 @@ QList<GraphItem*> PowerGraph::loadData(const Data &data)
|
|||||||
const Graph &graph = track.power();
|
const Graph &graph = track.power();
|
||||||
|
|
||||||
if (!graph.isValid()) {
|
if (!graph.isValid()) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
} else {
|
} else {
|
||||||
PowerGraphItem *gi = new PowerGraphItem(graph, _graphType);
|
PowerGraphItem *gi = new PowerGraphItem(graph, _graphType, _width,
|
||||||
GraphView::addGraph(gi);
|
_palette.nextColor());
|
||||||
|
|
||||||
|
_tracks.append(gi);
|
||||||
|
if (_showTracks)
|
||||||
|
addGraph(gi);
|
||||||
_avg.append(QPointF(track.distance(), gi->avg()));
|
_avg.append(QPointF(track.distance(), gi->avg()));
|
||||||
graphs.append(gi);
|
graphs.append(gi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.routes().count(); i++) {
|
for (int i = 0; i < data.routes().count(); i++) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.areas().count(); i++)
|
for (int i = 0; i < data.areas().count(); i++)
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
redraw();
|
redraw();
|
||||||
@ -75,6 +84,9 @@ qreal PowerGraph::avg() const
|
|||||||
|
|
||||||
void PowerGraph::clear()
|
void PowerGraph::clear()
|
||||||
{
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
_tracks.clear();
|
||||||
|
|
||||||
_avg.clear();
|
_avg.clear();
|
||||||
|
|
||||||
GraphTab::clear();
|
GraphTab::clear();
|
||||||
@ -84,7 +96,13 @@ void PowerGraph::showTracks(bool show)
|
|||||||
{
|
{
|
||||||
_showTracks = show;
|
_showTracks = show;
|
||||||
|
|
||||||
showGraph(show);
|
for (int i = 0; i < _tracks.size(); i++) {
|
||||||
|
if (show)
|
||||||
|
addGraph(_tracks.at(i));
|
||||||
|
else
|
||||||
|
removeGraph(_tracks.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
@ -3,12 +3,15 @@
|
|||||||
|
|
||||||
#include "graphtab.h"
|
#include "graphtab.h"
|
||||||
|
|
||||||
|
class PowerGraphItem;
|
||||||
|
|
||||||
class PowerGraph : public GraphTab
|
class PowerGraph : public GraphTab
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PowerGraph(QWidget *parent = 0);
|
PowerGraph(QWidget *parent = 0);
|
||||||
|
~PowerGraph();
|
||||||
|
|
||||||
QString label() const {return tr("Power");}
|
QString label() const {return tr("Power");}
|
||||||
QList<GraphItem*> loadData(const Data &data);
|
QList<GraphItem*> loadData(const Data &data);
|
||||||
@ -23,6 +26,7 @@ private:
|
|||||||
QVector<QPointF> _avg;
|
QVector<QPointF> _avg;
|
||||||
|
|
||||||
bool _showTracks;
|
bool _showTracks;
|
||||||
|
QList<PowerGraphItem*> _tracks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // POWERGRAPH_H
|
#endif // POWERGRAPH_H
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
#include "powergraphitem.h"
|
#include "powergraphitem.h"
|
||||||
|
|
||||||
|
|
||||||
PowerGraphItem::PowerGraphItem(const Graph &graph, GraphType type,
|
PowerGraphItem::PowerGraphItem(const Graph &graph, GraphType type, int width,
|
||||||
QGraphicsItem *parent) : GraphItem(graph, type, parent)
|
const QColor &color, QGraphicsItem *parent)
|
||||||
|
: GraphItem(graph, type, width, color, parent)
|
||||||
{
|
{
|
||||||
setToolTip(toolTip());
|
setToolTip(toolTip());
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ class PowerGraphItem : public GraphItem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PowerGraphItem(const Graph &graph, GraphType type,
|
PowerGraphItem(const Graph &graph, GraphType type, int width,
|
||||||
QGraphicsItem *parent = 0);
|
const QColor &color, QGraphicsItem *parent = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString toolTip() const;
|
QString toolTip() const;
|
||||||
|
@ -24,7 +24,7 @@ QString RouteItem::toolTip(Units units) const
|
|||||||
RouteItem::RouteItem(const Route &route, Map *map, QGraphicsItem *parent)
|
RouteItem::RouteItem(const Route &route, Map *map, QGraphicsItem *parent)
|
||||||
: PathItem(route.path(), map, parent)
|
: PathItem(route.path(), map, parent)
|
||||||
{
|
{
|
||||||
const QVector<Waypoint> &waypoints = route.waypoints();
|
const RouteData &waypoints = route.data();
|
||||||
|
|
||||||
_waypoints.resize(waypoints.size());
|
_waypoints.resize(waypoints.size());
|
||||||
for (int i = 0; i < waypoints.size(); i++)
|
for (int i = 0; i < waypoints.size(); i++)
|
||||||
|
@ -152,7 +152,7 @@
|
|||||||
#define ENABLE_HTTP2_SETTING "enableHTTP2"
|
#define ENABLE_HTTP2_SETTING "enableHTTP2"
|
||||||
#define ENABLE_HTTP2_DEFAULT true
|
#define ENABLE_HTTP2_DEFAULT true
|
||||||
#define PIXMAP_CACHE_SETTING "pixmapCache"
|
#define PIXMAP_CACHE_SETTING "pixmapCache"
|
||||||
#define PIXMAP_CACHE_DEFAULT 64 /* MB */
|
#define PIXMAP_CACHE_DEFAULT 256 /* MB */
|
||||||
#define CONNECTION_TIMEOUT_SETTING "connectionTimeout"
|
#define CONNECTION_TIMEOUT_SETTING "connectionTimeout"
|
||||||
#define CONNECTION_TIMEOUT_DEFAULT 30 /* s */
|
#define CONNECTION_TIMEOUT_DEFAULT 30 /* s */
|
||||||
#define HIRES_PRINT_SETTING "hiresPrint"
|
#define HIRES_PRINT_SETTING "hiresPrint"
|
||||||
|
@ -18,6 +18,11 @@ SpeedGraph::SpeedGraph(QWidget *parent) : GraphTab(parent)
|
|||||||
setSliderPrecision(1);
|
setSliderPrecision(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpeedGraph::~SpeedGraph()
|
||||||
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
}
|
||||||
|
|
||||||
void SpeedGraph::setInfo()
|
void SpeedGraph::setInfo()
|
||||||
{
|
{
|
||||||
if (_showTracks) {
|
if (_showTracks) {
|
||||||
@ -44,13 +49,18 @@ QList<GraphItem*> SpeedGraph::loadData(const Data &data)
|
|||||||
const Graph &graph = track.speed();
|
const Graph &graph = track.speed();
|
||||||
|
|
||||||
if (!graph.isValid()) {
|
if (!graph.isValid()) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
} else {
|
} else {
|
||||||
SpeedGraphItem *gi = new SpeedGraphItem(graph, _graphType,
|
SpeedGraphItem *gi = new SpeedGraphItem(graph, _graphType, _width,
|
||||||
track.movingTime());
|
_palette.nextColor(), track.movingTime());
|
||||||
gi->setTimeType(_timeType);
|
gi->setTimeType(_timeType);
|
||||||
GraphView::addGraph(gi);
|
gi->setUnits(_units);
|
||||||
|
|
||||||
|
_tracks.append(gi);
|
||||||
|
if (_showTracks)
|
||||||
|
addGraph(gi);
|
||||||
|
|
||||||
_avg.append(QPointF(track.distance(), gi->avg()));
|
_avg.append(QPointF(track.distance(), gi->avg()));
|
||||||
_mavg.append(QPointF(track.distance(), gi->mavg()));
|
_mavg.append(QPointF(track.distance(), gi->mavg()));
|
||||||
graphs.append(gi);
|
graphs.append(gi);
|
||||||
@ -58,12 +68,12 @@ QList<GraphItem*> SpeedGraph::loadData(const Data &data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.routes().count(); i++) {
|
for (int i = 0; i < data.routes().count(); i++) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.areas().count(); i++)
|
for (int i = 0; i < data.areas().count(); i++)
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
redraw();
|
redraw();
|
||||||
@ -87,6 +97,9 @@ qreal SpeedGraph::avg() const
|
|||||||
|
|
||||||
void SpeedGraph::clear()
|
void SpeedGraph::clear()
|
||||||
{
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
_tracks.clear();
|
||||||
|
|
||||||
_avg.clear();
|
_avg.clear();
|
||||||
_mavg.clear();
|
_mavg.clear();
|
||||||
|
|
||||||
@ -121,8 +134,8 @@ void SpeedGraph::setTimeType(enum TimeType type)
|
|||||||
{
|
{
|
||||||
_timeType = type;
|
_timeType = type;
|
||||||
|
|
||||||
for (int i = 0; i < _graphs.size(); i++)
|
for (int i = 0; i < _tracks.size(); i++)
|
||||||
static_cast<SpeedGraphItem*>(_graphs.at(i))->setTimeType(type);
|
_tracks.at(i)->setTimeType(type);
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
redraw();
|
redraw();
|
||||||
@ -132,7 +145,13 @@ void SpeedGraph::showTracks(bool show)
|
|||||||
{
|
{
|
||||||
_showTracks = show;
|
_showTracks = show;
|
||||||
|
|
||||||
showGraph(show);
|
for (int i = 0; i < _tracks.size(); i++) {
|
||||||
|
if (show)
|
||||||
|
addGraph(_tracks.at(i));
|
||||||
|
else
|
||||||
|
removeGraph(_tracks.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
@ -4,12 +4,15 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include "graphtab.h"
|
#include "graphtab.h"
|
||||||
|
|
||||||
|
class SpeedGraphItem;
|
||||||
|
|
||||||
class SpeedGraph : public GraphTab
|
class SpeedGraph : public GraphTab
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SpeedGraph(QWidget *parent = 0);
|
SpeedGraph(QWidget *parent = 0);
|
||||||
|
~SpeedGraph();
|
||||||
|
|
||||||
QString label() const {return tr("Speed");}
|
QString label() const {return tr("Speed");}
|
||||||
QList<GraphItem*> loadData(const Data &data);
|
QList<GraphItem*> loadData(const Data &data);
|
||||||
@ -29,7 +32,9 @@ private:
|
|||||||
|
|
||||||
Units _units;
|
Units _units;
|
||||||
TimeType _timeType;
|
TimeType _timeType;
|
||||||
|
|
||||||
bool _showTracks;
|
bool _showTracks;
|
||||||
|
QList<SpeedGraphItem *> _tracks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SPEEDGRAPH_H
|
#endif // SPEEDGRAPH_H
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
#include "speedgraphitem.h"
|
#include "speedgraphitem.h"
|
||||||
|
|
||||||
|
|
||||||
SpeedGraphItem::SpeedGraphItem(const Graph &graph, GraphType type,
|
SpeedGraphItem::SpeedGraphItem(const Graph &graph, GraphType type, int width,
|
||||||
qreal movingTime, QGraphicsItem *parent) : GraphItem(graph, type, parent)
|
const QColor &color, qreal movingTime, QGraphicsItem *parent)
|
||||||
|
: GraphItem(graph, type, width, color, parent)
|
||||||
{
|
{
|
||||||
_units = Metric;
|
_units = Metric;
|
||||||
_timeType = Total;
|
_timeType = Total;
|
||||||
|
@ -9,8 +9,8 @@ class SpeedGraphItem : public GraphItem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SpeedGraphItem(const Graph &graph, GraphType type, qreal movingTime,
|
SpeedGraphItem(const Graph &graph, GraphType type, int width,
|
||||||
QGraphicsItem *parent = 0);
|
const QColor &color, qreal movingTime, QGraphicsItem *parent = 0);
|
||||||
|
|
||||||
qreal avg() const {return _avg;}
|
qreal avg() const {return _avg;}
|
||||||
qreal mavg() const {return _mavg;}
|
qreal mavg() const {return _mavg;}
|
||||||
@ -23,9 +23,8 @@ private:
|
|||||||
QString toolTip() const;
|
QString toolTip() const;
|
||||||
|
|
||||||
qreal _avg, _mavg, _max;
|
qreal _avg, _mavg, _max;
|
||||||
|
|
||||||
Units _units;
|
|
||||||
TimeType _timeType;
|
TimeType _timeType;
|
||||||
|
Units _units;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SPEEDGRAPHITEM_H
|
#endif // SPEEDGRAPHITEM_H
|
||||||
|
@ -14,6 +14,11 @@ TemperatureGraph::TemperatureGraph(QWidget *parent) : GraphTab(parent)
|
|||||||
setSliderPrecision(1);
|
setSliderPrecision(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TemperatureGraph::~TemperatureGraph()
|
||||||
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
}
|
||||||
|
|
||||||
void TemperatureGraph::setInfo()
|
void TemperatureGraph::setInfo()
|
||||||
{
|
{
|
||||||
if (_showTracks) {
|
if (_showTracks) {
|
||||||
@ -38,24 +43,29 @@ QList<GraphItem*> TemperatureGraph::loadData(const Data &data)
|
|||||||
const Graph &graph = track.temperature();
|
const Graph &graph = track.temperature();
|
||||||
|
|
||||||
if (!graph.isValid()) {
|
if (!graph.isValid()) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
} else {
|
} else {
|
||||||
TemperatureGraphItem *gi = new TemperatureGraphItem(graph,
|
TemperatureGraphItem *gi = new TemperatureGraphItem(graph,
|
||||||
_graphType);
|
_graphType, _width, _palette.nextColor());
|
||||||
GraphView::addGraph(gi);
|
gi->setUnits(_units);
|
||||||
|
|
||||||
|
_tracks.append(gi);
|
||||||
|
if (_showTracks)
|
||||||
|
addGraph(gi);
|
||||||
|
|
||||||
_avg.append(QPointF(track.distance(), gi->avg()));
|
_avg.append(QPointF(track.distance(), gi->avg()));
|
||||||
graphs.append(gi);
|
graphs.append(gi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.routes().count(); i++) {
|
for (int i = 0; i < data.routes().count(); i++) {
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
graphs.append(0);
|
graphs.append(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data.areas().count(); i++)
|
for (int i = 0; i < data.areas().count(); i++)
|
||||||
skipColor();
|
_palette.nextColor();
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
redraw();
|
redraw();
|
||||||
@ -78,6 +88,9 @@ qreal TemperatureGraph::avg() const
|
|||||||
|
|
||||||
void TemperatureGraph::clear()
|
void TemperatureGraph::clear()
|
||||||
{
|
{
|
||||||
|
qDeleteAll(_tracks);
|
||||||
|
_tracks.clear();
|
||||||
|
|
||||||
_avg.clear();
|
_avg.clear();
|
||||||
|
|
||||||
GraphTab::clear();
|
GraphTab::clear();
|
||||||
@ -108,7 +121,13 @@ void TemperatureGraph::showTracks(bool show)
|
|||||||
{
|
{
|
||||||
_showTracks = show;
|
_showTracks = show;
|
||||||
|
|
||||||
showGraph(show);
|
for (int i = 0; i < _tracks.size(); i++) {
|
||||||
|
if (show)
|
||||||
|
addGraph(_tracks.at(i));
|
||||||
|
else
|
||||||
|
removeGraph(_tracks.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
setInfo();
|
setInfo();
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
@ -3,12 +3,15 @@
|
|||||||
|
|
||||||
#include "graphtab.h"
|
#include "graphtab.h"
|
||||||
|
|
||||||
|
class TemperatureGraphItem;
|
||||||
|
|
||||||
class TemperatureGraph : public GraphTab
|
class TemperatureGraph : public GraphTab
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TemperatureGraph(QWidget *parent = 0);
|
TemperatureGraph(QWidget *parent = 0);
|
||||||
|
~TemperatureGraph();
|
||||||
|
|
||||||
QString label() const {return tr("Temperature");}
|
QString label() const {return tr("Temperature");}
|
||||||
QList<GraphItem*> loadData(const Data &data);
|
QList<GraphItem*> loadData(const Data &data);
|
||||||
@ -26,6 +29,7 @@ private:
|
|||||||
QVector<QPointF> _avg;
|
QVector<QPointF> _avg;
|
||||||
|
|
||||||
bool _showTracks;
|
bool _showTracks;
|
||||||
|
QList<TemperatureGraphItem *> _tracks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TEMPERATUREGRAPH_H
|
#endif // TEMPERATUREGRAPH_H
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
|
|
||||||
TemperatureGraphItem::TemperatureGraphItem(const Graph &graph, GraphType type,
|
TemperatureGraphItem::TemperatureGraphItem(const Graph &graph, GraphType type,
|
||||||
QGraphicsItem *parent) : GraphItem(graph, type, parent)
|
int width, const QColor &color, QGraphicsItem *parent)
|
||||||
|
: GraphItem(graph, type, width, color, parent)
|
||||||
{
|
{
|
||||||
_min = GraphItem::min();
|
_min = GraphItem::min();
|
||||||
_max = GraphItem::max();
|
_max = GraphItem::max();
|
||||||
|
@ -8,8 +8,8 @@ class TemperatureGraphItem : public GraphItem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TemperatureGraphItem(const Graph &graph, GraphType type,
|
TemperatureGraphItem(const Graph &graph, GraphType type, int width,
|
||||||
QGraphicsItem *parent = 0);
|
const QColor &color, QGraphicsItem *parent = 0);
|
||||||
|
|
||||||
qreal max() const {return _max;}
|
qreal max() const {return _max;}
|
||||||
qreal min() const {return _min;}
|
qreal min() const {return _min;}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
void ToolTip::insert(const QString &key, const QString &value)
|
void ToolTip::insert(const QString &key, const QString &value)
|
||||||
{
|
{
|
||||||
_list.append(KV(key, value));
|
_list.append(KV<QString, QString>(key, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ToolTip::toString() const
|
QString ToolTip::toString() const
|
||||||
|
@ -14,7 +14,7 @@ public:
|
|||||||
QString toString() const;
|
QString toString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<KV> _list;
|
QList<KV<QString, QString> > _list;
|
||||||
ImageInfo _img;
|
ImageInfo _img;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
#ifndef KV_H
|
#ifndef KV_H
|
||||||
#define KV_H
|
#define KV_H
|
||||||
|
|
||||||
#include <QString>
|
template <class KEY, class VALUE>
|
||||||
|
|
||||||
class KV {
|
class KV {
|
||||||
public:
|
public:
|
||||||
KV(const QString &key, const QString &value) : _key(key), _value(value) {}
|
KV(const KEY &key, const VALUE &value) : _key(key), _value(value) {}
|
||||||
|
|
||||||
const QString &key() const {return _key;}
|
const KEY &key() const {return _key;}
|
||||||
const QString &value() const {return _value;}
|
const VALUE &value() const {return _value;}
|
||||||
|
|
||||||
bool operator==(const KV &other) const
|
bool operator==(const KV &other) const {return _key == other._key;}
|
||||||
{return this->key() == other.key();}
|
bool operator<(const KV &other) const {return _key < other._key;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _key;
|
KEY _key;
|
||||||
QString _value;
|
VALUE _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KV_H
|
#endif // KV_H
|
||||||
|
@ -17,6 +17,7 @@ public:
|
|||||||
TIFFFile(QIODevice *device);
|
TIFFFile(QIODevice *device);
|
||||||
|
|
||||||
bool isValid() const {return _ifd != 0;}
|
bool isValid() const {return _ifd != 0;}
|
||||||
|
bool isBE() const {return _be;}
|
||||||
quint32 ifd() const {return _ifd;}
|
quint32 ifd() const {return _ifd;}
|
||||||
|
|
||||||
bool seek(qint64 pos) {return _device->seek(_offset + pos);}
|
bool seek(qint64 pos) {return _device->seek(_offset + pos);}
|
||||||
|
67
src/data/csv.cpp
Normal file
67
src/data/csv.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include <QStringList>
|
||||||
|
#include "csv.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
RFC 4180 parser with the following enchancements:
|
||||||
|
- allows an arbitrary delimiter
|
||||||
|
- allows LF line ends in addition to CRLF line ends
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool CSV::readEntry(QStringList &list)
|
||||||
|
{
|
||||||
|
int state = 0;
|
||||||
|
char c;
|
||||||
|
QByteArray field;
|
||||||
|
|
||||||
|
while (_device->getChar(&c)) {
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
if (c == '\r')
|
||||||
|
state = 3;
|
||||||
|
else if (c == '\n') {
|
||||||
|
list.append(field);
|
||||||
|
_line++;
|
||||||
|
return true;
|
||||||
|
} else if (c == _delimiter) {
|
||||||
|
list.append(field);
|
||||||
|
field.clear();
|
||||||
|
} else if (c == '"') {
|
||||||
|
if (!field.isEmpty())
|
||||||
|
return false;
|
||||||
|
state = 1;
|
||||||
|
} else
|
||||||
|
field.append(c);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (c == '"')
|
||||||
|
state = 2;
|
||||||
|
else {
|
||||||
|
field.append(c);
|
||||||
|
if (c == '\n')
|
||||||
|
_line++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (c == '"') {
|
||||||
|
field.append('"');
|
||||||
|
state = 1;
|
||||||
|
} else if (c == _delimiter || c == '\r' || c == '\n') {
|
||||||
|
_device->ungetChar(c);
|
||||||
|
state = 0;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (c == '\n') {
|
||||||
|
_device->ungetChar(c);
|
||||||
|
state = 0;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list.append(field);
|
||||||
|
|
||||||
|
return (state == 0);
|
||||||
|
}
|
22
src/data/csv.h
Normal file
22
src/data/csv.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef CSV_H
|
||||||
|
#define CSV_H
|
||||||
|
|
||||||
|
#include <QIODevice>
|
||||||
|
|
||||||
|
class CSV
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CSV(QIODevice *device, char delimiter = ',')
|
||||||
|
: _device(device), _delimiter(delimiter), _line(1) {}
|
||||||
|
|
||||||
|
bool readEntry(QStringList &list);
|
||||||
|
bool atEnd() const {return _device->atEnd();}
|
||||||
|
int line() const {return _line;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QIODevice *_device;
|
||||||
|
char _delimiter;
|
||||||
|
int _line;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSV_H
|
@ -1,3 +1,5 @@
|
|||||||
|
#include <QStringList>
|
||||||
|
#include "csv.h"
|
||||||
#include "csvparser.h"
|
#include "csvparser.h"
|
||||||
|
|
||||||
bool CSVParser::parse(QFile *file, QList<TrackData> &tracks,
|
bool CSVParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||||
@ -7,42 +9,38 @@ bool CSVParser::parse(QFile *file, QList<TrackData> &tracks,
|
|||||||
Q_UNUSED(tracks);
|
Q_UNUSED(tracks);
|
||||||
Q_UNUSED(routes);
|
Q_UNUSED(routes);
|
||||||
Q_UNUSED(polygons);
|
Q_UNUSED(polygons);
|
||||||
bool res;
|
CSV csv(file);
|
||||||
|
QStringList entry;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
_errorLine = 1;
|
|
||||||
_errorString.clear();
|
|
||||||
|
|
||||||
while (!file->atEnd()) {
|
while (!csv.atEnd()) {
|
||||||
QByteArray line = file->readLine();
|
if (!csv.readEntry(entry) || entry.size() < 3) {
|
||||||
QList<QByteArray> list = line.split(',');
|
|
||||||
if (list.size() < 3) {
|
|
||||||
_errorString = "Parse error";
|
_errorString = "Parse error";
|
||||||
|
_errorLine = csv.line();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal lon = list[0].trimmed().toDouble(&res);
|
double lon = entry.at(0).trimmed().toDouble(&ok);
|
||||||
if (!res || (lon < -180.0 || lon > 180.0)) {
|
if (!ok || (lon < -180.0 || lon > 180.0)) {
|
||||||
_errorString = "Invalid longitude";
|
_errorString = "Invalid longitude";
|
||||||
|
_errorLine = csv.line();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
qreal lat = list[1].trimmed().toDouble(&res);
|
double lat = entry.at(1).trimmed().toDouble(&ok);
|
||||||
if (!res || (lat < -90.0 || lat > 90.0)) {
|
if (!ok || (lat < -90.0 || lat > 90.0)) {
|
||||||
_errorString = "Invalid latitude";
|
_errorString = "Invalid latitude";
|
||||||
|
_errorLine = csv.line();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Waypoint wp(Coordinates(lon, lat));
|
Waypoint wp(Coordinates(lon, lat));
|
||||||
|
wp.setName(entry.at(2).trimmed());
|
||||||
QByteArray ba = list[2].trimmed();
|
if (entry.size() > 3)
|
||||||
QString name = QString::fromUtf8(ba.data(), ba.size());
|
wp.setDescription(entry.at(3).trimmed());
|
||||||
wp.setName(name);
|
|
||||||
|
|
||||||
if (list.size() > 3) {
|
|
||||||
ba = list[3].trimmed();
|
|
||||||
wp.setDescription(QString::fromUtf8(ba.data(), ba.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
waypoints.append(wp);
|
waypoints.append(wp);
|
||||||
_errorLine++;
|
|
||||||
|
entry.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
167
src/data/cupparser.cpp
Normal file
167
src/data/cupparser.cpp
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
#include <cmath>
|
||||||
|
#include <QStringList>
|
||||||
|
#include "csv.h"
|
||||||
|
#include "cupparser.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum SegmentType {
|
||||||
|
Header, Waypoints, Tasks
|
||||||
|
};
|
||||||
|
|
||||||
|
static double latitude(const QString &str)
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
if (str.length() != 9)
|
||||||
|
return NAN;
|
||||||
|
int deg = str.left(2).toInt(&ok);
|
||||||
|
if (!ok || deg > 90)
|
||||||
|
return NAN;
|
||||||
|
double min = str.mid(2, 6).toDouble(&ok);
|
||||||
|
if (!ok || min > 60)
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
double dd = deg + min/60.0;
|
||||||
|
return (str.right(1) == "S") ? -dd : dd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double longitude(const QString &str)
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
if (str.length() != 10)
|
||||||
|
return NAN;
|
||||||
|
int deg = str.left(3).toInt(&ok);
|
||||||
|
if (!ok || deg > 180)
|
||||||
|
return NAN;
|
||||||
|
double min = str.mid(3, 6).toDouble(&ok);
|
||||||
|
if (!ok || min > 60)
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
double dd = deg + min/60.0;
|
||||||
|
return (str.right(1) == "W") ? -dd : dd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double elevation(const QString &str)
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
double ele;
|
||||||
|
|
||||||
|
if (str.right(2) == "ft")
|
||||||
|
ele = str.left(str.length() - 2).toDouble(&ok) * 0.3048;
|
||||||
|
else if (str.right(1) == "m")
|
||||||
|
ele = str.left(str.length() - 1).toDouble(&ok);
|
||||||
|
else
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
return ok ? ele : NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CUPParser::waypoint(const QStringList &entry, QVector<Waypoint> &waypoints)
|
||||||
|
{
|
||||||
|
if (entry.size() < 11) {
|
||||||
|
_errorString = "Invalid number of fields";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double lon = longitude(entry.at(4));
|
||||||
|
if (std::isnan(lon)) {
|
||||||
|
_errorString = "Invalid longitude";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
double lat = latitude(entry.at(3));
|
||||||
|
if (std::isnan(lat)) {
|
||||||
|
_errorString = "Invalid latitude";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Waypoint wp(Coordinates(lon, lat));
|
||||||
|
wp.setName(entry.at(0));
|
||||||
|
wp.setDescription(entry.at(10));
|
||||||
|
wp.setElevation(elevation(entry.at(5)));
|
||||||
|
waypoints.append(wp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CUPParser::task(const QStringList &entry,
|
||||||
|
const QVector<Waypoint> &waypoints, QList<RouteData> &routes)
|
||||||
|
{
|
||||||
|
if (entry.size() < 3) {
|
||||||
|
_errorString = "Invalid number of fields";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RouteData r;
|
||||||
|
r.setName(entry.at(0));
|
||||||
|
for (int i = 1; i < entry.size(); i++) {
|
||||||
|
if (entry.at(i) == "???")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Waypoint w;
|
||||||
|
for (int j = 0; j < waypoints.size(); j++) {
|
||||||
|
if (waypoints.at(j).name() == entry.at(i)) {
|
||||||
|
w = waypoints.at(j);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (w.coordinates().isNull()) {
|
||||||
|
_errorString = entry.at(i) + ": unknown turnpoint";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
r.append(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
routes.append(r);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CUPParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||||
|
QList<RouteData> &routes, QList<Area> &polygons,
|
||||||
|
QVector<Waypoint> &waypoints)
|
||||||
|
{
|
||||||
|
Q_UNUSED(tracks);
|
||||||
|
Q_UNUSED(polygons);
|
||||||
|
CSV csv(file);
|
||||||
|
QStringList entry;
|
||||||
|
SegmentType segment = Header;
|
||||||
|
|
||||||
|
|
||||||
|
while (!csv.atEnd()) {
|
||||||
|
if (!csv.readEntry(entry)) {
|
||||||
|
_errorString = "CSV parse error";
|
||||||
|
_errorLine = csv.line();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segment == Header) {
|
||||||
|
segment = Waypoints;
|
||||||
|
if (entry.size() >= 11 && entry.at(3) == "lat"
|
||||||
|
&& entry.at(4) == "lon") {
|
||||||
|
entry.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (segment == Waypoints && entry.size() == 1
|
||||||
|
&& entry.at(0) == "-----Related Tasks-----") {
|
||||||
|
segment = Tasks;
|
||||||
|
entry.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segment == Waypoints) {
|
||||||
|
if (!waypoint(entry, waypoints))
|
||||||
|
return false;
|
||||||
|
} else if (segment == Tasks) {
|
||||||
|
if (entry.at(0) != "Options" && !entry.at(0).startsWith("ObsZone=")
|
||||||
|
&& !task(entry, waypoints, routes))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.clear();
|
||||||
|
_errorLine = csv.line();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
25
src/data/cupparser.h
Normal file
25
src/data/cupparser.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef CUPPARSER_H
|
||||||
|
#define CUPPARSER_H
|
||||||
|
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
class CUPParser : public Parser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CUPParser() : _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:
|
||||||
|
bool waypoint(const QStringList &entry, QVector<Waypoint> &waypoints);
|
||||||
|
bool task(const QStringList &entry, const QVector<Waypoint> &waypoints,
|
||||||
|
QList<RouteData> &routes);
|
||||||
|
|
||||||
|
QString _errorString;
|
||||||
|
int _errorLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CUPPARSER_H
|
@ -17,6 +17,7 @@
|
|||||||
#include "geojsonparser.h"
|
#include "geojsonparser.h"
|
||||||
#endif // ENABLE_GEOJSON
|
#endif // ENABLE_GEOJSON
|
||||||
#include "exifparser.h"
|
#include "exifparser.h"
|
||||||
|
#include "cupparser.h"
|
||||||
#include "dem.h"
|
#include "dem.h"
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ static SLFParser slf;
|
|||||||
static GeoJSONParser geojson;
|
static GeoJSONParser geojson;
|
||||||
#endif // ENABLE_GEOJSON
|
#endif // ENABLE_GEOJSON
|
||||||
static EXIFParser exif;
|
static EXIFParser exif;
|
||||||
|
static CUPParser cup;
|
||||||
|
|
||||||
static QHash<QString, Parser*> parsers()
|
static QHash<QString, Parser*> parsers()
|
||||||
{
|
{
|
||||||
@ -60,6 +62,7 @@ static QHash<QString, Parser*> parsers()
|
|||||||
#endif // ENABLE_GEOJSON
|
#endif // ENABLE_GEOJSON
|
||||||
hash.insert("jpeg", &exif);
|
hash.insert("jpeg", &exif);
|
||||||
hash.insert("jpg", &exif);
|
hash.insert("jpg", &exif);
|
||||||
|
hash.insert("cup", &cup);
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
@ -68,13 +71,35 @@ static QHash<QString, Parser*> parsers()
|
|||||||
QHash<QString, Parser*> Data::_parsers = parsers();
|
QHash<QString, Parser*> Data::_parsers = parsers();
|
||||||
bool Data::_useDEM = false;
|
bool Data::_useDEM = false;
|
||||||
|
|
||||||
void Data::processData(const QList<TrackData> &trackData,
|
void Data::processData(QList<TrackData> &trackData, QList<RouteData> &routeData)
|
||||||
const QList<RouteData> &routeData)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < trackData.count(); i++)
|
for (int i = 0; i < trackData.count(); i++) {
|
||||||
|
TrackData &track = trackData[i];
|
||||||
|
for (int j = 0; j < track.size(); j++) {
|
||||||
|
SegmentData &segment = track[j];
|
||||||
|
for (int k = 0; k < segment.size(); k++) {
|
||||||
|
Trackpoint &t = segment[k];
|
||||||
|
if (!t.hasElevation() || _useDEM) {
|
||||||
|
qreal elevation = DEM::elevation(t.coordinates());
|
||||||
|
if (!std::isnan(elevation))
|
||||||
|
t.setElevation(elevation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_tracks.append(Track(trackData.at(i)));
|
_tracks.append(Track(trackData.at(i)));
|
||||||
for (int i = 0; i < routeData.count(); i++)
|
}
|
||||||
|
for (int i = 0; i < routeData.count(); i++) {
|
||||||
|
RouteData &route = routeData[i];
|
||||||
|
for (int j = 0; j < route.size(); j++) {
|
||||||
|
Waypoint &w = route[j];
|
||||||
|
if (!w.hasElevation() || _useDEM) {
|
||||||
|
qreal elevation = DEM::elevation(w.coordinates());
|
||||||
|
if (!std::isnan(elevation))
|
||||||
|
w.setElevation(elevation);
|
||||||
|
}
|
||||||
|
}
|
||||||
_routes.append(Route(routeData.at(i)));
|
_routes.append(Route(routeData.at(i)));
|
||||||
|
}
|
||||||
for (int i = 0; i < _waypoints.size(); i++) {
|
for (int i = 0; i < _waypoints.size(); i++) {
|
||||||
if (!_waypoints.at(i).hasElevation() || _useDEM) {
|
if (!_waypoints.at(i).hasElevation() || _useDEM) {
|
||||||
qreal elevation = DEM::elevation(_waypoints.at(i).coordinates());
|
qreal elevation = DEM::elevation(_waypoints.at(i).coordinates());
|
||||||
@ -147,6 +172,7 @@ QString Data::formats()
|
|||||||
return
|
return
|
||||||
qApp->translate("Data", "Supported files") + " (" + supported + ");;"
|
qApp->translate("Data", "Supported files") + " (" + supported + ");;"
|
||||||
+ qApp->translate("Data", "CSV files") + " (*.csv);;"
|
+ qApp->translate("Data", "CSV files") + " (*.csv);;"
|
||||||
|
+ qApp->translate("Data", "CUP files") + " (*.cup);;"
|
||||||
+ qApp->translate("Data", "FIT files") + " (*.fit);;"
|
+ qApp->translate("Data", "FIT files") + " (*.fit);;"
|
||||||
#ifdef ENABLE_GEOJSON
|
#ifdef ENABLE_GEOJSON
|
||||||
+ qApp->translate("Data", "GeoJSON files") + " (*.geojson *.json);;"
|
+ qApp->translate("Data", "GeoJSON files") + " (*.geojson *.json);;"
|
||||||
@ -177,6 +203,4 @@ QStringList Data::filter()
|
|||||||
void Data::useDEM(bool use)
|
void Data::useDEM(bool use)
|
||||||
{
|
{
|
||||||
_useDEM = use;
|
_useDEM = use;
|
||||||
Route::useDEM(use);
|
|
||||||
Track::useDEM(use);
|
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,7 @@ public:
|
|||||||
static void useDEM(bool use);
|
static void useDEM(bool use);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processData(const QList<TrackData> &trackData,
|
void processData(QList<TrackData> &trackData, QList<RouteData> &routeData);
|
||||||
const QList<RouteData> &routeData);
|
|
||||||
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
|
@ -113,9 +113,12 @@ Coordinates EXIFParser::coordinates(TIFFFile &file, const IFDEntry &lon,
|
|||||||
if (!c.isValid())
|
if (!c.isValid())
|
||||||
return Coordinates();
|
return Coordinates();
|
||||||
|
|
||||||
if (lonRef.offset == 'W')
|
char ew = file.isBE() ? lonRef.offset >> 24 : lonRef.offset;
|
||||||
|
char ns = file.isBE() ? latRef.offset >> 24 : latRef.offset;
|
||||||
|
|
||||||
|
if (ew == 'W')
|
||||||
c.rlon() = -c.lon();
|
c.rlon() = -c.lon();
|
||||||
if (latRef.offset == 'S')
|
if (ns == 'S')
|
||||||
c.rlat() = -c.lat();
|
c.rlat() = -c.lat();
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
@ -87,13 +87,10 @@ template<class T> bool FITParser::readValue(CTX &ctx, T &val)
|
|||||||
|
|
||||||
ctx.len -= sizeof(T);
|
ctx.len -= sizeof(T);
|
||||||
|
|
||||||
if (sizeof(T) > 1) {
|
if (ctx.endian)
|
||||||
if (ctx.endian)
|
val = qFromBigEndian(data);
|
||||||
val = qFromBigEndian(data);
|
else
|
||||||
else
|
val = qFromLittleEndian(data);
|
||||||
val = qFromLittleEndian(data);
|
|
||||||
} else
|
|
||||||
val = data;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -268,6 +265,14 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
|
|||||||
if (val != 0x7f)
|
if (val != 0x7f)
|
||||||
ctx.trackpoint.setTemperature((qint8)val);
|
ctx.trackpoint.setTemperature((qint8)val);
|
||||||
break;
|
break;
|
||||||
|
case 73:
|
||||||
|
if (val != 0xffffffff)
|
||||||
|
ctx.trackpoint.setSpeed(val / 1000.0f);
|
||||||
|
break;
|
||||||
|
case 78:
|
||||||
|
if (val != 0xffffffff)
|
||||||
|
ctx.trackpoint.setElevation((val / 5.0) - 500);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasTime() const
|
bool hasTime() const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < size(); i++) {
|
for (int i = 0; i < size(); i++) {
|
||||||
|
@ -130,6 +130,8 @@ bool IGCParser::readBRecord(SegmentData &segment, const char *line,
|
|||||||
|
|
||||||
if (len < 35)
|
if (len < 35)
|
||||||
return false;
|
return false;
|
||||||
|
if (line[24] != 'A')
|
||||||
|
return true;
|
||||||
|
|
||||||
if (!readTimestamp(line + 1, time)) {
|
if (!readTimestamp(line + 1, time)) {
|
||||||
_errorString = "Invalid timestamp";
|
_errorString = "Invalid timestamp";
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
#include "dem.h"
|
|
||||||
#include "route.h"
|
#include "route.h"
|
||||||
|
|
||||||
|
|
||||||
bool Route::_useDEM = false;
|
|
||||||
|
|
||||||
Route::Route(const RouteData &data) : _data(data)
|
Route::Route(const RouteData &data) : _data(data)
|
||||||
{
|
{
|
||||||
qreal dist = 0;
|
qreal dist = 0;
|
||||||
@ -34,19 +31,9 @@ Graph Route::elevation() const
|
|||||||
graph.append(GraphSegment());
|
graph.append(GraphSegment());
|
||||||
GraphSegment &gs = graph.last();
|
GraphSegment &gs = graph.last();
|
||||||
|
|
||||||
for (int i = 0; i < _data.size(); i++) {
|
for (int i = 0; i < _data.size(); i++)
|
||||||
if (_data.at(i).hasElevation() && !_useDEM)
|
if (_data.at(i).hasElevation())
|
||||||
gs.append(GraphPoint(_distance.at(i), NAN,
|
gs.append(GraphPoint(_distance.at(i), NAN, _data.at(i).elevation()));
|
||||||
_data.at(i).elevation()));
|
|
||||||
else {
|
|
||||||
qreal elevation = DEM::elevation(_data.at(i).coordinates());
|
|
||||||
if (!std::isnan(elevation))
|
|
||||||
gs.append(GraphPoint(_distance.at(i), NAN, elevation));
|
|
||||||
else if (_data.at(i).hasElevation())
|
|
||||||
gs.append(GraphPoint(_distance.at(i), NAN,
|
|
||||||
_data.at(i).elevation()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ public:
|
|||||||
|
|
||||||
Path path() const;
|
Path path() const;
|
||||||
|
|
||||||
const QVector<Waypoint> &waypoints() const {return _data;}
|
const RouteData &data() const {return _data;}
|
||||||
|
|
||||||
Graph elevation() const;
|
Graph elevation() const;
|
||||||
|
|
||||||
@ -24,13 +24,9 @@ public:
|
|||||||
|
|
||||||
bool isValid() const {return _data.size() >= 2;}
|
bool isValid() const {return _data.size() >= 2;}
|
||||||
|
|
||||||
static void useDEM(bool use) {_useDEM = use;}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RouteData _data;
|
RouteData _data;
|
||||||
QVector<qreal> _distance;
|
QVector<qreal> _distance;
|
||||||
|
|
||||||
static bool _useDEM;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ROUTE_H
|
#endif // ROUTE_H
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#include "dem.h"
|
|
||||||
#include "track.h"
|
#include "track.h"
|
||||||
|
|
||||||
|
|
||||||
@ -13,7 +12,6 @@ int Track::_pauseInterval = 10;
|
|||||||
|
|
||||||
bool Track::_outlierEliminate = true;
|
bool Track::_outlierEliminate = true;
|
||||||
bool Track::_useReportedSpeed = false;
|
bool Track::_useReportedSpeed = false;
|
||||||
bool Track::_useDEM = false;
|
|
||||||
|
|
||||||
|
|
||||||
static qreal median(QVector<qreal> &v)
|
static qreal median(QVector<qreal> &v)
|
||||||
@ -178,21 +176,10 @@ Graph Track::elevation() const
|
|||||||
GraphSegment gs;
|
GraphSegment gs;
|
||||||
|
|
||||||
for (int j = 0; j < sd.size(); j++) {
|
for (int j = 0; j < sd.size(); j++) {
|
||||||
if (seg.outliers.contains(j))
|
if (!sd.at(j).hasElevation() || seg.outliers.contains(j))
|
||||||
continue;
|
continue;
|
||||||
|
gs.append(GraphPoint(seg.distance.at(j), seg.time.at(j),
|
||||||
if (sd.at(j).hasElevation() && !_useDEM)
|
sd.at(j).elevation()));
|
||||||
gs.append(GraphPoint(seg.distance.at(j), seg.time.at(j),
|
|
||||||
sd.at(j).elevation()));
|
|
||||||
else {
|
|
||||||
qreal elevation = DEM::elevation(sd.at(j).coordinates());
|
|
||||||
if (!std::isnan(elevation))
|
|
||||||
gs.append(GraphPoint(seg.distance.at(j), seg.time.at(j),
|
|
||||||
elevation));
|
|
||||||
else if (sd.at(j).hasElevation())
|
|
||||||
gs.append(GraphPoint(seg.distance.at(j), seg.time.at(j),
|
|
||||||
sd.at(j).elevation()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.append(filter(gs, _elevationWindow));
|
ret.append(filter(gs, _elevationWindow));
|
||||||
|
@ -45,7 +45,6 @@ public:
|
|||||||
static void setOutlierElimination(bool eliminate)
|
static void setOutlierElimination(bool eliminate)
|
||||||
{_outlierEliminate = eliminate;}
|
{_outlierEliminate = eliminate;}
|
||||||
static void useReportedSpeed(bool use) {_useReportedSpeed = use;}
|
static void useReportedSpeed(bool use) {_useReportedSpeed = use;}
|
||||||
static void useDEM(bool use) {_useDEM = use;}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Segment {
|
struct Segment {
|
||||||
@ -71,7 +70,6 @@ private:
|
|||||||
static qreal _pauseSpeed;
|
static qreal _pauseSpeed;
|
||||||
static int _pauseInterval;
|
static int _pauseInterval;
|
||||||
static bool _useReportedSpeed;
|
static bool _useReportedSpeed;
|
||||||
static bool _useDEM;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRACK_H
|
#endif // TRACK_H
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#define CHECK(condition) \
|
#define CHECK(condition) \
|
||||||
if (!(condition)) { \
|
if (!(condition)) { \
|
||||||
_errorString = "Invalid/corrupted IMG file"; \
|
_errorString = "Unsupported or invalid IMG file"; \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,13 +85,8 @@ IMG::IMG(const QString &fileName)
|
|||||||
&& read(type, sizeof(type)) && readValue(size) && readValue(part));
|
&& read(type, sizeof(type)) && readValue(size) && readValue(part));
|
||||||
SubFile::Type tt = SubFile::type(type);
|
SubFile::Type tt = SubFile::type(type);
|
||||||
|
|
||||||
if (tt == SubFile::GMP) {
|
|
||||||
_errorString = "NT maps not supported";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString fn(QByteArray(name, sizeof(name)));
|
QString fn(QByteArray(name, sizeof(name)));
|
||||||
if (VectorTile::isTileFile(tt)) {
|
if (SubFile::isTileFile(tt)) {
|
||||||
VectorTile *tile;
|
VectorTile *tile;
|
||||||
QMap<QString, VectorTile*>::iterator it = tileMap.find(fn);
|
QMap<QString, VectorTile*>::iterator it = tileMap.find(fn);
|
||||||
if (it == tileMap.end()) {
|
if (it == tileMap.end()) {
|
||||||
@ -101,7 +96,7 @@ IMG::IMG(const QString &fileName)
|
|||||||
tile = *it;
|
tile = *it;
|
||||||
|
|
||||||
SubFile *file = part ? tile->file(tt)
|
SubFile *file = part ? tile->file(tt)
|
||||||
: tile->addFile(this, tt, size);
|
: tile->addFile(this, tt);
|
||||||
CHECK(file);
|
CHECK(file);
|
||||||
|
|
||||||
_file.seek(offset + 0x20);
|
_file.seek(offset + 0x20);
|
||||||
@ -114,7 +109,7 @@ IMG::IMG(const QString &fileName)
|
|||||||
} else if (tt == SubFile::TYP) {
|
} else if (tt == SubFile::TYP) {
|
||||||
SubFile *typ = 0;
|
SubFile *typ = 0;
|
||||||
if (typFile.isNull()) {
|
if (typFile.isNull()) {
|
||||||
_typ = new SubFile(this, size);
|
_typ = new SubFile(this);
|
||||||
typ = _typ;
|
typ = _typ;
|
||||||
typFile = fn;
|
typFile = fn;
|
||||||
} else if (fn == typFile)
|
} else if (fn == typFile)
|
||||||
@ -166,7 +161,7 @@ void IMG::load()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(!_style);
|
Q_ASSERT(!_style);
|
||||||
|
|
||||||
if (_typ && _typ->isValid())
|
if (_typ)
|
||||||
_style = new Style(_typ);
|
_style = new Style(_typ);
|
||||||
else {
|
else {
|
||||||
QFile typFile(ProgramPaths::typFile());
|
QFile typFile(ProgramPaths::typFile());
|
||||||
@ -227,10 +222,7 @@ template<class T> bool IMG::readValue(T &val)
|
|||||||
if (read((char*)&data, sizeof(T)) < (qint64)sizeof(T))
|
if (read((char*)&data, sizeof(T)) < (qint64)sizeof(T))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (sizeof(T) > 1)
|
val = qFromLittleEndian(data);
|
||||||
val = qFromLittleEndian(data);
|
|
||||||
else
|
|
||||||
val = data;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#define FIRST_SHIELD Label::Shield::USInterstate
|
||||||
|
#define LAST_SHIELD Label::Shield::Oval
|
||||||
|
|
||||||
class Label {
|
class Label {
|
||||||
public:
|
public:
|
||||||
class Shield
|
class Shield
|
||||||
|
@ -35,7 +35,8 @@ static QString capitalize(const QString &str)
|
|||||||
if (str.isEmpty())
|
if (str.isEmpty())
|
||||||
return str;
|
return str;
|
||||||
for (int i = 0; i < str.size(); i++)
|
for (int i = 0; i < str.size(); i++)
|
||||||
if (str.at(i).isLetter() && !str.at(i).isUpper())
|
if (str.at(i).isLetter() && !(str.at(i).isUpper()
|
||||||
|
|| str.at(i) == QChar(0x00DF)))
|
||||||
return str;
|
return str;
|
||||||
|
|
||||||
QString ret(str);
|
QString ret(str);
|
||||||
@ -53,15 +54,18 @@ bool LBLFile::init()
|
|||||||
{
|
{
|
||||||
Handle hdl;
|
Handle hdl;
|
||||||
quint16 codepage;
|
quint16 codepage;
|
||||||
|
quint8 multiplier, poiMultiplier;
|
||||||
|
|
||||||
if (!(seek(hdl, 0x15) && readUInt32(hdl, _offset)
|
if (!(seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||||
&& readUInt32(hdl, _size) && readByte(hdl, _multiplier)
|
&& readUInt32(hdl, _size) && readByte(hdl, multiplier)
|
||||||
&& readByte(hdl, _encoding) && seek(hdl, 0x57)
|
&& readByte(hdl, _encoding) && seek(hdl, _gmpOffset + 0x57)
|
||||||
&& readUInt32(hdl, _poiOffset) && readUInt32(hdl, _poiSize)
|
&& readUInt32(hdl, _poiOffset) && readUInt32(hdl, _poiSize)
|
||||||
&& seek(hdl, 0xAA) && readUInt16(hdl, codepage)))
|
&& readByte(hdl, poiMultiplier) && seek(hdl, _gmpOffset + 0xAA)
|
||||||
|
&& readUInt16(hdl, codepage)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_multiplier = 1<<_multiplier;
|
_multiplier = 1<<multiplier;
|
||||||
|
_poiMultiplier = 1<<poiMultiplier;
|
||||||
|
|
||||||
if (codepage == 65001)
|
if (codepage == 65001)
|
||||||
_codec = QTextCodec::codecForName("UTF-8");
|
_codec = QTextCodec::codecForName("UTF-8");
|
||||||
@ -102,7 +106,8 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset) const
|
|||||||
else if (c[cpt] == 0x1b)
|
else if (c[cpt] == 0x1b)
|
||||||
curCharSet = Special;
|
curCharSet = Special;
|
||||||
else if (c[cpt] >= 0x2a && c[cpt] <= 0x2f) {
|
else if (c[cpt] >= 0x2a && c[cpt] <= 0x2f) {
|
||||||
shieldType = (Label::Shield::Type)(c[cpt] - 0x29);
|
shieldType = static_cast<Label::Shield::Type>
|
||||||
|
(c[cpt] - 0x29);
|
||||||
bap = &shieldLabel;
|
bap = &shieldLabel;
|
||||||
} else if (bap == &shieldLabel
|
} else if (bap == &shieldLabel
|
||||||
&& NORMAL_CHARS[c[cpt]] == ' ')
|
&& NORMAL_CHARS[c[cpt]] == ' ')
|
||||||
@ -145,7 +150,7 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset) const
|
|||||||
else
|
else
|
||||||
bap->append(' ');
|
bap->append(' ');
|
||||||
} else if (c <= 0x07) {
|
} else if (c <= 0x07) {
|
||||||
shieldType = (Label::Shield::Type)c;
|
shieldType = static_cast<Label::Shield::Type>(c);
|
||||||
bap = &shieldLabel;
|
bap = &shieldLabel;
|
||||||
} else if (bap == &shieldLabel && QChar(c).isSpace()) {
|
} else if (bap == &shieldLabel && QChar(c).isSpace()) {
|
||||||
bap = &label;
|
bap = &label;
|
||||||
@ -160,14 +165,15 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset) const
|
|||||||
|
|
||||||
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi)
|
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi)
|
||||||
{
|
{
|
||||||
if (!_size && !init())
|
if (!_multiplier && !init())
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
quint32 labelOffset;
|
quint32 labelOffset;
|
||||||
if (poi) {
|
if (poi) {
|
||||||
quint32 poiOffset;
|
quint32 poiOffset;
|
||||||
if (!(seek(hdl, _poiOffset + offset) && readUInt24(hdl, poiOffset)
|
if (!(_poiSize >= offset * _poiMultiplier
|
||||||
&& (poiOffset & 0x3FFFFF)))
|
&& seek(hdl, _poiOffset + offset * _poiMultiplier)
|
||||||
|
&& readUInt24(hdl, poiOffset) && (poiOffset & 0x3FFFFF)))
|
||||||
return QString();
|
return QString();
|
||||||
labelOffset = _offset + (poiOffset & 0x3FFFFF) * _multiplier;
|
labelOffset = _offset + (poiOffset & 0x3FFFFF) * _multiplier;
|
||||||
} else
|
} else
|
||||||
|
@ -9,9 +9,12 @@ class QTextCodec;
|
|||||||
class LBLFile : public SubFile
|
class LBLFile : public SubFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LBLFile(IMG *img, quint32 size)
|
LBLFile(IMG *img)
|
||||||
: SubFile(img, size), _offset(0), _size(0), _poiOffset(0), _poiSize(0),
|
: SubFile(img), _codec(0), _offset(0), _size(0), _poiOffset(0),
|
||||||
_multiplier(0), _encoding(0), _codec(0) {}
|
_poiSize(0), _poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||||
|
LBLFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||||
|
_codec(0), _offset(0), _size(0), _poiOffset(0), _poiSize(0),
|
||||||
|
_poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||||
|
|
||||||
Label label(Handle &hdl, quint32 offset, bool poi = false);
|
Label label(Handle &hdl, quint32 offset, bool poi = false);
|
||||||
|
|
||||||
@ -21,13 +24,14 @@ private:
|
|||||||
Label label6b(Handle &hdl, quint32 offset) const;
|
Label label6b(Handle &hdl, quint32 offset) const;
|
||||||
Label label8b(Handle &hdl, quint32 offset) const;
|
Label label8b(Handle &hdl, quint32 offset) const;
|
||||||
|
|
||||||
|
QTextCodec *_codec;
|
||||||
quint32 _offset;
|
quint32 _offset;
|
||||||
quint32 _size;
|
quint32 _size;
|
||||||
quint32 _poiOffset;
|
quint32 _poiOffset;
|
||||||
quint32 _poiSize;
|
quint32 _poiSize;
|
||||||
|
quint8 _poiMultiplier;
|
||||||
quint8 _multiplier;
|
quint8 _multiplier;
|
||||||
quint8 _encoding;
|
quint8 _encoding;
|
||||||
QTextCodec *_codec;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LBLFILE_H
|
#endif // LBLFILE_H
|
||||||
|
@ -3,22 +3,21 @@
|
|||||||
bool NETFile::init()
|
bool NETFile::init()
|
||||||
{
|
{
|
||||||
Handle hdl;
|
Handle hdl;
|
||||||
|
quint8 multiplier;
|
||||||
|
|
||||||
if (!(seek(hdl, 0x15) && readUInt32(hdl, _offset)
|
if (!(seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||||
&& readUInt32(hdl, _size) && readByte(hdl, _multiplier)))
|
&& readUInt32(hdl, _size) && readByte(hdl, multiplier)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_multiplier = 1<<_multiplier;
|
_multiplier = 1<<multiplier;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NETFile::lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset)
|
bool NETFile::lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset)
|
||||||
{
|
{
|
||||||
if (!_init) {
|
if (!_multiplier && !init())
|
||||||
if (!(_init = init()))
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(seek(hdl, _offset + netOffset * _multiplier)
|
if (!(seek(hdl, _offset + netOffset * _multiplier)
|
||||||
&& readUInt24(hdl, lblOffset)))
|
&& readUInt24(hdl, lblOffset)))
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
class NETFile : public SubFile
|
class NETFile : public SubFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NETFile(IMG *img, quint32 size) : SubFile(img, size), _init(false) {}
|
NETFile(IMG *img) : SubFile(img), _offset(0), _size(0), _multiplier(0) {}
|
||||||
|
NETFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||||
|
_offset(0), _size(0), _multiplier(0) {}
|
||||||
|
|
||||||
bool lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset);
|
bool lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset);
|
||||||
|
|
||||||
@ -16,8 +18,6 @@ private:
|
|||||||
quint32 _offset;
|
quint32 _offset;
|
||||||
quint32 _size;
|
quint32 _size;
|
||||||
quint8 _multiplier;
|
quint8 _multiplier;
|
||||||
|
|
||||||
bool _init;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NETFILE_H
|
#endif // NETFILE_H
|
||||||
|
@ -1,10 +1,26 @@
|
|||||||
#include "trefile.h"
|
#include "common/rectc.h"
|
||||||
#include "units.h"
|
#include "units.h"
|
||||||
#include "lblfile.h"
|
#include "lblfile.h"
|
||||||
#include "netfile.h"
|
#include "netfile.h"
|
||||||
#include "rgnfile.h"
|
#include "rgnfile.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int bitSize(quint8 baseSize, bool variableSign, bool extraBit)
|
||||||
|
{
|
||||||
|
int bits = 2;
|
||||||
|
if (baseSize <= 9)
|
||||||
|
bits += baseSize;
|
||||||
|
else
|
||||||
|
bits += 2 * baseSize - 9;
|
||||||
|
|
||||||
|
if (variableSign)
|
||||||
|
bits++;
|
||||||
|
if (extraBit)
|
||||||
|
bits++;
|
||||||
|
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
bool RGNFile::BitStream::read(int bits, quint32 &val)
|
bool RGNFile::BitStream::read(int bits, quint32 &val)
|
||||||
{
|
{
|
||||||
val = 0;
|
val = 0;
|
||||||
@ -34,29 +50,42 @@ bool RGNFile::BitStream::read(int bits, quint32 &val)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RGNFile::BitStream::readDelta(int bits, int sign, bool extraBit,
|
RGNFile::DeltaStream::DeltaStream(const SubFile &file, Handle &hdl,
|
||||||
|
quint32 length, quint8 info, bool extraBit, bool extended)
|
||||||
|
: BitStream(file, hdl, length), _readBits(0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
_extraBit = extraBit ? 1 : 0;
|
||||||
|
if (!(sign(_lonSign) && sign(_latSign)))
|
||||||
|
return;
|
||||||
|
if (extended) {
|
||||||
|
quint32 b;
|
||||||
|
if (!read(1, b))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_lonBits = bitSize(info & 0x0F, !_lonSign, extraBit);
|
||||||
|
_latBits = bitSize(info >> 4, !_latSign, false);
|
||||||
|
_readBits = _lonBits + _latBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RGNFile::DeltaStream::readDelta(int bits, int sign, int extraBit,
|
||||||
qint32 &delta)
|
qint32 &delta)
|
||||||
{
|
{
|
||||||
quint32 value;
|
quint32 value;
|
||||||
int bo = 0;
|
|
||||||
|
|
||||||
if (!read(bits, value))
|
if (!read(bits, value))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (extraBit) {
|
value >>= extraBit;
|
||||||
value>>=1;
|
|
||||||
bo = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sign) {
|
if (!sign) {
|
||||||
qint32 signMask = 1 << (bits - bo - 1);
|
qint32 signMask = 1 << (bits - extraBit - 1);
|
||||||
if (value & signMask) {
|
if (value & signMask) {
|
||||||
qint32 comp = value ^ signMask;
|
qint32 comp = value ^ signMask;
|
||||||
if (comp)
|
if (comp)
|
||||||
delta = comp - signMask;
|
delta = comp - signMask;
|
||||||
else {
|
else {
|
||||||
qint32 other;
|
qint32 other;
|
||||||
if (!readDelta(bits - bo, sign, false, other))
|
if (!readDelta(bits - extraBit, sign, false, other))
|
||||||
return false;
|
return false;
|
||||||
if (other < 0)
|
if (other < 0)
|
||||||
delta = 1 - signMask + other;
|
delta = 1 - signMask + other;
|
||||||
@ -73,42 +102,15 @@ bool RGNFile::BitStream::readDelta(int bits, int sign, bool extraBit,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RGNFile::BitStream::finish()
|
bool RGNFile::DeltaStream::sign(int &val)
|
||||||
{
|
|
||||||
while (_length--)
|
|
||||||
if (!_file.readByte(_hdl, _data))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool RGNFile::init()
|
|
||||||
{
|
|
||||||
Handle hdl;
|
|
||||||
|
|
||||||
if (!(seek(hdl, 0x15) && readUInt32(hdl, _offset)
|
|
||||||
&& readUInt32(hdl, _size) && readUInt32(hdl, _polygonsOffset)
|
|
||||||
&& readUInt32(hdl, _polygonsSize) && seek(hdl, 0x39)
|
|
||||||
&& readUInt32(hdl, _linesOffset) && readUInt32(hdl, _linesSize)
|
|
||||||
&& seek(hdl, 0x55) && readUInt32(hdl, _pointsOffset)
|
|
||||||
&& readUInt32(hdl, _pointsSize)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (_offset + _size > size())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RGNFile::sign(BitStream &bs, int &val)
|
|
||||||
{
|
{
|
||||||
quint32 bit;
|
quint32 bit;
|
||||||
val = 0;
|
val = 0;
|
||||||
|
|
||||||
if (!bs.read(1, bit))
|
if (!read(1, bit))
|
||||||
return false;
|
return false;
|
||||||
if (bit) {
|
if (bit) {
|
||||||
if (!bs.read(1, bit))
|
if (!read(1, bit))
|
||||||
return false;
|
return false;
|
||||||
val = bit ? -1 : 1;
|
val = bit ? -1 : 1;
|
||||||
}
|
}
|
||||||
@ -116,20 +118,41 @@ bool RGNFile::sign(BitStream &bs, int &val)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RGNFile::bitSize(quint8 baseSize, bool variableSign, bool extraBit)
|
|
||||||
|
bool RGNFile::init()
|
||||||
{
|
{
|
||||||
int bits = 2;
|
Handle hdl;
|
||||||
if (baseSize <= 9)
|
quint16 hdrLen;
|
||||||
bits += baseSize;
|
|
||||||
else
|
|
||||||
bits += 2 * baseSize - 9;
|
|
||||||
|
|
||||||
if (variableSign)
|
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)
|
||||||
bits++;
|
&& seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||||
if (extraBit)
|
&& readUInt32(hdl, _size)))
|
||||||
bits++;
|
return false;
|
||||||
|
|
||||||
return bits;
|
if (hdrLen >= 0x5D) {
|
||||||
|
if (!(readUInt32(hdl, _polygonsOffset) && readUInt32(hdl, _polygonsSize)
|
||||||
|
&& seek(hdl, _gmpOffset + 0x39) && readUInt32(hdl, _linesOffset)
|
||||||
|
&& readUInt32(hdl, _linesSize) && seek(hdl, _gmpOffset + 0x55)
|
||||||
|
&& readUInt32(hdl, _pointsOffset) && readUInt32(hdl, _pointsSize)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdrLen >= 0x7D) {
|
||||||
|
quint32 dictOffset, dictSize;
|
||||||
|
if (!(seek(hdl, _gmpOffset + 0x71) && readUInt32(hdl, dictOffset)
|
||||||
|
&& readUInt32(hdl, dictSize)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// NT maps
|
||||||
|
if (dictSize || dictOffset) {
|
||||||
|
qWarning("NT compression not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_init = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||||
@ -167,28 +190,17 @@ bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
|||||||
poly.type = (segment.type() == Segment::Polygon)
|
poly.type = (segment.type() == Segment::Polygon)
|
||||||
? ((quint32)(type & 0x7F)) << 8 : ((quint32)(type & 0x3F)) << 8;
|
? ((quint32)(type & 0x7F)) << 8 : ((quint32)(type & 0x3F)) << 8;
|
||||||
|
|
||||||
RectC br;
|
|
||||||
QPoint pos(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())),
|
QPoint pos(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())),
|
||||||
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits())));
|
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits())));
|
||||||
Coordinates c(toWGS84(pos.x()), toWGS84(pos.y()));
|
Coordinates c(toWGS84(pos.x()), toWGS84(pos.y()));
|
||||||
br = br.united(c);
|
RectC br(c, c);
|
||||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||||
|
|
||||||
BitStream bs(*this, hdl, len);
|
qint32 lonDelta, latDelta;
|
||||||
int lonSign, latSign;
|
DeltaStream stream(*this, hdl, len, bitstreamInfo, labelPtr & 0x400000,
|
||||||
if (!sign(bs, lonSign) || !sign(bs, latSign))
|
false);
|
||||||
return false;
|
while (stream.readNext(lonDelta, latDelta)) {
|
||||||
bool extraBit = labelPtr & 0x400000;
|
|
||||||
int lonBits = bitSize(bitstreamInfo & 0x0F, !lonSign, extraBit);
|
|
||||||
int latBits = bitSize(bitstreamInfo >> 4, !latSign, false);
|
|
||||||
|
|
||||||
while (bs.hasNext(lonBits + latBits)) {
|
|
||||||
qint32 lonDelta, latDelta;
|
|
||||||
|
|
||||||
if (!(bs.readDelta(lonBits, lonSign, extraBit, lonDelta)
|
|
||||||
&& bs.readDelta(latBits, latSign, false, latDelta)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
pos.rx() += lonDelta<<(24-subdiv->bits());
|
pos.rx() += lonDelta<<(24-subdiv->bits());
|
||||||
pos.ry() += latDelta<<(24-subdiv->bits());
|
pos.ry() += latDelta<<(24-subdiv->bits());
|
||||||
|
|
||||||
@ -196,7 +208,7 @@ bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
|||||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||||
br = br.united(c);
|
br = br.united(c);
|
||||||
}
|
}
|
||||||
if (!bs.finish())
|
if (!(stream.atEnd() && stream.flush()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!rect.intersects(br))
|
if (!rect.intersects(br))
|
||||||
@ -222,10 +234,9 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
|||||||
const SubDiv *subdiv, const Segment &segment, LBLFile *lbl, Handle &lblHdl,
|
const SubDiv *subdiv, const Segment &segment, LBLFile *lbl, Handle &lblHdl,
|
||||||
QList<IMG::Poly> *polys) const
|
QList<IMG::Poly> *polys) const
|
||||||
{
|
{
|
||||||
quint32 labelPtr;
|
quint32 len, labelPtr = 0;
|
||||||
quint8 type, subtype, len8, len82, bitstreamInfo;
|
quint8 type, subtype, bitstreamInfo;
|
||||||
qint16 lon, lat;
|
qint16 lon, lat;
|
||||||
quint16 len;
|
|
||||||
|
|
||||||
|
|
||||||
if (!seek(hdl, segment.start()))
|
if (!seek(hdl, segment.start()))
|
||||||
@ -235,7 +246,8 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
|||||||
IMG::Poly poly;
|
IMG::Poly poly;
|
||||||
|
|
||||||
if (!(readByte(hdl, type) && readByte(hdl, subtype)
|
if (!(readByte(hdl, type) && readByte(hdl, subtype)
|
||||||
&& readInt16(hdl, lon) && readInt16(hdl, lat) && readByte(hdl, len8)))
|
&& readInt16(hdl, lon) && readInt16(hdl, lat)
|
||||||
|
&& readVUInt32(hdl, len) && readByte(hdl, bitstreamInfo)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (subtype & 0x80) {
|
if (subtype & 0x80) {
|
||||||
@ -243,40 +255,17 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len8 & 0x01)
|
|
||||||
len = (len8>>1) - 1;
|
|
||||||
else {
|
|
||||||
if (!readByte(hdl, len82))
|
|
||||||
return false;
|
|
||||||
len = ((len8 | ((quint16)len82<<8))>>2) - 1;
|
|
||||||
}
|
|
||||||
if (!readByte(hdl, bitstreamInfo))
|
|
||||||
return false;
|
|
||||||
poly.type = 0x10000 + (quint16(type) << 8) + (subtype & 0x1F);
|
poly.type = 0x10000 + (quint16(type) << 8) + (subtype & 0x1F);
|
||||||
|
|
||||||
RectC br;
|
|
||||||
QPoint pos(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())),
|
QPoint pos(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())),
|
||||||
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits())));
|
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits())));
|
||||||
Coordinates c(toWGS84(pos.x()), toWGS84(pos.y()));
|
Coordinates c(toWGS84(pos.x()), toWGS84(pos.y()));
|
||||||
br = br.united(c);
|
RectC br(c, c);
|
||||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||||
|
|
||||||
BitStream bs(*this, hdl, len);
|
qint32 lonDelta, latDelta;
|
||||||
int lonSign, latSign;
|
DeltaStream stream(*this, hdl, len - 1, bitstreamInfo, false, true);
|
||||||
if (!sign(bs, lonSign) || !sign(bs, latSign))
|
while (stream.readNext(lonDelta, latDelta)) {
|
||||||
return false;
|
|
||||||
quint32 extraBit;
|
|
||||||
bs.read(1, extraBit);
|
|
||||||
int lonBits = bitSize(bitstreamInfo & 0x0F, !lonSign, extraBit);
|
|
||||||
int latBits = bitSize(bitstreamInfo >> 4, !latSign, extraBit);
|
|
||||||
|
|
||||||
while (bs.hasNext(lonBits + latBits)) {
|
|
||||||
qint32 lonDelta, latDelta;
|
|
||||||
|
|
||||||
if (!(bs.readDelta(lonBits, lonSign, false, lonDelta)
|
|
||||||
&& bs.readDelta(latBits, latSign, false, latDelta)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
pos.rx() += lonDelta<<(24-subdiv->bits());
|
pos.rx() += lonDelta<<(24-subdiv->bits());
|
||||||
pos.ry() += latDelta<<(24-subdiv->bits());
|
pos.ry() += latDelta<<(24-subdiv->bits());
|
||||||
|
|
||||||
@ -284,19 +273,21 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
|||||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||||
br = br.united(c);
|
br = br.united(c);
|
||||||
}
|
}
|
||||||
if (!bs.finish())
|
if (!(stream.atEnd() && stream.flush()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (subtype & 0x20) {
|
if ((subtype & 0x20)) {
|
||||||
if (!readUInt24(hdl, labelPtr))
|
if (!readUInt24(hdl, labelPtr))
|
||||||
return false;
|
return false;
|
||||||
if (lbl && (labelPtr & 0x3FFFFF))
|
} else
|
||||||
poly.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
|
labelPtr = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (!rect.intersects(br))
|
if (!rect.intersects(br))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (lbl && (labelPtr & 0x3FFFFF))
|
||||||
|
poly.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
|
||||||
|
|
||||||
polys->append(poly);
|
polys->append(poly);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +395,7 @@ void RGNFile::objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
|
|||||||
{
|
{
|
||||||
Handle rgnHdl, lblHdl, netHdl;
|
Handle rgnHdl, lblHdl, netHdl;
|
||||||
|
|
||||||
if (!_size && !init())
|
if (!_init && !init())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QVector<RGNFile::Segment> seg(segments(rgnHdl, subdiv));
|
QVector<RGNFile::Segment> seg(segments(rgnHdl, subdiv));
|
||||||
@ -436,7 +427,7 @@ void RGNFile::extObjects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
|
|||||||
{
|
{
|
||||||
Handle rgnHdl, lblHdl;
|
Handle rgnHdl, lblHdl;
|
||||||
|
|
||||||
if (!_size && !init())
|
if (!_init && !init())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (polygons && subdiv->polygonsOffset() != subdiv->polygonsEnd()) {
|
if (polygons && subdiv->polygonsOffset() != subdiv->polygonsEnd()) {
|
||||||
@ -459,7 +450,7 @@ void RGNFile::extObjects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
|
|||||||
quint32 start = _pointsOffset + subdiv->pointsOffset();
|
quint32 start = _pointsOffset + subdiv->pointsOffset();
|
||||||
quint32 end = subdiv->pointsEnd()
|
quint32 end = subdiv->pointsEnd()
|
||||||
? _pointsOffset + subdiv->pointsEnd()
|
? _pointsOffset + subdiv->pointsEnd()
|
||||||
: _pointsOffset + _linesSize;
|
: _pointsOffset + _pointsSize;
|
||||||
extPointObjects(rect, rgnHdl, subdiv, Segment(start, end,
|
extPointObjects(rect, rgnHdl, subdiv, Segment(start, end,
|
||||||
Segment::Point), lbl, lblHdl, points);
|
Segment::Point), lbl, lblHdl, points);
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,13 @@ class NETFile;
|
|||||||
class RGNFile : public SubFile
|
class RGNFile : public SubFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RGNFile(IMG *img, quint32 size)
|
RGNFile(IMG *img)
|
||||||
: SubFile(img, size), _offset(0), _size(0), _polygonsOffset(0),
|
: SubFile(img), _offset(0), _size(0), _polygonsOffset(0),
|
||||||
_polygonsSize(), _linesOffset(), _linesSize(), _pointsOffset(),
|
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
|
||||||
_pointsSize() {}
|
_pointsSize(0), _init(false) {}
|
||||||
|
RGNFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset), _offset(0),
|
||||||
|
_size(0), _polygonsOffset(0), _polygonsSize(0), _linesOffset(0),
|
||||||
|
_linesSize(0), _pointsOffset(0), _pointsSize(0), _init(false) {}
|
||||||
|
|
||||||
void objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
|
void objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
|
||||||
NETFile *net, QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
NETFile *net, QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
||||||
@ -53,27 +56,45 @@ private:
|
|||||||
|
|
||||||
class BitStream {
|
class BitStream {
|
||||||
public:
|
public:
|
||||||
BitStream(const SubFile &file, Handle &hdl, quint16 length)
|
BitStream(const SubFile &file, Handle &hdl, quint32 length)
|
||||||
: _file(file), _hdl(hdl), _length(length), _remaining(0) {}
|
: _file(file), _hdl(hdl), _length(length), _remaining(0) {}
|
||||||
|
|
||||||
bool read(int bits, quint32 &val);
|
bool read(int bits, quint32 &val);
|
||||||
bool readDelta(int bits, int sign, bool extraBit, qint32 &delta);
|
bool flush() {return _file.seek(_hdl, _hdl.pos + _length);}
|
||||||
bool hasNext(int bits) const
|
quint32 bitsAvailable() const {return _length * 8 + _remaining;}
|
||||||
{return _length * 8 + _remaining >= (quint32)bits;}
|
|
||||||
bool finish();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const SubFile &_file;
|
const SubFile &_file;
|
||||||
Handle &_hdl;
|
Handle &_hdl;
|
||||||
quint16 _length;
|
quint32 _length, _remaining;
|
||||||
quint32 _remaining;
|
|
||||||
quint8 _data;
|
quint8 _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool sign(BitStream &bs, int &val);
|
class DeltaStream : public BitStream {
|
||||||
static int bitSize(quint8 baseSize, bool variableSign, bool extraBit);
|
public:
|
||||||
|
DeltaStream(const SubFile &file, Handle &hdl, quint32 length,
|
||||||
|
quint8 info, bool extraBit, bool extended);
|
||||||
|
|
||||||
|
bool readNext(qint32 &lonDelta, qint32 &latDelta)
|
||||||
|
{
|
||||||
|
return hasNext()
|
||||||
|
? (readDelta(_lonBits, _lonSign, _extraBit, lonDelta)
|
||||||
|
&& readDelta(_latBits, _latSign, false, latDelta))
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
bool atEnd() const {return (_readBits != 0xFFFFFFFF && !hasNext());}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool hasNext() const {return bitsAvailable() >= _readBits;}
|
||||||
|
bool sign(int &val);
|
||||||
|
bool readDelta(int bits, int sign, int extraBit, qint32 &delta);
|
||||||
|
|
||||||
|
int _lonSign, _latSign, _extraBit;
|
||||||
|
quint32 _lonBits, _latBits, _readBits;
|
||||||
|
};
|
||||||
|
|
||||||
bool init();
|
bool init();
|
||||||
|
|
||||||
QVector<Segment> segments(Handle &hdl, const SubDiv *subdiv) const;
|
QVector<Segment> segments(Handle &hdl, const SubDiv *subdiv) const;
|
||||||
bool polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
bool polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||||
const Segment &segment, LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
const Segment &segment, LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||||
@ -99,6 +120,8 @@ private:
|
|||||||
quint32 _linesSize;
|
quint32 _linesSize;
|
||||||
quint32 _pointsOffset;
|
quint32 _pointsOffset;
|
||||||
quint32 _pointsSize;
|
quint32 _pointsSize;
|
||||||
|
|
||||||
|
bool _init;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
|
@ -942,7 +942,7 @@ Style::Style(SubFile *typ)
|
|||||||
defaultPolygonStyle();
|
defaultPolygonStyle();
|
||||||
defaultPointStyle();
|
defaultPointStyle();
|
||||||
|
|
||||||
if (typ && typ->isValid())
|
if (typ)
|
||||||
parseTYPFile(typ);
|
parseTYPFile(typ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,21 +20,13 @@ SubFile::Type SubFile::type(const char str[3])
|
|||||||
return Unknown;
|
return Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
SubFile::SubFile(QFile *file) : _img(0), _file(file), _size(0)
|
SubFile::SubFile(QFile *file) :_gmpOffset(0), _img(0), _file(file), _blocks(0)
|
||||||
{
|
{
|
||||||
if (!_file->open(QIODevice::ReadOnly))
|
if (!_file->open(QIODevice::ReadOnly))
|
||||||
qWarning("Error opening %s: %s", qPrintable(_file->fileName()),
|
qWarning("Error opening %s: %s", qPrintable(_file->fileName()),
|
||||||
qPrintable(_file->errorString()));
|
qPrintable(_file->errorString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SubFile::isValid() const
|
|
||||||
{
|
|
||||||
return _file
|
|
||||||
? _file->isOpen()
|
|
||||||
: ((quint32)_img->blockSize() * (quint32)_blocks.size() - _size
|
|
||||||
< (quint32)_img->blockSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SubFile::seek(Handle &handle, quint32 pos) const
|
bool SubFile::seek(Handle &handle, quint32 pos) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(_img || _file);
|
Q_ASSERT(_img || _file);
|
||||||
@ -46,9 +38,9 @@ bool SubFile::seek(Handle &handle, quint32 pos) const
|
|||||||
int blockNum = pos / blockSize;
|
int blockNum = pos / blockSize;
|
||||||
|
|
||||||
if (handle.blockNum != blockNum) {
|
if (handle.blockNum != blockNum) {
|
||||||
if (blockNum >= _blocks.size())
|
if (blockNum >= _blocks->size())
|
||||||
return false;
|
return false;
|
||||||
if (!_img->readBlock(_blocks.at(blockNum), handle.data))
|
if (!_img->readBlock(_blocks->at(blockNum), handle.data))
|
||||||
return false;
|
return false;
|
||||||
handle.blockNum = blockNum;
|
handle.blockNum = blockNum;
|
||||||
}
|
}
|
||||||
@ -74,29 +66,55 @@ bool SubFile::readByte(Handle &handle, quint8 &val) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 SubFile::size() const
|
bool SubFile::readVUInt32(Handle &hdl, quint32 &val) const
|
||||||
{
|
{
|
||||||
return _img ? _size : (quint32)_file->size();
|
quint8 bytes, shift, b;
|
||||||
|
|
||||||
|
if (!readByte(hdl, b))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((b & 1) == 0) {
|
||||||
|
if ((b & 2) == 0) {
|
||||||
|
bytes = ((b >> 2) & 1) ^ 3;
|
||||||
|
shift = 5;
|
||||||
|
} else {
|
||||||
|
shift = 6;
|
||||||
|
bytes = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shift = 7;
|
||||||
|
bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = b >> (8 - shift);
|
||||||
|
|
||||||
|
for (int i = 1; i <= bytes; i++) {
|
||||||
|
if (!readByte(hdl, b))
|
||||||
|
return false;
|
||||||
|
val |= (((quint32)b) << (i * 8)) >> (8 - shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SubFile::fileName() const
|
QString SubFile::fileName() const
|
||||||
{
|
{
|
||||||
return _img ? _img->fileName() : _file->fileName();
|
return _file ? _file->fileName() : _img->fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
QDebug operator<<(QDebug dbg, const SubFile &file)
|
QDebug operator<<(QDebug dbg, const SubFile &file)
|
||||||
{
|
{
|
||||||
bool continuous = true;
|
bool continuous = true;
|
||||||
for (int i = 1; i < file._blocks.size(); i++) {
|
for (int i = 1; i < file._blocks->size(); i++) {
|
||||||
if (file._blocks.at(i) != file._blocks.at(i-1) + 1) {
|
if (file._blocks->at(i) != file._blocks->at(i-1) + 1) {
|
||||||
continuous = false;
|
continuous = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg.nospace() << "SubFile(" << file._size << ", " << file._blocks.size()
|
dbg.nospace() << "SubFile(" << file._blocks->size() << ", "
|
||||||
<< ", " << continuous << ")";
|
<< continuous << ")";
|
||||||
return dbg.space();
|
return dbg.space();
|
||||||
}
|
}
|
||||||
#endif // QT_NO_DEBUG
|
#endif // QT_NO_DEBUG
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user