mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-07-01 21:39:15 +02:00
Compare commits
75 Commits
Author | SHA1 | Date | |
---|---|---|---|
089d796194 | |||
2677bb77f8 | |||
13dba26d3e | |||
9675e19b94 | |||
8d3fcc7a17 | |||
8dc5cb7aa8 | |||
af99e4e05a | |||
d18c0d1643 | |||
b9a93d30c0 | |||
2b6d3799ec | |||
152828042f | |||
e1683a7560 | |||
444cf344a9 | |||
7ac0bcf6d2 | |||
a1ac306bfc | |||
db4a436ff5 | |||
84a6f6c875 | |||
06f2c883d4 | |||
fc95ebfe2b | |||
4b64ee467c | |||
331cb48e11 | |||
fce0c49504 | |||
f670fb0859 | |||
1e45713aa4 | |||
7265c85b83 | |||
4d156044d0 | |||
17c9416532 | |||
8e9db2354e | |||
544a838821 | |||
44d84bf19e | |||
4ca9c79dc4 | |||
cb77cc37c4 | |||
98dd8c264c | |||
84d860e2a2 | |||
e10f8e9c1b | |||
f433f855a4 | |||
c90a03e22c | |||
fbc0fd86cf | |||
aa07b20aa4 | |||
8a7edcfd8d | |||
04a145a2e7 | |||
66f0f6a202 | |||
5698b4c9b0 | |||
77c4eda385 | |||
d6de3acbd2 | |||
652ed8e919 | |||
58e1980b0d | |||
fda33cc95b | |||
02e724fefb | |||
da220c4b62 | |||
6ffc71fd36 | |||
635e2f1fe3 | |||
23e4e66c1b | |||
1739625896 | |||
e9ef68a81c | |||
06205470fe | |||
c535632eb6 | |||
9f1f06577c | |||
0e45831111 | |||
0c8e864d32 | |||
c9cac70e1f | |||
045cbe81bf | |||
bffd1d9172 | |||
b8102d6bb7 | |||
fc80bd1b7c | |||
2441c4996d | |||
89878fade1 | |||
83b7741ed9 | |||
f44b14473d | |||
699de8b133 | |||
b7dd11fa1f | |||
0a32a9b865 | |||
02ad65461c | |||
5fa52b0166 | |||
84f41b5aa9 |
@ -1,4 +1,4 @@
|
||||
version: 4.19.{build}
|
||||
version: 5.0.{build}
|
||||
configuration: Release
|
||||
platform: Any CPU
|
||||
environment:
|
||||
@ -34,11 +34,11 @@ build_script:
|
||||
|
||||
copy pkg\%NSI% installer
|
||||
|
||||
copy pkg\datums.csv installer
|
||||
xcopy pkg\csv installer\csv /i
|
||||
|
||||
copy pkg\ellipsoids.csv installer
|
||||
xcopy pkg\maps installer\maps /i
|
||||
|
||||
copy pkg\maps.txt installer
|
||||
xcopy lang\*.qm installer\translations\ /sy
|
||||
|
||||
copy licence.txt installer
|
||||
|
||||
@ -49,4 +49,4 @@ build_script:
|
||||
|
||||
makensis.exe installer\%NSI%
|
||||
artifacts:
|
||||
- path: installer\GPXSee-*.exe
|
||||
- path: installer\GPXSee-*.exe
|
||||
|
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# C++ objects and libs
|
||||
*.o
|
||||
|
||||
# Qt-es
|
||||
/.qmake.stash
|
||||
moc_*.cpp
|
||||
moc_*.h
|
||||
qrc_*.cpp
|
||||
Makefile*
|
||||
*.qm
|
||||
|
||||
# Binary
|
||||
GPXSee
|
7
CONTRIBUTING.md
Normal file
7
CONTRIBUTING.md
Normal file
@ -0,0 +1,7 @@
|
||||
Only localization contributions are accepted at the moment, code pull requests will be rejected.
|
||||
|
||||
The rationale is, that I want leave the possibility to distribute GPXsee builds in the OS X/Windows
|
||||
stores under a non-GPL licence open. In the future, code pull requests under a QT-like contribution
|
||||
agreement [1] will be possible.
|
||||
|
||||
[1] https://d21tv0wm5mksdn.cloudfront.net/wp-content/uploads/2015/03/Qt-ContributionLicenseAgreement_v1_2_FINAL.pdf
|
60
gpxsee.pro
60
gpxsee.pro
@ -1,5 +1,5 @@
|
||||
TARGET = GPXSee
|
||||
VERSION = 4.19
|
||||
VERSION = 5.0
|
||||
QT += core \
|
||||
gui \
|
||||
network
|
||||
@ -14,6 +14,7 @@ HEADERS += src/config.h \
|
||||
src/common/range.h \
|
||||
src/common/rectc.h \
|
||||
src/common/wgs84.h \
|
||||
src/common/str2int.h \
|
||||
src/GUI/app.h \
|
||||
src/GUI/icons.h \
|
||||
src/GUI/gui.h \
|
||||
@ -86,7 +87,11 @@ HEADERS += src/config.h \
|
||||
src/map/ozf.h \
|
||||
src/map/atlas.h \
|
||||
src/map/matrix.h \
|
||||
src/map/misc.h \
|
||||
src/map/geotiff.h \
|
||||
src/map/pcs.h \
|
||||
src/map/transform.h \
|
||||
src/map/mapfile.h \
|
||||
src/map/tifffile.h \
|
||||
src/data/graph.h \
|
||||
src/data/poi.h \
|
||||
src/data/waypoint.h \
|
||||
@ -106,11 +111,17 @@ HEADERS += src/config.h \
|
||||
src/data/fitparser.h \
|
||||
src/data/igcparser.h \
|
||||
src/data/nmeaparser.h \
|
||||
src/data/str2int.h
|
||||
src/map/gcs.h \
|
||||
src/map/angularunits.h \
|
||||
src/map/primemeridian.h \
|
||||
src/map/linearunits.h \
|
||||
src/map/ct.h \
|
||||
src/map/mapsource.h
|
||||
SOURCES += src/main.cpp \
|
||||
src/common/coordinates.cpp \
|
||||
src/common/rectc.cpp \
|
||||
src/common/range.cpp \
|
||||
src/common/str2int.cpp \
|
||||
src/GUI/app.cpp \
|
||||
src/GUI/gui.cpp \
|
||||
src/GUI/axisitem.cpp \
|
||||
@ -163,13 +174,17 @@ SOURCES += src/main.cpp \
|
||||
src/map/matrix.cpp \
|
||||
src/map/ellipsoid.cpp \
|
||||
src/map/datum.cpp \
|
||||
src/map/projection.cpp \
|
||||
src/map/mercator.cpp \
|
||||
src/map/transversemercator.cpp \
|
||||
src/map/utm.cpp \
|
||||
src/map/lambertconic.cpp \
|
||||
src/map/albersequal.cpp \
|
||||
src/map/lambertazimuthal.cpp \
|
||||
src/map/geotiff.cpp \
|
||||
src/map/pcs.cpp \
|
||||
src/map/transform.cpp \
|
||||
src/map/mapfile.cpp \
|
||||
src/map/tifffile.cpp \
|
||||
src/data/data.cpp \
|
||||
src/data/poi.cpp \
|
||||
src/data/track.cpp \
|
||||
@ -182,25 +197,40 @@ SOURCES += src/main.cpp \
|
||||
src/data/fitparser.cpp \
|
||||
src/data/igcparser.cpp \
|
||||
src/data/nmeaparser.cpp \
|
||||
src/data/str2int.cpp
|
||||
src/map/projection.cpp \
|
||||
src/map/gcs.cpp \
|
||||
src/map/angularunits.cpp \
|
||||
src/map/primemeridian.cpp \
|
||||
src/map/linearunits.cpp \
|
||||
src/map/mapsource.cpp
|
||||
RESOURCES += gpxsee.qrc
|
||||
TRANSLATIONS = lang/gpxsee_cs.ts \
|
||||
lang/gpxsee_sv.ts \
|
||||
lang/gpxsee_de.ts
|
||||
lang/gpxsee_de.ts \
|
||||
lang/gpxsee_ru.ts \
|
||||
lang/gpxsee_fi.ts \
|
||||
lang/gpxsee_fr.ts
|
||||
macx {
|
||||
ICON = icons/gpxsee.icns
|
||||
QMAKE_INFO_PLIST = Info.plist
|
||||
APP_RESOURCES.files = icons/gpx.icns \
|
||||
icons/tcx.icns \
|
||||
QMAKE_INFO_PLIST = pkg/Info.plist
|
||||
LOCALE.path = Contents/Resources/translations
|
||||
LOCALE.files = lang/gpxsee_cs.qm \
|
||||
lang/gpxsee_de.qm \
|
||||
lang/gpxsee_fi.qm \
|
||||
lang/gpxsee_fr.qm \
|
||||
lang/gpxsee_ru.qm \
|
||||
lang/gpxsee_sv.qm
|
||||
CSV.path = Contents/Resources
|
||||
CSV.files = pkg/csv
|
||||
MAPS.path = Contents/Resources
|
||||
MAPS.files = pkg/maps
|
||||
ICONS.path = Contents/Resources/icons
|
||||
ICONS.files = icons/tcx.icns \
|
||||
icons/kml.icns \
|
||||
icons/fit.icns \
|
||||
icons/igc.icns \
|
||||
icons/nmea.icns \
|
||||
pkg/maps.txt \
|
||||
pkg/ellipsoids.csv \
|
||||
pkg/datums.csv
|
||||
APP_RESOURCES.path = Contents/Resources
|
||||
QMAKE_BUNDLE_DATA += APP_RESOURCES
|
||||
icons/nmea.icns
|
||||
QMAKE_BUNDLE_DATA += LOCALE MAPS ICONS CSV
|
||||
}
|
||||
win32 {
|
||||
RC_ICONS = icons/gpxsee.ico \
|
||||
|
@ -20,8 +20,5 @@
|
||||
<file>icons/system-run.png</file>
|
||||
<file>icons/document-print-preview.png</file>
|
||||
<file>icons/view-filter.png</file>
|
||||
<file>lang/gpxsee_cs.qm</file>
|
||||
<file>lang/gpxsee_sv.qm</file>
|
||||
<file>lang/gpxsee_de.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -46,50 +46,50 @@
|
||||
</context>
|
||||
<context>
|
||||
<name>Data</name>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="102"/>
|
||||
<source>Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)</source>
|
||||
<translation>Podporované soubory (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="103"/>
|
||||
<source>CSV files (*.csv)</source>
|
||||
<translation>Soubory CSV (*.csv)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="103"/>
|
||||
<source>FIT files (*.fit)</source>
|
||||
<translation>Soubory FIT (*.fit)</translation>
|
||||
<source>Supported files</source>
|
||||
<translation>Podporované soubory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="104"/>
|
||||
<source>GPX files (*.gpx)</source>
|
||||
<translation>Soubory GPX (*.gpx)</translation>
|
||||
<source>CSV files</source>
|
||||
<translation>Soubory CSV</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="104"/>
|
||||
<source>IGC files (*.igc)</source>
|
||||
<translation>Soubory IGC (*.igc)</translation>
|
||||
<source>FIT files</source>
|
||||
<translation>Soubory FIT</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="105"/>
|
||||
<source>KML files (*.kml)</source>
|
||||
<translation>Soubory KML (*.kml)</translation>
|
||||
<source>GPX files</source>
|
||||
<translation>Soubory GPX</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="105"/>
|
||||
<source>NMEA files (*.nmea)</source>
|
||||
<translation>Soubory NMEA (*.nmea)</translation>
|
||||
<source>IGC files</source>
|
||||
<translation>Soubory IGC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="106"/>
|
||||
<source>TCX files (*.tcx)</source>
|
||||
<translation>Soubory TCX (*.tcx)</translation>
|
||||
<source>KML files</source>
|
||||
<translation>Soubory KML</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="106"/>
|
||||
<source>All files (*)</source>
|
||||
<translation>Všechny soubory (*)</translation>
|
||||
<source>NMEA files</source>
|
||||
<translation>Soubory NMEA</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="107"/>
|
||||
<source>TCX files</source>
|
||||
<translation>Soubory TCX</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="107"/>
|
||||
<source>All files</source>
|
||||
<translation>Všechny soubory</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -295,341 +295,351 @@
|
||||
<context>
|
||||
<name>GUI</name>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="600"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="562"/>
|
||||
<source>GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at </source>
|
||||
<translation>Program GPXSee je distribuován pod podmínkami licence GNU General Public License verze 3. Pro více informací navštivte stránky programu na adrese </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="685"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="634"/>
|
||||
<source>Open file</source>
|
||||
<translation>Otevřít soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="775"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="723"/>
|
||||
<source>Open POI file</source>
|
||||
<translation>Otevřít POI soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="234"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="196"/>
|
||||
<source>Quit</source>
|
||||
<translation>Ukončit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="243"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="617"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="618"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="205"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="579"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="580"/>
|
||||
<source>Keyboard controls</source>
|
||||
<translation>Ovládací klávesy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="268"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="230"/>
|
||||
<source>Close</source>
|
||||
<translation>Zavřít</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="274"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="236"/>
|
||||
<source>Reload</source>
|
||||
<translation>Znovu načíst</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="529"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="491"/>
|
||||
<source>Show</source>
|
||||
<translation>Zobrazit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="445"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="523"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="407"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="485"/>
|
||||
<source>File</source>
|
||||
<translation>Soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="241"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="651"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="652"/>
|
||||
<source>Data sources</source>
|
||||
<translation>Zdroje dat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="285"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="247"/>
|
||||
<source>Close POI files</source>
|
||||
<translation>Zavřit POI soubory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="287"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="249"/>
|
||||
<source>Overlap POIs</source>
|
||||
<translation>Překrývat POI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="291"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="253"/>
|
||||
<source>Show POI labels</source>
|
||||
<translation>Zobrazit názvy POI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="296"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="258"/>
|
||||
<source>Show POIs</source>
|
||||
<translation>Zobrazit POI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="305"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="267"/>
|
||||
<source>Show map</source>
|
||||
<translation>Zobrazit mapu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="315"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="277"/>
|
||||
<source>Clear tile cache</source>
|
||||
<translation>Vymazat mezipaměť dlaždic</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="252"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="214"/>
|
||||
<source>Open...</source>
|
||||
<translation>Otevřít...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="282"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="203"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="613"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="614"/>
|
||||
<source>Paths</source>
|
||||
<translation>Cesty</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="244"/>
|
||||
<source>Load POI file...</source>
|
||||
<translation>Nahrát POI soubor...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="313"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="275"/>
|
||||
<source>Load map...</source>
|
||||
<translation>Nahrát mapu...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="319"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="323"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="634"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="281"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="285"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="596"/>
|
||||
<source>Next map</source>
|
||||
<translation>Následující mapa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="333"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="295"/>
|
||||
<source>Show tracks</source>
|
||||
<translation>Zobrazit cesty</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="337"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="299"/>
|
||||
<source>Show routes</source>
|
||||
<translation>Zobrazit trasy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="341"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="303"/>
|
||||
<source>Show waypoints</source>
|
||||
<translation>Zobrazit navigační body</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="345"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="307"/>
|
||||
<source>Waypoint labels</source>
|
||||
<translation>Názvy navigačních bodů</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="356"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="318"/>
|
||||
<source>Show graphs</source>
|
||||
<translation>Zobrazit grafy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="376"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="338"/>
|
||||
<source>Show grid</source>
|
||||
<translation>Zobrazit mřížku</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="380"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="342"/>
|
||||
<source>Show slider info</source>
|
||||
<translation>Zobrazit informace o posuvníku</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="386"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="348"/>
|
||||
<source>Show toolbars</source>
|
||||
<translation>Zobrazovat nástrojové lišty</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="392"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="354"/>
|
||||
<source>Total time</source>
|
||||
<translation>Celkový čas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="397"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="950"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="359"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="898"/>
|
||||
<source>Moving time</source>
|
||||
<translation>Čistý čas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="404"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="366"/>
|
||||
<source>Metric</source>
|
||||
<translation>Metrické</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="409"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="371"/>
|
||||
<source>Imperial</source>
|
||||
<translation>Imperiální</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="415"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="377"/>
|
||||
<source>Fullscreen mode</source>
|
||||
<translation>Celoobrazovkový režim</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="421"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="383"/>
|
||||
<source>Options...</source>
|
||||
<translation>Nastavení...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="427"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="389"/>
|
||||
<source>Next</source>
|
||||
<translation>Následující</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="430"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="392"/>
|
||||
<source>Previous</source>
|
||||
<translation>Předchozí</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="434"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="396"/>
|
||||
<source>Last</source>
|
||||
<translation>Poslední</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="437"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="399"/>
|
||||
<source>First</source>
|
||||
<translation>První</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="459"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="421"/>
|
||||
<source>Map</source>
|
||||
<translation>Mapa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="467"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="429"/>
|
||||
<source>Graph</source>
|
||||
<translation>Graf</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="476"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="438"/>
|
||||
<source>POI</source>
|
||||
<translation>POI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="477"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="439"/>
|
||||
<source>POI files</source>
|
||||
<translation>POI soubory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="488"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="450"/>
|
||||
<source>Data</source>
|
||||
<translation>Data</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="489"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="451"/>
|
||||
<source>Display</source>
|
||||
<translation>Zobrazit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="497"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="459"/>
|
||||
<source>Settings</source>
|
||||
<translation>Nastavení</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="501"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="463"/>
|
||||
<source>Units</source>
|
||||
<translation>Jednotky</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="510"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="472"/>
|
||||
<source>Help</source>
|
||||
<translation>Nápověda</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="627"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="589"/>
|
||||
<source>Append file</source>
|
||||
<translation>Přidat soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="628"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="590"/>
|
||||
<source>Next/Previous</source>
|
||||
<translation>Následující/Předchozí</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="630"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="592"/>
|
||||
<source>Toggle graph type</source>
|
||||
<translation>Přepnout typ grafu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="632"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="594"/>
|
||||
<source>Toggle time type</source>
|
||||
<translation>Přepnout typ času</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="636"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="598"/>
|
||||
<source>Previous map</source>
|
||||
<translation>Předchozí mapa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="637"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="599"/>
|
||||
<source>Zoom in</source>
|
||||
<translation>Přiblížit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="639"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="601"/>
|
||||
<source>Zoom out</source>
|
||||
<translation>Oddálit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="641"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="603"/>
|
||||
<source>Digital zoom</source>
|
||||
<translation>Digitální zoom</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="642"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="604"/>
|
||||
<source>Zoom</source>
|
||||
<translation>Zoom</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="654"/>
|
||||
<source>Online maps</source>
|
||||
<translation>Online mapy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="655"/>
|
||||
<source>Online map URLs are read on program startup from the following file:</source>
|
||||
<translation>URL online map jsou načteny při startu programu z následujícího souboru:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="658"/>
|
||||
<source>The file format is one map entry per line, consisting of the map name, tiles URL and an optional maximal zoom level delimited by a TAB character. The tile X and Y coordinates are replaced with $x and $y in the URL and the zoom level is replaced with $z. An example map file could look like:</source>
|
||||
<translation>Formát souboru je jeden mapový záznam na řádku, kde mapový záznam sestává ze jména mapy, URL dlaždic a volitelně maximálního zoomu navzájem oddělených tabulátorem. Souřadnice dlaždice jsou v URL nahrazeny řetězci $x a $y, zoom pak řetězcem $z. Příklad:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="667"/>
|
||||
<source>Offline maps are loaded on program startup from the following directory:</source>
|
||||
<translation>Offline mapy jsou načítány při startu aplikace z následujícího adresáře:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1151"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1099"/>
|
||||
<source>Open map file</source>
|
||||
<translation>Otevřít mapový soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1181"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1137"/>
|
||||
<source>No files loaded</source>
|
||||
<translation>Nejsou načteny žádné soubory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="936"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="939"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="884"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="887"/>
|
||||
<source>Date</source>
|
||||
<translation>Datum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="928"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="617"/>
|
||||
<source>Map directory:</source>
|
||||
<translation>Adresář s mapami:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="618"/>
|
||||
<source>POI directory:</source>
|
||||
<translation>Adresář s POI body:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="620"/>
|
||||
<source>GCS file:</source>
|
||||
<translation>Soubor s GCS daty:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="621"/>
|
||||
<source>PCS file:</source>
|
||||
<translation>Soubor s PCS daty:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="622"/>
|
||||
<source>Ellipsoids file:</source>
|
||||
<translation>Soubor s daty elipsoidů:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="625"/>
|
||||
<source>User override directory:</source>
|
||||
<translation>Uživatelský adresář:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="876"/>
|
||||
<source>Routes</source>
|
||||
<translation>Trasy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1172"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1126"/>
|
||||
<source>Error loading map:</source>
|
||||
<translation>Mapu nelze načíst:</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../src/GUI/gui.cpp" line="1185"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1141"/>
|
||||
<source>%n files</source>
|
||||
<translation>
|
||||
<numerusform>%n soubor</numerusform>
|
||||
@ -638,117 +648,97 @@
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="621"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="583"/>
|
||||
<source>Next file</source>
|
||||
<translation>Následující soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="597"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="559"/>
|
||||
<source>Version </source>
|
||||
<translation>Verze </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="257"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="219"/>
|
||||
<source>Print...</source>
|
||||
<translation>Tisknout...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="262"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="224"/>
|
||||
<source>Export to PDF...</source>
|
||||
<translation>Exportovat do PDF...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="930"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="878"/>
|
||||
<source>Waypoints</source>
|
||||
<translation>Navigační body</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="622"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="584"/>
|
||||
<source>Previous file</source>
|
||||
<translation>Předchozí soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="349"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="311"/>
|
||||
<source>Route waypoints</source>
|
||||
<translation>Body tras</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="624"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="586"/>
|
||||
<source>First file</source>
|
||||
<translation>První soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="626"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="588"/>
|
||||
<source>Last file</source>
|
||||
<translation>Poslední soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="666"/>
|
||||
<source>Offline maps</source>
|
||||
<translation>Offline mapy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="670"/>
|
||||
<source>The expected structure is one map/atlas in a separate subdirectory. Supported map formats are OziExplorer maps and TrekBuddy maps/atlases (tared and non-tared).</source>
|
||||
<translation>Očekávaná struktura je jedna mapa/atlas v samostatném podadresáři. Podporované mapové formáty jsou OziExplorer mapy a TrekBuddy mapy/atlasy (včetně tar varianty).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="675"/>
|
||||
<source>To make GPXSee load a POI file automatically on startup, add the file to the following directory:</source>
|
||||
<translation>POI soubory, které se mají automaticky nahrát při startu programu jsou načítány z následujícího adresáře:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="764"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="712"/>
|
||||
<source>Error loading data file:</source>
|
||||
<translation>Datový soubor nelze načíst:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="767"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="792"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="715"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="740"/>
|
||||
<source>Line: %1</source>
|
||||
<translation>Řádka: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="789"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="737"/>
|
||||
<source>Error loading POI file:</source>
|
||||
<translation>Soubor POI nelze načíst:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="922"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="870"/>
|
||||
<source>Name</source>
|
||||
<translation>Název</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="926"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="874"/>
|
||||
<source>Tracks</source>
|
||||
<translation>Cesty</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="246"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="596"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="208"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="558"/>
|
||||
<source>About GPXSee</source>
|
||||
<translation>O aplikaci GPXSee</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="534"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="496"/>
|
||||
<source>Navigation</source>
|
||||
<translation>Navigace</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="674"/>
|
||||
<source>POIs</source>
|
||||
<translation>POI body</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="364"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="946"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="326"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="894"/>
|
||||
<source>Distance</source>
|
||||
<translation>Vzdálenost</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="370"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="498"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="948"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="332"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="460"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="896"/>
|
||||
<source>Time</source>
|
||||
<translation>Čas</translation>
|
||||
</message>
|
||||
@ -848,14 +838,29 @@
|
||||
<context>
|
||||
<name>MapList</name>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="141"/>
|
||||
<source>Map files (*.map *.tba *.tar)</source>
|
||||
<translation>Mapové soubory (*.map *.tba *.tar)</translation>
|
||||
<location filename="../src/map/maplist.cpp" line="128"/>
|
||||
<source>Supported files</source>
|
||||
<translation>Podporované soubory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="142"/>
|
||||
<source>URL list files (*.txt)</source>
|
||||
<translation>Seznamy URL (*.txt)</translation>
|
||||
<location filename="../src/map/maplist.cpp" line="129"/>
|
||||
<source>OziExplorer maps</source>
|
||||
<translation>OziExplorer mapy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="130"/>
|
||||
<source>TrekBuddy maps/atlases</source>
|
||||
<translation>TrekBuddy mapy/atlasy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="131"/>
|
||||
<source>GeoTIFF images</source>
|
||||
<translation>GeoTIFF obrázky</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="132"/>
|
||||
<source>Online map sources</source>
|
||||
<translation>Online mapové zdroje</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -46,50 +46,50 @@
|
||||
</context>
|
||||
<context>
|
||||
<name>Data</name>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="102"/>
|
||||
<source>Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)</source>
|
||||
<translation>Unterstütze Dateien (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="103"/>
|
||||
<source>CSV files (*.csv)</source>
|
||||
<translation>CSV-Dateien (*.csv)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="103"/>
|
||||
<source>FIT files (*.fit)</source>
|
||||
<translation>FIT-Dateien (*.fit)</translation>
|
||||
<source>Supported files</source>
|
||||
<translation>Unterstütze Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="104"/>
|
||||
<source>GPX files (*.gpx)</source>
|
||||
<translation>GPX-Dateien (*.gpx)</translation>
|
||||
<source>CSV files</source>
|
||||
<translation>CSV-Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="104"/>
|
||||
<source>IGC files (*.igc)</source>
|
||||
<translation>IGC-Dateien (*.igc)</translation>
|
||||
<source>FIT files</source>
|
||||
<translation>FIT-Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="105"/>
|
||||
<source>KML files (*.kml)</source>
|
||||
<translation>KML-Dateien (*.kml)</translation>
|
||||
<source>GPX files</source>
|
||||
<translation>GPX-Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="105"/>
|
||||
<source>NMEA files (*.nmea)</source>
|
||||
<translation>NMEA-Dateien (*.nmea)</translation>
|
||||
<source>IGC files</source>
|
||||
<translation>IGC-Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="106"/>
|
||||
<source>TCX files (*.tcx)</source>
|
||||
<translation>TCX-Dateien (*.tcx)</translation>
|
||||
<source>KML files</source>
|
||||
<translation>KML-Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="106"/>
|
||||
<source>All files (*)</source>
|
||||
<translation>Alle Dateien (*)</translation>
|
||||
<source>NMEA files</source>
|
||||
<translation>NMEA-Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="107"/>
|
||||
<source>TCX files</source>
|
||||
<translation>TCX-Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="107"/>
|
||||
<source>All files</source>
|
||||
<translation>Alle Dateien</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -295,335 +295,340 @@
|
||||
<context>
|
||||
<name>GUI</name>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="600"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="562"/>
|
||||
<source>GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at </source>
|
||||
<translation>GPXSee wird unter der GNU General Public License version 3 vertrieben. Mehr Informationen zu GPXSee auf der Homepage </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="685"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="617"/>
|
||||
<source>Map directory:</source>
|
||||
<translation>Kartenverzeichnis:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="618"/>
|
||||
<source>POI directory:</source>
|
||||
<translation>POI-Verzeichnis:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="620"/>
|
||||
<source>GCS file:</source>
|
||||
<translation>GCS-Datei:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="621"/>
|
||||
<source>PCS file:</source>
|
||||
<translation>PCS-Datei:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="622"/>
|
||||
<source>Ellipsoids file:</source>
|
||||
<translation>Ellipsoidendatei:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="625"/>
|
||||
<source>User override directory:</source>
|
||||
<translation>Benutzerverzeichnis:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="634"/>
|
||||
<source>Open file</source>
|
||||
<translation>Datei öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="775"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="723"/>
|
||||
<source>Open POI file</source>
|
||||
<translation>POI Datei öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="234"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="196"/>
|
||||
<source>Quit</source>
|
||||
<translation>Beenden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="243"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="617"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="618"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="205"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="579"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="580"/>
|
||||
<source>Keyboard controls</source>
|
||||
<translation>Tastaturkürzel</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="268"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="230"/>
|
||||
<source>Close</source>
|
||||
<translation>Schließen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="274"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="236"/>
|
||||
<source>Reload</source>
|
||||
<translation>Neu Laden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="529"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="491"/>
|
||||
<source>Show</source>
|
||||
<translation>Ansicht</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="445"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="523"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="407"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="485"/>
|
||||
<source>File</source>
|
||||
<translation>Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="241"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="651"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="652"/>
|
||||
<source>Data sources</source>
|
||||
<translation>Datenquellen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="285"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="247"/>
|
||||
<source>Close POI files</source>
|
||||
<translation>POI-Datei schließen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="287"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="249"/>
|
||||
<source>Overlap POIs</source>
|
||||
<translation>POI überlappen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="291"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="253"/>
|
||||
<source>Show POI labels</source>
|
||||
<translation>POI-Labels anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="296"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="258"/>
|
||||
<source>Show POIs</source>
|
||||
<translation>POIs anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="305"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="267"/>
|
||||
<source>Show map</source>
|
||||
<translation>Karte anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="315"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="277"/>
|
||||
<source>Clear tile cache</source>
|
||||
<translation>Tile-Cache bereinigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="252"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="214"/>
|
||||
<source>Open...</source>
|
||||
<translation>Öffnen...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="282"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="203"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="613"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="614"/>
|
||||
<source>Paths</source>
|
||||
<translation>Pfade</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="244"/>
|
||||
<source>Load POI file...</source>
|
||||
<translation>POI-Datei laden...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="313"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="275"/>
|
||||
<source>Load map...</source>
|
||||
<translation>Karte laden...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="319"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="323"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="634"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="281"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="285"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="596"/>
|
||||
<source>Next map</source>
|
||||
<translation>Nächste Karte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="333"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="295"/>
|
||||
<source>Show tracks</source>
|
||||
<translation>Strecken anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="337"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="299"/>
|
||||
<source>Show routes</source>
|
||||
<translation>Routen anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="341"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="303"/>
|
||||
<source>Show waypoints</source>
|
||||
<translation>Wegpunkte anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="345"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="307"/>
|
||||
<source>Waypoint labels</source>
|
||||
<translation>Wegpunkt Labels</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="356"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="318"/>
|
||||
<source>Show graphs</source>
|
||||
<translation>Graphen anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="376"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="338"/>
|
||||
<source>Show grid</source>
|
||||
<translation>Gitter anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="380"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="342"/>
|
||||
<source>Show slider info</source>
|
||||
<translation>Schieberinfo anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="386"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="348"/>
|
||||
<source>Show toolbars</source>
|
||||
<translation>Toolbars anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="392"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="354"/>
|
||||
<source>Total time</source>
|
||||
<translation>Gesamtzeit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="397"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="950"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="359"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="898"/>
|
||||
<source>Moving time</source>
|
||||
<translation>Bewegungszeit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="404"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="366"/>
|
||||
<source>Metric</source>
|
||||
<translation>Metrisch</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="409"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="371"/>
|
||||
<source>Imperial</source>
|
||||
<translation>Imperial</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="415"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="377"/>
|
||||
<source>Fullscreen mode</source>
|
||||
<translation>Vollbildmodus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="421"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="383"/>
|
||||
<source>Options...</source>
|
||||
<translation>Einstellungen...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="427"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="389"/>
|
||||
<source>Next</source>
|
||||
<translation>Nächste</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="430"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="392"/>
|
||||
<source>Previous</source>
|
||||
<translation>Vorherige</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="434"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="396"/>
|
||||
<source>Last</source>
|
||||
<translation>Letzte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="437"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="399"/>
|
||||
<source>First</source>
|
||||
<translation>Erste</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="459"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="421"/>
|
||||
<source>Map</source>
|
||||
<translation>Karte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="467"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="429"/>
|
||||
<source>Graph</source>
|
||||
<translation>Graph</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="476"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="438"/>
|
||||
<source>POI</source>
|
||||
<translation>POI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="477"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="439"/>
|
||||
<source>POI files</source>
|
||||
<translation>POI-Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="488"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="450"/>
|
||||
<source>Data</source>
|
||||
<translation>Daten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="489"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="451"/>
|
||||
<source>Display</source>
|
||||
<translation>Anzeige</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="497"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="459"/>
|
||||
<source>Settings</source>
|
||||
<translation>Einstellungen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="501"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="463"/>
|
||||
<source>Units</source>
|
||||
<translation>Einheiten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="510"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="472"/>
|
||||
<source>Help</source>
|
||||
<translation>Hilfe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="627"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="589"/>
|
||||
<source>Append file</source>
|
||||
<translation>An Datei anhängen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="628"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="590"/>
|
||||
<source>Next/Previous</source>
|
||||
<translation>Nächste/Vorherige</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="630"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="592"/>
|
||||
<source>Toggle graph type</source>
|
||||
<translation>Graphtyp umschalten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="632"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="594"/>
|
||||
<source>Toggle time type</source>
|
||||
<translation>Zeittyp umschalten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="636"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="598"/>
|
||||
<source>Previous map</source>
|
||||
<translation>Vorherige Karte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="637"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="599"/>
|
||||
<source>Zoom in</source>
|
||||
<translation>Hineinzoomen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="639"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="601"/>
|
||||
<source>Zoom out</source>
|
||||
<translation>Herauszoomen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="641"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="603"/>
|
||||
<source>Digital zoom</source>
|
||||
<translation>Digitaler Zoom</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="642"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="604"/>
|
||||
<source>Zoom</source>
|
||||
<translation>Zoom</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="654"/>
|
||||
<source>Online maps</source>
|
||||
<translation>Onlinekarten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="655"/>
|
||||
<source>Online map URLs are read on program startup from the following file:</source>
|
||||
<translation>Onlinekarten URLs werden zu Programmstart aus der folgenden Datei gelesen:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="658"/>
|
||||
<source>The file format is one map entry per line, consisting of the map name, tiles URL and an optional maximal zoom level delimited by a TAB character. The tile X and Y coordinates are replaced with $x and $y in the URL and the zoom level is replaced with $z. An example map file could look like:</source>
|
||||
<translation>Das Dateiformat ist eine Karte pro Linie. Jede Linie besteht aus dem Kartenname, der Tiles URL und wahlweise dem maximalen Zoomlevel getrennt durch ein TAB Zeichen. X und Y Koordinate einer Tile werden in der URL durch $x und $y ersetzt und das Zoomlevel durch $z. Ein Beispiel einer Kartendatei könnte so aussehen:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="666"/>
|
||||
<source>Offline maps</source>
|
||||
<translation>Offlinekarten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="667"/>
|
||||
<source>Offline maps are loaded on program startup from the following directory:</source>
|
||||
<translation>Offlinekarten werden zu Programmstart aus dem folgenden Verzeichnis geladen:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1151"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1099"/>
|
||||
<source>Open map file</source>
|
||||
<translation>Karte Datei öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1172"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1126"/>
|
||||
<source>Error loading map:</source>
|
||||
<translation>Fehler beim Laden der Karte-Datei:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1181"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1137"/>
|
||||
<source>No files loaded</source>
|
||||
<translation>Keine Dateien geladen</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../src/GUI/gui.cpp" line="1185"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1141"/>
|
||||
<source>%n files</source>
|
||||
<translation>
|
||||
<numerusform>%n Datei</numerusform>
|
||||
@ -631,123 +636,108 @@
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="936"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="939"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="884"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="887"/>
|
||||
<source>Date</source>
|
||||
<translation>Datum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="928"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="876"/>
|
||||
<source>Routes</source>
|
||||
<translation>Routen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="621"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="583"/>
|
||||
<source>Next file</source>
|
||||
<translation>Nächste Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="597"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="559"/>
|
||||
<source>Version </source>
|
||||
<translation>Version </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="257"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="219"/>
|
||||
<source>Print...</source>
|
||||
<translation>Drucken...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="262"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="224"/>
|
||||
<source>Export to PDF...</source>
|
||||
<translation>Als PDF exportieren...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="930"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="878"/>
|
||||
<source>Waypoints</source>
|
||||
<translation>Wegpunkte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="622"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="584"/>
|
||||
<source>Previous file</source>
|
||||
<translation>Vorherige Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="349"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="311"/>
|
||||
<source>Route waypoints</source>
|
||||
<translation>Routen Wegpunkte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="624"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="586"/>
|
||||
<source>First file</source>
|
||||
<translation>Erste Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="626"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="588"/>
|
||||
<source>Last file</source>
|
||||
<translation>Letzte Datei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="670"/>
|
||||
<source>The expected structure is one map/atlas in a separate subdirectory. Supported map formats are OziExplorer maps and TrekBuddy maps/atlases (tared and non-tared).</source>
|
||||
<translation>Die erwartete Struktur ist eine Karte/ein Atlas pro Unterverzeichnis. Unterstützte Kartenformate sind OziExplorer Karten und TrekBuddy Karten/Atlanten (mit oder ohne tar Kompression).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="675"/>
|
||||
<source>To make GPXSee load a POI file automatically on startup, add the file to the following directory:</source>
|
||||
<translation>Damit GPXSee zu Programmstart automatisch eine POI-Datei lädt, fügen Sie diese zu folgendem Verzeichnis hinzu:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="764"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="712"/>
|
||||
<source>Error loading data file:</source>
|
||||
<translation>Fehler beim Laden der Datei:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="767"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="792"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="715"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="740"/>
|
||||
<source>Line: %1</source>
|
||||
<translation>Linie: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="789"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="737"/>
|
||||
<source>Error loading POI file:</source>
|
||||
<translation>Fehler beim Laden der POI-Datei:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="922"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="870"/>
|
||||
<source>Name</source>
|
||||
<translation>Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="926"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="874"/>
|
||||
<source>Tracks</source>
|
||||
<translation>Strecken</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="246"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="596"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="208"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="558"/>
|
||||
<source>About GPXSee</source>
|
||||
<translation>Über GPXSee</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="534"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="496"/>
|
||||
<source>Navigation</source>
|
||||
<translation>Navigation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="674"/>
|
||||
<source>POIs</source>
|
||||
<translation>POIs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="364"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="946"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="326"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="894"/>
|
||||
<source>Distance</source>
|
||||
<translation>Distanz</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="370"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="498"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="948"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="332"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="460"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="896"/>
|
||||
<source>Time</source>
|
||||
<translation>Zeit</translation>
|
||||
</message>
|
||||
@ -847,14 +837,29 @@
|
||||
<context>
|
||||
<name>MapList</name>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="141"/>
|
||||
<source>Map files (*.map *.tba *.tar)</source>
|
||||
<translation>Karten-Dateien (*.map *.tba *.tar)</translation>
|
||||
<location filename="../src/map/maplist.cpp" line="128"/>
|
||||
<source>Supported files</source>
|
||||
<translation>Unterstütze Dateien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="142"/>
|
||||
<source>URL list files (*.txt)</source>
|
||||
<translation>URL-Liste Dateien (*.txt)</translation>
|
||||
<location filename="../src/map/maplist.cpp" line="129"/>
|
||||
<source>OziExplorer maps</source>
|
||||
<translation>OziExplorer Karten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="130"/>
|
||||
<source>TrekBuddy maps/atlases</source>
|
||||
<translation>TrekBuddy Karten/Atlanten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="131"/>
|
||||
<source>GeoTIFF images</source>
|
||||
<translation>GeoTIFF Bilder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="132"/>
|
||||
<source>Online map sources</source>
|
||||
<translation>Online-Kartenquellen</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
1501
lang/gpxsee_fi.ts
Normal file
1501
lang/gpxsee_fi.ts
Normal file
File diff suppressed because it is too large
Load Diff
1501
lang/gpxsee_fr.ts
Normal file
1501
lang/gpxsee_fr.ts
Normal file
File diff suppressed because it is too large
Load Diff
1502
lang/gpxsee_ru.ts
Normal file
1502
lang/gpxsee_ru.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -46,50 +46,50 @@
|
||||
</context>
|
||||
<context>
|
||||
<name>Data</name>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="102"/>
|
||||
<source>Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)</source>
|
||||
<translation>Filer som stöds (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="103"/>
|
||||
<source>CSV files (*.csv)</source>
|
||||
<translation>CSV-filer (*.csv)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="103"/>
|
||||
<source>FIT files (*.fit)</source>
|
||||
<translation>FIT-filer (*.fit)</translation>
|
||||
<source>Supported files</source>
|
||||
<translation>Filer som stöds</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="104"/>
|
||||
<source>GPX files (*.gpx)</source>
|
||||
<translation>GPX-filer (*.gpx)</translation>
|
||||
<source>CSV files</source>
|
||||
<translation>CSV-filer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="104"/>
|
||||
<source>IGC files (*.igc)</source>
|
||||
<translation>IGC-filer (*.igc)</translation>
|
||||
<source>FIT files</source>
|
||||
<translation>FIT-filer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="105"/>
|
||||
<source>KML files (*.kml)</source>
|
||||
<translation>KML-filer (*.kml)</translation>
|
||||
<source>GPX files</source>
|
||||
<translation>GPX-filer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="105"/>
|
||||
<source>NMEA files (*.nmea)</source>
|
||||
<translation>NMEA-filer (*.nmea)</translation>
|
||||
<source>IGC files</source>
|
||||
<translation>IGC-filer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="106"/>
|
||||
<source>TCX files (*.tcx)</source>
|
||||
<translation>TCX-filer (*.tcx)</translation>
|
||||
<source>KML files</source>
|
||||
<translation>KML-filer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="106"/>
|
||||
<source>All files (*)</source>
|
||||
<translation>Alla filer (*)</translation>
|
||||
<source>NMEA files</source>
|
||||
<translation>NMEA-filer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="107"/>
|
||||
<source>TCX files</source>
|
||||
<translation>TCX-filer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/data/data.cpp" line="107"/>
|
||||
<source>All files</source>
|
||||
<translation>Alla filer</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -295,335 +295,340 @@
|
||||
<context>
|
||||
<name>GUI</name>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="600"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="562"/>
|
||||
<source>GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at </source>
|
||||
<translation>GPXSee distribueras under vilkoren för GNU General Public License version 3. För mer info om GPXSee, besök hemsidan på </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="685"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="617"/>
|
||||
<source>Map directory:</source>
|
||||
<translation>Kartmapp:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="618"/>
|
||||
<source>POI directory:</source>
|
||||
<translation>POI-mapp:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="620"/>
|
||||
<source>GCS file:</source>
|
||||
<translation>GCS-fil:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="621"/>
|
||||
<source>PCS file:</source>
|
||||
<translation>PCS-fil:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="622"/>
|
||||
<source>Ellipsoids file:</source>
|
||||
<translation>Ellipsoids-fil:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="625"/>
|
||||
<source>User override directory:</source>
|
||||
<translation>Användarspecificerad mapp:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="634"/>
|
||||
<source>Open file</source>
|
||||
<translation>Öppna fil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="775"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="723"/>
|
||||
<source>Open POI file</source>
|
||||
<translation>Öppna POI-fil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="234"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="196"/>
|
||||
<source>Quit</source>
|
||||
<translation>Avsluta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="243"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="617"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="618"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="205"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="579"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="580"/>
|
||||
<source>Keyboard controls</source>
|
||||
<translation>Snabbtangenter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="268"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="230"/>
|
||||
<source>Close</source>
|
||||
<translation>Stäng</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="274"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="236"/>
|
||||
<source>Reload</source>
|
||||
<translation>Uppdatera</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="529"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="491"/>
|
||||
<source>Show</source>
|
||||
<translation>Visa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="445"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="523"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="407"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="485"/>
|
||||
<source>File</source>
|
||||
<translation>Arkiv</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="241"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="651"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="652"/>
|
||||
<source>Data sources</source>
|
||||
<translation>Datakällor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="285"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="247"/>
|
||||
<source>Close POI files</source>
|
||||
<translation>Stäng POI-filer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="287"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="249"/>
|
||||
<source>Overlap POIs</source>
|
||||
<translation>Överlappa POI:er</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="291"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="253"/>
|
||||
<source>Show POI labels</source>
|
||||
<translation>Visa POI-namn</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="296"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="258"/>
|
||||
<source>Show POIs</source>
|
||||
<translation>Visa POI:er</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="305"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="267"/>
|
||||
<source>Show map</source>
|
||||
<translation>Visa karta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="315"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="277"/>
|
||||
<source>Clear tile cache</source>
|
||||
<translation>Rensa kart-cache</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="252"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="214"/>
|
||||
<source>Open...</source>
|
||||
<translation>Öppna...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="282"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="203"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="613"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="614"/>
|
||||
<source>Paths</source>
|
||||
<translation type="unfinished">Sökvägar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="244"/>
|
||||
<source>Load POI file...</source>
|
||||
<translation>Läs in POI-fil...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="313"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="275"/>
|
||||
<source>Load map...</source>
|
||||
<translation>Läs in karta...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="319"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="323"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="634"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="281"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="285"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="596"/>
|
||||
<source>Next map</source>
|
||||
<translation>Nästa karta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="333"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="295"/>
|
||||
<source>Show tracks</source>
|
||||
<translation>Visa spår</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="337"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="299"/>
|
||||
<source>Show routes</source>
|
||||
<translation>Visa rutter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="341"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="303"/>
|
||||
<source>Show waypoints</source>
|
||||
<translation>Visa vägpunkter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="345"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="307"/>
|
||||
<source>Waypoint labels</source>
|
||||
<translation>Vägpunktsnamn</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="356"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="318"/>
|
||||
<source>Show graphs</source>
|
||||
<translation>Visa diagram</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="376"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="338"/>
|
||||
<source>Show grid</source>
|
||||
<translation>Visa stödlinjer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="380"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="342"/>
|
||||
<source>Show slider info</source>
|
||||
<translation>Visa reglageinfo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="386"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="348"/>
|
||||
<source>Show toolbars</source>
|
||||
<translation>Visa verktygsfält</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="392"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="354"/>
|
||||
<source>Total time</source>
|
||||
<translation>Total tid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="397"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="950"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="359"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="898"/>
|
||||
<source>Moving time</source>
|
||||
<translation>Förflyttningstid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="404"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="366"/>
|
||||
<source>Metric</source>
|
||||
<translation>Meter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="409"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="371"/>
|
||||
<source>Imperial</source>
|
||||
<translation>Imperial</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="415"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="377"/>
|
||||
<source>Fullscreen mode</source>
|
||||
<translation>Helskärmsläge</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="421"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="383"/>
|
||||
<source>Options...</source>
|
||||
<translation>Alternativ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="427"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="389"/>
|
||||
<source>Next</source>
|
||||
<translation>Nästa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="430"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="392"/>
|
||||
<source>Previous</source>
|
||||
<translation>Föregående</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="434"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="396"/>
|
||||
<source>Last</source>
|
||||
<translation>Sista</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="437"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="399"/>
|
||||
<source>First</source>
|
||||
<translation>Första</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="459"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="421"/>
|
||||
<source>Map</source>
|
||||
<translation>Karta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="467"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="429"/>
|
||||
<source>Graph</source>
|
||||
<translation>Diagram</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="476"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="438"/>
|
||||
<source>POI</source>
|
||||
<translation>POI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="477"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="439"/>
|
||||
<source>POI files</source>
|
||||
<translation>POI-filer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="488"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="450"/>
|
||||
<source>Data</source>
|
||||
<translation>Data</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="489"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="451"/>
|
||||
<source>Display</source>
|
||||
<translation>Visa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="497"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="459"/>
|
||||
<source>Settings</source>
|
||||
<translation>Inställningar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="501"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="463"/>
|
||||
<source>Units</source>
|
||||
<translation>Enhet</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="510"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="472"/>
|
||||
<source>Help</source>
|
||||
<translation>Hjälp</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="627"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="589"/>
|
||||
<source>Append file</source>
|
||||
<translation>Lägg till fil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="628"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="590"/>
|
||||
<source>Next/Previous</source>
|
||||
<translation>Nästa/Föregående</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="630"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="592"/>
|
||||
<source>Toggle graph type</source>
|
||||
<translation>Växla diagramtyp</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="632"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="594"/>
|
||||
<source>Toggle time type</source>
|
||||
<translation>Växla tidstyp</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="636"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="598"/>
|
||||
<source>Previous map</source>
|
||||
<translation>Föregående karta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="637"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="599"/>
|
||||
<source>Zoom in</source>
|
||||
<translation>Zooma in</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="639"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="601"/>
|
||||
<source>Zoom out</source>
|
||||
<translation>Zooma ut</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="641"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="603"/>
|
||||
<source>Digital zoom</source>
|
||||
<translation>Digital zoom</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="642"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="604"/>
|
||||
<source>Zoom</source>
|
||||
<translation>Zoom</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="654"/>
|
||||
<source>Online maps</source>
|
||||
<translation>Online-kartor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="655"/>
|
||||
<source>Online map URLs are read on program startup from the following file:</source>
|
||||
<translation>Online-kartors URL:er, läses från följande fil vid programstart:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="658"/>
|
||||
<source>The file format is one map entry per line, consisting of the map name, tiles URL and an optional maximal zoom level delimited by a TAB character. The tile X and Y coordinates are replaced with $x and $y in the URL and the zoom level is replaced with $z. An example map file could look like:</source>
|
||||
<translation>Filformatet är en kartpost per rad, bestående av kartans namn, webbadress och maximal zoomnivå om tillämpligt, Kartrutans X- och Y-koordinater ersätts med $x och $y, i webbadressen och zoomnivån ersätts med $z. Ett exempel på en kartfil kan se ut så här:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="666"/>
|
||||
<source>Offline maps</source>
|
||||
<translation>Offline-kartor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="667"/>
|
||||
<source>Offline maps are loaded on program startup from the following directory:</source>
|
||||
<translation>Offline-kartor läses in från följande mapp vid programstart:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1151"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1099"/>
|
||||
<source>Open map file</source>
|
||||
<translation>Öppna kartfil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1172"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1126"/>
|
||||
<source>Error loading map:</source>
|
||||
<translation>Fel vid inläsning av karta:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1181"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1137"/>
|
||||
<source>No files loaded</source>
|
||||
<translation>Inga filer inlästa</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../src/GUI/gui.cpp" line="1185"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="1141"/>
|
||||
<source>%n files</source>
|
||||
<translation>
|
||||
<numerusform>%n filer</numerusform>
|
||||
@ -631,123 +636,108 @@
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="936"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="939"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="884"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="887"/>
|
||||
<source>Date</source>
|
||||
<translation>Datum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="928"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="876"/>
|
||||
<source>Routes</source>
|
||||
<translation>Rutter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="621"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="583"/>
|
||||
<source>Next file</source>
|
||||
<translation>Nästa fil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="597"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="559"/>
|
||||
<source>Version </source>
|
||||
<translation>Version </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="257"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="219"/>
|
||||
<source>Print...</source>
|
||||
<translation>Skriv ut...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="262"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="224"/>
|
||||
<source>Export to PDF...</source>
|
||||
<translation>Exportera till PDF...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="930"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="878"/>
|
||||
<source>Waypoints</source>
|
||||
<translation>Vägpunkter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="622"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="584"/>
|
||||
<source>Previous file</source>
|
||||
<translation>Föregående fil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="349"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="311"/>
|
||||
<source>Route waypoints</source>
|
||||
<translation>Ruttvägpunkter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="624"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="586"/>
|
||||
<source>First file</source>
|
||||
<translation>Första filen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="626"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="588"/>
|
||||
<source>Last file</source>
|
||||
<translation>Sista filen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="670"/>
|
||||
<source>The expected structure is one map/atlas in a separate subdirectory. Supported map formats are OziExplorer maps and TrekBuddy maps/atlases (tared and non-tared).</source>
|
||||
<translation>Den förväntade strukturen är en karta/atlas i en separat undermapp. Kartformat som stöds är OziExplorer kartor och TrekBuddy-kartor/-kartsamlingar (tarerade och icke tarerade).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="675"/>
|
||||
<source>To make GPXSee load a POI file automatically on startup, add the file to the following directory:</source>
|
||||
<translation>För att GPXSee skall läsa in en POI-fil automatiskt vid programstart, läggs filen i följande mapp:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="764"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="712"/>
|
||||
<source>Error loading data file:</source>
|
||||
<translation>Fel vid inläsning av datafil:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="767"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="792"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="715"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="740"/>
|
||||
<source>Line: %1</source>
|
||||
<translation>Rad: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="789"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="737"/>
|
||||
<source>Error loading POI file:</source>
|
||||
<translation>Fel vid inläsning av POI-fil:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="922"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="870"/>
|
||||
<source>Name</source>
|
||||
<translation>Namn</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="926"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="874"/>
|
||||
<source>Tracks</source>
|
||||
<translation>Spår</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="246"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="596"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="208"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="558"/>
|
||||
<source>About GPXSee</source>
|
||||
<translation>Om GPXSee</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="534"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="496"/>
|
||||
<source>Navigation</source>
|
||||
<translation>Navigation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="674"/>
|
||||
<source>POIs</source>
|
||||
<translation>POI:er</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="364"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="946"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="326"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="894"/>
|
||||
<source>Distance</source>
|
||||
<translation>Avstånd</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="370"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="498"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="948"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="332"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="460"/>
|
||||
<location filename="../src/GUI/gui.cpp" line="896"/>
|
||||
<source>Time</source>
|
||||
<translation>Tid</translation>
|
||||
</message>
|
||||
@ -847,14 +837,29 @@
|
||||
<context>
|
||||
<name>MapList</name>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="141"/>
|
||||
<source>Map files (*.map *.tba *.tar)</source>
|
||||
<translation>Kartfiler (*.map *.tba *.tar)</translation>
|
||||
<location filename="../src/map/maplist.cpp" line="128"/>
|
||||
<source>Supported files</source>
|
||||
<translation>Filer som stöds</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="142"/>
|
||||
<source>URL list files (*.txt)</source>
|
||||
<translation>URL-listfiler (*.txt)</translation>
|
||||
<location filename="../src/map/maplist.cpp" line="129"/>
|
||||
<source>OziExplorer maps</source>
|
||||
<translation>OziExplorer-kartor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="130"/>
|
||||
<source>TrekBuddy maps/atlases</source>
|
||||
<translation>TrekBuddy-kartor/-atlaser</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="131"/>
|
||||
<source>GeoTIFF images</source>
|
||||
<translation>GeoTIFF-bilder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/map/maplist.cpp" line="132"/>
|
||||
<source>Online map sources</source>
|
||||
<translation>Online-kartkällor</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -29,7 +29,7 @@
|
||||
<string>application/gpx+xml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>gpx.icns</string>
|
||||
<string>icons/gpx.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>GPS Exchange Format</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@ -45,7 +45,7 @@
|
||||
<string>application/tcx+xml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>tcx.icns</string>
|
||||
<string>icons/tcx.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Training Center XML</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@ -61,7 +61,7 @@
|
||||
<string>application/vnd.google-earth.kml+xml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>kml.icns</string>
|
||||
<string>icons/kml.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Keyhole Markup Language</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@ -77,7 +77,7 @@
|
||||
<string>application/vnd.ant.fit</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>fit.icns</string>
|
||||
<string>icons/fit.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Flexible and Interoperable Data Transfer</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@ -93,7 +93,7 @@
|
||||
<string>application/vnd.fai.igc</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>igc.icns</string>
|
||||
<string>icons/igc.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Flight Recorder Data Format</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@ -109,7 +109,7 @@
|
||||
<string>application/vnd.nmea.nmea</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>nmea.icns</string>
|
||||
<string>icons/nmea.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>NMEA 0183 data</string>
|
||||
<key>CFBundleTypeRole</key>
|
19
pkg/csv/ellipsoids.csv
Normal file
19
pkg/csv/ellipsoids.csv
Normal file
@ -0,0 +1,19 @@
|
||||
Airy 1830,7001,6377563.396,299.3249646
|
||||
Modified Airy,7002,6377340.189,299.3249646
|
||||
Australian National,7003,6378160.0,298.25
|
||||
Bessel 1841,7004,6377397.155,299.1528128
|
||||
Bessel 1841 (Norway),7005,6377492.0176,299.1528
|
||||
Clarke 1866,7008,6378206.4,294.9786982
|
||||
Clarke 1880 (Palestine),7010,6378300.789,293.466
|
||||
Clarke 1880 (IGN),7011,6378249.2,293.466021
|
||||
Clarke 1880,7012,6378249.145,293.465
|
||||
Everest 1830 (1937 Adjustment),7015,6377276.345,300.8017
|
||||
Everest 1830 Modified,7018,6377304.063,300.8017
|
||||
GRS 80,7019,6378137.0,298.257222101
|
||||
Helmert 1906,7020,6378200.0,298.3
|
||||
International 1924,7022,6378388.0,297.0
|
||||
Krassovsky 1940,7024,6378245.0,298.3
|
||||
South American 1969,7036,6378160.0,298.25
|
||||
WGS 72,7043,6378135.0,298.26
|
||||
Bessel 1841 (Namibia),7046,6377483.865,299.1528128
|
||||
Hough 1960,7053,6378270.0,297.0
|
|
121
pkg/csv/gcs.csv
Normal file
121
pkg/csv/gcs.csv
Normal file
@ -0,0 +1,121 @@
|
||||
Adindan,4201,6201,9122,7012,8901,9603,-162,-12,206
|
||||
Afgooye,4205,6205,9122,7024,8901,9603,-43,-163,45
|
||||
Ain el Abd 1970,4204,6204,9122,7022,8901,9603,-150,-251,-2
|
||||
Anna 1 Astro 1965,4708,6708,9122,7003,8901,9603,-491,-22,435
|
||||
Arc 1950,4209,6209,9122,7012,8901,9603,-143,-90,-294
|
||||
Arc 1960,4210,6210,9122,7012,8901,9603,-160,-8,-300
|
||||
Ascension Island 1958,4712,6712,9122,7022,8901,9603,-207,107,52
|
||||
Astro B4 Sorol Atoll,4707,6707,9122,7022,8901,9603,114,-116,-333
|
||||
Astro Beacon 1945,4709,6709,9122,7022,8901,9603,145,75,-272
|
||||
Astro DOS 71/4,4710,6710,9122,7022,8901,9603,-320,550,-494
|
||||
Astronomic Stn 1952,4711,6711,9122,7022,8901,9603,124,-234,-25
|
||||
Australian Geodetic 1966,4202,6202,9122,7003,8901,9603,-133,-48,148
|
||||
Australian Geodetic 1984,4203,6203,9122,7003,8901,9603,-134,-48,149
|
||||
Australian Geocentric 1994 (GDA94),4283,6283,9122,7019,8901,9603,0,0,0
|
||||
Austrian,4312,6312,9122,7004,8901,9603,594,84,471
|
||||
Bellevue (IGN),4714,6714,9122,7022,8901,9603,-127,-769,472
|
||||
Bermuda 1957,4216,6216,9122,7008,8901,9603,-73,213,296
|
||||
Bogota Observatory,4218,6218,9122,7022,8901,9603,307,304,-318
|
||||
Campo Inchauspe,4221,6221,9122,7022,8901,9603,-148,136,90
|
||||
Canton Astro 1966,4716,6716,9122,7022,8901,9603,298,-304,-375
|
||||
Cape,4222,6222,9122,7012,8901,9603,-136,-108,-292
|
||||
Cape Canaveral,4717,6717,9122,7008,8901,9603,-2,150,181
|
||||
Carthage,4223,6223,9122,7012,8901,9603,-263,6,431
|
||||
CH-1903,4149,6149,9122,7004,8901,9603,674,15,405
|
||||
Chatham 1971,4672,6672,9122,7022,8901,9603,175,-38,113
|
||||
Chua Astro,4224,6224,9122,7022,8901,9603,-134,229,-29
|
||||
Corrego Alegre,4225,6225,9122,7022,8901,9603,-206,172,-6
|
||||
Djakarta (Batavia),4211,6211,9122,7004,8901,9603,-377,681,-50
|
||||
DOS 1968,,,9122,7022,8901,9603,230,-199,-752
|
||||
Easter Island 1967,4719,6719,9122,7022,8901,9603,211,147,111
|
||||
Egypt,4199,6199,9122,7022,8901,9603,-130,-117,-151
|
||||
European 1950,4230,6230,9122,7022,8901,9603,-87,-98,-121
|
||||
European 1950 (Mean France),,,9122,7022,8901,9603,-87,-96,-120
|
||||
European 1950 (Spain and Portugal),,,9122,7022,8901,9603,-84,-107,-120
|
||||
European 1979,4668,6668,9122,7022,8901,9603,-86,-98,-119
|
||||
Finland Hayford,4123,6123,9122,7022,8901,9603,-78,-231,-97
|
||||
Gandajika Base,4233,6233,9122,7022,8901,9603,-133,-321,50
|
||||
Geodetic Datum 1949,4272,6272,9122,7022,8901,9603,84,-22,209
|
||||
GGRS 87,4121,6121,9122,7019,8901,9603,-199.87,74.79,246.62
|
||||
Guam 1963,4675,6675,9122,7008,8901,9603,-100,-248,259
|
||||
GUX 1 Astro,4718,6718,9122,7022,8901,9603,252,-209,-751
|
||||
Hartebeeshoek94,4148,6148,9122,7030,8901,9603,0,0,0
|
||||
Hermannskogel,3906,1031,9122,7004,8901,9603,653,-212,449
|
||||
Hjorsey 1955,4658,6658,9122,7022,8901,9603,-73,46,-86
|
||||
Hong Kong 1963,4739,6739,9122,7022,8901,9603,-156,-271,-189
|
||||
Hu-Tzu-Shan,4236,6236,9122,7022,8901,9603,-634,-549,-201
|
||||
Indian Bangladesh,4682,6682,9122,7015,8901,9603,289,734,257
|
||||
Indian Thailand,4240,6240,9122,7015,8901,9603,214,836,303
|
||||
Israeli,4281,6281,9122,7010,8901,9603,-235,-85,264
|
||||
Ireland 1965,4299,6299,9122,7002,8901,9603,506,-122,611
|
||||
ISTS 073 Astro 1969,4724,6724,9122,7022,8901,9603,208,-435,-229
|
||||
Johnston Island,4725,6725,9122,7022,8901,9603,191,-77,-204
|
||||
Kandawala,4244,6244,9122,7015,8901,9603,-97,787,86
|
||||
Kerguelen Island,4698,6698,9122,7022,8901,9603,145,-187,103
|
||||
Kertau 1948,4245,6245,9122,7018,8901,9603,-11,851,5
|
||||
L.C. 5 Astro,4726,6726,9122,7008,8901,9603,42,124,147
|
||||
Liberia 1964,4251,6251,9122,7012,8901,9603,-90,40,88
|
||||
Luzon Mindanao,,,9122,7008,8901,9603,-133,-79,-72
|
||||
Luzon Philippines,4253,6253,9122,7008,8901,9603,-133,-77,-51
|
||||
Mahe 1971,4256,6256,9122,7012,8901,9603,41,-220,-134
|
||||
Marco Astro,4616,6616,9122,7022,8901,9603,-289,-124,60
|
||||
Massawa,4262,6262,9122,7004,8901,9603,639,405,60
|
||||
Merchich,4261,6261,9122,7012,8901,9603,31,146,47
|
||||
Midway Astro 1961,4727,6727,9122,7022,8901,9603,912,-58,1227
|
||||
Minna,4263,6263,9122,7012,8901,9603,-92,-93,122
|
||||
NAD27 Alaska,,,9122,7008,8901,9603,-5,135,172
|
||||
NAD27 Bahamas,,,9122,7008,8901,9603,-4,154,178
|
||||
NAD27 Canada,,,9122,7008,8901,9603,-10,158,187
|
||||
NAD27 Canal Zone,,,9122,7008,8901,9603,0,125,201
|
||||
NAD27 Caribbean,,,9122,7008,8901,9603,-3,142,183
|
||||
NAD27 Central,,,9122,7008,8901,9603,0,125,194
|
||||
NAD27 CONUS,4267,6267,9122,7008,8901,9603,-8,160,176
|
||||
NAD27 Cuba,,,9122,7008,8901,9603,-9,152,178
|
||||
NAD27 Greenland,,,9122,7008,8901,9603,11,114,195
|
||||
NAD27 Mexico,,,9122,7008,8901,9603,-12,130,190
|
||||
NAD27 San Salvador,,,9122,7008,8901,9603,1,140,165
|
||||
NAD83,4269,6269,9122,7019,8901,9603,0,0,0
|
||||
Nahrwn Masirah Ilnd,,,9122,7012,8901,9603,-247,-148,369
|
||||
Nahrwn Saudi Arbia,,,9122,7012,8901,9603,-231,-196,482
|
||||
Nahrwn United Arab,4270,6270,9122,7012,8901,9603,-249,-156,381
|
||||
Naparima BWI,4271,6271,9122,7022,8901,9603,-2,374,172
|
||||
NGO1948,4273,6273,9122,7005,8901,9603,315,-217,528
|
||||
NTF France,4275,6275,9122,7011,8901,9603,-168,-60,320
|
||||
Norsk,4817,6817,9122,7005,8913,9603,278,93,474
|
||||
NZGD1949,4272,6272,9122,7022,8901,9603,84,-22,209
|
||||
NZGD2000,4167,6167,9122,7030,8901,9603,0,0,0
|
||||
Observatorio 1966,4182,6182,9122,7022,8901,9603,-425,-169,81
|
||||
Old Egyptian,4229,6229,9122,7020,8901,9603,-130,110,-13
|
||||
Old Hawaiian,4135,6135,9122,7008,8901,9603,61,-285,-181
|
||||
Oman,4232,6232,9122,7012,8901,9603,-346,-1,224
|
||||
Ord Srvy Grt Britn,4277,6277,9122,7001,8901,9603,375,-111,431
|
||||
Pico De Las Nieves,4728,6728,9122,7022,8901,9603,-307,-92,127
|
||||
Pitcairn Astro 1967,4729,6729,9122,7022,8901,9603,185,165,42
|
||||
Potsdam Rauenberg DHDN,4314,6314,9122,7004,8901,9603,606,23,413
|
||||
Prov So Amrican 1956,4248,6248,9122,7022,8901,9603,-288,175,-376
|
||||
Prov So Chilean 1963,4254,6254,9122,7022,8901,9603,16,196,93
|
||||
Puerto Rico,4139,6139,9122,7008,8901,9603,11,72,-101
|
||||
Pulkovo 1942 (1),4284,6284,9122,7024,8901,9603,28,-130,-95
|
||||
Pulkovo 1942 (2),,,9122,7024,8901,9603,28,-130,-95
|
||||
Qatar National,4285,6285,9122,7022,8901,9603,-128,-283,22
|
||||
Qornoq,4287,6287,9108,7022,8901,9603,164,138,-189
|
||||
Reunion,4626,6626,9122,7022,8901,9603,94,-948,-1262
|
||||
Rijksdriehoeksmeting,4289,6289,9122,7004,8901,9603,593,26,478
|
||||
Rome 1940,4806,6806,9122,7022,8906,9603,-225,-65,9
|
||||
RT 90,4124,6124,9122,7004,8901,9603,498,-36,568
|
||||
S42,4179,6179,9122,7024,8901,9603,28,-121,-77
|
||||
Santo (DOS),4730,6730,9122,7022,8901,9603,170,42,84
|
||||
Sao Braz,4184,6184,9122,7022,8901,9603,-203,141,53
|
||||
Sapper Hill 1943,4292,6292,9122,7022,8901,9603,-355,16,74
|
||||
Schwarzeck,4293,6293,9122,7046,8901,9603,616,97,-251
|
||||
South American 1969,4291,6291,9108,7036,8901,9603,-57,1,-41
|
||||
Southeast Base,4615,6615,9122,7022,8901,9603,-499,-249,314
|
||||
Southwest Base,4183,6183,9122,7022,8901,9603,-104,167,-38
|
||||
Timbalai 1948,4298,6298,9122,7015,8901,9603,-689,691,-46
|
||||
Tokyo,4301,6301,9122,7004,8901,9603,-128,481,664
|
||||
Tristan Astro 1968,4734,6734,9122,7022,8901,9603,-632,438,-609
|
||||
Viti Levu 1916,4731,6731,9122,7012,8901,9603,51,391,-36
|
||||
Wake-Eniwetok 1960,4732,6732,9122,7053,8901,9603,101,52,-39
|
||||
WGS 72,4322,6322,9122,7043,8901,9603,0,0,5
|
||||
Yacare,4309,6309,9122,7022,8901,9603,-155,171,37
|
||||
Zanderij,4311,6311,9122,7022,8901,9603,-265,120,-358
|
|
1626
pkg/csv/pcs.csv
Normal file
1626
pkg/csv/pcs.csv
Normal file
File diff suppressed because it is too large
Load Diff
123
pkg/datums.csv
123
pkg/datums.csv
@ -1,123 +0,0 @@
|
||||
Adindan,4201,5,-162,-12,206
|
||||
Afgooye,4205,15,-43,-163,45
|
||||
Ain el Abd 1970,4204,14,-150,-251,-2
|
||||
Anna 1 Astro 1965,4708,2,-491,-22,435
|
||||
Arc 1950,4209,5,-143,-90,-294
|
||||
Arc 1960,4210,5,-160,-8,-300
|
||||
Ascension Island 1958,4712,14,-207,107,52
|
||||
Astro B4 Sorol Atoll,4707,14,114,-116,-333
|
||||
Astro Beacon 1945,4709,14,145,75,-272
|
||||
Astro DOS 71/4,4710,14,-320,550,-494
|
||||
Astronomic Stn 1952,4711,14,124,-234,-25
|
||||
Australian Geodetic 1966,4202,2,-133,-48,148
|
||||
Australian Geodetic 1984,4203,2,-134,-48,149
|
||||
Australian Geocentric 1994 (GDA94),4283,11,0,0,0
|
||||
Austrian,4312,3,594,84,471
|
||||
Bellevue (IGN),4714,14,-127,-769,472
|
||||
Bermuda 1957,4216,4,-73,213,296
|
||||
Bogota Observatory,4218,14,307,304,-318
|
||||
Campo Inchauspe,4221,14,-148,136,90
|
||||
Canton Astro 1966,4716,14,298,-304,-375
|
||||
Cape,4222,5,-136,-108,-292
|
||||
Cape Canaveral,4717,4,-2,150,181
|
||||
Carthage,4223,5,-263,6,431
|
||||
CH-1903,4149,3,674,15,405
|
||||
Chatham 1971,4672,14,175,-38,113
|
||||
Chua Astro,4224,14,-134,229,-29
|
||||
Corrego Alegre,4225,14,-206,172,-6
|
||||
Djakarta (Batavia),4211,3,-377,681,-50
|
||||
DOS 1968,,14,230,-199,-752
|
||||
Easter Island 1967,4719,14,211,147,111
|
||||
Egypt,,14,-130,-117,-151
|
||||
European 1950,4230,14,-87,-98,-121
|
||||
European 1950 (Mean France),,14,-87,-96,-120
|
||||
European 1950 (Spain and Portugal),,14,-84,-107,-120
|
||||
European 1979,4668,14,-86,-98,-119
|
||||
Finland Hayford,4123,14,-78,-231,-97
|
||||
Gandajika Base,4233,14,-133,-321,50
|
||||
Geodetic Datum 1949,4272,14,84,-22,209
|
||||
GGRS 87,4121,11,-199.87,74.79,246.62
|
||||
Guam 1963,4675,4,-100,-248,259
|
||||
GUX 1 Astro,4718,14,252,-209,-751
|
||||
Hartebeeshoek94,4148,20,0,0,0
|
||||
Hermannskogel,3906,3,653,-212,449
|
||||
Hjorsey 1955,4658,14,-73,46,-86
|
||||
Hong Kong 1963,4739,14,-156,-271,-189
|
||||
Hu-Tzu-Shan,4236,14,-634,-549,-201
|
||||
Indian Bangladesh,4682,6,289,734,257
|
||||
Indian Thailand,4240,6,214,836,303
|
||||
Israeli,4281,23,-235,-85,264
|
||||
Ireland 1965,4299,1,506,-122,611
|
||||
ISTS 073 Astro 1969,4724,14,208,-435,-229
|
||||
Johnston Island,4725,14,191,-77,-204
|
||||
Kandawala,4244,6,-97,787,86
|
||||
Kerguelen Island,4698,14,145,-187,103
|
||||
Kertau 1948,4245,7,-11,851,5
|
||||
L.C. 5 Astro,4726,4,42,124,147
|
||||
Liberia 1964,4251,5,-90,40,88
|
||||
Luzon Mindanao,,4,-133,-79,-72
|
||||
Luzon Philippines,4253,4,-133,-77,-51
|
||||
Mahe 1971,4256,5,41,-220,-134
|
||||
Marco Astro,4616,14,-289,-124,60
|
||||
Massawa,4262,3,639,405,60
|
||||
Merchich,4261,5,31,146,47
|
||||
Midway Astro 1961,4727,14,912,-58,1227
|
||||
Minna,4263,5,-92,-93,122
|
||||
NAD27 Alaska,,4,-5,135,172
|
||||
NAD27 Bahamas,,4,-4,154,178
|
||||
NAD27 Canada,,4,-10,158,187
|
||||
NAD27 Canal Zone,,4,0,125,201
|
||||
NAD27 Caribbean,,4,-7,152,178
|
||||
NAD27 Central,,4,0,125,194
|
||||
NAD27 CONUS,,4,-8,160,176
|
||||
NAD27 Cuba,,4,-9,152,178
|
||||
NAD27 Greenland,,4,11,114,195
|
||||
NAD27 Mexico,,4,-12,130,190
|
||||
NAD27 San Salvador,,4,1,140,165
|
||||
NAD83,4269,11,0,0,0
|
||||
Nahrwn Masirah Ilnd,,5,-247,-148,369
|
||||
Nahrwn Saudi Arbia,,5,-231,-196,482
|
||||
Nahrwn United Arab,,5,-249,-156,381
|
||||
Naparima BWI,4271,14,-2,374,172
|
||||
NGO1948,4273,27,315,-217,528
|
||||
NTF France,4275,24,-168,-60,320
|
||||
Norsk,4817,27,278,93,474
|
||||
NZGD1949,4272,14,84,-22,209
|
||||
NZGD2000,4167,20,0,0,0
|
||||
Observatorio 1966,4182,14,-425,-169,81
|
||||
Old Egyptian,4229,12,-130,110,-13
|
||||
Old Hawaiian,4135,4,61,-285,-181
|
||||
Oman,4232,5,-346,-1,224
|
||||
Ord Srvy Grt Britn,4277,0,375,-111,431
|
||||
Pico De Las Nieves,4728,14,-307,-92,127
|
||||
Pitcairn Astro 1967,4729,14,185,165,42
|
||||
Potsdam Rauenberg DHDN,4314,3,606,23,413
|
||||
Prov So Amrican 1956,4248,14,-288,175,-376
|
||||
Prov So Chilean 1963,4254,14,16,196,93
|
||||
Puerto Rico,4139,4,11,72,-101
|
||||
Pulkovo 1942 (1),4284,15,28,-130,-95
|
||||
Pulkovo 1942 (2),4284,15,28,-130,-95
|
||||
Qatar National,4285,14,-128,-283,22
|
||||
Qornoq,4287,14,164,138,-189
|
||||
Reunion,4626,14,94,-948,-1262
|
||||
Rijksdriehoeksmeting,4289,3,593,26,478
|
||||
Rome 1940,4806,14,-225,-65,9
|
||||
RT 90,4124,3,498,-36,568
|
||||
S42,4179,15,28,-121,-77
|
||||
Santo (DOS),4730,14,170,42,84
|
||||
Sao Braz,4184,14,-203,141,53
|
||||
Sapper Hill 1943,4292,14,-355,16,74
|
||||
Schwarzeck,4293,21,616,97,-251
|
||||
South American 1969,4291,16,-57,1,-41
|
||||
South Asia,,8,7,-10,-26
|
||||
Southeast Base,4615,14,-499,-249,314
|
||||
Southwest Base,4183,14,-104,167,-38
|
||||
Timbalai 1948,4298,6,-689,691,-46
|
||||
Tokyo,4301,3,-128,481,664
|
||||
Tristan Astro 1968,4734,14,-632,438,-609
|
||||
Viti Levu 1916,4731,5,51,391,-36
|
||||
Wake-Eniwetok 1960,4732,13,101,52,-39
|
||||
WGS 72,4322,19,0,0,5
|
||||
WGS 84,4326,20,0,0,0
|
||||
Yacare,4309,14,-155,171,37
|
||||
Zanderij,4311,14,-265,120,-358
|
|
@ -1,30 +0,0 @@
|
||||
0,Airy 1830,6377563.396,299.3249646
|
||||
1,Modified Airy,6377340.189,299.3249646
|
||||
2,Australian National,6378160.0,298.25
|
||||
3,Bessel 1841,6377397.155,299.1528128
|
||||
4,Clarke 1866,6378206.4,294.9786982
|
||||
5,Clarke 1880,6378249.145,293.465
|
||||
6,Everest (India 1830),6377276.345,300.8017
|
||||
7,Everest (1948),6377304.063,300.8017
|
||||
8,Modified Fischer 1960,6378155.0,298.3
|
||||
9,Everest (Pakistan),6377309.613,300.8017
|
||||
10,Indonesian 1974,6378160.0,298.247
|
||||
11,GRS 80,6378137.0,298.257222101
|
||||
12,Helmert 1906,6378200.0,298.3
|
||||
13,Hough 1960,6378270.0,297.0
|
||||
14,International 1924,6378388.0,297.0
|
||||
15,Krassovsky 1940,6378245.0,298.3
|
||||
16,South American 1969,6378160.0,298.25
|
||||
17,Everest (Malaysia 1969),6377295.664,300.8017
|
||||
18,Everest (Sabah Sarawak),6377298.556,300.8017
|
||||
19,WGS 72,6378135.0,298.26
|
||||
20,WGS 84,6378137.0,298.257223563
|
||||
21,Bessel 1841 (Namibia),6377483.865,299.1528128
|
||||
22,Everest (India 1956),6377301.243,300.8017
|
||||
23,Clarke 1880 Palestine,6378300.789,293.466
|
||||
24,Clarke 1880 IGN,6378249.2,293.466021
|
||||
25,Hayford 1909,6378388.0,296.959263
|
||||
26,Clarke 1858,6378350.87,294.26
|
||||
27,Bessel 1841 (Norway),6377492.0176,299.1528
|
||||
28,Plessis 1817 (France),6376523.0,308.6409971
|
||||
29,Hayford 1924,6378388.0,297.0
|
|
12
pkg/gpxsee.desktop
Normal file
12
pkg/gpxsee.desktop
Normal file
@ -0,0 +1,12 @@
|
||||
[Desktop Entry]
|
||||
Name=GPXSee
|
||||
Comment=GPS log file viewer and analyzer
|
||||
Comment[cz]=Prohlížeč a analyzátor GPS logů
|
||||
Comment[fi]=Ohjelma GPS-lokien katseluun ja analysointiin
|
||||
Comment[ru]=Программа для просмотра и анализа GPS логов
|
||||
Exec=gpxsee %F
|
||||
Icon=gpxsee
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Graphics;Viewer;Maps;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;
|
@ -5,7 +5,7 @@
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "4.19"
|
||||
!define VERSION "5.0"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}.exe"
|
||||
@ -83,9 +83,8 @@ Section "GPXSee" SEC_APP
|
||||
|
||||
; Put the files there
|
||||
File "gpxsee.exe"
|
||||
File "maps.txt"
|
||||
File "ellipsoids.csv"
|
||||
File "datums.csv"
|
||||
File /r "maps"
|
||||
File /r "csv"
|
||||
|
||||
; Create start menu entry and add links
|
||||
SetShellVarContext all
|
||||
@ -195,6 +194,38 @@ Section "ANGLE" SEC_ANGLE
|
||||
|
||||
SectionEnd
|
||||
|
||||
SectionGroup "Localization" SEC_LOCALIZATION
|
||||
Section "Czech"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_cs.qm translations\gpxsee_cs.qm
|
||||
File /oname=translations\qt_cs.qm translations\qt_cs.qm
|
||||
SectionEnd
|
||||
Section "Finnish"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_fi.qm translations\gpxsee_fi.qm
|
||||
File /oname=translations\qt_fi.qm translations\qt_fi.qm
|
||||
SectionEnd
|
||||
Section "French"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_fr.qm translations\gpxsee_fr.qm
|
||||
File /oname=translations\qt_fr.qm translations\qt_fr.qm
|
||||
SectionEnd
|
||||
Section "German"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_de.qm translations\gpxsee_de.qm
|
||||
File /oname=translations\qt_de.qm translations\qt_de.qm
|
||||
SectionEnd
|
||||
Section "Russian"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_ru.qm translations\gpxsee_ru.qm
|
||||
File /oname=translations\qt_ru.qm translations\qt_ru.qm
|
||||
SectionEnd
|
||||
Section "Swedish"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_sv.qm translations\gpxsee_sv.qm
|
||||
SectionEnd
|
||||
SectionGroupEnd
|
||||
|
||||
;--------------------------------
|
||||
|
||||
; Uninstaller
|
||||
@ -246,6 +277,8 @@ LangString DESC_ANGLE ${LANG_ENGLISH} \
|
||||
"ANGLE (OpenGL via Direct3D). Enables OpenGL on systems without native OpenGL drivers."
|
||||
LangString DESC_APP ${LANG_ENGLISH} \
|
||||
"GPXSee application"
|
||||
LangString DESC_LOCALIZATION ${LANG_ENGLISH} \
|
||||
"Localization"
|
||||
|
||||
;Assign language strings to sections
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
@ -254,4 +287,5 @@ LangString DESC_APP ${LANG_ENGLISH} \
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_ANGLE} $(DESC_ANGLE)
|
||||
!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
|
||||
|
46
pkg/gpxsee.xml
Normal file
46
pkg/gpxsee.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
|
||||
<mime-type type="application/gpx+xml">
|
||||
<comment>GPS Exchange Format</comment>
|
||||
<sub-class-of type="application/xml"/>
|
||||
<generic-icon name="application-xml"/>
|
||||
<glob pattern="*.gpx"/>
|
||||
</mime-type>
|
||||
|
||||
<mime-type type="application/tcx+xml">
|
||||
<comment>Training Center XML</comment>
|
||||
<sub-class-of type="application/xml"/>
|
||||
<generic-icon name="application-xml"/>
|
||||
<glob pattern="*.tcx"/>
|
||||
</mime-type>
|
||||
|
||||
<mime-type type="application/kml+xml">
|
||||
<comment>Keyhole Markup Language</comment>
|
||||
<sub-class-of type="application/xml"/>
|
||||
<generic-icon name="application-xml"/>
|
||||
<glob pattern="*.kml"/>
|
||||
</mime-type>
|
||||
|
||||
<mime-type type="application/vnd.ant.fit">
|
||||
<comment>Flexible and Interoperable Data Transfer</comment>
|
||||
<sub-class-of type="application/octet-stream"/>
|
||||
<generic-icon name="application-octet-stream"/>
|
||||
<glob pattern="*.fit"/>
|
||||
</mime-type>
|
||||
|
||||
<mime-type type="application/vnd.fai.igc">
|
||||
<comment>Flight Recorder Data Format</comment>
|
||||
<sub-class-of type="text/plain"/>
|
||||
<generic-icon name="text-plain"/>
|
||||
<glob pattern="*.igc"/>
|
||||
</mime-type>
|
||||
|
||||
<mime-type type="application/vnd.nmea.nmea">
|
||||
<comment>NMEA 0183 data</comment>
|
||||
<sub-class-of type="text/plain"/>
|
||||
<generic-icon name="text-plain"/>
|
||||
<glob pattern="*.nmea"/>
|
||||
</mime-type>
|
||||
|
||||
</mime-info>
|
@ -5,7 +5,7 @@
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "4.19"
|
||||
!define VERSION "5.0"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||
@ -90,9 +90,8 @@ Section "GPXSee" SEC_APP
|
||||
|
||||
; Put the files there
|
||||
File "gpxsee.exe"
|
||||
File "maps.txt"
|
||||
File "ellipsoids.csv"
|
||||
File "datums.csv"
|
||||
File /r "maps"
|
||||
File /r "csv"
|
||||
|
||||
; Create start menu entry and add links
|
||||
SetShellVarContext all
|
||||
@ -197,6 +196,38 @@ Section "ANGLE" SEC_ANGLE
|
||||
|
||||
SectionEnd
|
||||
|
||||
SectionGroup "Localization" SEC_LOCALIZATION
|
||||
Section "Czech"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_cs.qm translations\gpxsee_cs.qm
|
||||
File /oname=translations\qt_cs.qm translations\qt_cs.qm
|
||||
SectionEnd
|
||||
Section "Finnish"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_fi.qm translations\gpxsee_fi.qm
|
||||
File /oname=translations\qt_fi.qm translations\qt_fi.qm
|
||||
SectionEnd
|
||||
Section "French"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_fr.qm translations\gpxsee_fr.qm
|
||||
File /oname=translations\qt_fr.qm translations\qt_fr.qm
|
||||
SectionEnd
|
||||
Section "German"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_de.qm translations\gpxsee_de.qm
|
||||
File /oname=translations\qt_de.qm translations\qt_de.qm
|
||||
SectionEnd
|
||||
Section "Russian"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_ru.qm translations\gpxsee_ru.qm
|
||||
File /oname=translations\qt_ru.qm translations\qt_ru.qm
|
||||
SectionEnd
|
||||
Section "Swedish"
|
||||
CreateDirectory "$INSTDIR\translations"
|
||||
File /oname=translations\gpxsee_sv.qm translations\gpxsee_sv.qm
|
||||
SectionEnd
|
||||
SectionGroupEnd
|
||||
|
||||
;--------------------------------
|
||||
|
||||
; Uninstaller
|
||||
@ -249,6 +280,8 @@ LangString DESC_ANGLE ${LANG_ENGLISH} \
|
||||
"ANGLE (OpenGL via Direct3D). Enables OpenGL on systems without native OpenGL drivers."
|
||||
LangString DESC_APP ${LANG_ENGLISH} \
|
||||
"GPXSee application"
|
||||
LangString DESC_LOCALIZATION ${LANG_ENGLISH} \
|
||||
"Localization"
|
||||
|
||||
;Assign language strings to sections
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
@ -257,4 +290,5 @@ LangString DESC_APP ${LANG_ENGLISH} \
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_ANGLE} $(DESC_ANGLE)
|
||||
!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
|
||||
|
@ -1,5 +0,0 @@
|
||||
Open Topo Map https://a.tile.opentopomap.org/$z/$x/$y.png 17
|
||||
4UMaps http://4umaps.eu/$z/$x/$y.png 15
|
||||
Open Street Map http://tile.openstreetmap.org/$z/$x/$y.png 19
|
||||
USGS Topo https://navigator.er.usgs.gov/tiles/tcr.cgi/$z/$x/$y.png 15
|
||||
USGS Imagery https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y 15
|
7
pkg/maps/4UMaps.xml
Normal file
7
pkg/maps/4UMaps.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<name>4UMaps</name>
|
||||
<url>http://4umaps.eu/$z/$x/$y.png</url>
|
||||
<zoom min="2" max="15"/>
|
||||
<bounds bottom="-65"/>
|
||||
</map>
|
5
pkg/maps/OpenStreetMap.xml
Normal file
5
pkg/maps/OpenStreetMap.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<name>Open Street Map</name>
|
||||
<url>http://tile.openstreetmap.org/$z/$x/$y.png</url>
|
||||
</map>
|
6
pkg/maps/OpenTopoMap.xml
Normal file
6
pkg/maps/OpenTopoMap.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<name>Open Topo Map</name>
|
||||
<url>https://a.tile.opentopomap.org/$z/$x/$y.png</url>
|
||||
<zoom max="17"/>
|
||||
</map>
|
7
pkg/maps/USGS-imagery.xml
Normal file
7
pkg/maps/USGS-imagery.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<name>USGS Imagery</name>
|
||||
<url>https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y</url>
|
||||
<zoom min="2" max="15"/>
|
||||
<bounds bottom="0" top="74"/>
|
||||
</map>
|
6
pkg/maps/USGS-topo.xml
Normal file
6
pkg/maps/USGS-topo.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<name>USGS Topo</name>
|
||||
<url>https://navigator.er.usgs.gov/tiles/tcr.cgi/$z/$x/$y.png</url>
|
||||
<zoom min="2" max="15"/>
|
||||
</map>
|
@ -7,7 +7,8 @@
|
||||
#include "map/onlinemap.h"
|
||||
#include "map/downloader.h"
|
||||
#include "map/ellipsoid.h"
|
||||
#include "map/datum.h"
|
||||
#include "map/gcs.h"
|
||||
#include "map/pcs.h"
|
||||
#include "opengl.h"
|
||||
#include "gui.h"
|
||||
#include "config.h"
|
||||
@ -18,13 +19,16 @@ App::App(int &argc, char **argv) : QApplication(argc, argv),
|
||||
_argc(argc), _argv(argv)
|
||||
{
|
||||
QTranslator *gpxsee = new QTranslator(this);
|
||||
QString locale = QLocale::system().name();
|
||||
gpxsee->load(QString(":/lang/gpxsee_") + locale);
|
||||
gpxsee->load(QLocale::system(), "gpxsee", "_", TRANSLATIONS_DIR);
|
||||
installTranslator(gpxsee);
|
||||
|
||||
QTranslator *qt = new QTranslator(this);
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MAC)
|
||||
qt->load(QLocale::system(), "qt", "_", TRANSLATIONS_DIR);
|
||||
#else // Q_OS_WINDOWS || Q_OS_MAC
|
||||
qt->load(QLocale::system(), "qt", "_", QLibraryInfo::location(
|
||||
QLibraryInfo::TranslationsPath));
|
||||
#endif // Q_OS_WINDOWS || Q_OS_MAC
|
||||
installTranslator(qt);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
@ -35,6 +39,7 @@ App::App(int &argc, char **argv) : QApplication(argc, argv),
|
||||
OnlineMap::setDownloader(new Downloader(this));
|
||||
OPENGL_SET_SAMPLES(4);
|
||||
loadDatums();
|
||||
loadPCSs();
|
||||
|
||||
_gui = new GUI();
|
||||
}
|
||||
@ -67,7 +72,6 @@ bool App::event(QEvent *event)
|
||||
void App::loadDatums()
|
||||
{
|
||||
QString ef, df;
|
||||
bool ok = false;
|
||||
|
||||
if (QFile::exists(USER_ELLIPSOID_FILE))
|
||||
ef = USER_ELLIPSOID_FILE;
|
||||
@ -76,34 +80,32 @@ void App::loadDatums()
|
||||
else
|
||||
qWarning("No ellipsoids file found.");
|
||||
|
||||
if (QFile::exists(USER_DATUM_FILE))
|
||||
df = USER_DATUM_FILE;
|
||||
else if (QFile::exists(GLOBAL_DATUM_FILE))
|
||||
df = GLOBAL_DATUM_FILE;
|
||||
if (QFile::exists(USER_GCS_FILE))
|
||||
df = USER_GCS_FILE;
|
||||
else if (QFile::exists(GLOBAL_GCS_FILE))
|
||||
df = GLOBAL_GCS_FILE;
|
||||
else
|
||||
qWarning("No datums file found.");
|
||||
|
||||
if (!ef.isNull() && !df.isNull()) {
|
||||
if (!Ellipsoid::loadList(ef)) {
|
||||
if (Ellipsoid::errorLine())
|
||||
qWarning("%s: parse error on line %d: %s", qPrintable(ef),
|
||||
Ellipsoid::errorLine(), qPrintable(Ellipsoid::errorString()));
|
||||
else
|
||||
qWarning("%s: %s", qPrintable(ef), qPrintable(
|
||||
Ellipsoid::errorString()));
|
||||
} else {
|
||||
if (!Datum::loadList(df)) {
|
||||
if (Datum::errorLine())
|
||||
qWarning("%s: parse error on line %d: %s", qPrintable(df),
|
||||
Datum::errorLine(), qPrintable(Datum::errorString()));
|
||||
else
|
||||
qWarning("%s: %s", qPrintable(df), qPrintable(
|
||||
Datum::errorString()));
|
||||
} else
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
Ellipsoid::loadList(ef);
|
||||
GCS::loadList(df);
|
||||
} else
|
||||
qWarning("Maps based on a datum different from WGS84 won't work.");
|
||||
}
|
||||
|
||||
void App::loadPCSs()
|
||||
{
|
||||
QString file;
|
||||
|
||||
if (QFile::exists(USER_PCS_FILE))
|
||||
file = USER_PCS_FILE;
|
||||
else if (QFile::exists(GLOBAL_PCS_FILE))
|
||||
file = GLOBAL_PCS_FILE;
|
||||
else {
|
||||
qWarning("No PCS file found.");
|
||||
return;
|
||||
}
|
||||
|
||||
PCS::loadList(file);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ protected:
|
||||
|
||||
private:
|
||||
void loadDatums();
|
||||
void loadPCSs();
|
||||
|
||||
int &_argc;
|
||||
char **_argv;
|
||||
|
152
src/GUI/gui.cpp
152
src/GUI/gui.cpp
@ -101,69 +101,31 @@ GUI::~GUI()
|
||||
void GUI::loadMaps()
|
||||
{
|
||||
_ml = new MapList(this);
|
||||
|
||||
QString offline, online;
|
||||
|
||||
if (QFile::exists(USER_MAP_FILE))
|
||||
online = USER_MAP_FILE;
|
||||
else if (QFile::exists(GLOBAL_MAP_FILE))
|
||||
online = GLOBAL_MAP_FILE;
|
||||
|
||||
if (!online.isNull() && !_ml->loadFile(online))
|
||||
qWarning("%s: %s", qPrintable(online), qPrintable(_ml->errorString()));
|
||||
|
||||
QString dir;
|
||||
|
||||
if (QFile::exists(USER_MAP_DIR))
|
||||
offline = USER_MAP_DIR;
|
||||
dir = USER_MAP_DIR;
|
||||
else if (QFile::exists(GLOBAL_MAP_DIR))
|
||||
offline = GLOBAL_MAP_DIR;
|
||||
dir = GLOBAL_MAP_DIR;
|
||||
|
||||
if (!offline.isNull()) {
|
||||
QDir md(offline);
|
||||
QFileInfoList ml = md.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
|
||||
for (int i = 0; i < ml.size(); i++) {
|
||||
QDir dir(ml.at(i).absoluteFilePath());
|
||||
QFileInfoList fl = dir.entryInfoList(MapList::filter(), QDir::Files);
|
||||
|
||||
if (fl.isEmpty())
|
||||
qWarning("%s: no map/atlas file found",
|
||||
qPrintable(ml.at(i).absoluteFilePath()));
|
||||
else if (fl.size() > 1)
|
||||
qWarning("%s: ambiguous directory content",
|
||||
qPrintable(ml.at(i).absoluteFilePath()));
|
||||
else
|
||||
if (!_ml->loadFile(fl.first().absoluteFilePath()))
|
||||
qWarning("%s: %s", qPrintable(fl.first().absoluteFilePath()),
|
||||
qPrintable(_ml->errorString()));
|
||||
}
|
||||
}
|
||||
if (!dir.isNull() && !_ml->loadDir(dir))
|
||||
qWarning("%s", qPrintable(_ml->errorString()));
|
||||
|
||||
_map = new EmptyMap(this);
|
||||
}
|
||||
|
||||
void GUI::loadPOIs()
|
||||
{
|
||||
QFileInfoList list;
|
||||
QDir userDir(USER_POI_DIR);
|
||||
QDir globalDir(GLOBAL_POI_DIR);
|
||||
|
||||
_poi = new POI(this);
|
||||
QString dir;
|
||||
|
||||
if (userDir.exists())
|
||||
list = userDir.entryInfoList(QStringList(), QDir::Files);
|
||||
else
|
||||
list = globalDir.entryInfoList(QStringList(), QDir::Files);
|
||||
if (QFile::exists(USER_POI_DIR))
|
||||
dir = USER_POI_DIR;
|
||||
else if (QFile::exists(GLOBAL_POI_DIR))
|
||||
dir = GLOBAL_POI_DIR;
|
||||
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
if (!_poi->loadFile(list.at(i).absoluteFilePath())) {
|
||||
qWarning("Error loading POI file: %s: %s\n",
|
||||
qPrintable(list.at(i).fileName()),
|
||||
qPrintable(_poi->errorString()));
|
||||
if (_poi->errorLine())
|
||||
qWarning("Line: %d\n", _poi->errorLine());
|
||||
}
|
||||
}
|
||||
if (!dir.isNull() && !_poi->loadDir(dir))
|
||||
qWarning("%s", qPrintable(_poi->errorString()));
|
||||
}
|
||||
|
||||
void GUI::createBrowser()
|
||||
@ -238,8 +200,8 @@ void GUI::createActions()
|
||||
addAction(_exitAction);
|
||||
|
||||
// Help & About
|
||||
_dataSourcesAction = new QAction(tr("Data sources"), this);
|
||||
connect(_dataSourcesAction, SIGNAL(triggered()), this, SLOT(dataSources()));
|
||||
_pathsAction = new QAction(tr("Paths"), this);
|
||||
connect(_pathsAction, SIGNAL(triggered()), this, SLOT(paths()));
|
||||
_keysAction = new QAction(tr("Keyboard controls"), this);
|
||||
connect(_keysAction, SIGNAL(triggered()), this, SLOT(keys()));
|
||||
_aboutAction = new QAction(QIcon(QPixmap(APP_ICON)),
|
||||
@ -508,7 +470,7 @@ void GUI::createMenus()
|
||||
settingsMenu->addAction(_openOptionsAction);
|
||||
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("Help"));
|
||||
helpMenu->addAction(_dataSourcesAction);
|
||||
helpMenu->addAction(_pathsAction);
|
||||
helpMenu->addAction(_keysAction);
|
||||
helpMenu->addSeparator();
|
||||
helpMenu->addAction(_aboutAction);
|
||||
@ -644,37 +606,26 @@ void GUI::keys()
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void GUI::dataSources()
|
||||
void GUI::paths()
|
||||
{
|
||||
QMessageBox msgBox(this);
|
||||
|
||||
msgBox.setWindowTitle(tr("Data sources"));
|
||||
msgBox.setText("<h3>" + tr("Data sources") + "</h3>");
|
||||
msgBox.setWindowTitle(tr("Paths"));
|
||||
msgBox.setText("<h3>" + tr("Paths") + "</h3>");
|
||||
msgBox.setInformativeText(
|
||||
"<h4>" + tr("Online maps") + "</h4><p>"
|
||||
+ tr("Online map URLs are read on program startup from the "
|
||||
"following file:")
|
||||
+ "</p><p><code>" + USER_MAP_FILE + "</code></p><p>"
|
||||
+ tr("The file format is one map entry per line, consisting of the map "
|
||||
"name, tiles URL and an optional maximal zoom level delimited by "
|
||||
"a TAB character. The tile X and Y coordinates are replaced with $x "
|
||||
"and $y in the URL and the zoom level is replaced with $z. An example "
|
||||
"map file could look like:")
|
||||
+ "</p><p><code>Map1 http://tile.server.com/map/$z/$x/$y.png 15"
|
||||
"<br/>Map2 http://mapserver.org/map/$z-$x-$y</code></p>"
|
||||
|
||||
+ "<h4>" + tr("Offline maps") + "</h4><p>"
|
||||
+ tr("Offline maps are loaded on program startup from the following "
|
||||
"directory:")
|
||||
+ "</p><p><code>" + USER_MAP_DIR + "</code></p><p>"
|
||||
+ tr("The expected structure is one map/atlas in a separate subdirectory."
|
||||
" Supported map formats are OziExplorer maps and TrekBuddy maps/atlases"
|
||||
" (tared and non-tared).") + "</p>"
|
||||
|
||||
+ "<h4>" + tr("POIs") + "</h4><p>"
|
||||
+ tr("To make GPXSee load a POI file automatically on startup, add "
|
||||
"the file to the following directory:")
|
||||
+ "</p><p><code>" + USER_POI_DIR + "</code></p>"
|
||||
"<style>td {white-space: pre; padding-right: 1em;}</style>"
|
||||
"<div><table><tr><td>" + tr("Map directory:") + "</td><td><code>"
|
||||
+ QDir::cleanPath(GLOBAL_MAP_DIR) + "</code></td></tr><tr><td>"
|
||||
+ tr("POI directory:") + "</td><td><code>"
|
||||
+ QDir::cleanPath(GLOBAL_POI_DIR) + "</code></td></tr><tr><td>"
|
||||
+ tr("GCS file:") + "</td><td><code>" + QDir::cleanPath(GLOBAL_GCS_FILE)
|
||||
+ "</code></td></tr><tr><td>" + tr("PCS file:") + "</td><td><code>"
|
||||
+ QDir::cleanPath(GLOBAL_PCS_FILE) + "</code></td></tr><tr><td>"
|
||||
+ tr("Ellipsoids file:") + "</td><td><code>"
|
||||
+ QDir::cleanPath(GLOBAL_ELLIPSOID_FILE) + "</code></td></tr>"
|
||||
+ "<tr><td></td><td></td></tr></table></div><div><table><tr><td>"
|
||||
+ tr("User override directory:") + "</td><td><code>"
|
||||
+ QDir::cleanPath(USER_DIR) + "</td></tr></table></div>"
|
||||
);
|
||||
|
||||
msgBox.exec();
|
||||
@ -692,8 +643,6 @@ void GUI::openFile()
|
||||
|
||||
bool GUI::openFile(const QString &fileName)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
if (fileName.isEmpty() || _files.contains(fileName))
|
||||
return false;
|
||||
|
||||
@ -708,13 +657,14 @@ bool GUI::openFile(const QString &fileName)
|
||||
updateWindowTitle();
|
||||
updateGraphTabs();
|
||||
updateMapView();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
if (_files.isEmpty())
|
||||
_fileActionGroup->setEnabled(false);
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool GUI::loadFile(const QString &fileName)
|
||||
@ -1148,30 +1098,38 @@ void GUI::showGraphSliderInfo(bool show)
|
||||
|
||||
void GUI::loadMap()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open map file"),
|
||||
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open map file"),
|
||||
QString(), MapList::formats());
|
||||
QStringList list = files;
|
||||
|
||||
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
|
||||
loadMap(*it);
|
||||
}
|
||||
|
||||
bool GUI::loadMap(const QString &fileName)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
return false;
|
||||
|
||||
int count = _ml->maps().count();
|
||||
if (_ml->loadFile(fileName)) {
|
||||
for (int i = count; i < _ml->maps().count(); i++) {
|
||||
QAction *a = new QAction(_ml->maps().at(i)->name(), this);
|
||||
a->setCheckable(true);
|
||||
a->setActionGroup(_mapsActionGroup);
|
||||
_mapsSignalMapper->setMapping(a, i);
|
||||
connect(a, SIGNAL(triggered()), _mapsSignalMapper, SLOT(map()));
|
||||
_mapActions.append(a);
|
||||
_mapMenu->insertAction(_mapsEnd, a);
|
||||
}
|
||||
QAction *a = new QAction(_ml->maps().last()->name(), this);
|
||||
a->setCheckable(true);
|
||||
a->setActionGroup(_mapsActionGroup);
|
||||
_mapsSignalMapper->setMapping(a, _ml->maps().size() - 1);
|
||||
connect(a, SIGNAL(triggered()), _mapsSignalMapper, SLOT(map()));
|
||||
_mapActions.append(a);
|
||||
_mapMenu->insertAction(_mapsEnd, a);
|
||||
_showMapAction->setEnabled(true);
|
||||
_clearMapCacheAction->setEnabled(true);
|
||||
_mapActions.last()->activate(QAction::Trigger);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
QString error = tr("Error loading map:") + "\n\n"
|
||||
+ fileName + "\n\n" + _ml->errorString();
|
||||
QMessageBox::critical(this, APP_NAME, error);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
private slots:
|
||||
void about();
|
||||
void keys();
|
||||
void dataSources();
|
||||
void paths();
|
||||
void printFile();
|
||||
void exportFile();
|
||||
void openFile();
|
||||
@ -99,6 +99,7 @@ private:
|
||||
|
||||
bool openPOIFile(const QString &fileName);
|
||||
bool loadFile(const QString &fileName);
|
||||
bool loadMap(const QString &fileName);
|
||||
void exportFile(const QString &fileName);
|
||||
void updateStatusBarInfo();
|
||||
void updateWindowTitle();
|
||||
@ -135,7 +136,7 @@ private:
|
||||
QActionGroup *_mapsActionGroup;
|
||||
QAction *_exitAction;
|
||||
QAction *_keysAction;
|
||||
QAction *_dataSourcesAction;
|
||||
QAction *_pathsAction;
|
||||
QAction *_aboutAction;
|
||||
QAction *_aboutQtAction;
|
||||
QAction *_printFileAction;
|
||||
|
@ -1,9 +0,0 @@
|
||||
#include "margins.h"
|
||||
|
||||
|
||||
QDebug operator<<(QDebug dbg, const MarginsF &margins)
|
||||
{
|
||||
dbg.nospace() << "MarginsF(" << margins.left() << ", " << margins.top()
|
||||
<< ", " << margins.right() << margins.bottom() << ")";
|
||||
return dbg.maybeSpace();
|
||||
}
|
@ -25,6 +25,11 @@ private:
|
||||
qreal _left, _top, _right, _bottom;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug dbg, const MarginsF &margins);
|
||||
inline QDebug operator<<(QDebug dbg, const MarginsF &margins)
|
||||
{
|
||||
dbg.nospace() << "MarginsF(" << margins.left() << ", " << margins.top()
|
||||
<< ", " << margins.right() << margins.bottom() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
|
||||
#endif // MARGINS_H
|
||||
|
15
src/config.h
15
src/config.h
@ -12,9 +12,9 @@
|
||||
#define FONT_FAMILY "Arial"
|
||||
#define FONT_SIZE 12 // px
|
||||
|
||||
#define ELLIPSOID_FILE QString("ellipsoids.csv")
|
||||
#define DATUM_FILE QString("datums.csv")
|
||||
#define MAP_FILE QString("maps.txt")
|
||||
#define ELLIPSOID_FILE QString("csv/ellipsoids.csv")
|
||||
#define GCS_FILE QString("csv/gcs.csv")
|
||||
#define PCS_FILE QString("csv/pcs.csv")
|
||||
#define MAP_DIR QString("maps")
|
||||
#define POI_DIR QString("POI")
|
||||
|
||||
@ -31,15 +31,16 @@
|
||||
#endif
|
||||
|
||||
#define USER_ELLIPSOID_FILE USER_DIR + QString("/") + ELLIPSOID_FILE
|
||||
#define USER_DATUM_FILE USER_DIR + QString("/") + DATUM_FILE
|
||||
#define USER_GCS_FILE USER_DIR + QString("/") + GCS_FILE
|
||||
#define USER_PCS_FILE USER_DIR + QString("/") + PCS_FILE
|
||||
#define USER_MAP_DIR USER_DIR + QString("/") + MAP_DIR
|
||||
#define USER_MAP_FILE USER_DIR + QString("/") + MAP_FILE
|
||||
#define USER_POI_DIR USER_DIR + QString("/") + POI_DIR
|
||||
#define GLOBAL_ELLIPSOID_FILE GLOBAL_DIR + QString("/") + ELLIPSOID_FILE
|
||||
#define GLOBAL_DATUM_FILE GLOBAL_DIR + QString("/") + DATUM_FILE
|
||||
#define GLOBAL_GCS_FILE GLOBAL_DIR + QString("/") + GCS_FILE
|
||||
#define GLOBAL_PCS_FILE GLOBAL_DIR + QString("/") + PCS_FILE
|
||||
#define GLOBAL_MAP_DIR GLOBAL_DIR + QString("/") + MAP_DIR
|
||||
#define GLOBAL_MAP_FILE GLOBAL_DIR + QString("/") + MAP_FILE
|
||||
#define GLOBAL_POI_DIR GLOBAL_DIR + QString("/") + POI_DIR
|
||||
#define TILES_DIR USER_DIR + QString("/tiles")
|
||||
#define TRANSLATIONS_DIR GLOBAL_DIR + QString("/translations")
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
|
@ -7,7 +7,6 @@ class CSVParser : public Parser
|
||||
{
|
||||
public:
|
||||
CSVParser() : _errorLine(0) {}
|
||||
~CSVParser() {}
|
||||
|
||||
bool parse(QFile *file, QList<TrackData> &track, QList<RouteData> &routes,
|
||||
QList<Waypoint> &waypoints);
|
||||
|
@ -99,11 +99,12 @@ bool Data::loadFile(const QString &fileName)
|
||||
|
||||
QString Data::formats()
|
||||
{
|
||||
return tr("Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)")
|
||||
+ ";;" + tr("CSV files (*.csv)") + ";;" + tr("FIT files (*.fit)") + ";;"
|
||||
+ tr("GPX files (*.gpx)") + ";;" + tr("IGC files (*.igc)") + ";;"
|
||||
+ tr("KML files (*.kml)") + ";;" + tr("NMEA files (*.nmea)") + ";;"
|
||||
+ tr("TCX files (*.tcx)") + ";;" + tr("All files (*)");
|
||||
return
|
||||
tr("Supported files") + " (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx);;"
|
||||
+ tr("CSV files") + " (*.csv);;" + tr("FIT files") + " (*.fit);;"
|
||||
+ tr("GPX files") + " (*.gpx);;" + tr("IGC files") + " (*.igc);;"
|
||||
+ tr("KML files") + " (*.kml);;" + tr("NMEA files") + " (*.nmea);;"
|
||||
+ tr("TCX files") + " (*.tcx);;" + tr("All files") + "(*)";
|
||||
}
|
||||
|
||||
QStringList Data::filter()
|
||||
|
@ -7,7 +7,6 @@ class FITParser : public Parser
|
||||
{
|
||||
public:
|
||||
FITParser();
|
||||
~FITParser() {}
|
||||
|
||||
bool parse(QFile *file, QList<TrackData> &tracks, QList<RouteData> &routes,
|
||||
QList<Waypoint> &waypoints);
|
||||
|
@ -8,8 +8,6 @@
|
||||
class GPXParser : public Parser
|
||||
{
|
||||
public:
|
||||
~GPXParser() {}
|
||||
|
||||
bool parse(QFile *file, QList<TrackData> &tracks,
|
||||
QList<RouteData> &routes, QList<Waypoint> &waypoints);
|
||||
QString errorString() const {return _reader.errorString();}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <cstring>
|
||||
#include "str2int.h"
|
||||
#include "common/str2int.h"
|
||||
#include "igcparser.h"
|
||||
|
||||
|
||||
|
@ -10,7 +10,6 @@ class IGCParser : public Parser
|
||||
{
|
||||
public:
|
||||
IGCParser() : _errorLine(0) {}
|
||||
~IGCParser() {}
|
||||
|
||||
bool parse(QFile *file, QList<TrackData> &tracks,
|
||||
QList<RouteData> &routes, QList<Waypoint> &waypoints);
|
||||
|
@ -8,8 +8,6 @@
|
||||
class KMLParser : public Parser
|
||||
{
|
||||
public:
|
||||
~KMLParser() {}
|
||||
|
||||
bool parse(QFile *file, QList<TrackData> &tracks,
|
||||
QList<RouteData> &routes, QList<Waypoint> &waypoints);
|
||||
QString errorString() const {return _reader.errorString();}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <cstring>
|
||||
#include "str2int.h"
|
||||
#include "common/str2int.h"
|
||||
#include "nmeaparser.h"
|
||||
|
||||
|
||||
|
@ -9,7 +9,6 @@ class NMEAParser : public Parser
|
||||
{
|
||||
public:
|
||||
NMEAParser() : _errorLine(0), _GGA(false) {}
|
||||
~NMEAParser() {}
|
||||
|
||||
bool parse(QFile *file, QList<TrackData> &tracks,
|
||||
QList<RouteData> &routes, QList<Waypoint> &waypoints);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include "data.h"
|
||||
#include "poi.h"
|
||||
|
||||
@ -9,20 +10,25 @@ POI::POI(QObject *parent) : QObject(parent)
|
||||
_radius = 1000;
|
||||
}
|
||||
|
||||
bool POI::loadFile(const QString &fileName)
|
||||
bool POI::loadFile(const QString &path, bool dir)
|
||||
{
|
||||
Data data;
|
||||
FileIndex index;
|
||||
|
||||
_errorString.clear();
|
||||
_errorLine = 0;
|
||||
|
||||
index.enabled = true;
|
||||
index.start = _data.size();
|
||||
|
||||
if (!data.loadFile(fileName)) {
|
||||
_errorString = data.errorString();
|
||||
_errorLine = data.errorLine();
|
||||
if (!data.loadFile(path)) {
|
||||
if (dir) {
|
||||
if (data.errorLine())
|
||||
_errorString += QString("%1:%2: %3\n").arg(path)
|
||||
.arg(data.errorLine()).arg(data.errorString());
|
||||
else
|
||||
_errorString += path + ": " + data.errorString() + "\n";
|
||||
} else {
|
||||
_errorString = data.errorString();
|
||||
_errorLine = data.errorLine();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -38,7 +44,7 @@ bool POI::loadFile(const QString &fileName)
|
||||
_tree.Insert(c, c, i);
|
||||
}
|
||||
|
||||
_files.append(fileName);
|
||||
_files.append(path);
|
||||
_indexes.append(index);
|
||||
|
||||
emit pointsChanged();
|
||||
@ -46,6 +52,39 @@ bool POI::loadFile(const QString &fileName)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool POI::loadFile(const QString &path)
|
||||
{
|
||||
_errorString.clear();
|
||||
_errorLine = 0;
|
||||
|
||||
return loadFile(path, false);
|
||||
}
|
||||
|
||||
bool POI::loadDir(const QString &path)
|
||||
{
|
||||
QDir md(path);
|
||||
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
QFileInfoList fl = md.entryInfoList();
|
||||
bool ret = true;
|
||||
|
||||
_errorString.clear();
|
||||
_errorLine = 0;
|
||||
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
const QFileInfo &fi = fl.at(i);
|
||||
|
||||
if (fi.isDir()) {
|
||||
if (!loadDir(fi.absoluteFilePath()))
|
||||
ret = false;
|
||||
} else {
|
||||
if (!loadFile(fi.absoluteFilePath(), true))
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool cb(size_t data, void* context)
|
||||
{
|
||||
QSet<int> *set = (QSet<int>*) context;
|
||||
|
@ -18,7 +18,8 @@ class POI : public QObject
|
||||
public:
|
||||
POI(QObject *parent = 0);
|
||||
|
||||
bool loadFile(const QString &fileName);
|
||||
bool loadFile(const QString &path);
|
||||
bool loadDir(const QString &path);
|
||||
const QString &errorString() const {return _errorString;}
|
||||
int errorLine() const {return _errorLine;}
|
||||
|
||||
@ -43,6 +44,8 @@ private:
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
bool loadFile(const QString &path, bool dir);
|
||||
|
||||
POITree _tree;
|
||||
QVector<Waypoint> _data;
|
||||
QStringList _files;
|
||||
|
@ -8,8 +8,6 @@
|
||||
class TCXParser : public Parser
|
||||
{
|
||||
public:
|
||||
~TCXParser() {}
|
||||
|
||||
bool parse(QFile *file, QList<TrackData> &tracks,
|
||||
QList<RouteData> &routes, QList<Waypoint> &waypoints);
|
||||
QString errorString() const {return _reader.errorString();}
|
||||
|
@ -56,7 +56,7 @@ Defense.
|
||||
((clat) / sqrt(one_minus_sqr_es_sin))
|
||||
|
||||
|
||||
AlbersEqual::AlbersEqual(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
AlbersEqual::AlbersEqual(const Ellipsoid *ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double falseEasting, double falseNorthing)
|
||||
{
|
||||
@ -78,7 +78,7 @@ AlbersEqual::AlbersEqual(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
sp1 = deg2rad(standardParallel1);
|
||||
sp2 = deg2rad(standardParallel2);
|
||||
|
||||
_es2 = 2 * _e.flattening() - _e.flattening() * _e.flattening();
|
||||
_es2 = 2 * _e->flattening() - _e->flattening() * _e->flattening();
|
||||
_es = sqrt(_es2);
|
||||
_one_minus_es2 = 1 - _es2;
|
||||
_two_es = 2 * _es;
|
||||
@ -108,7 +108,7 @@ AlbersEqual::AlbersEqual(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
_n = sin_lat1;
|
||||
|
||||
_C = sqr_m1 + _n * q1;
|
||||
_a_over_n = _e.radius() / _n;
|
||||
_a_over_n = _e->radius() / _n;
|
||||
nq0 = _n * q0;
|
||||
_rho0 = (_C < nq0) ? 0 : _a_over_n * sqrt(_C - nq0);
|
||||
}
|
||||
@ -171,7 +171,7 @@ Coordinates AlbersEqual::xy2ll(const QPointF &p) const
|
||||
if (rho != 0.0)
|
||||
theta = atan2(dx, rho0_minus_dy);
|
||||
rho_n = rho * _n;
|
||||
q = (_C - (rho_n * rho_n) / (_e.radius() * _e.radius())) / _n;
|
||||
q = (_C - (rho_n * rho_n) / (_e->radius() * _e->radius())) / _n;
|
||||
qc = 1 - ((_one_minus_es2) / (_two_es)) * log((1.0 - _es) / (1.0 + _es));
|
||||
if (fabs(fabs(qc) - fabs(q)) > 1.0e-6) {
|
||||
q_over_2 = q / 2.0;
|
||||
|
@ -2,20 +2,22 @@
|
||||
#define ALBERSEQUAL_H
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
|
||||
class AlbersEqual : public Projection
|
||||
class AlbersEqual : public CT
|
||||
{
|
||||
public:
|
||||
AlbersEqual(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
AlbersEqual(const Ellipsoid *ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double falseEasting, double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new AlbersEqual(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
Ellipsoid _e;
|
||||
const Ellipsoid *_e;
|
||||
|
||||
double _latitudeOrigin;
|
||||
double _longitudeOrigin;
|
||||
|
90
src/map/angularunits.cpp
Normal file
90
src/map/angularunits.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "common/coordinates.h"
|
||||
#include "common/str2int.h"
|
||||
#include "angularunits.h"
|
||||
|
||||
static double sDMS2deg(double val)
|
||||
{
|
||||
double angle;
|
||||
const char *decimal;
|
||||
|
||||
QString qstr(QString::number(qAbs(val), 'f', 7));
|
||||
const char *str = qstr.toLatin1().constData();
|
||||
decimal = strrchr(str, '.');
|
||||
int deg = str2int(str, decimal - str);
|
||||
int min = str2int(decimal + 1, 2);
|
||||
int sec = str2int(decimal + 3, 2);
|
||||
int f = str2int(decimal + 5, 3);
|
||||
|
||||
angle = deg + min/60.0 + sec/3600.0 + (f/1000.0)/3600.0;
|
||||
|
||||
return (val < 0) ? -angle : angle;
|
||||
}
|
||||
|
||||
static double deg2sDMS(double val)
|
||||
{
|
||||
double aval = qAbs(val);
|
||||
|
||||
int deg = aval;
|
||||
double r1 = aval - deg;
|
||||
|
||||
int min = r1 * 60.0;
|
||||
double r2 = r1 - (min / 60.0);
|
||||
|
||||
int sec = r2 * 3600.0;
|
||||
double r3 = r2 - (sec / 3600.0);
|
||||
int f = (int)(r3 * 3600.0 * 1000.0);
|
||||
|
||||
QString str(QString("%1.%2%3%4").arg(deg).arg(min, 2, 10, QChar('0'))
|
||||
.arg(sec, 2, 10, QChar('0')).arg(f, 3, 10, QChar('0')));
|
||||
|
||||
return (val < 0) ? -str.toDouble() : str.toDouble();
|
||||
}
|
||||
|
||||
AngularUnits::AngularUnits(int code) : _code(code)
|
||||
{
|
||||
switch (code) {
|
||||
case 9101:
|
||||
_f = 180.0 / M_PI;
|
||||
break;
|
||||
case 9102:
|
||||
case 9107:
|
||||
case 9108:
|
||||
case 9110:
|
||||
case 9122:
|
||||
_f = 1.0;
|
||||
break;
|
||||
case 9103:
|
||||
_f = 1 / 60.0;
|
||||
break;
|
||||
case 9104:
|
||||
_f = 1 / 3600.0;
|
||||
break;
|
||||
case 9105:
|
||||
_f = 180.0 / 200.0;
|
||||
break;
|
||||
case 9106:
|
||||
_f = 180.0 / 200.0;
|
||||
break;
|
||||
case 9109:
|
||||
_f = 180.0 / (M_PI * 1000000.0);
|
||||
break;
|
||||
default:
|
||||
_f = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
double AngularUnits::toDegrees(double val) const
|
||||
{
|
||||
return (_code == 9110) ? sDMS2deg(val) : val * _f;
|
||||
}
|
||||
|
||||
double AngularUnits::fromDegrees(double val) const
|
||||
{
|
||||
return (_code == 9110) ? deg2sDMS(val) : val / _f;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const AngularUnits &au)
|
||||
{
|
||||
dbg.nospace() << "AngularUnits(" << deg2rad(au._f) << ")";
|
||||
return dbg.space();
|
||||
}
|
32
src/map/angularunits.h
Normal file
32
src/map/angularunits.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef ANGULARUNITS_H
|
||||
#define ANGULARUNITS_H
|
||||
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
|
||||
class AngularUnits
|
||||
{
|
||||
public:
|
||||
AngularUnits() : _code(0), _f(NAN) {}
|
||||
AngularUnits(int code);
|
||||
|
||||
bool isNull() const {return std::isnan(_f);}
|
||||
bool isValid() const {return !std::isnan(_f);}
|
||||
|
||||
double toDegrees(double val) const;
|
||||
double fromDegrees(double val) const;
|
||||
|
||||
friend bool operator==(const AngularUnits &au1, const AngularUnits &au2);
|
||||
friend QDebug operator<<(QDebug dbg, const AngularUnits &au);
|
||||
|
||||
private:
|
||||
int _code;
|
||||
double _f;
|
||||
};
|
||||
|
||||
inline bool operator==(const AngularUnits &au1, const AngularUnits &au2)
|
||||
{return (au1._f == au2._f);}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const AngularUnits &au);
|
||||
|
||||
#endif // ANGULARUNITS_H
|
@ -31,37 +31,6 @@ static bool yCmp(const OfflineMap *m1, const OfflineMap *m2)
|
||||
return TL(m1).y() > TL(m2).y();
|
||||
}
|
||||
|
||||
bool Atlas::isAtlas(Tar &tar, const QString &path)
|
||||
{
|
||||
QFileInfo fi(path);
|
||||
QByteArray ba;
|
||||
QString suffix = fi.suffix().toLower();
|
||||
|
||||
if (suffix == "tar") {
|
||||
if (!tar.load(path)) {
|
||||
_errorString = "Error reading tar file";
|
||||
return false;
|
||||
}
|
||||
QString tbaFileName = fi.completeBaseName() + ".tba";
|
||||
ba = tar.file(tbaFileName);
|
||||
} else if (suffix == "tba") {
|
||||
QFile tbaFile(path);
|
||||
if (!tbaFile.open(QIODevice::ReadOnly)) {
|
||||
_errorString = QString("Error opening tba file: %1")
|
||||
.arg(tbaFile.errorString());
|
||||
return false;
|
||||
}
|
||||
ba = tbaFile.readAll();
|
||||
}
|
||||
|
||||
if (ba.startsWith("Atlas 1.0"))
|
||||
return true;
|
||||
else {
|
||||
_errorString = "Missing or invalid tba file";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Atlas::computeZooms()
|
||||
{
|
||||
qSort(_maps.begin(), _maps.end(), resCmp);
|
||||
@ -111,16 +80,38 @@ void Atlas::computeBounds()
|
||||
|
||||
Atlas::Atlas(const QString &fileName, QObject *parent) : Map(parent)
|
||||
{
|
||||
Tar tar;
|
||||
QFileInfo fi(fileName);
|
||||
QByteArray ba;
|
||||
QString suffix = fi.suffix().toLower();
|
||||
Tar tar;
|
||||
|
||||
_valid = false;
|
||||
_zoom = 0;
|
||||
_name = fi.dir().dirName();
|
||||
_ci = -1; _cz = -1;
|
||||
|
||||
if (!isAtlas(tar, fileName))
|
||||
|
||||
if (suffix == "tar") {
|
||||
if (!tar.load(fileName)) {
|
||||
_errorString = "Error reading tar file";
|
||||
return;
|
||||
}
|
||||
QString tbaFileName = fi.completeBaseName() + ".tba";
|
||||
ba = tar.file(tbaFileName);
|
||||
} else if (suffix == "tba") {
|
||||
QFile tbaFile(fileName);
|
||||
if (!tbaFile.open(QIODevice::ReadOnly)) {
|
||||
_errorString = QString("Error opening tba file: %1")
|
||||
.arg(tbaFile.errorString());
|
||||
return;
|
||||
}
|
||||
ba = tbaFile.readAll();
|
||||
}
|
||||
if (!ba.startsWith("Atlas 1.0")) {
|
||||
_errorString = "Missing or invalid tba file";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QDir dir(fi.absolutePath());
|
||||
QFileInfoList layers = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
@ -336,3 +327,20 @@ void Atlas::unload()
|
||||
for (int i = 0; i < _maps.count(); i++)
|
||||
_maps.at(i)->unload();
|
||||
}
|
||||
|
||||
bool Atlas::isAtlas(const QString &path)
|
||||
{
|
||||
QFileInfo fi(path);
|
||||
QString suffix = fi.suffix().toLower();
|
||||
Tar tar;
|
||||
|
||||
if (suffix == "tar") {
|
||||
if (!tar.load(path))
|
||||
return false;
|
||||
QString tbaFileName = fi.completeBaseName() + ".tba";
|
||||
return tar.contains(tbaFileName);
|
||||
} else if (suffix == "tba")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -35,9 +35,10 @@ public:
|
||||
bool isValid() const {return _valid;}
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
static bool isAtlas(const QString &path);
|
||||
|
||||
private:
|
||||
void draw(QPainter *painter, const QRectF &rect, int mapIndex);
|
||||
bool isAtlas(Tar &tar, const QString &path);
|
||||
void computeZooms();
|
||||
void computeBounds();
|
||||
|
||||
|
17
src/map/ct.h
Normal file
17
src/map/ct.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef CT_H
|
||||
#define CT_H
|
||||
|
||||
#include <QPointF>
|
||||
#include "common/coordinates.h"
|
||||
|
||||
class CT {
|
||||
public:
|
||||
virtual ~CT() {}
|
||||
|
||||
virtual CT *clone() const = 0;
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const = 0;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const = 0;
|
||||
};
|
||||
|
||||
#endif // CT_H
|
@ -1,96 +1,14 @@
|
||||
#include <cmath>
|
||||
#include <QFile>
|
||||
#include "common/wgs84.h"
|
||||
#include "datum.h"
|
||||
|
||||
|
||||
static QMap<QString, Datum> WGS84()
|
||||
{
|
||||
QMap<QString, Datum> map;
|
||||
map.insert("WGS 84", Datum(Ellipsoid(WGS84_RADIUS, WGS84_FLATTENING),
|
||||
0.0, 0.0, 0.0));
|
||||
return map;
|
||||
}
|
||||
|
||||
QMap<QString, Datum> Datum::_datums = WGS84();
|
||||
QString Datum::_errorString;
|
||||
int Datum::_errorLine = 0;
|
||||
|
||||
Datum Datum::datum(const QString &name)
|
||||
{
|
||||
QMap<QString, Datum>::const_iterator it = _datums.find(name);
|
||||
|
||||
if (it == _datums.end())
|
||||
return Datum();
|
||||
|
||||
return it.value();
|
||||
}
|
||||
|
||||
bool Datum::loadList(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
bool res;
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
_errorString = qPrintable(file.errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
_errorLine = 1;
|
||||
_errorString.clear();
|
||||
|
||||
while (!file.atEnd()) {
|
||||
QByteArray line = file.readLine();
|
||||
QList<QByteArray> list = line.split(',');
|
||||
if (list.size() != 6) {
|
||||
_errorString = "Format error";
|
||||
return false;
|
||||
}
|
||||
|
||||
int eid = list[2].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
_errorString = "Invalid ellipsoid id";
|
||||
return false;
|
||||
}
|
||||
double dx = list[3].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
_errorString = "Invalid dx";
|
||||
return false;
|
||||
}
|
||||
double dy = list[4].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
_errorString = "Invalid dy";
|
||||
return false;
|
||||
}
|
||||
double dz = list[5].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
_errorString = "Invalid dz";
|
||||
return false;
|
||||
}
|
||||
|
||||
Ellipsoid e = Ellipsoid::ellipsoid(eid);
|
||||
if (e.isNull()) {
|
||||
_errorString = "Unknown ellipsoid ID";
|
||||
return false;
|
||||
}
|
||||
|
||||
Datum d(e, dx, dy, dz);
|
||||
_datums.insert(list[0].trimmed(), d);
|
||||
|
||||
_errorLine++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
static Ellipsoid WGS84e = Ellipsoid(WGS84_RADIUS, WGS84_FLATTENING);
|
||||
static Datum WGS84 = Datum(&WGS84e, 0.0, 0.0, 0.0);
|
||||
|
||||
// Abridged Molodensky transformation
|
||||
Coordinates Datum::toWGS84(const Coordinates &c) const
|
||||
static Coordinates molodensky(const Coordinates &c, const Datum &from,
|
||||
const Datum &to)
|
||||
{
|
||||
if (_ellipsoid.radius() == WGS84_RADIUS
|
||||
&& _ellipsoid.flattening() == WGS84_FLATTENING
|
||||
&& _dx == 0.0 && _dy == 0.0 && _dz == 0.0)
|
||||
return c;
|
||||
|
||||
double rlat = deg2rad(c.lat());
|
||||
double rlon = deg2rad(c.lon());
|
||||
|
||||
@ -100,21 +18,51 @@ Coordinates Datum::toWGS84(const Coordinates &c) const
|
||||
double clon = cos(rlon);
|
||||
double ssqlat = slat * slat;
|
||||
|
||||
double from_f = ellipsoid().flattening();
|
||||
double df = WGS84_FLATTENING - from_f;
|
||||
double from_a = ellipsoid().radius();
|
||||
double da = WGS84_RADIUS - from_a;
|
||||
double from_esq = ellipsoid().flattening()
|
||||
* (2.0 - ellipsoid().flattening());
|
||||
double dx = from.dx() - to.dx();
|
||||
double dy = from.dy() - to.dy();
|
||||
double dz = from.dz() - to.dz();
|
||||
|
||||
double from_f = from.ellipsoid()->flattening();
|
||||
double to_f = to.ellipsoid()->flattening();
|
||||
double df = to_f - from_f;
|
||||
double from_a = from.ellipsoid()->radius();
|
||||
double to_a = to.ellipsoid()->radius();
|
||||
double da = to_a - from_a;
|
||||
double from_esq = from_f * (2.0 - from_f);
|
||||
double adb = 1.0 / (1.0 - from_f);
|
||||
double rn = from_a / sqrt(1 - from_esq * ssqlat);
|
||||
double rm = from_a * (1 - from_esq) / pow((1 - from_esq * ssqlat), 1.5);
|
||||
double from_h = 0.0;
|
||||
|
||||
double dlat = (-dx() * slat * clon - dy() * slat * slon + dz() * clat + da
|
||||
double dlat = (-dx * slat * clon - dy * slat * slon + dz * clat + da
|
||||
* rn * from_esq * slat * clat / from_a + df * (rm * adb + rn / adb) * slat
|
||||
* clat) / (rm + from_h);
|
||||
double dlon = (-dx() * slon + dy() * clon) / ((rn + from_h) * clat);
|
||||
|
||||
double dlon = (-dx * slon + dy * clon) / ((rn + from_h) * clat);
|
||||
|
||||
return Coordinates(c.lon() + rad2deg(dlon), c.lat() + rad2deg(dlat));
|
||||
}
|
||||
|
||||
Datum::Datum(const Ellipsoid *ellipsoid, double dx, double dy,
|
||||
double dz) : _ellipsoid(ellipsoid), _dx(dx), _dy(dy), _dz(dz)
|
||||
{
|
||||
_WGS84 = (*_ellipsoid == *WGS84.ellipsoid() && _dx == WGS84.dx()
|
||||
&& _dy == WGS84.dy() && _dz == WGS84.dz()) ? true : false;
|
||||
}
|
||||
|
||||
Coordinates Datum::toWGS84(const Coordinates &c) const
|
||||
{
|
||||
return _WGS84 ? c : molodensky(c, *this, WGS84);
|
||||
}
|
||||
|
||||
Coordinates Datum::fromWGS84(const Coordinates &c) const
|
||||
{
|
||||
return _WGS84 ? c : molodensky(c, WGS84, *this);
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Datum &datum)
|
||||
{
|
||||
dbg.nospace() << "Datum(" << *datum.ellipsoid() << ", " << datum.dx()
|
||||
<< ", " << datum.dy() << ", " << datum.dz() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
|
@ -1,40 +1,44 @@
|
||||
#ifndef DATUM_H
|
||||
#define DATUM_H
|
||||
|
||||
#include <QMap>
|
||||
#include <cmath>
|
||||
#include <QList>
|
||||
#include <QDebug>
|
||||
#include "ellipsoid.h"
|
||||
#include "common/coordinates.h"
|
||||
|
||||
class Datum
|
||||
{
|
||||
public:
|
||||
Datum() : _ellipsoid(Ellipsoid()), _dx(0.0), _dy(0.0), _dz(0.0) {}
|
||||
Datum(const Ellipsoid &ellipsoid, double dx, double dy, double dz)
|
||||
: _ellipsoid(ellipsoid), _dx(dx), _dy(dy), _dz(dz) {}
|
||||
Datum() : _ellipsoid(0), _dx(NAN), _dy(NAN), _dz(NAN),
|
||||
_WGS84(false) {}
|
||||
Datum(const Ellipsoid *ellipsoid, double dx, double dy, double dz);
|
||||
|
||||
const Ellipsoid &ellipsoid() const {return _ellipsoid;}
|
||||
const Ellipsoid *ellipsoid() const {return _ellipsoid;}
|
||||
double dx() const {return _dx;}
|
||||
double dy() const {return _dy;}
|
||||
double dz() const {return _dz;}
|
||||
|
||||
bool isNull() const
|
||||
{return (_ellipsoid.isNull() && _dx == 0.0 && _dy == 0.0 && _dz == 0.0);}
|
||||
{return (!_ellipsoid && std::isnan(_dx) && std::isnan(_dy)
|
||||
&& std::isnan(_dz));}
|
||||
bool isValid() const
|
||||
{return (_ellipsoid && !std::isnan(_dx) && !std::isnan(_dy)
|
||||
&& !std::isnan(_dz));}
|
||||
|
||||
Coordinates toWGS84(const Coordinates &c) const;
|
||||
|
||||
static bool loadList(const QString &path);
|
||||
static const QString &errorString() {return _errorString;}
|
||||
static int errorLine() {return _errorLine;}
|
||||
|
||||
static Datum datum(const QString &name);
|
||||
Coordinates fromWGS84(const Coordinates &c) const;
|
||||
|
||||
private:
|
||||
Ellipsoid _ellipsoid;
|
||||
const Ellipsoid *_ellipsoid;
|
||||
double _dx, _dy, _dz;
|
||||
|
||||
static QMap<QString, Datum> _datums;
|
||||
static QString _errorString;
|
||||
static int _errorLine;
|
||||
bool _WGS84;
|
||||
};
|
||||
|
||||
inline bool operator==(const Datum &d1, const Datum &d2)
|
||||
{return (d1.ellipsoid() == d2.ellipsoid() && d1.dx() == d2.dx()
|
||||
&& d1.dy() == d2.dy() && d1.dz() == d2.dz());}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Datum &datum);
|
||||
|
||||
#endif // DATUM_H
|
||||
|
@ -1,62 +1,74 @@
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include "common/wgs84.h"
|
||||
#include "ellipsoid.h"
|
||||
|
||||
QMap<int, Ellipsoid> Ellipsoid::_ellipsoids;
|
||||
QString Ellipsoid::_errorString;
|
||||
int Ellipsoid::_errorLine = 0;
|
||||
QMap<int, Ellipsoid> Ellipsoid::_ellipsoids = WGS84();
|
||||
|
||||
Ellipsoid Ellipsoid::ellipsoid(int id)
|
||||
QMap<int, Ellipsoid> Ellipsoid::WGS84()
|
||||
{
|
||||
QMap<int, Ellipsoid> map;
|
||||
map.insert(7030, Ellipsoid(WGS84_RADIUS, WGS84_FLATTENING));
|
||||
return map;
|
||||
}
|
||||
|
||||
const Ellipsoid *Ellipsoid::ellipsoid(int id)
|
||||
{
|
||||
QMap<int, Ellipsoid>::const_iterator it = _ellipsoids.find(id);
|
||||
|
||||
if (it == _ellipsoids.end())
|
||||
return Ellipsoid();
|
||||
|
||||
return it.value();
|
||||
return 0;
|
||||
else
|
||||
return &(it.value());
|
||||
}
|
||||
|
||||
bool Ellipsoid::loadList(const QString &path)
|
||||
void Ellipsoid::loadList(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
bool res;
|
||||
int ln = 0;
|
||||
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
_errorString = qPrintable(file.errorString());
|
||||
return false;
|
||||
qWarning("Error opening ellipsoids file: %s: %s", qPrintable(path),
|
||||
qPrintable(file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
_errorLine = 1;
|
||||
_errorString.clear();
|
||||
|
||||
while (!file.atEnd()) {
|
||||
ln++;
|
||||
|
||||
QByteArray line = file.readLine();
|
||||
QList<QByteArray> list = line.split(',');
|
||||
if (list.size() != 4) {
|
||||
_errorString = "Format error";
|
||||
return false;
|
||||
qWarning("%s: %d: Format error", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
int id = list[0].trimmed().toInt(&res);
|
||||
int id = list[1].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
_errorString = "Invalid ellipsoid id";
|
||||
return false;
|
||||
qWarning("%s: %d: Invalid ellipsoid code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double radius = list[2].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
_errorString = "Invalid ellipsoid radius";
|
||||
return false;
|
||||
qWarning("%s: %d: Invalid radius", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double flattening = list[3].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
_errorString = "Invalid ellipsoid flattening";
|
||||
return false;
|
||||
qWarning("%s: %d: Invalid flattening", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
Ellipsoid e(radius, 1.0/flattening);
|
||||
_ellipsoids.insert(id, e);
|
||||
|
||||
_errorLine++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Ellipsoid &ellipsoid)
|
||||
{
|
||||
dbg.nospace() << "Ellipsoid(" << ellipsoid.radius() << ", "
|
||||
<< 1.0 / ellipsoid.flattening() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
|
@ -1,34 +1,40 @@
|
||||
#ifndef ELLIPSOID_H
|
||||
#define ELLIPSOID_H
|
||||
|
||||
#include <cmath>
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
#include <QDebug>
|
||||
|
||||
class Ellipsoid
|
||||
{
|
||||
public:
|
||||
Ellipsoid() : _radius(0.0), _flattening(0.0) {}
|
||||
Ellipsoid() : _radius(NAN), _flattening(NAN) {}
|
||||
Ellipsoid(double radius, double flattening)
|
||||
: _radius(radius), _flattening(flattening) {}
|
||||
|
||||
double radius() const {return _radius;}
|
||||
double flattening() const {return _flattening;}
|
||||
|
||||
bool isNull() const {return (_radius == 0.0 && _flattening == 0.0);}
|
||||
bool isNull() const
|
||||
{return (std::isnan(_radius) && std::isnan(_flattening));}
|
||||
bool isValid() const
|
||||
{return !(std::isnan(_radius) || std::isnan(_flattening));}
|
||||
|
||||
static bool loadList(const QString &path);
|
||||
static const QString &errorString() {return _errorString;}
|
||||
static int errorLine() {return _errorLine;}
|
||||
|
||||
static Ellipsoid ellipsoid(int id);
|
||||
static const Ellipsoid *ellipsoid(int id);
|
||||
static void loadList(const QString &path);
|
||||
|
||||
private:
|
||||
double _radius;
|
||||
double _flattening;
|
||||
|
||||
static QMap<int, Ellipsoid> WGS84();
|
||||
static QMap<int, Ellipsoid> _ellipsoids;
|
||||
static QString _errorString;
|
||||
static int _errorLine;
|
||||
};
|
||||
|
||||
inline bool operator==(const Ellipsoid &e1, const Ellipsoid &e2)
|
||||
{return (e1.radius() == e2.radius() && e1.flattening() == e2.flattening());}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Ellipsoid &ellipsoid);
|
||||
|
||||
#endif // ELLIPSOID_H
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "common/rectc.h"
|
||||
#include "common/wgs84.h"
|
||||
#include "mercator.h"
|
||||
#include "misc.h"
|
||||
#include "emptymap.h"
|
||||
|
||||
|
||||
@ -18,7 +17,7 @@ EmptyMap::EmptyMap(QObject *parent) : Map(parent)
|
||||
|
||||
QRectF EmptyMap::bounds() const
|
||||
{
|
||||
return scaled(QRectF(QPointF(-180, -180), QSizeF(360, 360)), 1.0/_scale);
|
||||
return QRectF(ll2xy(Coordinates(-180, 85)), ll2xy(Coordinates(180, -85)));
|
||||
}
|
||||
|
||||
qreal EmptyMap::zoomFit(const QSize &size, const RectC &br)
|
||||
@ -72,13 +71,13 @@ void EmptyMap::draw(QPainter *painter, const QRectF &rect)
|
||||
painter->fillRect(rect, _backgroundColor);
|
||||
}
|
||||
|
||||
QPointF EmptyMap::ll2xy(const Coordinates &c)
|
||||
QPointF EmptyMap::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
QPointF m = Mercator().ll2xy(c);
|
||||
return QPointF(m.x() / _scale, m.y() / -_scale);
|
||||
}
|
||||
|
||||
Coordinates EmptyMap::xy2ll(const QPointF &p)
|
||||
Coordinates EmptyMap::xy2ll(const QPointF &p) const
|
||||
{
|
||||
QPointF m(p.x() * _scale, -p.y() * _scale);
|
||||
return Mercator().xy2ll(m);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef EMPTYMAP_H
|
||||
#define EMPTYMAP_H
|
||||
|
||||
#include "common/coordinates.h"
|
||||
#include "map.h"
|
||||
|
||||
class EmptyMap : public Map
|
||||
@ -21,12 +22,17 @@ public:
|
||||
qreal zoomIn();
|
||||
qreal zoomOut();
|
||||
|
||||
QPointF ll2xy(const Coordinates &c);
|
||||
Coordinates xy2ll(const QPointF &p);
|
||||
QPointF ll2xy(const Coordinates &c)
|
||||
{return static_cast<const EmptyMap &>(*this).ll2xy(c);}
|
||||
Coordinates xy2ll(const QPointF &p)
|
||||
{return static_cast<const EmptyMap &>(*this).xy2ll(p);}
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect);
|
||||
|
||||
private:
|
||||
QPointF ll2xy(const Coordinates &c) const;
|
||||
Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
QString _name;
|
||||
qreal _scale;
|
||||
};
|
||||
|
191
src/map/gcs.cpp
Normal file
191
src/map/gcs.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
#include <QFile>
|
||||
#include "common/wgs84.h"
|
||||
#include "gcs.h"
|
||||
|
||||
|
||||
class GCS::Entry {
|
||||
public:
|
||||
Entry(int id, int gd, const QString &name, const GCS &gcs)
|
||||
: _id(id), _gd(gd), _name(name), _gcs(gcs) {}
|
||||
|
||||
int id() const {return _id;}
|
||||
int gd() const {return _gd;}
|
||||
const QString &name() const {return _name;}
|
||||
const GCS &gcs() const {return _gcs;}
|
||||
|
||||
private:
|
||||
int _id, _gd;
|
||||
QString _name;
|
||||
GCS _gcs;
|
||||
};
|
||||
|
||||
static Ellipsoid WGS84e = Ellipsoid(WGS84_RADIUS, WGS84_FLATTENING);
|
||||
static Datum WGS84d = Datum(&WGS84e, 0.0, 0.0, 0.0);
|
||||
|
||||
static int parameter(const QString &str, bool *res)
|
||||
{
|
||||
QString field = str.trimmed();
|
||||
if (field.isEmpty()) {
|
||||
*res = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return field.toInt(res);
|
||||
}
|
||||
|
||||
QList<GCS::Entry> GCS::_gcss = WGS84();
|
||||
|
||||
QList<GCS::Entry> GCS::WGS84()
|
||||
{
|
||||
QList<GCS::Entry> list;
|
||||
list.append(GCS::Entry(4326, 6326, "WGS 84", GCS(WGS84d, 8901, 9122)));
|
||||
return list;
|
||||
}
|
||||
|
||||
const GCS *GCS::gcs(int id)
|
||||
{
|
||||
for (int i = 0; i < _gcss.size(); i++)
|
||||
if (_gcss.at(i).id() == id)
|
||||
return &(_gcss.at(i).gcs());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const GCS *GCS::gcs(int geodeticDatum, int primeMeridian, int angularUnits)
|
||||
{
|
||||
for (int i = 0; i < _gcss.size(); i++) {
|
||||
const Entry &e = _gcss.at(i);
|
||||
if (e.gd() == geodeticDatum && e.gcs().primeMeridian() == primeMeridian
|
||||
&& e.gcs().angularUnits() == angularUnits)
|
||||
return &(e.gcs());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const GCS *GCS::gcs(const QString &name)
|
||||
{
|
||||
for (int i = 0; i < _gcss.size(); i++)
|
||||
if (_gcss.at(i).name() == name)
|
||||
return &(_gcss.at(i).gcs());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GCS::loadList(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
bool res;
|
||||
int ln = 0;
|
||||
const Ellipsoid *e;
|
||||
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
qWarning("Error opening PCS file: %s: %s", qPrintable(path),
|
||||
qPrintable(file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
while (!file.atEnd()) {
|
||||
ln++;
|
||||
|
||||
QByteArray line = file.readLine();
|
||||
QList<QByteArray> list = line.split(',');
|
||||
if (list.size() < 10) {
|
||||
qWarning("%s: %d: Format error", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
int id = parameter(list[1], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid GCS code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int gd = parameter(list[2], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid geodetic datum code", qPrintable(path),
|
||||
ln);
|
||||
continue;
|
||||
}
|
||||
int au = list[3].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid angular units code", qPrintable(path),
|
||||
ln);
|
||||
continue;
|
||||
}
|
||||
int el = list[4].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid ellipsoid code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int pm = list[5].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid prime meridian code", qPrintable(path),
|
||||
ln);
|
||||
continue;
|
||||
}
|
||||
int ct = list[6].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid coordinates transformation code",
|
||||
qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double dx = list[7].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid dx", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double dy = list[8].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid dy", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double dz = list[9].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid dz", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(e = Ellipsoid::ellipsoid(el))) {
|
||||
qWarning("%s: %d: Unknown ellipsoid code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
Datum datum;
|
||||
switch (ct) {
|
||||
case 9603:
|
||||
datum = Datum(e, dx, dy, dz);
|
||||
break;
|
||||
default:
|
||||
qWarning("%s: %d: Unknown coordinates transformation method",
|
||||
qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
GCS gcs(datum, pm, au);
|
||||
if (gcs.isValid())
|
||||
_gcss.append(Entry(id, gd, list[0].trimmed(), gcs));
|
||||
else
|
||||
qWarning("%s: %d: Unknown prime meridian/angular units code",
|
||||
qPrintable(path), ln);
|
||||
}
|
||||
}
|
||||
|
||||
Coordinates GCS::toWGS84(const Coordinates &c) const
|
||||
{
|
||||
return datum().toWGS84(Coordinates(_primeMeridian.toGreenwich(c.lon()),
|
||||
c.lat()));
|
||||
}
|
||||
|
||||
Coordinates GCS::fromWGS84(const Coordinates &c) const
|
||||
{
|
||||
Coordinates ds(datum().fromWGS84(c));
|
||||
return Coordinates(_primeMeridian.fromGreenwich(ds.lon()), ds.lat());
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const GCS &gcs)
|
||||
{
|
||||
dbg.nospace() << "GCS(" << gcs.datum() << ", " << gcs.primeMeridian()
|
||||
<< ", " << gcs.angularUnits() << ")";
|
||||
return dbg.space();
|
||||
}
|
55
src/map/gcs.h
Normal file
55
src/map/gcs.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef GCS_H
|
||||
#define GCS_H
|
||||
|
||||
#include "datum.h"
|
||||
#include "angularunits.h"
|
||||
#include "primemeridian.h"
|
||||
|
||||
class GCS
|
||||
{
|
||||
public:
|
||||
GCS() {}
|
||||
GCS(const Datum &datum, const PrimeMeridian &primeMeridian,
|
||||
const AngularUnits &angularUnits) : _datum(datum),
|
||||
_primeMeridian(primeMeridian), _angularUnits(angularUnits) {}
|
||||
|
||||
const PrimeMeridian &primeMeridian() const {return _primeMeridian;}
|
||||
const AngularUnits &angularUnits() const {return _angularUnits;}
|
||||
const Datum &datum() const {return _datum;}
|
||||
|
||||
bool isNull() const {return _datum.isNull() && _angularUnits.isNull()
|
||||
&& _primeMeridian.isNull();}
|
||||
bool isValid() const {return _datum.isValid() && _angularUnits.isValid()
|
||||
&& _primeMeridian.isValid();}
|
||||
|
||||
Coordinates toWGS84(const Coordinates &c) const;
|
||||
Coordinates fromWGS84(const Coordinates &c) const;
|
||||
|
||||
|
||||
static const GCS *gcs(int id);
|
||||
static const GCS *gcs(int geodeticDatum, int primeMeridian,
|
||||
int angularUnits);
|
||||
static const GCS *gcs(const QString &name);
|
||||
|
||||
static void loadList(const QString &path);
|
||||
|
||||
private:
|
||||
class Entry;
|
||||
|
||||
static QList<Entry> WGS84();
|
||||
|
||||
Datum _datum;
|
||||
PrimeMeridian _primeMeridian;
|
||||
AngularUnits _angularUnits;
|
||||
|
||||
static QList<Entry> _gcss;
|
||||
};
|
||||
|
||||
inline bool operator==(const GCS &gcs1, const GCS &gcs2)
|
||||
{return (gcs1.datum() == gcs2.datum()
|
||||
&& gcs1.primeMeridian() == gcs2.primeMeridian()
|
||||
&& gcs1.angularUnits() == gcs2.angularUnits());}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const GCS &gcs);
|
||||
|
||||
#endif // GCS_H
|
484
src/map/geotiff.cpp
Normal file
484
src/map/geotiff.cpp
Normal file
@ -0,0 +1,484 @@
|
||||
#include <QFileInfo>
|
||||
#include <QtEndian>
|
||||
#include "pcs.h"
|
||||
#include "latlon.h"
|
||||
#include "geotiff.h"
|
||||
|
||||
|
||||
#define TIFF_DOUBLE 12
|
||||
#define TIFF_SHORT 3
|
||||
#define TIFF_LONG 4
|
||||
|
||||
#define ModelPixelScaleTag 33550
|
||||
#define ModelTiepointTag 33922
|
||||
#define ModelTransformationTag 34264
|
||||
#define GeoKeyDirectoryTag 34735
|
||||
#define GeoDoubleParamsTag 34736
|
||||
#define ImageWidth 256
|
||||
#define ImageHeight 257
|
||||
|
||||
#define GTModelTypeGeoKey 1024
|
||||
#define GTRasterTypeGeoKey 1025
|
||||
#define GeographicTypeGeoKey 2048
|
||||
#define GeogGeodeticDatumGeoKey 2050
|
||||
#define GeogPrimeMeridianGeoKey 2051
|
||||
#define GeogAngularUnitsGeoKey 2054
|
||||
#define ProjectedCSTypeGeoKey 3072
|
||||
#define ProjectionGeoKey 3074
|
||||
#define ProjCoordTransGeoKey 3075
|
||||
#define ProjLinearUnitsGeoKey 3076
|
||||
#define ProjStdParallel1GeoKey 3078
|
||||
#define ProjStdParallel2GeoKey 3079
|
||||
#define ProjNatOriginLongGeoKey 3080
|
||||
#define ProjNatOriginLatGeoKey 3081
|
||||
#define ProjFalseEastingGeoKey 3082
|
||||
#define ProjFalseNorthingGeoKey 3083
|
||||
#define ProjScaleAtNatOriginGeoKey 3092
|
||||
|
||||
#define ModelTypeProjected 1
|
||||
#define ModelTypeGeographic 2
|
||||
#define ModelTypeGeocentric 3
|
||||
|
||||
#define IS_SET(map, key) \
|
||||
((map).contains(key) && (map).value(key).SHORT != 32767)
|
||||
|
||||
#define ARRAY_SIZE(a) \
|
||||
(sizeof(a) / sizeof(*a))
|
||||
|
||||
typedef struct {
|
||||
quint16 KeyDirectoryVersion;
|
||||
quint16 KeyRevision;
|
||||
quint16 MinorRevision;
|
||||
quint16 NumberOfKeys;
|
||||
} Header;
|
||||
|
||||
typedef struct {
|
||||
quint16 KeyID;
|
||||
quint16 TIFFTagLocation;
|
||||
quint16 Count;
|
||||
quint16 ValueOffset;
|
||||
} KeyEntry;
|
||||
|
||||
|
||||
bool GeoTIFF::readEntry(TIFFFile &file, Ctx &ctx) const
|
||||
{
|
||||
quint16 tag;
|
||||
quint16 type;
|
||||
quint32 count, offset;
|
||||
|
||||
if (!file.readValue(tag))
|
||||
return false;
|
||||
if (!file.readValue(type))
|
||||
return false;
|
||||
if (!file.readValue(count))
|
||||
return false;
|
||||
if (!file.readValue(offset))
|
||||
return false;
|
||||
|
||||
switch (tag) {
|
||||
case ModelPixelScaleTag:
|
||||
if (type != TIFF_DOUBLE || count != 3)
|
||||
return false;
|
||||
ctx.scale = offset;
|
||||
break;
|
||||
case ModelTiepointTag:
|
||||
if (type != TIFF_DOUBLE || count < 6 || count % 6)
|
||||
return false;
|
||||
ctx.tiepoints = offset;
|
||||
ctx.tiepointCount = count / 6;
|
||||
break;
|
||||
case GeoKeyDirectoryTag:
|
||||
if (type != TIFF_SHORT)
|
||||
return false;
|
||||
ctx.keys = offset;
|
||||
break;
|
||||
case GeoDoubleParamsTag:
|
||||
if (type != TIFF_DOUBLE)
|
||||
return false;
|
||||
ctx.values = offset;
|
||||
break;
|
||||
case ModelTransformationTag:
|
||||
if (type != TIFF_DOUBLE || count != 16)
|
||||
return false;
|
||||
ctx.matrix = offset;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoTIFF::readIFD(TIFFFile &file, quint32 &offset, Ctx &ctx) const
|
||||
{
|
||||
quint16 count;
|
||||
|
||||
if (!file.seek(offset))
|
||||
return false;
|
||||
if (!file.readValue(count))
|
||||
return false;
|
||||
|
||||
for (quint16 i = 0; i < count; i++)
|
||||
if (!readEntry(file, ctx))
|
||||
return false;
|
||||
|
||||
if (!file.readValue(offset))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoTIFF::readScale(TIFFFile &file, quint32 offset, QPointF &scale) const
|
||||
{
|
||||
if (!file.seek(offset))
|
||||
return false;
|
||||
|
||||
if (!file.readValue(scale.rx()))
|
||||
return false;
|
||||
if (!file.readValue(scale.ry()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoTIFF::readTiepoints(TIFFFile &file, quint32 offset, quint32 count,
|
||||
QList<ReferencePoint> &points) const
|
||||
{
|
||||
double z, pz;
|
||||
QPointF xy, pp;
|
||||
|
||||
if (!file.seek(offset))
|
||||
return false;
|
||||
|
||||
for (quint32 i = 0; i < count; i++) {
|
||||
if (!file.readValue(xy.rx()))
|
||||
return false;
|
||||
if (!file.readValue(xy.ry()))
|
||||
return false;
|
||||
if (!file.readValue(z))
|
||||
return false;
|
||||
|
||||
if (!file.readValue(pp.rx()))
|
||||
return false;
|
||||
if (!file.readValue(pp.ry()))
|
||||
return false;
|
||||
if (!file.readValue(pz))
|
||||
return false;
|
||||
|
||||
ReferencePoint p;
|
||||
p.xy = xy.toPoint();
|
||||
p.pp = pp;
|
||||
points.append(p);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoTIFF::readMatrix(TIFFFile &file, quint32 offset, double matrix[16]) const
|
||||
{
|
||||
if (!file.seek(offset))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
if (!file.readValue(matrix[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoTIFF::readKeys(TIFFFile &file, Ctx &ctx, QMap<quint16, Value> &kv) const
|
||||
{
|
||||
Header header;
|
||||
KeyEntry entry;
|
||||
Value value;
|
||||
|
||||
if (!file.seek(ctx.keys))
|
||||
return false;
|
||||
|
||||
if (!file.readValue(header.KeyDirectoryVersion))
|
||||
return false;
|
||||
if (!file.readValue(header.KeyRevision))
|
||||
return false;
|
||||
if (!file.readValue(header.MinorRevision))
|
||||
return false;
|
||||
if (!file.readValue(header.NumberOfKeys))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < header.NumberOfKeys; i++) {
|
||||
if (!file.readValue(entry.KeyID))
|
||||
return false;
|
||||
if (!file.readValue(entry.TIFFTagLocation))
|
||||
return false;
|
||||
if (!file.readValue(entry.Count))
|
||||
return false;
|
||||
if (!file.readValue(entry.ValueOffset))
|
||||
return false;
|
||||
|
||||
switch (entry.KeyID) {
|
||||
case GTModelTypeGeoKey:
|
||||
case GTRasterTypeGeoKey:
|
||||
case GeographicTypeGeoKey:
|
||||
case GeogGeodeticDatumGeoKey:
|
||||
case GeogPrimeMeridianGeoKey:
|
||||
case GeogAngularUnitsGeoKey:
|
||||
case ProjectedCSTypeGeoKey:
|
||||
case ProjectionGeoKey:
|
||||
case ProjCoordTransGeoKey:
|
||||
case ProjLinearUnitsGeoKey:
|
||||
if (entry.TIFFTagLocation != 0 || entry.Count != 1)
|
||||
return false;
|
||||
value.SHORT = entry.ValueOffset;
|
||||
kv.insert(entry.KeyID, value);
|
||||
break;
|
||||
case ProjScaleAtNatOriginGeoKey:
|
||||
case ProjNatOriginLongGeoKey:
|
||||
case ProjNatOriginLatGeoKey:
|
||||
case ProjFalseEastingGeoKey:
|
||||
case ProjFalseNorthingGeoKey:
|
||||
case ProjStdParallel1GeoKey:
|
||||
case ProjStdParallel2GeoKey:
|
||||
if (!readGeoValue(file, ctx.values, entry.ValueOffset,
|
||||
value.DOUBLE))
|
||||
return false;
|
||||
kv.insert(entry.KeyID, value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoTIFF::readGeoValue(TIFFFile &file, quint32 offset, quint16 index,
|
||||
double &val) const
|
||||
{
|
||||
qint64 pos = file.pos();
|
||||
|
||||
if (!file.seek(offset + index * sizeof(double)))
|
||||
return false;
|
||||
if (!file.readValue(val))
|
||||
return false;
|
||||
|
||||
if (!file.seek(pos))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const GCS *GeoTIFF::gcs(QMap<quint16, Value> &kv)
|
||||
{
|
||||
const GCS *gcs = 0;
|
||||
|
||||
if (IS_SET(kv, GeographicTypeGeoKey)) {
|
||||
if (!(gcs = GCS::gcs(kv.value(GeographicTypeGeoKey).SHORT)))
|
||||
_errorString = QString("%1: unknown GCS")
|
||||
.arg(kv.value(GeographicTypeGeoKey).SHORT);
|
||||
} else if (IS_SET(kv, GeogGeodeticDatumGeoKey)) {
|
||||
int pm = IS_SET(kv, GeogPrimeMeridianGeoKey)
|
||||
? kv.value(GeogPrimeMeridianGeoKey).SHORT : 8901;
|
||||
int au = IS_SET(kv, GeogAngularUnitsGeoKey)
|
||||
? kv.value(GeogAngularUnitsGeoKey).SHORT : 9102;
|
||||
|
||||
if (!(gcs = GCS::gcs(kv.value(GeogGeodeticDatumGeoKey).SHORT, pm, au)))
|
||||
_errorString = QString("%1+%2: unknown geodetic datum + prime"
|
||||
" meridian combination")
|
||||
.arg(kv.value(GeogGeodeticDatumGeoKey).SHORT)
|
||||
.arg(kv.value(GeogPrimeMeridianGeoKey).SHORT);
|
||||
} else
|
||||
_errorString = "Can not determine GCS";
|
||||
|
||||
return gcs;
|
||||
}
|
||||
|
||||
Projection::Method GeoTIFF::method(QMap<quint16, Value> &kv)
|
||||
{
|
||||
if (!IS_SET(kv, ProjCoordTransGeoKey)) {
|
||||
_errorString = "Missing coordinate transformation method";
|
||||
return Projection::Method();
|
||||
}
|
||||
|
||||
switch (kv.value(ProjCoordTransGeoKey).SHORT) {
|
||||
case 1:
|
||||
return Projection::Method(9807);
|
||||
case 7:
|
||||
return Projection::Method(1024);
|
||||
case 8:
|
||||
return Projection::Method(9801);
|
||||
case 9:
|
||||
return Projection::Method(9802);
|
||||
case 10:
|
||||
return Projection::Method(9820);
|
||||
case 11:
|
||||
return Projection::Method(9822);
|
||||
default:
|
||||
_errorString = QString("%1: unknown coordinate transformation method")
|
||||
.arg(kv.value(ProjCoordTransGeoKey).SHORT);
|
||||
return Projection::Method();
|
||||
}
|
||||
}
|
||||
|
||||
bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
|
||||
{
|
||||
if (IS_SET(kv, ProjectedCSTypeGeoKey)) {
|
||||
const PCS *pcs;
|
||||
if (!(pcs = PCS::pcs(kv.value(ProjectedCSTypeGeoKey).SHORT))) {
|
||||
_errorString = QString("%1: unknown PCS")
|
||||
.arg(kv.value(ProjectedCSTypeGeoKey).SHORT);
|
||||
return false;
|
||||
}
|
||||
_projection = Projection(pcs->gcs(), pcs->method(), pcs->setup(),
|
||||
pcs->units());
|
||||
} else if (IS_SET(kv, ProjectionGeoKey)) {
|
||||
const GCS *g = gcs(kv);
|
||||
if (!g)
|
||||
return false;
|
||||
const PCS *pcs = PCS::pcs(g, kv.value(ProjectionGeoKey).SHORT);
|
||||
if (!pcs) {
|
||||
_errorString = QString("%1: unknown projection code")
|
||||
.arg(kv.value(GeographicTypeGeoKey).SHORT)
|
||||
.arg(kv.value(ProjectionGeoKey).SHORT);
|
||||
return false;
|
||||
}
|
||||
_projection = Projection(pcs->gcs(), pcs->method(), pcs->setup(),
|
||||
pcs->units());
|
||||
} else {
|
||||
const GCS *g = gcs(kv);
|
||||
if (!g)
|
||||
return false;
|
||||
Projection::Method m(method(kv));
|
||||
if (m.isNull())
|
||||
return false;
|
||||
|
||||
AngularUnits au(IS_SET(kv, GeogAngularUnitsGeoKey)
|
||||
? kv.value(GeogAngularUnitsGeoKey).SHORT : 9102);
|
||||
LinearUnits lu(IS_SET(kv, ProjLinearUnitsGeoKey)
|
||||
? kv.value(ProjLinearUnitsGeoKey).SHORT : 9001);
|
||||
if (lu.isNull()) {
|
||||
_errorString = QString("%1: unknown projection linear units code")
|
||||
.arg(kv.value(ProjLinearUnitsGeoKey).SHORT);
|
||||
return false;
|
||||
}
|
||||
|
||||
Projection::Setup setup(
|
||||
au.toDegrees(kv.value(ProjNatOriginLatGeoKey).DOUBLE),
|
||||
au.toDegrees(kv.value(ProjNatOriginLongGeoKey).DOUBLE),
|
||||
kv.value(ProjScaleAtNatOriginGeoKey).DOUBLE,
|
||||
lu.toMeters(kv.value(ProjFalseEastingGeoKey).DOUBLE),
|
||||
lu.toMeters(kv.value(ProjFalseNorthingGeoKey).DOUBLE),
|
||||
au.toDegrees(kv.value(ProjStdParallel1GeoKey).DOUBLE),
|
||||
au.toDegrees(kv.value(ProjStdParallel2GeoKey).DOUBLE)
|
||||
);
|
||||
|
||||
_projection = Projection(g, m, setup, lu);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoTIFF::geographicModel(QMap<quint16, Value> &kv)
|
||||
{
|
||||
const GCS *g = gcs(kv);
|
||||
if (!g)
|
||||
return false;
|
||||
|
||||
_projection = Projection(g);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoTIFF::load(const QString &path)
|
||||
{
|
||||
quint32 ifd;
|
||||
QList<ReferencePoint> points;
|
||||
QPointF scale;
|
||||
QMap<quint16, Value> kv;
|
||||
Ctx ctx;
|
||||
TIFFFile file;
|
||||
|
||||
|
||||
file.setFileName(path);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
_errorString = QString("Error opening TIFF file: %1")
|
||||
.arg(file.errorString());
|
||||
return false;
|
||||
}
|
||||
if (!file.readHeader(ifd)) {
|
||||
_errorString = "Invalid TIFF header";
|
||||
return false;
|
||||
}
|
||||
|
||||
while (ifd) {
|
||||
if (!readIFD(file, ifd, ctx)) {
|
||||
_errorString = "Invalid IFD";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx.keys) {
|
||||
_errorString = "Not a GeoTIFF file";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctx.scale) {
|
||||
if (!readScale(file, ctx.scale, scale)) {
|
||||
_errorString = "Error reading model pixel scale";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (ctx.tiepoints) {
|
||||
if (!readTiepoints(file, ctx.tiepoints, ctx.tiepointCount, points)) {
|
||||
_errorString = "Error reading raster->model tiepoint pairs";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!readKeys(file, ctx, kv)) {
|
||||
_errorString = "Error reading Geo key/value";
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (kv.value(GTModelTypeGeoKey).SHORT) {
|
||||
case ModelTypeProjected:
|
||||
if (!projectedModel(kv))
|
||||
return false;
|
||||
break;
|
||||
case ModelTypeGeographic:
|
||||
if (!geographicModel(kv))
|
||||
return false;
|
||||
break;
|
||||
case ModelTypeGeocentric:
|
||||
_errorString = "Geocentric models are not supported";
|
||||
return false;
|
||||
default:
|
||||
_errorString = "Unknown/missing model type";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctx.scale && ctx.tiepoints) {
|
||||
const ReferencePoint &p = points.first();
|
||||
_transform = QTransform(scale.x(), 0, 0, -scale.y(), p.pp.x() - p.xy.x()
|
||||
/ scale.x(), p.pp.y() + p.xy.x() / scale.y()).inverted();
|
||||
} else if (ctx.tiepointCount > 1) {
|
||||
Transform t(points);
|
||||
if (t.isNull()) {
|
||||
_errorString = t.errorString();
|
||||
return false;
|
||||
}
|
||||
_transform = t.transform();
|
||||
} else if (ctx.matrix) {
|
||||
double m[16];
|
||||
if (!readMatrix(file, ctx.matrix, m)) {
|
||||
_errorString = "Error reading transformation matrix";
|
||||
return false;
|
||||
}
|
||||
if (m[2] != 0.0 || m[6] != 0.0 || m[8] != 0.0 || m[9] != 0.0
|
||||
|| m[10] != 0.0 || m[11] != 0.0) {
|
||||
_errorString = "Not a baseline transformation matrix";
|
||||
}
|
||||
_transform = QTransform(m[0], m[1], m[4], m[5], m[3], m[7]).inverted();
|
||||
} else {
|
||||
_errorString = "Incomplete/missing model transformation info";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
61
src/map/geotiff.h
Normal file
61
src/map/geotiff.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef GEOTIFF_H
|
||||
#define GEOTIFF_H
|
||||
|
||||
#include <QTransform>
|
||||
#include <QFile>
|
||||
#include <QMap>
|
||||
#include "gcs.h"
|
||||
#include "projection.h"
|
||||
#include "tifffile.h"
|
||||
#include "transform.h"
|
||||
#include "linearunits.h"
|
||||
|
||||
class GeoTIFF
|
||||
{
|
||||
public:
|
||||
bool load(const QString &path);
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
const Projection &projection() const {return _projection;}
|
||||
const QTransform &transform() const {return _transform;}
|
||||
|
||||
private:
|
||||
union Value {
|
||||
quint16 SHORT;
|
||||
double DOUBLE;
|
||||
};
|
||||
|
||||
struct Ctx {
|
||||
quint32 scale;
|
||||
quint32 tiepoints;
|
||||
quint32 tiepointCount;
|
||||
quint32 matrix;
|
||||
quint32 keys;
|
||||
quint32 values;
|
||||
|
||||
Ctx() : scale(0), tiepoints(0), tiepointCount(0), matrix(0), keys(0),
|
||||
values(0) {}
|
||||
};
|
||||
|
||||
bool readEntry(TIFFFile &file, Ctx &ctx) const;
|
||||
bool readIFD(TIFFFile &file, quint32 &offset, Ctx &ctx) const;
|
||||
bool readScale(TIFFFile &file, quint32 offset, QPointF &scale) const;
|
||||
bool readTiepoints(TIFFFile &file, quint32 offset, quint32 count,
|
||||
QList<ReferencePoint> &points) const;
|
||||
bool readMatrix(TIFFFile &file, quint32 offset, double matrix[16]) const;
|
||||
bool readKeys(TIFFFile &file, Ctx &ctx, QMap<quint16, Value> &kv) const;
|
||||
bool readGeoValue(TIFFFile &file, quint32 offset, quint16 index,
|
||||
double &val) const;
|
||||
|
||||
const GCS *gcs(QMap<quint16, Value> &kv);
|
||||
Projection::Method method(QMap<quint16, Value> &kv);
|
||||
bool geographicModel(QMap<quint16, Value> &kv);
|
||||
bool projectedModel(QMap<quint16, Value> &kv);
|
||||
|
||||
QTransform _transform;
|
||||
Projection _projection;
|
||||
|
||||
QString _errorString;
|
||||
};
|
||||
|
||||
#endif // GEOTIFF_H
|
@ -48,19 +48,19 @@ Defense.
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#endif // M_PI_2
|
||||
|
||||
LambertAzimuthal::LambertAzimuthal(const Ellipsoid &ellipsoid,
|
||||
LambertAzimuthal::LambertAzimuthal(const Ellipsoid *ellipsoid,
|
||||
double latitudeOrigin, double longitudeOrigin, double falseEasting,
|
||||
double falseNorthing)
|
||||
{
|
||||
double es2, es4, es6;
|
||||
|
||||
_e = ellipsoid;
|
||||
es2 = 2 * _e.flattening() - _e.flattening() * _e.flattening();
|
||||
es2 = 2 * ellipsoid->flattening() - ellipsoid->flattening()
|
||||
* ellipsoid->flattening();
|
||||
|
||||
es4 = es2 * es2;
|
||||
es6 = es4 * es2;
|
||||
_ra = _e.radius() * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6
|
||||
/ 3024.0);
|
||||
_ra = ellipsoid->radius() * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0
|
||||
* es6 / 3024.0);
|
||||
_latOrigin = deg2rad(latitudeOrigin);
|
||||
_sinLatOrigin = sin(_latOrigin);
|
||||
_cosLatOrigin = cos(_latOrigin);
|
||||
|
@ -2,20 +2,20 @@
|
||||
#define LAMBERTAZIMUTHAL_H
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
|
||||
class LambertAzimuthal : public Projection
|
||||
class LambertAzimuthal : public CT
|
||||
{
|
||||
public:
|
||||
LambertAzimuthal(const Ellipsoid &ellipsoid, double latitudeOrigin,
|
||||
LambertAzimuthal(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double falseEasting, double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new LambertAzimuthal(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
Ellipsoid _e;
|
||||
|
||||
double _ra;
|
||||
double _sinLatOrigin;
|
||||
double _cosLatOrigin;
|
||||
|
@ -1,3 +1,46 @@
|
||||
/*
|
||||
* Based on libgeotrans with the following Source Code Disclaimer:
|
||||
|
||||
1. The GEOTRANS source code ("the software") is provided free of charge by
|
||||
the National Imagery and Mapping Agency (NIMA) of the United States
|
||||
Department of Defense. Although NIMA makes no copyright claim under Title 17
|
||||
U.S.C., NIMA claims copyrights in the source code under other legal regimes.
|
||||
NIMA hereby grants to each user of the software a license to use and
|
||||
distribute the software, and develop derivative works.
|
||||
|
||||
2. Warranty Disclaimer: The software was developed to meet only the internal
|
||||
requirements of the U.S. National Imagery and Mapping Agency. The software
|
||||
is provided "as is," and no warranty, express or implied, including but not
|
||||
limited to the implied warranties of merchantability and fitness for
|
||||
particular purpose or arising by statute or otherwise in law or from a
|
||||
course of dealing or usage in trade, is made by NIMA as to the accuracy and
|
||||
functioning of the software.
|
||||
|
||||
3. NIMA and its personnel are not required to provide technical support or
|
||||
general assistance with respect to the software.
|
||||
|
||||
4. Neither NIMA nor its personnel will be liable for any claims, losses, or
|
||||
damages arising from or connected with the use of the software. The user
|
||||
agrees to hold harmless the United States National Imagery and Mapping
|
||||
Agency. The user's sole and exclusive remedy is to stop using the software.
|
||||
|
||||
5. NIMA requests that products developed using the software credit the
|
||||
source of the software with the following statement, "The product was
|
||||
developed using GEOTRANS, a product of the National Imagery and Mapping
|
||||
Agency and U.S. Army Engineering Research and Development Center."
|
||||
|
||||
6. For any products developed using the software, NIMA requires a disclaimer
|
||||
that use of the software does not indicate endorsement or approval of the
|
||||
product by the Secretary of Defense or the National Imagery and Mapping
|
||||
Agency. Pursuant to the United States Code, 10 U.S.C. Sec. 2797, the name of
|
||||
the National Imagery and Mapping Agency, the initials "NIMA", the seal of
|
||||
the National Imagery and Mapping Agency, or any colorable imitation thereof
|
||||
shall not be used to imply approval, endorsement, or authorization of a
|
||||
product without prior written permission from United States Secretary of
|
||||
Defense.
|
||||
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include "lambertconic.h"
|
||||
|
||||
@ -5,76 +48,229 @@
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#endif // M_PI_2
|
||||
#ifndef M_PI_4
|
||||
#define M_PI_4 0.78539816339744830962
|
||||
#endif // M_PI_4
|
||||
#define M_PI_4 0.785398163397448309616
|
||||
#endif /* M_PI_4 */
|
||||
|
||||
static double q(const Ellipsoid &el, double b)
|
||||
#define LAMBERT_m(clat, essin) (clat / sqrt(1.0 - essin * essin))
|
||||
#define LAMBERT2_t(lat, essin, es_over_2) \
|
||||
(tan(M_PI_4 - lat / 2) * pow((1.0 + essin) / (1.0 - essin), es_over_2))
|
||||
#define LAMBERT1_t(lat, essin, es_over_2) \
|
||||
(tan(M_PI_4 - lat / 2) / pow((1.0 - essin) / (1.0 + essin), es_over_2))
|
||||
|
||||
|
||||
LambertConic1::LambertConic1(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double scale, double falseEasting,
|
||||
double falseNorthing)
|
||||
{
|
||||
double e = sqrt(el.flattening() * (2. - el.flattening()));
|
||||
double esb = e * sin(b);
|
||||
return log(tan(M_PI_4 + b / 2.) * pow((1. - esb) / (1. + esb), e / 2.));
|
||||
double es2;
|
||||
double es_sin;
|
||||
double m0;
|
||||
double lat_orig;
|
||||
|
||||
|
||||
lat_orig = deg2rad(latitudeOrigin);
|
||||
_longitudeOrigin = deg2rad(longitudeOrigin);
|
||||
if (_longitudeOrigin > M_PI)
|
||||
_longitudeOrigin -= 2 * M_PI;
|
||||
|
||||
_falseEasting = falseEasting;
|
||||
_falseNorthing = falseNorthing;
|
||||
|
||||
es2 = 2.0 * ellipsoid->flattening() - ellipsoid->flattening()
|
||||
* ellipsoid->flattening();
|
||||
_es = sqrt(es2);
|
||||
_es_over_2 = _es / 2.0;
|
||||
|
||||
_n = sin(lat_orig);
|
||||
|
||||
es_sin = _es * sin(lat_orig);
|
||||
m0 = LAMBERT_m(cos(lat_orig), es_sin);
|
||||
_t0 = LAMBERT1_t(lat_orig, es_sin, _es_over_2);
|
||||
|
||||
_rho0 = ellipsoid->radius() * scale * m0 / _n;
|
||||
|
||||
_rho_olat = _rho0;
|
||||
}
|
||||
|
||||
static double iq(const Ellipsoid &el, double q)
|
||||
QPointF LambertConic1::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
double e = sqrt(el.flattening() * (2. - el.flattening()));
|
||||
double b0 = 0.;
|
||||
double b = 2. * atan(exp(q)) - M_PI_2;
|
||||
double t;
|
||||
double rho;
|
||||
double dlam;
|
||||
double theta;
|
||||
double lat = deg2rad(c.lat());
|
||||
|
||||
do {
|
||||
b0 = b;
|
||||
double esb = e * sin(b);
|
||||
b = 2. * atan(exp(q) * pow((1. - esb) / (1. + esb), -e / 2.)) - M_PI_2;
|
||||
} while (fabs(b - b0) > 1e-10);
|
||||
|
||||
return b;
|
||||
if (fabs(fabs(lat) - M_PI_2) > 1.0e-10) {
|
||||
t = LAMBERT1_t(lat, _es * sin(lat), _es_over_2);
|
||||
rho = _rho0 * pow(t / _t0, _n);
|
||||
} else
|
||||
rho = 0.0;
|
||||
|
||||
dlam = deg2rad(c.lon()) - _longitudeOrigin;
|
||||
|
||||
if (dlam > M_PI)
|
||||
dlam -= 2 * M_PI;
|
||||
if (dlam < -M_PI)
|
||||
dlam += 2 * M_PI;
|
||||
|
||||
theta = _n * dlam;
|
||||
|
||||
return QPointF(rho * sin(theta) + _falseEasting, _rho_olat - rho
|
||||
* cos(theta) + _falseNorthing);
|
||||
}
|
||||
|
||||
static double nradius(const Ellipsoid &el, double phi)
|
||||
Coordinates LambertConic1::xy2ll(const QPointF &p) const
|
||||
{
|
||||
double sin_phi = sin(phi);
|
||||
return (el.radius() / sqrt(1. - (el.flattening() * (2. - el.flattening()))
|
||||
* sin_phi * sin_phi));
|
||||
double dx;
|
||||
double dy;
|
||||
double rho;
|
||||
double rho_olat_minus_dy;
|
||||
double t;
|
||||
double PHI;
|
||||
double es_sin;
|
||||
double tempPHI = 0.0;
|
||||
double theta = 0.0;
|
||||
double tolerance = 4.85e-10;
|
||||
int count = 30;
|
||||
double lat, lon;
|
||||
|
||||
|
||||
dy = p.y() - _falseNorthing;
|
||||
dx = p.x() - _falseEasting;
|
||||
rho_olat_minus_dy = _rho_olat - dy;
|
||||
rho = sqrt(dx * dx + (rho_olat_minus_dy) * (rho_olat_minus_dy));
|
||||
|
||||
if (_n < 0.0) {
|
||||
rho *= -1.0;
|
||||
dx *= -1.0;
|
||||
rho_olat_minus_dy *= -1.0;
|
||||
}
|
||||
|
||||
if (rho != 0.0) {
|
||||
theta = atan2(dx, rho_olat_minus_dy) / _n;
|
||||
t = _t0 * pow(rho / _rho0, 1 / _n);
|
||||
PHI = M_PI_2 - 2.0 * atan(t);
|
||||
while (fabs(PHI - tempPHI) > tolerance && count) {
|
||||
tempPHI = PHI;
|
||||
es_sin = _es * sin(PHI);
|
||||
PHI = M_PI_2 - 2.0 * atan(t * pow((1.0 - es_sin) / (1.0 + es_sin),
|
||||
_es_over_2));
|
||||
count--;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return Coordinates();
|
||||
|
||||
lat = PHI;
|
||||
lon = theta + _longitudeOrigin;
|
||||
|
||||
if (fabs(lat) < 2.0e-7)
|
||||
lat = 0.0;
|
||||
if (lat > M_PI_2)
|
||||
lat = M_PI_2;
|
||||
else if (lat < -M_PI_2)
|
||||
lat = -M_PI_2;
|
||||
|
||||
if (lon > M_PI) {
|
||||
if (lon - M_PI < 3.5e-6)
|
||||
lon = M_PI;
|
||||
else
|
||||
lon -= 2 * M_PI;
|
||||
}
|
||||
if (lon < -M_PI) {
|
||||
if (fabs(lon + M_PI) < 3.5e-6)
|
||||
lon = -M_PI;
|
||||
else
|
||||
lon += 2 * M_PI;
|
||||
}
|
||||
|
||||
if (fabs(lon) < 2.0e-7)
|
||||
lon = 0.0;
|
||||
if (lon > M_PI)
|
||||
lon = M_PI;
|
||||
else if (lon < -M_PI)
|
||||
lon = -M_PI;
|
||||
} else {
|
||||
if (_n > 0.0)
|
||||
lat = M_PI_2;
|
||||
else
|
||||
lat = -M_PI_2;
|
||||
lon = _longitudeOrigin;
|
||||
}
|
||||
|
||||
return Coordinates(rad2deg(lon), rad2deg(lat));
|
||||
}
|
||||
|
||||
LambertConic::LambertConic(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double scale, double falseEasting, double falseNorthing) : _e(ellipsoid)
|
||||
LambertConic2::LambertConic2(const Ellipsoid *ellipsoid,
|
||||
double standardParallel1, double standardParallel2, double latitudeOrigin,
|
||||
double longitudeOrigin, double falseEasting, double falseNorthing)
|
||||
{
|
||||
_cm = deg2rad(longitudeOrigin);
|
||||
_fe = falseEasting;
|
||||
_fn = falseNorthing;
|
||||
double es, es_over_2, es2, es_sin;
|
||||
double lat0;
|
||||
double k0;
|
||||
double t0;
|
||||
double t1, t2;
|
||||
double t_olat;
|
||||
double m0;
|
||||
double m1;
|
||||
double m2;
|
||||
double n;
|
||||
double const_value;
|
||||
double sp1, sp2;
|
||||
double lat_orig;
|
||||
|
||||
double sp1 = deg2rad(standardParallel1);
|
||||
double sp2 = deg2rad(standardParallel2);
|
||||
|
||||
double N1 = nradius(_e, sp1);
|
||||
double N2 = nradius(_e, sp2);
|
||||
lat_orig = deg2rad(latitudeOrigin);
|
||||
sp1 = deg2rad(standardParallel1);
|
||||
sp2 = deg2rad(standardParallel2);
|
||||
|
||||
_q0 = q(_e, deg2rad(latitudeOrigin));
|
||||
double q1 = q(_e, sp1);
|
||||
double q2 = q(_e, sp2);
|
||||
if (fabs(sp1 - sp2) > 1.0e-10) {
|
||||
es2 = 2 * ellipsoid->flattening() - ellipsoid->flattening()
|
||||
* ellipsoid->flattening();
|
||||
es = sqrt(es2);
|
||||
es_over_2 = es / 2.0;
|
||||
|
||||
_n = log((N1 * cos(sp1)) / (N2 * cos(sp2))) / (q2 - q1);
|
||||
double R1 = N1 * cos(sp1) / _n;
|
||||
_R0 = scale * R1 * exp(_n * (q1 - _q0));
|
||||
es_sin = es * sin(lat_orig);
|
||||
t_olat = LAMBERT2_t(lat_orig, es_sin, es_over_2);
|
||||
|
||||
es_sin = es * sin(sp1);
|
||||
m1 = LAMBERT_m(cos(sp1), es_sin);
|
||||
t1 = LAMBERT2_t(sp1, es_sin, es_over_2);
|
||||
|
||||
es_sin = es * sin(sp2);
|
||||
m2 = LAMBERT_m(cos(sp2), es_sin);
|
||||
t2 = LAMBERT2_t(sp2, es_sin, es_over_2);
|
||||
|
||||
n = log(m1 / m2) / log(t1 / t2);
|
||||
|
||||
lat0 = asin(n);
|
||||
|
||||
es_sin = es * sin(lat0);
|
||||
m0 = LAMBERT_m(cos(lat0), es_sin);
|
||||
t0 = LAMBERT2_t(lat0, es_sin, es_over_2);
|
||||
|
||||
k0 = (m1 / m0) * (pow(t0 / t1, n));
|
||||
|
||||
const_value = ((ellipsoid->radius() * m2) / (n * pow(t2, n)));
|
||||
|
||||
falseNorthing += (const_value * pow(t_olat, n)) - (const_value
|
||||
* pow(t0, n));
|
||||
} else {
|
||||
lat0 = sp1;
|
||||
k0 = 1.0;
|
||||
}
|
||||
|
||||
_lc1 = LambertConic1(ellipsoid, rad2deg(lat0), longitudeOrigin, k0,
|
||||
falseEasting, falseNorthing);
|
||||
}
|
||||
|
||||
QPointF LambertConic::ll2xy(const Coordinates &c) const
|
||||
QPointF LambertConic2::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
double dl = _n * (deg2rad(c.lon()) - _cm);
|
||||
double R = _R0 * exp(_n * (_q0 - q(_e, deg2rad(c.lat()))));
|
||||
|
||||
return QPointF(_fe + R * sin(dl), _fn + _R0 - R * cos(dl));
|
||||
return _lc1.ll2xy(c);
|
||||
}
|
||||
|
||||
Coordinates LambertConic::xy2ll(const QPointF &p) const
|
||||
Coordinates LambertConic2::xy2ll(const QPointF &p) const
|
||||
{
|
||||
double dl = atan((p.x() - _fe) / (_fn + _R0 - p.y()));
|
||||
double dx = p.x() - _fe;
|
||||
double dy = p.y() - _fn - _R0;
|
||||
double R = sqrt(dx * dx + dy * dy);
|
||||
double q = _q0 - log(fabs(R / _R0)) / _n;
|
||||
|
||||
return Coordinates(rad2deg(_cm + dl / _n), rad2deg(iq(_e, q)));
|
||||
return _lc1.xy2ll(p);
|
||||
}
|
||||
|
@ -2,28 +2,48 @@
|
||||
#define LAMBERTCONIC_H
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
|
||||
class LambertConic : public Projection
|
||||
class LambertConic1 : public CT
|
||||
{
|
||||
public:
|
||||
LambertConic(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double scale, double falseEasting, double falseNorthing);
|
||||
LambertConic1() {}
|
||||
LambertConic1(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double scale, double falseEasting,
|
||||
double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new LambertConic1(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
Ellipsoid _e;
|
||||
double _longitudeOrigin;
|
||||
double _falseEasting;
|
||||
double _falseNorthing;
|
||||
|
||||
double _cm;
|
||||
double _fe;
|
||||
double _fn;
|
||||
|
||||
double _q0;
|
||||
double _R0;
|
||||
double _es;
|
||||
double _es_over_2;
|
||||
double _n;
|
||||
double _t0;
|
||||
double _rho0;
|
||||
double _rho_olat;
|
||||
};
|
||||
|
||||
class LambertConic2 : public CT
|
||||
{
|
||||
public:
|
||||
LambertConic2(const Ellipsoid *ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double falseEasting, double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new LambertConic2(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
LambertConic1 _lc1;
|
||||
};
|
||||
|
||||
#endif // LAMBERTCONIC_H
|
||||
|
@ -1,15 +1,23 @@
|
||||
#ifndef LATLON_H
|
||||
#define LATLON_H
|
||||
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
#include "angularunits.h"
|
||||
|
||||
class LatLon : public Projection
|
||||
class LatLon : public CT
|
||||
{
|
||||
public:
|
||||
LatLon(const AngularUnits &au) : _au(au) {}
|
||||
|
||||
virtual CT *clone() const {return new LatLon(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const
|
||||
{return QPointF(c.lon(), c.lat());}
|
||||
{return QPointF(_au.fromDegrees(c.lon()), _au.fromDegrees(c.lat()));}
|
||||
virtual Coordinates xy2ll(const QPointF &p) const
|
||||
{return Coordinates(p.x(), p.y());}
|
||||
{return Coordinates(_au.toDegrees(p.x()), _au.toDegrees(p.y()));}
|
||||
|
||||
private:
|
||||
AngularUnits _au;
|
||||
};
|
||||
|
||||
#endif // LATLON_H
|
||||
|
27
src/map/linearunits.cpp
Normal file
27
src/map/linearunits.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "linearunits.h"
|
||||
|
||||
LinearUnits::LinearUnits(int code)
|
||||
{
|
||||
switch (code) {
|
||||
case 9001:
|
||||
_f = 1.0;
|
||||
break;
|
||||
case 9002:
|
||||
_f = 0.3048;
|
||||
break;
|
||||
case 9003:
|
||||
_f = 12.0 / 39.37;
|
||||
break;
|
||||
case 9040:
|
||||
_f = 36.0 / 39.370147;
|
||||
break;
|
||||
default:
|
||||
_f = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const LinearUnits &lu)
|
||||
{
|
||||
dbg.nospace() << "LinearUnits(" << lu._f << ")";
|
||||
return dbg.space();
|
||||
}
|
36
src/map/linearunits.h
Normal file
36
src/map/linearunits.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef LINEARUNITS_H
|
||||
#define LINEARUNITS_H
|
||||
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
#include <QPointF>
|
||||
|
||||
class LinearUnits
|
||||
{
|
||||
public:
|
||||
LinearUnits() : _f(NAN) {}
|
||||
LinearUnits(int code);
|
||||
|
||||
bool isNull() const {return std::isnan(_f);}
|
||||
bool isValid() const {return !std::isnan(_f);}
|
||||
|
||||
double toMeters(double val) const {return val * _f;}
|
||||
QPointF toMeters(const QPointF &p) const
|
||||
{return QPointF(p.x() * _f, p.y() * _f);}
|
||||
double fromMeters(double val) const {return val / _f;}
|
||||
QPointF fromMeters(const QPointF &p) const
|
||||
{return QPointF(p.x() / _f, p.y() /_f);}
|
||||
|
||||
friend bool operator==(const LinearUnits &lu1, const LinearUnits &lu2);
|
||||
friend QDebug operator<<(QDebug dbg, const LinearUnits &lu);
|
||||
|
||||
private:
|
||||
double _f;
|
||||
};
|
||||
|
||||
inline bool operator==(const LinearUnits &lu1, const LinearUnits &lu2)
|
||||
{return (lu1._f == lu2._f);}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const LinearUnits &lu);
|
||||
|
||||
#endif // LINEARUNITS_H
|
265
src/map/mapfile.cpp
Normal file
265
src/map/mapfile.cpp
Normal file
@ -0,0 +1,265 @@
|
||||
#include "utm.h"
|
||||
#include "gcs.h"
|
||||
#include "mapfile.h"
|
||||
|
||||
|
||||
static double parameter(const QString &str, bool *res)
|
||||
{
|
||||
QString field = str.trimmed();
|
||||
if (field.isEmpty()) {
|
||||
*res = true;
|
||||
return NAN;
|
||||
}
|
||||
|
||||
return field.toDouble(res);
|
||||
}
|
||||
|
||||
int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
QString &projection, Projection::Setup &setup, QString &datum)
|
||||
{
|
||||
bool res, r[8];
|
||||
int ln = 1;
|
||||
|
||||
while (!device.atEnd()) {
|
||||
QByteArray line = device.readLine();
|
||||
|
||||
if (ln == 1) {
|
||||
if (!line.trimmed().startsWith("OziExplorer Map Data File"))
|
||||
return ln;
|
||||
} else if (ln == 2)
|
||||
_name = line.trimmed();
|
||||
else if (ln == 3)
|
||||
_image = line.trimmed();
|
||||
else if (ln == 5)
|
||||
datum = line.split(',').at(0).trimmed();
|
||||
else {
|
||||
QList<QByteArray> list = line.split(',');
|
||||
QString key(list.at(0).trimmed());
|
||||
bool ll = true; bool pp = true;
|
||||
|
||||
|
||||
if (key.startsWith("Point") && list.count() == 17
|
||||
&& !list.at(2).trimmed().isEmpty()) {
|
||||
CalibrationPoint p;
|
||||
|
||||
int x = list.at(2).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
return ln;
|
||||
int y = list.at(3).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
return ln;
|
||||
|
||||
int latd = list.at(6).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
qreal latm = list.at(7).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
int lond = list.at(9).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
qreal lonm = list.at(10).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
if (ll && list.at(8).trimmed() == "S") {
|
||||
latd = -latd;
|
||||
latm = -latm;
|
||||
}
|
||||
if (ll && list.at(11).trimmed() == "W") {
|
||||
lond = -lond;
|
||||
lonm = -lonm;
|
||||
}
|
||||
|
||||
p.zone = list.at(13).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
p.zone = 0;
|
||||
qreal ppx = list.at(14).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
pp = false;
|
||||
qreal ppy = list.at(15).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
pp = false;
|
||||
if (list.at(16).trimmed() == "S")
|
||||
p.zone = -p.zone;
|
||||
|
||||
p.rp.xy = QPoint(x, y);
|
||||
if (ll) {
|
||||
p.ll = Coordinates(lond + lonm/60.0, latd + latm/60.0);
|
||||
if (p.ll.isValid())
|
||||
points.append(p);
|
||||
else
|
||||
return ln;
|
||||
} else if (pp) {
|
||||
p.rp.pp = QPointF(ppx, ppy);
|
||||
points.append(p);
|
||||
} else
|
||||
return ln;
|
||||
} else if (key == "IWH") {
|
||||
if (list.count() < 4)
|
||||
return ln;
|
||||
int w = list.at(2).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
return ln;
|
||||
int h = list.at(3).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
return ln;
|
||||
_size = QSize(w, h);
|
||||
} else if (key == "Map Projection") {
|
||||
if (list.count() < 2)
|
||||
return ln;
|
||||
projection = list.at(1);
|
||||
} else if (key == "Projection Setup") {
|
||||
if (list.count() < 8)
|
||||
return ln;
|
||||
|
||||
setup = Projection::Setup(
|
||||
parameter(list[1], &r[1]), parameter(list[2], &r[2]),
|
||||
parameter(list[3], &r[3]), parameter(list[4], &r[4]),
|
||||
parameter(list[5], &r[5]), parameter(list[6], &r[6]),
|
||||
parameter(list[7], &r[7]));
|
||||
|
||||
for (int i = 1; i < 8; i++)
|
||||
if (!r[i])
|
||||
return ln;
|
||||
}
|
||||
}
|
||||
|
||||
ln++;
|
||||
}
|
||||
|
||||
return (ln == 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
QString &projection, Projection::Setup &setup, QString &datum)
|
||||
{
|
||||
int el;
|
||||
|
||||
if (!device.open(QIODevice::ReadOnly)) {
|
||||
_errorString = QString("Error opening file: %1")
|
||||
.arg(device.errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((el = parse(device, points, projection, setup, datum))) {
|
||||
_errorString = QString("Parse error on line %1").arg(el);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const GCS *MapFile::createGCS(const QString &datum)
|
||||
{
|
||||
const GCS *gcs;
|
||||
|
||||
if (!(gcs = GCS::gcs(datum)))
|
||||
_errorString = QString("%1: Unknown datum").arg(datum);
|
||||
|
||||
return gcs;
|
||||
}
|
||||
|
||||
bool MapFile::createProjection(const GCS *gcs, const QString &name,
|
||||
const Projection::Setup &setup, QList<CalibrationPoint> &points)
|
||||
{
|
||||
if (name == "Mercator")
|
||||
_projection = Projection(gcs, 1024, setup, 9001);
|
||||
else if (name == "Transverse Mercator")
|
||||
_projection = Projection(gcs, 9807, setup, 9001);
|
||||
else if (name == "Latitude/Longitude")
|
||||
_projection = Projection(gcs);
|
||||
else if (name == "Lambert Conformal Conic")
|
||||
_projection = Projection(gcs, 9802, setup, 9001);
|
||||
else if (name == "Albers Equal Area")
|
||||
_projection = Projection(gcs, 9822, setup, 9001);
|
||||
else if (name == "(A)Lambert Azimuthual Equal Area")
|
||||
_projection = Projection(gcs, 9820, setup, 9001);
|
||||
else if (name == "(UTM) Universal Transverse Mercator") {
|
||||
int zone;
|
||||
if (points.first().zone)
|
||||
zone = points.first().zone;
|
||||
else if (!points.first().ll.isNull())
|
||||
zone = UTM::zone(points.first().ll);
|
||||
else {
|
||||
_errorString = "Can not determine UTM zone";
|
||||
return false;
|
||||
}
|
||||
_projection = Projection(gcs, 9807, UTM::setup(zone), 9001);
|
||||
} else if (name == "(NZTM2) New Zealand TM 2000")
|
||||
_projection = Projection(gcs, 9807, Projection::Setup(0, 173.0, 0.9996,
|
||||
1600000, 10000000, NAN, NAN), 9001);
|
||||
else if (name == "(BNG) British National Grid")
|
||||
_projection = Projection(gcs, 9807, Projection::Setup(49, -2, 0.999601,
|
||||
400000, -100000, NAN, NAN), 9001);
|
||||
else if (name == "(IG) Irish Grid")
|
||||
_projection = Projection(gcs, 9807, Projection::Setup(53.5, -8,
|
||||
1.000035, 200000, 250000, NAN, NAN), 9001);
|
||||
else if (name == "(SG) Swedish Grid")
|
||||
_projection = Projection(gcs, 9807, Projection::Setup(0, 15.808278, 1,
|
||||
1500000, 0, NAN, NAN), 9001);
|
||||
else if (name == "(I) France Zone I")
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(49.5, 2.337229,
|
||||
NAN, 600000, 1200000, 48.598523, 50.395912), 9001);
|
||||
else if (name == "(II) France Zone II")
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(46.8, 2.337229,
|
||||
NAN, 600000, 2200000, 45.898919, 47.696014), 9001);
|
||||
else if (name == "(III) France Zone III")
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(44.1, 2.337229,
|
||||
NAN, 600000, 3200000, 43.199291, 44.996094), 9001);
|
||||
else if (name == "(IV) France Zone IV")
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(42.165, 2.337229,
|
||||
NAN, 234.358, 4185861.369, 41.560388, 42.767663), 9001);
|
||||
else if (name == "(VICGRID) Victoria Australia")
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(-37, 145, NAN,
|
||||
2500000, 4500000, -36, -38), 9001);
|
||||
else if (name == "(VG94) VICGRID94 Victoria Australia")
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(-37, 145, NAN,
|
||||
2500000, 2500000, -36, -38), 9001);
|
||||
else {
|
||||
_errorString = QString("%1: Unknown map projection").arg(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapFile::computeTransformation(QList<CalibrationPoint> &points)
|
||||
{
|
||||
QList<ReferencePoint> rp;
|
||||
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
if (points.at(i).rp.pp.isNull())
|
||||
points[i].rp.pp = _projection.ll2xy(points.at(i).ll);
|
||||
|
||||
rp.append(points.at(i).rp);
|
||||
}
|
||||
|
||||
Transform t(rp);
|
||||
if (t.isNull()) {
|
||||
_errorString = t.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
_transform = t.transform();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapFile::load(QIODevice &file)
|
||||
{
|
||||
QList<CalibrationPoint> points;
|
||||
QString ct, datum;
|
||||
Projection::Setup setup;
|
||||
const GCS *gcs;
|
||||
|
||||
if (!parseMapFile(file, points, ct, setup, datum))
|
||||
return false;
|
||||
if (!(gcs = createGCS(datum)))
|
||||
return false;
|
||||
if (!createProjection(gcs, ct, setup, points))
|
||||
return false;
|
||||
if (!computeTransformation(points))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
49
src/map/mapfile.h
Normal file
49
src/map/mapfile.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef MAPFILE_H
|
||||
#define MAPFILE_H
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QTransform>
|
||||
#include "gcs.h"
|
||||
#include "transform.h"
|
||||
#include "projection.h"
|
||||
|
||||
class MapFile
|
||||
{
|
||||
public:
|
||||
bool load(QIODevice &file);
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
const Projection &projection() const {return _projection;}
|
||||
const QTransform &transform() const {return _transform;}
|
||||
|
||||
const QString &name() const {return _name;}
|
||||
const QString &image() const {return _image;}
|
||||
const QSize &size() const {return _size;}
|
||||
|
||||
private:
|
||||
struct CalibrationPoint {
|
||||
ReferencePoint rp;
|
||||
Coordinates ll;
|
||||
int zone;
|
||||
};
|
||||
|
||||
int parse(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
QString &projection, Projection::Setup &setup, QString &datum);
|
||||
bool parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
QString &projection, Projection::Setup &setup, QString &datum);
|
||||
const GCS *createGCS(const QString &datum);
|
||||
bool createProjection(const GCS *gcs, const QString &projection,
|
||||
const Projection::Setup &setup, QList<CalibrationPoint> &points);
|
||||
bool computeTransformation(QList<CalibrationPoint> &points);
|
||||
|
||||
QString _name;
|
||||
QString _image;
|
||||
QSize _size;
|
||||
|
||||
Projection _projection;
|
||||
QTransform _transform;
|
||||
|
||||
QString _errorString;
|
||||
};
|
||||
|
||||
#endif // MAPFILE_H
|
@ -4,147 +4,140 @@
|
||||
#include "atlas.h"
|
||||
#include "offlinemap.h"
|
||||
#include "onlinemap.h"
|
||||
#include "mapsource.h"
|
||||
#include "maplist.h"
|
||||
|
||||
|
||||
#define ZOOM_MAX 18
|
||||
#define ZOOM_MIN 2
|
||||
|
||||
Map *MapList::loadListEntry(const QByteArray &line)
|
||||
bool MapList::loadSource(const QString &path, bool dir)
|
||||
{
|
||||
int max;
|
||||
MapSource ms;
|
||||
Map *map;
|
||||
|
||||
QList<QByteArray> list = line.split('\t');
|
||||
if (list.size() < 2)
|
||||
return 0;
|
||||
|
||||
QByteArray ba1 = list.at(0).trimmed();
|
||||
QByteArray ba2 = list.at(1).trimmed();
|
||||
if (ba1.isEmpty() || ba2.isEmpty())
|
||||
return 0;
|
||||
|
||||
if (list.size() == 3) {
|
||||
bool ok;
|
||||
max = QString(list.at(2).trimmed()).toInt(&ok);
|
||||
if (!ok)
|
||||
return 0;
|
||||
} else
|
||||
max = ZOOM_MAX;
|
||||
|
||||
return new OnlineMap(QString::fromUtf8(ba1.data(), ba1.size()),
|
||||
QString::fromLatin1(ba2.data(), ba2.size()), Range(ZOOM_MIN, max), this);
|
||||
}
|
||||
|
||||
bool MapList::loadList(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
QList<Map*> maps;
|
||||
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
_errorString = file.errorString();
|
||||
if (!ms.loadFile(path, &map)) {
|
||||
if (dir)
|
||||
_errorString += path + ": " + ms.errorString() + "\n";
|
||||
else
|
||||
_errorString = ms.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
int ln = 0;
|
||||
while (!file.atEnd()) {
|
||||
ln++;
|
||||
QByteArray line = file.readLine();
|
||||
Map *map = loadListEntry(line);
|
||||
|
||||
if (map)
|
||||
maps.append(map);
|
||||
else {
|
||||
for (int i = 0; i < maps.count(); i++)
|
||||
delete maps.at(i);
|
||||
_errorString = QString("Invalid map list entry on line %1.")
|
||||
.arg(QString::number(ln));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_maps += maps;
|
||||
map->setParent(this);
|
||||
_maps.append(map);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapList::loadMap(const QString &path)
|
||||
bool MapList::loadMap(const QString &path, bool dir)
|
||||
{
|
||||
OfflineMap *map = new OfflineMap(path, this);
|
||||
|
||||
if (map->isValid()) {
|
||||
_maps.append(map);
|
||||
return true;
|
||||
} else {
|
||||
_errorString = map->errorString();
|
||||
if (dir)
|
||||
_errorString += path + ": " + map->errorString() + "\n";
|
||||
else
|
||||
_errorString = map->errorString();
|
||||
delete map;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MapList::loadTba(const QString &path)
|
||||
bool MapList::loadAtlas(const QString &path, bool dir)
|
||||
{
|
||||
Atlas *atlas = new Atlas(path, this);
|
||||
|
||||
if (atlas->isValid()) {
|
||||
_maps.append(atlas);
|
||||
return true;
|
||||
} else {
|
||||
_errorString = atlas->errorString();
|
||||
if (dir)
|
||||
_errorString += path + ": " + atlas->errorString() + "\n";
|
||||
else
|
||||
_errorString = atlas->errorString();
|
||||
delete atlas;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MapList::loadTar(const QString &path)
|
||||
{
|
||||
Atlas *atlas = new Atlas(path, this);
|
||||
if (atlas->isValid()) {
|
||||
_maps.append(atlas);
|
||||
return true;
|
||||
} else {
|
||||
_errorString = atlas->errorString();
|
||||
delete atlas;
|
||||
OfflineMap *map = new OfflineMap(path, this);
|
||||
if (map->isValid()) {
|
||||
_maps.append(map);
|
||||
return true;
|
||||
} else {
|
||||
qWarning("%s: %s", qPrintable(path), qPrintable(_errorString));
|
||||
qWarning("%s: %s", qPrintable(path),
|
||||
qPrintable(map->errorString()));
|
||||
_errorString = "Not a map/atlas file";
|
||||
delete map;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MapList::loadFile(const QString &path)
|
||||
bool MapList::loadFile(const QString &path, bool *atlas, bool dir)
|
||||
{
|
||||
QFileInfo fi(path);
|
||||
QString suffix = fi.suffix().toLower();
|
||||
|
||||
if (suffix == "txt")
|
||||
return loadList(path);
|
||||
else if (suffix == "map")
|
||||
return loadMap(path);
|
||||
else if (suffix == "tba")
|
||||
return loadTba(path);
|
||||
else if (suffix == "tar")
|
||||
return loadTar(path);
|
||||
else {
|
||||
_errorString = "Not a map/atlas file";
|
||||
return false;
|
||||
if (Atlas::isAtlas(path)) {
|
||||
*atlas = true;
|
||||
return loadAtlas(path, dir);
|
||||
} else if (suffix == "xml") {
|
||||
*atlas = false;
|
||||
return loadSource(path, dir);
|
||||
} else {
|
||||
*atlas = false;
|
||||
return loadMap(path, dir);
|
||||
}
|
||||
}
|
||||
|
||||
bool MapList::loadDirR(const QString &path)
|
||||
{
|
||||
QDir md(path);
|
||||
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
md.setSorting(QDir::DirsLast);
|
||||
QFileInfoList ml = md.entryInfoList();
|
||||
bool atlas, ret = true;
|
||||
|
||||
for (int i = 0; i < ml.size(); i++) {
|
||||
const QFileInfo &fi = ml.at(i);
|
||||
QString suffix = fi.suffix().toLower();
|
||||
|
||||
if (fi.isDir() && fi.fileName() != "set") {
|
||||
if (!loadDirR(fi.absoluteFilePath()))
|
||||
ret = false;
|
||||
} else if (filter().contains("*." + suffix)) {
|
||||
if (!loadFile(fi.absoluteFilePath(), &atlas, true))
|
||||
ret = false;
|
||||
if (atlas)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool MapList::loadFile(const QString &path)
|
||||
{
|
||||
bool atlas;
|
||||
|
||||
_errorString.clear();
|
||||
return loadFile(path, &atlas, false);
|
||||
}
|
||||
|
||||
bool MapList::loadDir(const QString &path)
|
||||
{
|
||||
_errorString.clear();
|
||||
return loadDirR(path);
|
||||
}
|
||||
|
||||
void MapList::clear()
|
||||
{
|
||||
for (int i = 0; i < _maps.count(); i++)
|
||||
delete _maps.at(i);
|
||||
_maps.clear();
|
||||
}
|
||||
|
||||
QString MapList::formats()
|
||||
{
|
||||
return tr("Map files (*.map *.tba *.tar)") + ";;"
|
||||
+ tr("URL list files (*.txt)");
|
||||
return
|
||||
tr("Supported files") + " (*.map *.tar *.tba *.tif *.tiff *.xml);;"
|
||||
+ tr("OziExplorer maps") + " (*.map);;"
|
||||
+ tr("TrekBuddy maps/atlases") + " (*.tar *.tba);;"
|
||||
+ tr("GeoTIFF images") + " (*.tif *.tiff);;"
|
||||
+ tr("Online map sources") + " (*.xml)";
|
||||
}
|
||||
|
||||
QStringList MapList::filter()
|
||||
{
|
||||
QStringList filter;
|
||||
filter << "*.map" << "*.tba" << "*.tar" << "*.txt";
|
||||
filter << "*.map" << "*.tba" << "*.tar" << "*.xml" << "*.tif" << "*.tiff";
|
||||
return filter;
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <QString>
|
||||
#include "map.h"
|
||||
|
||||
class Tar;
|
||||
|
||||
class MapList : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -13,6 +15,8 @@ public:
|
||||
MapList(QObject *parent = 0) : QObject(parent) {}
|
||||
|
||||
bool loadFile(const QString &path);
|
||||
bool loadDir(const QString &path);
|
||||
void clear();
|
||||
|
||||
const QList<Map*> &maps() const {return _maps;}
|
||||
const QString &errorString() const {return _errorString;}
|
||||
@ -21,12 +25,14 @@ public:
|
||||
static QStringList filter();
|
||||
|
||||
private:
|
||||
bool loadFile(const QString &path, bool *atlas, bool dir);
|
||||
bool loadDirR(const QString &path);
|
||||
|
||||
Map *loadListEntry(const QByteArray &line);
|
||||
|
||||
bool loadList(const QString &path);
|
||||
bool loadMap(const QString &path);
|
||||
bool loadTba(const QString &path);
|
||||
bool loadTar(const QString &path);
|
||||
bool loadSource(const QString &path, bool dir);
|
||||
bool loadMap(const QString &path, bool dir);
|
||||
bool loadAtlas(const QString &path, bool dir);
|
||||
|
||||
QList<Map*> _maps;
|
||||
QString _errorString;
|
||||
|
172
src/map/mapsource.cpp
Normal file
172
src/map/mapsource.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
#include <QFile>
|
||||
#include <QXmlStreamReader>
|
||||
#include "onlinemap.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
|
||||
|
||||
Range MapSource::zooms(QXmlStreamReader &reader)
|
||||
{
|
||||
const QXmlStreamAttributes &attr = reader.attributes();
|
||||
int min, max;
|
||||
bool res;
|
||||
|
||||
if (attr.hasAttribute("min")) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
min = attr.value("min").toString().toInt(&res);
|
||||
#else // QT_VERSION < 5
|
||||
min = attr.value("min").toInt(&res);
|
||||
#endif // QT_VERSION < 5
|
||||
if (!res || (min < ZOOM_MIN || min > ZOOM_MAX)) {
|
||||
reader.raiseError("Invalid minimal zoom level");
|
||||
return Range();
|
||||
}
|
||||
} else
|
||||
min = ZOOM_MIN;
|
||||
|
||||
if (attr.hasAttribute("max")) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
max = attr.value("max").toString().toInt(&res);
|
||||
#else // QT_VERSION < 5
|
||||
max = attr.value("max").toInt(&res);
|
||||
#endif // QT_VERSION < 5
|
||||
if (!res || (max < ZOOM_MIN || max > ZOOM_MAX)) {
|
||||
reader.raiseError("Invalid maximal zoom level");
|
||||
return Range();
|
||||
}
|
||||
} else
|
||||
max = ZOOM_MAX;
|
||||
|
||||
if (min > max || max < min) {
|
||||
reader.raiseError("Invalid maximal/minimal zoom level combination");
|
||||
return Range();
|
||||
}
|
||||
|
||||
return Range(min, max);
|
||||
}
|
||||
|
||||
RectC MapSource::bounds(QXmlStreamReader &reader)
|
||||
{
|
||||
const QXmlStreamAttributes &attr = reader.attributes();
|
||||
double top, left, bottom, right;
|
||||
bool res;
|
||||
|
||||
if (attr.hasAttribute("top")) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
top = attr.value("top").toString().toDouble(&res);
|
||||
#else // QT_VERSION < 5
|
||||
top = attr.value("top").toDouble(&res);
|
||||
#endif // QT_VERSION < 5
|
||||
if (!res || (top < BOUNDS_BOTTOM || top > BOUNDS_TOP)) {
|
||||
reader.raiseError("Invalid bounds top value");
|
||||
return RectC();
|
||||
}
|
||||
} else
|
||||
top = BOUNDS_TOP;
|
||||
|
||||
if (attr.hasAttribute("bottom")) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
bottom = attr.value("bottom").toString().toDouble(&res);
|
||||
#else // QT_VERSION < 5
|
||||
bottom = attr.value("bottom").toDouble(&res);
|
||||
#endif // QT_VERSION < 5
|
||||
if (!res || (bottom < BOUNDS_BOTTOM || bottom > BOUNDS_TOP)) {
|
||||
reader.raiseError("Invalid bounds bottom value");
|
||||
return RectC();
|
||||
}
|
||||
} else
|
||||
bottom = BOUNDS_BOTTOM;
|
||||
|
||||
if (attr.hasAttribute("left")) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
left = attr.value("left").toString().toDouble(&res);
|
||||
#else // QT_VERSION < 5
|
||||
left = attr.value("left").toDouble(&res);
|
||||
#endif // QT_VERSION < 5
|
||||
if (!res || (left < BOUNDS_LEFT || left > BOUNDS_RIGHT)) {
|
||||
reader.raiseError("Invalid bounds left value");
|
||||
return RectC();
|
||||
}
|
||||
} else
|
||||
left = BOUNDS_LEFT;
|
||||
|
||||
if (attr.hasAttribute("right")) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
right = attr.value("right").toString().toDouble(&res);
|
||||
#else // QT_VERSION < 5
|
||||
right = attr.value("right").toDouble(&res);
|
||||
#endif // QT_VERSION < 5
|
||||
if (!res || (right < BOUNDS_LEFT || right > BOUNDS_RIGHT)) {
|
||||
reader.raiseError("Invalid bounds right value");
|
||||
return RectC();
|
||||
}
|
||||
} else
|
||||
right = BOUNDS_RIGHT;
|
||||
|
||||
if (bottom > top || top < bottom) {
|
||||
reader.raiseError("Invalid bottom/top bounds combination");
|
||||
return RectC();
|
||||
}
|
||||
if (left > right || right < left) {
|
||||
reader.raiseError("Invalid left/right bounds combination");
|
||||
return RectC();
|
||||
}
|
||||
|
||||
return RectC(Coordinates(left, top), Coordinates(right, bottom));
|
||||
}
|
||||
|
||||
void MapSource::map(QXmlStreamReader &reader, Map **map)
|
||||
{
|
||||
QString name, url;
|
||||
Range z(ZOOM_MIN, ZOOM_MAX);
|
||||
RectC b(Coordinates(BOUNDS_LEFT, BOUNDS_TOP),
|
||||
Coordinates(BOUNDS_RIGHT, BOUNDS_BOTTOM));
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "name")
|
||||
name = reader.readElementText();
|
||||
else if (reader.name() == "url")
|
||||
url = reader.readElementText();
|
||||
else if (reader.name() == "zoom") {
|
||||
z = zooms(reader);
|
||||
reader.skipCurrentElement();
|
||||
} else if (reader.name() == "bounds") {
|
||||
b = bounds(reader);
|
||||
reader.skipCurrentElement();
|
||||
} else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
*map = reader.error() ? 0 : new OnlineMap(name, url, z, b);
|
||||
}
|
||||
|
||||
bool MapSource::loadFile(const QString &path, Map **map)
|
||||
{
|
||||
QFile file(path);
|
||||
QXmlStreamReader reader;
|
||||
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
_errorString = file.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
reader.setDevice(&file);
|
||||
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == "map")
|
||||
MapSource::map(reader, map);
|
||||
else
|
||||
reader.raiseError("Not an online map source file");
|
||||
}
|
||||
|
||||
_errorString = reader.error() ? QString("%1: %2").arg(reader.lineNumber())
|
||||
.arg(reader.errorString()) : QString();
|
||||
|
||||
return !reader.error();
|
||||
}
|
25
src/map/mapsource.h
Normal file
25
src/map/mapsource.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef MAPSOURCE_H
|
||||
#define MAPSOURCE_H
|
||||
|
||||
#include <QList>
|
||||
#include "common/range.h"
|
||||
#include "common/rectc.h"
|
||||
|
||||
class Map;
|
||||
class QXmlStreamReader;
|
||||
|
||||
class MapSource
|
||||
{
|
||||
public:
|
||||
bool loadFile(const QString &path, Map **map);
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
private:
|
||||
RectC bounds(QXmlStreamReader &reader);
|
||||
Range zooms(QXmlStreamReader &reader);
|
||||
void map(QXmlStreamReader &reader, Map **map);
|
||||
|
||||
QString _errorString;
|
||||
};
|
||||
|
||||
#endif // MAPSOURCE_H
|
@ -1,11 +1,13 @@
|
||||
#ifndef MERCATOR_H
|
||||
#define MERCATOR_H
|
||||
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
|
||||
class Mercator : public Projection
|
||||
class Mercator : public CT
|
||||
{
|
||||
public:
|
||||
virtual CT *clone() const {return new Mercator(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
};
|
||||
|
@ -1,7 +0,0 @@
|
||||
#include <QRectF>
|
||||
|
||||
inline QRectF scaled(const QRectF &rect, qreal factor)
|
||||
{
|
||||
return QRectF(QPointF(rect.left() * factor, rect.top() * factor),
|
||||
QSizeF(rect.width() * factor, rect.height() * factor));
|
||||
}
|
@ -9,297 +9,20 @@
|
||||
#include <QPixmapCache>
|
||||
#include "common/coordinates.h"
|
||||
#include "common/rectc.h"
|
||||
#include "datum.h"
|
||||
#include "utm.h"
|
||||
#include "matrix.h"
|
||||
#include "ozf.h"
|
||||
#include "mapfile.h"
|
||||
#include "geotiff.h"
|
||||
#include "offlinemap.h"
|
||||
|
||||
|
||||
int OfflineMap::parse(QIODevice &device, QList<ReferencePoint> &points,
|
||||
QString &projection, Projection::Setup &setup, QString &datum)
|
||||
void OfflineMap::computeResolution()
|
||||
{
|
||||
bool res;
|
||||
int ln = 1;
|
||||
Coordinates tl = xy2ll((bounds().topLeft()));
|
||||
Coordinates br = xy2ll(bounds().bottomRight());
|
||||
|
||||
while (!device.atEnd()) {
|
||||
QByteArray line = device.readLine();
|
||||
qreal ds = tl.distanceTo(br);
|
||||
qreal ps = QLineF(bounds().topLeft(), bounds().bottomRight()).length();
|
||||
|
||||
if (ln == 1) {
|
||||
if (!line.trimmed().startsWith("OziExplorer Map Data File"))
|
||||
return ln;
|
||||
} else if (ln == 2)
|
||||
_name = line.trimmed();
|
||||
else if (ln == 3)
|
||||
_imgPath = line.trimmed();
|
||||
else if (ln == 5)
|
||||
datum = line.split(',').at(0).trimmed();
|
||||
else {
|
||||
QList<QByteArray> list = line.split(',');
|
||||
QString key(list.at(0).trimmed());
|
||||
bool ll = true; bool pp = true;
|
||||
|
||||
if (key.startsWith("Point") && list.count() == 17
|
||||
&& !list.at(2).trimmed().isEmpty()) {
|
||||
int x = list.at(2).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
return ln;
|
||||
int y = list.at(3).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
return ln;
|
||||
|
||||
int latd = list.at(6).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
qreal latm = list.at(7).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
int lond = list.at(9).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
qreal lonm = list.at(10).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
if (ll && list.at(8).trimmed() == "S") {
|
||||
latd = -latd;
|
||||
latm = -latm;
|
||||
}
|
||||
if (ll && list.at(11).trimmed() == "W") {
|
||||
lond = -lond;
|
||||
lonm = -lonm;
|
||||
}
|
||||
|
||||
setup.zone = list.at(13).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
setup.zone = 0;
|
||||
qreal ppx = list.at(14).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
pp = false;
|
||||
qreal ppy = list.at(15).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
pp = false;
|
||||
if (list.at(16).trimmed() == "S")
|
||||
setup.zone = -setup.zone;
|
||||
|
||||
ReferencePoint p;
|
||||
p.xy = QPoint(x, y);
|
||||
if (ll) {
|
||||
p.ll = Coordinates(lond + lonm/60.0, latd + latm/60.0);
|
||||
if (p.ll.isValid())
|
||||
points.append(p);
|
||||
else
|
||||
return ln;
|
||||
} else if (pp) {
|
||||
p.pp = QPointF(ppx, ppy);
|
||||
points.append(p);
|
||||
} else
|
||||
return ln;
|
||||
} else if (key == "IWH") {
|
||||
if (list.count() < 4)
|
||||
return ln;
|
||||
int w = list.at(2).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
return ln;
|
||||
int h = list.at(3).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
return ln;
|
||||
_size = QSize(w, h);
|
||||
} else if (key == "Map Projection") {
|
||||
if (list.count() < 2)
|
||||
return ln;
|
||||
projection = list.at(1);
|
||||
} else if (key == "Projection Setup") {
|
||||
if (list.count() < 8)
|
||||
return ln;
|
||||
setup.latitudeOrigin = list.at(1).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
setup.latitudeOrigin = 0;
|
||||
setup.longitudeOrigin = list.at(2).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
setup.longitudeOrigin = 0;
|
||||
setup.scale = list.at(3).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
setup.scale = 1.0;
|
||||
setup.falseEasting = list.at(4).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
setup.falseEasting = 0;
|
||||
setup.falseNorthing = list.at(5).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
setup.falseNorthing = 0;
|
||||
setup.standardParallel1 = list.at(6).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
setup.standardParallel1 = 0;
|
||||
setup.standardParallel2 = list.at(7).trimmed().toFloat(&res);
|
||||
if (!res)
|
||||
setup.standardParallel2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ln++;
|
||||
}
|
||||
|
||||
if (!setup.zone && !points.first().ll.isNull())
|
||||
setup.zone = UTM::zone(points.first().ll);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool OfflineMap::parseMapFile(QIODevice &device, QList<ReferencePoint> &points,
|
||||
QString &projection, Projection::Setup &setup, QString &datum)
|
||||
{
|
||||
int el;
|
||||
|
||||
if (!device.open(QIODevice::ReadOnly)) {
|
||||
_errorString = QString("Error opening map file: %1")
|
||||
.arg(device.errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((el = parse(device, points, projection, setup, datum))) {
|
||||
_errorString = QString("Map file parse error on line %1").arg(el);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OfflineMap::createProjection(const QString &datum,
|
||||
const QString &projection, const Projection::Setup &setup,
|
||||
QList<ReferencePoint> &points)
|
||||
{
|
||||
if (points.count() < 2) {
|
||||
_errorString = "Insufficient number of reference points";
|
||||
return false;
|
||||
}
|
||||
|
||||
Datum d = Datum::datum(datum);
|
||||
if (d.isNull()) {
|
||||
_errorString = QString("%1: Unknown datum").arg(datum);
|
||||
return false;
|
||||
}
|
||||
|
||||
_projection = Projection::projection(projection, d.ellipsoid(), setup);
|
||||
if (!_projection) {
|
||||
_errorString = Projection::errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
if (points.at(i).ll.isNull())
|
||||
points[i].ll = d.toWGS84(_projection->xy2ll(points.at(i).pp));
|
||||
else
|
||||
points[i].ll = d.toWGS84(points[i].ll);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OfflineMap::simpleTransformation(const QList<ReferencePoint> &points)
|
||||
{
|
||||
if (points.at(0).xy.x() == points.at(1).xy.x()
|
||||
|| points.at(0).xy.y() == points.at(1).xy.y()) {
|
||||
_errorString = "Invalid reference points tuple";
|
||||
return false;
|
||||
}
|
||||
|
||||
QPointF p0(_projection->ll2xy(points.at(0).ll));
|
||||
QPointF p1(_projection->ll2xy(points.at(1).ll));
|
||||
|
||||
qreal dX, dY, lat0, lon0;
|
||||
dX = (p0.x() - p1.x()) / (points.at(0).xy.x() - points.at(1).xy.x());
|
||||
dY = (p1.y() - p0.y()) / (points.at(1).xy.y() - points.at(0).xy.y());
|
||||
lat0 = p0.y() - points.at(0).xy.y() * dY;
|
||||
lon0 = p1.x() - points.at(1).xy.x() * dX;
|
||||
|
||||
_transform = QTransform(1.0/dX, 0, 0, 1.0/dY, -lon0/dX, -lat0/dY);
|
||||
_inverted = _transform.inverted();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OfflineMap::affineTransformation(const QList<ReferencePoint> &points)
|
||||
{
|
||||
Matrix c(3, 2);
|
||||
c.zeroize();
|
||||
for (size_t i = 0; i < c.h(); i++) {
|
||||
for (size_t j = 0; j < c.w(); j++) {
|
||||
for (int k = 0; k < points.size(); k++) {
|
||||
double f[3], t[2];
|
||||
QPointF p = _projection->ll2xy(points.at(k).ll);
|
||||
|
||||
f[0] = p.x();
|
||||
f[1] = p.y();
|
||||
f[2] = 1.0;
|
||||
t[0] = points.at(k).xy.x();
|
||||
t[1] = points.at(k).xy.y();
|
||||
c.m(i,j) += f[i] * t[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Matrix Q(3, 3);
|
||||
Q.zeroize();
|
||||
for (int qi = 0; qi < points.size(); qi++) {
|
||||
double v[3];
|
||||
QPointF p = _projection->ll2xy(points.at(qi).ll);
|
||||
|
||||
v[0] = p.x();
|
||||
v[1] = p.y();
|
||||
v[2] = 1.0;
|
||||
for (size_t i = 0; i < Q.h(); i++)
|
||||
for (size_t j = 0; j < Q.w(); j++)
|
||||
Q.m(i,j) += v[i] * v[j];
|
||||
}
|
||||
|
||||
Matrix M = Q.augemented(c);
|
||||
if (!M.eliminate()) {
|
||||
_errorString = "Singular transformation matrix";
|
||||
return false;
|
||||
}
|
||||
|
||||
_transform = QTransform(M.m(0,3), M.m(0,4), M.m(1,3), M.m(1,4), M.m(2,3),
|
||||
M.m(2,4));
|
||||
_inverted = _transform.inverted();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OfflineMap::computeTransformation(const QList<ReferencePoint> &points)
|
||||
{
|
||||
Q_ASSERT(points.size() >= 2);
|
||||
|
||||
if (points.size() == 2)
|
||||
return simpleTransformation(points);
|
||||
else
|
||||
return affineTransformation(points);
|
||||
}
|
||||
|
||||
bool OfflineMap::computeResolution(QList<ReferencePoint> &points)
|
||||
{
|
||||
Q_ASSERT(points.count() >= 2);
|
||||
|
||||
int maxLon = 0, minLon = 0, maxLat = 0, minLat = 0;
|
||||
qreal dLon, pLon, dLat, pLat;
|
||||
|
||||
for (int i = 1; i < points.size(); i++) {
|
||||
if (points.at(i).ll.lon() < points.at(minLon).ll.lon())
|
||||
minLon = i;
|
||||
if (points.at(i).ll.lon() > points.at(maxLon).ll.lon())
|
||||
maxLon = i;
|
||||
if (points.at(i).ll.lat() < points.at(minLat).ll.lat())
|
||||
minLat = i;
|
||||
if (points.at(i).ll.lat() > points.at(maxLat).ll.lat())
|
||||
maxLat = i;
|
||||
}
|
||||
|
||||
dLon = points.at(minLon).ll.distanceTo(points.at(maxLon).ll);
|
||||
pLon = QLineF(points.at(minLon).xy, points.at(maxLon).xy).length();
|
||||
dLat = points.at(minLat).ll.distanceTo(points.at(maxLat).ll);
|
||||
pLat = QLineF(points.at(minLat).xy, points.at(maxLat).xy).length();
|
||||
|
||||
_resolution = (dLon/pLon + dLat/pLat) / 2.0;
|
||||
|
||||
return true;
|
||||
_resolution = ds/ps;
|
||||
}
|
||||
|
||||
bool OfflineMap::getImageInfo(const QString &path)
|
||||
@ -384,16 +107,11 @@ bool OfflineMap::totalSizeSet()
|
||||
OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
: Map(parent)
|
||||
{
|
||||
QList<ReferencePoint> points;
|
||||
QString proj, datum;
|
||||
Projection::Setup setup;
|
||||
QFileInfo fi(fileName);
|
||||
QString suffix = fi.suffix().toLower();
|
||||
|
||||
|
||||
_valid = false;
|
||||
_img = 0;
|
||||
_projection = 0;
|
||||
_resolution = 0.0;
|
||||
_zoom = 0;
|
||||
_scale = QPointF(1.0, 1.0);
|
||||
@ -411,23 +129,46 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
return;
|
||||
}
|
||||
QBuffer mapFile(&ba);
|
||||
if (!parseMapFile(mapFile, points, proj, setup, datum))
|
||||
MapFile mf;
|
||||
if (!mf.load(mapFile)) {
|
||||
_errorString = mf.errorString();
|
||||
return;
|
||||
} else if (suffix =="map") {
|
||||
} else {
|
||||
_name = mf.name();
|
||||
_size = mf.size();
|
||||
_imgPath = mf.image();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
}
|
||||
} else if (suffix == "map") {
|
||||
MapFile mf;
|
||||
QFile mapFile(fileName);
|
||||
if (!parseMapFile(mapFile, points, proj, setup, datum))
|
||||
if (!mf.load(mapFile)) {
|
||||
_errorString = mf.errorString();
|
||||
return;
|
||||
} else {
|
||||
_name = mf.name();
|
||||
_size = mf.size();
|
||||
_imgPath = mf.image();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
}
|
||||
} else if (suffix == "tif" || suffix == "tiff") {
|
||||
GeoTIFF gt;
|
||||
if (!gt.load(fileName)) {
|
||||
_errorString = gt.errorString();
|
||||
return;
|
||||
} else {
|
||||
_name = fi.fileName();
|
||||
_imgPath = fileName;
|
||||
_projection = gt.projection();
|
||||
_transform = gt.transform();
|
||||
}
|
||||
} else {
|
||||
_errorString = "Not a map file";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!createProjection(datum, proj, setup, points))
|
||||
return;
|
||||
if (!computeTransformation(points))
|
||||
return;
|
||||
computeResolution(points);
|
||||
|
||||
if (_tar.isOpen()) {
|
||||
if (!totalSizeSet())
|
||||
return;
|
||||
@ -448,20 +189,20 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
}
|
||||
}
|
||||
|
||||
_inverted = _transform.inverted();
|
||||
computeResolution();
|
||||
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||
: Map(parent)
|
||||
{
|
||||
QList<ReferencePoint> points;
|
||||
QString proj, datum;
|
||||
Projection::Setup setup;
|
||||
QFileInfo fi(fileName);
|
||||
MapFile mf;
|
||||
|
||||
_valid = false;
|
||||
_img = 0;
|
||||
_projection = 0;
|
||||
_resolution = 0.0;
|
||||
_zoom = 0;
|
||||
_scale = QPointF(1.0, 1.0);
|
||||
@ -477,28 +218,26 @@ OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||
}
|
||||
QBuffer buffer(&ba);
|
||||
|
||||
if (!parseMapFile(buffer, points, proj, setup, datum))
|
||||
if (!mf.load(buffer)) {
|
||||
_errorString = mf.errorString();
|
||||
return;
|
||||
if (!createProjection(datum, proj, setup, points))
|
||||
return;
|
||||
if (!totalSizeSet())
|
||||
return;
|
||||
if (!computeTransformation(points))
|
||||
return;
|
||||
computeResolution(points);
|
||||
}
|
||||
|
||||
_name = mf.name();
|
||||
_size = mf.size();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
|
||||
_inverted = _transform.inverted();
|
||||
computeResolution();
|
||||
|
||||
_tarPath = fi.absolutePath() + "/" + fi.completeBaseName() + ".tar";
|
||||
_imgPath = QString();
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
OfflineMap::~OfflineMap()
|
||||
{
|
||||
if (_img)
|
||||
delete _img;
|
||||
if (_projection)
|
||||
delete _projection;
|
||||
delete _img;
|
||||
}
|
||||
|
||||
void OfflineMap::load()
|
||||
@ -522,10 +261,8 @@ void OfflineMap::load()
|
||||
|
||||
void OfflineMap::unload()
|
||||
{
|
||||
if (_img) {
|
||||
delete _img;
|
||||
_img = 0;
|
||||
}
|
||||
delete _img;
|
||||
_img = 0;
|
||||
}
|
||||
|
||||
void OfflineMap::drawTiled(QPainter *painter, const QRectF &rect)
|
||||
@ -599,13 +336,9 @@ void OfflineMap::drawOZF(QPainter *painter, const QRectF &rect)
|
||||
|
||||
void OfflineMap::drawImage(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
if (!_img || _img->isNull())
|
||||
painter->fillRect(rect, _backgroundColor);
|
||||
else {
|
||||
QRect r(rect.toRect());
|
||||
painter->drawImage(r.left(), r.top(), *_img, r.left(), r.top(),
|
||||
r.width(), r.height());
|
||||
}
|
||||
QRect r(rect.toRect());
|
||||
painter->drawImage(r.left(), r.top(), *_img, r.left(), r.top(),
|
||||
r.width(), r.height());
|
||||
}
|
||||
|
||||
void OfflineMap::draw(QPainter *painter, const QRectF &rect)
|
||||
@ -614,26 +347,28 @@ void OfflineMap::draw(QPainter *painter, const QRectF &rect)
|
||||
drawOZF(painter, rect);
|
||||
else if (_tileSize.isValid())
|
||||
drawTiled(painter, rect);
|
||||
else
|
||||
else if (_img && !_img->isNull())
|
||||
drawImage(painter, rect);
|
||||
else
|
||||
painter->fillRect(rect, _backgroundColor);
|
||||
}
|
||||
|
||||
QPointF OfflineMap::ll2xy(const Coordinates &c)
|
||||
{
|
||||
if (_ozf.isOpen()) {
|
||||
QPointF p(_transform.map(_projection->ll2xy(c)));
|
||||
QPointF p(_transform.map(_projection.ll2xy(c)));
|
||||
return QPointF(p.x() * _scale.x(), p.y() * _scale.y());
|
||||
} else
|
||||
return _transform.map(_projection->ll2xy(c));
|
||||
return _transform.map(_projection.ll2xy(c));
|
||||
}
|
||||
|
||||
Coordinates OfflineMap::xy2ll(const QPointF &p)
|
||||
{
|
||||
if (_ozf.isOpen()) {
|
||||
return _projection->xy2ll(_inverted.map(QPointF(p.x() / _scale.x(),
|
||||
return _projection.xy2ll(_inverted.map(QPointF(p.x() / _scale.x(),
|
||||
p.y() / _scale.y())));
|
||||
} else
|
||||
return _projection->xy2ll(_inverted.map(p));
|
||||
return _projection.xy2ll(_inverted.map(p));
|
||||
}
|
||||
|
||||
QRectF OfflineMap::bounds() const
|
||||
@ -660,8 +395,8 @@ qreal OfflineMap::zoomFit(const QSize &size, const RectC &br)
|
||||
if (!br.isValid())
|
||||
rescale(0);
|
||||
else {
|
||||
QRect sbr(QRectF(_transform.map(_projection->ll2xy(br.topLeft())),
|
||||
_transform.map(_projection->ll2xy(br.bottomRight())))
|
||||
QRect sbr(QRectF(_transform.map(_projection.ll2xy(br.topLeft())),
|
||||
_transform.map(_projection.ll2xy(br.bottomRight())))
|
||||
.toRect().normalized());
|
||||
|
||||
for (int i = 0; i < _ozf.zooms(); i++) {
|
||||
|
@ -2,8 +2,9 @@
|
||||
#define OFFLINEMAP_H
|
||||
|
||||
#include <QTransform>
|
||||
#include "common/coordinates.h"
|
||||
#include "projection.h"
|
||||
#include "transform.h"
|
||||
#include "linearunits.h"
|
||||
#include "map.h"
|
||||
#include "tar.h"
|
||||
#include "ozf.h"
|
||||
@ -43,47 +44,28 @@ public:
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
QPointF ll2pp(const Coordinates &c) const
|
||||
{return _projection->ll2xy(c);}
|
||||
{return _projection.ll2xy(c);}
|
||||
QPointF xy2pp(const QPointF &p) const
|
||||
{return _inverted.map(p);}
|
||||
QPointF pp2xy(const QPointF &p) const
|
||||
{return _transform.map(p);}
|
||||
|
||||
private:
|
||||
struct ReferencePoint {
|
||||
QPoint xy;
|
||||
Coordinates ll;
|
||||
QPointF pp;
|
||||
};
|
||||
|
||||
int parse(QIODevice &device, QList<ReferencePoint> &points,
|
||||
QString &projection, Projection::Setup &setup, QString &datum);
|
||||
bool parseMapFile(QIODevice &device, QList<ReferencePoint> &points,
|
||||
QString &projection, Projection::Setup &setup, QString &datum);
|
||||
bool totalSizeSet();
|
||||
bool createProjection(const QString &datum, const QString &projection,
|
||||
const Projection::Setup &setup, QList<ReferencePoint> &points);
|
||||
bool simpleTransformation(const QList<ReferencePoint> &points);
|
||||
bool affineTransformation(const QList<ReferencePoint> &points);
|
||||
bool computeTransformation(const QList<ReferencePoint> &points);
|
||||
bool computeResolution(QList<ReferencePoint> &points);
|
||||
bool getTileInfo(const QStringList &tiles, const QString &path = QString());
|
||||
bool getImageInfo(const QString &path);
|
||||
bool totalSizeSet();
|
||||
|
||||
void drawTiled(QPainter *painter, const QRectF &rect);
|
||||
void drawOZF(QPainter *painter, const QRectF &rect);
|
||||
void drawImage(QPainter *painter, const QRectF &rect);
|
||||
|
||||
void computeResolution();
|
||||
void rescale(int zoom);
|
||||
|
||||
QString _name;
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
|
||||
QSize _size;
|
||||
Projection *_projection;
|
||||
Projection _projection;
|
||||
QTransform _transform, _inverted;
|
||||
qreal _resolution;
|
||||
|
||||
OZF _ozf;
|
||||
Tar _tar;
|
||||
@ -92,9 +74,14 @@ private:
|
||||
QString _imgPath;
|
||||
QSize _tileSize;
|
||||
QString _tileName;
|
||||
QSize _size;
|
||||
|
||||
int _zoom;
|
||||
qreal _resolution;
|
||||
QPointF _scale;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
};
|
||||
|
||||
#endif // OFFLINEMAP_H
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "mercator.h"
|
||||
#include "downloader.h"
|
||||
#include "config.h"
|
||||
#include "misc.h"
|
||||
#include "onlinemap.h"
|
||||
|
||||
|
||||
@ -47,13 +46,11 @@ static bool loadTileFile(Tile &tile, const QString &file)
|
||||
Downloader *OnlineMap::downloader;
|
||||
|
||||
OnlineMap::OnlineMap(const QString &name, const QString &url,
|
||||
const Range &zooms, QObject *parent) : Map(parent)
|
||||
const Range &zooms, const RectC &bounds, QObject *parent)
|
||||
: Map(parent), _name(name), _url(url), _zooms(zooms), _bounds(bounds)
|
||||
{
|
||||
_name = name;
|
||||
_url = url;
|
||||
_block = false;
|
||||
_zooms = zooms;
|
||||
_zoom = zooms.max();
|
||||
_zoom = _zooms.max();
|
||||
|
||||
QString path = TILES_DIR + QString("/") + name;
|
||||
if (!QDir().mkpath(path))
|
||||
@ -168,8 +165,7 @@ void OnlineMap::clearCache()
|
||||
|
||||
QRectF OnlineMap::bounds() const
|
||||
{
|
||||
return scaled(QRectF(QPointF(-180, -180), QSizeF(360, 360)),
|
||||
1.0/zoom2scale(_zoom));
|
||||
return QRectF(ll2xy(_bounds.topLeft()), ll2xy(_bounds.bottomRight()));
|
||||
}
|
||||
|
||||
int OnlineMap::limitZoom(int zoom) const
|
||||
@ -253,14 +249,14 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect)
|
||||
}
|
||||
}
|
||||
|
||||
QPointF OnlineMap::ll2xy(const Coordinates &c)
|
||||
QPointF OnlineMap::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
QPointF m = Mercator().ll2xy(c);
|
||||
return QPointF(m.x() / scale, m.y() / -scale);
|
||||
}
|
||||
|
||||
Coordinates OnlineMap::xy2ll(const QPointF &p)
|
||||
Coordinates OnlineMap::xy2ll(const QPointF &p) const
|
||||
{
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
QPointF m(p.x() * scale, -p.y() * scale);
|
||||
|
@ -1,7 +1,9 @@
|
||||
#ifndef ONLINEMAP_H
|
||||
#define ONLINEMAP_H
|
||||
|
||||
#include "common/coordinates.h"
|
||||
#include "common/range.h"
|
||||
#include "common/rectc.h"
|
||||
#include "map.h"
|
||||
#include "tile.h"
|
||||
|
||||
@ -13,7 +15,7 @@ class OnlineMap : public Map
|
||||
|
||||
public:
|
||||
OnlineMap(const QString &name, const QString &url, const Range &zooms,
|
||||
QObject *parent = 0);
|
||||
const RectC &bounds, QObject *parent = 0);
|
||||
|
||||
const QString &name() const {return _name;}
|
||||
|
||||
@ -26,8 +28,10 @@ public:
|
||||
qreal zoomIn();
|
||||
qreal zoomOut();
|
||||
|
||||
QPointF ll2xy(const Coordinates &c);
|
||||
Coordinates xy2ll(const QPointF &p);
|
||||
QPointF ll2xy(const Coordinates &c)
|
||||
{return static_cast<const OnlineMap &>(*this).ll2xy(c);}
|
||||
Coordinates xy2ll(const QPointF &p)
|
||||
{return static_cast<const OnlineMap &>(*this).xy2ll(p);}
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect);
|
||||
|
||||
@ -44,6 +48,9 @@ private slots:
|
||||
void emitLoaded();
|
||||
|
||||
private:
|
||||
QPointF ll2xy(const Coordinates &c) const;
|
||||
Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
void fillTile(Tile &tile);
|
||||
QString tileUrl(const Tile &tile) const;
|
||||
QString tileFile(const Tile &tile) const;
|
||||
@ -51,10 +58,11 @@ private:
|
||||
void loadTilesSync(QList<Tile> &list);
|
||||
int limitZoom(int zoom) const;
|
||||
|
||||
Range _zooms;
|
||||
int _zoom;
|
||||
QString _name;
|
||||
QString _url;
|
||||
Range _zooms;
|
||||
RectC _bounds;
|
||||
int _zoom;
|
||||
bool _block;
|
||||
|
||||
static Downloader *downloader;
|
||||
|
195
src/map/pcs.cpp
Normal file
195
src/map/pcs.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
#include <QFile>
|
||||
#include "angularunits.h"
|
||||
#include "pcs.h"
|
||||
|
||||
|
||||
class PCS::Entry {
|
||||
public:
|
||||
Entry(int id, int proj, const PCS &pcs) : _id(id), _proj(proj), _pcs(pcs) {}
|
||||
|
||||
int id() const {return _id;}
|
||||
int proj() const {return _proj;}
|
||||
const PCS &pcs() const {return _pcs;}
|
||||
|
||||
private:
|
||||
int _id, _proj;
|
||||
PCS _pcs;
|
||||
};
|
||||
|
||||
QList<PCS::Entry> PCS::_pcss;
|
||||
|
||||
static bool parameter(int key, double val, int units, Projection::Setup &setup)
|
||||
{
|
||||
switch (key) {
|
||||
case 8801:
|
||||
case 8821:
|
||||
{AngularUnits au(units);
|
||||
if (au.isNull())
|
||||
return false;
|
||||
setup.setLatitudeOrigin(au.toDegrees(val));}
|
||||
return true;
|
||||
case 8802:
|
||||
case 8822:
|
||||
{AngularUnits au(units);
|
||||
if (au.isNull())
|
||||
return false;
|
||||
setup.setLongitudeOrigin(au.toDegrees(val));}
|
||||
return true;
|
||||
case 8805:
|
||||
setup.setScale(val);
|
||||
return true;
|
||||
case 8806:
|
||||
case 8826:
|
||||
{LinearUnits lu(units);
|
||||
if (lu.isNull())
|
||||
return false;
|
||||
setup.setFalseEasting(lu.toMeters(val));}
|
||||
return true;
|
||||
case 8807:
|
||||
case 8827:
|
||||
{LinearUnits lu(units);
|
||||
if (lu.isNull())
|
||||
return false;
|
||||
setup.setFalseNorthing(lu.toMeters(val));}
|
||||
return true;
|
||||
case 8823:
|
||||
{AngularUnits au(units);
|
||||
if (au.isNull())
|
||||
return false;
|
||||
setup.setStandardParallel1(au.toDegrees(val));}
|
||||
return true;
|
||||
case 8824:
|
||||
{AngularUnits au(units);
|
||||
if (au.isNull())
|
||||
return false;
|
||||
setup.setStandardParallel2(au.toDegrees(val));}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int projectionSetup(const QList<QByteArray> &list,
|
||||
Projection::Setup &setup)
|
||||
{
|
||||
bool r1, r2, r3;
|
||||
|
||||
for (int i = 6; i < 24; i += 3) {
|
||||
QString ks = list[i].trimmed();
|
||||
if (ks.isEmpty())
|
||||
break;
|
||||
|
||||
int key = ks.toInt(&r1);
|
||||
double val = list[i+1].trimmed().toDouble(&r2);
|
||||
int un = list[i+2].trimmed().toInt(&r3);
|
||||
if (!r1 || !r2 || !r3)
|
||||
return (i - 6)/3 + 1;
|
||||
|
||||
if (!parameter(key, val, un, setup))
|
||||
return (i - 6)/3 + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const PCS *PCS::pcs(int id)
|
||||
{
|
||||
for (int i = 0; i < _pcss.size(); i++)
|
||||
if (_pcss.at(i).id() == id)
|
||||
return &(_pcss.at(i).pcs());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const PCS *PCS::pcs(const GCS *gcs, int proj)
|
||||
{
|
||||
for (int i = 0; i < _pcss.size(); i++)
|
||||
if (_pcss.at(i).proj() == proj && *(_pcss.at(i).pcs().gcs()) == *gcs)
|
||||
return &(_pcss.at(i).pcs());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PCS::loadList(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
bool res;
|
||||
int ln = 0, pn;
|
||||
const GCS *gcs;
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
qWarning("Error opening PCS file: %s: %s", qPrintable(path),
|
||||
qPrintable(file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
while (!file.atEnd()) {
|
||||
ln++;
|
||||
|
||||
QByteArray line = file.readLine();
|
||||
QList<QByteArray> list = line.split(',');
|
||||
if (list.size() != 24) {
|
||||
qWarning("%s: %d: Format error", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
int id = list[1].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid PCS code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int gcsid = list[2].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid GCS code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int proj = list[3].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid projection code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int units = list[4].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid linear units code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int transform = list[5].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid coordinate transformation code",
|
||||
qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LinearUnits(units).isNull()) {
|
||||
qWarning("%s: %d: Unknown linear units code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
if (Projection::Method(transform).isNull()) {
|
||||
qWarning("%s: %d: Unknown coordinate transformation code",
|
||||
qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
if (!(gcs = GCS::gcs(gcsid))) {
|
||||
qWarning("%s: %d: Unknown GCS code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
Projection::Setup setup;
|
||||
if ((pn = projectionSetup(list, setup))) {
|
||||
qWarning("%s: %d: Invalid projection parameter #%d",
|
||||
qPrintable(path), ln, pn);
|
||||
continue;
|
||||
}
|
||||
|
||||
PCS pcs(gcs, transform, setup, units);
|
||||
_pcss.append(Entry(id, proj, pcs));
|
||||
}
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const PCS &pcs)
|
||||
{
|
||||
dbg.nospace() << "PCS(" << *pcs.gcs() << ", " << pcs.method() << ", "
|
||||
<< pcs.units() << ", " << pcs.setup() << ")";
|
||||
return dbg.space();
|
||||
}
|
48
src/map/pcs.h
Normal file
48
src/map/pcs.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef PCS_H
|
||||
#define PCS_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QList>
|
||||
#include "gcs.h"
|
||||
#include "linearunits.h"
|
||||
#include "projection.h"
|
||||
|
||||
class PCS
|
||||
{
|
||||
public:
|
||||
PCS() : _gcs(0) {}
|
||||
PCS(const GCS *gcs, const Projection::Method &method,
|
||||
const Projection::Setup &setup, const LinearUnits &units)
|
||||
: _gcs(gcs), _method(method), _setup(setup), _units(units) {}
|
||||
PCS(const GCS *gcs, int proj);
|
||||
|
||||
const GCS *gcs() const {return _gcs;}
|
||||
const Projection::Method &method() const {return _method;}
|
||||
const Projection::Setup &setup() const {return _setup;}
|
||||
const LinearUnits &units() const {return _units;}
|
||||
|
||||
bool isNull() const
|
||||
{return (_gcs->isNull() && _units.isNull() && _method.isNull()
|
||||
&& _setup.isNull());}
|
||||
bool isValid() const
|
||||
{return (_gcs->isValid() && _units.isValid() && _method.isValid());}
|
||||
|
||||
static void loadList(const QString &path);
|
||||
static const PCS *pcs(int id);
|
||||
static const PCS *pcs(const GCS *gcs, int proj);
|
||||
|
||||
private:
|
||||
class Entry;
|
||||
|
||||
const GCS *_gcs;
|
||||
Projection::Method _method;
|
||||
Projection::Setup _setup;
|
||||
LinearUnits _units;
|
||||
|
||||
static QList<Entry> _pcss;
|
||||
static GCS _nullGCS;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug dbg, const PCS &pcs);
|
||||
|
||||
#endif // PCS_H
|
73
src/map/primemeridian.cpp
Normal file
73
src/map/primemeridian.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "primemeridian.h"
|
||||
|
||||
static double shift(double lon, double offset)
|
||||
{
|
||||
double ret = lon + offset;
|
||||
|
||||
if (ret > 180.0)
|
||||
ret -= 360.0;
|
||||
if (ret < -180)
|
||||
ret += 360.0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PrimeMeridian::PrimeMeridian(int code)
|
||||
{
|
||||
switch (code) {
|
||||
case 8901:
|
||||
_pm = 0.0;
|
||||
break;
|
||||
case 8902:
|
||||
_pm = -9.1319061111;
|
||||
break;
|
||||
case 8903:
|
||||
_pm = 2.3372291666;
|
||||
break;
|
||||
case 8904:
|
||||
_pm = -74.0809166666;
|
||||
break;
|
||||
case 8905:
|
||||
_pm = -3.6879388888;
|
||||
break;
|
||||
case 8906:
|
||||
_pm = 12.4523333333;
|
||||
break;
|
||||
case 8907:
|
||||
_pm = 7.4395833333;
|
||||
break;
|
||||
case 8908:
|
||||
_pm = 106.8077194444;
|
||||
break;
|
||||
case 8909:
|
||||
_pm = -17.6666666666;
|
||||
break;
|
||||
case 8910:
|
||||
_pm = 4.3679750000;
|
||||
break;
|
||||
case 8911:
|
||||
_pm = 18.0582777777;
|
||||
break;
|
||||
case 8913:
|
||||
_pm = 10.7229166666;
|
||||
break;
|
||||
default:
|
||||
_pm = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
double PrimeMeridian::toGreenwich(double val) const
|
||||
{
|
||||
return shift(val, _pm);
|
||||
}
|
||||
|
||||
double PrimeMeridian::fromGreenwich(double val) const
|
||||
{
|
||||
return shift(val, -_pm);
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const PrimeMeridian &pm)
|
||||
{
|
||||
dbg.nospace() << "PrimeMeridian(" << pm._pm << ")";
|
||||
return dbg.space();
|
||||
}
|
31
src/map/primemeridian.h
Normal file
31
src/map/primemeridian.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef PRIMEMERIDIAN_H
|
||||
#define PRIMEMERIDIAN_H
|
||||
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
|
||||
class PrimeMeridian
|
||||
{
|
||||
public:
|
||||
PrimeMeridian() : _pm(NAN) {}
|
||||
PrimeMeridian(int code);
|
||||
|
||||
bool isNull() const {return std::isnan(_pm);}
|
||||
bool isValid() const {return !std::isnan(_pm);}
|
||||
|
||||
double toGreenwich(double val) const;
|
||||
double fromGreenwich(double val) const;
|
||||
|
||||
friend bool operator==(const PrimeMeridian &pm1, const PrimeMeridian &pm2);
|
||||
friend QDebug operator<<(QDebug dbg, const PrimeMeridian &pm);
|
||||
|
||||
private:
|
||||
double _pm;
|
||||
};
|
||||
|
||||
inline bool operator==(const PrimeMeridian &pm1, const PrimeMeridian &pm2)
|
||||
{return (pm1._pm == pm2._pm);}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const PrimeMeridian &pm);
|
||||
|
||||
#endif // PRIMEMERIDIAN_H
|
@ -1,89 +1,121 @@
|
||||
#include "latlon.h"
|
||||
#include "datum.h"
|
||||
#include "mercator.h"
|
||||
#include "transversemercator.h"
|
||||
#include "utm.h"
|
||||
#include "lambertconic.h"
|
||||
#include "albersequal.h"
|
||||
#include "lambertazimuthal.h"
|
||||
#include "latlon.h"
|
||||
#include "gcs.h"
|
||||
#include "projection.h"
|
||||
|
||||
|
||||
QString Projection::_errorString;
|
||||
|
||||
Projection *Projection::projection(const QString &name,
|
||||
const Ellipsoid &ellipsoid, const Setup &setup)
|
||||
Projection::Method::Method(int id)
|
||||
{
|
||||
if (setup.latitudeOrigin < -90.0 || setup.latitudeOrigin > 90.0
|
||||
|| setup.longitudeOrigin < -180.0 || setup.longitudeOrigin > 180.0
|
||||
|| setup.standardParallel1 < -90.0 || setup.standardParallel1 > 90.0
|
||||
|| setup.standardParallel2 < -90.0 || setup.standardParallel2 > 90.0) {
|
||||
_errorString = "Invalid projection setup";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (name == "Mercator")
|
||||
return new Mercator();
|
||||
else if (name == "Transverse Mercator")
|
||||
return new TransverseMercator(ellipsoid,
|
||||
setup.latitudeOrigin, setup.longitudeOrigin, setup.scale,
|
||||
setup.falseEasting, setup.falseNorthing);
|
||||
else if (name == "Latitude/Longitude")
|
||||
return new LatLon();
|
||||
else if (name == "Lambert Conformal Conic")
|
||||
return new LambertConic(ellipsoid,
|
||||
setup.standardParallel1, setup.standardParallel2,
|
||||
setup.latitudeOrigin, setup.longitudeOrigin, setup.scale,
|
||||
setup.falseEasting, setup.falseNorthing);
|
||||
else if (name == "Albers Equal Area")
|
||||
return new AlbersEqual(ellipsoid, setup.standardParallel1,
|
||||
setup.standardParallel2, setup.latitudeOrigin, setup.longitudeOrigin,
|
||||
setup.falseEasting, setup.falseNorthing);
|
||||
else if (name == "(A)Lambert Azimuthual Equal Area")
|
||||
return new LambertAzimuthal(ellipsoid, setup.latitudeOrigin,
|
||||
setup.longitudeOrigin, setup.falseEasting, setup.falseNorthing);
|
||||
else if (name == "(UTM) Universal Transverse Mercator") {
|
||||
if (setup.zone)
|
||||
return new UTM(ellipsoid, setup.zone);
|
||||
else {
|
||||
_errorString = "Can not determine UTM zone";
|
||||
return 0;
|
||||
}
|
||||
} else if (name == "(NZTM2) New Zealand TM 2000")
|
||||
return new TransverseMercator(ellipsoid, 0, 173.0, 0.9996,
|
||||
1600000, 10000000);
|
||||
else if (name == "(BNG) British National Grid")
|
||||
return new TransverseMercator(ellipsoid, 49, -2, 0.999601,
|
||||
400000, -100000);
|
||||
else if (name == "(IG) Irish Grid")
|
||||
return new TransverseMercator(ellipsoid, 53.5, -8, 1.000035,
|
||||
200000, 250000);
|
||||
else if (name == "(SG) Swedish Grid")
|
||||
return new TransverseMercator(ellipsoid, 0, 15.808278, 1,
|
||||
1500000, 0);
|
||||
else if (name == "(I) France Zone I")
|
||||
return new LambertConic(ellipsoid, 48.598523, 50.395912,
|
||||
49.5, 2.337229, 1 /*0.99987734*/, 600000, 1200000);
|
||||
else if (name == "(II) France Zone II")
|
||||
return new LambertConic(ellipsoid, 45.898919, 47.696014,
|
||||
46.8, 2.337229, 1 /*0.99987742*/, 600000, 2200000);
|
||||
else if (name == "(III) France Zone III")
|
||||
return new LambertConic(ellipsoid, 43.199291, 44.996094,
|
||||
44.1, 2.337229, 1 /*0.99987750*/, 600000, 3200000);
|
||||
else if (name == "(IV) France Zone IV")
|
||||
return new LambertConic(ellipsoid, 41.560388, 42.767663,
|
||||
42.165, 2.337229, 1 /*0.99994471*/, 234.358, 4185861.369);
|
||||
else if (name == "(VICGRID) Victoria Australia")
|
||||
return new LambertConic(ellipsoid, -36, -38, -37, 145, 1,
|
||||
2500000, 4500000);
|
||||
else if (name == "(VG94) VICGRID94 Victoria Australia")
|
||||
return new LambertConic(ellipsoid, -36, -38, -37, 145, 1,
|
||||
2500000, 2500000);
|
||||
else {
|
||||
_errorString = QString("%1: Unknown map projection").arg(name);
|
||||
return 0;
|
||||
switch (id) {
|
||||
case 1024:
|
||||
case 9801:
|
||||
case 9802:
|
||||
case 9807:
|
||||
case 9820:
|
||||
case 9822:
|
||||
case 9841:
|
||||
_id = id;
|
||||
break;
|
||||
default:
|
||||
_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const QString &Projection::errorString()
|
||||
Projection::Projection(const GCS *gcs, const Method &method, const Setup &setup,
|
||||
const LinearUnits &units) : _gcs(gcs), _units(units)
|
||||
{
|
||||
return _errorString;
|
||||
const Ellipsoid *ellipsoid = _gcs->datum().ellipsoid();
|
||||
|
||||
switch (method.id()) {
|
||||
case 9807:
|
||||
_ct = new TransverseMercator(ellipsoid, setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.scale(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
case 1024:
|
||||
case 9841:
|
||||
_ct = new Mercator();
|
||||
break;
|
||||
case 9802:
|
||||
_ct = new LambertConic2(ellipsoid, setup.standardParallel1(),
|
||||
setup.standardParallel2(), setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
case 9801:
|
||||
_ct = new LambertConic1(ellipsoid, setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.scale(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
case 9820:
|
||||
_ct = new LambertAzimuthal(ellipsoid, setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
case 9822:
|
||||
_ct = new AlbersEqual(ellipsoid, setup.standardParallel1(),
|
||||
setup.standardParallel2(), setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
default:
|
||||
_ct = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Projection::Projection(const GCS *gcs) : _gcs(gcs)
|
||||
{
|
||||
_ct = new LatLon(gcs->angularUnits());
|
||||
_units = LinearUnits(9001);
|
||||
}
|
||||
|
||||
Projection::Projection(const Projection &p)
|
||||
{
|
||||
_gcs = p._gcs;
|
||||
_units = p._units;
|
||||
_ct = p._ct->clone();
|
||||
}
|
||||
|
||||
Projection::~Projection()
|
||||
{
|
||||
delete _ct;
|
||||
}
|
||||
|
||||
Projection &Projection::operator=(const Projection &p)
|
||||
{
|
||||
_gcs = p._gcs;
|
||||
_units = p._units;
|
||||
_ct = p._ct->clone();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QPointF Projection::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
return _units.fromMeters(_ct->ll2xy(_gcs->fromWGS84(c)));
|
||||
}
|
||||
|
||||
Coordinates Projection::xy2ll(const QPointF &p) const
|
||||
{
|
||||
return _gcs->toWGS84(_ct->xy2ll(_units.toMeters(p)));
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Projection::Setup &setup)
|
||||
{
|
||||
dbg.nospace() << "Setup(" << setup.latitudeOrigin() << ", "
|
||||
<< setup.longitudeOrigin() << ", " << setup.scale() << ", "
|
||||
<< setup.falseEasting() << ", " << setup.falseNorthing() << ", "
|
||||
<< setup.standardParallel1() << ", " << setup.standardParallel2() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Projection::Method &method)
|
||||
{
|
||||
dbg.nospace() << "Method(" << method.id() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
|
@ -2,35 +2,91 @@
|
||||
#define PROJECTION_H
|
||||
|
||||
#include <QPointF>
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
#include "common/coordinates.h"
|
||||
#include "linearunits.h"
|
||||
|
||||
class Ellipsoid;
|
||||
class GCS;
|
||||
class CT;
|
||||
class AngularUnits;
|
||||
|
||||
class Projection {
|
||||
public:
|
||||
struct Setup {
|
||||
double latitudeOrigin;
|
||||
double longitudeOrigin;
|
||||
double scale;
|
||||
double falseEasting;
|
||||
double falseNorthing;
|
||||
double standardParallel1;
|
||||
double standardParallel2;
|
||||
int zone;
|
||||
class Setup {
|
||||
public:
|
||||
Setup() : _latitudeOrigin(NAN), _longitudeOrigin(NAN), _scale(NAN),
|
||||
_falseEasting(NAN), _falseNorthing(NAN), _standardParallel1(NAN),
|
||||
_standardParallel2(NAN) {}
|
||||
Setup(double latitudeOrigin, double longitudeOrigin, double scale,
|
||||
double falseEasting, double falseNorthing, double standardParallel1,
|
||||
double standardParallel2) : _latitudeOrigin(latitudeOrigin),
|
||||
_longitudeOrigin(longitudeOrigin), _scale(scale),
|
||||
_falseEasting(falseEasting), _falseNorthing(falseNorthing),
|
||||
_standardParallel1(standardParallel1),
|
||||
_standardParallel2(standardParallel2) {}
|
||||
|
||||
double latitudeOrigin() const {return _latitudeOrigin;}
|
||||
double longitudeOrigin() const {return _longitudeOrigin;}
|
||||
double scale() const {return _scale;}
|
||||
double falseEasting() const {return _falseEasting;}
|
||||
double falseNorthing() const {return _falseNorthing;}
|
||||
double standardParallel1() const {return _standardParallel1;}
|
||||
double standardParallel2() const {return _standardParallel2;}
|
||||
|
||||
void setLatitudeOrigin(double val) {_latitudeOrigin = val;}
|
||||
void setLongitudeOrigin(double val) {_longitudeOrigin = val;}
|
||||
void setScale(double val) {_scale = val;}
|
||||
void setFalseEasting(double val) {_falseEasting = val;}
|
||||
void setFalseNorthing(double val) {_falseNorthing = val;}
|
||||
void setStandardParallel1(double val) {_standardParallel1 = val;}
|
||||
void setStandardParallel2(double val) {_standardParallel2 = val;}
|
||||
|
||||
bool isNull() const {return std::isnan(_latitudeOrigin)
|
||||
&& std::isnan(_longitudeOrigin) && std::isnan(_scale)
|
||||
&& std::isnan(_falseEasting) && std::isnan(_falseNorthing)
|
||||
&& std::isnan(_standardParallel1) && std::isnan(_standardParallel2);}
|
||||
|
||||
private:
|
||||
double _latitudeOrigin;
|
||||
double _longitudeOrigin;
|
||||
double _scale;
|
||||
double _falseEasting;
|
||||
double _falseNorthing;
|
||||
double _standardParallel1;
|
||||
double _standardParallel2;
|
||||
};
|
||||
|
||||
virtual ~Projection() {}
|
||||
class Method {
|
||||
public:
|
||||
Method() : _id(0) {}
|
||||
Method(int id);
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const = 0;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const = 0;
|
||||
int id() const {return _id;}
|
||||
bool isNull() const {return (_id == 0);}
|
||||
bool isValid() const {return !isNull();}
|
||||
private:
|
||||
int _id;
|
||||
};
|
||||
|
||||
static Projection *projection(const QString &name,
|
||||
const Ellipsoid &ellipsoid, const Setup &setup);
|
||||
static const QString &errorString();
|
||||
Projection() : _gcs(0), _ct(0) {}
|
||||
Projection(const Projection &p);
|
||||
Projection(const GCS *gcs, const Method &method, const Setup &setup,
|
||||
const LinearUnits &units);
|
||||
Projection(const GCS *gcs);
|
||||
~Projection();
|
||||
|
||||
Projection &operator=(const Projection &p);
|
||||
|
||||
QPointF ll2xy(const Coordinates &c) const;
|
||||
Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
static QString _errorString;
|
||||
const GCS * _gcs;
|
||||
CT *_ct;
|
||||
LinearUnits _units;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Projection::Setup &setup);
|
||||
QDebug operator<<(QDebug dbg, const Projection::Method &method);
|
||||
|
||||
#endif // PROJECTION_H
|
||||
|
@ -12,6 +12,7 @@ public:
|
||||
|
||||
QStringList files() const {return _index.keys();}
|
||||
QByteArray file(const QString &name);
|
||||
bool contains(const QString &name) const {return _index.contains(name);}
|
||||
|
||||
QString fileName() const {return _file.fileName();}
|
||||
bool isOpen() const {return _file.isOpen();}
|
||||
|
28
src/map/tifffile.cpp
Normal file
28
src/map/tifffile.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include "tifffile.h"
|
||||
|
||||
#define TIFF_II 0x4949
|
||||
#define TIFF_MM 0x4D4D
|
||||
#define TIFF_MAGIC 42
|
||||
|
||||
bool TIFFFile::readHeader(quint32 &ifd)
|
||||
{
|
||||
quint16 endian, magic;
|
||||
|
||||
if (QFile::read((char*)&endian, sizeof(endian)) < (qint64)sizeof(endian))
|
||||
return false;
|
||||
if (endian == TIFF_II)
|
||||
_be = false;
|
||||
else if (endian == TIFF_MM)
|
||||
_be = true;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (!readValue(magic))
|
||||
return false;
|
||||
if (magic != TIFF_MAGIC)
|
||||
return false;
|
||||
if (!readValue(ifd))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
43
src/map/tifffile.h
Normal file
43
src/map/tifffile.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef TIFFFILE_H
|
||||
#define TIFFFILE_H
|
||||
|
||||
#include <QFile>
|
||||
#include <QtEndian>
|
||||
|
||||
class TIFFFile : public QFile
|
||||
{
|
||||
public:
|
||||
TIFFFile() : QFile(), _be(false) {}
|
||||
TIFFFile(const QString &path) : QFile(path), _be(false) {}
|
||||
|
||||
bool readHeader(quint32 &ifd);
|
||||
template<class T> bool readValue(T &val)
|
||||
{
|
||||
T data;
|
||||
|
||||
if (QFile::read((char*)&data, sizeof(T)) < (qint64)sizeof(T))
|
||||
return false;
|
||||
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
if (_be)
|
||||
val = data;
|
||||
else {
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
|
||||
}
|
||||
#else
|
||||
if (_be) {
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
|
||||
} else
|
||||
val = data;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _be;
|
||||
};
|
||||
|
||||
#endif // TIFFFILE_H
|
@ -24,7 +24,7 @@ private:
|
||||
inline QDebug operator<<(QDebug dbg, const Tile &tile)
|
||||
{
|
||||
dbg.nospace() << "Tile(" << tile.zoom() << ", " << tile.xy() << ")";
|
||||
return dbg.maybeSpace();
|
||||
return dbg.space();
|
||||
}
|
||||
|
||||
#endif // TILE_H
|
||||
|
80
src/map/transform.cpp
Normal file
80
src/map/transform.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
#include "projection.h"
|
||||
#include "matrix.h"
|
||||
#include "transform.h"
|
||||
|
||||
void Transform::simple(const QList<ReferencePoint> &points)
|
||||
{
|
||||
if (points.at(0).xy.x() == points.at(1).xy.x()
|
||||
|| points.at(0).xy.y() == points.at(1).xy.y()) {
|
||||
_errorString = "Invalid reference points tuple";
|
||||
return;
|
||||
}
|
||||
|
||||
qreal sX, sY, dX, dY;
|
||||
sX = (points.at(0).xy.x() - points.at(1).xy.x())
|
||||
/ (points.at(0).pp.x() - points.at(1).pp.x());
|
||||
sY = (points.at(1).xy.y() - points.at(0).xy.y())
|
||||
/ (points.at(1).pp.y() - points.at(0).pp.y());
|
||||
dX = points.at(1).xy.x() - points.at(1).pp.x() * sX;
|
||||
dY = points.at(0).xy.y() - points.at(0).pp.y() * sY;
|
||||
|
||||
_transform = QTransform(sX, 0, 0, sY, dX, dY);
|
||||
}
|
||||
|
||||
void Transform::affine(const QList<ReferencePoint> &points)
|
||||
{
|
||||
Matrix c(3, 2);
|
||||
c.zeroize();
|
||||
for (size_t i = 0; i < c.h(); i++) {
|
||||
for (size_t j = 0; j < c.w(); j++) {
|
||||
for (int k = 0; k < points.size(); k++) {
|
||||
double f[3], t[2];
|
||||
|
||||
f[0] = points.at(k).pp.x();
|
||||
f[1] = points.at(k).pp.y();
|
||||
f[2] = 1.0;
|
||||
t[0] = points.at(k).xy.x();
|
||||
t[1] = points.at(k).xy.y();
|
||||
c.m(i,j) += f[i] * t[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Matrix Q(3, 3);
|
||||
Q.zeroize();
|
||||
for (int qi = 0; qi < points.size(); qi++) {
|
||||
double v[3];
|
||||
|
||||
v[0] = points.at(qi).pp.x();
|
||||
v[1] = points.at(qi).pp.y();
|
||||
v[2] = 1.0;
|
||||
for (size_t i = 0; i < Q.h(); i++)
|
||||
for (size_t j = 0; j < Q.w(); j++)
|
||||
Q.m(i,j) += v[i] * v[j];
|
||||
}
|
||||
|
||||
Matrix M = Q.augemented(c);
|
||||
if (!M.eliminate()) {
|
||||
_errorString = "Singular transformation matrix";
|
||||
return;
|
||||
}
|
||||
|
||||
_transform = QTransform(M.m(0,3), M.m(0,4), M.m(1,3), M.m(1,4), M.m(2,3),
|
||||
M.m(2,4));
|
||||
}
|
||||
|
||||
Transform::Transform(const QList<ReferencePoint> &points)
|
||||
{
|
||||
if (points.count() < 2)
|
||||
_errorString = "Insufficient number of reference points";
|
||||
else if (points.size() == 2)
|
||||
simple(points);
|
||||
else
|
||||
affine(points);
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const ReferencePoint &p)
|
||||
{
|
||||
dbg.nospace() << "ReferencePoint(" << p.xy << ", " << p.pp << ")";
|
||||
return dbg.space();
|
||||
}
|
32
src/map/transform.h
Normal file
32
src/map/transform.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef TRANSFORM_H
|
||||
#define TRANSFORM_H
|
||||
|
||||
#include <QTransform>
|
||||
#include <QList>
|
||||
#include "common/coordinates.h"
|
||||
|
||||
struct ReferencePoint {
|
||||
QPoint xy;
|
||||
QPointF pp;
|
||||
};
|
||||
|
||||
class Transform
|
||||
{
|
||||
public:
|
||||
Transform(const QList<ReferencePoint> &points);
|
||||
|
||||
bool isNull() {return _transform.type() == QTransform::TxNone;}
|
||||
const QString &errorString() const {return _errorString;}
|
||||
const QTransform &transform() const {return _transform;}
|
||||
|
||||
private:
|
||||
void simple(const QList<ReferencePoint> &points);
|
||||
void affine(const QList<ReferencePoint> &points);
|
||||
|
||||
QTransform _transform;
|
||||
QString _errorString;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug dbg, const ReferencePoint &p);
|
||||
|
||||
#endif // TRANSFORM_H
|
@ -47,17 +47,17 @@ Defense.
|
||||
|
||||
|
||||
#define SPHSN(lat) \
|
||||
((double)(_e.radius() / sqrt(1.e0 - _es * pow(sin(lat), 2))))
|
||||
((double)(_e->radius() / sqrt(1.e0 - _es * pow(sin(lat), 2))))
|
||||
#define SPHTMD(lat) \
|
||||
((double)(_ap * lat - _bp * sin(2.e0 * lat) + _cp * sin(4.e0 * lat) \
|
||||
- _dp * sin(6.e0 * lat) + _ep * sin(8.e0 * lat)))
|
||||
#define DENOM(lat) \
|
||||
((double)(sqrt(1.e0 - _es * pow(sin(lat),2))))
|
||||
#define SPHSR(lat) \
|
||||
((double)(_e.radius() * (1.e0 - _es) / pow(DENOM(lat), 3)))
|
||||
((double)(_e->radius() * (1.e0 - _es) / pow(DENOM(lat), 3)))
|
||||
|
||||
|
||||
TransverseMercator::TransverseMercator(const Ellipsoid &ellipsoid,
|
||||
TransverseMercator::TransverseMercator(const Ellipsoid *ellipsoid,
|
||||
double latitudeOrigin, double longitudeOrigin, double scale,
|
||||
double falseEasting, double falseNorthing)
|
||||
{
|
||||
@ -72,24 +72,24 @@ TransverseMercator::TransverseMercator(const Ellipsoid &ellipsoid,
|
||||
_falseEasting = falseEasting;
|
||||
_falseNorthing = falseNorthing;
|
||||
|
||||
_es = 2 * _e.flattening() - _e.flattening() * _e.flattening();
|
||||
_es = 2 * _e->flattening() - _e->flattening() * _e->flattening();
|
||||
_ebs = (1 / (1 - _es)) - 1;
|
||||
|
||||
b = _e.radius() * (1 - _e.flattening());
|
||||
b = _e->radius() * (1 - _e->flattening());
|
||||
|
||||
tn = (_e.radius() - b) / (_e.radius() + b);
|
||||
tn = (_e->radius() - b) / (_e->radius() + b);
|
||||
tn2 = tn * tn;
|
||||
tn3 = tn2 * tn;
|
||||
tn4 = tn3 * tn;
|
||||
tn5 = tn4 * tn;
|
||||
|
||||
_ap = _e.radius() * (1.e0 - tn + 5.e0 * (tn2 - tn3) / 4.e0 + 81.e0
|
||||
_ap = _e->radius() * (1.e0 - tn + 5.e0 * (tn2 - tn3) / 4.e0 + 81.e0
|
||||
* (tn4 - tn5) / 64.e0);
|
||||
_bp = 3.e0 * _e.radius() * (tn - tn2 + 7.e0 * (tn3 - tn4) / 8.e0 + 55.e0
|
||||
_bp = 3.e0 * _e->radius() * (tn - tn2 + 7.e0 * (tn3 - tn4) / 8.e0 + 55.e0
|
||||
* tn5 / 64.e0 ) / 2.e0;
|
||||
_cp = 15.e0 * _e.radius() * (tn2 - tn3 + 3.e0 * (tn4 - tn5 ) / 4.e0) / 16.0;
|
||||
_dp = 35.e0 * _e.radius() * (tn3 - tn4 + 11.e0 * tn5 / 16.e0) / 48.e0;
|
||||
_ep = 315.e0 * _e.radius() * (tn4 - tn5) / 512.e0;
|
||||
_cp = 15.e0 * _e->radius() * (tn2 - tn3 + 3.e0 * (tn4 - tn5 ) / 4.e0) / 16.0;
|
||||
_dp = 35.e0 * _e->radius() * (tn3 - tn4 + 11.e0 * tn5 / 16.e0) / 48.e0;
|
||||
_ep = 315.e0 * _e->radius() * (tn4 - tn5) / 512.e0;
|
||||
}
|
||||
|
||||
QPointF TransverseMercator::ll2xy(const Coordinates &c) const
|
||||
|
@ -1,21 +1,23 @@
|
||||
#ifndef TRANSVERSEMERCATOR_H
|
||||
#define TRANSVERSEMERCATOR_H
|
||||
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
#include "ellipsoid.h"
|
||||
|
||||
class TransverseMercator : public Projection
|
||||
class TransverseMercator : public CT
|
||||
{
|
||||
public:
|
||||
TransverseMercator(const Ellipsoid &ellipsoid, double latitudeOrigin,
|
||||
TransverseMercator(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double scale, double falseEasting,
|
||||
double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new TransverseMercator(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
Ellipsoid _e;
|
||||
const Ellipsoid *_e;
|
||||
double _longitudeOrigin;
|
||||
double _latitudeOrigin;
|
||||
double _scale;
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "ellipsoid.h"
|
||||
#include "utm.h"
|
||||
|
||||
UTM::UTM(const Ellipsoid &ellipsoid, int zone)
|
||||
: _tm(ellipsoid, 0, (qAbs(zone) - 1)*6 - 180 + 3, 0.9996, 500000,
|
||||
zone < 0 ? 10000000 : 0)
|
||||
Projection::Setup UTM::setup(int zone)
|
||||
{
|
||||
return Projection::Setup(0, (qAbs(zone) - 1)*6 - 180 + 3, 0.9996, 500000,
|
||||
zone < 0 ? 10000000 : 0, 0, 0);
|
||||
}
|
||||
|
||||
int UTM::zone(const Coordinates &c)
|
||||
|
@ -2,22 +2,12 @@
|
||||
#define UTM_H
|
||||
|
||||
#include "projection.h"
|
||||
#include "transversemercator.h"
|
||||
|
||||
class UTM : public Projection
|
||||
class UTM
|
||||
{
|
||||
public:
|
||||
UTM(const Ellipsoid &ellipsoid, int zone);
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const
|
||||
{return _tm.ll2xy(c);}
|
||||
virtual Coordinates xy2ll(const QPointF &p) const
|
||||
{return _tm.xy2ll(p);}
|
||||
|
||||
static int zone(const Coordinates &c);
|
||||
|
||||
private:
|
||||
TransverseMercator _tm;
|
||||
static Projection::Setup setup(int zone);
|
||||
};
|
||||
|
||||
#endif // UTM_H
|
||||
|
Reference in New Issue
Block a user