1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-01 21:39:15 +02:00

Compare commits

..

88 Commits
5.18 ... 6.0

Author SHA1 Message Date
083dd39bef Fixed broken merge 2018-09-23 12:20:04 +02:00
bd64ca4f57 Merge branch 'origin/master' into Weblate 2018-09-23 12:00:15 +02:00
b382a5e674 Translated using Weblate (Russian)
Currently translated at 100.0% (323 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2018-09-23 11:57:20 +02:00
20687a1df7 Translated using Weblate (Finnish)
Currently translated at 98.1% (317 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2018-09-23 11:57:20 +02:00
bb82750e9b Translated using Weblate (German)
Currently translated at 100.0% (323 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2018-09-23 11:57:20 +02:00
51e6058960 Translated using Weblate (German)
Currently translated at 99.6% (322 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2018-09-23 11:57:20 +02:00
db3f111815 Translated using Weblate (Swedish)
Currently translated at 100.0% (323 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2018-09-23 11:57:20 +02:00
219311577f Translated using Weblate (German)
Currently translated at 99.3% (321 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2018-09-23 11:57:20 +02:00
26d4770f47 Translated using Weblate (Czech)
Currently translated at 100.0% (323 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/cs/
2018-09-23 11:57:20 +02:00
db0d9ceffb Translated using Weblate (Russian)
Currently translated at 99.3% (320 of 322 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2018-09-23 11:57:20 +02:00
fc9b01480c Translated using Weblate (Russian)
Currently translated at 99.0% (319 of 322 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2018-09-23 11:56:41 +02:00
cd8f415615 Translated using Weblate (Russian)
Currently translated at 100.0% (323 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2018-09-23 11:35:22 +02:00
824393879b Translated using Weblate (Finnish)
Currently translated at 98.1% (317 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2018-09-23 11:35:21 +02:00
f79f555d6f Translated using Weblate (German)
Currently translated at 100.0% (323 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2018-09-23 11:35:02 +02:00
13e9a50d59 Translated using Weblate (German)
Currently translated at 99.6% (322 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2018-09-23 11:23:05 +02:00
f1667e70b5 Translated using Weblate (Swedish)
Currently translated at 100.0% (323 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2018-09-23 09:23:04 +02:00
1ce347230b Translated using Weblate (German)
Currently translated at 99.3% (321 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2018-09-23 09:23:04 +02:00
d4f3e293df Translated using Weblate (Czech)
Currently translated at 100.0% (323 of 323 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/cs/
2018-09-23 09:23:03 +02:00
7492b74aed Merge branch 'origin/master' into Weblate 2018-09-22 23:31:47 +02:00
71dbb176bb Translation sources update 2018-09-22 23:30:54 +02:00
301107add1 Merge branch 'origin/master' into Weblate 2018-09-22 23:13:58 +02:00
60ae4c0268 Translations update 2018-09-22 23:12:22 +02:00
bd76e508ae Merge branch 'origin/master' into Weblate 2018-09-22 14:17:48 +02:00
e9f7642cde Code cleanup 2018-09-22 14:17:24 +02:00
5c73cb55cb Merge branch 'origin/master' into Weblate 2018-09-22 13:33:21 +02:00
c39298000d Added TMS maps support 2018-09-22 13:32:54 +02:00
e17d7d4a8f Merge branch 'origin/master' into Weblate 2018-09-22 12:43:45 +02:00
65b74b146d Added support for local (file:) URLs 2018-09-22 12:42:49 +02:00
b937b9f2cb Merge branch 'origin/master' into Weblate 2018-09-22 10:26:29 +02:00
d7fe0fa9bf Fixed broken automatic loading of MBTiles maps 2018-09-22 10:25:43 +02:00
9657104f50 Merge branch 'origin/master' into Weblate 2018-09-21 23:25:07 +02:00
5a692c71a8 Added support for tiles with a different size than 256px 2018-09-21 23:18:05 +02:00
e8ede272ae Merge branch 'origin/master' into Weblate 2018-09-21 01:59:41 +02:00
39a8a144dd Addedmissing SQL libs to the Windows installer 2018-09-21 01:58:58 +02:00
02700a485d Merge branch 'origin/master' into Weblate 2018-09-21 00:20:17 +02:00
99ea19e35a Use the map name from the metadata table if available 2018-09-21 00:19:30 +02:00
a6bb0f1520 Merge branch 'origin/master' into Weblate 2018-09-20 08:51:13 +02:00
0a74684713 Improved map validity checks 2018-09-20 08:50:52 +02:00
332a4d9393 Merge branch 'origin/master' into Weblate 2018-09-20 08:00:21 +02:00
db98f381b5 Added initial MBTiles support 2018-09-20 07:59:47 +02:00
31a600638f Translated using Weblate (Norwegian Bokmål)
Currently translated at 13.9% (45 of 322 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2018-09-20 05:29:31 +02:00
2ff18bc373 Merge branch 'origin/master' into Weblate 2018-09-19 01:06:37 +02:00
c2e301f4e8 Added Norwegian translation file 2018-09-19 01:05:49 +02:00
a25303fe98 Merge branch 'origin/master' into Weblate 2018-09-17 20:12:05 +02:00
2bee8656a4 Properly split the paths exactly at the date line 2018-09-17 20:11:23 +02:00
4a31f6f76d Merge branch 'origin/master' into Weblate 2018-09-16 19:40:06 +02:00
eaef588443 Moved maps info to a separate section 2018-09-16 19:40:02 +02:00
87a808265e Merge branch 'origin/master' into Weblate 2018-09-16 19:34:21 +02:00
a39cef2abd Fixed typo 2018-09-16 19:34:18 +02:00
960827e92b Merge branch 'origin/master' into Weblate 2018-09-16 19:32:42 +02:00
7de1b84f77 Extended build info 2018-09-16 19:32:40 +02:00
4b1fa13429 Merge branch 'origin/master' into Weblate 2018-09-16 17:51:14 +02:00
f10857eddc Added english translation file
(Language selection is broken without it on Mac when the user's languages
list contains more than one language)
2018-09-16 17:49:47 +02:00
781fc22113 Merge branch 'origin/master' into Weblate 2018-09-16 17:41:00 +02:00
9ced0fd3a7 Do not process the Danish translations until they are done 2018-09-16 17:40:22 +02:00
3e71d1b785 Merge branch 'origin/master' into Weblate 2018-09-16 17:13:31 +02:00
491bf5614b Lupdate formating 2018-09-16 17:12:49 +02:00
fc873719e1 Merge branch 'origin/master' into Weblate 2018-09-16 17:12:05 +02:00
99c3edddfd Added Danish translation stub 2018-09-16 17:11:35 +02:00
fde8ad620b Merge branch 'origin/master' into Weblate 2018-09-16 13:19:35 +02:00
7855c69729 Fixed WMS/WMTS URLs composing 2018-09-16 12:05:11 +02:00
8749be9103 Merge branch 'origin/master' into Weblate 2018-09-15 13:40:38 +02:00
6f9f49a435 Merge branch 'origin/master' into Weblate 2018-09-15 10:43:17 +02:00
cfdb12c4ae Merge branch 'origin/master' into Weblate 2018-09-15 08:40:35 +02:00
9436f98023 Merge branch 'origin/master' into Weblate 2018-09-15 00:23:12 +02:00
905f80b1ce Merge branch 'origin/master' into Weblate 2018-09-14 00:09:53 +02:00
4ef1fa77f8 Merge branch 'origin/master' into Weblate 2018-09-13 01:45:21 +02:00
d483cd35cd Merge branch 'origin/master' into Weblate 2018-09-13 01:15:41 +02:00
c2b09df118 Merge branch 'origin/master' into Weblate 2018-09-13 00:48:49 +02:00
7e537d819a Merge branch 'origin/master' into Weblate 2018-09-12 20:13:37 +02:00
b68567f000 Merge branch 'origin/master' into Weblate 2018-09-12 19:58:17 +02:00
ca8ff6c7ee Translated using Weblate (Finnish)
Currently translated at 98.1% (316 of 322 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2018-09-11 11:42:40 +02:00
e9c15ef956 Translated using Weblate (Finnish)
Currently translated at 97.8% (315 of 322 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2018-09-11 09:15:20 +02:00
e39f0881ab Translated using Weblate (Russian)
Currently translated at 100.0% (322 of 322 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2018-09-11 08:55:41 +02:00
6f05d38d31 Translated using Weblate (Russian)
Currently translated at 99.3% (320 of 322 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2018-09-11 08:26:55 +02:00
9cb91a35ef Translated using Weblate (Russian)
Currently translated at 99.0% (319 of 322 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2018-09-11 08:21:48 +02:00
bb0073d7e7 Translated using Weblate (Swedish)
Currently translated at 100.0% (322 of 322 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2018-09-11 08:21:47 +02:00
97d646bb19 Merge branch 'origin/master' into Weblate 2018-09-11 01:01:05 +02:00
3fcf04daf7 Merge branch 'origin/master' into Weblate 2018-09-11 00:36:06 +02:00
3daab92b84 Merge branch 'origin/master' into Weblate 2018-09-11 00:34:31 +02:00
fc555fd7d0 Merge branch 'origin/master' into Weblate 2018-09-10 21:23:03 +02:00
57741f8c2d Translated using Weblate (Swedish)
Currently translated at 100.0% (316 of 316 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2018-09-09 19:10:29 +02:00
6eb3a4f7de Translated using Weblate (Russian)
Currently translated at 100.0% (316 of 316 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2018-09-09 19:10:29 +02:00
295a89b3cc Translated using Weblate (German)
Currently translated at 100.0% (316 of 316 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2018-09-09 19:10:29 +02:00
dc3fdc4c3b Translated using Weblate (Finnish)
Currently translated at 98.7% (312 of 316 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2018-09-09 19:10:29 +02:00
3867b723a9 Translated using Weblate (Swedish)
Currently translated at 100.0% (316 of 316 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2018-09-09 19:10:29 +02:00
d7fc400d73 Translated using Weblate (Russian)
Currently translated at 100.0% (316 of 316 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2018-09-09 19:10:29 +02:00
f8f6859e7d Translated using Weblate (Finnish)
Currently translated at 98.7% (312 of 316 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2018-09-09 19:10:29 +02:00
33 changed files with 4143 additions and 181 deletions

View File

@ -1,4 +1,4 @@
version: 5.18.{build}
version: 6.0.{build}
configuration: Release
platform: Any CPU
environment:

View File

@ -3,7 +3,7 @@ GPXSee is a Qt-based GPS log file viewer and analyzer that supports GPX, TCX,
KML, FIT, IGC, NMEA, SLF, LOC and OziExplorer files.
## Features
* [User-definable online maps](https://github.com/tumic0/GPXSee-maps) (OSM/Google tiles, WMTS, WMS).
* User-definable online maps (OSM/Google tiles, WMTS, WMS).
* Offline maps (OziExplorer maps, TrekBuddy maps/atlases, Garmin JNX maps, GeoTIFF images).
* Elevation, speed, heart rate, cadence, power, temperature and gear ratio/shifts graphs.
* Support for multiple tracks in one view.
@ -17,10 +17,15 @@ KML, FIT, IGC, NMEA, SLF, LOC and OziExplorer files.
![GPXSee - Linux](https://a.fsdn.com/con/app/proj/gpxsee/screenshots/linux2.png)
## Build
Build requirements:
* Qt 4.8 or QT 5.x (Qt >= 5.10.1 recommended for all features)
* C++03 compiler (tested: msvc2015, gcc >= 4.8, clang/Apple LLVM version 8.1.0)
Build steps:
```shell
lrelease gpxsee.pro
qmake gpxsee.pro
make
make # nmake on windows
```
## Download
@ -33,5 +38,8 @@ make
## Homepage
http://www.gpxsee.org
## Maps
[GPXSee maps repository](https://github.com/tumic0/GPXSee-maps)
## Translations
GPXSee uses [Weblate](https://hosted.weblate.org/projects/gpxsee) for translations.

View File

@ -1,9 +1,10 @@
TARGET = GPXSee
VERSION = 5.18
VERSION = 6.0
QT += core \
gui \
network
network \
sql
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets
QT += printsupport
@ -142,7 +143,9 @@ HEADERS += src/config.h \
src/data/slfparser.h \
src/map/geotiffmap.h \
src/map/image.h \
src/common/greatcircle.h
src/common/greatcircle.h \
src/map/mbtilesmap.h \
src/map/osm.h
SOURCES += src/main.cpp \
src/common/coordinates.cpp \
src/common/rectc.cpp \
@ -248,10 +251,13 @@ SOURCES += src/main.cpp \
src/data/slfparser.cpp \
src/map/geotiffmap.cpp \
src/map/image.cpp \
src/common/greatcircle.cpp
src/common/greatcircle.cpp \
src/map/mbtilesmap.cpp \
src/map/osm.cpp
RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_cs.ts \
TRANSLATIONS = lang/gpxsee_en.ts \
lang/gpxsee_cs.ts \
lang/gpxsee_sv.ts \
lang/gpxsee_de.ts \
lang/gpxsee_ru.ts \
@ -263,7 +269,8 @@ macx {
ICON = icons/gpxsee.icns
QMAKE_INFO_PLIST = pkg/Info.plist
LOCALE.path = Contents/Resources/translations
LOCALE.files = lang/gpxsee_cs.qm \
LOCALE.files = lang/gpxsee_en.qm \
lang/gpxsee_cs.qm \
lang/gpxsee_de.qm \
lang/gpxsee_fi.qm \
lang/gpxsee_fr.qm \

View File

@ -958,32 +958,37 @@
<context>
<name>MapList</name>
<message>
<location filename="../src/map/maplist.cpp" line="114"/>
<location filename="../src/map/maplist.cpp" line="117"/>
<source>Supported files</source>
<translation>Podporované soubory</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="115"/>
<location filename="../src/map/maplist.cpp" line="119"/>
<source>MBTiles maps</source>
<translation>MBTiles mapy</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="120"/>
<source>Garmin JNX maps</source>
<translation>Garmin JNX mapy</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="116"/>
<location filename="../src/map/maplist.cpp" line="121"/>
<source>OziExplorer maps</source>
<translation>OziExplorer mapy</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="117"/>
<location filename="../src/map/maplist.cpp" line="122"/>
<source>TrekBuddy maps/atlases</source>
<translation>TrekBuddy mapy/atlasy</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="118"/>
<location filename="../src/map/maplist.cpp" line="123"/>
<source>GeoTIFF images</source>
<translation>GeoTIFF obrázky</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="119"/>
<location filename="../src/map/maplist.cpp" line="124"/>
<source>Online map sources</source>
<translation>Online mapové zdroje</translation>
</message>

1747
lang/gpxsee_da.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -957,32 +957,37 @@
<context>
<name>MapList</name>
<message>
<location filename="../src/map/maplist.cpp" line="114"/>
<location filename="../src/map/maplist.cpp" line="117"/>
<source>Supported files</source>
<translation>Unterstütze Dateien</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="115"/>
<location filename="../src/map/maplist.cpp" line="119"/>
<source>MBTiles maps</source>
<translation>MBTiles Karten</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="120"/>
<source>Garmin JNX maps</source>
<translation>Garmin JNX Karten</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="116"/>
<location filename="../src/map/maplist.cpp" line="121"/>
<source>OziExplorer maps</source>
<translation>OziExplorer Karten</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="117"/>
<location filename="../src/map/maplist.cpp" line="122"/>
<source>TrekBuddy maps/atlases</source>
<translation>TrekBuddy Karten/Atlanten</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="118"/>
<location filename="../src/map/maplist.cpp" line="123"/>
<source>GeoTIFF images</source>
<translation>GeoTIFF Bilder</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="119"/>
<location filename="../src/map/maplist.cpp" line="124"/>
<source>Online map sources</source>
<translation>Online-Kartenquellen</translation>
</message>
@ -1084,22 +1089,22 @@
<message>
<location filename="../src/GUI/optionsdialog.cpp" line="45"/>
<source>High-resolution</source>
<translation type="unfinished"></translation>
<translation>Hohe Auflösung</translation>
</message>
<message>
<location filename="../src/GUI/optionsdialog.cpp" line="46"/>
<source>Standard</source>
<translation type="unfinished"></translation>
<translation>Standardmäßig</translation>
</message>
<message>
<location filename="../src/GUI/optionsdialog.cpp" line="51"/>
<source>Non-HiDPI maps are loaded as HiDPI maps. The map is sharp but map objects are small/hard to read.</source>
<translation type="unfinished"></translation>
<translation>Nicht-HiDPI-Karten werden als HiDPI-Karten geladen. Die Karte ist scharf, aber die Kartenobjekte sind klein / schwer zu lesen.</translation>
</message>
<message>
<location filename="../src/GUI/optionsdialog.cpp" line="53"/>
<source>Non-HiDPI maps are loaded such as they are. Map objects have the expected size but the map is blurry.</source>
<translation type="unfinished"></translation>
<translation>Nicht-HiDPI-Karten werden so geladen, wie sie sind. Kartenobjekte haben die erwartete Größe, aber die Karte ist verschwommen.</translation>
</message>
<message>
<location filename="../src/GUI/optionsdialog.cpp" line="86"/>
@ -1109,7 +1114,7 @@
<message>
<location filename="../src/GUI/optionsdialog.cpp" line="88"/>
<source>HiDPI display mode</source>
<translation type="unfinished"></translation>
<translation>HiDPI-Anzeigemodus</translation>
</message>
<message>
<location filename="../src/GUI/optionsdialog.cpp" line="122"/>
@ -1411,7 +1416,7 @@
<message>
<location filename="../src/GUI/optionsdialog.cpp" line="532"/>
<source>Maps</source>
<translation type="unfinished"></translation>
<translation>Karten</translation>
</message>
<message>
<location filename="../src/GUI/optionsdialog.cpp" line="533"/>

14
lang/gpxsee_en.ts Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
<name>GUI</name>
<message numerus="yes">
<source>%n files</source>
<translation>
<numerusform>%n file</numerusform>
<numerusform>%n files</numerusform>
</translation>
</message>
</context>
</TS>

View File

@ -957,32 +957,37 @@
<context>
<name>MapList</name>
<message>
<location filename="../src/map/maplist.cpp" line="114"/>
<location filename="../src/map/maplist.cpp" line="117"/>
<source>Supported files</source>
<translation>Tuetut tiedostot</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="115"/>
<location filename="../src/map/maplist.cpp" line="119"/>
<source>MBTiles maps</source>
<translation>MBTiles -kartat</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="120"/>
<source>Garmin JNX maps</source>
<translation>Garmin JNX -kartat</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="116"/>
<location filename="../src/map/maplist.cpp" line="121"/>
<source>OziExplorer maps</source>
<translation>OziExplorer -kartat</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="117"/>
<location filename="../src/map/maplist.cpp" line="122"/>
<source>TrekBuddy maps/atlases</source>
<translation>TrekBuddy -kartat/kartastot</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="118"/>
<location filename="../src/map/maplist.cpp" line="123"/>
<source>GeoTIFF images</source>
<translation>GeoTIFF -kuvat</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="119"/>
<location filename="../src/map/maplist.cpp" line="124"/>
<source>Online map sources</source>
<translation>Online-karttojen lähteet</translation>
</message>

View File

@ -957,32 +957,37 @@
<context>
<name>MapList</name>
<message>
<location filename="../src/map/maplist.cpp" line="114"/>
<location filename="../src/map/maplist.cpp" line="117"/>
<source>Supported files</source>
<translation>Formats pris en charge</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="115"/>
<location filename="../src/map/maplist.cpp" line="119"/>
<source>MBTiles maps</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="120"/>
<source>Garmin JNX maps</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="116"/>
<location filename="../src/map/maplist.cpp" line="121"/>
<source>OziExplorer maps</source>
<translation>Cartes OziExplorer</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="117"/>
<location filename="../src/map/maplist.cpp" line="122"/>
<source>TrekBuddy maps/atlases</source>
<translation>Cartes ou atlas TrekBuddy</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="118"/>
<location filename="../src/map/maplist.cpp" line="123"/>
<source>GeoTIFF images</source>
<translation>Images GeoTIFF</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="119"/>
<location filename="../src/map/maplist.cpp" line="124"/>
<source>Online map sources</source>
<translation>Cartes en ligne</translation>
</message>

1747
lang/gpxsee_no.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -958,32 +958,37 @@
<context>
<name>MapList</name>
<message>
<location filename="../src/map/maplist.cpp" line="114"/>
<location filename="../src/map/maplist.cpp" line="117"/>
<source>Supported files</source>
<translation>Obsługiwane pliki</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="115"/>
<location filename="../src/map/maplist.cpp" line="119"/>
<source>MBTiles maps</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="120"/>
<source>Garmin JNX maps</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="116"/>
<location filename="../src/map/maplist.cpp" line="121"/>
<source>OziExplorer maps</source>
<translation>Mapy OziExplorer</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="117"/>
<location filename="../src/map/maplist.cpp" line="122"/>
<source>TrekBuddy maps/atlases</source>
<translation>Mapy/atlasy TrekBuddy</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="118"/>
<location filename="../src/map/maplist.cpp" line="123"/>
<source>GeoTIFF images</source>
<translation>Obrazy GeoTIFF</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="119"/>
<location filename="../src/map/maplist.cpp" line="124"/>
<source>Online map sources</source>
<translation>Źródła map online</translation>
</message>

View File

@ -958,32 +958,37 @@
<context>
<name>MapList</name>
<message>
<location filename="../src/map/maplist.cpp" line="114"/>
<location filename="../src/map/maplist.cpp" line="117"/>
<source>Supported files</source>
<translation>Все поддерживаемые файлы</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="115"/>
<location filename="../src/map/maplist.cpp" line="119"/>
<source>MBTiles maps</source>
<translation>MBTiles карты</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="120"/>
<source>Garmin JNX maps</source>
<translation>Garmin JNX карты</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="116"/>
<location filename="../src/map/maplist.cpp" line="121"/>
<source>OziExplorer maps</source>
<translation>OziExplorer карты</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="117"/>
<location filename="../src/map/maplist.cpp" line="122"/>
<source>TrekBuddy maps/atlases</source>
<translation>TrekBuddy карты/атласы</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="118"/>
<location filename="../src/map/maplist.cpp" line="123"/>
<source>GeoTIFF images</source>
<translation>GeoTIFF изображения</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="119"/>
<location filename="../src/map/maplist.cpp" line="124"/>
<source>Online map sources</source>
<translation>Источники онлайн карт</translation>
</message>

View File

@ -655,9 +655,11 @@
<message numerus="yes">
<location filename="../src/GUI/gui.cpp" line="1326"/>
<source>%n files</source>
<translation><numerusform>%n fil</numerusform>
<numerusform>%n filer</numerusform>
</translation></message>
<translation>
<numerusform>%n fil</numerusform>
<numerusform>%n filer</numerusform>
</translation>
</message>
<message>
<location filename="../src/GUI/gui.cpp" line="1002"/>
<location filename="../src/GUI/gui.cpp" line="1006"/>
@ -955,32 +957,37 @@
<context>
<name>MapList</name>
<message>
<location filename="../src/map/maplist.cpp" line="114"/>
<location filename="../src/map/maplist.cpp" line="117"/>
<source>Supported files</source>
<translation>Filer som stöds</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="115"/>
<location filename="../src/map/maplist.cpp" line="119"/>
<source>MBTiles maps</source>
<translation>MBTiles-kartor</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="120"/>
<source>Garmin JNX maps</source>
<translation>Garmin JNX-kartor</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="116"/>
<location filename="../src/map/maplist.cpp" line="121"/>
<source>OziExplorer maps</source>
<translation>OziExplorer-kartor</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="117"/>
<location filename="../src/map/maplist.cpp" line="122"/>
<source>TrekBuddy maps/atlases</source>
<translation>TrekBuddy-kartor/-atlaser</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="118"/>
<location filename="../src/map/maplist.cpp" line="123"/>
<source>GeoTIFF images</source>
<translation>GeoTIFF-bilder</translation>
</message>
<message>
<location filename="../src/map/maplist.cpp" line="119"/>
<location filename="../src/map/maplist.cpp" line="124"/>
<source>Online map sources</source>
<translation>Online-kartkällor</translation>
</message>

View File

@ -30,7 +30,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "5.18"
!define VERSION "6.0"
; The file to write
OutFile "GPXSee-${VERSION}.exe"
@ -153,10 +153,12 @@ Section "QT framework" SEC_QT
File "Qt5Widgets.dll"
File "Qt5PrintSupport.dll"
File "Qt5Network.dll"
File "Qt5Sql.dll"
File /r "platforms"
File /r "imageformats"
File /r "printsupport"
File /r "styles"
File /r "sqldrivers"
SectionEnd
@ -270,4 +272,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

@ -30,7 +30,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "5.18"
!define VERSION "6.0"
; The file to write
OutFile "GPXSee-${VERSION}_x64.exe"
@ -160,10 +160,12 @@ Section "QT framework" SEC_QT
File "Qt5Widgets.dll"
File "Qt5PrintSupport.dll"
File "Qt5Network.dll"
File "Qt5Sql.dll"
File /r "platforms"
File /r "imageformats"
File /r "printsupport"
File /r "styles"
File /r "sqldrivers"
SectionEnd
@ -273,4 +275,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

@ -49,9 +49,26 @@ void PathItem::updateShape()
void PathItem::addSegment(const Coordinates &c1, const Coordinates &c2)
{
if (fabs(c1.lon() - c2.lon()) > 180.0)
_painterPath.moveTo(_map->ll2xy(c2));
else
if (fabs(c1.lon() - c2.lon()) > 180.0) {
QPointF p;
if (c2.lon() < 0) {
QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() + 360,
c2.lat()));
QLineF dl(QPointF(180, -90), QPointF(180, 90));
l.intersect(dl, &p);
_painterPath.lineTo(_map->ll2xy(Coordinates(180, p.y())));
_painterPath.moveTo(_map->ll2xy(Coordinates(-180, p.y())));
} else {
QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() - 360,
c2.lat()));
QLineF dl(QPointF(-180, -90), QPointF(-180, 90));
l.intersect(dl, &p);
_painterPath.lineTo(_map->ll2xy(Coordinates(-180, p.y())));
_painterPath.moveTo(_map->ll2xy(Coordinates(180, p.y())));
}
_painterPath.lineTo(_map->ll2xy(c2));
} else
_painterPath.lineTo(_map->ll2xy(c2));
}

View File

@ -19,6 +19,8 @@ public:
void setMin(int min) {_min = min;}
void setMax(int max) {_max = max;}
bool contains(int val) const {return (val >= _min && val <= _max);}
private:
int _min, _max;
};

View File

@ -23,6 +23,11 @@ public:
{return Coordinates((_tl.lon() + _br.lon()) / 2.0,
(_tl.lat() + _br.lat()) / 2.0);}
double top() const {return _tl.lat();}
double bottom() const {return _br.lat();}
double left() const {return _tl.lon();}
double right() const {return _br.lon();}
RectC operator|(const RectC &r) const;
RectC &operator|=(const RectC &r) {*this = *this | r; return *this;}
RectC operator&(const RectC &r) const;

View File

@ -6,6 +6,7 @@
#include "jnxmap.h"
#include "geotiffmap.h"
#include "mapsource.h"
#include "mbtilesmap.h"
#include "maplist.h"
@ -56,6 +57,8 @@ bool MapList::loadFile(const QString &path, bool *atlas, bool dir)
return loadMap(new JNXMap(path, this), path, dir);
else if (suffix == "tif" || suffix == "tiff")
return loadMap(new GeoTIFFMap(path, this), path, dir);
else if (suffix == "mbtiles")
return loadMap(new MBTilesMap(path, this), path, dir);
else
return loadMap(new OziMap(path, this), path, dir);
}
@ -111,7 +114,9 @@ void MapList::clear()
QString MapList::formats()
{
return
tr("Supported files") + " (*.jnx *.map *.tar *.tba *.tif *.tiff *.xml);;"
tr("Supported files")
+ " (*.jnx *.map *.mbtiles *.tar *.tba *.tif *.tiff *.xml);;"
+ tr("MBTiles maps") + " (*.mbtiles);;"
+ tr("Garmin JNX maps") + " (*.jnx);;"
+ tr("OziExplorer maps") + " (*.map);;"
+ tr("TrekBuddy maps/atlases") + " (*.tar *.tba);;"
@ -123,6 +128,6 @@ QStringList MapList::filter()
{
QStringList filter;
filter << "*.jnx" << "*.map" << "*.tba" << "*.tar" << "*.xml" << "*.tif"
<< "*.tiff";
<< "*.tiff" << "*.mbtiles";
return filter;
}

View File

@ -4,19 +4,12 @@
#include "onlinemap.h"
#include "wmtsmap.h"
#include "wmsmap.h"
#include "osm.h"
#include "mapsource.h"
#define ZOOM_MAX 19
#define ZOOM_MIN 0
#define BOUNDS_LEFT -180
#define BOUNDS_TOP 85.0511
#define BOUNDS_RIGHT 180
#define BOUNDS_BOTTOM -85.0511
MapSource::Config::Config() : type(OSM), zooms(ZOOM_MIN, ZOOM_MAX),
bounds(Coordinates(BOUNDS_LEFT, BOUNDS_TOP), Coordinates(BOUNDS_RIGHT,
BOUNDS_BOTTOM)), format("image/png"), rest(false), tileRatio(1.0) {}
MapSource::Config::Config() : type(OSM), zooms(osm::zooms), bounds(osm::bounds),
format("image/png"), rest(false), tileRatio(1.0) {}
static CoordinateSystem coordinateSystem(QXmlStreamReader &reader)
@ -38,21 +31,21 @@ Range MapSource::zooms(QXmlStreamReader &reader)
if (attr.hasAttribute("min")) {
min = attr.value("min").toString().toInt(&res);
if (!res || (min < ZOOM_MIN || min > ZOOM_MAX)) {
if (!res || !osm::zooms.contains(min)) {
reader.raiseError("Invalid minimal zoom level");
return Range();
}
} else
min = ZOOM_MIN;
min = osm::zooms.min();
if (attr.hasAttribute("max")) {
max = attr.value("max").toString().toInt(&res);
if (!res || (max < ZOOM_MIN || max > ZOOM_MAX)) {
if (!res || !osm::zooms.contains(max)) {
reader.raiseError("Invalid maximal zoom level");
return Range();
}
} else
max = ZOOM_MAX;
max = osm::zooms.max();
if (min > max) {
reader.raiseError("Invalid maximal/minimal zoom level combination");
@ -70,39 +63,41 @@ RectC MapSource::bounds(QXmlStreamReader &reader)
if (attr.hasAttribute("top")) {
top = attr.value("top").toString().toDouble(&res);
if (!res || (top < BOUNDS_BOTTOM || top > BOUNDS_TOP)) {
if (!res || (top < osm::bounds.bottom() || top > osm::bounds.top())) {
reader.raiseError("Invalid bounds top value");
return RectC();
}
} else
top = BOUNDS_TOP;
top = osm::bounds.top();
if (attr.hasAttribute("bottom")) {
bottom = attr.value("bottom").toString().toDouble(&res);
if (!res || (bottom < BOUNDS_BOTTOM || bottom > BOUNDS_TOP)) {
if (!res || (bottom < osm::bounds.bottom()
|| bottom > osm::bounds.top())) {
reader.raiseError("Invalid bounds bottom value");
return RectC();
}
} else
bottom = BOUNDS_BOTTOM;
bottom = osm::bounds.bottom();
if (attr.hasAttribute("left")) {
left = attr.value("left").toString().toDouble(&res);
if (!res || (left < BOUNDS_LEFT || left > BOUNDS_RIGHT)) {
if (!res || (left < osm::bounds.left() || left > osm::bounds.right())) {
reader.raiseError("Invalid bounds left value");
return RectC();
}
} else
left = BOUNDS_LEFT;
left = osm::bounds.left();
if (attr.hasAttribute("right")) {
right = attr.value("right").toString().toDouble(&res);
if (!res || (right < BOUNDS_LEFT || right > BOUNDS_RIGHT)) {
if (!res || (right < osm::bounds.left()
|| right > osm::bounds.right())) {
reader.raiseError("Invalid bounds right value");
return RectC();
}
} else
right = BOUNDS_RIGHT;
right = osm::bounds.right();
if (bottom >= top) {
reader.raiseError("Invalid bottom/top bounds combination");
@ -119,8 +114,20 @@ RectC MapSource::bounds(QXmlStreamReader &reader)
void MapSource::map(QXmlStreamReader &reader, Config &config)
{
const QXmlStreamAttributes &attr = reader.attributes();
config.type = (attr.value("type") == "WMTS") ? WMTS
: (attr.value("type") == "WMS") ? WMS : OSM;
QStringRef type = attr.value("type");
if (type == "WMTS")
config.type = WMTS;
else if (type == "WMS")
config.type = WMS;
else if (type == "TMS")
config.type = TMS;
else if (type == "OSM" || type.isEmpty())
config.type = OSM;
else {
reader.raiseError("Invalid map type");
return;
}
while (reader.readNextStartElement()) {
if (reader.name() == "name")
@ -231,16 +238,23 @@ Map *MapSource::loadMap(const QString &path, QString &errorString)
}
}
if (config.type == WMTS)
return new WMTSMap(config.name, WMTS::Setup(config.url, config.layer,
config.set, config.style, config.format, config.rest,
config.coordinateSystem, config.dimensions, config.authorization),
config.tileRatio);
else if (config.type == WMS)
return new WMSMap(config.name, WMS::Setup(config.url, config.layer,
config.style, config.format, config.crs, config.coordinateSystem,
config.dimensions, config.authorization));
else
return new OnlineMap(config.name, config.url, config.zooms,
config.bounds, config.tileRatio, config.authorization);
switch (config.type) {
case WMTS:
return new WMTSMap(config.name, WMTS::Setup(config.url, config.layer,
config.set, config.style, config.format, config.rest,
config.coordinateSystem, config.dimensions, config.authorization),
config.tileRatio);
case WMS:
return new WMSMap(config.name, WMS::Setup(config.url, config.layer,
config.style, config.format, config.crs, config.coordinateSystem,
config.dimensions, config.authorization));
case TMS:
return new OnlineMap(config.name, config.url, config.zooms,
config.bounds, config.tileRatio, config.authorization, true);
case OSM:
return new OnlineMap(config.name, config.url, config.zooms,
config.bounds, config.tileRatio, config.authorization, false);
default:
return 0;
}
}

View File

@ -19,7 +19,8 @@ private:
enum Type {
OSM,
WMTS,
WMS
WMS,
TMS
};
struct Config {

264
src/map/mbtilesmap.cpp Normal file
View File

@ -0,0 +1,264 @@
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlField>
#include <QFileInfo>
#include <QPainter>
#include <QPixmapCache>
#include "common/rectc.h"
#include "common/wgs84.h"
#include "osm.h"
#include "config.h"
#include "mbtilesmap.h"
#define META_TYPE(type) static_cast<QMetaType::Type>(type)
static double index2mercator(int index, int zoom)
{
return rad2deg(-M_PI + 2 * M_PI * ((double)index / (1<<zoom)));
}
MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent)
: Map(parent), _fileName(fileName), _deviceRatio(1.0), _tileRatio(1.0),
_valid(false)
{
_db = QSqlDatabase::addDatabase("QSQLITE", fileName);
_db.setDatabaseName(fileName);
if (!_db.open()) {
_errorString = fileName + ": Error opening database file";
return;
}
QSqlRecord r = _db.record("tiles");
if (r.isEmpty()
|| r.field(0).name() != "zoom_level"
|| META_TYPE(r.field(0).type()) != QMetaType::Int
|| r.field(1).name() != "tile_column"
|| META_TYPE(r.field(1).type()) != QMetaType::Int
|| r.field(2).name() != "tile_row"
|| META_TYPE(r.field(2).type()) != QMetaType::Int
|| r.field(3).name() != "tile_data"
|| META_TYPE(r.field(3).type()) != QMetaType::QByteArray) {
_errorString = "Invalid table format";
return;
}
{
QSqlQuery query("SELECT min(zoom_level), max(zoom_level) FROM tiles",
_db);
if (!query.first()) {
_errorString = "Empty tile set";
return;
}
_zooms = Range(query.value(0).toInt(), query.value(1).toInt());
if (_zooms.min() < 0 || !_zooms.isValid()) {
_errorString = "Invalid zoom levels";
return;
}
}
_zoom = _zooms.max();
{
QString sql = QString("SELECT min(tile_column), min(tile_row), "
"max(tile_column), max(tile_row) FROM tiles WHERE zoom_level = %1")
.arg(_zooms.min());
QSqlQuery query(sql, _db);
query.first();
double minX = index2mercator(qMin((1<<_zooms.min()) - 1,
qMax(0, query.value(0).toInt())), _zooms.min());
double minY = index2mercator(qMin((1<<_zooms.min()) - 1,
qMax(0, query.value(1).toInt())), _zooms.min());
double maxX = index2mercator(qMin((1<<_zooms.min()) - 1,
qMax(0, query.value(2).toInt())) + 1, _zooms.min());
double maxY = index2mercator(qMin((1<<_zooms.min()) - 1,
qMax(0, query.value(3).toInt())) + 1, _zooms.min());
Coordinates tl(osm::m2ll(QPointF(minX, maxY)));
Coordinates br(osm::m2ll(QPointF(maxX, minY)));
// Workaround of broken zoom levels 0 and 1 due to numerical instability
tl.rlat() = qMin(tl.lat(), osm::bounds.top());
br.rlat() = qMax(br.lat(), osm::bounds.bottom());
_bounds = RectC(tl, br);
}
{
QString sql = QString("SELECT tile_data FROM tiles LIMIT 1");
QSqlQuery query(sql, _db);
query.first();
QImage tile = QImage::fromData(query.value(0).toByteArray());
if (tile.isNull() || tile.size().width() != tile.size().height()) {
_errorString = "Unsupported/invalid tile images";
return;
}
_tileSize = tile.size().width();
}
{
QSqlQuery query("SELECT value FROM metadata WHERE name = 'name'", _db);
if (query.first())
_name = query.value(0).toString();
else {
qWarning("%s: missing map name", qPrintable(_fileName));
_name = QFileInfo(_fileName).fileName();
}
}
{
QSqlQuery query(
"SELECT value FROM metadata WHERE name = 'tilepixelratio'", _db);
if (query.first()) {
bool ok;
_tileRatio = query.value(0).toString().toDouble(&ok);
if (!ok) {
_errorString = "Invalid tile pixel ratio";
return;
}
}
}
_db.close();
_valid = true;
}
void MBTilesMap::load()
{
_db.open();
}
void MBTilesMap::unload()
{
_db.close();
}
QRectF MBTilesMap::bounds()
{
return QRectF(ll2xy(_bounds.topLeft()), ll2xy(_bounds.bottomRight()));
}
int MBTilesMap::limitZoom(int zoom) const
{
if (zoom < _zooms.min())
return _zooms.min();
if (zoom > _zooms.max())
return _zooms.max();
return zoom;
}
int MBTilesMap::zoomFit(const QSize &size, const RectC &rect)
{
if (!rect.isValid())
_zoom = _zooms.max();
else {
QRectF tbr(osm::ll2m(rect.topLeft()), osm::ll2m(rect.bottomRight()));
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
_zoom = limitZoom(osm::scale2zoom(qMax(sc.x(), -sc.y())
/ coordinatesRatio(), _tileSize));
}
return _zoom;
}
qreal MBTilesMap::resolution(const QRectF &rect)
{
qreal scale = osm::zoom2scale(_zoom, _tileSize);
return (WGS84_RADIUS * 2.0 * M_PI * scale / 360.0
* cos(2.0 * atan(exp(deg2rad(-rect.center().y() * scale))) - M_PI/2));
}
int MBTilesMap::zoomIn()
{
_zoom = qMin(_zoom + 1, _zooms.max());
return _zoom;
}
int MBTilesMap::zoomOut()
{
_zoom = qMax(_zoom - 1, _zooms.min());
return _zoom;
}
qreal MBTilesMap::coordinatesRatio() const
{
return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0;
}
qreal MBTilesMap::imageRatio() const
{
return _deviceRatio > 1.0 ? _deviceRatio : _tileRatio;
}
qreal MBTilesMap::tileSize() const
{
return (_tileSize / coordinatesRatio());
}
QByteArray MBTilesMap::tileData(int zoom, const QPoint &tile) const
{
QSqlQuery query(_db);
query.prepare("SELECT tile_data FROM tiles "
"WHERE zoom_level=:zoom AND tile_column=:x AND tile_row=:y");
query.bindValue(":zoom", zoom);
query.bindValue(":x", tile.x());
query.bindValue(":y", (1<<zoom) - tile.y() - 1);
query.exec();
if (query.first())
return query.value(0).toByteArray();
return QByteArray();
}
void MBTilesMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
{
Q_UNUSED(flags);
qreal scale = osm::zoom2scale(_zoom, _tileSize);
QRectF b(bounds());
QPoint tile = osm::mercator2tile(QPointF(rect.topLeft().x() * scale,
-rect.topLeft().y() * scale) * coordinatesRatio(), _zoom);
QPointF tl(floor(rect.left() / tileSize())
* tileSize(), floor(rect.top() / tileSize()) * tileSize());
QSizeF s(qMin(rect.right() - tl.x(), b.width()),
qMin(rect.bottom() - tl.y(), b.height()));
for (int i = 0; i < ceil(s.width() / tileSize()); i++) {
for (int j = 0; j < ceil(s.height() / tileSize()); j++) {
QPixmap pm;
QPoint t(tile.x() + i, tile.y() + j);
QString key = _fileName + "-" + QString::number(_zoom) + "_"
+ QString::number(t.x()) + "_" + QString::number(t.y());
if (!QPixmapCache::find(key, &pm))
if (pm.loadFromData(tileData(_zoom, t)))
QPixmapCache::insert(key, pm);
QPointF tp(qMax(tl.x(), b.left()) + (t.x() - tile.x()) * tileSize(),
qMax(tl.y(), b.top()) + (t.y() - tile.y()) * tileSize());
if (!pm.isNull()) {
#ifdef ENABLE_HIDPI
pm.setDevicePixelRatio(imageRatio());
#endif // ENABLE_HIDPI
painter->drawPixmap(tp, pm);
}
}
}
}
QPointF MBTilesMap::ll2xy(const Coordinates &c)
{
qreal scale = osm::zoom2scale(_zoom, _tileSize);
QPointF m = osm::ll2m(c);
return QPointF(m.x() / scale, m.y() / -scale) / coordinatesRatio();
}
Coordinates MBTilesMap::xy2ll(const QPointF &p)
{
qreal scale = osm::zoom2scale(_zoom, _tileSize);
return osm::m2ll(QPointF(p.x() * scale, -p.y() * scale)
* coordinatesRatio());
}

57
src/map/mbtilesmap.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef MBTILESMAP_H
#define MBTILESMAP_H
#include <QSqlDatabase>
#include <QByteArray>
#include "common/range.h"
#include "map.h"
class MBTilesMap : public Map
{
public:
MBTilesMap(const QString &fileName, QObject *parent = 0);
QString name() const {return _name;}
QRectF bounds();
qreal resolution(const QRectF &rect);
int zoom() const {return _zoom;}
void setZoom(int zoom) {_zoom = zoom;}
int zoomFit(const QSize &size, const RectC &rect);
int zoomIn();
int zoomOut();
QPointF ll2xy(const Coordinates &c);
Coordinates xy2ll(const QPointF &p);
void draw(QPainter *painter, const QRectF &rect, Flags flags);
void load();
void unload();
void setDevicePixelRatio(qreal ratio) {_deviceRatio = ratio;}
bool isValid() const {return _valid;}
QString errorString() const {return _errorString;}
private:
int limitZoom(int zoom) const;
qreal tileSize() const;
qreal coordinatesRatio() const;
qreal imageRatio() const;
QByteArray tileData(int zoom, const QPoint &tile) const;
QSqlDatabase _db;
QString _fileName, _name;
RectC _bounds;
Range _zooms;
int _zoom;
int _tileSize;
qreal _deviceRatio, _tileRatio;
bool _valid;
QString _errorString;
};
#endif // MBTILESMAP_H

View File

@ -3,49 +3,19 @@
#include "common/rectc.h"
#include "common/wgs84.h"
#include "downloader.h"
#include "osm.h"
#include "config.h"
#include "onlinemap.h"
#define TILE_SIZE 256
#define EPSILON 1e-6
static QPointF ll2m(const Coordinates &c)
{
return QPointF(c.lon(), rad2deg(log(tan(M_PI_4 + deg2rad(c.lat())/2.0))));
}
static Coordinates m2ll(const QPointF &p)
{
return Coordinates(p.x(), rad2deg(2.0 * atan(exp(deg2rad(p.y()))) - M_PI_2));
}
static QPoint mercator2tile(const QPointF &m, int z)
{
QPoint tile;
tile.setX((int)(floor((m.x() + 180.0) / 360.0 * (1<<z))));
tile.setY((int)(floor((1.0 - (m.y() / 180.0)) / 2.0 * (1<<z))));
return tile;
}
static qreal zoom2scale(int zoom)
{
return (360.0/(qreal)((1<<zoom) * TILE_SIZE));
}
static int scale2zoom(qreal scale)
{
return (int)(log2(360.0/(scale * (qreal)TILE_SIZE)) + EPSILON);
}
OnlineMap::OnlineMap(const QString &name, const QString &url,
const Range &zooms, const RectC &bounds, qreal tileRatio,
const Authorization &authorization, QObject *parent)
const Authorization &authorization, bool invertY, QObject *parent)
: Map(parent), _name(name), _zooms(zooms), _bounds(bounds),
_zoom(_zooms.max()), _deviceRatio(1.0), _tileRatio(tileRatio), _valid(false)
_zoom(_zooms.max()), _deviceRatio(1.0), _tileRatio(tileRatio),
_invertY(invertY), _valid(false)
{
QString dir(TILES_DIR + "/" + _name);
@ -83,9 +53,10 @@ int OnlineMap::zoomFit(const QSize &size, const RectC &rect)
if (!rect.isValid())
_zoom = _zooms.max();
else {
QRectF tbr(ll2m(rect.topLeft()), ll2m(rect.bottomRight()));
QRectF tbr(osm::ll2m(rect.topLeft()), osm::ll2m(rect.bottomRight()));
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
_zoom = limitZoom(scale2zoom(qMax(sc.x(), -sc.y()) / coordinatesRatio()));
_zoom = limitZoom(osm::scale2zoom(qMax(sc.x(), -sc.y())
/ coordinatesRatio(), TILE_SIZE));
}
return _zoom;
@ -93,7 +64,7 @@ int OnlineMap::zoomFit(const QSize &size, const RectC &rect)
qreal OnlineMap::resolution(const QRectF &rect)
{
qreal scale = zoom2scale(_zoom);
qreal scale = osm::zoom2scale(_zoom, TILE_SIZE);
return (WGS84_RADIUS * 2.0 * M_PI * scale / 360.0
* cos(2.0 * atan(exp(deg2rad(-rect.center().y() * scale))) - M_PI/2));
@ -128,10 +99,10 @@ qreal OnlineMap::tileSize() const
void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
{
qreal scale = zoom2scale(_zoom);
qreal scale = osm::zoom2scale(_zoom, TILE_SIZE);
QRectF b(bounds());
QPoint tile = mercator2tile(QPointF(rect.topLeft().x() * scale,
QPoint tile = osm::mercator2tile(QPointF(rect.topLeft().x() * scale,
-rect.topLeft().y() * scale) * coordinatesRatio(), _zoom);
QPointF tl(floor(rect.left() / tileSize())
* tileSize(), floor(rect.top() / tileSize()) * tileSize());
@ -141,7 +112,8 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
qMin(rect.bottom() - tl.y(), b.height()));
for (int i = 0; i < ceil(s.width() / tileSize()); i++)
for (int j = 0; j < ceil(s.height() / tileSize()); j++)
tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), _zoom));
tiles.append(Tile(QPoint(tile.x() + i,
_invertY ? (1<<_zoom) - (tile.y() + j) - 1 : tile.y() + j), _zoom));
if (flags & Map::Block)
_tileLoader->loadTilesSync(tiles);
@ -151,7 +123,8 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
for (int i = 0; i < tiles.count(); i++) {
Tile &t = tiles[i];
QPointF tp(qMax(tl.x(), b.left()) + (t.xy().x() - tile.x()) * tileSize(),
qMax(tl.y(), b.top()) + (t.xy().y() - tile.y()) * tileSize());
qMax(tl.y(), b.top()) + ((_invertY ? (1<<_zoom) - t.xy().y() - 1 :
t.xy().y()) - tile.y()) * tileSize());
if (!t.pixmap().isNull()) {
#ifdef ENABLE_HIDPI
t.pixmap().setDevicePixelRatio(imageRatio());
@ -163,13 +136,14 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
QPointF OnlineMap::ll2xy(const Coordinates &c)
{
qreal scale = zoom2scale(_zoom);
QPointF m = ll2m(c);
qreal scale = osm::zoom2scale(_zoom, TILE_SIZE);
QPointF m = osm::ll2m(c);
return QPointF(m.x() / scale, m.y() / -scale) / coordinatesRatio();
}
Coordinates OnlineMap::xy2ll(const QPointF &p)
{
qreal scale = zoom2scale(_zoom);
return m2ll(QPointF(p.x() * scale, -p.y() * scale) * coordinatesRatio());
qreal scale = osm::zoom2scale(_zoom, TILE_SIZE);
return osm::m2ll(QPointF(p.x() * scale, -p.y() * scale)
* coordinatesRatio());
}

View File

@ -13,7 +13,7 @@ class OnlineMap : public Map
public:
OnlineMap(const QString &name, const QString &url, const Range &zooms,
const RectC &bounds, qreal tileRatio, const Authorization &authorization,
QObject *parent = 0);
bool invertY, QObject *parent = 0);
QString name() const {return _name;}
@ -49,6 +49,7 @@ private:
RectC _bounds;
int _zoom;
qreal _deviceRatio, _tileRatio;
bool _invertY;
bool _valid;
QString _errorString;

29
src/map/osm.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "osm.h"
#define EPSILON 1e-6
QPointF osm::ll2m(const Coordinates &c)
{
return QPointF(c.lon(), rad2deg(log(tan(M_PI_4 + deg2rad(c.lat())/2.0))));
}
Coordinates osm::m2ll(const QPointF &p)
{
return Coordinates(p.x(), rad2deg(2.0 * atan(exp(deg2rad(p.y()))) - M_PI_2));
}
QPoint osm::mercator2tile(const QPointF &m, int z)
{
return QPoint((int)(floor((m.x() + 180.0) / 360.0 * (1<<z))),
(int)(floor((1.0 - (m.y() / 180.0)) / 2.0 * (1<<z))));
}
qreal osm::zoom2scale(int zoom, int tileSize)
{
return (360.0/(qreal)((1<<zoom) * tileSize));
}
int osm::scale2zoom(qreal scale, int tileSize)
{
return (int)(log2(360.0/(scale * (qreal)tileSize)) + EPSILON);
}

22
src/map/osm.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef OSM_H
#define OSM_H
#include <QPointF>
#include <common/coordinates.h>
#include <common/rectc.h>
#include <common/range.h>
namespace osm
{
static const RectC bounds(Coordinates(-180, 85.0511),
Coordinates(180, -85.0511));
static const Range zooms(0, 19);
QPointF ll2m(const Coordinates &c);
Coordinates m2ll(const QPointF &p);
QPoint mercator2tile(const QPointF &m, int z);
qreal zoom2scale(int zoom, int tileSize);
int scale2zoom(qreal scale, int tileSize);
}
#endif // OSM_H

View File

@ -26,13 +26,16 @@ void TileLoader::loadTilesAsync(QList<Tile> &list)
for (int i = 0; i < list.size(); i++) {
Tile &t = list[i];
QString file = tileFile(t);
QString file(tileFile(t));
QFileInfo fi(file);
QUrl url(tileUrl(t));
if (!fi.exists())
dl.append(Download(tileUrl(t), file));
else
if (url.isLocalFile())
loadTileFile(t, url.toLocalFile());
else if (fi.exists())
loadTileFile(t, file);
else
dl.append(Download(tileUrl(t), file));
}
if (!dl.empty())
@ -45,13 +48,16 @@ void TileLoader::loadTilesSync(QList<Tile> &list)
for (int i = 0; i < list.size(); i++) {
Tile &t = list[i];
QString file = tileFile(t);
QString file(tileFile(t));
QFileInfo fi(file);
QUrl url(tileUrl(t));
if (!fi.exists())
dl.append(Download(tileUrl(t), file));
else
if (url.isLocalFile())
loadTileFile(t, url.toLocalFile());
else if (fi.exists())
loadTileFile(t, file);
else
dl.append(Download(tileUrl(t), file));
}
if (dl.empty())
@ -84,7 +90,7 @@ void TileLoader::clearCache()
_downloader->clearErrors();
}
QString TileLoader::tileUrl(const Tile &tile) const
QUrl TileLoader::tileUrl(const Tile &tile) const
{
QString url(_url);
@ -101,7 +107,7 @@ QString TileLoader::tileUrl(const Tile &tile) const
url.replace("$y", QString::number(tile.xy().y()));
}
return url;
return QUrl(url);
}
QString TileLoader::tileFile(const Tile &tile) const

View File

@ -26,7 +26,7 @@ signals:
void finished();
private:
QString tileUrl(const Tile &tile) const;
QUrl tileUrl(const Tile &tile) const;
QString tileFile(const Tile &tile) const;
Downloader *_downloader;

View File

@ -274,8 +274,8 @@ bool WMS::getCapabilities(const QString &url, const QString &file,
WMS::WMS(const QString &file, const WMS::Setup &setup) : _valid(false)
{
QString capaUrl = QString("%1?service=WMS&request=GetCapabilities")
.arg(setup.url());
QString capaUrl = QString("%1%2service=WMS&request=GetCapabilities")
.arg(setup.url(), setup.url().contains('?') ? "&" : "?");
if (!QFileInfo(file).exists())
if (!getCapabilities(capaUrl, file, setup.authorization()))

View File

@ -20,11 +20,11 @@ QString WMSMap::tileUrl(const QString &version) const
{
QString url;
url = QString("%1?version=%2&request=GetMap&bbox=$bbox"
"&width=%3&height=%4&layers=%5&styles=%6&format=%7&transparent=true")
.arg(_setup.url(), version, QString::number(TILE_SIZE),
QString::number(TILE_SIZE), _setup.layer(), _setup.style(),
_setup.format());
url = QString("%1%2version=%3&request=GetMap&bbox=$bbox"
"&width=%4&height=%5&layers=%6&styles=%7&format=%8&transparent=true")
.arg(_setup.url(), _setup.url().contains('?') ? "&" : "?", version,
QString::number(TILE_SIZE), QString::number(TILE_SIZE), _setup.layer(),
_setup.style(), _setup.format());
if (version >= "1.3.0")
url.append(QString("&CRS=%1").arg(_setup.crs()));

View File

@ -277,7 +277,7 @@ bool WMTS::parseCapabilities(const QString &path, const Setup &setup)
return true;
}
bool WMTS::getCapabilities(const QString &url, const QString &file,
bool WMTS::downloadCapabilities(const QString &url, const QString &file,
const Authorization &authorization)
{
Downloader d;
@ -300,21 +300,22 @@ bool WMTS::getCapabilities(const QString &url, const QString &file,
WMTS::WMTS(const QString &file, const WMTS::Setup &setup) : _valid(false)
{
QString capaUrl = setup.rest() ? setup.url() :
QString("%1?service=WMTS&Version=1.0.0&request=GetCapabilities")
.arg(setup.url());
QUrl url(setup.rest() ? setup.url() : QString(
"%1%2service=WMTS&Version=1.0.0&request=GetCapabilities").arg(setup.url(),
setup.url().contains('?') ? "&" : "?"));
if (!QFileInfo(file).exists())
if (!getCapabilities(capaUrl, file, setup.authorization()))
if (!url.isLocalFile() && !QFileInfo(file).exists())
if (!downloadCapabilities(url.toString(), file, setup.authorization()))
return;
if (!parseCapabilities(file, setup))
if (!parseCapabilities(url.isLocalFile() ? url.toLocalFile() : file, setup))
return;
QString style = setup.style().isEmpty() ? "default" : setup.style();
if (!setup.rest()) {
_tileUrl = QString("%1?service=WMTS&Version=1.0.0&request=GetTile"
"&Format=%2&Layer=%3&Style=%4&TileMatrixSet=%5&TileMatrix=$z"
"&TileRow=$y&TileCol=$x").arg(setup.url(), setup.format(),
_tileUrl = QString("%1%2service=WMTS&Version=1.0.0&request=GetTile"
"&Format=%3&Layer=%4&Style=%5&TileMatrixSet=%6&TileMatrix=$z"
"&TileRow=$y&TileCol=$x").arg(setup.url(),
setup.url().contains('?') ? "&" : "?" , setup.format(),
setup.layer(), style, setup.set());
for (int i = 0; i < setup.dimensions().size(); i++) {
const QPair<QString, QString> &dim = setup.dimensions().at(i);

View File

@ -139,7 +139,7 @@ private:
void contents(QXmlStreamReader &reader, CTX &ctx);
void capabilities(QXmlStreamReader &reader, CTX &ctx);
bool parseCapabilities(const QString &path, const Setup &setup);
bool getCapabilities(const QString &url, const QString &file,
bool downloadCapabilities(const QString &url, const QString &file,
const Authorization &authorization);
QSet<TileMatrix> _matrixes;