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

Compare commits

...

122 Commits
7.35 ... 7.38

Author SHA1 Message Date
84d5673e17 Merge branch 'origin/master' into Weblate. 2020-12-15 21:51:38 +01:00
e40836e6bb Added missing file associations + icons 2020-12-15 21:51:08 +01:00
88aef38f9d Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (383 of 383 strings)

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

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

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

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

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

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

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

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

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-11-25 17:29:14 +01:00
609e73256a Back to the original graph tab layout/style on OS X 2020-11-24 21:11:32 +01:00
50c43dc0b7 Merge branch 'origin/master' into Weblate. 2020-11-23 22:28:18 +01:00
b6194d535e Version++ 2020-11-23 22:28:11 +01:00
a4906050b8 Merge branch 'origin/master' into Weblate. 2020-11-23 22:26:47 +01:00
d1d0341ce5 Fixed PNG export when the file has not a ".png" extension 2020-11-23 22:26:15 +01:00
1b27be6173 Draw the graph tabs area more style aware 2020-11-23 22:20:06 +01:00
2eed9884a5 Fixed graph lines start/end exceeding the graph area 2020-11-23 22:17:19 +01:00
afee454b92 Merge branch 'origin/master' into Weblate. 2020-11-23 00:10:05 +01:00
8ade76b9f4 Improved form layout on OS X 2020-11-23 00:09:17 +01:00
45ca0f306c Merge branch 'origin/master' into Weblate. 2020-11-22 23:42:33 +01:00
faf445d708 Fixed broken label bounding box computation 2020-11-22 23:41:58 +01:00
7ed4821e81 Merge branch 'origin/master' into Weblate. 2020-11-22 14:52:06 +01:00
524a854d35 Code cleanup 2020-11-22 14:51:57 +01:00
800189cec5 Merge branch 'origin/master' into Weblate. 2020-11-22 14:39:44 +01:00
dc209bd96e Yet another graph zoom improvement
(and yet not ideal...)
2020-11-22 14:38:52 +01:00
d71b9f5e19 Merge branch 'origin/master' into Weblate. 2020-11-21 20:38:49 +01:00
781bc8c38f Improved graph zooming
(however, still not perfect...)
2020-11-21 20:37:22 +01:00
a49c2cd7c2 Merge branch 'origin/master' into Weblate. 2020-11-19 21:48:55 +01:00
75bd542feb A more sane (and usefull) angular units compare 2020-11-19 21:47:45 +01:00
c43a68c3b0 Inform about the whole parameter combination that failed to load 2020-11-19 21:46:25 +01:00
d211371ed0 Translated using Weblate (Hungarian)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-11-18 10:29:05 +01:00
eaed49786a Merge branch 'origin/master' into Weblate. 2020-11-15 22:38:30 +01:00
baf574b68b Process all the ll2xy operations in parallel 2020-11-15 22:38:22 +01:00
f4561ba0b5 Merge branch 'origin/master' into Weblate. 2020-11-15 20:10:15 +01:00
c120ad9715 Translated using Weblate (Ukrainian)
Currently translated at 99.7% (375 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-11-15 20:10:15 +01:00
0f49beeff5 Translated using Weblate (Turkish)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-11-15 20:10:15 +01:00
f2bfd5711b Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.7% (375 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2020-11-15 20:10:14 +01:00
3d43a0e472 Translated using Weblate (Russian)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-11-15 20:10:14 +01:00
049ca264b2 Translated using Weblate (Finnish)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-11-15 20:10:14 +01:00
3635a7dfdc Specified GPL license version 2020-11-15 20:10:08 +01:00
2ae572ba88 Translated using Weblate (Swedish)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-11-15 19:12:20 +01:00
5fac30c962 Localization update 2020-11-15 12:26:53 +01:00
4e29801d9a Explicitly specify the NIMA source code based files 2020-11-14 22:36:17 +01:00
0ace6da8a3 Fixed Qt4 build 2020-11-13 23:43:52 +01:00
cfcaa72cd2 Added licenses info 2020-11-13 23:00:30 +01:00
1b1f706c5c Added R-tree implementation info/license 2020-11-13 22:45:29 +01:00
b4d240d8fe Added "copy coordinates to clipboard"
closes #291
2020-11-13 20:15:17 +01:00
ed9ebfffac Use the propper type in friend declaration 2020-11-11 23:15:12 +01:00
fa03ecd419 Use the propper array delete operator 2020-11-11 18:47:34 +01:00
609202fe57 Fixed broken QObject parenting 2020-11-11 18:46:26 +01:00
f55d6d8501 API cleanup 2020-11-10 20:14:59 +01:00
731b309ac9 Remove the special timestamps check from the FIT parser
(Use the common logic in the Track class instead)
2020-11-10 20:07:46 +01:00
f85977d881 Merge branch 'origin/master' into Weblate. 2020-11-10 01:04:34 +01:00
12e395270b Version++ 2020-11-10 01:04:28 +01:00
45b637ba17 Merge branch 'origin/master' into Weblate. 2020-11-10 00:58:58 +01:00
f139d33502 Huffman encoded labels
+ more or less related fixes/refactoring
2020-11-10 00:58:19 +01:00
63e7735abe Translated using Weblate (French)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fr/
2020-11-03 15:20:23 +01:00
27122f94ef Merge branch 'origin/master' into Weblate. 2020-11-02 20:16:38 +01:00
0644bb72a0 Broken subdivs are more common than one would expect... 2020-11-02 20:16:02 +01:00
a4d14511de Merge branch 'origin/master' into Weblate. 2020-11-02 00:19:09 +01:00
1225d350d4 Allow broken subdiv bounds produced by mkgmap 2020-11-02 00:18:27 +01:00
a1d93cc548 Merge branch 'origin/master' into Weblate. 2020-11-01 23:48:14 +01:00
80f5bbfbce Print a warning on invalid subdiv bounds 2020-11-01 23:47:44 +01:00
70c9431ee4 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-10-28 14:26:59 +01:00
de7664ccc7 Added PNG export info 2020-10-28 12:15:46 +01:00
140 changed files with 7752 additions and 4271 deletions

View File

@ -1,4 +1,4 @@
version: 7.35.{build}
version: 7.38.{build}
configuration:
- Release

View File

@ -9,7 +9,7 @@ GPXSee is a Qt-based GPS log file viewer and analyzer that supports all common G
* Support for DEM files (SRTM HGT).
* Support for multiple tracks in one view.
* Support for POI files.
* Print/export to PDF.
* Print/export to PDF/PNG.
* Full-screen mode.
* HiDPI/Retina displays & maps support.
* Native GUI for Windows, Mac OS X and Linux.
@ -43,3 +43,14 @@ make # nmake on windows
## Translations
GPXSee uses [Weblate](https://hosted.weblate.org/projects/gpxsee/translations/) for translations.
## License
GPXSee is licensed under GPL-3.0 (only). However, some 3rd party parts are using different, GPL compatible,
licenses:
* [Oxygen icons](icons/GUI) - LGPLv3
* [Mapbox Maki icons](icons/POI) - CC0
* [RTree implementation](src/common/rtree.h) - Public domain
* [Albers](src/map/albersequal.cpp), [Geocentric](src/map/geocentric.cpp), [LCC](src/map/lambertconic.cpp),
[Mercator](src/map/mercator.cpp), [Polar Stereographic](src/map/polarstereographic.cpp)
and [Transverse Mercator](src/map/transversemercator.cpp) projections - NIMA Source Code Disclaimer
* [Projection parameters CSV files](pkg/csv) - BSD/EPSG/Public domain

View File

@ -3,7 +3,7 @@ unix:!macx {
} else {
TARGET = GPXSee
}
VERSION = 7.35
VERSION = 7.38
QT += core \
gui \
@ -19,9 +19,12 @@ equals(QT_MAJOR_VERSION, 5) : lessThan(QT_MINOR_VERSION, 4) {QT += opengl}
INCLUDEPATH += ./src
HEADERS += src/common/config.h \
src/GUI/axislabelitem.h \
src/GUI/graphicsscene.h \
src/GUI/mapaction.h \
src/GUI/mapitem.h \
src/GUI/marginswidget.h \
src/GUI/planeitem.h \
src/GUI/popup.h \
src/common/garmin.h \
src/common/staticassert.h \
@ -93,13 +96,18 @@ HEADERS += src/common/config.h \
src/map/IMG/bitstream.h \
src/map/IMG/deltastream.h \
src/map/IMG/gmap.h \
src/map/IMG/huffmanbuffer.h \
src/map/IMG/huffmanstream.h \
src/map/IMG/huffmantable.h \
src/map/IMG/huffmantext.h \
src/map/IMG/nodfile.h \
src/map/IMG/mapdata.h \
src/map/IMG/rastertile.h \
src/map/IMG/textpathitem.h \
src/map/IMG/textpointitem.h \
src/map/bsbmap.h \
src/map/invalidmap.h \
src/map/polyconic.h \
src/map/projection.h \
src/map/ellipsoid.h \
src/map/datum.h \
@ -202,6 +210,8 @@ HEADERS += src/common/config.h \
src/GUI/pdfexportdialog.h \
src/GUI/pngexportdialog.h
SOURCES += src/main.cpp \
src/GUI/axislabelitem.cpp \
src/GUI/mapitem.cpp \
src/GUI/marginswidget.cpp \
src/GUI/popup.cpp \
src/common/coordinates.cpp \
@ -258,18 +268,22 @@ SOURCES += src/main.cpp \
src/map/IMG/bitstream.cpp \
src/map/IMG/deltastream.cpp \
src/map/IMG/gmap.cpp \
src/map/IMG/huffmanbuffer.cpp \
src/map/IMG/huffmanstream.cpp \
src/map/IMG/huffmantable.cpp \
src/map/IMG/huffmantext.cpp \
src/map/IMG/nodfile.cpp \
src/map/IMG/mapdata.cpp \
src/map/IMG/rastertile.cpp \
src/map/IMG/textpathitem.cpp \
src/map/IMG/textpointitem.cpp \
src/map/bsbmap.cpp \
src/map/maplist.cpp \
src/map/onlinemap.cpp \
src/map/downloader.cpp \
src/map/emptymap.cpp \
src/map/ozimap.cpp \
src/map/polyconic.cpp \
src/map/tar.cpp \
src/map/atlas.cpp \
src/map/ozf.cpp \
@ -419,7 +433,13 @@ macx {
icons/formats/json.icns \
icons/formats/cup.icns \
icons/formats/gpi.icns \
icons/formats/sml.icns
icons/formats/sml.icns \
icons/formats/img.icns \
icons/formats/jnx.icns \
icons/formats/kap.icns \
icons/formats/mbts.icns \
icons/formats/rmap.icns \
icons/formats/tba.icns
QMAKE_BUNDLE_DATA += locale maps icons csv
}
@ -439,7 +459,14 @@ win32 {
icons/formats/json.ico \
icons/formats/cup.ico \
icons/formats/gpi.ico \
icons/formats/sml.ico
icons/formats/sml.ico \
icons/formats/img.ico \
icons/formats/jnx.ico \
icons/formats/kap.ico \
icons/formats/map.ico \
icons/formats/mbts.ico \
icons/formats/rmap.ico \
icons/formats/tba.ico
DEFINES += _USE_MATH_DEFINES \
NOGDI
}

BIN
icons/formats/img.icns Normal file

Binary file not shown.

BIN
icons/formats/img.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

BIN
icons/formats/jnx.icns Normal file

Binary file not shown.

BIN
icons/formats/jnx.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

BIN
icons/formats/kap.icns Normal file

Binary file not shown.

BIN
icons/formats/kap.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

BIN
icons/formats/map.icns Normal file

Binary file not shown.

BIN
icons/formats/map.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

BIN
icons/formats/mbts.icns Normal file

Binary file not shown.

BIN
icons/formats/mbts.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

BIN
icons/formats/rmap.icns Normal file

Binary file not shown.

BIN
icons/formats/rmap.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

View File

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

BIN
icons/formats/tba.icns Normal file

Binary file not shown.

BIN
icons/formats/tba.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

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

View File

@ -15,4 +15,4 @@ Icon=gpxsee
Terminal=false
Type=Application
Categories=Graphics;Viewer;Education;Geography;Maps;Sports;Qt;
MimeType=application/gpx+xml;application/tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/loc+xml;application/slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/sml+xml;
MimeType=application/gpx+xml;application/vnd.garmin.tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/vnd.groundspeak.loc+xml;application/vnd.sigma.slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/vnd.suunto.sml+xml;image/jpeg;text/csv;application/vnd.garmin.img;application/vnd.garmin.jnx;application/vnd.garmin.gmap+xml;image/vnd.maptech.kap;application/vnd.oziexplorer.map;application/vnd.mapbox.mbtiles;application/vnd.twonav.rmap;application/vnd.trekbuddy.tba;application/vnd.gpxsee.map+xml;application/x-tar;image/tiff;

View File

@ -7,7 +7,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "7.35"
!define VERSION "7.38"
; The file to write
OutFile "GPXSee-${VERSION}.exe"
@ -109,14 +109,14 @@ Section "GPXSee" SEC_APP
; Associate file formats
DetailPrint "Associating file types..."
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 8
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 9
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 10
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 11
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 12
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 13
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 14
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 15
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 11
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 16
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 17
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 18
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 19
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 20
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 21
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 22
!insertmacro FILE_ASSOCIATION_ADD "wpt" "OziExplorer Waypoint File" 1
!insertmacro FILE_ASSOCIATION_ADD "loc" "Geocaching.com Waypoint File" 2
!insertmacro FILE_ASSOCIATION_ADD "slf" "Sigma Log File" 3
@ -124,6 +124,47 @@ Section "GPXSee" SEC_APP
!insertmacro FILE_ASSOCIATION_ADD "cup" "SeeYou CUP File" 5
!insertmacro FILE_ASSOCIATION_ADD "gpi" "Garmin POI File" 6
!insertmacro FILE_ASSOCIATION_ADD "sml" "Suunto Markup Language" 7
!insertmacro FILE_ASSOCIATION_ADD "img" "Garmin IMG Map" 8
!insertmacro FILE_ASSOCIATION_ADD "jnx" "Garmin JNX Map" 9
!insertmacro FILE_ASSOCIATION_ADD "kap" "BSB Nautical Chart" 10
!insertmacro FILE_ASSOCIATION_ADD "map" "OziExplorer Map File" 12
!insertmacro FILE_ASSOCIATION_ADD "mbtiles" "MBTiles Map File" 13
!insertmacro FILE_ASSOCIATION_ADD "rmap" "TwoNav Raster Map File" 14
!insertmacro FILE_ASSOCIATION_ADD "tba" "TrekBuddy Atlas" 15
WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\""
WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tcx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".fit\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".igc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".nmea\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".plt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rte\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".wpt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".loc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".slf\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".geojson\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".cup\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".gpi\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".sml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".csv\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".json\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpeg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".img\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jnx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".map\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".mbtiles\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rtmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tar\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tba\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tif\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tiff\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".xml\OpenWithList" "GPXSee.exe" ""
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd
@ -210,7 +251,7 @@ Section "Uninstall"
Delete "$SMPROGRAMS\$StartMenuFolder\*.*"
RMDir "$SMPROGRAMS\$StartMenuFolder"
; Remove GPX file association
; Remove file associations
!insertmacro FILE_ASSOCIATION_REMOVE "gpx"
!insertmacro FILE_ASSOCIATION_REMOVE "tcx"
!insertmacro FILE_ASSOCIATION_REMOVE "kml"
@ -226,6 +267,47 @@ Section "Uninstall"
!insertmacro FILE_ASSOCIATION_REMOVE "cup"
!insertmacro FILE_ASSOCIATION_REMOVE "gpi"
!insertmacro FILE_ASSOCIATION_REMOVE "sml"
!insertmacro FILE_ASSOCIATION_REMOVE "img"
!insertmacro FILE_ASSOCIATION_REMOVE "jnx"
!insertmacro FILE_ASSOCIATION_REMOVE "kap"
!insertmacro FILE_ASSOCIATION_REMOVE "map"
!insertmacro FILE_ASSOCIATION_REMOVE "mbtiles"
!insertmacro FILE_ASSOCIATION_REMOVE "rmap"
!insertmacro FILE_ASSOCIATION_REMOVE "tba"
DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".fit\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".igc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".nmea\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".plt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rte\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".wpt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".loc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".slf\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".geojson\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".cup\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".gpi\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".sml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".csv\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".json\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpeg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".img\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jnx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".map\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".mbtiles\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rtmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tar\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tba\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tif\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tiff\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".xml\OpenWithList" "GPXSee.exe"
DeleteRegKey HKCR "Applications\GPXSee.exe"
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd
@ -256,4 +338,4 @@ LangString DESC_LOCALIZATION ${LANG_ENGLISH} \
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_MSVC} $(DESC_MSVC)
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_APP} $(DESC_APP)
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_LOCALIZATION} $(DESC_LOCALIZATION)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
!insertmacro MUI_FUNCTION_DESCRIPTION_END

View File

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

View File

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

View File

@ -16,6 +16,7 @@
#include "opengl.h"
#include "gui.h"
#include "settings.h"
#include "mapaction.h"
#include "app.h"
@ -76,11 +77,25 @@ App::~App()
int App::run()
{
MapAction *lastReady = 0;
QStringList args(arguments());
_gui->show();
QStringList args(arguments());
for (int i = 1; i < args.count(); i++)
_gui->openFile(args.at(i));
for (int i = 1; i < args.count(); i++) {
if (!_gui->openFile(args.at(i), true)) {
MapAction *a;
if (!_gui->loadMap(args.at(i), a, true))
_gui->openFile(args.at(i), false);
else {
if (a)
lastReady = a;
}
}
}
if (lastReady)
lastReady->trigger();
return exec();
}
@ -89,7 +104,18 @@ bool App::event(QEvent *event)
{
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent *e = static_cast<QFileOpenEvent *>(event);
return _gui->openFile(e->file());
if (!_gui->openFile(e->file(), true)) {
MapAction *a;
if (!_gui->loadMap(e->file(), a, true))
return _gui->openFile(e->file(), false);
else {
if (a)
a->trigger();
return true;
}
} else
return true;
}
return QApplication::event(event);

View File

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

View File

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

View File

@ -41,6 +41,7 @@ AxisItem::AxisItem(Type type, QGraphicsItem *parent)
{
_type = type;
_size = 0;
_zoom = 1.0;
_font.setPixelSize(FONT_SIZE);
_font.setFamily(FONT_FAMILY);
@ -52,8 +53,10 @@ void AxisItem::setRange(const RangeF &range)
_range = range;
QFontMetrics fm(_font);
Ticks ticks(_range.min(), _range.max(), (_type == X) ? XTICKS : YTICKS);
Ticks ticks(_range.min(), _range.max(),
(_type == X) ? XTICKS * _zoom : YTICKS * _zoom);
_ticks = QVector<Tick>(ticks.count());
for (int i = 0; i < ticks.count(); i++) {
Tick &t = _ticks[i];
t.value = ticks.val(i);
@ -72,34 +75,23 @@ void AxisItem::setSize(qreal size)
update();
}
void AxisItem::setLabel(const QString& label)
{
prepareGeometryChange();
QFontMetrics fm(_font);
_label = label;
_labelBB = fm.tightBoundingRect(label);
updateBoundingRect();
update();
}
void AxisItem::updateBoundingRect()
{
QFontMetrics fm(_font);
QRect es = _ticks.isEmpty() ? QRect() : _ticks.last().boundingBox;
QRect ss = _ticks.isEmpty() ? QRect() : _ticks.first().boundingBox;
QRect ls(_labelBB);
if (_type == X) {
_boundingRect = QRectF(-ss.width()/2, -TICK/2, _size + es.width()/2
+ ss.width()/2, ls.height() + es.height() - fm.descent() + TICK
+ 2*PADDING + 1);
+ ss.width()/2, es.height() - 2*fm.descent() + TICK + 2*PADDING);
} else {
int mtw = 0;
for (int i = 0; i < _ticks.count(); i++)
mtw = qMax(_ticks.at(i).boundingBox.width(), mtw);
_boundingRect = QRectF(-(ls.height() + mtw + 2*PADDING + TICK/2),
-(_size + es.height()/2 + fm.descent()), ls.height() + mtw + 2*PADDING
+ TICK, _size + es.height()/2 + fm.descent() + ss.height()/2);
_boundingRect = QRectF(-(mtw + 2*PADDING + TICK/2 - fm.descent()),
-(_size + es.height()/2 + fm.descent()), mtw + 2*PADDING
+ TICK - fm.descent(), _size + es.height()/2 + fm.descent()
+ ss.height()/2);
}
}
@ -108,7 +100,6 @@ void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
{
Q_UNUSED(option);
Q_UNUSED(widget);
QFontMetrics fm(_font);
QRect ts;
painter->setRenderHint(QPainter::Antialiasing, false);
@ -130,9 +121,6 @@ void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- (ts.width()/2), ts.height() + TICK/2 + PADDING,
_locale.toString(val));
}
painter->drawText(_size/2 - _labelBB.width()/2, _labelBB.height()
+ ts.height() - 2*fm.descent() + TICK/2 + 2*PADDING, _label);
} else {
painter->drawLine(0, 0, 0, -_size);
@ -149,17 +137,10 @@ void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
-((_size/_range.size()) * (val - _range.min())) + (ts.height()/2),
_locale.toString(val));
}
painter->rotate(-90);
painter->drawText(_size/2 - _labelBB.width()/2, -(mtw + 2*PADDING
+ TICK/2), _label);
painter->rotate(90);
}
/*
painter->setPen(Qt::red);
painter->drawRect(boundingRect());
*/
//painter->setPen(Qt::red);
//painter->drawRect(boundingRect());
}
QSizeF AxisItem::margin() const
@ -168,15 +149,15 @@ QSizeF AxisItem::margin() const
QRect es = _ticks.isEmpty() ? QRect() : _ticks.last().boundingBox;
if (_type == X) {
return QSizeF(es.width()/2, _labelBB.height() + es.height()
- fm.descent() + TICK/2 + 2*PADDING);
return QSizeF(es.width()/2, es.height() - 2*fm.descent() + TICK/2
+ 2*PADDING);
} else {
int mtw = 0;
for (int i = 0; i < _ticks.count(); i++)
mtw = qMax(_ticks.at(i).boundingBox.width(), mtw);
return QSizeF(_labelBB.height() -fm.descent() + mtw + 2*PADDING
+ TICK/2, es.height()/2 + fm.descent());
return QSizeF(mtw + 2*PADDING + TICK/2 - fm.descent(),
es.height()/2 + fm.descent());
}
}

View File

@ -13,13 +13,15 @@ public:
AxisItem(Type type, QGraphicsItem *parent = 0);
/* Note: The items position is at the 0 point of the axis line, not at the
top-left point of the bounding rect as usual */
QRectF boundingRect() const {return _boundingRect;}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
void setRange(const RangeF &range);
void setSize(qreal size);
void setLabel(const QString& label);
void setZoom(qreal zoom) {_zoom = zoom;}
QSizeF margin() const;
QList<qreal> ticks() const;
@ -35,12 +37,11 @@ private:
Type _type;
RangeF _range;
qreal _size;
QString _label;
QRect _labelBB;
QVector<Tick> _ticks;
QRectF _boundingRect;
QFont _font;
QLocale _locale;
qreal _zoom;
};
#endif // AXISITEM_H

54
src/GUI/axislabelitem.cpp Normal file
View File

@ -0,0 +1,54 @@
#include <QPainter>
#include <QFontMetrics>
#include "font.h"
#include "axislabelitem.h"
AxisLabelItem::AxisLabelItem(Type type, QGraphicsItem *parent)
: QGraphicsItem(parent), _type(type)
{
_font.setPixelSize(FONT_SIZE);
_font.setFamily(FONT_FAMILY);
}
void AxisLabelItem::setLabel(const QString& label, const QString &units)
{
prepareGeometryChange();
QFontMetrics fm(_font);
_label = QString("%1 [%2]").arg(label, units.isEmpty() ? "-" : units);
_labelBB = fm.tightBoundingRect(_label);
updateBoundingRect();
update();
}
void AxisLabelItem::updateBoundingRect()
{
QFontMetrics fm(_font);
if (_type == X)
_boundingRect = QRectF(0, 0, _labelBB.width(), fm.height());
else
_boundingRect = QRectF(0, 0, fm.height(), _labelBB.width());
}
void AxisLabelItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
QFontMetrics fm(_font);
painter->setFont(_font);
if (_type == X) {
painter->drawText(0, fm.height() - fm.descent(), _label);
} else {
painter->rotate(-90);
painter->drawText(-_labelBB.width(), fm.height() - fm.descent(), _label);
painter->rotate(90);
}
//painter->setRenderHint(QPainter::Antialiasing, false);
//painter->setPen(Qt::red);
//painter->drawRect(boundingRect());
}

30
src/GUI/axislabelitem.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef AXISLABELITEM_H
#define AXISLABELITEM_H
#include <QGraphicsItem>
#include <QFont>
class AxisLabelItem : public QGraphicsItem
{
public:
enum Type {X, Y};
AxisLabelItem(Type type, QGraphicsItem *parent = 0);
QRectF boundingRect() const {return _boundingRect;}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
void setLabel(const QString& label, const QString &units);
private:
void updateBoundingRect();
Type _type;
QString _label;
QFont _font;
QRect _labelBB;
QRectF _boundingRect;
};
#endif // AXISLABELITEM_H

View File

@ -15,6 +15,8 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
CoordinatesFormat format() const {return _format;}
void setCoordinates(const Coordinates &c);
void setFormat(const CoordinatesFormat &format);
void setDigitalZoom(qreal zoom);

View File

@ -11,7 +11,7 @@ GraphItem::GraphItem(const Graph &graph, GraphType type, int width,
Q_ASSERT(_graph.isValid());
_units = Metric;
_pen = QPen(color, width, style);
_pen = QPen(color, width, style, Qt::FlatCap);
_sx = 0; _sy = 0;
_time = _graph.hasTime();
setZValue(2.0);

View File

@ -14,8 +14,7 @@ class GraphTab : public GraphView
Q_OBJECT
public:
GraphTab(QWidget *parent = 0) : GraphView(parent)
{setFrameShape(QFrame::NoFrame);}
GraphTab(QWidget *parent = 0) : GraphView(parent) {}
virtual ~GraphTab() {}
virtual QString label() const = 0;

View File

@ -9,6 +9,7 @@
#include "data/graph.h"
#include "opengl.h"
#include "axisitem.h"
#include "axislabelitem.h"
#include "slideritem.h"
#include "sliderinfoitem.h"
#include "infoitem.h"
@ -22,6 +23,9 @@
#define MARGIN 10.0
#define IW(item) ((item)->boundingRect().width())
#define IH(item) ((item)->boundingRect().height())
GraphView::GraphView(QWidget *parent)
: QGraphicsView(parent)
{
@ -38,6 +42,10 @@ GraphView::GraphView(QWidget *parent)
_xAxis->setZValue(1.0);
_yAxis = new AxisItem(AxisItem::Y);
_yAxis->setZValue(1.0);
_xAxisLabel = new AxisLabelItem(AxisLabelItem::X);
_xAxisLabel->setZValue(1.0);
_yAxisLabel = new AxisLabelItem(AxisLabelItem::Y);
_yAxisLabel->setZValue(1.0);
_slider = new SliderItem();
_slider->setZValue(4.0);
_sliderInfo = new SliderInfoItem(_slider);
@ -73,34 +81,24 @@ GraphView::~GraphView()
{
delete _xAxis;
delete _yAxis;
delete _xAxisLabel;
delete _yAxisLabel;
delete _slider;
delete _info;
delete _grid;
delete _message;
}
void GraphView::createXLabel()
{
_xAxis->setLabel(QString("%1 [%2]").arg(_xLabel,
_xUnits.isEmpty() ? "-" : _xUnits));
}
void GraphView::createYLabel()
{
_yAxis->setLabel(QString("%1 [%2]").arg(_yLabel,
_yUnits.isEmpty() ? "-" : _yUnits));
}
void GraphView::setYLabel(const QString &label)
{
_yLabel = label;
createYLabel();
_yAxisLabel->setLabel(_yLabel, _yUnits);
}
void GraphView::setYUnits(const QString &units)
{
_yUnits = units;
createYLabel();
_yAxisLabel->setLabel(_yLabel, _yUnits);
}
void GraphView::setXUnits()
@ -144,7 +142,7 @@ void GraphView::setXUnits()
}
}
createXLabel();
_xAxisLabel->setLabel(_xLabel, _xUnits);
}
void GraphView::setUnits(Units units)
@ -163,6 +161,7 @@ void GraphView::setGraphType(GraphType type)
{
_graphType = type;
_bounds = QRectF();
_zoom = 1.0;
for (int i = 0; i < _graphs.count(); i++) {
GraphItem *gi = _graphs.at(i);
@ -257,6 +256,8 @@ void GraphView::redraw(const QSizeF &size)
if (_bounds.isNull()) {
removeItem(_xAxis);
removeItem(_yAxis);
removeItem(_xAxisLabel);
removeItem(_yAxisLabel);
removeItem(_slider);
removeItem(_info);
removeItem(_grid);
@ -268,6 +269,8 @@ void GraphView::redraw(const QSizeF &size)
removeItem(_message);
addItem(_xAxis);
addItem(_yAxis);
addItem(_xAxisLabel);
addItem(_yAxisLabel);
addItem(_slider);
addItem(_info);
addItem(_grid);
@ -278,7 +281,9 @@ void GraphView::redraw(const QSizeF &size)
if (ry.size() < _minYRange * _yScale)
ry.resize(_minYRange * _yScale);
_xAxis->setZoom(_zoom);
_xAxis->setRange(rx);
_xAxis->setZoom(_zoom);
_yAxis->setRange(ry);
mx = _xAxis->margin();
my = _yAxis->margin();
@ -288,9 +293,10 @@ void GraphView::redraw(const QSizeF &size)
r.adjust(0, -(_minYRange/2 - r.height()/2), 0,
_minYRange/2 - r.height()/2);
sx = (size.width() - (my.width() + mx.width())) / r.width();
sx = (size.width() - (my.width() + mx.width()) - IW(_yAxisLabel))
/ r.width();
sy = (size.height() - (mx.height() + my.height())
- _info->boundingRect().height()) / r.height();
- IH(_info) - IH(_xAxisLabel)) / r.height();
sx *= _zoom;
for (int i = 0; i < _graphs.size(); i++)
@ -316,10 +322,12 @@ void GraphView::redraw(const QSizeF &size)
_slider->setArea(r);
updateSliderPosition();
r |= _xAxis->sceneBoundingRect();
r |= _yAxis->sceneBoundingRect();
_info->setPos(r.topLeft() + QPointF(r.width()/2
- _info->boundingRect().width()/2, -_info->boundingRect().height()));
_info->setPos(QPointF(r.width()/2 - IW(_info)/2 - (IW(_yAxisLabel)
+ IW(_yAxis))/2, r.top() - IH(_info) - my.height()));
_xAxisLabel->setPos(QPointF(r.width()/2 - IW(_xAxisLabel)/2,
r.bottom() + mx.height()));
_yAxisLabel->setPos(QPointF(r.left() - my.width() - IW(_yAxisLabel),
r.bottom() - (r.height()/2 + IH(_yAxisLabel)/2)));
_scene->setSceneRect(_scene->itemsBoundingRect());
}
@ -367,8 +375,10 @@ void GraphView::wheelEvent(QWheelEvent *e)
void GraphView::paintEvent(QPaintEvent *e)
{
QRectF viewRect(mapToScene(rect()).boundingRect());
_info->setPos(QPointF(viewRect.left() + (viewRect.width()
- _info->boundingRect().width())/2.0, _info->pos().y()));
_info->setPos(QPointF(viewRect.left() + (viewRect.width() - IW(_info))/2.0,
_info->pos().y()));
_xAxisLabel->setPos(QPointF(viewRect.left() + (viewRect.width()
- IW(_xAxisLabel))/2.0, _xAxisLabel->pos().y()));
QGraphicsView::paintEvent(e);
}

View File

@ -10,6 +10,7 @@
class AxisItem;
class AxisLabelItem;
class SliderItem;
class SliderInfoItem;
class GraphItem;
@ -86,8 +87,6 @@ private slots:
private:
void redraw(const QSizeF &size);
void setXUnits();
void createXLabel();
void createYLabel();
void updateSliderPosition();
void updateSliderInfo();
void removeItem(QGraphicsItem *item);
@ -96,6 +95,7 @@ private:
GraphicsScene *_scene;
AxisItem *_xAxis, *_yAxis;
AxisLabelItem *_xAxisLabel, *_yAxisLabel;
SliderItem *_slider;
SliderInfoItem *_sliderInfo;
InfoItem *_info;

View File

@ -23,10 +23,8 @@ void GridItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->drawLine(0, -_yTicks.at(i), boundingRect().width(),
-_yTicks.at(i));
/*
painter->setPen(Qt::red);
painter->drawRect(boundingRect());
*/
//painter->setPen(Qt::red);
//painter->drawRect(boundingRect());
}
void GridItem::setTicks(const QList<qreal> &x, const QList<qreal> &y)

View File

@ -51,6 +51,7 @@
#include "graphtab.h"
#include "graphitem.h"
#include "pathitem.h"
#include "mapitem.h"
#include "mapaction.h"
#include "gui.h"
@ -130,20 +131,25 @@ void GUI::createMapActions()
if (mapDir.isNull())
return;
QString unused;
QList<Map*> maps(MapList::loadMaps(mapDir, unused));
QList<Map*> maps(MapList::loadMaps(mapDir));
for (int i = 0; i < maps.count(); i++) {
MapAction *a = createMapAction(maps.at(i));
connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized()));
Map *map = maps.at(i);
if (map->isValid()) {
MapAction *a = createMapAction(map);
connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized()));
} else {
qWarning("%s: %s", qPrintable(map->path()),
qPrintable(map->errorString()));
delete map;
}
}
}
MapAction *GUI::createMapAction(Map *map)
{
MapAction *a = new MapAction(map);
MapAction *a = new MapAction(map, _mapsActionGroup);
a->setMenuRole(QAction::NoRole);
a->setCheckable(true);
a->setActionGroup(_mapsActionGroup);
connect(a, SIGNAL(triggered()), this, SLOT(mapChanged()));
return a;
@ -160,7 +166,7 @@ void GUI::mapInitialized()
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else {
qWarning("%s: %s", qPrintable(map->name()), qPrintable(map->errorString()));
qWarning("%s: %s", qPrintable(map->path()), qPrintable(map->errorString()));
action->deleteLater();
}
}
@ -307,10 +313,14 @@ void GUI::createActions()
this);
_loadMapAction->setMenuRole(QAction::NoRole);
connect(_loadMapAction, SIGNAL(triggered()), this, SLOT(loadMap()));
_loadMapDirAction = new QAction(QIcon(OPEN_FILE_ICON),
tr("Load map directory..."), this);
_loadMapDirAction->setMenuRole(QAction::NoRole);
connect(_loadMapDirAction, SIGNAL(triggered()), this, SLOT(loadMapDir()));
_clearMapCacheAction = new QAction(tr("Clear tile cache"), this);
_clearMapCacheAction->setEnabled(false);
_clearMapCacheAction->setMenuRole(QAction::NoRole);
connect(_clearMapCacheAction, SIGNAL(triggered()), _mapView,
connect(_clearMapCacheAction, SIGNAL(triggered()), this,
SLOT(clearMapCache()));
_nextMapAction = new QAction(tr("Next map"), this);
_nextMapAction->setMenuRole(QAction::NoRole);
@ -520,6 +530,7 @@ void GUI::createMenus()
_mapMenu->addActions(_mapsActionGroup->actions());
_mapsEnd = _mapMenu->addSeparator();
_mapMenu->addAction(_loadMapAction);
_mapMenu->addAction(_loadMapDirAction);
_mapMenu->addAction(_clearMapCacheAction);
_mapMenu->addSeparator();
_mapMenu->addAction(_showCoordinatesAction);
@ -632,15 +643,15 @@ void GUI::createMapView()
void GUI::createGraphTabs()
{
_graphTabWidget = new QTabWidget();
connect(_graphTabWidget, SIGNAL(currentChanged(int)), this,
SLOT(graphChanged(int)));
_graphTabWidget->setSizePolicy(QSizePolicy(QSizePolicy::Ignored,
QSizePolicy::Preferred));
_graphTabWidget->setMinimumHeight(200);
#ifdef Q_OS_WIN32
#ifndef Q_OS_MAC
_graphTabWidget->setDocumentMode(true);
#endif // Q_OS_WIN32
#endif // Q_OS_MAC
connect(_graphTabWidget, SIGNAL(currentChanged(int)), this,
SLOT(graphChanged(int)));
_tabs.append(new ElevationGraph(_graphTabWidget));
_tabs.append(new SpeedGraph(_graphTabWidget));
@ -650,9 +661,13 @@ void GUI::createGraphTabs()
_tabs.append(new TemperatureGraph(_graphTabWidget));
_tabs.append(new GearRatioGraph(_graphTabWidget));
for (int i = 0; i < _tabs.count(); i++)
for (int i = 0; i < _tabs.count(); i++) {
#if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
_tabs.at(i)->setFrameShape(QFrame::NoFrame);
#endif // Q_OS_WIN32 || Q_OS_MAC
connect(_tabs.at(i), SIGNAL(sliderPositionChanged(qreal)), this,
SLOT(sliderPositionChanged(qreal)));
}
}
void GUI::createStatusBar()
@ -721,7 +736,10 @@ void GUI::keys()
+ "</i></td></tr><tr><td>" + tr("Zoom out") + "</td><td><i>"
+ QKeySequence(ZOOM_OUT).toString() + "</i></td></tr><tr><td>"
+ tr("Digital zoom") + "</td><td><i>" + QKeySequence(MODIFIER).toString()
+ tr("Zoom") + "</i></td></tr></table></div>");
+ tr("Zoom") + "</i></td></tr><tr><td></td><td></td></tr><tr><td>"
+ tr("Copy coordinates") + "</td><td><i>"
+ QKeySequence(MODIFIER).toString() + tr("Left Click")
+ "</i></td></tr></table></div>");
msgBox.exec();
}
@ -753,101 +771,45 @@ void GUI::paths()
void GUI::openFile()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open file"),
_dataDir, Data::formats());
QStringList list = files;
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open file"),
_dataDir, Data::formats()));
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
openFile(*it);
if (!list.isEmpty())
_dataDir = QFileInfo(list.first()).path();
for (int i = 0; i < files.size(); i++)
openFile(files.at(i));
if (!files.isEmpty())
_dataDir = QFileInfo(files.last()).path();
}
bool GUI::openFile(const QString &fileName)
bool GUI::openFile(const QString &fileName, bool silent)
{
if (fileName.isEmpty() || _files.contains(fileName))
return false;
if (loadFile(fileName)) {
_files.append(fileName);
_browser->setCurrent(fileName);
_fileActionGroup->setEnabled(true);
_navigationActionGroup->setEnabled(true);
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
if (_files.contains(fileName))
return true;
} else {
if (_files.isEmpty())
_fileActionGroup->setEnabled(false);
if (!loadFile(fileName, silent))
return false;
}
_files.append(fileName);
_browser->setCurrent(fileName);
_fileActionGroup->setEnabled(true);
// Explicitly enable the reload action as it may be disabled by loadMapDir()
_reloadFileAction->setEnabled(true);
_navigationActionGroup->setEnabled(true);
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
return true;
}
bool GUI::loadFile(const QString &fileName)
bool GUI::loadFile(const QString &fileName, bool silent)
{
Data data(fileName);
QList<QList<GraphItem*> > graphs;
QList<PathItem*> paths;
Data data(fileName, !silent);
if (data.isValid()) {
for (int i = 0; i < data.tracks().count(); i++) {
const Track &track = data.tracks().at(i);
_trackDistance += track.distance();
_time += track.time();
_movingTime += track.movingTime();
#ifdef ENABLE_TIMEZONES
const QDateTime date = track.date().toTimeZone(
_options.timeZone.zone());
#else // ENABLE_TIMEZONES
const QDateTime &date = track.date();
#endif // ENABLE_TIMEZONES
if (_dateRange.first.isNull() || _dateRange.first > date)
_dateRange.first = date;
if (_dateRange.second.isNull() || _dateRange.second < date)
_dateRange.second = date;
}
_trackCount += data.tracks().count();
for (int i = 0; i < data.routes().count(); i++)
_routeDistance += data.routes().at(i).distance();
_routeCount += data.routes().count();
_waypointCount += data.waypoints().count();
_areaCount += data.areas().count();
if (_pathName.isNull()) {
if (data.tracks().count() == 1 && !data.routes().count())
_pathName = data.tracks().first().name();
else if (data.routes().count() == 1 && !data.tracks().count())
_pathName = data.routes().first().name();
} else
_pathName = QString();
for (int i = 0; i < _tabs.count(); i++)
graphs.append(_tabs.at(i)->loadData(data));
if (updateGraphTabs())
_splitter->refresh();
paths = _mapView->loadData(data);
for (int i = 0; i < paths.count(); i++) {
const PathItem *pi = paths.at(i);
for (int j = 0; j < graphs.count(); j++) {
const GraphItem *gi = graphs.at(j).at(i);
if (!gi)
continue;
connect(gi, SIGNAL(sliderPositionChanged(qreal)), pi,
SLOT(moveMarker(qreal)));
connect(pi, SIGNAL(selected(bool)), gi, SLOT(hover(bool)));
connect(gi, SIGNAL(selected(bool)), pi, SLOT(hover(bool)));
}
}
loadData(data);
return true;
} else {
} else if (!silent) {
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
@ -859,25 +821,83 @@ bool GUI::loadFile(const QString &fileName)
error.append("\n" + tr("Line: %1").arg(data.errorLine()));
QMessageBox::critical(this, APP_NAME, error);
return false;
} else
return false;
}
void GUI::loadData(const Data &data)
{
QList<QList<GraphItem*> > graphs;
QList<PathItem*> paths;
for (int i = 0; i < data.tracks().count(); i++) {
const Track &track = data.tracks().at(i);
_trackDistance += track.distance();
_time += track.time();
_movingTime += track.movingTime();
#ifdef ENABLE_TIMEZONES
const QDateTime date = track.date().toTimeZone(
_options.timeZone.zone());
#else // ENABLE_TIMEZONES
const QDateTime &date = track.date();
#endif // ENABLE_TIMEZONES
if (_dateRange.first.isNull() || _dateRange.first > date)
_dateRange.first = date;
if (_dateRange.second.isNull() || _dateRange.second < date)
_dateRange.second = date;
}
_trackCount += data.tracks().count();
for (int i = 0; i < data.routes().count(); i++)
_routeDistance += data.routes().at(i).distance();
_routeCount += data.routes().count();
_waypointCount += data.waypoints().count();
_areaCount += data.areas().count();
if (_pathName.isNull()) {
if (data.tracks().count() == 1 && !data.routes().count())
_pathName = data.tracks().first().name();
else if (data.routes().count() == 1 && !data.tracks().count())
_pathName = data.routes().first().name();
} else
_pathName = QString();
for (int i = 0; i < _tabs.count(); i++)
graphs.append(_tabs.at(i)->loadData(data));
if (updateGraphTabs())
_splitter->refresh();
paths = _mapView->loadData(data);
for (int i = 0; i < paths.count(); i++) {
const PathItem *pi = paths.at(i);
for (int j = 0; j < graphs.count(); j++) {
const GraphItem *gi = graphs.at(j).at(i);
if (!gi)
continue;
connect(gi, SIGNAL(sliderPositionChanged(qreal)), pi,
SLOT(moveMarker(qreal)));
connect(pi, SIGNAL(selected(bool)), gi, SLOT(hover(bool)));
connect(gi, SIGNAL(selected(bool)), pi, SLOT(hover(bool)));
}
}
}
void GUI::openPOIFile()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open POI file"),
_poiDir, Data::formats());
QStringList list = files;
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open POI file"),
_poiDir, Data::formats()));
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
openPOIFile(*it);
if (!list.isEmpty())
_poiDir = QFileInfo(list.first()).path();
for (int i = 0; i < files.size(); i++)
openPOIFile(files.at(i));
if (!files.isEmpty())
_poiDir = QFileInfo(files.last()).path();
}
bool GUI::openPOIFile(const QString &fileName)
{
if (fileName.isEmpty() || _poi->files().contains(fileName))
return false;
if (_poi->files().contains(fileName))
return true;
if (_poi->loadFile(fileName)) {
_mapView->showPOI(true);
@ -1065,7 +1085,7 @@ void GUI::exportPNGFile()
p.setRenderHint(QPainter::Antialiasing);
p.fillRect(rect, Qt::white);
plotMainPage(&p, contentRect, 1.0, true);
img.save(_pngExport.fileName);
img.save(_pngExport.fileName, "png");
if (!_tabs.isEmpty() && _options.separateGraphPage) {
QImage img2(_pngExport.size.width(), (int)graphPlotHeight(rect, 1)
@ -1080,7 +1100,7 @@ void GUI::exportPNGFile()
QFileInfo fi(_pngExport.fileName);
img2.save(fi.absolutePath() + "/" + fi.baseName() + "-graphs."
+ fi.suffix());
+ fi.suffix(), "png");
}
}
@ -1221,7 +1241,7 @@ void GUI::plotMainPage(QPainter *painter, const QRectF &rect, qreal ratio,
sc = 1;
}
MapView::PlotFlags flags = MapView::NoFlags;
MapView::PlotFlags flags;
if (_options.hiresPrint)
flags |= MapView::HiRes;
if (expand)
@ -1421,45 +1441,73 @@ void GUI::showGraphSliderInfo(bool show)
void GUI::loadMap()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open map file"),
_mapDir, MapList::formats());
QStringList list = files;
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open map file"),
_mapDir, MapList::formats()));
MapAction *a, *lastReady = 0;
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
loadMap(*it);
if (!list.isEmpty())
_mapDir = QFileInfo(list.first()).path();
for (int i = 0; i < files.size(); i++) {
if (loadMap(files.at(i), a) && a)
lastReady = a;
}
if (!files.isEmpty())
_mapDir = QFileInfo(files.last()).path();
if (lastReady)
lastReady->trigger();
}
bool GUI::loadMap(const QString &fileName)
static MapAction *findMapAction(const QList<QAction*> &mapActions,
const Map *map)
{
// On OS X fileName may be a directory!
if (fileName.isEmpty())
return false;
QString error;
QList<Map*> maps = MapList::loadMaps(fileName, error);
if (maps.isEmpty()) {
error = tr("Error loading map:") + "\n\n"
+ fileName + "\n\n" + error;
QMessageBox::critical(this, APP_NAME, error);
return false;
for (int i = 0; i < mapActions.count(); i++) {
const Map *m = mapActions.at(i)->data().value<Map*>();
if (map->path() == m->path())
return static_cast<MapAction*>(mapActions.at(i));
}
return 0;
}
bool GUI::loadMap(const QString &fileName, MapAction *&action, bool silent)
{
QList<Map*> maps(MapList::loadMaps(fileName));
QList<QAction*> existingActions(_mapsActionGroup->actions());
MapAction *lastReady = 0;
bool valid = false;
for (int i = 0; i < maps.size(); i++) {
Map *map = maps.at(i);
MapAction *a = createMapAction(map);
_mapMenu->insertAction(_mapsEnd, a);
if (map->isReady()) {
a->trigger();
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded()));
MapAction *a;
if (!(a = findMapAction(existingActions, map))) {
if (!map->isValid()) {
if (!silent)
QMessageBox::critical(this, APP_NAME,
tr("Error loading map:") + "\n\n" + map->path() + "\n\n"
+ map->errorString());
delete map;
} else {
valid = true;
a = createMapAction(map);
_mapMenu->insertAction(_mapsEnd, a);
if (map->isReady()) {
lastReady = a;
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded()));
}
} else {
valid = true;
map = a->data().value<Map*>();
if (map->isReady())
lastReady = a;
}
}
return true;
action = lastReady;
return valid;
}
void GUI::mapLoaded()
@ -1472,13 +1520,94 @@ void GUI::mapLoaded()
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else {
QString error = tr("Error loading map:") + "\n\n"
+ map->name() + "\n\n" + map->errorString();
QString error = tr("Error loading map:") + "\n\n" + map->path() + "\n\n"
+ map->errorString();
QMessageBox::critical(this, APP_NAME, error);
action->deleteLater();
}
}
void GUI::mapLoadedDir()
{
MapAction *action = static_cast<MapAction*>(QObject::sender());
Map *map = action->data().value<Map*>();
if (map->isValid()) {
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
QList<MapAction*> actions;
actions.append(action);
_mapView->loadMaps(actions);
} else {
QString error = tr("Error loading map:") + "\n\n" + map->path() + "\n\n"
+ map->errorString();
QMessageBox::critical(this, APP_NAME, error);
action->deleteLater();
}
}
void GUI::loadMapDir()
{
QString dir(QFileDialog::getExistingDirectory(this,
tr("Select map directory"), _mapDir, QFileDialog::ShowDirsOnly));
if (dir.isEmpty())
return;
QList<Map*> maps(MapList::loadMaps(dir));
QList<MapAction*> actions;
QList<QAction*> existingActions(_mapsActionGroup->actions());
QFileInfo fi(dir);
QMenu *menu = new QMenu(fi.fileName());
for (int i = 0; i < maps.size(); i++) {
Map *map = maps.at(i);
MapAction *a;
if (!(a = findMapAction(existingActions, map))) {
if (!map->isValid()) {
QMessageBox::critical(this, APP_NAME, tr("Error loading map:")
+ "\n\n" + map->path() + "\n\n" + map->errorString());
delete map;
} else {
a = createMapAction(map);
menu->addAction(a);
if (map->isReady()) {
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
actions.append(a);
} else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoadedDir()));
}
} else {
map = a->data().value<Map*>();
if (map->isReady())
actions.append(a);
}
}
_mapView->loadMaps(actions);
if (menu->isEmpty())
delete menu;
else {
menu->setStyleSheet("QMenu { menu-scrollable: 1; }");
_mapMenu->insertMenu(_mapsEnd, menu);
}
_mapDir = fi.absolutePath();
_areaCount += maps.size();
_fileActionGroup->setEnabled(true);
_reloadFileAction->setEnabled(false);
}
void GUI::clearMapCache()
{
if (QMessageBox::question(this, APP_NAME,
tr("Clear the map tile cache?")) == QMessageBox::Yes)
_mapView->clearMapCache();
}
void GUI::updateStatusBarInfo()
{
if (_files.count() == 0)
@ -1529,7 +1658,7 @@ void GUI::nextMap()
if (!checked)
return;
QList<QAction*> maps = _mapsActionGroup->actions();
QList<QAction*> maps(_mapsActionGroup->actions());
for (int i = 1; i < maps.size(); i++) {
int next = (maps.indexOf(checked) + i) % maps.count();
if (maps.at(next)->isEnabled()) {
@ -1545,7 +1674,7 @@ void GUI::prevMap()
if (!checked)
return;
QList<QAction*> maps = _mapsActionGroup->actions();
QList<QAction*> maps(_mapsActionGroup->actions());
for (int i = 1; i < maps.size(); i++) {
int prev = (maps.indexOf(checked) + maps.count() - i) % maps.count();
if (maps.at(prev)->isEnabled()) {
@ -1771,9 +1900,25 @@ void GUI::dragEnterEvent(QDragEnterEvent *event)
void GUI::dropEvent(QDropEvent *event)
{
QList<QUrl> urls = event->mimeData()->urls();
for (int i = 0; i < urls.size(); i++)
openFile(urls.at(i).toLocalFile());
MapAction *lastReady = 0;
QList<QUrl> urls(event->mimeData()->urls());
for (int i = 0; i < urls.size(); i++) {
QString file(urls.at(i).toLocalFile());
if (!openFile(file, true)) {
MapAction *a;
if (!loadMap(file, a, true))
openFile(file, false);
else {
if (a)
lastReady = a;
}
}
}
if (lastReady)
lastReady->trigger();
event->acceptProposedAction();
}
@ -2391,7 +2536,7 @@ void GUI::readSettings()
QAction *GUI::mapAction(const QString &name)
{
QList<QAction *> maps = _mapsActionGroup->actions();
QList<QAction *> maps(_mapsActionGroup->actions());
// Last map
for (int i = 0; i < maps.count(); i++) {

View File

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

View File

@ -53,10 +53,8 @@ void InfoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
}
}
/*
painter->setPen(Qt::red);
painter->drawRect(boundingRect());
*/
//painter->setPen(Qt::red);
//painter->drawRect(boundingRect());
}
void InfoItem::insert(const QString &key, const QString &value)

View File

@ -8,6 +8,7 @@
#define PREV_KEY Qt::Key_Backspace
#define FIRST_KEY Qt::Key_Home
#define LAST_KEY Qt::Key_End
#define MODIFIER_KEY Qt::Key_Shift
#define MODIFIER Qt::ShiftModifier
#define ZOOM_IN Qt::Key_Plus
#define ZOOM_OUT Qt::Key_Minus

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

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

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

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

View File

@ -3,6 +3,7 @@
#include <QWheelEvent>
#include <QApplication>
#include <QScrollBar>
#include <QClipboard>
#include "data/poi.h"
#include "data/data.h"
#include "map/map.h"
@ -14,8 +15,10 @@
#include "areaitem.h"
#include "scaleitem.h"
#include "coordinatesitem.h"
#include "mapitem.h"
#include "keys.h"
#include "graphicsscene.h"
#include "mapaction.h"
#include "mapview.h"
@ -26,6 +29,20 @@
#define COORDINATES_OFFSET SCALE_OFFSET
template<typename T>
static void updateZValues(T &items)
{
for (int i = 0; i < items.size(); i++) {
const QGraphicsItem *ai = items.at(i);
for (int j = 0; j < items.size(); j++) {
QGraphicsItem *aj = items[j];
if (aj->boundingRect().contains(ai->boundingRect()))
aj->setZValue(qMin(ai->zValue() - 1, aj->zValue()));
}
}
}
MapView::MapView(Map *map, POI *poi, QWidget *parent)
: QGraphicsView(parent)
{
@ -38,7 +55,7 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setRenderHint(QPainter::Antialiasing, true);
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
setResizeAnchor(QGraphicsView::AnchorViewCenter);
setAcceptDrops(false);
@ -169,18 +186,19 @@ void MapView::addArea(const Area &area)
}
AreaItem *ai = new AreaItem(area, _map);
_areas.append(ai);
_ar |= ai->area().boundingRect();
ai->setColor(_palette.nextColor());
ai->setWidth(_areaWidth);
ai->setStyle(_areaStyle);
ai->setOpacity(_areaOpacity);
ai->setDigitalZoom(_digitalZoom);
ai->setVisible(_showAreas);
_scene->addItem(ai);
_ar |= ai->bounds();
_areas.append(ai);
if (_showAreas)
addPOI(_poi->points(ai->area()));
addPOI(_poi->points(ai->bounds()));
}
void MapView::addWaypoints(const QVector<Waypoint> &waypoints)
@ -204,6 +222,26 @@ void MapView::addWaypoints(const QVector<Waypoint> &waypoints)
}
}
MapItem *MapView::addMap(MapAction *map)
{
MapItem *mi = new MapItem(map, _map);
mi->setColor(_palette.nextColor());
mi->setWidth(_areaWidth);
mi->setStyle(_areaStyle);
mi->setOpacity(_areaOpacity);
mi->setDigitalZoom(_digitalZoom);
mi->setVisible(_showAreas);
_scene->addItem(mi);
_ar |= mi->bounds();
_areas.append(mi);
if (_showAreas)
addPOI(_poi->points(mi->bounds()));
return mi;
}
QList<PathItem *> MapView::loadData(const Data &data)
{
QList<PathItem *> paths;
@ -226,18 +264,37 @@ QList<PathItem *> MapView::loadData(const Data &data)
else
updatePOIVisibility();
if (!data.areas().isEmpty())
updateZValues(_areas);
centerOn(contentCenter());
return paths;
}
void MapView::loadMaps(const QList<MapAction *> &maps)
{
int zoom = _map->zoom();
for (int i = 0; i < maps.size(); i++)
addMap(maps.at(i));
if (fitMapZoom() != zoom)
rescale();
else
updatePOIVisibility();
updateZValues(_areas);
centerOn(contentCenter());
}
int MapView::fitMapZoom() const
{
RectC br = _tr | _rr | _wr | _ar;
return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN),
br.isNull() ? RectC(_map->xy2ll(_map->bounds().topLeft()),
_map->xy2ll(_map->bounds().bottomRight())) : br);
br.isNull() ? _map->llBounds() : br);
}
QPointF MapView::contentCenter() const
@ -372,7 +429,7 @@ void MapView::updatePOI()
addPOI(_poi->points(_routes.at(i)->path()));
if (_showAreas)
for (int i = 0; i < _areas.size(); i++)
addPOI(_poi->points(_areas.at(i)->area()));
addPOI(_poi->points(_areas.at(i)->bounds()));
if (_showWaypoints)
for (int i = 0; i< _waypoints.size(); i++)
addPOI(_poi->points(_waypoints.at(i)->waypoint()));
@ -503,6 +560,10 @@ void MapView::wheelEvent(QWheelEvent *event)
void MapView::mouseDoubleClickEvent(QMouseEvent *event)
{
QGraphicsView::mouseDoubleClickEvent(event);
if (event->isAccepted())
return;
if (event->button() != Qt::LeftButton && event->button() != Qt::RightButton)
return;
@ -522,7 +583,12 @@ void MapView::keyPressEvent(QKeyEvent *event)
else if (_digitalZoom && event->key() == Qt::Key_Escape) {
digitalZoom(0);
return;
} else {
} else {
if (event->key() == MODIFIER_KEY) {
_cursor = viewport()->cursor();
viewport()->setCursor(Qt::CrossCursor);
}
QGraphicsView::keyPressEvent(event);
return;
}
@ -530,6 +596,24 @@ void MapView::keyPressEvent(QKeyEvent *event)
zoom(z, pos);
}
void MapView::keyReleaseEvent(QKeyEvent *event)
{
if (event->key() == MODIFIER_KEY
&& viewport()->cursor().shape() == Qt::CrossCursor)
viewport()->setCursor(_cursor);
QGraphicsView::keyReleaseEvent(event);
}
void MapView::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->modifiers() & MODIFIER)
QApplication::clipboard()->setText(Format::coordinates(
_map->xy2ll(mapToScene(event->pos())), _coordinates->format()));
else
QGraphicsView::mousePressEvent(event);
}
void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
PlotFlags flags)
{

View File

@ -29,10 +29,12 @@ class ScaleItem;
class CoordinatesItem;
class PathItem;
class GraphItem;
class AreaItem;
class PlaneItem;
class MapItem;
class Area;
class GraphicsScene;
class QTimeZone;
class MapAction;
class MapView : public QGraphicsView
{
@ -49,6 +51,7 @@ public:
MapView(Map *map, POI *poi, QWidget *parent = 0);
QList<PathItem *> loadData(const Data &data);
void loadMaps(const QList<MapAction*> &maps);
void setPalette(const Palette &palette);
void setPOI(POI *poi);
@ -108,6 +111,7 @@ private:
PathItem *addTrack(const Track &track);
PathItem *addRoute(const Route &route);
MapItem *addMap(MapAction *map);
void addArea(const Area &area);
void addWaypoints(const QVector<Waypoint> &waypoints);
void addPOI(const QList<Waypoint> &waypoints);
@ -123,13 +127,15 @@ private:
void updatePOIVisibility();
void skipColor() {_palette.nextColor();}
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void drawBackground(QPainter *painter, const QRectF &rect);
void paintEvent(QPaintEvent *event);
void scrollContentsBy(int dx, int dy);
void mouseMoveEvent(QMouseEvent *event);
void leaveEvent(QEvent *event);
GraphicsScene *_scene;
@ -138,7 +144,7 @@ private:
QList<TrackItem*> _tracks;
QList<RouteItem*> _routes;
QList<WaypointItem*> _waypoints;
QList<AreaItem*> _areas;
QList<PlaneItem*> _areas;
POIHash _pois;
RectC _tr, _rr, _wr, _ar;
@ -163,6 +169,7 @@ private:
int _digitalZoom;
bool _plot;
QCursor _cursor;
#ifdef ENABLE_HIDPI
qreal _deviceRatio;

View File

@ -477,12 +477,18 @@ QWidget *OptionsDialog::createDataPage()
QFormLayout *formLayout = new QFormLayout();
formLayout->addRow(tr("Speed:"), speedOptions);
formLayout->addRow(tr("Elevation:"), elevationOptions);
#ifdef ENABLE_TIMEZONES
formLayout->addRow(tr("Time zone:"), zoneOptions);
#endif // ENABLE_TIMEZONES
formLayout->addRow(_useSegments);
QFormLayout *segmentsLayout = new QFormLayout();
segmentsLayout->addWidget(_useSegments);
sourceTabLayout->addLayout(formLayout);
sourceTabLayout->addWidget(line());
sourceTabLayout->addLayout(segmentsLayout);
#else // Q_OS_MAC
QFormLayout *speedLayout = new QFormLayout();
QFormLayout *elevationLayout = new QFormLayout();

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

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

View File

@ -15,4 +15,15 @@ inline double toWGS24(qint32 v)
return toWGS32(LS(v, 8));
}
inline quint8 vs(const quint8 b0)
{
static const quint8 sizes[] = {4, 1, 2, 1, 3, 1, 2, 1};
return sizes[b0 & 0x07];
}
inline quint8 bs(const quint8 val)
{
return (val + 7) >> 3;
}
#endif // GARMIN_H

View File

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

View File

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

View File

@ -1,3 +1,26 @@
// TITLE
//
// R-TREES: A DYNAMIC INDEX STRUCTURE FOR SPATIAL SEARCHING
//
// DESCRIPTION
//
// A C++ templated version of the RTree algorithm.
// For more information please read the comments in RTree.h
//
// AUTHORS
//
// * 1983 Original algorithm and test code by Antonin Guttman
// and Michael Stonebraker, UC Berkely
// * 1994 ANSI C ported from original test code by Melinda Green
// (melinda@superliminal.com)
// * 1995 Sphere volume fix for degeneracy problem submitted by Paul Brook
// * 2004 Templated C++ port by Greg Douglas
// * 2018 Iterator fix and Qt macros by Martin Tuma
//
// LICENSE:
//
// Entirely free for all uses. Enjoy!
#ifndef RTREE_H
#define RTREE_H

View File

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

View File

@ -20,6 +20,7 @@
#include "cupparser.h"
#include "gpiparser.h"
#include "smlparser.h"
#include "map/map.h"
#include "data.h"
@ -82,7 +83,7 @@ void Data::processData(QList<TrackData> &trackData, QList<RouteData> &routeData)
_routes.append(Route(routeData.at(i)));
}
Data::Data(const QString &fileName)
Data::Data(const QString &fileName, bool tryUnknown)
{
QFile file(fileName);
QFileInfo fi(fileName);
@ -108,7 +109,7 @@ Data::Data(const QString &fileName)
_errorLine = it.value()->errorLine();
_errorString = it.value()->errorString();
}
} else {
} else if (tryUnknown) {
for (it = _parsers.begin(); it != _parsers.end(); it++) {
if (it.value()->parse(&file, trackData, routeData, _polygons,
_waypoints)) {

View File

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

View File

@ -51,13 +51,13 @@ class FITParser::CTX {
public:
CTX(QFile *file, QVector<Waypoint> &waypoints)
: file(file), waypoints(waypoints), len(0), endian(0), timestamp(0),
lastWrite(0), ratio(NAN) {}
ratio(NAN) {}
QFile *file;
QVector<Waypoint> &waypoints;
quint32 len;
quint8 endian;
quint32 timestamp, lastWrite;
quint32 timestamp;
MessageDefinition defs[16];
qreal ratio;
Trackpoint trackpoint;
@ -361,14 +361,12 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
ctx.ratio = ((qreal)front / (qreal)rear);
}
} else if (def->globalId == RECORD_MESSAGE) {
if (ctx.timestamp > ctx.lastWrite
&& ctx.trackpoint.coordinates().isValid()) {
if (ctx.trackpoint.coordinates().isValid()) {
ctx.trackpoint.setTimestamp(QDateTime::fromTime_t(ctx.timestamp
+ 631065600));
ctx.trackpoint.setRatio(ctx.ratio);
ctx.segment.append(ctx.trackpoint);
ctx.trackpoint = Trackpoint();
ctx.lastWrite = ctx.timestamp;
}
} else if (def->globalId == COURSE_POINT)
if (waypoint.coordinates().isValid())

View File

@ -485,15 +485,8 @@ static quint32 readCamera(QDataStream &stream, QVector<Waypoint> &waypoints,
waypoints.append(Coordinates(toWGS24(lon), toWGS24(lat)));
Area area;
Polygon polygon;
QVector<Coordinates> v(4);
v[0] = Coordinates(toWGS24(left), toWGS24(top));
v[1] = Coordinates(toWGS24(right), toWGS24(top));
v[2] = Coordinates(toWGS24(right), toWGS24(bottom));
v[3] = Coordinates(toWGS24(left), toWGS24(bottom));
polygon.append(v);
area.append(polygon);
Area area(RectC(Coordinates(toWGS24(left), toWGS24(top)),
Coordinates(toWGS24(right), toWGS24(bottom))));
switch (type) {
case 8:

View File

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

View File

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

View File

@ -81,7 +81,11 @@ bool GMAP::loadTile(const QDir &dir, bool baseMap)
QFileInfoList ml = dir.entryInfoList(QDir::Files);
for (int i = 0; i < ml.size(); i++) {
const QFileInfo &fi = ml.at(i);
tile->addFile(fi.absoluteFilePath(), tileType(fi.suffix()));
SubFile::Type tt = tileType(fi.suffix());
if (VectorTile::isTileFile(tt)) {
_files.append(new QString(fi.absoluteFilePath()));
tile->addFile(_files.last(), tt);
}
}
if (!tile->init()) {
@ -131,8 +135,10 @@ GMAP::GMAP(const QString &fileName) : _fileName(fileName)
fi.absoluteFilePath() == baseMap.absoluteFilePath());
}
if (baseDir.exists(typFilePath))
_typ = new SubFile(baseDir.filePath(typFilePath));
if (baseDir.exists(typFilePath)) {
_files.append(new QString(baseDir.filePath(typFilePath)));
_typ = new SubFile(_files.last());
}
if (!_tileTree.Count())
_errorString = "No usable map tile found";
@ -140,6 +146,11 @@ GMAP::GMAP(const QString &fileName) : _fileName(fileName)
_valid = true;
}
GMAP::~GMAP()
{
qDeleteAll(_files);
}
bool GMAP::isGMAP(const QString &path)
{
QFile file(path);

View File

@ -10,6 +10,7 @@ class GMAP : public MapData
{
public:
GMAP(const QString &fileName);
~GMAP();
QString fileName() const {return _fileName;}
@ -25,6 +26,7 @@ private:
bool loadTile(const QDir &dir, bool baseMap);
QString _fileName;
QList<const QString*> _files;
};
#endif // GMAP_H

View File

@ -0,0 +1,24 @@
#include "rgnfile.h"
#include "huffmanbuffer.h"
bool HuffmanBuffer::load(const RGNFile *rgn, SubFile::Handle &rgnHdl)
{
quint32 recordSize, recordOffset = rgn->dictOffset();
for (int i = 0; i <= _id; i++) {
if (!rgn->seek(rgnHdl, recordOffset))
return false;
if (!rgn->readVUInt32(rgnHdl, recordSize))
return false;
recordOffset = rgn->pos(rgnHdl) + recordSize;
if (recordOffset > rgn->dictOffset() + rgn->dictSize())
return false;
};
resize(recordSize);
for (int i = 0; i < QByteArray::size(); i++)
if (!rgn->readUInt8(rgnHdl, *((quint8*)(data() + i))))
return false;
return true;
}

View File

@ -0,0 +1,21 @@
#ifndef HUFFMANBUFFER_H
#define HUFFMANBUFFER_H
#include <QByteArray>
#include "subfile.h"
class RGNFile;
class HuffmanBuffer : public QByteArray
{
public:
HuffmanBuffer(quint8 id) : _id(id) {}
quint8 id() const {return _id;}
bool load(const RGNFile *rgn, SubFile::Handle &rgnHdl);
private:
quint8 _id;
};
#endif // HUFFMANBUFFER_H

View File

@ -1,17 +1,7 @@
#include "common/garmin.h"
#include "huffmantable.h"
static quint8 vs(const quint8 b0)
{
static const quint8 sizes[] = {4, 1, 2, 1, 3, 1, 2, 1};
return sizes[b0 & 0x07];
}
static inline quint8 bs(const quint8 val)
{
return (val + 7) >> 3;
}
static inline quint32 readVUint32(const quint8 *buffer, quint32 bytes)
{
quint32 val = 0;
@ -22,10 +12,9 @@ static inline quint32 readVUint32(const quint8 *buffer, quint32 bytes)
return val;
}
bool HuffmanTable::load(const SubFile &file, SubFile::Handle &hdl,
quint32 offset, quint32 size, quint32 id)
bool HuffmanTable::load(const RGNFile *rgn, SubFile::Handle &rgnHdl)
{
if (!getBuffer(file, hdl, offset, size, id))
if (!_buffer.load(rgn, rgnHdl))
return false;
_s0 = (quint8)_buffer.at(0) & 0x0F;
@ -42,31 +31,6 @@ bool HuffmanTable::load(const SubFile &file, SubFile::Handle &hdl,
_s10 = _s14 + _s1c * _s1d;
_s18 = _s10 + (_s1 << _s0);
_id = id;
return true;
}
bool HuffmanTable::getBuffer(const SubFile &file, SubFile::Handle &hdl,
quint32 offset, quint32 size, quint8 id)
{
quint32 recordSize, recordOffset = offset;
for (int i = 0; i <= id; i++) {
if (!file.seek(hdl, recordOffset))
return false;
if (!file.readVUInt32(hdl, recordSize))
return false;
recordOffset = file.pos(hdl) + recordSize;
if (recordOffset > offset + size)
return false;
};
_buffer.resize(recordSize);
for (int i = 0; i < _buffer.size(); i++)
if (!file.readUInt8(hdl, *((quint8*)(_buffer.data() + i))))
return false;
return true;
}

View File

@ -1,31 +1,26 @@
#ifndef HUFFMANTABLE_H
#define HUFFMANTABLE_H
#include "subfile.h"
#include "huffmanbuffer.h"
class RGNFile;
class HuffmanTable {
public:
HuffmanTable() : _s2(0) {}
HuffmanTable(quint8 id) : _buffer(id) {}
bool load(const SubFile &file, SubFile::Handle &hdl, quint32 offset,
quint32 size, quint32 id);
bool isNull() const {return _s2 == 0;}
bool load(const RGNFile *rgn, SubFile::Handle &rgnHdl);
quint8 maxSymbolSize() const {return _s2;}
quint32 symbol(quint32 data, quint8 &size) const;
quint8 id() const {return _id;}
quint8 id() const {return _buffer.id();}
private:
bool getBuffer(const SubFile &file, SubFile::Handle &hdl, quint32 offset,
quint32 size, quint8 id);
QByteArray _buffer;
HuffmanBuffer _buffer;
quint8 _s0, _s1, _s2, _s3;
quint8 *_s10, *_s14, *_s18;
quint8 _s1c, _s1d, _s1e, _s1f, _s20;
quint16 _s22;
quint8 _id;
};
#endif // HUFFMANTABLE_H

169
src/map/IMG/huffmantext.cpp Normal file
View File

@ -0,0 +1,169 @@
#include "common/garmin.h"
#include "subfile.h"
#include "huffmantext.h"
static inline quint32 readVUint32(const quint8 *buffer, quint32 bytes)
{
quint32 val = 0;
for (quint32 i = 0; i < bytes; i++)
val = val | (quint32)*(buffer - i) << ((bytes - i - 1) << 3);
return val;
}
bool HuffmanText::load(const RGNFile *rgn, SubFile::Handle &rgnHdl)
{
if (!_buffer.load(rgn, rgnHdl))
return false;
quint8 *buffer = (quint8 *)_buffer.constData();
_b0 = buffer[0];
_b1 = buffer[1];
_b2 = buffer[2];
_b3 = buffer[3];
_vs = vs(buffer[4]);
_bs3 = bs(_b3);
_bs1 = bs(_b1);
_mul = _bs1 + 1 + _vs;
_bp1 = buffer + _vs + 4;
_bp2 = _bp1 + _mul * _b2;
_bp3 = _bp2 + ((_bs3 + 1) << (_b0 & 0xf));
_bp4 = _bp3 - 1;
return true;
}
bool HuffmanText::fetch(const SubFile *file, SubFile::Handle &hdl,
quint32 &data, quint32 &bits, quint32 &usedBits, quint32 &usedData) const
{
quint32 rs, ls, old;
bits = _b1 - bits;
if (usedBits < bits) {
old = usedBits ? usedData >> (0x20 - usedBits) : 0;
if (!file->readVUInt32SW(hdl, 4, usedData))
return false;
ls = bits - usedBits;
rs = 0x20 - (bits - usedBits);
old = usedData >> rs | old << ls;
} else {
ls = bits;
rs = usedBits - bits;
old = usedData >> (0x20 - bits);
}
usedData = usedData << ls;
data = data | old << (0x20 - _b1);
usedBits = rs;
return true;
}
bool HuffmanText::decode(const SubFile *file, SubFile::Handle &hdl,
QVector<quint8> &str) const
{
quint32 bits = 0;
quint32 data = 0;
quint32 usedBits = 0;
quint32 usedData = 0;
quint32 ls = 8;
quint32 lo = _vs * 8 - 8;
while (true) {
if (!fetch(file, hdl, data, bits, usedBits, usedData))
return false;
quint32 off = (data >> (0x20 - (_b0 & 0xf))) * (_bs3 + 1);
quint32 sb = _bp2[off];
quint32 ss = 0;
quint32 sym = _b2 - 1;
quint32 size;
if ((_b0 & 0xf) == 0 || (sb & 1) == 0) {
if ((_b0 & 0xf) != 0) {
ss = sb >> 1;
sym = _bp2[off + 1];
}
quint8 *tp = _bp1 + ss * _mul;
quint32 sd = data >> (0x20 - _b1);
while (ss < sym) {
quint32 cnt = (sym + 1 + ss) >> 1;
quint8 *prev = _bp1 + cnt * _mul;
quint32 nd = readVUint32(prev + _bs1 - 1, _bs1);
if (sd <= nd) {
sym = cnt - (sd < nd);
if (sd < nd) {
prev = tp;
cnt = ss;
}
}
tp = prev;
ss = cnt;
}
quint32 o1 = readVUint32(tp + _bs1 - 1, _bs1);
tp = tp + _bs1;
quint32 o2 = readVUint32(tp + _vs, _vs);
size = tp[0];
quint32 os = (sd - o1) >> (_b1 - size);
if ((_b0 & 0x10) == 0) {
sym = readVUint32(_bp4 + (o2 + 1 + os) * _bs3, _bs3);
} else {
quint32 v = (os + o2) * _b3;
quint32 idx = v >> 3;
quint32 r = v & 7;
quint32 shift = 8 - r;
sym = _bp3[idx] >> r;
if (shift < _b3) {
quint32 sz = bs(_b3 - shift);
quint32 val = readVUint32(_bp3 + idx + sz, sz);
sym = sym | val << shift;
}
}
} else {
sym = readVUint32(_bp2 + off + _bs3, _bs3);
size = (sb >> 1);
}
if (_b1 < size)
return false;
data = data << size;
bits = _b1 - size;
if ((_b3 & 7) == 0) {
for (quint32 i = 0; i < (_b3 >> 3); i++) {
str.append((quint8)sym);
if (((quint8)sym == '\0'))
return true;
sym = sym >> 8;
}
} else {
quint32 cnt = _b3;
if (ls <= _b3) {
do {
quint32 shift = ls;
lo = sym << (8 - shift) | (quint32)((quint8)lo >> shift);
sym = sym >> shift;
str.append((uchar)lo);
if (((uchar)lo == '\0'))
return true;
cnt = cnt - ls;
ls = 8;
} while (7 < cnt);
ls = 8;
}
if (cnt != 0) {
lo = sym << (8 - cnt) | (quint32)((quint8)lo >> cnt);
ls = ls - cnt;
}
}
}
}

35
src/map/IMG/huffmantext.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef HUFFMANTEXT_H
#define HUFFMANTEXT_H
#include "huffmanbuffer.h"
class HuffmanText
{
public:
HuffmanText() : _buffer(0) {}
bool load(const RGNFile *rgn, SubFile::Handle &rgnHdl);
bool decode(const SubFile *file, SubFile::Handle &hdl,
QVector<quint8> &str) const;
private:
bool fetch(const SubFile *file, SubFile::Handle &hdl, quint32 &data,
quint32 &bits, quint32 &usedBits, quint32 &usedData) const;
HuffmanBuffer _buffer;
quint32 _b0;
quint32 _b1;
quint32 _b2;
quint32 _b3;
quint32 _vs;
quint32 _bs3;
quint32 _bs1;
quint32 _mul;
quint8 *_bp1;
quint8 *_bp2;
quint8 *_bp3;
quint8 *_bp4;
};
#endif // HUFFMANTEXT_H

View File

@ -1,4 +1,6 @@
#include <QTextCodec>
#include "huffmantext.h"
#include "rgnfile.h"
#include "lblfile.h"
enum Charset {Normal, Symbol, Special};
@ -55,21 +57,48 @@ static QString capitalized(const QString &str)
}
bool LBLFile::init(Handle &hdl)
LBLFile::~LBLFile()
{
quint16 codepage;
quint8 multiplier, poiMultiplier;
delete _huffmanText;
delete[] _table;
}
if (!(seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
&& readUInt32(hdl, _size) && readUInt8(hdl, multiplier)
bool LBLFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
{
quint16 hdrLen, codepage;
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)
&& seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
&& readUInt32(hdl, _size) && readUInt8(hdl, _multiplier)
&& readUInt8(hdl, _encoding) && seek(hdl, _gmpOffset + 0x57)
&& readUInt32(hdl, _poiOffset) && readUInt32(hdl, _poiSize)
&& readUInt8(hdl, poiMultiplier) && seek(hdl, _gmpOffset + 0xAA)
&& readUInt8(hdl, _poiMultiplier) && seek(hdl, _gmpOffset + 0xAA)
&& readUInt16(hdl, codepage)))
return false;
_multiplier = 1<<multiplier;
_poiMultiplier = 1<<poiMultiplier;
if (hdrLen >= 0x132) {
quint32 offset, size;
quint16 recordSize;
if (!(seek(hdl, _gmpOffset + 0x124) && readUInt32(hdl, offset)
&& readUInt32(hdl, size) && readUInt16(hdl, recordSize)))
return false;
if (size && recordSize) {
_table = new quint32[size / recordSize];
if (!seek(hdl, offset))
return false;
for (quint32 i = 0; i < size / recordSize; i++) {
if (!readVUInt32(hdl, recordSize, _table[i]))
return false;
}
}
}
if (_encoding == 11) {
_huffmanText = new HuffmanText();
if (!_huffmanText->load(rgn, rgnHdl))
return false;
}
if (codepage == 65001)
_codec = QTextCodec::codecForName("UTF-8");
@ -82,6 +111,14 @@ bool LBLFile::init(Handle &hdl)
return true;
}
void LBLFile::clear()
{
delete _huffmanText;
delete[] _table;
_huffmanText = 0;
_table = 0;
}
Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize) const
{
Label::Shield::Type shieldType = Label::Shield::None;
@ -135,20 +172,16 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize) const
}
}
Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
Label LBLFile::str2label(const QVector<quint8> &str, bool capitalize) const
{
Label::Shield::Type shieldType = Label::Shield::None;
QByteArray label, shieldLabel;
QByteArray *bap = &label;
quint8 c;
if (!seek(hdl, offset))
return Label();
for (int i = 0; i < str.size(); i++) {
const quint8 &c = str.at(i);
while (true) {
if (!readUInt8(hdl, c))
return Label();
if (!c || c == 0x1d)
if (c == 0 || c == 0x1d)
break;
if (c == 0x1c)
@ -158,7 +191,7 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
bap = &label;
else
bap->append(' ');
} else if (c <= 0x07) {
} else if (c < 0x07) {
shieldType = static_cast<Label::Shield::Type>(c);
bap = &shieldLabel;
} else if (bap == &shieldLabel && c == 0x20) {
@ -175,21 +208,74 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
Label::Shield(shieldType, shieldText));
}
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize)
Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
{
if (!_multiplier && !init(hdl))
return QString();
QVector<quint8> str;
quint8 c;
if (!seek(hdl, offset))
return Label();
do {
if (!readUInt8(hdl, c))
return Label();
str.append(c);
} while (c);
return str2label(str, capitalize);
}
Label LBLFile::labelHuffman(Handle &hdl, quint32 offset, bool capitalize) const
{
QVector<quint8> str;
if (!seek(hdl, offset))
return Label();
if (!_huffmanText->decode(this, hdl, str))
return Label();
if (!_table)
return str2label(str, capitalize);
QVector<quint8> str2;
for (int i = 0; i < str.size(); i++) {
quint32 val = _table[str.at(i)];
if (val) {
if (!seek(hdl, _offset + ((val & 0x7fffff) << _multiplier)))
return Label();
if (str2.size() && str2.back() == '\0')
str2[str2.size() - 1] = ' ';
else if (str2.size())
str2.append(' ');
if (!_huffmanText->decode(this, hdl, str2))
return Label();
} else {
if (str.at(i) == 7) {
str2.append(0);
break;
}
if (str2.size() && str2.back() == '\0')
str2[str2.size() - 1] = ' ';
str2.append(str.at(i));
}
}
return str2label(str2, capitalize);
}
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize) const
{
quint32 labelOffset;
if (poi) {
quint32 poiOffset;
if (!(_poiSize >= offset * _poiMultiplier
&& seek(hdl, _poiOffset + offset * _poiMultiplier)
if (!(_poiSize >= (offset << _poiMultiplier)
&& seek(hdl, _poiOffset + (offset << _poiMultiplier))
&& readUInt24(hdl, poiOffset) && (poiOffset & 0x3FFFFF)))
return QString();
labelOffset = _offset + (poiOffset & 0x3FFFFF) * _multiplier;
labelOffset = _offset + ((poiOffset & 0x3FFFFF) << _multiplier);
} else
labelOffset = _offset + offset * _multiplier;
labelOffset = _offset + (offset << _multiplier);
if (labelOffset > _offset + _size)
return QString();
@ -200,6 +286,8 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize)
case 9:
case 10:
return label8b(hdl, labelOffset, capitalize);
case 11:
return labelHuffman(hdl, labelOffset, capitalize);
default:
return Label();
}

View File

@ -5,28 +5,40 @@
#include "label.h"
class QTextCodec;
class HuffmanText;
class RGNFile;
class LBLFile : public SubFile
{
public:
LBLFile(IMG *img)
: SubFile(img), _codec(0), _offset(0), _size(0), _poiOffset(0),
_poiSize(0), _poiMultiplier(0), _multiplier(0), _encoding(0) {}
LBLFile(const QString &path)
: SubFile(path), _codec(0), _offset(0), _size(0), _poiOffset(0),
_poiSize(0), _poiMultiplier(0), _multiplier(0), _encoding(0) {}
: SubFile(img), _huffmanText(0), _table(0), _codec(0), _offset(0),
_size(0), _poiOffset(0), _poiSize(0), _poiMultiplier(0), _multiplier(0),
_encoding(0) {}
LBLFile(const QString *path)
: SubFile(path), _huffmanText(0), _table(0), _codec(0), _offset(0),
_size(0), _poiOffset(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) {}
_huffmanText(0), _table(0), _codec(0), _offset(0), _size(0),
_poiOffset(0), _poiSize(0), _poiMultiplier(0), _multiplier(0),
_encoding(0) {}
~LBLFile();
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
void clear();
Label label(Handle &hdl, quint32 offset, bool poi = false,
bool capitalize = true);
bool capitalize = true) const;
private:
bool init(Handle &hdl);
Label str2label(const QVector<quint8> &str, bool capitalize) const;
Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
Label label8b(Handle &hdl, quint32 offset, bool capitalize) const;
Label labelHuffman(Handle &hdl, quint32 offset, bool capitalize) const;
HuffmanText *_huffmanText;
quint32 *_table;
QTextCodec *_codec;
quint32 _offset;

View File

@ -107,7 +107,7 @@ void MapData::load()
else {
QString typFile(ProgramPaths::typFile());
if (!typFile.isEmpty()) {
SubFile typ(typFile);
SubFile typ(&typFile);
_style = new Style(&typ);
} else
_style = new Style();

View File

@ -21,7 +21,7 @@ public:
struct Poly {
/* QPointF insted of Coordinates for performance reasons (no need to
duplicate all the vectors for drawing). Note, that we do not want to
ll2xy() the points in the IMG class as this can not be done in
ll2xy() the points in the MapData class as this can not be done in
parallel. */
QVector<QPointF> points;
Label label;
@ -44,15 +44,6 @@ public:
{return id < other.id;}
};
struct Polys {
Polys() {}
Polys(const QList<Poly> &polygons, const QList<Poly> &lines)
: polygons(polygons), lines(lines) {}
QList<Poly> polygons;
QList<Poly> lines;
};
MapData();
virtual ~MapData();
@ -87,8 +78,20 @@ protected:
QString _errorString;
private:
struct Polys {
Polys() {}
Polys(const QList<Poly> &polygons, const QList<Poly> &lines)
: polygons(polygons), lines(lines) {}
QList<Poly> polygons;
QList<Poly> lines;
};
QCache<const SubDiv*, Polys> _polyCache;
QCache<const SubDiv*, QList<Point> > _pointCache;
friend class VectorTile;
friend struct PolyCTX;
};
#ifndef QT_NO_DEBUG

View File

@ -3,6 +3,7 @@
#include "subdiv.h"
#include "nodfile.h"
#include "lblfile.h"
#include "rgnfile.h"
#include "netfile.h"
@ -93,7 +94,7 @@ static bool seekToLine(BitStream4R &bs, quint8 line)
}
static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
const HuffmanTable &table, IMG::Poly &poly)
const HuffmanTable *table, MapData::Poly &poly)
{
quint32 v1, v2, v2b;
if (!bs.readVuint32SM(v1, v2, v2b))
@ -113,7 +114,7 @@ static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
poly.boundingRect = RectC(c, c);
poly.points.append(QPointF(c.lon(), c.lat()));
HuffmanStreamR stream(bs, table);
HuffmanStreamR stream(bs, *table);
if (!stream.init())
return false;
qint32 lonDelta, latDelta;
@ -132,8 +133,8 @@ static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
return stream.atEnd();
}
static bool readNodeGeometry(NODFile *nod, SubFile::Handle &nodHdl,
NODFile::AdjacencyInfo &adj, IMG::Poly &poly, quint16 cnt = 0xFFFF)
static bool readNodeGeometry(const NODFile *nod, SubFile::Handle &nodHdl,
NODFile::AdjacencyInfo &adj, MapData::Poly &poly, quint16 cnt = 0xFFFF)
{
for (int i = 0; i <= cnt; i++) {
int ret = nod->nextNode(nodHdl, adj);
@ -151,7 +152,7 @@ static bool readNodeGeometry(NODFile *nod, SubFile::Handle &nodHdl,
return true;
}
static bool skipNodes(NODFile *nod, SubFile::Handle &nodHdl,
static bool skipNodes(const NODFile *nod, SubFile::Handle &nodHdl,
NODFile::AdjacencyInfo &adj, int cnt)
{
for (int i = 0; i < cnt; i++)
@ -161,10 +162,10 @@ static bool skipNodes(NODFile *nod, SubFile::Handle &nodHdl,
return true;
}
static bool readShape(NODFile *nod, SubFile::Handle &nodHdl,
NODFile::AdjacencyInfo &adj, BitStream4R &bs, const HuffmanTable &table,
const SubDiv *subdiv, quint32 shift, IMG::Poly &poly, quint16 cnt = 0xFFFF,
bool check = false)
static bool readShape(const NODFile *nod, SubFile::Handle &nodHdl,
NODFile::AdjacencyInfo &adj, BitStream4R &bs, const HuffmanTable *table,
const SubDiv *subdiv, quint32 shift, MapData::Poly &poly,
quint16 cnt = 0xFFFF, bool check = false)
{
quint32 v1, v2, v2b;
if (!bs.readVuint32SM(v1, v2, v2b))
@ -233,7 +234,7 @@ static bool readShape(NODFile *nod, SubFile::Handle &nodHdl,
}
}
HuffmanStreamR stream(bs, table);
HuffmanStreamR stream(bs, *table);
if (!stream.init(lonSign, latSign, flags, extraBits))
return false;
qint32 lonDelta, latDelta;
@ -345,8 +346,13 @@ static bool readShape(NODFile *nod, SubFile::Handle &nodHdl,
}
bool NETFile::linkLabel(Handle &hdl, quint32 offset, quint32 size, LBLFile *lbl,
Handle &lblHdl, Label &label)
NETFile::~NETFile()
{
delete _huffmanTable;
}
bool NETFile::linkLabel(Handle &hdl, quint32 offset, quint32 size,
const LBLFile *lbl, Handle &lblHdl, Label &label) const
{
if (!seek(hdl, offset))
return false;
@ -360,19 +366,13 @@ bool NETFile::linkLabel(Handle &hdl, quint32 offset, quint32 size, LBLFile *lbl,
if (!bs.readUInt24(labelPtr))
return false;
if (labelPtr & 0x3FFFFF) {
if (labelPtr & 0x400000) {
quint32 lblOff;
if (lblOffset(hdl, labelPtr & 0x3FFFFF, lblOff) && lblOff)
label = lbl->label(lblHdl, lblOff);
} else
label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
}
if (labelPtr & 0x3FFFFF)
label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
return true;
}
bool NETFile::init(Handle &hdl)
bool NETFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
{
quint16 hdrLen;
@ -385,31 +385,36 @@ bool NETFile::init(Handle &hdl)
quint32 info;
if (!(seek(hdl, _gmpOffset + 0x37) && readUInt32(hdl, info)))
return false;
_tableId = ((info >> 2) & 0xF);
if (!(seek(hdl, _gmpOffset + 0x43) && readUInt32(hdl, _linksOffset)
&& readUInt32(hdl, _linksSize) && readUInt8(hdl, _linksShift)))
return false;
}
_init = true;
quint8 tableId = ((info >> 2) & 0xF);
if (_linksSize && (!rgn->huffmanTable() || rgn->huffmanTable()->id()
!= tableId)) {
_huffmanTable = new HuffmanTable(tableId);
if (!_huffmanTable->load(rgn, rgnHdl))
return false;
}
_tp = _huffmanTable ? _huffmanTable : rgn->huffmanTable();
}
return true;
}
bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
NODFile *nod, Handle &nodHdl, LBLFile *lbl, Handle &lblHdl,
const NODFile::BlockInfo &blockInfo, quint8 linkId, quint8 lineId,
const HuffmanTable &table, QList<IMG::Poly> *lines)
void NETFile::clear()
{
if (!_init && !init(hdl))
return false;
delete _huffmanTable;
_huffmanTable = 0;
}
Q_ASSERT(_tableId == table.id());
if (_tableId != table.id())
return false;
IMG::Poly poly;
bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
const NODFile *nod, Handle &nodHdl, const LBLFile *lbl, Handle &lblHdl,
const NODFile::BlockInfo &blockInfo, quint8 linkId, quint8 lineId,
QList<MapData::Poly> *lines) const
{
MapData::Poly poly;
if (!nod->linkType(nodHdl, blockInfo, linkId, poly.type))
return false;
@ -445,7 +450,7 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
if (s69 == 1) {
if (s68 == 1) {
if (!readShape(nod, nodHdl, adj, bs, table, subdiv, shift, poly))
if (!readShape(nod, nodHdl, adj, bs, _tp, subdiv, shift, poly))
return false;
} else {
if (!readNodeGeometry(nod, nodHdl, adj, poly))
@ -459,7 +464,7 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
if (i == lineId) {
if (shape) {
bool check = (i < ca.size()) ? (ca.at(i) & mask) : false;
if (!readShape(nod, nodHdl, adj, bs, table, subdiv,
if (!readShape(nod, nodHdl, adj, bs, _tp, subdiv,
shift, poly, step, check))
return false;
} else {
@ -483,7 +488,7 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
return false;
if (!seekToLine(bs, lineId))
return false;
if (!readLine(bs, subdiv, table, poly))
if (!readLine(bs, subdiv, _tp, poly))
return false;
}
@ -496,11 +501,8 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
return true;
}
bool NETFile::lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset)
bool NETFile::lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset) const
{
if (!_init && !init(hdl))
return false;
if (!(seek(hdl, _offset + (netOffset << _shift))
&& readUInt24(hdl, lblOffset)))
return false;

View File

@ -1,42 +1,44 @@
#ifndef NETFILE_H
#define NETFILE_H
#include "img.h"
#include "subfile.h"
#include "nodfile.h"
class NODFile;
class LBLFile;
class RGNFile;
class SubDiv;
class HuffmanTable;
class NETFile : public SubFile
{
public:
NETFile(IMG *img) : SubFile(img), _offset(0), _size(0), _linksOffset(0),
_linksSize(0), _shift(0), _linksShift(0), _init(false) {}
NETFile(const QString &path) : SubFile(path), _offset(0), _size(0),
_linksOffset(0), _linksSize(0), _shift(0), _linksShift(0),
_init(false) {}
NETFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
NETFile(IMG *img) : SubFile(img), _huffmanTable(0), _tp(0), _offset(0),
_size(0), _linksOffset(0), _linksSize(0), _shift(0), _linksShift(0) {}
NETFile(const QString *path) : SubFile(path), _huffmanTable(0), _tp(0),
_offset(0), _size(0), _linksOffset(0), _linksSize(0), _shift(0),
_linksShift(0), _init(false) {}
_linksShift(0) {}
NETFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
_huffmanTable(0), _tp(0), _offset(0), _size(0), _linksOffset(0),
_linksSize(0), _shift(0), _linksShift(0) {}
~NETFile();
bool lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset);
bool link(const SubDiv *subdiv, quint32 shift, Handle &hdl, NODFile *nod,
Handle &nodHdl, LBLFile *lbl, Handle &lblHdl,
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
void clear();
bool lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset) const;
bool link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
const NODFile *nod, Handle &nodHdl, const LBLFile *lbl, Handle &lblHdl,
const NODFile::BlockInfo &blockInfo, quint8 linkId, quint8 lineId,
const HuffmanTable &table, QList<IMG::Poly> *lines);
QList<MapData::Poly> *lines) const;
private:
bool init(Handle &hdl);
bool linkLabel(Handle &hdl, quint32 offset, quint32 size, LBLFile *lbl,
Handle &lblHdl, Label &label);
bool linkLabel(Handle &hdl, quint32 offset, quint32 size,
const LBLFile *lbl, Handle &lblHdl, Label &label) const;
HuffmanTable *_huffmanTable;
const HuffmanTable *_tp;
quint32 _offset, _size, _linksOffset, _linksSize;
quint8 _shift, _linksShift;
quint8 _tableId;
bool _init;
};
#endif // NETFILE_H

View File

@ -81,14 +81,14 @@ static bool skipOptAdjData(BitStream1 &bs)
}
bool NODFile::init(Handle &hdl)
bool NODFile::load(Handle &hdl)
{
quint16 hdrLen;
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)))
return false;
if (hdrLen < 0x7b)
return false;
return true;
if (!(seek(hdl, _gmpOffset + 0x1d) && readUInt32(hdl, _flags)
&& readUInt8(hdl, _blockShift) && readUInt8(hdl, _nodeShift)))
@ -113,14 +113,6 @@ bool NODFile::init(Handle &hdl)
return (_indexIdSize > 0);
}
quint32 NODFile::indexIdSize(Handle &hdl)
{
if (!_indexIdSize && !init(hdl))
return 0;
return _indexIdSize;
}
bool NODFile::readBlock(Handle &hdl, quint32 blockOffset,
BlockInfo &blockInfo) const
{
@ -494,7 +486,7 @@ bool NODFile::relAdjInfo(Handle &hdl, AdjacencyInfo &adj) const
return true;
}
int NODFile::nextNode(Handle &hdl, AdjacencyInfo &adjInfo)
int NODFile::nextNode(Handle &hdl, AdjacencyInfo &adjInfo) const
{
if (adjInfo.nodeOffset == 0xFFFFFFFF)
return 1;

View File

@ -1,7 +1,6 @@
#ifndef NODFILE_H
#define NODFILE_H
#include "img.h"
#include "subfile.h"
class NODFile : public SubFile
@ -57,7 +56,7 @@ public:
NODFile(IMG *img) : SubFile(img), _indexOffset(0), _indexSize(0),
_indexFlags(0), _blockOffset(0), _blockSize(0), _indexRecordSize(0),
_blockRecordSize(0), _blockShift(0), _nodeShift(0), _indexIdSize(0) {}
NODFile(const QString &path) : SubFile(path), _indexOffset(0), _indexSize(0),
NODFile(const QString *path) : SubFile(path), _indexOffset(0), _indexSize(0),
_indexFlags(0), _blockOffset(0), _blockSize(0), _indexRecordSize(0),
_blockRecordSize(0), _blockShift(0), _nodeShift(0), _indexIdSize(0) {}
NODFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
@ -65,16 +64,17 @@ public:
_blockSize(0), _indexRecordSize(0), _blockRecordSize(0), _blockShift(0),
_nodeShift(0), _indexIdSize(0) {}
quint32 indexIdSize(Handle &hdl);
bool load(Handle &hdl);
quint32 indexIdSize() const {return _indexIdSize;}
bool blockInfo(Handle &hdl, quint32 blockId, BlockInfo &blockInfo) const;
bool linkInfo(Handle &hdl, const BlockInfo &blockInfo, quint32 linkId,
LinkInfo &linkInfo) const;
bool linkType(Handle &hdl, const BlockInfo &blockInfo, quint8 linkId,
quint32 &type) const;
int nextNode(Handle &hdl, AdjacencyInfo &adjInfo);
int nextNode(Handle &hdl, AdjacencyInfo &adjInfo) const;
private:
bool init(Handle &hdl);
bool nodeInfo(Handle &hdl, const BlockInfo &blockInfo, quint32 nodeOffset,
NodeInfo &nodeInfo) const;
bool nodeOffset(Handle &hdl, const BlockInfo &blockInfo, quint8 nodeId,

View File

@ -1,5 +1,6 @@
#include <QFont>
#include <QPainter>
#include "map/imgmap.h"
#include "textpathitem.h"
#include "textpointitem.h"
#include "bitmapline.h"
@ -166,6 +167,10 @@ void RasterTile::render()
{
QList<TextItem*> textItems;
ll2xy(_polygons);
ll2xy(_lines);
ll2xy(_points);
processPoints(textItems);
processPolygons(textItems);
processLines(textItems);
@ -186,6 +191,25 @@ void RasterTile::render()
qDeleteAll(textItems);
}
void RasterTile::ll2xy(QList<MapData::Poly> &polys)
{
for (int i = 0; i < polys.size(); i++) {
MapData::Poly &poly = polys[i];
for (int j = 0; j < poly.points.size(); j++) {
QPointF &p = poly.points[j];
p = _map->ll2xy(Coordinates(p.x(), p.y()));
}
}
}
void RasterTile::ll2xy(QList<MapData::Point> &points)
{
for (int i = 0; i < points.size(); i++) {
QPointF p(_map->ll2xy(points.at(i).coordinates));
points[i].coordinates = Coordinates(p.x(), p.y());
}
}
void RasterTile::drawPolygons(QPainter *painter)
{
for (int n = 0; n < _style->drawOrder().size(); n++) {
@ -430,4 +454,3 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
delete item;
}
}

View File

@ -7,14 +7,15 @@
class QPainter;
class TextItem;
class Style;
class IMGMap;
class RasterTile
{
public:
RasterTile(const Style *style, int zoom, const QRect &rect,
RasterTile(IMGMap *map, const Style *style, int zoom, const QRect &rect,
const QString &key, const QList<MapData::Poly> &polygons,
const QList<MapData::Poly> &lines, QList<MapData::Point> &points)
: _style(style), _zoom(zoom), _xy(rect.topLeft()),
: _map(map), _style(style), _zoom(zoom), _xy(rect.topLeft()),
_key(key), _img(rect.size(), QImage::Format_ARGB32_Premultiplied),
_polygons(polygons), _lines(lines), _points(points) {}
@ -25,6 +26,9 @@ public:
void render();
private:
void ll2xy(QList<MapData::Poly> &polys);
void ll2xy(QList<MapData::Point> &points);
void drawPolygons(QPainter *painter);
void drawLines(QPainter *painter);
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
@ -35,6 +39,7 @@ private:
void processShields(const QRect &tileRect, QList<TextItem*> &textItems);
void processStreetNames(const QRect &tileRect, QList<TextItem*> &textItems);
IMGMap *_map;
const Style *_style;
int _zoom;
QPoint _xy;

View File

@ -24,6 +24,11 @@ static quint64 pointId(const QPoint &pos, quint32 type, quint32 labelPtr)
return id;
}
RGNFile::~RGNFile()
{
delete _huffmanTable;
}
bool RGNFile::skipClassFields(Handle &hdl) const
{
quint8 flags;
@ -96,7 +101,7 @@ bool RGNFile::skipGblFields(Handle &hdl, quint32 flags) const
return seek(hdl, pos(hdl) + cnt);
}
bool RGNFile::init(Handle &hdl)
bool RGNFile::load(Handle &hdl)
{
quint16 hdrLen;
@ -125,24 +130,29 @@ bool RGNFile::init(Handle &hdl)
}
if (hdrLen >= 0x7D) {
quint32 dictOffset, dictSize, info;
if (!(seek(hdl, _gmpOffset + 0x71) && readUInt32(hdl, dictOffset)
&& readUInt32(hdl, dictSize) && readUInt32(hdl, info)))
quint32 info;
if (!(seek(hdl, _gmpOffset + 0x71) && readUInt32(hdl, _dictOffset)
&& readUInt32(hdl, _dictSize) && readUInt32(hdl, info)))
return false;
if (dictSize && dictOffset && (info & 0x1E))
if (!_huffmanTable.load(*this, hdl, dictOffset, dictSize,
((info >> 1) & 0xF) - 1))
if (_dictSize && _dictOffset && (info & 0x1E)) {
_huffmanTable = new HuffmanTable(((info >> 1) & 0xF) - 1);
if (!_huffmanTable->load(this, hdl))
return false;
}
}
_init = true;
return true;
}
void RGNFile::clear()
{
delete _huffmanTable;
_huffmanTable = 0;
}
bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl, NETFile *net,
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl, NETFile *net,
Handle &netHdl, QList<IMG::Poly> *polys) const
{
const SubDiv::Segment &segment = (segmentType == Line)
@ -218,7 +228,7 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
}
bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
QList<IMG::Poly> *polys) const
{
quint32 labelPtr, len;
@ -246,13 +256,13 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
poly.type = 0x10000 | (quint16(type)<<8) | (subtype & 0x1F);
labelPtr = 0;
if (!_huffmanTable.isNull()) {
if (_huffmanTable) {
pos = QPoint(LS(subdiv->lon(), 8) + LS(lon, 32-subdiv->bits()),
LS(subdiv->lat(), 8) + LS(lat, (32-subdiv->bits())));
qint32 lonDelta, latDelta;
BitStream4F bs(*this, hdl, len);
HuffmanStreamF stream(bs, _huffmanTable);
HuffmanStreamF stream(bs, *_huffmanTable);
if (!stream.init(segmentType == Line))
return false;
@ -329,7 +339,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
}
bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
QList<IMG::Point> *points) const
{
const SubDiv::Segment &segment = (segmentType == IndexedPoint)
@ -363,9 +373,8 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
point.coordinates = Coordinates(toWGS24(pos.x()), toWGS24(pos.y()));
point.id = pointId(pos, point.type, labelPtr & 0x3FFFFF);
if (lbl && (labelPtr & 0x3FFFFF))
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF,
labelPtr & 0x400000, !(point.type == 0x1400 || point.type == 0x1500
|| point.type == 0x1e00));
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, labelPtr & 0x400000,
!(point.type == 0x1400 || point.type == 0x1500 || point.type == 0x1e00));
points->append(point);
}
@ -373,11 +382,12 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
return true;
}
bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
Handle &lblHdl, QList<IMG::Point> *points) const
bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
const LBLFile *lbl, Handle &lblHdl, QList<IMG::Point> *points) const
{
const SubDiv::Segment &segment = subdiv->extPoints();
if (!segment.isValid())
return true;
if (!seek(hdl, segment.offset()))
@ -423,30 +433,27 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
}
bool RGNFile::links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
NETFile *net, Handle &netHdl, NODFile *nod, Handle &nodHdl, LBLFile *lbl,
Handle &lblHdl, QList<IMG::Poly> *lines) const
const NETFile *net, Handle &netHdl, const NODFile *nod, Handle &nodHdl,
const LBLFile *lbl, Handle &lblHdl, QList<IMG::Poly> *lines) const
{
quint32 size, blockIndexIdSize, blockIndexId;
quint32 size, blockIndexId;
quint8 flags;
const SubDiv::Segment &segment = subdiv->roadReferences();
if (!net || !nod)
return false;
if (!segment.isValid())
return true;
if (!seek(hdl, segment.offset()))
return false;
if (!net || !nod)
return false;
if (!(blockIndexIdSize = nod->indexIdSize(nodHdl)))
return false;
while (pos(hdl) < segment.end()) {
if (!readVUInt32(hdl, size))
return false;
quint32 entryStart = pos(hdl);
if (!(readUInt8(hdl, flags) && readVUInt32(hdl, blockIndexIdSize,
if (!(readUInt8(hdl, flags) && readVUInt32(hdl, nod->indexIdSize(),
blockIndexId)))
return false;
@ -494,10 +501,11 @@ bool RGNFile::links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
}
net->link(subdiv, shift, netHdl, nod, nodHdl, lbl, lblHdl,
blockInfo, linkId, lineId, _huffmanTable, lines);
blockInfo, linkId, lineId, lines);
}
Q_ASSERT(entryStart + size == pos(hdl));
if (entryStart + size != pos(hdl))
return false;
}
return true;
@ -546,7 +554,7 @@ QMap<RGNFile::SegmentType, SubDiv::Segment> RGNFile::segments(Handle &hdl,
return ret;
}
bool RGNFile::subdivInit(Handle &hdl, SubDiv *subdiv) const
bool RGNFile::subdivInit(Handle &hdl, SubDiv *subdiv)
{
QMap<RGNFile::SegmentType, SubDiv::Segment> seg(segments(hdl, subdiv));
SubDiv::Segment extPoints, extLines, extPolygons;

View File

@ -1,14 +1,13 @@
#ifndef RGNFILE_H
#define RGNFILE_H
#include "img.h"
#include "subfile.h"
#include "subdiv.h"
#include "huffmantable.h"
class LBLFile;
class NETFile;
class NODFile;
class HuffmanTable;
class RGNFile : public SubFile
{
@ -22,35 +21,41 @@ public:
};
RGNFile(IMG *img)
: SubFile(img), _offset(0), _size(0), _polygonsOffset(0),
: SubFile(img), _huffmanTable(0), _offset(0), _size(0), _polygonsOffset(0),
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
_pointsSize(0), _init(false) {}
RGNFile(const QString &path)
: SubFile(path), _offset(0), _size(0), _polygonsOffset(0),
_pointsSize(0) {}
RGNFile(const QString *path)
: SubFile(path), _huffmanTable(0), _offset(0), _size(0), _polygonsOffset(0),
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
_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) {}
_pointsSize(0) {}
RGNFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
_huffmanTable(0), _offset(0), _size(0), _polygonsOffset(0),
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
_pointsSize(0) {}
~RGNFile();
bool initialized() const {return _init;}
bool init(Handle &hdl);
void clear();
bool load(Handle &hdl);
bool polyObjects(Handle &hdl, const SubDiv *subdiv, SegmentType segmentType,
LBLFile *lbl, Handle &lblHdl, NETFile *net, Handle &netHdl,
QList<IMG::Poly> *polys) const;
const LBLFile *lbl, Handle &lblHdl, NETFile *net, Handle &netHdl,
QList<MapData::Poly> *polys) const;
bool pointObjects(Handle &hdl, const SubDiv *subdiv, SegmentType segmentType,
LBLFile *lbl, Handle &lblHdl, QList<IMG::Point> *points) const;
const LBLFile *lbl, Handle &lblHdl, QList<MapData::Point> *points) const;
bool extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
QList<IMG::Poly> *polys) const;
bool extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
Handle &lblHdl, QList<IMG::Point> *points) const;
bool links(Handle &hdl, const SubDiv *subdiv, quint32 shift, NETFile *net,
Handle &netHdl, NODFile *nod, Handle &nodHdl, LBLFile *lbl, Handle &lblHdl,
QList<IMG::Poly> *lines) const;
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
QList<MapData::Poly> *polys) const;
bool extPointObjects(Handle &hdl, const SubDiv *subdiv, const LBLFile *lbl,
Handle &lblHdl, QList<MapData::Point> *points) const;
bool links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
const NETFile *net, Handle &netHdl, const NODFile *nod, Handle &nodHdl,
const LBLFile *lbl, Handle &lblHdl, QList<MapData::Poly> *lines) const;
bool subdivInit(Handle &hdl, SubDiv *subdiv) const;
bool subdivInit(Handle &hdl, SubDiv *subdiv);
const HuffmanTable *huffmanTable() const {return _huffmanTable;}
quint32 dictOffset() const {return _dictOffset;}
quint32 dictSize() const {return _dictSize;}
private:
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
@ -60,8 +65,12 @@ private:
const;
bool skipGblFields(Handle &hdl, quint32 flags) const;
HuffmanTable *_huffmanTable;
quint32 _offset;
quint32 _size;
quint32 _dictOffset;
quint32 _dictSize;
quint32 _polygonsOffset;
quint32 _polygonsSize;
@ -75,10 +84,6 @@ private:
quint32 _pointsSize;
quint32 _pointsLclFlags[3];
quint32 _pointsGblFlags;
HuffmanTable _huffmanTable;
bool _init;
};
#endif // RGNFILE_H

View File

@ -42,14 +42,12 @@ public:
: _gmpOffset(0), _img(img), _blocks(new QVector<quint16>()), _path(0) {}
SubFile(SubFile *gmp, quint32 offset) : _gmpOffset(offset), _img(gmp->_img),
_blocks(gmp->_blocks), _path(gmp->_path) {}
SubFile(const QString &path)
: _gmpOffset(0), _img(0), _blocks(0), _path(new QString(path)) {}
SubFile(const QString *path)
: _gmpOffset(0), _img(0), _blocks(0), _path(path) {}
~SubFile()
{
if (!_gmpOffset) {
if (!_gmpOffset)
delete _blocks;
delete _path;
}
}
void addBlock(quint16 block) {_blocks->append(block);}
@ -151,7 +149,7 @@ private:
IMG *_img;
QVector<quint16> *_blocks;
QString *_path;
const QString *_path;
};
#endif // SUBFILE_H

View File

@ -202,14 +202,18 @@ bool TREFile::load(int idx)
double min[2], max[2];
RectC bounds(Coordinates(LB(lon - width), toWGS24(lat + height)),
Coordinates(RB(lon + width), toWGS24(lat - height)));
if (!bounds.isValid())
goto error;
min[0] = bounds.left();
min[1] = bounds.bottom();
max[0] = bounds.right();
max[1] = bounds.top();
/* both mkgmap and cGPSmapper generate all kinds of broken subdiv bounds
(zero lat/lon, zero width/height, ...) so we check only that the
subdiv item does not break the rtree, not for full bounds validity. */
if (!(min[0] <= max[0] && min[1] <= max[1]))
goto error;
tree->Insert(min, max, s);
}

View File

@ -14,7 +14,7 @@ class TREFile : public SubFile
{
public:
TREFile(IMG *img) : SubFile(img) {}
TREFile(const QString &path) : SubFile(path) {}
TREFile(const QString *path) : SubFile(path) {}
TREFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset) {}
~TREFile();

View File

@ -1,16 +1,16 @@
#include "vectortile.h"
static void copyPolys(const RectC &rect, QList<IMG::Poly> *src,
QList<IMG::Poly> *dst)
static void copyPolys(const RectC &rect, QList<MapData::Poly> *src,
QList<MapData::Poly> *dst)
{
for (int i = 0; i < src->size(); i++)
if (rect.intersects(src->at(i).boundingRect))
dst->append(src->at(i));
}
static void copyPoints(const RectC &rect, QList<IMG::Point> *src,
QList<IMG::Point> *dst)
static void copyPoints(const RectC &rect, QList<MapData::Point> *src,
QList<MapData::Point> *dst)
{
for (int j = 0; j < src->size(); j++)
if (rect.contains(src->at(j).coordinates))
@ -38,58 +38,6 @@ SubFile *VectorTile::file(SubFile::Type type)
}
}
SubFile *VectorTile::addFile(IMG *img, SubFile::Type type)
{
switch (type) {
case SubFile::TRE:
_tre = new TREFile(img);
return _tre;
case SubFile::RGN:
_rgn = new RGNFile(img);
return _rgn;
case SubFile::LBL:
_lbl = new LBLFile(img);
return _lbl;
case SubFile::NET:
_net = new NETFile(img);
return _net;
case SubFile::NOD:
_nod = new NODFile(img);
return _nod;
case SubFile::GMP:
_gmp = new SubFile(img);
return _gmp;
default:
return 0;
}
}
SubFile *VectorTile::addFile(const QString &path, SubFile::Type type)
{
switch (type) {
case SubFile::TRE:
_tre = new TREFile(path);
return _tre;
case SubFile::RGN:
_rgn = new RGNFile(path);
return _rgn;
case SubFile::LBL:
_lbl = new LBLFile(path);
return _lbl;
case SubFile::NET:
_net = new NETFile(path);
return _net;
case SubFile::NOD:
_nod = new NODFile(path);
return _nod;
case SubFile::GMP:
_gmp = new SubFile(path);
return _gmp;
default:
return 0;
}
}
bool VectorTile::init()
{
if (_gmp && !initGMP())
@ -120,23 +68,54 @@ bool VectorTile::initGMP()
return true;
}
bool VectorTile::load(SubFile::Handle &rgnHdl, SubFile::Handle &lblHdl,
SubFile::Handle &netHdl, SubFile::Handle &nodHdl)
{
_loaded = -1;
if (!_rgn->load(rgnHdl))
return false;
if (_lbl && !_lbl->load(lblHdl, _rgn, rgnHdl))
return false;
if (_net && !_net->load(netHdl, _rgn, rgnHdl))
return false;
if (_nod && !_nod->load(nodHdl))
return false;
_loaded = 1;
return true;
}
void VectorTile::clear()
{
_tre->clear();
_rgn->clear();
if (_lbl)
_lbl->clear();
if (_net)
_net->clear();
_loaded = 0;
}
void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
QCache<const SubDiv *, IMG::Polys> *polyCache) const
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
QCache<const SubDiv *, MapData::Polys> *polyCache)
{
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl), netHdl(_net), nodHdl(_nod);
if (!_rgn->initialized() && !_rgn->init(rgnHdl))
if (_loaded < 0 || (!_loaded && !load(rgnHdl, lblHdl, netHdl, nodHdl)))
return;
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
for (int i = 0; i < subdivs.size(); i++) {
SubDiv *subdiv = subdivs.at(i);
IMG::Polys *polys = polyCache->object(subdiv);
MapData::Polys *polys = polyCache->object(subdiv);
if (!polys) {
quint32 shift = _tre->shift(subdiv->bits());
QList<IMG::Poly> p, l;
QList<MapData::Poly> p, l;
if (!subdiv->initialized() && !_rgn->subdivInit(rgnHdl, subdiv))
continue;
@ -154,7 +133,7 @@ void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
copyPolys(rect, &p, polygons);
copyPolys(rect, &l, lines);
polyCache->insert(subdiv, new IMG::Polys(p, l));
polyCache->insert(subdiv, new MapData::Polys(p, l));
} else {
copyPolys(rect, &(polys->polygons), polygons);
copyPolys(rect, &(polys->lines), lines);
@ -163,21 +142,21 @@ void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
}
void VectorTile::points(const RectC &rect, int bits, bool baseMap,
QList<IMG::Point> *points, QCache<const SubDiv *,
QList<IMG::Point> > *pointCache) const
QList<MapData::Point> *points, QCache<const SubDiv *,
QList<MapData::Point> > *pointCache)
{
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl);
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl), netHdl(_net), nodHdl(_nod);
if (!_rgn->initialized() && !_rgn->init(rgnHdl))
if (_loaded < 0 || (!_loaded && !load(rgnHdl, lblHdl, netHdl, nodHdl)))
return;
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
for (int i = 0; i < subdivs.size(); i++) {
SubDiv *subdiv = subdivs.at(i);
QList<IMG::Point> *pl = pointCache->object(subdiv);
QList<MapData::Point> *pl = pointCache->object(subdiv);
if (!pl) {
QList<IMG::Point> p;
QList<MapData::Point> p;
if (!subdiv->initialized() && !_rgn->subdivInit(rgnHdl, subdiv))
continue;
@ -189,7 +168,7 @@ void VectorTile::points(const RectC &rect, int bits, bool baseMap,
_rgn->extPointObjects(rgnHdl, subdiv, _lbl, lblHdl, &p);
copyPoints(rect, &p, points);
pointCache->insert(subdiv, new QList<IMG::Point>(p));
pointCache->insert(subdiv, new QList<MapData::Point>(p));
} else
copyPoints(rect, pl, points);
}

View File

@ -1,7 +1,6 @@
#ifndef VECTORTILE_H
#define VECTORTILE_H
#include "trefile.h"
#include "trefile.h"
#include "rgnfile.h"
#include "lblfile.h"
@ -10,7 +9,8 @@
class VectorTile {
public:
VectorTile() : _tre(0), _rgn(0), _lbl(0), _net(0), _nod(0), _gmp(0) {}
VectorTile()
: _tre(0), _rgn(0), _lbl(0), _net(0), _nod(0), _gmp(0), _loaded(0) {}
~VectorTile()
{
delete _tre; delete _rgn; delete _lbl; delete _net; delete _nod;
@ -19,21 +19,19 @@ public:
bool init();
void markAsBasemap() {_tre->markAsBasemap();}
void clear() {_tre->clear();}
void clear();
const RectC &bounds() const {return _tre->bounds();}
Range zooms() const {return _tre->zooms();}
SubFile *file(SubFile::Type type);
SubFile *addFile(IMG *img, SubFile::Type type);
SubFile *addFile(const QString &path, SubFile::Type type);
void polys(const RectC &rect, int bits, bool baseMap,
QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
QCache<const SubDiv *, IMG::Polys> *polyCache) const;
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
QCache<const SubDiv *, MapData::Polys> *polyCache);
void points(const RectC &rect, int bits, bool baseMap,
QList<IMG::Point> *points, QCache<const SubDiv*,
QList<IMG::Point> > *pointCache) const;
QList<MapData::Point> *points, QCache<const SubDiv*,
QList<MapData::Point> > *pointCache);
static bool isTileFile(SubFile::Type type)
{
@ -42,8 +40,37 @@ public:
|| type == SubFile::NOD || type == SubFile::GMP);
}
template<typename T>
SubFile *addFile(T *container, SubFile::Type type)
{
switch (type) {
case SubFile::TRE:
_tre = new TREFile(container);
return _tre;
case SubFile::RGN:
_rgn = new RGNFile(container);
return _rgn;
case SubFile::LBL:
_lbl = new LBLFile(container);
return _lbl;
case SubFile::NET:
_net = new NETFile(container);
return _net;
case SubFile::NOD:
_nod = new NODFile(container);
return _nod;
case SubFile::GMP:
_gmp = new SubFile(container);
return _gmp;
default:
return 0;
}
}
private:
bool initGMP();
bool load(SubFile::Handle &rgnHdl, SubFile::Handle &lblHdl,
SubFile::Handle &netHdl, SubFile::Handle &nodHdl);
TREFile *_tre;
RGNFile *_rgn;
@ -51,6 +78,8 @@ private:
NETFile *_net;
NODFile *_nod;
SubFile *_gmp;
int _loaded;
};
#ifndef QT_NO_DEBUG

View File

@ -11,7 +11,12 @@ public:
AngularUnits(int code);
bool operator==(const AngularUnits &other) const
{return (_code == other._code && _f == other._f);}
{
if (_code == 9110)
return (other._code == 9110);
else
return (_f == other._f);
}
bool isNull() const {return std::isnan(_f);}
bool isValid() const {return !std::isnan(_f);}

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