mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-07-04 06:49:16 +02:00
Compare commits
57 Commits
Author | SHA1 | Date | |
---|---|---|---|
b40e0d3bbf | |||
9300d671a1 | |||
b9ed0c3933 | |||
46cefada94 | |||
e1e49b32e6 | |||
fa99d01a77 | |||
688e309ef7 | |||
ae4723acb1 | |||
8c6f70d837 | |||
d1b0e2ef73 | |||
962310df7d | |||
f8c031e931 | |||
8022a9efbe | |||
fbab4b0097 | |||
5e5ff6d96f | |||
55e967673c | |||
757ba6a566 | |||
ee80260e46 | |||
fa3e6d8550 | |||
6e95d484cd | |||
376587202b | |||
d11ffc9ea4 | |||
bf6ebdc088 | |||
619df591e2 | |||
10aa7d3945 | |||
12319fd8fd | |||
ccb7336e3f | |||
a7fea3878c | |||
a6cf88aa92 | |||
b054cf9046 | |||
9c5153f89a | |||
2ebcdeeeff | |||
1bc4833a81 | |||
3202fc4c15 | |||
5852a9dc09 | |||
c587d8cd9a | |||
586f30a337 | |||
da06c032bc | |||
3def9f95b0 | |||
dc25290637 | |||
9fd5b1b80a | |||
94ee5b6e67 | |||
9556476f1b | |||
b6e798f5c3 | |||
e82f2a02c2 | |||
361ffacc35 | |||
18fc6cc3e2 | |||
9815f0bff2 | |||
805cbe921c | |||
d529055ea3 | |||
5d590b7c86 | |||
1003c7b56f | |||
820f967bd6 | |||
27632bf07e | |||
ee5b8fa333 | |||
7e42b57d73 | |||
292fc9b433 |
@ -1,4 +1,4 @@
|
||||
version: 5.0.{build}
|
||||
version: 5.3.{build}
|
||||
configuration: Release
|
||||
platform: Any CPU
|
||||
environment:
|
||||
|
@ -4,7 +4,7 @@ KML, FIT, IGC and NMEA files.
|
||||
|
||||
## Features
|
||||
* User-definable online maps.
|
||||
* Offline maps (OziExplorer maps and TrekBuddy maps/atlases).
|
||||
* Offline maps (OziExplorer maps, TrekBuddy maps/atlases, GeoTIFF images).
|
||||
* Elevation, speed, heart rate, cadence, power and temperature graphs.
|
||||
* Support for multiple tracks in one view.
|
||||
* Support for POI files.
|
||||
|
12
gpxsee.pro
12
gpxsee.pro
@ -1,5 +1,5 @@
|
||||
TARGET = GPXSee
|
||||
VERSION = 5.0
|
||||
VERSION = 5.3
|
||||
QT += core \
|
||||
gui \
|
||||
network
|
||||
@ -116,7 +116,10 @@ HEADERS += src/config.h \
|
||||
src/map/primemeridian.h \
|
||||
src/map/linearunits.h \
|
||||
src/map/ct.h \
|
||||
src/map/mapsource.h
|
||||
src/map/mapsource.h \
|
||||
src/map/tileloader.h \
|
||||
src/map/wmtsmap.h \
|
||||
src/map/wmts.h
|
||||
SOURCES += src/main.cpp \
|
||||
src/common/coordinates.cpp \
|
||||
src/common/rectc.cpp \
|
||||
@ -202,7 +205,10 @@ SOURCES += src/main.cpp \
|
||||
src/map/angularunits.cpp \
|
||||
src/map/primemeridian.cpp \
|
||||
src/map/linearunits.cpp \
|
||||
src/map/mapsource.cpp
|
||||
src/map/mapsource.cpp \
|
||||
src/map/tileloader.cpp \
|
||||
src/map/wmtsmap.cpp \
|
||||
src/map/wmts.cpp
|
||||
RESOURCES += gpxsee.qrc
|
||||
TRANSLATIONS = lang/gpxsee_cs.ts \
|
||||
lang/gpxsee_sv.ts \
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
58
pkg/appdata.xml
Normal file
58
pkg/appdata.xml
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>gpxsee.desktop</id>
|
||||
<metadata_license>MIT</metadata_license>
|
||||
<project_license>GPL-3.0</project_license>
|
||||
|
||||
<name>GPXSee</name>
|
||||
<summary>GPS log file viewer and analyzer</summary>
|
||||
<description>
|
||||
<p>GPXSee is a GPS log file viewer and analyzer that supports GPX, TCX,
|
||||
KML, FIT, IGC and NMEA files.</p>
|
||||
|
||||
<p>Features:</p>
|
||||
<ul>
|
||||
<li>User-definable online maps.</li>
|
||||
<li>Offline maps (OziExplorer maps, TrekBuddy maps/atlases, GeoTIFF
|
||||
images).</li>
|
||||
<li>Elevation, speed, heart rate, cadence, power and temperature
|
||||
graphs.</li>
|
||||
<li>Support for multiple tracks in one view.</li>
|
||||
<li>Support for POI files.</li>
|
||||
<li>Print/export to PDF.</li>
|
||||
<li>Full-screen mode.</li>
|
||||
<li>Opens GPX, TCX, FIT, KML, IGC, NMEA and Garmin CSV files.</li>
|
||||
</ul>
|
||||
</description>
|
||||
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>http://www.gpxsee.org/gallery/lin1.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>http://www.gpxsee.org/gallery/lin2.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<categories>
|
||||
<category>Graphics</category>
|
||||
<category>Viewer</category>
|
||||
</categories>
|
||||
|
||||
<url type="homepage">http://www.gpxsee.org</url>
|
||||
|
||||
<launchable type="desktop-id">gpxsee.desktop</launchable>
|
||||
|
||||
<provides>
|
||||
<binary>gpxsee</binary>
|
||||
</provides>
|
||||
|
||||
<mimetypes>
|
||||
<mimetype>application/gpx+xml</mimetype>
|
||||
<mimetype>application/tcx+xml</mimetype>
|
||||
<mimetype>application/vnd.ant.fit</mimetype>
|
||||
<mimetype>application/vnd.google-earth.kml+xml</mimetype>
|
||||
<mimetype>application/vnd.fai.igc</mimetype>
|
||||
<mimetype>application/vnd.nmea.nmea</mimetype>
|
||||
</mimetypes>
|
||||
</component>
|
@ -29,6 +29,7 @@ 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
|
||||
ETRS 89,4258,6258,9122,7019,8901,9603,0,0,0
|
||||
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
|
||||
@ -104,6 +105,7 @@ 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
|
||||
S42 (83),4178,6178,9122,7024,8901,9603,26,-121,-78
|
||||
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
|
||||
|
|
162
pkg/csv/pcs.csv
162
pkg/csv/pcs.csv
@ -35,13 +35,24 @@ NZGD2000 / Bluff 2000,2132,4167,17958,9001,9807,8801,-46.36,9110,8802,168.2034,9
|
||||
NZGD2000 / UTM zone 58S,2133,4167,16158,9001,9807,8801,0,9102,8802,165,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,
|
||||
NZGD2000 / UTM zone 59S,2134,4167,16159,9001,9807,8801,0,9102,8802,171,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,
|
||||
NZGD2000 / UTM zone 60S,2135,4167,16160,9001,9807,8801,0,9102,8802,177,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,
|
||||
Pulkovo 1942(83) / Gauss Kruger zone 3,2166,4178,16263,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / Gauss Kruger zone 4,2167,4178,16264,9001,9807,8801,0,9102,8802,12,9102,8805,1,9201,8806,4500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / Gauss Kruger zone 5,2168,4178,16265,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,5500000,9001,8807,0,9001,,,
|
||||
MGI / Slovenia Grid,2170,4312,19967,9001,9807,8801,0,9110,8802,15,9110,8805,0.9999,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / Poland zone V,2175,4179,18285,9001,9807,8801,0,9110,8802,18.573,9110,8805,0.999983,9201,8806,237000,9001,8807,-4700000,9001,,,
|
||||
ETRS89 / Poland CS2000 zone 5,2176,4258,18305,9001,9807,8801,0,9102,8802,15,9102,8805,0.999923,9201,8806,5500000,9001,8807,0,9001,,,
|
||||
ETRS89 / Poland CS2000 zone 6,2177,4258,18306,9001,9807,8801,0,9102,8802,18,9102,8805,0.999923,9201,8806,6500000,9001,8807,0,9001,,,
|
||||
ETRS89 / Poland CS2000 zone 7,2178,4258,18307,9001,9807,8801,0,9102,8802,21,9102,8805,0.999923,9201,8806,7500000,9001,8807,0,9001,,,
|
||||
ETRS89 / Poland CS2000 zone 8,2179,4258,18308,9001,9807,8801,0,9102,8802,24,9102,8805,0.999923,9201,8806,8500000,9001,8807,0,9001,,,
|
||||
ETRS89 / Poland CS92,2180,4258,18300,9001,9807,8801,0,9102,8802,19,9102,8805,0.9993,9201,8806,500000,9001,8807,-5300000,9001,,,
|
||||
Azores Occidental 1939 / UTM zone 25N,2188,4182,16025,9001,9807,8801,0,9102,8802,-33,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Azores Central 1948 / UTM zone 26N,2189,4183,16026,9001,9807,8801,0,9102,8802,-27,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Azores Oriental 1940 / UTM zone 26N,2190,4184,16026,9001,9807,8801,0,9102,8802,-27,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ED50 / France EuroLambert,2192,4230,18086,9001,9801,8801,46.48,9110,8802,2.2014025,9110,8805,0.99987742,9201,8806,600000,9001,8807,2200000,9001,,,
|
||||
NZGD2000 / New Zealand Transverse Mercator 2000,2193,4167,19971,9001,9807,8801,0,9102,8802,173,9102,8805,0.9996,9201,8806,1600000,9001,8807,10000000,9001,,,
|
||||
ETRS89 / Kp2000 Jutland,2196,4258,18401,9001,9807,8801,0,9110,8802,9.3,9110,8805,0.99995,9201,8806,200000,9001,8807,0,9001,,,
|
||||
ETRS89 / Kp2000 Zealand,2197,4258,18402,9001,9807,8801,0,9102,8802,12,9102,8805,0.99995,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / Kp2000 Bornholm,2198,4258,18403,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,900000,9001,8807,0,9001,,,
|
||||
NAD27 / Tennessee,2204,4267,15302,9003,9802,8821,34.4,9110,8822,-86,9110,8823,35.15,9110,8824,36.25,9110,8826,2000000,9003,8827,100000,9003
|
||||
NAD83 / Kentucky North,2205,4269,15303,9001,9802,8821,37.3,9110,8822,-84.15,9110,8823,37.58,9110,8824,38.58,9110,8826,500000,9001,8827,0,9001
|
||||
ED50 / 3-degree Gauss-Kruger zone 9,2206,4230,16269,9001,9807,8801,0,9102,8802,27,9102,8805,1,9201,8806,9500000,9001,8807,0,9001,,,
|
||||
@ -51,6 +62,7 @@ ED50 / 3-degree Gauss-Kruger zone 12,2209,4230,16272,9001,9807,8801,0,9102,8802,
|
||||
ED50 / 3-degree Gauss-Kruger zone 13,2210,4230,16273,9001,9807,8801,0,9102,8802,39,9102,8805,1,9201,8806,13500000,9001,8807,0,9001,,,
|
||||
ED50 / 3-degree Gauss-Kruger zone 14,2211,4230,16274,9001,9807,8801,0,9102,8802,42,9102,8805,1,9201,8806,14500000,9001,8807,0,9001,,,
|
||||
ED50 / 3-degree Gauss-Kruger zone 15,2212,4230,16275,9001,9807,8801,0,9102,8802,45,9102,8805,1,9201,8806,15500000,9001,8807,0,9001,,,
|
||||
ETRS89 / TM 30 NE,2213,4258,16430,9001,9807,8801,0,9102,8802,30,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
NAD83 / Arizona East (ft),2222,4269,15304,9002,9807,8801,31,9110,8802,-110.1,9110,8805,0.9999,9201,8806,700000,9002,8807,0,9002,,,
|
||||
NAD83 / Arizona Central (ft),2223,4269,15305,9002,9807,8801,31,9110,8802,-111.55,9110,8805,0.9999,9201,8806,700000,9002,8807,0,9002,,,
|
||||
NAD83 / Arizona West (ft),2224,4269,15306,9002,9807,8801,31,9110,8802,-113.45,9110,8805,0.999933333,9201,8806,700000,9002,8807,0,9002,,,
|
||||
@ -138,6 +150,9 @@ KKJ / Finland zone 1,2391,4123,18191,9001,9807,8801,0,9102,8802,21,9102,8805,1,9
|
||||
KKJ / Finland zone 2,2392,4123,18192,9001,9807,8801,0,9102,8802,24,9102,8805,1,9201,8806,2500000,9001,8807,0,9001,,,
|
||||
KKJ / Finland Uniform Coordinate System,2393,4123,18193,9001,9807,8801,0,9102,8802,27,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
KKJ / Finland zone 4,2394,4123,18194,9001,9807,8801,0,9102,8802,30,9102,8805,1,9201,8806,4500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 3,2397,4178,16263,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 4,2398,4178,16264,9001,9807,8801,0,9102,8802,12,9102,8805,1,9201,8806,4500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 5,2399,4178,16265,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,5500000,9001,8807,0,9001,,,
|
||||
RT90 2.5 gon W,2400,4124,19929,9001,9807,8801,0,9110,8802,15.48298,9110,8805,1,9201,8806,1500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942 / Gauss-Kruger CM 9E,2492,4284,16302,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942 / Gauss-Kruger CM 15E,2493,4284,16303,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
@ -309,6 +324,22 @@ RT90 0 gon,3022,4124,17336,9001,9807,8801,0,9110,8802,18.03298,9110,8805,1,9201,
|
||||
RT90 2.5 gon O,3023,4124,17337,9001,9807,8801,0,9110,8802,20.18298,9110,8805,1,9201,8806,1500000,9001,8807,0,9001,,,
|
||||
RT90 5 gon O,3024,4124,17338,9001,9807,8801,0,9110,8802,22.33298,9110,8805,1,9201,8806,1500000,9001,8807,0,9001,,,
|
||||
WGS 84 / Australian Antarctic Lambert,3033,4326,19994,9001,9802,8821,-50,9110,8822,70,9110,8823,-68.3,9110,8824,-74.3,9110,8826,6000000,9001,8827,6000000,9001
|
||||
ETRS89 / LCC Europe,3034,4258,19985,9001,9802,8821,52,9102,8822,10,9102,8823,35,9102,8824,65,9102,8826,4000000,9001,8827,2800000,9001
|
||||
ETRS89 / LAEA Europe,3035,4258,19986,9001,9820,8801,52,9102,8802,10,9102,8806,4321000,9001,8807,3210000,9001,,,,,,
|
||||
ETRS89 / TM26,3038,4258,16026,9001,9807,8801,0,9102,8802,-27,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / TM27,3039,4258,16027,9001,9807,8801,0,9102,8802,-21,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 28N (N-E),3040,4258,16028,9001,9807,8801,0,9102,8802,-15,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 29N (N-E),3041,4258,16029,9001,9807,8801,0,9102,8802,-9,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 30N (N-E),3042,4258,16030,9001,9807,8801,0,9102,8802,-3,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 31N (N-E),3043,4258,16031,9001,9807,8801,0,9102,8802,3,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 32N (N-E),3044,4258,16032,9001,9807,8801,0,9102,8802,9,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 33N (N-E),3045,4258,16033,9001,9807,8801,0,9102,8802,15,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 34N (N-E),3046,4258,16034,9001,9807,8801,0,9102,8802,21,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 35N (N-E),3047,4258,16035,9001,9807,8801,0,9102,8802,27,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 36N (N-E),3048,4258,16036,9001,9807,8801,0,9102,8802,33,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 37N (N-E),3049,4258,16037,9001,9807,8801,0,9102,8802,39,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / TM38,3050,4258,16038,9001,9807,8801,0,9102,8802,45,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / TM39,3051,4258,16039,9001,9807,8801,0,9102,8802,51,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Hjorsey 1955 / UTM zone 26N,3054,4658,16026,9001,9807,8801,0,9102,8802,-27,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Hjorsey 1955 / UTM zone 27N,3055,4658,16027,9001,9807,8801,0,9102,8802,-21,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Hjorsey 1955 / UTM zone 28N,3056,4658,16028,9001,9807,8801,0,9102,8802,-15,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
@ -332,10 +363,25 @@ Tokyo / UTM zone 54N,3095,4301,16054,9001,9807,8801,0,9102,8802,141,9102,8805,0.
|
||||
Tokyo / UTM zone 55N,3096,4301,16055,9001,9807,8801,0,9102,8802,147,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Gulshan 303 / Bangladesh Transverse Mercator,3106,4682,16490,9001,9807,8801,0,9102,8802,90,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
GDA94 / SA Lambert,3107,4283,17359,9001,9802,8821,-32,9102,8822,135,9102,8823,-28,9102,8824,-36,9102,8826,1000000,9001,8827,2000000,9001
|
||||
ETRS89 / Guernsey Grid,3108,4258,19998,9001,9807,8801,49.3,9110,8802,-2.25,9110,8805,0.999997,9201,8806,47000,9001,8807,50000,9001,,,
|
||||
ETRS89 / Jersey Transverse Mercator,3109,4258,19999,9001,9807,8801,49.225,9102,8802,-2.135,9102,8805,0.9999999,9201,8806,40000,9001,8807,70000,9001,,,
|
||||
AGD66 / Vicgrid66,3110,4202,17360,9001,9802,8821,-37,9102,8822,145,9102,8823,-36,9102,8824,-38,9102,8826,2500000,9001,8827,4500000,9001
|
||||
GDA94 / Vicgrid,3111,4283,17361,9001,9802,8821,-37,9102,8822,145,9102,8823,-36,9102,8824,-38,9102,8826,2500000,9001,8827,2500000,9001
|
||||
GDA94 / Geoscience Australia Lambert,3112,4283,17362,9001,9802,8821,0,9102,8822,134,9102,8823,-18,9102,8824,-36,9102,8826,0,9001,8827,0,9001
|
||||
GDA94 / BCSG02,3113,4283,17363,9001,9807,8801,-28,9102,8802,153,9102,8805,0.99999,9201,8806,50000,9001,8807,100000,9001,,,
|
||||
ETRS89 / ETRS-GK19FIN,3126,4258,18183,9001,9807,8801,0,9102,8802,19,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK20FIN,3127,4258,18184,9001,9807,8801,0,9102,8802,20,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK21FIN,3128,4258,18185,9001,9807,8801,0,9102,8802,21,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK22FIN,3129,4258,18186,9001,9807,8801,0,9102,8802,22,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK23FIN,3130,4258,18187,9001,9807,8801,0,9102,8802,23,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK24FIN,3131,4258,18188,9001,9807,8801,0,9102,8802,24,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK25FIN,3132,4258,18189,9001,9807,8801,0,9102,8802,25,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK26FIN,3133,4258,18190,9001,9807,8801,0,9102,8802,26,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK27FIN,3134,4258,18195,9001,9807,8801,0,9102,8802,27,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK28FIN,3135,4258,18196,9001,9807,8801,0,9102,8802,28,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK29FIN,3136,4258,18197,9001,9807,8801,0,9102,8802,29,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK30FIN,3137,4258,18198,9001,9807,8801,0,9102,8802,30,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / ETRS-GK31FIN,3138,4258,18199,9001,9807,8801,0,9102,8802,31,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942 / 3-degree Gauss-Kruger zone 6,3146,4284,16266,9001,9807,8801,0,9102,8802,18,9102,8805,1,9201,8806,6500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942 / 3-degree Gauss-Kruger CM 18E,3147,4284,16366,9001,9807,8801,0,9102,8802,18,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
NAD83 / Ontario MNR Lambert,3161,4269,19875,9001,9802,8821,0,9102,8822,-85,9102,8823,44.5,9102,8824,53.5,9102,8826,930000,9001,8827,6430000,9001
|
||||
@ -439,6 +485,7 @@ KKJ / Finland zone 5,3387,4123,18205,9001,9807,8801,0,9102,8802,33,9102,8805,1,9
|
||||
Pulkovo 1942 / 3-degree Gauss-Kruger zone 60,3389,4284,16099,9001,9807,8801,0,9102,8802,180,9102,8805,1,9201,8806,60500000,9001,8807,0,9001,,,
|
||||
NAD83 / Alberta 10-TM (Forest),3400,4269,19881,9001,9807,8801,0,9102,8802,-115,9102,8805,0.9992,9201,8806,500000,9001,8807,0,9001,,,
|
||||
NAD83 / Alberta 10-TM (Resource),3401,4269,19882,9001,9807,8801,0,9102,8802,-115,9102,8805,0.9992,9201,8806,0,9001,8807,0,9001,,,
|
||||
ETRS89 / Austria Lambert,3416,4258,19947,9001,9802,8821,47.3,9110,8822,13.2,9110,8823,49,9110,8824,46,9110,8826,400000,9001,8827,400000,9001
|
||||
NAD83 / Iowa North (ftUS),3417,4269,15377,9003,9802,8821,41.3,9110,8822,-93.3,9110,8823,43.16,9110,8824,42.04,9110,8826,4921250,9003,8827,3280833.3333,9003
|
||||
NAD83 / Iowa South (ftUS),3418,4269,15378,9003,9802,8821,40,9110,8822,-93.3,9110,8823,41.47,9110,8824,40.37,9110,8826,1640416.6667,9003,8827,0,9003
|
||||
NAD83 / Kansas North (ftUS),3419,4269,15379,9003,9802,8821,38.2,9110,8822,-98,9110,8823,39.47,9110,8824,38.43,9110,8826,1312333.3333,9003,8827,0,9003
|
||||
@ -453,6 +500,7 @@ NAD83 / Illinois East (ftUS),3435,4269,15387,9003,9807,8801,36.4,9110,8802,-88.2
|
||||
NAD83 / Illinois West (ftUS),3436,4269,15388,9003,9807,8801,36.4,9110,8802,-90.1,9110,8805,0.999941177,9201,8806,2296583.3333,9003,8807,0,9003,,,
|
||||
NAD83 / New Hampshire (ftUS),3437,4269,15389,9003,9807,8801,42.3,9110,8802,-71.4,9110,8805,0.999966667,9201,8806,984250,9003,8807,0,9003,,,
|
||||
NAD83 / Rhode Island (ftUS),3438,4269,15390,9003,9807,8801,41.05,9110,8802,-71.3,9110,8805,0.99999375,9201,8806,328083.3333,9003,8807,0,9003,,,
|
||||
ETRS89 / Belgian Lambert 2005,3447,4258,19862,9001,9802,8821,50.4752134,9110,8822,4.2133177,9110,8823,49.5,9110,8824,51.1,9110,8826,150328,9001,8827,166262,9001
|
||||
NAD83 / Louisiana North (ftUS),3451,4269,15391,9003,9802,8821,30.3,9110,8822,-92.3,9110,8823,32.4,9110,8824,31.1,9110,8826,3280833.3333,9003,8827,0,9003
|
||||
NAD83 / Louisiana South (ftUS),3452,4269,15392,9003,9802,8821,28.3,9110,8822,-91.2,9110,8823,30.42,9110,8824,29.18,9110,8826,3280833.3333,9003,8827,0,9003
|
||||
NAD83 / Louisiana Offshore (ftUS),3453,4269,15393,9003,9802,8821,25.3,9110,8822,-91.2,9110,8823,27.5,9110,8824,26.1,9110,8826,3280833.3333,9003,8827,0,9003
|
||||
@ -485,6 +533,7 @@ NAD83 / Wyoming West Central (ftUS),3738,4269,14937,9003,9807,8801,40.3,9110,880
|
||||
NAD83 / Wyoming West (ftUS),3739,4269,14938,9003,9807,8801,40.3,9110,8802,-110.05,9110,8805,0.9999375,9201,8806,2624666.6667,9003,8807,328083.3333,9003,,,
|
||||
NAD83 / Hawaii zone 3 (ftUS),3759,4269,15138,9003,9807,8801,21.1,9110,8802,-158,9110,8805,0.99999,9201,8806,1640416.6667,9003,8807,0,9003,,,
|
||||
WGS 84 / South Georgia Lambert,3762,4326,19854,9001,9802,8821,-55,9102,8822,-37,9102,8823,-54,9110,8824,-54.45,9110,8826,0,9001,8827,0,9001
|
||||
ETRS89 / Portugal TM06,3763,4258,19853,9001,9807,8801,39.400573,9110,8802,-8.075919,9110,8805,1,9201,8806,0,9001,8807,0,9001,,,
|
||||
NZGD2000 / Chatham Island Circuit 2000,3764,4167,17959,9001,9807,8801,-44,9110,8802,-176.3,9110,8805,1,9201,8806,400000,9001,8807,800000,9001,,,
|
||||
Bermuda 1957 / UTM zone 20N,3769,4216,16020,9001,9807,8801,0,9102,8802,-63,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
NAD27 / Alberta 3TM ref merid 111 W,3771,4267,17722,9001,9807,8801,0,9102,8802,-111,9102,8805,0.9999,9201,8806,0,9001,8807,0,9001,,,
|
||||
@ -508,15 +557,35 @@ NAD27 / MTQ Lambert,3797,4267,19844,9001,9802,8821,44,9102,8822,-70,9102,8823,50
|
||||
NAD83 / MTQ Lambert,3798,4269,19844,9001,9802,8821,44,9102,8822,-70,9102,8823,50,9102,8824,46,9102,8826,800000,9001,8827,0,9001
|
||||
NAD27 / Alberta 3TM ref merid 120 W,3800,4267,17726,9001,9807,8801,0,9102,8802,-120,9102,8805,0.9999,9201,8806,0,9001,8807,0,9001,,,
|
||||
NAD83 / Alberta 3TM ref merid 120 W,3801,4269,17726,9001,9807,8801,0,9102,8802,-120,9102,8805,0.9999,9201,8806,0,9001,8807,0,9001,,,
|
||||
ETRS89 / Belgian Lambert 2008,3812,4258,3811,9001,9802,8821,50.4752134,9110,8822,4.2133177,9110,8823,49.5,9110,8824,51.1,9110,8826,649328,9001,8827,665262,9001
|
||||
NAD83 / Mississippi TM,3814,4269,3813,9001,9807,8801,32.3,9110,8802,-89.45,9110,8805,0.9998335,9201,8806,500000,9001,8807,1300000,9001,,,
|
||||
Hu Tzu Shan 1950 / UTM zone 51N,3829,4236,16051,9001,9807,8801,0,9102,8802,123,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / Gauss-Kruger zone 2,3833,4179,16202,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,2500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / Gauss-Kruger zone 2,3834,4178,16202,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,2500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / Gauss-Kruger zone 3,3835,4178,16203,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / Gauss-Kruger zone 4,3836,4178,16204,9001,9807,8801,0,9102,8802,21,9102,8805,1,9201,8806,4500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 3,3837,4179,16263,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 4,3838,4179,16264,9001,9807,8801,0,9102,8802,12,9102,8805,1,9201,8806,4500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 9,3839,4179,16269,9001,9807,8801,0,9102,8802,27,9102,8805,1,9201,8806,9500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 10,3840,4179,16270,9001,9807,8801,0,9102,8802,30,9102,8805,1,9201,8806,10500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 6,3841,4178,16266,9001,9807,8801,0,9102,8802,18,9102,8805,1,9201,8806,6500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 7,3842,4178,16266,9001,9807,8801,0,9102,8802,18,9102,8805,1,9201,8806,6500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 8,3843,4178,16266,9001,9807,8801,0,9102,8802,18,9102,8805,1,9201,8806,6500000,9001,8807,0,9001,,,
|
||||
NZGD2000 / NZCS2000,3851,4167,17964,9001,9802,8821,-41,9110,8822,173,9110,8823,-37.3,9110,8824,-44.3,9110,8826,3000000,9001,8827,7000000,9001
|
||||
WGS 84 / Pseudo-Mercator,3857,4326,3856,9001,1024,8801,0,9102,8802,0,9102,8806,0,9001,8807,0,9001,,,,,,
|
||||
ETRS89 / GK19FIN,3873,4258,3860,9001,9807,8801,0,9102,8802,19,9102,8805,1,9201,8806,19500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK20FIN,3874,4258,3861,9001,9807,8801,0,9102,8802,20,9102,8805,1,9201,8806,20500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK21FIN,3875,4258,3862,9001,9807,8801,0,9102,8802,21,9102,8805,1,9201,8806,21500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK22FIN,3876,4258,3863,9001,9807,8801,0,9102,8802,22,9102,8805,1,9201,8806,22500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK23FIN,3877,4258,3864,9001,9807,8801,0,9102,8802,23,9102,8805,1,9201,8806,23500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK24FIN,3878,4258,3865,9001,9807,8801,0,9102,8802,24,9102,8805,1,9201,8806,24500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK25FIN,3879,4258,3866,9001,9807,8801,0,9102,8802,25,9102,8805,1,9201,8806,25500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK26FIN,3880,4258,3867,9001,9807,8801,0,9102,8802,26,9102,8805,1,9201,8806,26500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK27FIN,3881,4258,3868,9001,9807,8801,0,9102,8802,27,9102,8805,1,9201,8806,27500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK28FIN,3882,4258,3869,9001,9807,8801,0,9102,8802,28,9102,8805,1,9201,8806,28500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK29FIN,3883,4258,3870,9001,9807,8801,0,9102,8802,29,9102,8805,1,9201,8806,29500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK30FIN,3884,4258,3871,9001,9807,8801,0,9102,8802,30,9102,8805,1,9201,8806,30500000,9001,8807,0,9001,,,
|
||||
ETRS89 / GK31FIN,3885,4258,3872,9001,9807,8801,0,9102,8802,31,9102,8805,1,9201,8806,31500000,9001,8807,0,9001,,,
|
||||
ED50 / Iraq National Grid,3893,4230,19907,9001,9807,8801,29.0134566,9110,8802,46.3,9110,8805,0.9994,9201,8806,800000,9001,8807,0,9001,,,
|
||||
MGI 1901 / Balkans zone 5,3907,3906,18275,9001,9807,8801,0,9102,8802,15,9102,8805,0.9999,9201,8806,5500000,9001,8807,0,9001,,,
|
||||
MGI 1901 / Balkans zone 6,3908,3906,18276,9001,9807,8801,0,9102,8802,18,9102,8805,0.9999,9201,8806,6500000,9001,8807,0,9001,,,
|
||||
@ -533,6 +602,10 @@ WGS 84 / Dubai Local TM,3997,4326,19839,9001,9807,8801,0,9110,8802,55.2,9110,880
|
||||
WGS 84 / TMzn35N,4037,4326,16035,9001,9807,8801,0,9102,8802,27,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
WGS 84 / TMzn36N,4038,4326,16036,9001,9807,8801,0,9102,8802,33,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Chua / UTM zone 23S,4071,4224,16123,9001,9807,8801,0,9102,8802,-45,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,
|
||||
ETRS89 / DKTM1,4093,4258,4089,9001,9807,8801,0,9102,8802,9,9102,8805,0.99998,9201,8806,200000,9001,8807,-5000000,9001,,,
|
||||
ETRS89 / DKTM2,4094,4258,4090,9001,9807,8801,0,9102,8802,10,9102,8805,0.99998,9201,8806,400000,9001,8807,-5000000,9001,,,
|
||||
ETRS89 / DKTM3,4095,4258,4091,9001,9807,8801,0,9102,8802,11.75,9102,8805,0.99998,9201,8806,600000,9001,8807,-5000000,9001,,,
|
||||
ETRS89 / DKTM4,4096,4258,4092,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,800000,9001,8807,-5000000,9001,,,
|
||||
NAD83 / BLM 59N (ftUS),4217,4269,4186,9003,9807,8801,0,9102,8802,171,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD27 / BLM 59N (ftUS),4399,4267,4186,9003,9807,8801,0,9102,8802,171,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD27 / BLM 60N (ftUS),4400,4267,4187,9003,9807,8801,0,9102,8802,177,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
@ -549,6 +622,7 @@ NAD27 / BLM 10N (ftUS),4410,4267,4110,9003,9807,8801,0,9102,8802,-123,9102,8805,
|
||||
NAD27 / BLM 11N (ftUS),4411,4267,4111,9003,9807,8801,0,9102,8802,-117,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD27 / BLM 12N (ftUS),4412,4267,4112,9003,9807,8801,0,9102,8802,-111,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD27 / BLM 13N (ftUS),4413,4267,4113,9003,9807,8801,0,9102,8802,-105,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 7,4417,4178,16267,9001,9807,8801,0,9102,8802,21,9102,8805,1,9201,8806,7500000,9001,8807,0,9001,,,
|
||||
NAD27 / BLM 18N (ftUS),4418,4267,4118,9003,9807,8801,0,9102,8802,-75,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD27 / BLM 19N (ftUS),4419,4267,4119,9003,9807,8801,0,9102,8802,-69,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD83 / BLM 60N (ftUS),4420,4269,4187,9003,9807,8801,0,9102,8802,177,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
@ -565,17 +639,74 @@ NAD83 / BLM 10N (ftUS),4430,4269,4110,9003,9807,8801,0,9102,8802,-123,9102,8805,
|
||||
NAD83 / BLM 11N (ftUS),4431,4269,4111,9003,9807,8801,0,9102,8802,-117,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD83 / BLM 12N (ftUS),4432,4269,4112,9003,9807,8801,0,9102,8802,-111,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD83 / BLM 13N (ftUS),4433,4269,4113,9003,9807,8801,0,9102,8802,-105,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 8,4434,4178,16268,9001,9807,8801,0,9102,8802,24,9102,8805,1,9201,8806,8500000,9001,8807,0,9001,,,
|
||||
NAD83 / BLM 18N (ftUS),4438,4269,4118,9003,9807,8801,0,9102,8802,-75,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD83 / BLM 19N (ftUS),4439,4269,4119,9003,9807,8801,0,9102,8802,-69,9102,8805,0.9996,9201,8806,1640416.67,9003,8807,0,9003,,,
|
||||
NAD27 / Pennsylvania South,4455,4267,4436,9003,9802,8821,39.2,9110,8822,-77.45,9110,8823,40.58,9110,8824,39.56,9110,8826,2000000,9003,8827,0,9003
|
||||
NAD27 / New York Long Island,4456,4267,4454,9003,9802,8821,40.3,9110,8822,-74,9110,8823,41.02,9110,8824,40.4,9110,8826,2000000,9003,8827,100000,9003
|
||||
NAD83 / South Dakota North (ftUS),4457,4269,15394,9003,9802,8821,43.5,9110,8822,-100,9110,8823,45.41,9110,8824,44.25,9110,8826,1968500,9003,8827,0,9003
|
||||
WGS 84 / Australian Centre for Remote Sensing Lambert,4462,4326,4460,9001,9802,8821,-27,9102,8822,132,9102,8823,-18,9102,8824,-36,9102,8826,0,9001,8827,0,9001
|
||||
ETRS89 / UTM zone 32N (zE-N),4647,4258,4648,9001,9807,8801,0,9102,8802,9,9102,8805,0.9996,9201,8806,32500000,9001,8807,0,9001,,,
|
||||
WGS 84 / Cape Verde National,4826,4326,4825,9001,9802,8821,15.5,9110,8822,-24,9110,8823,15,9110,8824,16.4,9110,8826,161587.83,9001,8827,128511.202,9001
|
||||
ETRS89 / LCC Germany (N-E),4839,4258,4838,9001,9802,8821,51,9102,8822,10.3,9110,8823,48.4,9110,8824,53.4,9110,8826,0,9001,8827,0,9001
|
||||
ETRS89 / NTM zone 5,4855,4258,4845,9001,9807,8801,0,9110,8802,5.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 6,4856,4258,4846,9001,9807,8801,0,9110,8802,6.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 7,4857,4258,4847,9001,9807,8801,0,9110,8802,7.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 8,4858,4258,4848,9001,9807,8801,0,9110,8802,8.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 9,4859,4258,4849,9001,9807,8801,0,9110,8802,9.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 10,4860,4258,4850,9001,9807,8801,0,9110,8802,10.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 11,4861,4258,4851,9001,9807,8801,0,9110,8802,11.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 12,4862,4258,4852,9001,9807,8801,0,9110,8802,12.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 13,4863,4258,4853,9001,9807,8801,0,9110,8802,13.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 14,4864,4258,4854,9001,9807,8801,0,9110,8802,14.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 15,4865,4258,4841,9001,9807,8801,0,9110,8802,15.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 16,4866,4258,4842,9001,9807,8801,0,9110,8802,16.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 17,4867,4258,4843,9001,9807,8801,0,9110,8802,17.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 18,4868,4258,4844,9001,9807,8801,0,9110,8802,18.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 19,4869,4258,4881,9001,9807,8801,0,9110,8802,19.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 20,4870,4258,5000,9001,9807,8801,0,9110,8802,20.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 21,4871,4258,5001,9001,9807,8801,0,9110,8802,21.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 22,4872,4258,5002,9001,9807,8801,0,9110,8802,22.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 23,4873,4258,5003,9001,9807,8801,0,9110,8802,23.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 24,4874,4258,5004,9001,9807,8801,0,9110,8802,24.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 25,4875,4258,5005,9001,9807,8801,0,9110,8802,25.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 26,4876,4258,5006,9001,9807,8801,0,9110,8802,26.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 27,4877,4258,5007,9001,9807,8801,0,9110,8802,27.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 28,4878,4258,5008,9001,9807,8801,0,9110,8802,28.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 29,4879,4258,5009,9001,9807,8801,0,9110,8802,29.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 30,4880,4258,5010,9001,9807,8801,0,9110,8802,30.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
NAD27 / Conus Albers,5069,4267,5068,9001,9822,8821,23,9102,8822,-96,9102,8823,29.3,9110,8824,45.3,9110,8826,0,9001,8827,0,9001
|
||||
NAD83 / Conus Albers,5070,4269,5068,9001,9822,8821,23,9102,8822,-96,9102,8823,29.3,9110,8824,45.3,9110,8826,0,9001,8827,0,9001
|
||||
ETRS89 / NTM zone 5,5105,4258,5135,9001,9807,8801,58,9110,8802,5.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 6,5106,4258,5136,9001,9807,8801,58,9110,8802,6.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 7,5107,4258,5137,9001,9807,8801,58,9110,8802,7.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 8,5108,4258,5138,9001,9807,8801,58,9110,8802,8.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 9,5109,4258,5139,9001,9807,8801,58,9110,8802,9.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 10,5110,4258,5140,9001,9807,8801,58,9110,8802,10.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 11,5111,4258,5141,9001,9807,8801,58,9110,8802,11.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 12,5112,4258,5142,9001,9807,8801,58,9110,8802,12.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 13,5113,4258,5143,9001,9807,8801,58,9110,8802,13.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 14,5114,4258,5144,9001,9807,8801,58,9110,8802,14.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 15,5115,4258,5145,9001,9807,8801,58,9110,8802,15.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 16,5116,4258,5146,9001,9807,8801,58,9110,8802,16.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 17,5117,4258,5147,9001,9807,8801,58,9110,8802,17.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 18,5118,4258,5148,9001,9807,8801,58,9110,8802,18.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 19,5119,4258,5149,9001,9807,8801,58,9110,8802,19.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 20,5120,4258,5150,9001,9807,8801,58,9110,8802,20.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 21,5121,4258,5151,9001,9807,8801,58,9110,8802,21.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 22,5122,4258,5152,9001,9807,8801,58,9110,8802,22.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 23,5123,4258,5153,9001,9807,8801,58,9110,8802,23.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 24,5124,4258,5154,9001,9807,8801,58,9110,8802,24.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 25,5125,4258,5155,9001,9807,8801,58,9110,8802,25.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 26,5126,4258,5156,9001,9807,8801,58,9110,8802,26.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 27,5127,4258,5157,9001,9807,8801,58,9110,8802,27.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 28,5128,4258,5158,9001,9807,8801,58,9110,8802,28.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 29,5129,4258,5159,9001,9807,8801,58,9110,8802,29.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
ETRS89 / NTM zone 30,5130,4258,5160,9001,9807,8801,58,9110,8802,30.3,9110,8805,1,9201,8806,100000,9001,8807,1000000,9001,,,
|
||||
WGS 84 / Gabon TM,5223,4326,5222,9001,9807,8801,0,9102,8802,12,9102,8805,0.9996,9201,8806,500000,9001,8807,500000,9001,,,
|
||||
Kandawala / Sri Lanka Grid,5234,4244,5231,9001,9807,8801,7.0001729,9110,8802,80.461816,9110,8805,0.9999238418,9201,8806,200000,9001,8807,200000,9001,,,
|
||||
ETRS89 / LCC Germany (E-N),5243,4258,4838,9001,9802,8821,51,9102,8822,10.3,9110,8823,48.4,9110,8824,53.4,9110,8826,0,9001,8827,0,9001
|
||||
ETRS89 / Faroe TM,5316,4258,5315,9001,9807,8801,0,9102,8802,-7,9102,8805,0.999997,9201,8806,200000,9001,8807,-6000000,9001,,,
|
||||
NAD83 / Teranet Ontario Lambert,5320,4269,5319,9001,9802,8821,0,9102,8822,-84,9102,8823,44.3,9110,8824,54.3,9110,8826,1000000,9001,8827,0,9001
|
||||
Ocotepeque 1935 / Guatemala Norte,5458,4267,18211,9001,9801,8801,16.49,9110,8802,-90.2,9110,8805,0.99992226,9201,8806,500000,9001,8807,292209.579,9001,,,
|
||||
CI1971 / Chatham Islands Map Grid,5518,4672,5517,9001,9807,8801,-44,9110,8802,-176.3,9110,8805,1,9201,8806,350000,9001,8807,650000,9001,,,
|
||||
@ -588,10 +719,20 @@ ED50 / TM 6 NE,5627,4230,16406,9001,9807,8801,0,9102,8802,6,9102,8805,0.9996,920
|
||||
Pulkovo 1942(58) / Gauss-Kruger zone 2 (E-N),5631,4179,16202,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,2500000,9001,8807,0,9001,,,
|
||||
ED50 / SPBA LCC,5643,4230,5642,9001,9802,8821,48,9102,8822,10,9102,8823,52.4,9110,8824,54.2,9110,8826,815000,9001,8827,0,9001
|
||||
NAD83 / Vermont (ftUS),5646,4269,5645,9003,9807,8801,42.3,9110,8802,-72.3,9110,8805,0.999964286,9201,8806,1640416.6667,9003,8807,0,9003,,,
|
||||
ETRS89 / UTM zone 31N (zE-N),5649,4258,5647,9001,9807,8801,0,9102,8802,3,9102,8805,0.9996,9201,8806,31500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 33N (zE-N),5650,4258,5648,9001,9807,8801,0,9102,8802,15,9102,8805,0.9996,9201,8806,33500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 31N (N-zE),5651,4258,5647,9001,9807,8801,0,9102,8802,3,9102,8805,0.9996,9201,8806,31500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 32N (N-zE),5652,4258,4648,9001,9807,8801,0,9102,8802,9,9102,8805,0.9996,9201,8806,32500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 33N (N-zE),5653,4258,5648,9001,9807,8801,0,9102,8802,15,9102,8805,0.9996,9201,8806,33500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / Gauss-Kruger zone 3 (E-N),5663,4179,16203,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / Gauss-Kruger zone 2 (E-N),5664,4178,16202,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,2500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / Gauss-Kruger zone 3 (E-N),5665,4178,16203,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 3 (E-N),5670,4179,16263,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 4 (E-N),5671,4179,16264,9001,9807,8801,0,9102,8802,12,9102,8805,1,9201,8806,4500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 5 (E-N),5672,4179,16265,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,5500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 3 (E-N),5673,4178,16263,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 4 (E-N),5674,4178,16264,9001,9807,8801,0,9102,8802,12,9102,8805,1,9201,8806,4500000,9001,8807,0,9001,,,
|
||||
Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 5 (E-N),5675,4178,16265,9001,9807,8801,0,9102,8802,15,9102,8805,1,9201,8806,5500000,9001,8807,0,9001,,,
|
||||
DHDN / 3-degree Gauss-Kruger zone 2 (E-N),5676,4314,16262,9001,9807,8801,0,9102,8802,6,9102,8805,1,9201,8806,2500000,9001,8807,0,9001,,,
|
||||
DHDN / 3-degree Gauss-Kruger zone 3 (E-N),5677,4314,16263,9001,9807,8801,0,9102,8802,9,9102,8805,1,9201,8806,3500000,9001,8807,0,9001,,,
|
||||
DHDN / 3-degree Gauss-Kruger zone 4 (E-N),5678,4314,16264,9001,9807,8801,0,9102,8802,12,9102,8805,1,9201,8806,4500000,9001,8807,0,9001,,,
|
||||
@ -615,6 +756,12 @@ WGS 84 / EPSG Arctic Regional zone C2,5932,4326,5917,9001,9802,8821,65.06045752,
|
||||
WGS 84 / EPSG Arctic Regional zone C3,5933,4326,5918,9001,9802,8821,65.06045752,9110,8822,33,9102,8823,69,9102,8824,61,9102,8826,0,9001,8827,0,9001
|
||||
WGS 84 / EPSG Arctic Regional zone C4,5934,4326,5919,9001,9802,8821,65.06045752,9110,8822,105,9102,8823,69,9102,8824,61,9102,8826,0,9001,8827,0,9001
|
||||
WGS 84 / EPSG Arctic Regional zone C5,5935,4326,5920,9001,9802,8821,65.06045752,9110,8822,177,9102,8823,69,9102,8824,61,9102,8826,0,9001,8827,0,9001
|
||||
ETRS89 / EPSG Arctic zone 2-22,6069,4258,5989,9001,9802,8821,82.03303296,9110,8822,16,9110,8823,83.4,9110,8824,80.2,9110,8826,22500000,9001,8827,2500000,9001
|
||||
ETRS89 / EPSG Arctic zone 3-11,6070,4258,5993,9001,9802,8821,78.42264151,9110,8822,21,9110,8823,80.2,9110,8824,77,9110,8826,11500000,9001,8827,3500000,9001
|
||||
ETRS89 / EPSG Arctic zone 4-26,6071,4258,6012,9001,9802,8821,75.21518519,9110,8822,10,9110,8823,77,9110,8824,73.4,9110,8826,26500000,9001,8827,4500000,9001
|
||||
ETRS89 / EPSG Arctic zone 4-28,6072,4258,6013,9001,9802,8821,75.21518519,9110,8822,34,9110,8823,77,9110,8824,73.4,9110,8826,28500000,9001,8827,4500000,9001
|
||||
ETRS89 / EPSG Arctic zone 5-11,6073,4258,6020,9001,9802,8821,72.01300331,9110,8822,14,9110,8823,73.4,9110,8824,70.2,9110,8826,11500000,9001,8827,5500000,9001
|
||||
ETRS89 / EPSG Arctic zone 5-13,6074,4258,6021,9001,9802,8821,72.01300331,9110,8822,34,9110,8823,73.4,9110,8824,70.2,9110,8826,13500000,9001,8827,5500000,9001
|
||||
WGS 84 / EPSG Arctic zone 2-24,6075,4326,5990,9001,9802,8821,82.03303296,9110,8822,53,9110,8823,83.4,9110,8824,80.2,9110,8826,24500000,9001,8827,2500000,9001
|
||||
WGS 84 / EPSG Arctic zone 2-26,6076,4326,5991,9001,9802,8821,82.03303296,9110,8822,93,9110,8823,83.4,9110,8824,80.2,9110,8826,26500000,9001,8827,2500000,9001
|
||||
WGS 84 / EPSG Arctic zone 3-13,6077,4326,5994,9001,9802,8821,78.42264151,9110,8822,52,9110,8823,80.2,9110,8824,77,9110,8826,13500000,9001,8827,3500000,9001
|
||||
@ -644,6 +791,7 @@ WGS 84 / EPSG Arctic zone 2-12,6121,4326,5984,9001,9802,8821,82.03303296,9110,88
|
||||
WGS 84 / EPSG Arctic zone 3-21,6122,4326,5998,9001,9802,8821,78.42264151,9110,8822,176,9110,8823,80.2,9110,8824,77,9110,8826,21500000,9001,8827,3500000,9001
|
||||
WGS 84 / EPSG Arctic zone 3-23,6123,4326,5999,9001,9802,8821,78.42264151,9110,8822,-153,9110,8823,80.2,9110,8824,77,9110,8826,23500000,9001,8827,3500000,9001
|
||||
WGS 84 / EPSG Arctic zone 4-12,6124,4326,6005,9001,9802,8821,75.21518519,9110,8822,-155,9110,8823,77,9110,8824,73.4,9110,8826,12500000,9001,8827,4500000,9001
|
||||
ETRS89 / EPSG Arctic zone 5-47,6125,4258,6038,9001,9802,8821,72.01300331,9110,8822,-5,9110,8823,73.4,9110,8824,70.2,9110,8826,47500000,9001,8827,5500000,9001
|
||||
Sister Islands National Grid 1961,6129,4726,6127,9002,9807,8801,0,9102,8802,-81,9102,8805,0.9996,9201,8806,1640419.9475,9002,8807,0,9002,,,
|
||||
Macedonia State Coordinate System,6204,3906,6203,9001,9807,8801,0,9102,8802,21,9102,8805,0.9999,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Macedonia State Coordinate System zone 7,6316,3906,18277,9001,9807,8801,0,9102,8802,21,9102,8805,0.9999,9201,8806,7500000,9001,8807,0,9001,,,
|
||||
@ -660,10 +808,12 @@ GDA94 / MGA zone 44,6735,4283,6728,9001,9807,8801,0,9102,8802,81,9102,8805,0.999
|
||||
GDA94 / MGA zone 46,6736,4283,6729,9001,9807,8801,0,9102,8802,93,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,
|
||||
GDA94 / MGA zone 47,6737,4283,6730,9001,9807,8801,0,9102,8802,99,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,
|
||||
GDA94 / MGA zone 59,6738,4283,6731,9001,9807,8801,0,9102,8802,171,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,
|
||||
ETRS89 / Albania TM 2010,6870,4258,6869,9001,9807,8801,0,9102,8802,20,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,
|
||||
NAD83 / Kansas LCC,6922,4269,6920,9001,9802,8821,36,9110,8822,-98.15,9110,8823,39.3,9110,8824,37.3,9110,8826,400000,9001,8827,0,9001
|
||||
NAD83 / Kansas LCC (ftUS),6923,4269,6921,9003,9802,8821,36,9110,8822,-98.15,9110,8823,39.3,9110,8824,37.3,9110,8826,1312333.3333,9003,8827,0,9003
|
||||
WGS 84 / NSIDC EASE-Grid 2.0 North,6931,4326,6929,9001,9820,8801,90,9102,8802,0,9102,8806,0,9001,8807,0,9001,,,,,,
|
||||
WGS 84 / NSIDC EASE-Grid 2.0 South,6932,4326,6930,9001,9820,8801,-90,9102,8802,0,9102,8806,0,9001,8807,0,9001,,,,,,
|
||||
ETRS89 / Albania LCC 2010,6962,4258,6961,9001,9802,8821,41,9102,8822,20,9102,8823,39,9102,8824,43,9102,8826,0,9001,8827,0,9001
|
||||
Palestine 1923 / Palestine Grid modified,7142,4281,7141,9001,9807,8801,31.4402749,9110,8802,35.124349,9110,8805,1,9201,8806,170251.555,9001,8807,126867.909,9001,,,
|
||||
WGS 84 / India NSF LCC,7755,4326,7722,9001,9802,8821,24,9102,8822,80,9102,8823,12.2822638,9110,8824,35.1022096,9110,8826,4000000,9001,8827,4000000,9001
|
||||
WGS 84 / Andhra Pradesh,7756,4326,7723,9001,9802,8821,16.25543298,9102,8822,80.875,9102,8823,13.75,9102,8824,18.75,9102,8826,1000000,9001,8827,1000000,9001
|
||||
@ -826,6 +976,18 @@ Luzon 1911 / Philippines zone II,25392,4253,18172,9001,9807,8801,0,9102,8802,119
|
||||
Luzon 1911 / Philippines zone III,25393,4253,18173,9001,9807,8801,0,9102,8802,121,9102,8805,0.99995,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Luzon 1911 / Philippines zone IV,25394,4253,18174,9001,9807,8801,0,9102,8802,123,9102,8805,0.99995,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Luzon 1911 / Philippines zone V,25395,4253,18175,9001,9807,8801,0,9102,8802,125,9102,8805,0.99995,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 28N,25828,4258,16028,9001,9807,8801,0,9102,8802,-15,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 29N,25829,4258,16029,9001,9807,8801,0,9102,8802,-9,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 30N,25830,4258,16030,9001,9807,8801,0,9102,8802,-3,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 31N,25831,4258,16031,9001,9807,8801,0,9102,8802,3,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 32N,25832,4258,16032,9001,9807,8801,0,9102,8802,9,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 33N,25833,4258,16033,9001,9807,8801,0,9102,8802,15,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 34N,25834,4258,16034,9001,9807,8801,0,9102,8802,21,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 35N,25835,4258,16035,9001,9807,8801,0,9102,8802,27,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 36N,25836,4258,16036,9001,9807,8801,0,9102,8802,33,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 37N,25837,4258,16037,9001,9807,8801,0,9102,8802,39,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / UTM zone 38N,25838,4258,16038,9001,9807,8801,0,9102,8802,45,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
ETRS89 / TM Baltic93,25884,4258,19939,9001,9807,8801,0,9102,8802,24,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,
|
||||
Merchich / Nord Maroc,26191,4261,18131,9001,9801,8801,37,9105,8802,-6,9105,8805,0.999625769,9201,8806,500000,9001,8807,300000,9001,,,
|
||||
Merchich / Sud Maroc,26192,4261,18132,9001,9801,8801,33,9105,8802,-6,9105,8805,0.999615596,9201,8806,500000,9001,8807,300000,9001,,,
|
||||
Merchich / Sahara,26193,4261,18133,9001,9801,8801,29,9105,8802,-6,9105,8805,0.9996,9201,8806,1200000,9001,8807,400000,9001,,,
|
||||
|
|
@ -5,7 +5,7 @@
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "5.0"
|
||||
!define VERSION "5.3"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}.exe"
|
||||
|
@ -5,7 +5,7 @@
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "5.0"
|
||||
!define VERSION "5.3"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||
|
@ -4,4 +4,5 @@
|
||||
<url>http://4umaps.eu/$z/$x/$y.png</url>
|
||||
<zoom min="2" max="15"/>
|
||||
<bounds bottom="-65"/>
|
||||
<copyright>Map data: © OpenStreetMap contributors (ODbL) | Rendering: © 4UMaps.eu</copyright>
|
||||
</map>
|
||||
|
@ -2,4 +2,5 @@
|
||||
<map>
|
||||
<name>Open Street Map</name>
|
||||
<url>http://tile.openstreetmap.org/$z/$x/$y.png</url>
|
||||
<copyright>Map data: © OpenStreetMap contributors (ODbL) | Rendering: © OpenStreetMap (CC-BY-SA)</copyright>
|
||||
</map>
|
||||
|
@ -3,4 +3,5 @@
|
||||
<name>Open Topo Map</name>
|
||||
<url>https://a.tile.opentopomap.org/$z/$x/$y.png</url>
|
||||
<zoom max="17"/>
|
||||
<copyright>Map data: © OpenStreetMap contributors (ODbL), SRTM | Rendering: © OpenTopoMap (CC-BY-SA)</copyright>
|
||||
</map>
|
||||
|
@ -4,4 +4,5 @@
|
||||
<url>https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y</url>
|
||||
<zoom min="2" max="15"/>
|
||||
<bounds bottom="0" top="74"/>
|
||||
<copyright>Map services and data available from U.S. Geological Survey, National Geospatial Program.</copyright>
|
||||
</map>
|
||||
|
@ -3,4 +3,5 @@
|
||||
<name>USGS Topo</name>
|
||||
<url>https://navigator.er.usgs.gov/tiles/tcr.cgi/$z/$x/$y.png</url>
|
||||
<zoom min="2" max="15"/>
|
||||
<copyright>Map services and data available from U.S. Geological Survey, National Geospatial Program.</copyright>
|
||||
</map>
|
||||
|
@ -4,7 +4,8 @@
|
||||
#include <QFileOpenEvent>
|
||||
#include <QNetworkProxyFactory>
|
||||
#include <QLibraryInfo>
|
||||
#include "map/onlinemap.h"
|
||||
#include "map/wmts.h"
|
||||
#include "map/tileloader.h"
|
||||
#include "map/downloader.h"
|
||||
#include "map/ellipsoid.h"
|
||||
#include "map/gcs.h"
|
||||
@ -36,7 +37,9 @@ App::App(int &argc, char **argv) : QApplication(argc, argv),
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
OnlineMap::setDownloader(new Downloader(this));
|
||||
Downloader *dl = new Downloader(this);
|
||||
TileLoader::setDownloader(dl);
|
||||
WMTS::setDownloader(dl);
|
||||
OPENGL_SET_SAMPLES(4);
|
||||
loadDatums();
|
||||
loadPCSs();
|
||||
|
@ -62,12 +62,17 @@ ExportDialog::ExportDialog(Export *exp, QWidget *parent)
|
||||
_bottomMargin = new QDoubleSpinBox();
|
||||
_leftMargin = new QDoubleSpinBox();
|
||||
_rightMargin = new QDoubleSpinBox();
|
||||
QString us = (_export->units == Imperial) ? tr("in") : tr("mm");
|
||||
QString us = (_export->units == Metric) ? tr("mm") : tr("in");
|
||||
_topMargin->setSuffix(UNIT_SPACE + us);
|
||||
_bottomMargin->setSuffix(UNIT_SPACE + us);
|
||||
_leftMargin->setSuffix(UNIT_SPACE + us);
|
||||
_rightMargin->setSuffix(UNIT_SPACE + us);
|
||||
if (_export->units == Imperial) {
|
||||
if (_export->units == Metric) {
|
||||
_topMargin->setValue(_export->margins.top());
|
||||
_bottomMargin->setValue(_export->margins.bottom());
|
||||
_leftMargin->setValue(_export->margins.left());
|
||||
_rightMargin->setValue(_export->margins.right());
|
||||
} else {
|
||||
_topMargin->setValue(_export->margins.top() * MM2IN);
|
||||
_bottomMargin->setValue(_export->margins.bottom() * MM2IN);
|
||||
_leftMargin->setValue(_export->margins.left() * MM2IN);
|
||||
@ -76,11 +81,6 @@ ExportDialog::ExportDialog(Export *exp, QWidget *parent)
|
||||
_bottomMargin->setSingleStep(0.1);
|
||||
_leftMargin->setSingleStep(0.1);
|
||||
_rightMargin->setSingleStep(0.1);
|
||||
} else {
|
||||
_topMargin->setValue(_export->margins.top());
|
||||
_bottomMargin->setValue(_export->margins.bottom());
|
||||
_leftMargin->setValue(_export->margins.left());
|
||||
_rightMargin->setValue(_export->margins.right());
|
||||
}
|
||||
|
||||
QGridLayout *marginsLayout = new QGridLayout();
|
||||
|
@ -2,6 +2,32 @@
|
||||
#include "common/coordinates.h"
|
||||
#include "format.h"
|
||||
|
||||
|
||||
static QString deg2DMS(double val)
|
||||
{
|
||||
int deg = val;
|
||||
double r1 = val - deg;
|
||||
|
||||
int min = r1 * 60.0;
|
||||
double r2 = r1 - (min / 60.0);
|
||||
|
||||
double sec = r2 * 3600.0;
|
||||
|
||||
return QString("%1°%2'%3\"").arg(deg).arg(min, 2, 10, QChar('0'))
|
||||
.arg(sec, 4, 'f', 1, QChar('0'));
|
||||
}
|
||||
|
||||
static QString deg2DMM(double val)
|
||||
{
|
||||
int deg = val;
|
||||
double r1 = val - deg;
|
||||
|
||||
double min = r1 * 60.0;
|
||||
|
||||
return QString("%1°%2'").arg(deg).arg(min, 6, 'f', 3, QChar('0'));
|
||||
}
|
||||
|
||||
|
||||
QString Format::timeSpan(qreal time, bool full)
|
||||
{
|
||||
unsigned h, m, s;
|
||||
@ -27,6 +53,13 @@ QString Format::distance(qreal value, Units units)
|
||||
else
|
||||
return QString::number(value * M2MI, 'f', 1) + UNIT_SPACE
|
||||
+ qApp->translate("Format", "mi");
|
||||
} else if (units == Nautical) {
|
||||
if (value < NMIINM)
|
||||
return QString::number(value * M2FT, 'f', 0) + UNIT_SPACE
|
||||
+ qApp->translate("Format", "ft");
|
||||
else
|
||||
return QString::number(value * M2NMI, 'f', 1) + UNIT_SPACE
|
||||
+ qApp->translate("Format", "nmi");
|
||||
} else {
|
||||
if (value < KMINM)
|
||||
return QString::number(value, 'f', 0) + UNIT_SPACE
|
||||
@ -47,11 +80,22 @@ QString Format::elevation(qreal value, Units units)
|
||||
+ qApp->translate("Format", "ft");
|
||||
}
|
||||
|
||||
QString Format::coordinates(const Coordinates &value)
|
||||
QString Format::coordinates(const Coordinates &value, CoordinatesFormat type)
|
||||
{
|
||||
QChar yH = (value.lat() < 0) ? 'S' : 'N';
|
||||
QChar xH = (value.lon() < 0) ? 'W' : 'E';
|
||||
|
||||
return QString::number(qAbs(value.lat()), 'f', 5) + yH + "," + QChar(0x00A0)
|
||||
+ QString::number(qAbs(value.lon()), 'f', 5) + xH;
|
||||
switch (type) {
|
||||
case DegreesMinutes:
|
||||
return deg2DMM(qAbs(value.lat())) + yH + "," + QChar(0x00A0)
|
||||
+ deg2DMM(qAbs(value.lon())) + xH;
|
||||
break;
|
||||
case DMS:
|
||||
return deg2DMS(qAbs(value.lat())) + yH + "," + QChar(0x00A0)
|
||||
+ deg2DMS(qAbs(value.lon())) + xH;
|
||||
break;
|
||||
default:
|
||||
return QString::number(qAbs(value.lat()), 'f', 5) + yH + ","
|
||||
+ QChar(0x00A0) + QString::number(qAbs(value.lon()), 'f', 5) + xH;
|
||||
}
|
||||
}
|
||||
|
@ -6,12 +6,18 @@
|
||||
|
||||
class Coordinates;
|
||||
|
||||
enum CoordinatesFormat {
|
||||
DecimalDegrees,
|
||||
DegreesMinutes,
|
||||
DMS
|
||||
};
|
||||
|
||||
namespace Format
|
||||
{
|
||||
QString timeSpan(qreal time, bool full = true);
|
||||
QString distance(qreal value, Units units);
|
||||
QString elevation(qreal value, Units units);
|
||||
QString coordinates(const Coordinates &value);
|
||||
QString coordinates(const Coordinates &value, CoordinatesFormat type);
|
||||
}
|
||||
|
||||
#endif // FORMAT_H
|
||||
|
@ -104,15 +104,7 @@ void GraphView::setYUnits(const QString &units)
|
||||
void GraphView::setXUnits()
|
||||
{
|
||||
if (_graphType == Distance) {
|
||||
if (_units == Metric) {
|
||||
if (bounds().width() < KMINM) {
|
||||
_xUnits = tr("m");
|
||||
_xScale = 1;
|
||||
} else {
|
||||
_xUnits = tr("km");
|
||||
_xScale = M2KM;
|
||||
}
|
||||
} else {
|
||||
if (_units == Imperial) {
|
||||
if (bounds().width() < MIINM) {
|
||||
_xUnits = tr("ft");
|
||||
_xScale = M2FT;
|
||||
@ -120,6 +112,22 @@ void GraphView::setXUnits()
|
||||
_xUnits = tr("mi");
|
||||
_xScale = M2MI;
|
||||
}
|
||||
} else if (_units == Nautical) {
|
||||
if (bounds().width() < NMIINM) {
|
||||
_xUnits = tr("ft");
|
||||
_xScale = M2FT;
|
||||
} else {
|
||||
_xUnits = tr("nmi");
|
||||
_xScale = M2NMI;
|
||||
}
|
||||
} else {
|
||||
if (bounds().width() < KMINM) {
|
||||
_xUnits = tr("m");
|
||||
_xScale = 1;
|
||||
} else {
|
||||
_xUnits = tr("km");
|
||||
_xScale = M2KM;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bounds().width() < MININS) {
|
||||
|
112
src/GUI/gui.cpp
112
src/GUI/gui.cpp
@ -40,7 +40,6 @@
|
||||
#include "filebrowser.h"
|
||||
#include "cpuarch.h"
|
||||
#include "graphtab.h"
|
||||
#include "format.h"
|
||||
#include "gui.h"
|
||||
|
||||
|
||||
@ -373,6 +372,28 @@ void GUI::createActions()
|
||||
_imperialUnitsAction->setActionGroup(ag);
|
||||
connect(_imperialUnitsAction, SIGNAL(triggered()), this,
|
||||
SLOT(setImperialUnits()));
|
||||
_nauticalUnitsAction = new QAction(tr("Nautical"), this);
|
||||
_nauticalUnitsAction->setCheckable(true);
|
||||
_nauticalUnitsAction->setActionGroup(ag);
|
||||
connect(_nauticalUnitsAction, SIGNAL(triggered()), this,
|
||||
SLOT(setNauticalUnits()));
|
||||
ag = new QActionGroup(this);
|
||||
ag->setExclusive(true);
|
||||
_decimalDegreesAction = new QAction(tr("Decimal degrees (DD)"), this);
|
||||
_decimalDegreesAction->setCheckable(true);
|
||||
_decimalDegreesAction->setActionGroup(ag);
|
||||
connect(_decimalDegreesAction, SIGNAL(triggered()), this,
|
||||
SLOT(setDecimalDegrees()));
|
||||
_degreesMinutesAction = new QAction(tr("Degrees and decimal minutes (DMM)"),
|
||||
this);
|
||||
_degreesMinutesAction->setCheckable(true);
|
||||
_degreesMinutesAction->setActionGroup(ag);
|
||||
connect(_degreesMinutesAction, SIGNAL(triggered()), this,
|
||||
SLOT(setDegreesMinutes()));
|
||||
_DMSAction = new QAction(tr("Degrees, minutes, seconds (DMS)"), this);
|
||||
_DMSAction->setCheckable(true);
|
||||
_DMSAction->setActionGroup(ag);
|
||||
connect(_DMSAction, SIGNAL(triggered()), this, SLOT(setDMS()));
|
||||
_fullscreenAction = new QAction(QIcon(QPixmap(FULLSCREEN_ICON)),
|
||||
tr("Fullscreen mode"), this);
|
||||
_fullscreenAction->setCheckable(true);
|
||||
@ -404,7 +425,7 @@ void GUI::createActions()
|
||||
|
||||
void GUI::createMenus()
|
||||
{
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
fileMenu->addAction(_openFileAction);
|
||||
fileMenu->addSeparator();
|
||||
fileMenu->addAction(_printFileAction);
|
||||
@ -418,7 +439,7 @@ void GUI::createMenus()
|
||||
fileMenu->addAction(_exitAction);
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
_mapMenu = menuBar()->addMenu(tr("Map"));
|
||||
_mapMenu = menuBar()->addMenu(tr("&Map"));
|
||||
_mapMenu->addActions(_mapActions);
|
||||
_mapsEnd = _mapMenu->addSeparator();
|
||||
_mapMenu->addAction(_loadMapAction);
|
||||
@ -426,7 +447,7 @@ void GUI::createMenus()
|
||||
_mapMenu->addSeparator();
|
||||
_mapMenu->addAction(_showMapAction);
|
||||
|
||||
QMenu *graphMenu = menuBar()->addMenu(tr("Graph"));
|
||||
QMenu *graphMenu = menuBar()->addMenu(tr("&Graph"));
|
||||
graphMenu->addAction(_distanceGraphAction);
|
||||
graphMenu->addAction(_timeGraphAction);
|
||||
graphMenu->addSeparator();
|
||||
@ -435,7 +456,7 @@ void GUI::createMenus()
|
||||
graphMenu->addSeparator();
|
||||
graphMenu->addAction(_showGraphsAction);
|
||||
|
||||
QMenu *poiMenu = menuBar()->addMenu(tr("POI"));
|
||||
QMenu *poiMenu = menuBar()->addMenu(tr("&POI"));
|
||||
_poiFilesMenu = poiMenu->addMenu(tr("POI files"));
|
||||
_poiFilesMenu->addActions(_poiFilesActions);
|
||||
poiMenu->addSeparator();
|
||||
@ -447,7 +468,7 @@ void GUI::createMenus()
|
||||
poiMenu->addSeparator();
|
||||
poiMenu->addAction(_showPOIAction);
|
||||
|
||||
QMenu *dataMenu = menuBar()->addMenu(tr("Data"));
|
||||
QMenu *dataMenu = menuBar()->addMenu(tr("&Data"));
|
||||
QMenu *displayMenu = dataMenu->addMenu(tr("Display"));
|
||||
displayMenu->addAction(_showWaypointLabelsAction);
|
||||
displayMenu->addAction(_showRouteWaypointsAction);
|
||||
@ -456,20 +477,25 @@ void GUI::createMenus()
|
||||
dataMenu->addAction(_showRoutesAction);
|
||||
dataMenu->addAction(_showWaypointsAction);
|
||||
|
||||
QMenu *settingsMenu = menuBar()->addMenu(tr("Settings"));
|
||||
QMenu *settingsMenu = menuBar()->addMenu(tr("&Settings"));
|
||||
QMenu *timeMenu = settingsMenu->addMenu(tr("Time"));
|
||||
timeMenu->addAction(_totalTimeAction);
|
||||
timeMenu->addAction(_movingTimeAction);
|
||||
QMenu *unitsMenu = settingsMenu->addMenu(tr("Units"));
|
||||
unitsMenu->addAction(_metricUnitsAction);
|
||||
unitsMenu->addAction(_imperialUnitsAction);
|
||||
unitsMenu->addAction(_nauticalUnitsAction);
|
||||
QMenu *coordinatesMenu = settingsMenu->addMenu(tr("Coordinates format"));
|
||||
coordinatesMenu->addAction(_decimalDegreesAction);
|
||||
coordinatesMenu->addAction(_degreesMinutesAction);
|
||||
coordinatesMenu->addAction(_DMSAction);
|
||||
settingsMenu->addSeparator();
|
||||
settingsMenu->addAction(_showToolbarsAction);
|
||||
settingsMenu->addAction(_fullscreenAction);
|
||||
settingsMenu->addSeparator();
|
||||
settingsMenu->addAction(_openOptionsAction);
|
||||
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("Help"));
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||
helpMenu->addAction(_pathsAction);
|
||||
helpMenu->addAction(_keysAction);
|
||||
helpMenu->addSeparator();
|
||||
@ -1121,7 +1147,7 @@ bool GUI::loadMap(const QString &fileName)
|
||||
_mapMenu->insertAction(_mapsEnd, a);
|
||||
_showMapAction->setEnabled(true);
|
||||
_clearMapCacheAction->setEnabled(true);
|
||||
_mapActions.last()->activate(QAction::Trigger);
|
||||
_mapActions.last()->trigger();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
@ -1293,6 +1319,11 @@ void GUI::setUnits(Units units)
|
||||
updateStatusBarInfo();
|
||||
}
|
||||
|
||||
void GUI::setCoordinatesFormat(CoordinatesFormat format)
|
||||
{
|
||||
_mapView->setCoordinatesFormat(format);
|
||||
}
|
||||
|
||||
void GUI::setGraphType(GraphType type)
|
||||
{
|
||||
_sliderPos = 0;
|
||||
@ -1363,15 +1394,15 @@ void GUI::keyPressEvent(QKeyEvent *event)
|
||||
|
||||
case TOGGLE_GRAPH_TYPE_KEY:
|
||||
if (_timeGraphAction->isChecked())
|
||||
_distanceGraphAction->activate(QAction::Trigger);
|
||||
_distanceGraphAction->trigger();
|
||||
else
|
||||
_timeGraphAction->activate(QAction::Trigger);
|
||||
_timeGraphAction->trigger();
|
||||
break;
|
||||
case TOGGLE_TIME_TYPE_KEY:
|
||||
if (_movingTimeAction->isChecked())
|
||||
_totalTimeAction->activate(QAction::Trigger);
|
||||
_totalTimeAction->trigger();
|
||||
else
|
||||
_movingTimeAction->activate(QAction::Trigger);
|
||||
_movingTimeAction->trigger();
|
||||
break;
|
||||
|
||||
case Qt::Key_Escape:
|
||||
@ -1437,11 +1468,15 @@ void GUI::writeSettings()
|
||||
if ((_movingTimeAction->isChecked() ? Moving : Total) !=
|
||||
TIME_TYPE_DEFAULT)
|
||||
settings.setValue(TIME_TYPE_SETTING, _movingTimeAction->isChecked()
|
||||
? Moving : Total);
|
||||
if ((_imperialUnitsAction->isChecked() ? Imperial : Metric) !=
|
||||
UNITS_DEFAULT)
|
||||
settings.setValue(UNITS_SETTING, _imperialUnitsAction->isChecked()
|
||||
? Imperial : Metric);
|
||||
? Moving : Total);
|
||||
Units units = _imperialUnitsAction->isChecked() ? Imperial
|
||||
: _nauticalUnitsAction->isChecked() ? Nautical : Metric;
|
||||
if (units != UNITS_DEFAULT)
|
||||
settings.setValue(UNITS_SETTING, units);
|
||||
CoordinatesFormat format = _DMSAction->isChecked() ? DMS
|
||||
: _degreesMinutesAction->isChecked() ? DegreesMinutes : DecimalDegrees;
|
||||
if (format != COORDINATES_DEFAULT)
|
||||
settings.setValue(COORDINATES_SETTING, format);
|
||||
if (_showToolbarsAction->isChecked() != SHOW_TOOLBARS_DEFAULT)
|
||||
settings.setValue(SHOW_TOOLBARS_SETTING,
|
||||
_showToolbarsAction->isChecked());
|
||||
@ -1601,6 +1636,7 @@ void GUI::writeSettings()
|
||||
|
||||
void GUI::readSettings()
|
||||
{
|
||||
int value;
|
||||
QSettings settings(APP_NAME, APP_NAME);
|
||||
|
||||
settings.beginGroup(WINDOW_SETTINGS_GROUP);
|
||||
@ -1610,20 +1646,27 @@ void GUI::readSettings()
|
||||
|
||||
settings.beginGroup(SETTINGS_SETTINGS_GROUP);
|
||||
if (settings.value(TIME_TYPE_SETTING, TIME_TYPE_DEFAULT).toInt()
|
||||
== Moving) {
|
||||
setTimeType(Moving);
|
||||
_movingTimeAction->setChecked(true);
|
||||
} else {
|
||||
setTimeType(Total);
|
||||
_totalTimeAction->setChecked(true);
|
||||
}
|
||||
if (settings.value(UNITS_SETTING, UNITS_DEFAULT).toInt() == Imperial) {
|
||||
setUnits(Imperial);
|
||||
_imperialUnitsAction->setChecked(true);
|
||||
} else {
|
||||
setUnits(Metric);
|
||||
_metricUnitsAction->setChecked(true);
|
||||
}
|
||||
== Moving)
|
||||
_movingTimeAction->trigger();
|
||||
else
|
||||
_totalTimeAction->trigger();
|
||||
|
||||
value = settings.value(UNITS_SETTING, UNITS_DEFAULT).toInt();
|
||||
if (value == Imperial)
|
||||
_imperialUnitsAction->trigger();
|
||||
else if (value == Nautical)
|
||||
_nauticalUnitsAction->trigger();
|
||||
else
|
||||
_metricUnitsAction->trigger();
|
||||
|
||||
value = settings.value(COORDINATES_SETTING, COORDINATES_DEFAULT).toInt();
|
||||
if (value == DMS)
|
||||
_DMSAction->trigger();
|
||||
else if (value == DegreesMinutes)
|
||||
_degreesMinutesAction->trigger();
|
||||
else
|
||||
_decimalDegreesAction->trigger();
|
||||
|
||||
if (!settings.value(SHOW_TOOLBARS_SETTING, SHOW_TOOLBARS_DEFAULT).toBool())
|
||||
showToolbars(false);
|
||||
else
|
||||
@ -1633,6 +1676,8 @@ void GUI::readSettings()
|
||||
settings.beginGroup(MAP_SETTINGS_GROUP);
|
||||
if (settings.value(SHOW_MAP_SETTING, SHOW_MAP_DEFAULT).toBool())
|
||||
_showMapAction->setChecked(true);
|
||||
else
|
||||
_mapView->showMap(false);
|
||||
if (_ml->maps().count()) {
|
||||
int index = mapIndex(settings.value(CURRENT_MAP_SETTING).toString());
|
||||
_mapActions.at(index)->trigger();
|
||||
@ -1867,7 +1912,8 @@ int GUI::mapIndex(const QString &name)
|
||||
|
||||
Units GUI::units() const
|
||||
{
|
||||
return _imperialUnitsAction->isChecked() ? Imperial : Metric;
|
||||
return _imperialUnitsAction->isChecked() ? Imperial
|
||||
: _nauticalUnitsAction->isChecked() ? Nautical : Metric;
|
||||
}
|
||||
|
||||
qreal GUI::distance() const
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "data/poi.h"
|
||||
#include "units.h"
|
||||
#include "timetype.h"
|
||||
#include "format.h"
|
||||
#include "exportdialog.h"
|
||||
#include "optionsdialog.h"
|
||||
|
||||
@ -73,8 +74,12 @@ private slots:
|
||||
void setMovingTime() {setTimeType(Moving);}
|
||||
void setMetricUnits() {setUnits(Metric);}
|
||||
void setImperialUnits() {setUnits(Imperial);}
|
||||
void setNauticalUnits() {setUnits(Nautical);}
|
||||
void setDistanceGraph() {setGraphType(Distance);}
|
||||
void setTimeGraph() {setGraphType(Time);}
|
||||
void setDecimalDegrees() {setCoordinatesFormat(DecimalDegrees);}
|
||||
void setDegreesMinutes() {setCoordinatesFormat(DegreesMinutes);}
|
||||
void setDMS() {setCoordinatesFormat(DMS);}
|
||||
|
||||
void sliderPositionChanged(qreal pos);
|
||||
|
||||
@ -111,6 +116,7 @@ private:
|
||||
Units units() const;
|
||||
void setTimeType(TimeType type);
|
||||
void setUnits(Units units);
|
||||
void setCoordinatesFormat(CoordinatesFormat format);
|
||||
void setGraphType(GraphType type);
|
||||
|
||||
qreal distance() const;
|
||||
@ -165,6 +171,10 @@ private:
|
||||
QAction *_firstAction;
|
||||
QAction *_metricUnitsAction;
|
||||
QAction *_imperialUnitsAction;
|
||||
QAction *_nauticalUnitsAction;
|
||||
QAction *_decimalDegreesAction;
|
||||
QAction *_degreesMinutesAction;
|
||||
QAction *_DMSAction;
|
||||
QAction *_totalTimeAction;
|
||||
QAction *_movingTimeAction;
|
||||
QAction *_nextMapAction;
|
||||
|
@ -49,6 +49,7 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
|
||||
connect(_poi, SIGNAL(pointsChanged()), this, SLOT(updatePOI()));
|
||||
|
||||
_units = Metric;
|
||||
_coordinatesFormat = DecimalDegrees;
|
||||
_opacity = 1.0;
|
||||
_backgroundColor = Qt::white;
|
||||
_markerColor = Qt::red;
|
||||
@ -75,6 +76,7 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
|
||||
_digitalZoom = 0;
|
||||
|
||||
_map->setBackgroundColor(_backgroundColor);
|
||||
_res = _map->resolution(_map->bounds());
|
||||
_scene->setSceneRect(_map->bounds());
|
||||
|
||||
centerOn(_scene->sceneRect().center());
|
||||
@ -94,7 +96,8 @@ void MapView::centerOn(const QPointF &pos)
|
||||
verticalScrollBar()->setValue(verticalScrollBar()->value()
|
||||
+ offset.y());
|
||||
|
||||
_res = _map->resolution(pos);
|
||||
QRectF vr(mapToScene(viewport()->rect()).boundingRect());
|
||||
_res = _map->resolution(vr);
|
||||
_mapScale->setResolution(_res);
|
||||
}
|
||||
|
||||
@ -137,6 +140,7 @@ PathItem *MapView::addRoute(const Route &route)
|
||||
ri->setWidth(_routeWidth);
|
||||
ri->setStyle(_routeStyle);
|
||||
ri->setUnits(_units);
|
||||
ri->setCoordinatesFormat(_coordinatesFormat);
|
||||
ri->setVisible(_showRoutes);
|
||||
ri->showWaypoints(_showRouteWaypoints);
|
||||
ri->showWaypointLabels(_showWaypointLabels);
|
||||
@ -162,7 +166,7 @@ void MapView::addWaypoints(const QList<Waypoint> &waypoints)
|
||||
wi->setSize(_waypointSize);
|
||||
wi->setColor(_waypointColor);
|
||||
wi->showLabel(_showWaypointLabels);
|
||||
wi->setUnits(_units);
|
||||
wi->setToolTipFormat(_units, _coordinatesFormat);
|
||||
wi->setVisible(_showWaypoints);
|
||||
wi->setDigitalZoom(_digitalZoom);
|
||||
_scene->addItem(wi);
|
||||
@ -265,9 +269,8 @@ void MapView::setPalette(const Palette &palette)
|
||||
|
||||
void MapView::setMap(Map *map)
|
||||
{
|
||||
QPointF pos = mapToScene(viewport()->rect().center());
|
||||
Coordinates center = _map->xy2ll(pos);
|
||||
qreal resolution = _map->resolution(pos);
|
||||
QRectF vr(mapToScene(viewport()->rect()).boundingRect());
|
||||
RectC cr(_map->xy2ll(vr.topLeft()), _map->xy2ll(vr.bottomRight()));
|
||||
|
||||
_map->unload();
|
||||
disconnect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
|
||||
@ -279,7 +282,7 @@ void MapView::setMap(Map *map)
|
||||
|
||||
digitalZoom(0);
|
||||
|
||||
_map->zoomFit(resolution, center);
|
||||
_map->zoomFit(viewport()->rect().size(), cr);
|
||||
_scene->setSceneRect(_map->bounds());
|
||||
|
||||
for (int i = 0; i < _tracks.size(); i++)
|
||||
@ -294,7 +297,7 @@ void MapView::setMap(Map *map)
|
||||
it.value()->setMap(_map);
|
||||
updatePOIVisibility();
|
||||
|
||||
centerOn(_map->ll2xy(center));
|
||||
centerOn(_map->ll2xy(cr.center()));
|
||||
|
||||
resetCachedContent();
|
||||
QPixmapCache::clear();
|
||||
@ -348,28 +351,49 @@ void MapView::addPOI(const QList<Waypoint> &waypoints)
|
||||
pi->showLabel(_showPOILabels);
|
||||
pi->setVisible(_showPOI);
|
||||
pi->setDigitalZoom(_digitalZoom);
|
||||
pi->setToolTipFormat(_units, _coordinatesFormat);
|
||||
_scene->addItem(pi);
|
||||
|
||||
_pois.insert(SearchPointer<Waypoint>(&(pi->waypoint())), pi);
|
||||
}
|
||||
}
|
||||
|
||||
void MapView::setUnits(enum Units units)
|
||||
void MapView::setUnits(Units units)
|
||||
{
|
||||
if (_units == units)
|
||||
return;
|
||||
|
||||
_units = units;
|
||||
|
||||
_mapScale->setUnits(units);
|
||||
_mapScale->setUnits(_units);
|
||||
|
||||
for (int i = 0; i < _tracks.count(); i++)
|
||||
_tracks[i]->setUnits(units);
|
||||
_tracks[i]->setUnits(_units);
|
||||
for (int i = 0; i < _routes.count(); i++)
|
||||
_routes[i]->setUnits(units);
|
||||
_routes[i]->setUnits(_units);
|
||||
for (int i = 0; i < _waypoints.size(); i++)
|
||||
_waypoints.at(i)->setUnits(units);
|
||||
_waypoints.at(i)->setToolTipFormat(_units, _coordinatesFormat);
|
||||
|
||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
||||
it.value()->setUnits(units);
|
||||
it.value()->setToolTipFormat(_units, _coordinatesFormat);
|
||||
}
|
||||
|
||||
void MapView::setCoordinatesFormat(CoordinatesFormat format)
|
||||
{
|
||||
if (_coordinatesFormat == format)
|
||||
return;
|
||||
|
||||
_coordinatesFormat = format;
|
||||
|
||||
for (int i = 0; i < _waypoints.count(); i++)
|
||||
_waypoints.at(i)->setToolTipFormat(_units, _coordinatesFormat);
|
||||
for (int i = 0; i < _routes.count(); i++)
|
||||
_routes[i]->setCoordinatesFormat(_coordinatesFormat);
|
||||
|
||||
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
|
||||
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
|
||||
it.value()->setToolTipFormat(_units, _coordinatesFormat);
|
||||
}
|
||||
|
||||
void MapView::clearMapCache()
|
||||
@ -476,9 +500,9 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
|
||||
bool hires)
|
||||
{
|
||||
QRect orig, adj;
|
||||
qreal ratio, diff, origRes, q;
|
||||
qreal ratio, diff, q;
|
||||
QPointF origScene, origPos;
|
||||
Coordinates origLL;
|
||||
RectC origC;
|
||||
|
||||
|
||||
// Enter plot mode
|
||||
@ -503,9 +527,9 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
|
||||
|
||||
// Adjust the view for printing
|
||||
if (hires) {
|
||||
origScene = mapToScene(orig.center());
|
||||
origLL = _map->xy2ll(origScene);
|
||||
origRes = _map->resolution(origScene);
|
||||
QRectF vr(mapToScene(orig).boundingRect());
|
||||
origC = RectC(_map->xy2ll(vr.topLeft()), _map->xy2ll(vr.bottomRight()));
|
||||
origScene = vr.center();
|
||||
|
||||
QPointF s(painter->device()->logicalDpiX()
|
||||
/ (qreal)metric(QPaintDevice::PdmDpiX),
|
||||
@ -535,7 +559,7 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
|
||||
|
||||
// Revert view changes to display mode
|
||||
if (hires) {
|
||||
_map->zoomFit(origRes, origLL);
|
||||
_map->zoomFit(orig.size(), origC);
|
||||
rescale();
|
||||
centerOn(origScene);
|
||||
}
|
||||
@ -738,17 +762,14 @@ void MapView::setBackgroundColor(const QColor &color)
|
||||
|
||||
void MapView::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
painter->fillRect(rect, _backgroundColor);
|
||||
|
||||
if (_showMap) {
|
||||
QRectF ir = rect.intersected(_map->bounds());
|
||||
|
||||
if (_opacity < 1.0 || ir != rect)
|
||||
painter->fillRect(rect, _backgroundColor);
|
||||
if (_opacity < 1.0)
|
||||
painter->setOpacity(_opacity);
|
||||
|
||||
_map->draw(painter, ir);
|
||||
} else
|
||||
painter->fillRect(rect, _backgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
void MapView::resizeEvent(QResizeEvent *event)
|
||||
@ -777,8 +798,8 @@ void MapView::scrollContentsBy(int dx, int dy)
|
||||
{
|
||||
QGraphicsView::scrollContentsBy(dx, dy);
|
||||
|
||||
QPointF center = mapToScene(viewport()->rect().center());
|
||||
qreal res = _map->resolution(center);
|
||||
QRectF sr(mapToScene(viewport()->rect()).boundingRect());
|
||||
qreal res = _map->resolution(sr);
|
||||
|
||||
if (qMax(res, _res) / qMin(res, _res) > 1.1) {
|
||||
_mapScale->setResolution(res);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "data/waypoint.h"
|
||||
#include "searchpointer.h"
|
||||
#include "units.h"
|
||||
#include "format.h"
|
||||
#include "palette.h"
|
||||
|
||||
class Data;
|
||||
@ -34,12 +35,13 @@ public:
|
||||
void setPalette(const Palette &palette);
|
||||
void setPOI(POI *poi);
|
||||
void setMap(Map *map);
|
||||
void setUnits(enum Units units);
|
||||
|
||||
void plot(QPainter *painter, const QRectF &target, qreal scale, bool hires);
|
||||
|
||||
void clear();
|
||||
|
||||
void setUnits(Units units);
|
||||
void setMarkerColor(const QColor &color);
|
||||
void setTrackWidth(int width);
|
||||
void setRouteWidth(int width);
|
||||
void setTrackStyle(Qt::PenStyle style);
|
||||
@ -52,7 +54,6 @@ public:
|
||||
void setBackgroundColor(const QColor &color);
|
||||
void useOpenGL(bool use);
|
||||
void useAntiAliasing(bool use);
|
||||
void setMarkerColor(const QColor &color);
|
||||
|
||||
public slots:
|
||||
void showMap(bool show);
|
||||
@ -65,6 +66,7 @@ public slots:
|
||||
void showWaypoints(bool show);
|
||||
void showRouteWaypoints(bool show);
|
||||
void clearMapCache();
|
||||
void setCoordinatesFormat(CoordinatesFormat format);
|
||||
|
||||
private slots:
|
||||
void updatePOI();
|
||||
@ -108,6 +110,7 @@ private:
|
||||
POI *_poi;
|
||||
Palette _palette;
|
||||
Units _units;
|
||||
CoordinatesFormat _coordinatesFormat;
|
||||
|
||||
qreal _opacity;
|
||||
QColor _backgroundColor;
|
||||
|
@ -25,11 +25,13 @@ private:
|
||||
qreal _left, _top, _right, _bottom;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
inline QDebug operator<<(QDebug dbg, const MarginsF &margins)
|
||||
{
|
||||
dbg.nospace() << "MarginsF(" << margins.left() << ", " << margins.top()
|
||||
<< ", " << margins.right() << margins.bottom() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // MARGINS_H
|
||||
|
@ -291,6 +291,9 @@ QWidget *OptionsDialog::createDataPage()
|
||||
if (_options->units == Imperial) {
|
||||
_pauseSpeed->setValue(_options->pauseSpeed * MS2MIH);
|
||||
_pauseSpeed->setSuffix(UNIT_SPACE + tr("mi/h"));
|
||||
} else if (_options->units == Nautical) {
|
||||
_pauseSpeed->setValue(_options->pauseSpeed * MS2KN);
|
||||
_pauseSpeed->setSuffix(UNIT_SPACE + tr("kn"));
|
||||
} else {
|
||||
_pauseSpeed->setValue(_options->pauseSpeed * MS2KMH);
|
||||
_pauseSpeed->setSuffix(UNIT_SPACE + tr("km/h"));
|
||||
@ -323,6 +326,9 @@ QWidget *OptionsDialog::createPOIPage()
|
||||
if (_options->units == Imperial) {
|
||||
_poiRadius->setValue(_options->poiRadius / MIINM);
|
||||
_poiRadius->setSuffix(UNIT_SPACE + tr("mi"));
|
||||
} else if (_options->units == Nautical) {
|
||||
_poiRadius->setValue(_options->poiRadius / NMIINM);
|
||||
_poiRadius->setSuffix(UNIT_SPACE + tr("nmi"));
|
||||
} else {
|
||||
_poiRadius->setValue(_options->poiRadius / KMINM);
|
||||
_poiRadius->setSuffix(UNIT_SPACE + tr("km"));
|
||||
@ -525,13 +531,15 @@ void OptionsDialog::accept()
|
||||
_options->powerFilter = _powerFilter->value();
|
||||
_options->outlierEliminate = _outlierEliminate->isChecked();
|
||||
qreal pauseSpeed = (_options->units == Imperial)
|
||||
? _pauseSpeed->value() / MS2MIH : _pauseSpeed->value() / MS2KMH;
|
||||
? _pauseSpeed->value() / MS2MIH : (_options->units == Nautical)
|
||||
? _pauseSpeed->value() / MS2KN : _pauseSpeed->value() / MS2KMH;
|
||||
if (qAbs(pauseSpeed - _options->pauseSpeed) > 0.01)
|
||||
_options->pauseSpeed = pauseSpeed;
|
||||
_options->pauseInterval = _pauseInterval->value();
|
||||
|
||||
qreal poiRadius = (_options->units == Imperial)
|
||||
? _poiRadius->value() * MIINM : _poiRadius->value() * KMINM;
|
||||
? _poiRadius->value() * MIINM : (_options->units == Nautical)
|
||||
? _poiRadius->value() * NMIINM : _poiRadius->value() * KMINM;
|
||||
if (qAbs(poiRadius - _options->poiRadius) > 0.01)
|
||||
_options->poiRadius = poiRadius;
|
||||
|
||||
|
@ -37,9 +37,11 @@ void Palette::reset()
|
||||
_state = _h;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Palette &palette)
|
||||
{
|
||||
dbg.nospace() << "Palette(" << palette.color() << ", " << palette.shift()
|
||||
<< ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -28,6 +28,8 @@ private:
|
||||
qreal _state;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Palette &palette);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // PALLETE_H
|
||||
|
@ -30,6 +30,8 @@ RouteItem::RouteItem(const Route &route, Map *map, QGraphicsItem *parent)
|
||||
|
||||
_name = route.name();
|
||||
_desc = route.description();
|
||||
_units = Metric;
|
||||
_coordinatesFormat = DecimalDegrees;
|
||||
|
||||
setToolTip(toolTip(Metric));
|
||||
}
|
||||
@ -47,9 +49,38 @@ void RouteItem::setMap(Map *map)
|
||||
PathItem::setMap(map);
|
||||
}
|
||||
|
||||
void RouteItem::setUnits(enum Units units)
|
||||
void RouteItem::setUnits(Units units)
|
||||
{
|
||||
setToolTip(toolTip(units));
|
||||
if (_units == units)
|
||||
return;
|
||||
|
||||
_units = units;
|
||||
|
||||
setToolTip(toolTip(_units));
|
||||
|
||||
QList<QGraphicsItem *> childs = childItems();
|
||||
for (int i = 0; i < childs.count(); i++) {
|
||||
if (childs.at(i) != _marker) {
|
||||
WaypointItem *wi = static_cast<WaypointItem*>(childs.at(i));
|
||||
wi->setToolTipFormat(_units, _coordinatesFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RouteItem::setCoordinatesFormat(CoordinatesFormat format)
|
||||
{
|
||||
if (_coordinatesFormat == format)
|
||||
return;
|
||||
|
||||
_coordinatesFormat = format;
|
||||
|
||||
QList<QGraphicsItem *> childs = childItems();
|
||||
for (int i = 0; i < childs.count(); i++) {
|
||||
if (childs.at(i) != _marker) {
|
||||
WaypointItem *wi = static_cast<WaypointItem*>(childs.at(i));
|
||||
wi->setToolTipFormat(_units, _coordinatesFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RouteItem::showWaypoints(bool show)
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "data/route.h"
|
||||
#include "pathitem.h"
|
||||
#include "units.h"
|
||||
#include "format.h"
|
||||
|
||||
class Map;
|
||||
|
||||
@ -17,6 +18,7 @@ public:
|
||||
void setMap(Map *map);
|
||||
|
||||
void setUnits(Units units);
|
||||
void setCoordinatesFormat(CoordinatesFormat format);
|
||||
void showWaypoints(bool show);
|
||||
void showWaypointLabels(bool show);
|
||||
|
||||
@ -25,6 +27,8 @@ private:
|
||||
|
||||
QString _name;
|
||||
QString _desc;
|
||||
Units _units;
|
||||
CoordinatesFormat _coordinatesFormat;
|
||||
};
|
||||
|
||||
#endif // ROUTEITEM_H
|
||||
|
@ -82,6 +82,9 @@ QString ScaleItem::units() const
|
||||
if (_units == Imperial)
|
||||
return _scale ? qApp->translate("ScaleItem", "mi")
|
||||
: qApp->translate("ScaleItem", "ft");
|
||||
else if (_units == Nautical)
|
||||
return _scale ? qApp->translate("ScaleItem", "nmi")
|
||||
: qApp->translate("ScaleItem", "ft");
|
||||
else
|
||||
return _scale ? qApp->translate("ScaleItem", "km")
|
||||
: qApp->translate("ScaleItem", "m");
|
||||
@ -94,8 +97,18 @@ void ScaleItem::computeScale()
|
||||
if (_units == Imperial) {
|
||||
_length = niceNum((res * M2FT * SCALE_WIDTH) / SEGMENTS, 1);
|
||||
if (_length >= MIINFT) {
|
||||
_length = niceNum((res * M2FT * FT2MI * SCALE_WIDTH) / SEGMENTS, 1);
|
||||
_width = (_length / (res * M2FT * FT2MI));
|
||||
_length = niceNum((res * M2MI * SCALE_WIDTH) / SEGMENTS, 1);
|
||||
_width = (_length / (res * M2MI));
|
||||
_scale = true;
|
||||
} else {
|
||||
_width = (_length / (res * M2FT));
|
||||
_scale = false;
|
||||
}
|
||||
} else if (_units == Nautical) {
|
||||
_length = niceNum((res * M2FT * SCALE_WIDTH) / SEGMENTS, 1);
|
||||
if (_length >= NMIINFT) {
|
||||
_length = niceNum((res * M2NMI * SCALE_WIDTH) / SEGMENTS, 1);
|
||||
_width = (_length / (res * M2NMI));
|
||||
_scale = true;
|
||||
} else {
|
||||
_width = (_length / (res * M2FT));
|
||||
|
@ -15,6 +15,8 @@
|
||||
#define TIME_TYPE_DEFAULT Total
|
||||
#define UNITS_SETTING "units"
|
||||
#define UNITS_DEFAULT (IMPERIAL_UNITS() ? Imperial : Metric)
|
||||
#define COORDINATES_SETTING "coordinates"
|
||||
#define COORDINATES_DEFAULT DecimalDegrees
|
||||
#define SHOW_TOOLBARS_SETTING "toolbar"
|
||||
#define SHOW_TOOLBARS_DEFAULT true
|
||||
|
||||
|
@ -79,12 +79,15 @@ void SpeedGraph::clear()
|
||||
|
||||
void SpeedGraph::setYUnits(Units units)
|
||||
{
|
||||
if (units == Metric) {
|
||||
GraphView::setYUnits(tr("km/h"));
|
||||
setYScale(MS2KMH);
|
||||
} else {
|
||||
if (units == Nautical) {
|
||||
GraphView::setYUnits(tr("kn"));
|
||||
setYScale(MS2KN);
|
||||
} else if (units == Imperial) {
|
||||
GraphView::setYUnits(tr("mi/h"));
|
||||
setYScale(MS2MIH);
|
||||
} else {
|
||||
GraphView::setYUnits(tr("km/h"));
|
||||
setYScale(MS2KMH);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,10 @@ SpeedGraphItem::SpeedGraphItem(const Graph &graph, GraphType type,
|
||||
QString SpeedGraphItem::toolTip() const
|
||||
{
|
||||
ToolTip tt;
|
||||
qreal scale = (_units == Metric) ? MS2KMH : MS2MIH;
|
||||
QString su = (_units == Metric) ? tr("km/h") : tr("mi/h");
|
||||
qreal scale = (_units == Imperial) ? MS2MIH : (_units == Nautical)
|
||||
? MS2KN : MS2KMH;
|
||||
QString su = (_units == Imperial) ? tr("mi/h") : (_units == Nautical)
|
||||
? tr("kn") : tr("km/h");
|
||||
|
||||
tt.insert(tr("Maximum"), QString::number(max() * scale, 'f', 1)
|
||||
+ UNIT_SPACE + su);
|
||||
|
@ -3,24 +3,29 @@
|
||||
|
||||
enum Units {
|
||||
Metric,
|
||||
Imperial
|
||||
Imperial,
|
||||
Nautical
|
||||
};
|
||||
|
||||
#define M2KM 0.001000000000 // m -> km
|
||||
#define M2MI 0.000621371192 // m -> mi
|
||||
#define M2NMI 0.000539956803 // m -> nmi
|
||||
#define M2FT 3.280839900000 // m -> ft
|
||||
#define MS2KMH 3.600000000000 // m/s -> km/h
|
||||
#define MS2MIH 2.236936290000 // m/s -> mi/h
|
||||
#define MS2KN 1.943844490000 // m/s -> kn
|
||||
#define FT2MI 0.000189393939 // ft -> mi
|
||||
#define MM2IN 0.039370100000 // mm -> in
|
||||
#define H2S 0.000277777778 // h -> s
|
||||
#define MIN2S 0.016666666667 // min -> s
|
||||
|
||||
#define KMINM 1000.0 // 1 km in m
|
||||
#define MIINFT 5280.0 // 1 mi in ft
|
||||
#define MIINM 1609.344 // 1 mi in m
|
||||
#define MININS 60.0 // 1 min in s
|
||||
#define HINS 3600.0 // 1 hins
|
||||
#define KMINM 1000.0 // 1 km in m
|
||||
#define MIINFT 5280.0 // 1 mi in ft
|
||||
#define NMIINFT 6076.11549 // 1 nm in ft
|
||||
#define MIINM 1609.344 // 1 mi in m
|
||||
#define NMIINM 1852.0 // 1 nmi in m
|
||||
#define MININS 60.0 // 1 min in s
|
||||
#define HINS 3600.0 // 1 hins
|
||||
|
||||
#define C2FS 1.8 // Celsius to Farenheit - scale
|
||||
#define C2FO 32.0 // Celsius to Farenheit - offset
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include "config.h"
|
||||
#include "format.h"
|
||||
#include "tooltip.h"
|
||||
#include "waypointitem.h"
|
||||
|
||||
@ -11,14 +10,14 @@
|
||||
#define FS(size) \
|
||||
((int)((qreal)size * 1.41))
|
||||
|
||||
QString WaypointItem::toolTip(Units units)
|
||||
QString WaypointItem::toolTip(Units units, CoordinatesFormat format)
|
||||
{
|
||||
ToolTip tt;
|
||||
|
||||
if (!_waypoint.name().isEmpty())
|
||||
tt.insert(qApp->translate("WaypointItem", "Name"), _waypoint.name());
|
||||
tt.insert(qApp->translate("WaypointItem", "Coordinates"),
|
||||
Format::coordinates(_waypoint.coordinates()));
|
||||
Format::coordinates(_waypoint.coordinates(), format));
|
||||
if (!std::isnan(_waypoint.elevation()))
|
||||
tt.insert(qApp->translate("WaypointItem", "Elevation"),
|
||||
Format::elevation(_waypoint.elevation(), units));
|
||||
@ -44,7 +43,7 @@ WaypointItem::WaypointItem(const Waypoint &waypoint, Map *map,
|
||||
updateShape();
|
||||
|
||||
setPos(map->ll2xy(waypoint.coordinates()));
|
||||
setToolTip(toolTip(Metric));
|
||||
setToolTip(toolTip(Metric, DecimalDegrees));
|
||||
setCursor(Qt::ArrowCursor);
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
@ -108,6 +107,9 @@ void WaypointItem::paint(QPainter *painter,
|
||||
|
||||
void WaypointItem::setSize(int size)
|
||||
{
|
||||
if (_size == size)
|
||||
return;
|
||||
|
||||
prepareGeometryChange();
|
||||
_size = size;
|
||||
updateShape();
|
||||
@ -115,17 +117,23 @@ void WaypointItem::setSize(int size)
|
||||
|
||||
void WaypointItem::setColor(const QColor &color)
|
||||
{
|
||||
if (_color == color)
|
||||
return;
|
||||
|
||||
_color = color;
|
||||
update();
|
||||
}
|
||||
|
||||
void WaypointItem::setUnits(enum Units units)
|
||||
void WaypointItem::setToolTipFormat(Units units, CoordinatesFormat format)
|
||||
{
|
||||
setToolTip(toolTip(units));
|
||||
setToolTip(toolTip(units, format));
|
||||
}
|
||||
|
||||
void WaypointItem::showLabel(bool show)
|
||||
{
|
||||
if (_showLabel == show)
|
||||
return;
|
||||
|
||||
prepareGeometryChange();
|
||||
_showLabel = show;
|
||||
updateShape();
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "data/waypoint.h"
|
||||
#include "map/map.h"
|
||||
#include "units.h"
|
||||
#include "format.h"
|
||||
|
||||
class WaypointItem : public QGraphicsItem
|
||||
{
|
||||
@ -15,7 +16,7 @@ public:
|
||||
const Waypoint &waypoint() const {return _waypoint;}
|
||||
|
||||
void setMap(Map *map) {setPos(map->ll2xy(_waypoint.coordinates()));}
|
||||
void setUnits(Units units);
|
||||
void setToolTipFormat(Units units, CoordinatesFormat format);
|
||||
void setSize(int size);
|
||||
void setColor(const QColor &color);
|
||||
void showLabel(bool show);
|
||||
@ -31,7 +32,7 @@ private:
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
||||
|
||||
void updateShape();
|
||||
QString toolTip(Units units);
|
||||
QString toolTip(Units units, CoordinatesFormat format);
|
||||
|
||||
QPainterPath _shape;
|
||||
Waypoint _waypoint;
|
||||
|
@ -16,12 +16,6 @@ qreal Coordinates::distanceTo(const Coordinates &c) const
|
||||
return (WGS84_RADIUS * (2.0 * atan2(sqrt(a), sqrt(1.0 - a))));
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Coordinates &c)
|
||||
{
|
||||
dbg.nospace() << "Coordinates(" << c.lon() << ", " << c.lat() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
|
||||
QPair<Coordinates, Coordinates> Coordinates::boundingRect(qreal distance) const
|
||||
{
|
||||
qreal radDist = distance / WGS84_RADIUS;
|
||||
@ -50,3 +44,11 @@ QPair<Coordinates, Coordinates> Coordinates::boundingRect(qreal distance) const
|
||||
maxLon)), rad2deg(qMin(minLat, maxLat))), Coordinates(rad2deg(qMax(minLon,
|
||||
maxLon)), rad2deg(qMax(minLat, maxLat))));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Coordinates &c)
|
||||
{
|
||||
dbg.nospace() << "Coordinates(" << c.lon() << ", " << c.lat() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -43,6 +43,8 @@ inline bool operator==(const Coordinates &c1, const Coordinates &c2)
|
||||
inline bool operator!=(const Coordinates &c1, const Coordinates &c2)
|
||||
{return !(c1 == c2);}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Coordinates &c);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // COORDINATES_H
|
||||
|
@ -8,6 +8,7 @@ void RangeF::resize(qreal size)
|
||||
_max += adj;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Range &range)
|
||||
{
|
||||
dbg.nospace() << "Range(" << range.min() << ", " << range.max() << ")";
|
||||
@ -19,3 +20,4 @@ QDebug operator<<(QDebug dbg, const RangeF &range)
|
||||
dbg.nospace() << "RangeF(" << range.min() << ", " << range.max() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -14,6 +14,8 @@ public:
|
||||
int max() const {return _max;}
|
||||
int size() const {return (_max - _min);}
|
||||
|
||||
bool isValid() const {return size() >= 0;}
|
||||
|
||||
private:
|
||||
int _min, _max;
|
||||
};
|
||||
@ -28,13 +30,17 @@ public:
|
||||
qreal max() const {return _max;}
|
||||
qreal size() const {return (_max - _min);}
|
||||
|
||||
bool isValid() const {return size() >= 0;}
|
||||
|
||||
void resize(qreal size);
|
||||
|
||||
private:
|
||||
qreal _min, _max;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Range &range);
|
||||
QDebug operator<<(QDebug dbg, const RangeF &range);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // RANGE_H
|
||||
|
@ -61,8 +61,10 @@ void RectC::unite(const Coordinates &c)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const RectC &rect)
|
||||
{
|
||||
dbg.nospace() << "RectC(" << rect.topLeft() << ", " << rect.size() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -37,6 +37,8 @@ private:
|
||||
Coordinates _tl, _br;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const RectC &rect);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // RECTC_H
|
||||
|
@ -30,12 +30,14 @@ private:
|
||||
|
||||
Q_DECLARE_TYPEINFO(GraphPoint, Q_PRIMITIVE_TYPE);
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
inline QDebug operator<<(QDebug dbg, const GraphPoint &point)
|
||||
{
|
||||
dbg.nospace() << "GraphPoint(" << point.s() << ", " << point.t() << ", "
|
||||
<< point.y() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
typedef QVector<GraphPoint> Graph;
|
||||
|
||||
|
@ -13,9 +13,11 @@ RectC Path::boundingRect() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const PathPoint &point)
|
||||
{
|
||||
dbg.nospace() << "PathPoint(" << point.distance() << ", "
|
||||
<< point.coordinates() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -23,7 +23,9 @@ private:
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(PathPoint, Q_PRIMITIVE_TYPE);
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const PathPoint &point);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
|
||||
class Path : public QVector<PathPoint>
|
||||
|
@ -49,9 +49,7 @@ static QSet<int> eliminate(const QVector<qreal> &v, int window)
|
||||
|
||||
static Graph filter(const Graph &g, int window)
|
||||
{
|
||||
if (g.size() < window)
|
||||
return Graph();
|
||||
if (window < 2)
|
||||
if (g.size() < window || window < 2)
|
||||
return Graph(g);
|
||||
|
||||
qreal acc = 0;
|
||||
@ -77,27 +75,32 @@ static Graph filter(const Graph &g, int window)
|
||||
Track::Track(const TrackData &data) : _data(data)
|
||||
{
|
||||
qreal dt, ds, total;
|
||||
int last;
|
||||
|
||||
|
||||
_time.append(0);
|
||||
_distance.append(0);
|
||||
_speed.append(0);
|
||||
|
||||
for (int i = 1; i < data.count(); i++) {
|
||||
ds = data.at(i).coordinates().distanceTo(data.at(i-1).coordinates());
|
||||
last = 0;
|
||||
|
||||
for (int i = 1; i < _data.count(); i++) {
|
||||
ds = _data.at(i).coordinates().distanceTo(_data.at(i-1).coordinates());
|
||||
_distance.append(ds);
|
||||
|
||||
if (data.first().hasTimestamp() && data.at(i).hasTimestamp())
|
||||
if (_data.first().hasTimestamp() && _data.at(i).hasTimestamp()
|
||||
&& _data.at(i).timestamp() > _data.at(last).timestamp()) {
|
||||
_time.append(_data.first().timestamp().msecsTo(
|
||||
_data.at(i).timestamp()) / 1000.0);
|
||||
else
|
||||
last = i;
|
||||
} else
|
||||
_time.append(NAN);
|
||||
|
||||
if (std::isnan(_time.at(i)) || std::isnan(_time.at(i-1)))
|
||||
_speed.append(NAN);
|
||||
else {
|
||||
dt = _time.at(i) - _time.at(i-1);
|
||||
if (!dt) {
|
||||
if (dt < 1e-3) {
|
||||
_speed.append(_speed.at(i-1));
|
||||
continue;
|
||||
}
|
||||
@ -106,7 +109,7 @@ Track::Track(const TrackData &data) : _data(data)
|
||||
}
|
||||
|
||||
_pause = 0;
|
||||
for (int i = 1; i < data.count(); i++) {
|
||||
for (int i = 1; i < _data.count(); i++) {
|
||||
if (_time.at(i) > _time.at(i-1) + _pauseInterval
|
||||
&& _speed.at(i) < _pauseSpeed) {
|
||||
_pause += _time.at(i) - _time.at(i-1);
|
||||
|
@ -57,6 +57,7 @@ private:
|
||||
|
||||
Q_DECLARE_TYPEINFO(Trackpoint, Q_MOVABLE_TYPE);
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
inline QDebug operator<<(QDebug dbg, const Trackpoint &trackpoint)
|
||||
{
|
||||
dbg.nospace() << "Trackpoint(" << trackpoint.coordinates() << ", "
|
||||
@ -65,5 +66,6 @@ inline QDebug operator<<(QDebug dbg, const Trackpoint &trackpoint)
|
||||
<< trackpoint.temperature() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // TRACKPOINT_H
|
||||
|
@ -48,12 +48,14 @@ inline uint qHash(const Waypoint &key)
|
||||
return ::qHash(key.name());
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
inline QDebug operator<<(QDebug dbg, const Waypoint &waypoint)
|
||||
{
|
||||
dbg.nospace() << "Waypoint(" << waypoint.coordinates() << ", "
|
||||
<< waypoint.name() << ", " << waypoint.description() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
Q_DECLARE_TYPEINFO(Waypoint, Q_MOVABLE_TYPE);
|
||||
|
||||
|
@ -41,6 +41,7 @@ Defense.
|
||||
|
||||
*/
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "albersequal.h"
|
||||
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef ALBERSEQUAL_H
|
||||
#define ALBERSEQUAL_H
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "ct.h"
|
||||
|
||||
class Ellipsoid;
|
||||
|
||||
class AlbersEqual : public CT
|
||||
{
|
||||
public:
|
||||
|
@ -8,7 +8,8 @@ static double sDMS2deg(double val)
|
||||
const char *decimal;
|
||||
|
||||
QString qstr(QString::number(qAbs(val), 'f', 7));
|
||||
const char *str = qstr.toLatin1().constData();
|
||||
QByteArray ba = qstr.toLatin1();
|
||||
const char *str = ba.constData();
|
||||
decimal = strrchr(str, '.');
|
||||
int deg = str2int(str, decimal - str);
|
||||
int min = str2int(decimal + 1, 2);
|
||||
@ -83,8 +84,10 @@ double AngularUnits::fromDegrees(double val) const
|
||||
return (_code == 9110) ? deg2sDMS(val) : val / _f;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const AngularUnits &au)
|
||||
{
|
||||
dbg.nospace() << "AngularUnits(" << deg2rad(au._f) << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -17,8 +17,9 @@ public:
|
||||
double fromDegrees(double val) const;
|
||||
|
||||
friend bool operator==(const AngularUnits &au1, const AngularUnits &au2);
|
||||
#ifndef QT_NO_DEBUG
|
||||
friend QDebug operator<<(QDebug dbg, const AngularUnits &au);
|
||||
|
||||
#endif // QT_NO_DEBUG
|
||||
private:
|
||||
int _code;
|
||||
double _f;
|
||||
@ -27,6 +28,8 @@ private:
|
||||
inline bool operator==(const AngularUnits &au1, const AngularUnits &au2)
|
||||
{return (au1._f == au2._f);}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const AngularUnits &au);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // ANGULARUNITS_H
|
||||
|
@ -15,8 +15,8 @@ static bool resCmp(const OfflineMap *m1, const OfflineMap *m2)
|
||||
{
|
||||
qreal r1, r2;
|
||||
|
||||
r1 = m1->resolution(m1->bounds().center());
|
||||
r2 = m2->resolution(m2->bounds().center());
|
||||
r1 = m1->resolution(m1->bounds());
|
||||
r2 = m2->resolution(m2->bounds());
|
||||
|
||||
return r1 > r2;
|
||||
}
|
||||
@ -37,8 +37,8 @@ void Atlas::computeZooms()
|
||||
|
||||
_zooms.append(QPair<int, int>(0, _maps.count() - 1));
|
||||
for (int i = 1; i < _maps.count(); i++) {
|
||||
qreal last = _maps.at(i-1)->resolution(_maps.at(i)->bounds().center());
|
||||
qreal cur = _maps.at(i)->resolution(_maps.at(i)->bounds().center());
|
||||
qreal last = _maps.at(i-1)->resolution(_maps.at(i)->bounds());
|
||||
qreal cur = _maps.at(i)->resolution(_maps.at(i)->bounds());
|
||||
if (cur < last * ZOOM_THRESHOLD) {
|
||||
_zooms.last().second = i-1;
|
||||
_zooms.append(QPair<int, int>(i, _maps.count() - 1));
|
||||
@ -169,26 +169,21 @@ QRectF Atlas::bounds() const
|
||||
return QRectF(QPointF(0, 0), s);
|
||||
}
|
||||
|
||||
qreal Atlas::resolution(const QPointF &p) const
|
||||
qreal Atlas::resolution(const QRectF &rect) const
|
||||
{
|
||||
int idx = _zooms.at(_zoom).first;
|
||||
|
||||
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).second; i++) {
|
||||
if (_bounds.at(i).second.contains(_maps.at(i)->xy2pp(p))) {
|
||||
if (_bounds.at(i).second.contains(_maps.at(i)->xy2pp(rect.center()))) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _maps.at(idx)->resolution(p);
|
||||
return _maps.at(idx)->resolution(rect);
|
||||
}
|
||||
|
||||
qreal Atlas::zoom() const
|
||||
{
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal Atlas::zoomFit(const QSize &size, const RectC &br)
|
||||
int Atlas::zoomFit(const QSize &size, const RectC &br)
|
||||
{
|
||||
_zoom = 0;
|
||||
|
||||
@ -217,33 +212,13 @@ qreal Atlas::zoomFit(const QSize &size, const RectC &br)
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal Atlas::zoomFit(qreal resolution, const Coordinates &c)
|
||||
{
|
||||
_zoom = 0;
|
||||
|
||||
for (int z = 0; z < _zooms.count(); z++) {
|
||||
for (int i = _zooms.at(z).first; i <= _zooms.at(z).second; i++) {
|
||||
if (!_bounds.at(i).first.contains(_maps.at(i)->ll2pp(c)))
|
||||
continue;
|
||||
|
||||
if (_maps.at(i)->resolution(_maps.at(i)->ll2xy(c)) < resolution)
|
||||
return _zoom;
|
||||
|
||||
_zoom = z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal Atlas::zoomIn()
|
||||
int Atlas::zoomIn()
|
||||
{
|
||||
_zoom = qMin(_zoom + 1, _zooms.size() - 1);
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal Atlas::zoomOut()
|
||||
int Atlas::zoomOut()
|
||||
{
|
||||
_zoom = qMax(_zoom - 1, 0);
|
||||
return _zoom;
|
||||
|
@ -17,13 +17,12 @@ public:
|
||||
const QString &name() const {return _name;}
|
||||
|
||||
QRectF bounds() const;
|
||||
qreal resolution(const QPointF &p) const;
|
||||
qreal resolution(const QRectF &rect) const;
|
||||
|
||||
qreal zoom() const;
|
||||
qreal zoomFit(const QSize &size, const RectC &br);
|
||||
qreal zoomFit(qreal resolution, const Coordinates &c);
|
||||
qreal zoomIn();
|
||||
qreal zoomOut();
|
||||
int zoom() const {return _zoom;}
|
||||
int zoomFit(const QSize &size, const RectC &br);
|
||||
int zoomIn();
|
||||
int zoomOut();
|
||||
|
||||
QPointF ll2xy(const Coordinates &c);
|
||||
Coordinates xy2ll(const QPointF &p);
|
||||
@ -33,7 +32,7 @@ public:
|
||||
void unload();
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
const QString &errorString() const {return _errorString;}
|
||||
QString errorString() const {return _errorString;}
|
||||
|
||||
static bool isAtlas(const QString &path);
|
||||
|
||||
|
@ -43,11 +43,12 @@ static Coordinates molodensky(const Coordinates &c, const Datum &from,
|
||||
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)
|
||||
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;
|
||||
_WGS84 = (_ellipsoid->radius() == WGS84_RADIUS
|
||||
&& _ellipsoid->flattening() == WGS84_FLATTENING && _dx == 0.0
|
||||
&& _dy == 0.0 && _dz == 0.0) ? true : false;
|
||||
}
|
||||
|
||||
Coordinates Datum::toWGS84(const Coordinates &c) const
|
||||
@ -60,9 +61,11 @@ Coordinates Datum::fromWGS84(const Coordinates &c) const
|
||||
return _WGS84 ? c : molodensky(c, WGS84, *this);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Datum &datum)
|
||||
{
|
||||
dbg.nospace() << "Datum(" << *datum.ellipsoid() << ", " << datum.dx()
|
||||
<< ", " << datum.dy() << ", " << datum.dz() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -39,6 +39,8 @@ 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());}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Datum &datum);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // DATUM_H
|
||||
|
@ -61,7 +61,7 @@ bool Downloader::saveToDisk(const QString &filename, QIODevice *data)
|
||||
QFile file(filename);
|
||||
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
qWarning("Error writing map tile: %s: %s\n",
|
||||
qWarning("Error writing file: %s: %s\n",
|
||||
qPrintable(filename), qPrintable(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
@ -80,11 +80,11 @@ void Downloader::downloadFinished(QNetworkReply *reply)
|
||||
QUrl origin = reply->request().attribute(ATTR_ORIGIN).toUrl();
|
||||
if (origin.isEmpty()) {
|
||||
_errorDownloads.insert(url);
|
||||
qWarning("Error downloading map tile: %s: %s\n",
|
||||
qWarning("Error downloading file: %s: %s\n",
|
||||
url.toEncoded().constData(), qPrintable(reply->errorString()));
|
||||
} else {
|
||||
_errorDownloads.insert(origin);
|
||||
qWarning("Error downloading map tile: %s -> %s: %s\n",
|
||||
qWarning("Error downloading file: %s -> %s: %s\n",
|
||||
origin.toEncoded().constData(), url.toEncoded().constData(),
|
||||
qPrintable(reply->errorString()));
|
||||
}
|
||||
@ -99,11 +99,11 @@ void Downloader::downloadFinished(QNetworkReply *reply)
|
||||
|
||||
if (location == url) {
|
||||
_errorDownloads.insert(url);
|
||||
qWarning("Error downloading map tile: %s: "
|
||||
qWarning("Error downloading file: %s: "
|
||||
"redirect loop\n", url.toEncoded().constData());
|
||||
} else if (level >= MAX_REDIRECT_LEVEL) {
|
||||
_errorDownloads.insert(origin);
|
||||
qWarning("Error downloading map tile: %s: "
|
||||
qWarning("Error downloading file: %s: "
|
||||
"redirect level limit reached\n",
|
||||
origin.toEncoded().constData());
|
||||
} else {
|
||||
|
@ -66,9 +66,11 @@ void Ellipsoid::loadList(const QString &path)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Ellipsoid &ellipsoid)
|
||||
{
|
||||
dbg.nospace() << "Ellipsoid(" << ellipsoid.radius() << ", "
|
||||
<< 1.0 / ellipsoid.flattening() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -35,6 +35,8 @@ private:
|
||||
inline bool operator==(const Ellipsoid &e1, const Ellipsoid &e2)
|
||||
{return (e1.radius() == e2.radius() && e1.flattening() == e2.flattening());}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Ellipsoid &ellipsoid);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // ELLIPSOID_H
|
||||
|
@ -3,16 +3,47 @@
|
||||
#include "common/coordinates.h"
|
||||
#include "common/rectc.h"
|
||||
#include "common/wgs84.h"
|
||||
#include "mercator.h"
|
||||
#include "emptymap.h"
|
||||
|
||||
|
||||
#define SCALE_MIN 0.5
|
||||
#define SCALE_MAX 1.0E-6
|
||||
#define ZOOM_MIN 0
|
||||
#define ZOOM_MAX 19
|
||||
#define TILE_SIZE 256
|
||||
|
||||
static QPointF ll2m(const Coordinates &c)
|
||||
{
|
||||
return QPointF(c.lon(), rad2deg(log(tan(M_PI/4.0 + deg2rad(c.lat())/2.0))));
|
||||
}
|
||||
|
||||
static Coordinates m2ll(const QPointF &p)
|
||||
{
|
||||
return Coordinates(p.x(), rad2deg(2 * atan(exp(deg2rad(p.y()))) - M_PI/2));
|
||||
}
|
||||
|
||||
static qreal zoom2scale(int zoom)
|
||||
{
|
||||
return (360.0/(qreal)((1<<zoom) * TILE_SIZE));
|
||||
}
|
||||
|
||||
static int scale2zoom(qreal scale)
|
||||
{
|
||||
return (int)log2(360.0/(scale * (qreal)TILE_SIZE));
|
||||
}
|
||||
|
||||
static int limitZoom(int zoom)
|
||||
{
|
||||
if (zoom < ZOOM_MIN)
|
||||
return ZOOM_MIN;
|
||||
if (zoom > ZOOM_MAX)
|
||||
return ZOOM_MAX;
|
||||
|
||||
return zoom;
|
||||
}
|
||||
|
||||
|
||||
EmptyMap::EmptyMap(QObject *parent) : Map(parent)
|
||||
{
|
||||
_scale = SCALE_MAX;
|
||||
_zoom = ZOOM_MAX;
|
||||
}
|
||||
|
||||
QRectF EmptyMap::bounds() const
|
||||
@ -20,50 +51,38 @@ QRectF EmptyMap::bounds() const
|
||||
return QRectF(ll2xy(Coordinates(-180, 85)), ll2xy(Coordinates(180, -85)));
|
||||
}
|
||||
|
||||
qreal EmptyMap::zoomFit(const QSize &size, const RectC &br)
|
||||
int EmptyMap::zoomFit(const QSize &size, const RectC &br)
|
||||
{
|
||||
if (!br.isValid())
|
||||
_scale = SCALE_MAX;
|
||||
_zoom = ZOOM_MAX;
|
||||
else {
|
||||
QRectF tbr(Mercator().ll2xy(br.topLeft()),
|
||||
Mercator().ll2xy(br.bottomRight()));
|
||||
QRectF tbr(ll2m(br.topLeft()), ll2m(br.bottomRight()));
|
||||
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
|
||||
_scale = qMax(sc.x(), sc.y());
|
||||
|
||||
_zoom = limitZoom(scale2zoom(qMax(sc.x(), sc.y())));
|
||||
}
|
||||
|
||||
_scale = qMax(_scale, SCALE_MAX);
|
||||
_scale = qMin(_scale, SCALE_MIN);
|
||||
|
||||
return _scale;
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal EmptyMap::zoomFit(qreal resolution, const Coordinates &c)
|
||||
qreal EmptyMap::resolution(const QRectF &rect) const
|
||||
{
|
||||
_scale = (360.0 * resolution) / (WGS84_RADIUS * 2 * M_PI
|
||||
* cos(deg2rad(c.lat())));
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
|
||||
_scale = qMax(_scale, SCALE_MAX);
|
||||
_scale = qMin(_scale, SCALE_MIN);
|
||||
|
||||
return _scale;
|
||||
return (WGS84_RADIUS * 2.0 * M_PI * scale / 360.0
|
||||
* cos(2.0 * atan(exp(deg2rad(-rect.center().y() * scale))) - M_PI/2));
|
||||
}
|
||||
|
||||
qreal EmptyMap::resolution(const QPointF &p) const
|
||||
int EmptyMap::zoomIn()
|
||||
{
|
||||
return (WGS84_RADIUS * 2 * M_PI * _scale / 360.0
|
||||
* cos(2.0 * atan(exp(deg2rad(-p.y() * _scale))) - M_PI/2));
|
||||
_zoom = qMin(_zoom + 1, ZOOM_MAX);
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal EmptyMap::zoomIn()
|
||||
int EmptyMap::zoomOut()
|
||||
{
|
||||
_scale = qMax(_scale / 2.0, SCALE_MAX);
|
||||
return _scale;
|
||||
}
|
||||
|
||||
qreal EmptyMap::zoomOut()
|
||||
{
|
||||
_scale = qMin(_scale * 2.0, SCALE_MIN);
|
||||
return _scale;
|
||||
_zoom = qMax(_zoom - 1, ZOOM_MIN);
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
void EmptyMap::draw(QPainter *painter, const QRectF &rect)
|
||||
@ -73,12 +92,13 @@ void EmptyMap::draw(QPainter *painter, const QRectF &rect)
|
||||
|
||||
QPointF EmptyMap::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
QPointF m = Mercator().ll2xy(c);
|
||||
return QPointF(m.x() / _scale, m.y() / -_scale);
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
QPointF m = ll2m(c);
|
||||
return QPointF(m.x() / scale, m.y() / -scale);
|
||||
}
|
||||
|
||||
Coordinates EmptyMap::xy2ll(const QPointF &p) const
|
||||
{
|
||||
QPointF m(p.x() * _scale, -p.y() * _scale);
|
||||
return Mercator().xy2ll(m);
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
return m2ll(QPointF(p.x() * scale, -p.y() * scale));
|
||||
}
|
||||
|
@ -14,13 +14,12 @@ public:
|
||||
const QString &name() const {return _name;}
|
||||
|
||||
QRectF bounds() const;
|
||||
qreal resolution(const QPointF &p) const;
|
||||
qreal resolution(const QRectF &rect) const;
|
||||
|
||||
qreal zoom() const {return _scale;}
|
||||
qreal zoomFit(const QSize &size, const RectC &br);
|
||||
qreal zoomFit(qreal resolution, const Coordinates &c);
|
||||
qreal zoomIn();
|
||||
qreal zoomOut();
|
||||
int zoom() const {return _zoom;}
|
||||
int zoomFit(const QSize &size, const RectC &br);
|
||||
int zoomIn();
|
||||
int zoomOut();
|
||||
|
||||
QPointF ll2xy(const Coordinates &c)
|
||||
{return static_cast<const EmptyMap &>(*this).ll2xy(c);}
|
||||
@ -34,7 +33,7 @@ private:
|
||||
Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
QString _name;
|
||||
qreal _scale;
|
||||
int _zoom;
|
||||
};
|
||||
|
||||
#endif // EMPTYMAP_H
|
||||
|
@ -183,9 +183,11 @@ Coordinates GCS::fromWGS84(const Coordinates &c) const
|
||||
return Coordinates(_primeMeridian.fromGreenwich(ds.lon()), ds.lat());
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const GCS &gcs)
|
||||
{
|
||||
dbg.nospace() << "GCS(" << gcs.datum() << ", " << gcs.primeMeridian()
|
||||
<< ", " << gcs.angularUnits() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -25,7 +25,6 @@ public:
|
||||
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);
|
||||
@ -50,6 +49,8 @@ inline bool operator==(const GCS &gcs1, const GCS &gcs2)
|
||||
&& gcs1.primeMeridian() == gcs2.primeMeridian()
|
||||
&& gcs1.angularUnits() == gcs2.angularUnits());}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const GCS &gcs);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // GCS_H
|
||||
|
@ -1,193 +1,72 @@
|
||||
/*
|
||||
* 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 "ellipsoid.h"
|
||||
#include "lambertazimuthal.h"
|
||||
|
||||
|
||||
#ifndef M_PI_2
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#endif // M_PI_2
|
||||
#define sin2(x) (sin(x) * sin(x))
|
||||
#define sqr(x) ((x) * (x))
|
||||
|
||||
LambertAzimuthal::LambertAzimuthal(const Ellipsoid *ellipsoid,
|
||||
double latitudeOrigin, double longitudeOrigin, double falseEasting,
|
||||
double falseNorthing)
|
||||
{
|
||||
double es2, es4, es6;
|
||||
double lat0 = deg2rad(latitudeOrigin);
|
||||
|
||||
es2 = 2 * ellipsoid->flattening() - ellipsoid->flattening()
|
||||
* ellipsoid->flattening();
|
||||
|
||||
es4 = es2 * es2;
|
||||
es6 = es4 * es2;
|
||||
_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);
|
||||
_absLatOrigin = fabs(_latOrigin);
|
||||
_lonOrigin = deg2rad(longitudeOrigin);
|
||||
if (_lonOrigin > M_PI)
|
||||
_lonOrigin -= 2.0 * M_PI;
|
||||
|
||||
_falseNorthing = falseNorthing;
|
||||
_falseEasting = falseEasting;
|
||||
_falseNorthing = falseNorthing;
|
||||
_lon0 = deg2rad(longitudeOrigin);
|
||||
|
||||
_a = ellipsoid->radius();
|
||||
|
||||
_es2 = 2.0 * ellipsoid->flattening() - ellipsoid->flattening()
|
||||
* ellipsoid->flattening();
|
||||
_es = sqrt(_es2);
|
||||
|
||||
double q0 = (1.0 - _es2) * ((sin(lat0) / (1.0 - _es2 * sin2(lat0)))
|
||||
- ((1.0/(2.0*_es)) * log((1.0 - _es * sin(lat0)) / (1.0 + _es
|
||||
* sin(lat0)))));
|
||||
_qP = (1.0 - _es2) * ((1.0 / (1.0 - _es2)) - ((1.0/(2.0*_es))
|
||||
* log((1.0 - _es) / (1.0 + _es))));
|
||||
_beta0 = asin(q0 / _qP);
|
||||
_Rq = _a * sqrt(_qP / 2.0);
|
||||
_D = _a * (cos(lat0) / sqrt(1.0 - _es2 * sin2(lat0))) / (_Rq * cos(_beta0));
|
||||
}
|
||||
|
||||
QPointF LambertAzimuthal::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
double dlam;
|
||||
double k_prime;
|
||||
double cd;
|
||||
double rlat = deg2rad(c.lat());
|
||||
double slat = sin(rlat);
|
||||
double clat = cos(rlat);
|
||||
double cos_c;
|
||||
double sin_dlam, cos_dlam;
|
||||
double Ra_kprime;
|
||||
double Ra_PI_OVER_2_Lat;
|
||||
QPointF p;
|
||||
double lon = deg2rad(c.lon());
|
||||
double lat = deg2rad(c.lat());
|
||||
|
||||
double q = (1.0 - _es2) * ((sin(lat) / (1.0 - _es2 * sin2(lat)))
|
||||
- ((1.0/(2.0*_es)) * log((1.0 - _es * sin(lat)) / (1.0 + _es
|
||||
* sin(lat)))));
|
||||
double beta = asin(q / _qP);
|
||||
double B = _Rq * sqrt(2.0 / (1.0 + sin(_beta0) * sin(beta) + (cos(_beta0)
|
||||
* cos(beta) * cos(lon - _lon0))));
|
||||
|
||||
dlam = deg2rad(c.lon()) - _lonOrigin;
|
||||
if (dlam > M_PI)
|
||||
dlam -= 2.0 * M_PI;
|
||||
if (dlam < -M_PI)
|
||||
dlam += 2.0 * M_PI;
|
||||
double x = _falseEasting + ((B * _D) * (cos(beta) * sin(lon - _lon0)));
|
||||
double y = _falseNorthing + (B / _D) * ((cos(_beta0) * sin(beta))
|
||||
- (sin(_beta0) * cos(beta) * cos(lon - _lon0)));
|
||||
|
||||
sin_dlam = sin(dlam);
|
||||
cos_dlam = cos(dlam);
|
||||
if (fabs(_absLatOrigin - M_PI_2) < 1.0e-10) {
|
||||
if (_latOrigin >= 0.0) {
|
||||
Ra_PI_OVER_2_Lat = _ra * (M_PI_2 - rlat);
|
||||
p.rx() = Ra_PI_OVER_2_Lat * sin_dlam + _falseEasting;
|
||||
p.ry() = -1.0 * (Ra_PI_OVER_2_Lat * cos_dlam) + _falseNorthing;
|
||||
} else {
|
||||
Ra_PI_OVER_2_Lat = _ra * (M_PI_2 + rlat);
|
||||
p.rx() = Ra_PI_OVER_2_Lat * sin_dlam + _falseEasting;
|
||||
p.ry() = Ra_PI_OVER_2_Lat * cos_dlam + _falseNorthing;
|
||||
}
|
||||
} else if (_absLatOrigin <= 1.0e-10) {
|
||||
cos_c = clat * cos_dlam;
|
||||
if (fabs(fabs(cos_c) - 1.0) < 1.0e-14) {
|
||||
if (cos_c >= 0.0) {
|
||||
p.rx() = _falseEasting;
|
||||
p.ry() = _falseNorthing;
|
||||
} else
|
||||
return QPointF(NAN, NAN);
|
||||
} else {
|
||||
cd = acos(cos_c);
|
||||
k_prime = cd / sin(cd);
|
||||
Ra_kprime = _ra * k_prime;
|
||||
p.rx() = Ra_kprime * clat * sin_dlam + _falseEasting;
|
||||
p.ry() = Ra_kprime * slat + _falseNorthing;
|
||||
}
|
||||
} else {
|
||||
cos_c = (_sinLatOrigin * slat) + (_cosLatOrigin * clat * cos_dlam);
|
||||
if (fabs(fabs(cos_c) - 1.0) < 1.0e-14) {
|
||||
if (cos_c >= 0.0) {
|
||||
p.rx() = _falseEasting;
|
||||
p.ry() = _falseNorthing;
|
||||
} else
|
||||
return QPointF(NAN, NAN);
|
||||
} else {
|
||||
cd = acos(cos_c);
|
||||
k_prime = cd / sin(cd);
|
||||
Ra_kprime = _ra * k_prime;
|
||||
p.rx() = Ra_kprime * clat * sin_dlam + _falseEasting;
|
||||
p.ry() = Ra_kprime * (_cosLatOrigin * slat - _sinLatOrigin * clat
|
||||
* cos_dlam) + _falseNorthing;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
return QPointF(x, y);
|
||||
}
|
||||
|
||||
Coordinates LambertAzimuthal::xy2ll(const QPointF &p) const
|
||||
{
|
||||
double dx, dy;
|
||||
double rho;
|
||||
double cd;
|
||||
double sin_c, cos_c, dy_sinc;
|
||||
double lat, lon;
|
||||
double es4 = _es2 * _es2;
|
||||
double es6 = _es2 * es4;
|
||||
|
||||
double rho = sqrt(sqr((p.x() - _falseEasting) / _D) + sqr(_D * (p.y()
|
||||
- _falseNorthing)));
|
||||
double C = 2.0 * asin(rho / (2.0*_Rq));
|
||||
double betaS = asin((cos(C) * sin(_beta0)) + ((_D * (p.y() -_falseNorthing)
|
||||
* sin(C) * cos(_beta0)) / rho));
|
||||
|
||||
dy = p.y() - _falseNorthing;
|
||||
dx = p.x() - _falseEasting;
|
||||
rho = sqrt(dx * dx + dy * dy);
|
||||
if (fabs(rho) <= 1.0e-10) {
|
||||
lat = _latOrigin;
|
||||
lon = _lonOrigin;
|
||||
} else {
|
||||
cd = rho / _ra;
|
||||
sin_c = sin(cd);
|
||||
cos_c = cos(cd);
|
||||
dy_sinc = dy * sin_c;
|
||||
lat = asin((cos_c * _sinLatOrigin) + ((dy_sinc * _cosLatOrigin) / rho));
|
||||
if (fabs(_absLatOrigin - M_PI_2) < 1.0e-10) {
|
||||
if (_latOrigin >= 0.0)
|
||||
lon = _lonOrigin + atan2(dx, -dy);
|
||||
else
|
||||
lon = _lonOrigin + atan2(dx, dy);
|
||||
}
|
||||
else
|
||||
lon = _lonOrigin + atan2((dx * sin_c), ((rho * _cosLatOrigin
|
||||
* cos_c) - (dy_sinc * _sinLatOrigin)));
|
||||
}
|
||||
|
||||
if (lat > M_PI_2)
|
||||
lat = M_PI_2;
|
||||
else if (lat < -M_PI_2)
|
||||
lat = -M_PI_2;
|
||||
|
||||
if (lon > M_PI)
|
||||
lon -= 2.0 * M_PI;
|
||||
if (lon < -M_PI)
|
||||
lon += 2.0 * M_PI;
|
||||
|
||||
if (lon > M_PI)
|
||||
lon = M_PI;
|
||||
else if (lon < -M_PI)
|
||||
lon = -M_PI;
|
||||
double lon = _lon0 + atan((p.x() - _falseEasting) * sin(C) / (_D * rho
|
||||
* cos(_beta0) * cos(C) - sqr(_D) * (p.y() - _falseNorthing) * sin(_beta0)
|
||||
* sin(C)));
|
||||
double lat = betaS + ((_es2/3.0 + 31.0*es4/180.0 + 517.0*es6/5040.0)
|
||||
* sin(2.0*betaS)) + ((23.0*es4/360.0 + 251.0*es6/3780.0) * sin(4.0*betaS))
|
||||
+ ((761.0*es6/45360.0)*sin(6.0*betaS));
|
||||
|
||||
return Coordinates(rad2deg(lon), rad2deg(lat));
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef LAMBERTAZIMUTHAL_H
|
||||
#define LAMBERTAZIMUTHAL_H
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "ct.h"
|
||||
|
||||
class Ellipsoid;
|
||||
|
||||
class LambertAzimuthal : public CT
|
||||
{
|
||||
public:
|
||||
@ -16,15 +17,10 @@ public:
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
double _ra;
|
||||
double _sinLatOrigin;
|
||||
double _cosLatOrigin;
|
||||
double _absLatOrigin;
|
||||
|
||||
double _latOrigin;
|
||||
double _lonOrigin;
|
||||
double _lon0;
|
||||
double _falseNorthing;
|
||||
double _falseEasting;
|
||||
double _a, _es, _es2, _qP, _beta0, _Rq, _D;
|
||||
};
|
||||
|
||||
#endif // LAMBERTAZIMUTHAL_H
|
||||
|
@ -42,6 +42,7 @@ Defense.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include "ellipsoid.h"
|
||||
#include "lambertconic.h"
|
||||
|
||||
#ifndef M_PI_2
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef LAMBERTCONIC_H
|
||||
#define LAMBERTCONIC_H
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "ct.h"
|
||||
|
||||
class Ellipsoid;
|
||||
|
||||
class LambertConic1 : public CT
|
||||
{
|
||||
public:
|
||||
|
@ -20,8 +20,10 @@ LinearUnits::LinearUnits(int code)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const LinearUnits &lu)
|
||||
{
|
||||
dbg.nospace() << "LinearUnits(" << lu._f << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -22,7 +22,9 @@ public:
|
||||
{return QPointF(p.x() / _f, p.y() /_f);}
|
||||
|
||||
friend bool operator==(const LinearUnits &lu1, const LinearUnits &lu2);
|
||||
#ifndef QT_NO_DEBUG
|
||||
friend QDebug operator<<(QDebug dbg, const LinearUnits &lu);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
private:
|
||||
double _f;
|
||||
@ -31,6 +33,8 @@ private:
|
||||
inline bool operator==(const LinearUnits &lu1, const LinearUnits &lu2)
|
||||
{return (lu1._f == lu2._f);}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const LinearUnits &lu);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // LINEARUNITS_H
|
||||
|
@ -20,13 +20,12 @@ public:
|
||||
virtual const QString &name() const = 0;
|
||||
|
||||
virtual QRectF bounds() const = 0;
|
||||
virtual qreal resolution(const QPointF &p) const = 0;
|
||||
virtual qreal resolution(const QRectF &rect) const = 0;
|
||||
|
||||
virtual qreal zoom() const = 0;
|
||||
virtual qreal zoomFit(const QSize &size, const RectC &br) = 0;
|
||||
virtual qreal zoomFit(qreal resolution, const Coordinates &c) = 0;
|
||||
virtual qreal zoomIn() = 0;
|
||||
virtual qreal zoomOut() = 0;
|
||||
virtual int zoom() const = 0;
|
||||
virtual int zoomFit(const QSize &size, const RectC &br) = 0;
|
||||
virtual int zoomIn() = 0;
|
||||
virtual int zoomOut() = 0;
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) = 0;
|
||||
virtual Coordinates xy2ll(const QPointF &p) = 0;
|
||||
@ -40,6 +39,9 @@ public:
|
||||
|
||||
void setBackgroundColor(const QColor &color) {_backgroundColor = color;}
|
||||
|
||||
virtual bool isValid() const {return true;}
|
||||
virtual QString errorString() const {return QString();}
|
||||
|
||||
signals:
|
||||
void loaded();
|
||||
|
||||
|
@ -13,7 +13,7 @@ bool MapList::loadSource(const QString &path, bool dir)
|
||||
MapSource ms;
|
||||
Map *map;
|
||||
|
||||
if (!ms.loadFile(path, &map)) {
|
||||
if (!(map = ms.loadFile(path))) {
|
||||
if (dir)
|
||||
_errorString += path + ": " + ms.errorString() + "\n";
|
||||
else
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include <QFile>
|
||||
#include <QXmlStreamReader>
|
||||
#include "onlinemap.h"
|
||||
#include "wmtsmap.h"
|
||||
#include "mapsource.h"
|
||||
|
||||
|
||||
#define ZOOM_MAX 19
|
||||
#define ZOOM_MIN 0
|
||||
#define BOUNDS_LEFT -180
|
||||
@ -11,6 +11,11 @@
|
||||
#define BOUNDS_RIGHT 180
|
||||
#define BOUNDS_BOTTOM -85.0511
|
||||
|
||||
MapSource::TMSConfig::TMSConfig()
|
||||
: zooms(ZOOM_MIN, ZOOM_MAX), bounds(Coordinates(BOUNDS_LEFT, BOUNDS_TOP),
|
||||
Coordinates(BOUNDS_RIGHT, BOUNDS_BOTTOM)) {}
|
||||
|
||||
|
||||
Range MapSource::zooms(QXmlStreamReader &reader)
|
||||
{
|
||||
const QXmlStreamAttributes &attr = reader.attributes();
|
||||
@ -43,7 +48,7 @@ Range MapSource::zooms(QXmlStreamReader &reader)
|
||||
} else
|
||||
max = ZOOM_MAX;
|
||||
|
||||
if (min > max || max < min) {
|
||||
if (min > max) {
|
||||
reader.raiseError("Invalid maximal/minimal zoom level combination");
|
||||
return Range();
|
||||
}
|
||||
@ -109,11 +114,11 @@ RectC MapSource::bounds(QXmlStreamReader &reader)
|
||||
} else
|
||||
right = BOUNDS_RIGHT;
|
||||
|
||||
if (bottom > top || top < bottom) {
|
||||
if (bottom >= top) {
|
||||
reader.raiseError("Invalid bottom/top bounds combination");
|
||||
return RectC();
|
||||
}
|
||||
if (left > right || right < left) {
|
||||
if (left >= right) {
|
||||
reader.raiseError("Invalid left/right bounds combination");
|
||||
return RectC();
|
||||
}
|
||||
@ -121,52 +126,102 @@ RectC MapSource::bounds(QXmlStreamReader &reader)
|
||||
return RectC(Coordinates(left, top), Coordinates(right, bottom));
|
||||
}
|
||||
|
||||
void MapSource::map(QXmlStreamReader &reader, Map **map)
|
||||
void MapSource::map(QXmlStreamReader &reader, Config &config)
|
||||
{
|
||||
QString name, url;
|
||||
Range z(ZOOM_MIN, ZOOM_MAX);
|
||||
RectC b(Coordinates(BOUNDS_LEFT, BOUNDS_TOP),
|
||||
Coordinates(BOUNDS_RIGHT, BOUNDS_BOTTOM));
|
||||
config.type = (reader.attributes().value("type") == "WMTS") ? WMTS : TMS;
|
||||
|
||||
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);
|
||||
config.name = reader.readElementText();
|
||||
else if (reader.name() == "url") {
|
||||
config.wmts.rest = (reader.attributes().value("type") == "REST")
|
||||
? true : false;
|
||||
config.url = reader.readElementText();
|
||||
} else if (reader.name() == "zoom") {
|
||||
config.tms.zooms = zooms(reader);
|
||||
reader.skipCurrentElement();
|
||||
} else if (reader.name() == "bounds") {
|
||||
b = bounds(reader);
|
||||
config.tms.bounds = bounds(reader);
|
||||
reader.skipCurrentElement();
|
||||
} else if (reader.name() == "format") {
|
||||
config.wmts.format = reader.readElementText();
|
||||
} else if (reader.name() == "layer")
|
||||
config.wmts.layer = reader.readElementText();
|
||||
else if (reader.name() == "style")
|
||||
config.wmts.style = reader.readElementText();
|
||||
else if (reader.name() == "set") {
|
||||
config.wmts.yx = (reader.attributes().value("axis") == "yx")
|
||||
? true : false;
|
||||
config.wmts.set = reader.readElementText();
|
||||
} else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
*map = reader.error() ? 0 : new OnlineMap(name, url, z, b);
|
||||
}
|
||||
|
||||
bool MapSource::loadFile(const QString &path, Map **map)
|
||||
Map *MapSource::loadFile(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
QXmlStreamReader reader;
|
||||
Config config;
|
||||
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
_errorString = file.errorString();
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
reader.setDevice(&file);
|
||||
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == "map")
|
||||
MapSource::map(reader, map);
|
||||
map(reader, config);
|
||||
else
|
||||
reader.raiseError("Not an online map source file");
|
||||
}
|
||||
if (reader.error()) {
|
||||
_errorString = QString("%1: %2").arg(reader.lineNumber())
|
||||
.arg(reader.errorString());
|
||||
return 0;
|
||||
}
|
||||
|
||||
_errorString = reader.error() ? QString("%1: %2").arg(reader.lineNumber())
|
||||
.arg(reader.errorString()) : QString();
|
||||
if (config.name.isEmpty()) {
|
||||
_errorString = "Missing name definition";
|
||||
return 0;
|
||||
}
|
||||
if (config.url.isEmpty()) {
|
||||
_errorString = "Missing URL definition";
|
||||
return 0;
|
||||
}
|
||||
if (config.type == WMTS) {
|
||||
if (config.wmts.layer.isEmpty()) {
|
||||
_errorString = "Missing layer definition";
|
||||
return 0;
|
||||
}
|
||||
if (config.wmts.style.isEmpty()) {
|
||||
_errorString = "Missing style definiton";
|
||||
return 0;
|
||||
}
|
||||
if (config.wmts.set.isEmpty()) {
|
||||
_errorString = "Missing set definiton";
|
||||
return 0;
|
||||
}
|
||||
if (config.wmts.format.isEmpty()) {
|
||||
_errorString = "Missing format definition";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return !reader.error();
|
||||
Map *m;
|
||||
if (config.type == WMTS)
|
||||
m = new WMTSMap(config.name, WMTS::Setup(config.url, config.wmts.layer,
|
||||
config.wmts.set, config.wmts.style, config.wmts.format,
|
||||
config.wmts.rest, config.wmts.yx));
|
||||
else
|
||||
m = new OnlineMap(config.name, config.url, config.tms.zooms,
|
||||
config.tms.bounds);
|
||||
if (!m->isValid()) {
|
||||
_errorString = m->errorString();
|
||||
delete m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
@ -11,13 +11,46 @@ class QXmlStreamReader;
|
||||
class MapSource
|
||||
{
|
||||
public:
|
||||
bool loadFile(const QString &path, Map **map);
|
||||
Map *loadFile(const QString &path);
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
TMS,
|
||||
WMTS
|
||||
};
|
||||
|
||||
struct TMSConfig {
|
||||
Range zooms;
|
||||
RectC bounds;
|
||||
|
||||
TMSConfig();
|
||||
};
|
||||
|
||||
struct WMTSConfig {
|
||||
QString layer;
|
||||
QString style;
|
||||
QString set;
|
||||
QString format;
|
||||
bool rest;
|
||||
bool yx;
|
||||
|
||||
WMTSConfig() : format("image/png"), rest(false), yx(false) {}
|
||||
};
|
||||
|
||||
struct Config {
|
||||
QString name;
|
||||
QString url;
|
||||
Type type;
|
||||
WMTSConfig wmts;
|
||||
TMSConfig tms;
|
||||
|
||||
Config() : type(TMS) {}
|
||||
};
|
||||
|
||||
RectC bounds(QXmlStreamReader &reader);
|
||||
Range zooms(QXmlStreamReader &reader);
|
||||
void map(QXmlStreamReader &reader, Map **map);
|
||||
void map(QXmlStreamReader &reader, Config &config);
|
||||
|
||||
QString _errorString;
|
||||
};
|
||||
|
@ -116,6 +116,7 @@ void Matrix::zeroize()
|
||||
_m[i] = 0;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Matrix &matrix)
|
||||
{
|
||||
dbg.nospace() << "Matrix(" << endl;
|
||||
@ -128,3 +129,4 @@ QDebug operator<<(QDebug dbg, const Matrix &matrix)
|
||||
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -31,6 +31,8 @@ private:
|
||||
size_t _w;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Matrix &matrix);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // MATRIX_H
|
||||
|
@ -1,12 +1,16 @@
|
||||
#include <cmath>
|
||||
#include "common/coordinates.h"
|
||||
#include "common/wgs84.h"
|
||||
#include "mercator.h"
|
||||
|
||||
QPointF Mercator::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
return QPointF(c.lon(), rad2deg(log(tan(M_PI/4.0 + deg2rad(c.lat())/2.0))));
|
||||
return QPointF(deg2rad(c.lon()) * WGS84_RADIUS,
|
||||
log(tan(M_PI/4.0 + deg2rad(c.lat())/2.0)) * WGS84_RADIUS);
|
||||
}
|
||||
|
||||
Coordinates Mercator::xy2ll(const QPointF &p) const
|
||||
{
|
||||
return Coordinates(p.x(), rad2deg(2 * atan(exp(deg2rad(p.y()))) - M_PI/2));
|
||||
return Coordinates(rad2deg(p.x() / WGS84_RADIUS),
|
||||
rad2deg(2 * atan(exp(p.y() / WGS84_RADIUS)) - M_PI/2));
|
||||
}
|
||||
|
@ -14,17 +14,6 @@
|
||||
#include "offlinemap.h"
|
||||
|
||||
|
||||
void OfflineMap::computeResolution()
|
||||
{
|
||||
Coordinates tl = xy2ll((bounds().topLeft()));
|
||||
Coordinates br = xy2ll(bounds().bottomRight());
|
||||
|
||||
qreal ds = tl.distanceTo(br);
|
||||
qreal ps = QLineF(bounds().topLeft(), bounds().bottomRight()).length();
|
||||
|
||||
_resolution = ds/ps;
|
||||
}
|
||||
|
||||
bool OfflineMap::getImageInfo(const QString &path)
|
||||
{
|
||||
QFileInfo ii(_imgPath);
|
||||
@ -112,7 +101,6 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
|
||||
_valid = false;
|
||||
_img = 0;
|
||||
_resolution = 0.0;
|
||||
_zoom = 0;
|
||||
_scale = QPointF(1.0, 1.0);
|
||||
|
||||
@ -190,7 +178,6 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
}
|
||||
|
||||
_inverted = _transform.inverted();
|
||||
computeResolution();
|
||||
|
||||
_valid = true;
|
||||
}
|
||||
@ -203,7 +190,6 @@ OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||
|
||||
_valid = false;
|
||||
_img = 0;
|
||||
_resolution = 0.0;
|
||||
_zoom = 0;
|
||||
_scale = QPointF(1.0, 1.0);
|
||||
|
||||
@ -227,9 +213,7 @@ OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||
_size = mf.size();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
|
||||
_inverted = _transform.inverted();
|
||||
computeResolution();
|
||||
|
||||
_tarPath = fi.absolutePath() + "/" + fi.completeBaseName() + ".tar";
|
||||
_valid = true;
|
||||
@ -353,7 +337,7 @@ void OfflineMap::draw(QPainter *painter, const QRectF &rect)
|
||||
painter->fillRect(rect, _backgroundColor);
|
||||
}
|
||||
|
||||
QPointF OfflineMap::ll2xy(const Coordinates &c)
|
||||
QPointF OfflineMap::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
if (_ozf.isOpen()) {
|
||||
QPointF p(_transform.map(_projection.ll2xy(c)));
|
||||
@ -362,7 +346,7 @@ QPointF OfflineMap::ll2xy(const Coordinates &c)
|
||||
return _transform.map(_projection.ll2xy(c));
|
||||
}
|
||||
|
||||
Coordinates OfflineMap::xy2ll(const QPointF &p)
|
||||
Coordinates OfflineMap::xy2ll(const QPointF &p) const
|
||||
{
|
||||
if (_ozf.isOpen()) {
|
||||
return _projection.xy2ll(_inverted.map(QPointF(p.x() / _scale.x(),
|
||||
@ -379,17 +363,18 @@ QRectF OfflineMap::bounds() const
|
||||
return QRectF(QPointF(0, 0), _size);
|
||||
}
|
||||
|
||||
qreal OfflineMap::resolution(const QPointF &p) const
|
||||
qreal OfflineMap::resolution(const QRectF &rect) const
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
Coordinates tl = xy2ll((rect.topLeft()));
|
||||
Coordinates br = xy2ll(rect.bottomRight());
|
||||
|
||||
if (_ozf.isOpen())
|
||||
return _resolution / ((_scale.x() + _scale.y()) / 2.0);
|
||||
else
|
||||
return _resolution;
|
||||
qreal ds = tl.distanceTo(br);
|
||||
qreal ps = QLineF(rect.topLeft(), rect.bottomRight()).length();
|
||||
|
||||
return ds/ps;
|
||||
}
|
||||
|
||||
qreal OfflineMap::zoomFit(const QSize &size, const RectC &br)
|
||||
int OfflineMap::zoomFit(const QSize &size, const RectC &br)
|
||||
{
|
||||
if (_ozf.isOpen()) {
|
||||
if (!br.isValid())
|
||||
@ -411,23 +396,7 @@ qreal OfflineMap::zoomFit(const QSize &size, const RectC &br)
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal OfflineMap::zoomFit(qreal resolution, const Coordinates &c)
|
||||
{
|
||||
Q_UNUSED(c);
|
||||
|
||||
if (_ozf.isOpen()) {
|
||||
for (int i = 0; i < _ozf.zooms(); i++) {
|
||||
rescale(i);
|
||||
qreal sr = _resolution / ((_scale.x() + _scale.y()) / 2.0);
|
||||
if (sr >= resolution)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal OfflineMap::zoomIn()
|
||||
int OfflineMap::zoomIn()
|
||||
{
|
||||
if (_ozf.isOpen())
|
||||
rescale(qMax(_zoom - 1, 0));
|
||||
@ -435,7 +404,7 @@ qreal OfflineMap::zoomIn()
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal OfflineMap::zoomOut()
|
||||
int OfflineMap::zoomOut()
|
||||
{
|
||||
if (_ozf.isOpen())
|
||||
rescale(qMin(_zoom + 1, _ozf.zooms() - 1));
|
||||
|
@ -24,16 +24,17 @@ public:
|
||||
const QString &name() const {return _name;}
|
||||
|
||||
QRectF bounds() const;
|
||||
qreal resolution(const QPointF &p) const;
|
||||
qreal resolution(const QRectF &rect) const;
|
||||
|
||||
qreal zoom() const {return _zoom;}
|
||||
qreal zoomFit(const QSize &size, const RectC &br);
|
||||
qreal zoomFit(qreal resolution, const Coordinates &c);
|
||||
qreal zoomIn();
|
||||
qreal zoomOut();
|
||||
int zoom() const {return _zoom;}
|
||||
int zoomFit(const QSize &size, const RectC &br);
|
||||
int zoomIn();
|
||||
int zoomOut();
|
||||
|
||||
QPointF ll2xy(const Coordinates &c);
|
||||
Coordinates xy2ll(const QPointF &p);
|
||||
QPointF ll2xy(const Coordinates &c)
|
||||
{return static_cast<const OfflineMap &>(*this).ll2xy(c);}
|
||||
Coordinates xy2ll(const QPointF &p)
|
||||
{return static_cast<const OfflineMap &>(*this).xy2ll(p);}
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect);
|
||||
|
||||
@ -41,7 +42,7 @@ public:
|
||||
void unload();
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
const QString &errorString() const {return _errorString;}
|
||||
QString errorString() const {return _errorString;}
|
||||
|
||||
QPointF ll2pp(const Coordinates &c) const
|
||||
{return _projection.ll2xy(c);}
|
||||
@ -51,6 +52,9 @@ public:
|
||||
{return _transform.map(p);}
|
||||
|
||||
private:
|
||||
QPointF ll2xy(const Coordinates &c) const;
|
||||
Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
bool getTileInfo(const QStringList &tiles, const QString &path = QString());
|
||||
bool getImageInfo(const QString &path);
|
||||
bool totalSizeSet();
|
||||
@ -59,7 +63,6 @@ private:
|
||||
void drawOZF(QPainter *painter, const QRectF &rect);
|
||||
void drawImage(QPainter *painter, const QRectF &rect);
|
||||
|
||||
void computeResolution();
|
||||
void rescale(int zoom);
|
||||
|
||||
QString _name;
|
||||
@ -77,7 +80,6 @@ private:
|
||||
QSize _size;
|
||||
|
||||
int _zoom;
|
||||
qreal _resolution;
|
||||
QPointF _scale;
|
||||
|
||||
bool _valid;
|
||||
|
@ -1,10 +1,7 @@
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QPainter>
|
||||
#include "common/coordinates.h"
|
||||
#include "common/rectc.h"
|
||||
#include "common/wgs84.h"
|
||||
#include "mercator.h"
|
||||
#include "downloader.h"
|
||||
#include "config.h"
|
||||
#include "onlinemap.h"
|
||||
@ -12,6 +9,16 @@
|
||||
|
||||
#define TILE_SIZE 256
|
||||
|
||||
static QPointF ll2m(const Coordinates &c)
|
||||
{
|
||||
return QPointF(c.lon(), rad2deg(log(tan(M_PI/4.0 + deg2rad(c.lat())/2.0))));
|
||||
}
|
||||
|
||||
static Coordinates m2ll(const QPointF &p)
|
||||
{
|
||||
return Coordinates(p.x(), rad2deg(2 * atan(exp(deg2rad(p.y()))) - M_PI/2));
|
||||
}
|
||||
|
||||
static QPoint mercator2tile(const QPointF &m, int z)
|
||||
{
|
||||
QPoint tile;
|
||||
@ -32,45 +39,35 @@ static int scale2zoom(qreal scale)
|
||||
return (int)log2(360.0/(scale * (qreal)TILE_SIZE));
|
||||
}
|
||||
|
||||
static bool loadTileFile(Tile &tile, const QString &file)
|
||||
{
|
||||
if (!tile.pixmap().load(file)) {
|
||||
qWarning("%s: error loading tile file\n", qPrintable(file));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Downloader *OnlineMap::downloader;
|
||||
|
||||
OnlineMap::OnlineMap(const QString &name, const QString &url,
|
||||
const Range &zooms, const RectC &bounds, QObject *parent)
|
||||
: Map(parent), _name(name), _url(url), _zooms(zooms), _bounds(bounds)
|
||||
const Range &zooms, const RectC &bounds, QObject *parent) :
|
||||
Map(parent), _name(name), _zooms(zooms), _bounds(bounds),
|
||||
_block(false), _valid(false)
|
||||
{
|
||||
_block = false;
|
||||
_zoom = _zooms.max();
|
||||
QString dir(TILES_DIR + "/" + _name);
|
||||
|
||||
QString path = TILES_DIR + QString("/") + name;
|
||||
if (!QDir().mkpath(path))
|
||||
qWarning("Error creating tiles dir: %s\n", qPrintable(path));
|
||||
_zoom = _zooms.max();
|
||||
_tileLoader = TileLoader(url, dir);
|
||||
|
||||
if (!QDir().mkpath(dir)) {
|
||||
_errorString = "Error creating tiles dir";
|
||||
return;
|
||||
}
|
||||
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
void OnlineMap::load()
|
||||
{
|
||||
connect(downloader, SIGNAL(finished()), this, SLOT(emitLoaded()));
|
||||
connect(TileLoader::downloader(), SIGNAL(finished()), this,
|
||||
SLOT(emitLoaded()));
|
||||
}
|
||||
|
||||
void OnlineMap::unload()
|
||||
{
|
||||
disconnect(downloader, SIGNAL(finished()), this, SLOT(emitLoaded()));
|
||||
}
|
||||
|
||||
void OnlineMap::fillTile(Tile &tile)
|
||||
{
|
||||
tile.pixmap() = QPixmap(TILE_SIZE, TILE_SIZE);
|
||||
tile.pixmap().fill(_backgroundColor);
|
||||
disconnect(TileLoader::downloader(), SIGNAL(finished()), this,
|
||||
SLOT(emitLoaded()));
|
||||
}
|
||||
|
||||
void OnlineMap::emitLoaded()
|
||||
@ -78,91 +75,6 @@ void OnlineMap::emitLoaded()
|
||||
emit loaded();
|
||||
}
|
||||
|
||||
void OnlineMap::loadTilesAsync(QList<Tile> &list)
|
||||
{
|
||||
QList<Download> dl;
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Tile &t = list[i];
|
||||
QString file = tileFile(t);
|
||||
QFileInfo fi(file);
|
||||
|
||||
if (!fi.exists()) {
|
||||
fillTile(t);
|
||||
dl.append(Download(tileUrl(t), file));
|
||||
} else
|
||||
loadTileFile(t, file);
|
||||
}
|
||||
|
||||
if (!dl.empty())
|
||||
downloader->get(dl);
|
||||
}
|
||||
|
||||
void OnlineMap::loadTilesSync(QList<Tile> &list)
|
||||
{
|
||||
QList<Download> dl;
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Tile &t = list[i];
|
||||
QString file = tileFile(t);
|
||||
QFileInfo fi(file);
|
||||
|
||||
if (!fi.exists())
|
||||
dl.append(Download(tileUrl(t), file));
|
||||
else
|
||||
loadTileFile(t, file);
|
||||
}
|
||||
|
||||
if (dl.empty())
|
||||
return;
|
||||
|
||||
QEventLoop wait;
|
||||
connect(downloader, SIGNAL(finished()), &wait, SLOT(quit()));
|
||||
if (downloader->get(dl))
|
||||
wait.exec();
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Tile &t = list[i];
|
||||
|
||||
if (t.pixmap().isNull()) {
|
||||
QString file = tileFile(t);
|
||||
QFileInfo fi(file);
|
||||
|
||||
if (!(fi.exists() && loadTileFile(t, file)))
|
||||
fillTile(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString OnlineMap::tileUrl(const Tile &tile) const
|
||||
{
|
||||
QString url(_url);
|
||||
|
||||
url.replace("$z", QString::number(tile.zoom()));
|
||||
url.replace("$x", QString::number(tile.xy().x()));
|
||||
url.replace("$y", QString::number(tile.xy().y()));
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
QString OnlineMap::tileFile(const Tile &tile) const
|
||||
{
|
||||
QString file = TILES_DIR + QString("/%1/%2-%3-%4").arg(name())
|
||||
.arg(tile.zoom()).arg(tile.xy().x()).arg(tile.xy().y());
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
void OnlineMap::clearCache()
|
||||
{
|
||||
QString path = TILES_DIR + QString("/") + name();
|
||||
QDir dir = QDir(path);
|
||||
QStringList list = dir.entryList();
|
||||
|
||||
for (int i = 0; i < list.count(); i++)
|
||||
dir.remove(list.at(i));
|
||||
}
|
||||
|
||||
QRectF OnlineMap::bounds() const
|
||||
{
|
||||
return QRectF(ll2xy(_bounds.topLeft()), ll2xy(_bounds.bottomRight()));
|
||||
@ -178,13 +90,12 @@ int OnlineMap::limitZoom(int zoom) const
|
||||
return zoom;
|
||||
}
|
||||
|
||||
qreal OnlineMap::zoomFit(const QSize &size, const RectC &br)
|
||||
int OnlineMap::zoomFit(const QSize &size, const RectC &br)
|
||||
{
|
||||
if (!br.isValid())
|
||||
_zoom = _zooms.max();
|
||||
else {
|
||||
QRectF tbr(Mercator().ll2xy(br.topLeft()),
|
||||
Mercator().ll2xy(br.bottomRight()));
|
||||
QRectF tbr(ll2m(br.topLeft()), ll2m(br.bottomRight()));
|
||||
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
|
||||
|
||||
_zoom = limitZoom(scale2zoom(qMax(sc.x(), sc.y())));
|
||||
@ -193,29 +104,21 @@ qreal OnlineMap::zoomFit(const QSize &size, const RectC &br)
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal OnlineMap::zoomFit(qreal resolution, const Coordinates &c)
|
||||
{
|
||||
_zoom = limitZoom((int)log2((WGS84_RADIUS * 2.0 * M_PI
|
||||
* cos(deg2rad(c.lat()))) / (resolution * TILE_SIZE)));
|
||||
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal OnlineMap::resolution(const QPointF &p) const
|
||||
qreal OnlineMap::resolution(const QRectF &rect) const
|
||||
{
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
|
||||
return (WGS84_RADIUS * 2.0 * M_PI * scale / 360.0
|
||||
* cos(2.0 * atan(exp(deg2rad(-p.y() * scale))) - M_PI/2));
|
||||
* cos(2.0 * atan(exp(deg2rad(-rect.center().y() * scale))) - M_PI/2));
|
||||
}
|
||||
|
||||
qreal OnlineMap::zoomIn()
|
||||
int OnlineMap::zoomIn()
|
||||
{
|
||||
_zoom = qMin(_zoom + 1, _zooms.max());
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal OnlineMap::zoomOut()
|
||||
int OnlineMap::zoomOut()
|
||||
{
|
||||
_zoom = qMax(_zoom - 1, _zooms.min());
|
||||
return _zoom;
|
||||
@ -237,28 +140,31 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect)
|
||||
tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), _zoom));
|
||||
|
||||
if (_block)
|
||||
loadTilesSync(tiles);
|
||||
_tileLoader.loadTilesSync(tiles);
|
||||
else
|
||||
loadTilesAsync(tiles);
|
||||
_tileLoader.loadTilesAsync(tiles);
|
||||
|
||||
for (int i = 0; i < tiles.count(); i++) {
|
||||
Tile &t = tiles[i];
|
||||
QPoint tp(tl.x() + (t.xy().x() - tile.x()) * TILE_SIZE,
|
||||
tl.y() + (t.xy().y() - tile.y()) * TILE_SIZE);
|
||||
painter->drawPixmap(tp, t.pixmap());
|
||||
if (t.pixmap().isNull())
|
||||
painter->fillRect(QRect(tp, QSize(TILE_SIZE, TILE_SIZE)),
|
||||
_backgroundColor);
|
||||
else
|
||||
painter->drawPixmap(tp, t.pixmap());
|
||||
}
|
||||
}
|
||||
|
||||
QPointF OnlineMap::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
QPointF m = Mercator().ll2xy(c);
|
||||
QPointF m = ll2m(c);
|
||||
return QPointF(m.x() / scale, m.y() / -scale);
|
||||
}
|
||||
|
||||
Coordinates OnlineMap::xy2ll(const QPointF &p) const
|
||||
{
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
QPointF m(p.x() * scale, -p.y() * scale);
|
||||
return Mercator().xy2ll(m);
|
||||
return m2ll(QPointF(p.x() * scale, -p.y() * scale));
|
||||
}
|
||||
|
@ -5,9 +5,7 @@
|
||||
#include "common/range.h"
|
||||
#include "common/rectc.h"
|
||||
#include "map.h"
|
||||
#include "tile.h"
|
||||
|
||||
class Downloader;
|
||||
#include "tileloader.h"
|
||||
|
||||
class OnlineMap : public Map
|
||||
{
|
||||
@ -20,13 +18,12 @@ public:
|
||||
const QString &name() const {return _name;}
|
||||
|
||||
QRectF bounds() const;
|
||||
qreal resolution(const QPointF &p) const;
|
||||
qreal resolution(const QRectF &rect) const;
|
||||
|
||||
qreal zoom() const {return _zoom;}
|
||||
qreal zoomFit(const QSize &size, const RectC &br);
|
||||
qreal zoomFit(qreal resolution, const Coordinates &c);
|
||||
qreal zoomIn();
|
||||
qreal zoomOut();
|
||||
int zoom() const {return _zoom;}
|
||||
int zoomFit(const QSize &size, const RectC &br);
|
||||
int zoomIn();
|
||||
int zoomOut();
|
||||
|
||||
QPointF ll2xy(const Coordinates &c)
|
||||
{return static_cast<const OnlineMap &>(*this).ll2xy(c);}
|
||||
@ -36,36 +33,31 @@ public:
|
||||
void draw(QPainter *painter, const QRectF &rect);
|
||||
|
||||
void setBlockingMode(bool block) {_block = block;}
|
||||
void clearCache();
|
||||
|
||||
static void setDownloader(Downloader *downloader)
|
||||
{OnlineMap::downloader = downloader;}
|
||||
void clearCache() {_tileLoader.clearCache();}
|
||||
|
||||
void load();
|
||||
void unload();
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
QString errorString() const {return _errorString;}
|
||||
|
||||
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;
|
||||
void loadTilesAsync(QList<Tile> &list);
|
||||
void loadTilesSync(QList<Tile> &list);
|
||||
int limitZoom(int zoom) const;
|
||||
|
||||
TileLoader _tileLoader;
|
||||
QString _name;
|
||||
QString _url;
|
||||
Range _zooms;
|
||||
RectC _bounds;
|
||||
int _zoom;
|
||||
bool _block;
|
||||
|
||||
static Downloader *downloader;
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
};
|
||||
|
||||
#endif // ONLINEMAP_H
|
||||
|
@ -187,9 +187,11 @@ void PCS::loadList(const QString &path)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const PCS &pcs)
|
||||
{
|
||||
dbg.nospace() << "PCS(" << *pcs.gcs() << ", " << pcs.method() << ", "
|
||||
<< pcs.units() << ", " << pcs.setup() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -43,6 +43,8 @@ private:
|
||||
static GCS _nullGCS;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const PCS &pcs);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // PCS_H
|
||||
|
@ -66,8 +66,10 @@ double PrimeMeridian::fromGreenwich(double val) const
|
||||
return shift(val, -_pm);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const PrimeMeridian &pm)
|
||||
{
|
||||
dbg.nospace() << "PrimeMeridian(" << pm._pm << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -17,7 +17,9 @@ public:
|
||||
double fromGreenwich(double val) const;
|
||||
|
||||
friend bool operator==(const PrimeMeridian &pm1, const PrimeMeridian &pm2);
|
||||
#ifndef QT_NO_DEBUG
|
||||
friend QDebug operator<<(QDebug dbg, const PrimeMeridian &pm);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
private:
|
||||
double _pm;
|
||||
@ -26,6 +28,8 @@ private:
|
||||
inline bool operator==(const PrimeMeridian &pm1, const PrimeMeridian &pm2)
|
||||
{return (pm1._pm == pm2._pm);}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const PrimeMeridian &pm);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // PRIMEMERIDIAN_H
|
||||
|
@ -27,7 +27,7 @@ Projection::Method::Method(int id)
|
||||
}
|
||||
|
||||
Projection::Projection(const GCS *gcs, const Method &method, const Setup &setup,
|
||||
const LinearUnits &units) : _gcs(gcs), _units(units)
|
||||
const LinearUnits &units) : _gcs(gcs), _units(units), _geographic(false)
|
||||
{
|
||||
const Ellipsoid *ellipsoid = _gcs->datum().ellipsoid();
|
||||
|
||||
@ -68,7 +68,7 @@ Projection::Projection(const GCS *gcs, const Method &method, const Setup &setup,
|
||||
}
|
||||
}
|
||||
|
||||
Projection::Projection(const GCS *gcs) : _gcs(gcs)
|
||||
Projection::Projection(const GCS *gcs) : _gcs(gcs), _geographic(true)
|
||||
{
|
||||
_ct = new LatLon(gcs->angularUnits());
|
||||
_units = LinearUnits(9001);
|
||||
@ -79,6 +79,7 @@ Projection::Projection(const Projection &p)
|
||||
_gcs = p._gcs;
|
||||
_units = p._units;
|
||||
_ct = p._ct->clone();
|
||||
_geographic = p._geographic;
|
||||
}
|
||||
|
||||
Projection::~Projection()
|
||||
@ -91,6 +92,7 @@ Projection &Projection::operator=(const Projection &p)
|
||||
_gcs = p._gcs;
|
||||
_units = p._units;
|
||||
_ct = p._ct->clone();
|
||||
_geographic = p._geographic;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -105,6 +107,7 @@ Coordinates Projection::xy2ll(const QPointF &p) const
|
||||
return _gcs->toWGS84(_ct->xy2ll(_units.toMeters(p)));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Projection::Setup &setup)
|
||||
{
|
||||
dbg.nospace() << "Setup(" << setup.latitudeOrigin() << ", "
|
||||
@ -119,3 +122,4 @@ QDebug operator<<(QDebug dbg, const Projection::Method &method)
|
||||
dbg.nospace() << "Method(" << method.id() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
int _id;
|
||||
};
|
||||
|
||||
Projection() : _gcs(0), _ct(0) {}
|
||||
Projection() : _gcs(0), _ct(0), _geographic(false) {}
|
||||
Projection(const Projection &p);
|
||||
Projection(const GCS *gcs, const Method &method, const Setup &setup,
|
||||
const LinearUnits &units);
|
||||
@ -77,16 +77,25 @@ public:
|
||||
|
||||
Projection &operator=(const Projection &p);
|
||||
|
||||
bool isNull() const {return (_gcs == 0 && _ct == 0 && _units.isNull());}
|
||||
bool isValid() const {return (_gcs == 0 || _ct == 0 || _units.isNull());}
|
||||
bool isGeographic() const {return _geographic;}
|
||||
|
||||
QPointF ll2xy(const Coordinates &c) const;
|
||||
Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
const LinearUnits &units() const {return _units;}
|
||||
|
||||
private:
|
||||
const GCS * _gcs;
|
||||
CT *_ct;
|
||||
LinearUnits _units;
|
||||
bool _geographic;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Projection::Setup &setup);
|
||||
QDebug operator<<(QDebug dbg, const Projection::Method &method);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // PROJECTION_H
|
||||
|
@ -8,23 +8,25 @@
|
||||
class Tile
|
||||
{
|
||||
public:
|
||||
Tile(const QPoint &xy, int zoom)
|
||||
Tile(const QPoint &xy, const QVariant &zoom)
|
||||
{_xy = xy; _zoom = zoom;}
|
||||
|
||||
int zoom() const {return _zoom;}
|
||||
QVariant zoom() const {return _zoom;}
|
||||
const QPoint& xy() const {return _xy;}
|
||||
QPixmap& pixmap() {return _pixmap;}
|
||||
|
||||
private:
|
||||
int _zoom;
|
||||
QVariant _zoom;
|
||||
QPoint _xy;
|
||||
QPixmap _pixmap;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
inline QDebug operator<<(QDebug dbg, const Tile &tile)
|
||||
{
|
||||
dbg.nospace() << "Tile(" << tile.zoom() << ", " << tile.xy() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // TILE_H
|
||||
|
99
src/map/tileloader.cpp
Normal file
99
src/map/tileloader.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QEventLoop>
|
||||
#include "downloader.h"
|
||||
#include "tileloader.h"
|
||||
|
||||
|
||||
static bool loadTileFile(Tile &tile, const QString &file)
|
||||
{
|
||||
if (!tile.pixmap().load(file)) {
|
||||
qWarning("%s: error loading tile file\n", qPrintable(file));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Downloader *TileLoader::_downloader = 0;
|
||||
|
||||
void TileLoader::loadTilesAsync(QList<Tile> &list)
|
||||
{
|
||||
QList<Download> dl;
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Tile &t = list[i];
|
||||
QString file = tileFile(t);
|
||||
QFileInfo fi(file);
|
||||
|
||||
if (!fi.exists())
|
||||
dl.append(Download(tileUrl(t), file));
|
||||
else
|
||||
loadTileFile(t, file);
|
||||
}
|
||||
|
||||
if (!dl.empty())
|
||||
_downloader->get(dl);
|
||||
}
|
||||
|
||||
void TileLoader::loadTilesSync(QList<Tile> &list)
|
||||
{
|
||||
QList<Download> dl;
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Tile &t = list[i];
|
||||
QString file = tileFile(t);
|
||||
QFileInfo fi(file);
|
||||
|
||||
if (!fi.exists())
|
||||
dl.append(Download(tileUrl(t), file));
|
||||
else
|
||||
loadTileFile(t, file);
|
||||
}
|
||||
|
||||
if (dl.empty())
|
||||
return;
|
||||
|
||||
QEventLoop wait;
|
||||
QObject::connect(_downloader, SIGNAL(finished()), &wait, SLOT(quit()));
|
||||
if (_downloader->get(dl))
|
||||
wait.exec();
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Tile &t = list[i];
|
||||
|
||||
if (t.pixmap().isNull()) {
|
||||
QString file = tileFile(t);
|
||||
if (QFileInfo(file).exists())
|
||||
loadTileFile(t, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileLoader::clearCache()
|
||||
{
|
||||
QDir dir = QDir(_dir);
|
||||
QStringList list = dir.entryList();
|
||||
|
||||
for (int i = 0; i < list.count(); i++)
|
||||
dir.remove(list.at(i));
|
||||
}
|
||||
|
||||
QString TileLoader::tileUrl(const Tile &tile) const
|
||||
{
|
||||
QString url(_url);
|
||||
|
||||
url.replace("$z", tile.zoom().toString());
|
||||
url.replace("$x", QString::number(tile.xy().x()));
|
||||
url.replace("$y", QString::number(tile.xy().y()));
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
QString TileLoader::tileFile(const Tile &tile) const
|
||||
{
|
||||
QString file = _dir + QString("/%1-%2-%3").arg(tile.zoom().toString())
|
||||
.arg(tile.xy().x()).arg(tile.xy().y());
|
||||
|
||||
return file;
|
||||
}
|
34
src/map/tileloader.h
Normal file
34
src/map/tileloader.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef TILELOADER_H
|
||||
#define TILELOADER_H
|
||||
|
||||
#include <QString>
|
||||
#include "tile.h"
|
||||
#include "downloader.h"
|
||||
|
||||
class TileLoader
|
||||
{
|
||||
public:
|
||||
TileLoader() {}
|
||||
TileLoader(const QString &url, const QString &dir)
|
||||
: _url(url), _dir(dir) {}
|
||||
|
||||
void loadTilesAsync(QList<Tile> &list);
|
||||
void loadTilesSync(QList<Tile> &list);
|
||||
void clearCache();
|
||||
|
||||
static Downloader *downloader() {return _downloader;}
|
||||
static void setDownloader(Downloader *downloader)
|
||||
{_downloader = downloader;}
|
||||
|
||||
private:
|
||||
void fillTile(Tile &tile);
|
||||
QString tileUrl(const Tile &tile) const;
|
||||
QString tileFile(const Tile &tile) const;
|
||||
|
||||
QString _url;
|
||||
QString _dir;
|
||||
|
||||
static Downloader *_downloader;
|
||||
};
|
||||
|
||||
#endif // TILELOADER_Honlinemap
|
@ -73,8 +73,10 @@ Transform::Transform(const QList<ReferencePoint> &points)
|
||||
affine(points);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const ReferencePoint &p)
|
||||
{
|
||||
dbg.nospace() << "ReferencePoint(" << p.xy << ", " << p.pp << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -27,6 +27,8 @@ private:
|
||||
QString _errorString;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const ReferencePoint &p);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // TRANSFORM_H
|
||||
|
@ -2,7 +2,8 @@
|
||||
#define TRANSVERSEMERCATOR_H
|
||||
|
||||
#include "ct.h"
|
||||
#include "ellipsoid.h"
|
||||
|
||||
class Ellipsoid;
|
||||
|
||||
class TransverseMercator : public CT
|
||||
{
|
||||
|
412
src/map/wmts.cpp
Normal file
412
src/map/wmts.cpp
Normal file
@ -0,0 +1,412 @@
|
||||
#include <QXmlStreamReader>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QEventLoop>
|
||||
#include <QTextStream>
|
||||
#include <QStringList>
|
||||
#include <QtAlgorithms>
|
||||
#include <QXmlStreamReader>
|
||||
#include "downloader.h"
|
||||
#include "pcs.h"
|
||||
#include "wmts.h"
|
||||
|
||||
|
||||
Downloader *WMTS::_downloader = 0;
|
||||
|
||||
bool WMTS::createProjection(const QString &crs)
|
||||
{
|
||||
QStringList list(crs.split(':'));
|
||||
QString authority, code;
|
||||
bool res;
|
||||
int epsg;
|
||||
const PCS *pcs;
|
||||
const GCS *gcs;
|
||||
|
||||
switch (list.size()) {
|
||||
case 2:
|
||||
authority = list.at(0);
|
||||
code = list.at(1);
|
||||
break;
|
||||
case 7:
|
||||
authority = list.at(4);
|
||||
code = list.at(6);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (authority == "EPSG") {
|
||||
epsg = code.toInt(&res);
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
if ((pcs = PCS::pcs(epsg))) {
|
||||
_projection = Projection(pcs->gcs(), pcs->method(), pcs->setup(),
|
||||
pcs->units());
|
||||
return true;
|
||||
} else if ((gcs = GCS::gcs(epsg))) {
|
||||
_projection = Projection(gcs);
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
} else if (authority == "OGC") {
|
||||
if (code == "CRS84") {
|
||||
_projection = Projection(GCS::gcs(4326));
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
WMTS::TileMatrix WMTS::tileMatrix(QXmlStreamReader &reader, bool yx)
|
||||
{
|
||||
TileMatrix matrix;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "Identifier")
|
||||
matrix.id = reader.readElementText();
|
||||
else if (reader.name() == "ScaleDenominator")
|
||||
matrix.scaleDenominator = reader.readElementText().toDouble();
|
||||
else if (reader.name() == "TopLeftCorner") {
|
||||
QString str = reader.readElementText();
|
||||
QTextStream ts(&str);
|
||||
if (yx)
|
||||
ts >> matrix.topLeft.ry() >> matrix.topLeft.rx();
|
||||
else
|
||||
ts >> matrix.topLeft.rx() >> matrix.topLeft.ry();
|
||||
} else if (reader.name() == "TileWidth")
|
||||
matrix.tile.setWidth(reader.readElementText().toInt());
|
||||
else if (reader.name() == "TileHeight")
|
||||
matrix.tile.setHeight(reader.readElementText().toInt());
|
||||
else if (reader.name() == "MatrixWidth")
|
||||
matrix.matrix.setWidth(reader.readElementText().toInt());
|
||||
else if (reader.name() == "MatrixHeight")
|
||||
matrix.matrix.setHeight(reader.readElementText().toInt());
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
if (!matrix.isValid())
|
||||
reader.raiseError("Invalid TileMatrix definition");
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
void WMTS::tileMatrixSet(QXmlStreamReader &reader, CTX &ctx)
|
||||
{
|
||||
QString id, crs;
|
||||
QSet<TileMatrix> matrixes;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "Identifier")
|
||||
id = reader.readElementText();
|
||||
else if (reader.name() == "SupportedCRS")
|
||||
crs = reader.readElementText();
|
||||
else if (reader.name() == "TileMatrix")
|
||||
matrixes.insert(tileMatrix(reader, ctx.setup.yx));
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
if (id == ctx.setup.set) {
|
||||
ctx.crs = crs;
|
||||
_matrixes = matrixes;
|
||||
}
|
||||
}
|
||||
|
||||
WMTS::MatrixLimits WMTS::tileMatrixLimits(QXmlStreamReader &reader)
|
||||
{
|
||||
MatrixLimits limits;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "TileMatrix")
|
||||
limits.id = reader.readElementText();
|
||||
else if (reader.name() == "MinTileRow")
|
||||
limits.rect.setTop(reader.readElementText().toInt());
|
||||
else if (reader.name() == "MaxTileRow")
|
||||
limits.rect.setBottom(reader.readElementText().toInt());
|
||||
else if (reader.name() == "MinTileCol")
|
||||
limits.rect.setLeft(reader.readElementText().toInt());
|
||||
else if (reader.name() == "MaxTileCol")
|
||||
limits.rect.setRight(reader.readElementText().toInt());
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
if (!limits.isValid())
|
||||
reader.raiseError("Invalid TileMatrixLimits definition");
|
||||
|
||||
return limits;
|
||||
}
|
||||
|
||||
QSet<WMTS::MatrixLimits> WMTS::tileMatrixSetLimits(QXmlStreamReader &reader)
|
||||
{
|
||||
QSet<MatrixLimits> limits;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "TileMatrixLimits")
|
||||
limits.insert(tileMatrixLimits(reader));
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
return limits;
|
||||
}
|
||||
|
||||
void WMTS::tileMatrixSetLink(QXmlStreamReader &reader, CTX &ctx)
|
||||
{
|
||||
QString id;
|
||||
QSet<MatrixLimits> limits;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "TileMatrixSet")
|
||||
id = reader.readElementText();
|
||||
else if (reader.name() == "TileMatrixSetLimits")
|
||||
limits = tileMatrixSetLimits(reader);
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
if (id == ctx.setup.set) {
|
||||
ctx.set = true;
|
||||
_limits = limits;
|
||||
}
|
||||
}
|
||||
|
||||
RectC WMTS::wgs84BoundingBox(QXmlStreamReader &reader)
|
||||
{
|
||||
Coordinates topLeft, bottomRight;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "LowerCorner") {
|
||||
QString str = reader.readElementText();
|
||||
QTextStream(&str) >> topLeft.rlon() >> bottomRight.rlat();
|
||||
} else if (reader.name() == "UpperCorner") {
|
||||
QString str = reader.readElementText();
|
||||
QTextStream(&str) >> bottomRight.rlon() >> topLeft.rlat();
|
||||
} else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
return RectC(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
QString WMTS::style(QXmlStreamReader &reader)
|
||||
{
|
||||
QString id;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "Identifier")
|
||||
id = reader.readElementText();
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void WMTS::layer(QXmlStreamReader &reader, CTX &ctx)
|
||||
{
|
||||
QString id, tpl;
|
||||
RectC bounds;
|
||||
QStringList formats, styles;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "Identifier")
|
||||
id = reader.readElementText();
|
||||
else if (reader.name() == "TileMatrixSetLink")
|
||||
tileMatrixSetLink(reader, ctx);
|
||||
else if (reader.name() == "WGS84BoundingBox")
|
||||
bounds = wgs84BoundingBox(reader);
|
||||
else if (reader.name() == "ResourceURL") {
|
||||
const QXmlStreamAttributes &attr = reader.attributes();
|
||||
if (attr.value("resourceType") == "tile")
|
||||
tpl = attr.value("template").toString();
|
||||
reader.skipCurrentElement();
|
||||
} else if (reader.name() == "Style")
|
||||
styles.append(style(reader));
|
||||
else if (reader.name() == "Format")
|
||||
formats.append(reader.readElementText());
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
if (id == ctx.setup.layer) {
|
||||
ctx.layer = true;
|
||||
_bounds = bounds;
|
||||
if (ctx.setup.rest)
|
||||
_tileUrl = tpl;
|
||||
if (styles.contains(ctx.setup.style))
|
||||
ctx.style = true;
|
||||
if (formats.contains(ctx.setup.format))
|
||||
ctx.format = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WMTS::contents(QXmlStreamReader &reader, CTX &ctx)
|
||||
{
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "TileMatrixSet")
|
||||
tileMatrixSet(reader, ctx);
|
||||
else if (reader.name() == "Layer")
|
||||
layer(reader, ctx);
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
void WMTS::capabilities(QXmlStreamReader &reader, CTX &ctx)
|
||||
{
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "Contents")
|
||||
contents(reader, ctx);
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
bool WMTS::parseCapabilities(const QString &path, const Setup &setup)
|
||||
{
|
||||
QFile file(path);
|
||||
CTX ctx(setup);
|
||||
QXmlStreamReader reader;
|
||||
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
_errorString = file.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
reader.setDevice(&file);
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == "Capabilities")
|
||||
capabilities(reader, ctx);
|
||||
else
|
||||
reader.raiseError("Not a Capabilities XML file");
|
||||
}
|
||||
if (reader.error()) {
|
||||
_errorString = QString("%1:%2: %3").arg(path).arg(reader.lineNumber())
|
||||
.arg(reader.errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ctx.layer) {
|
||||
_errorString = ctx.setup.layer + ": layer not provided";
|
||||
return false;
|
||||
}
|
||||
if (!ctx.style) {
|
||||
_errorString = ctx.setup.style + ": style not provided";
|
||||
return false;
|
||||
}
|
||||
if (!ctx.setup.rest && !ctx.format) {
|
||||
_errorString = ctx.setup.format + ": format not provided";
|
||||
return false;
|
||||
}
|
||||
if (!ctx.set) {
|
||||
_errorString = ctx.setup.set + ": set not provided";
|
||||
return false;
|
||||
}
|
||||
if (ctx.crs.isNull()) {
|
||||
_errorString = "Missing CRS definition";
|
||||
return false;
|
||||
}
|
||||
if (!createProjection(ctx.crs)) {
|
||||
_errorString = ctx.crs + ": unknown CRS";
|
||||
return false;
|
||||
}
|
||||
if (_matrixes.isEmpty()) {
|
||||
_errorString = "No usable tile matrix found";
|
||||
return false;
|
||||
}
|
||||
if (ctx.setup.rest && _tileUrl.isNull()) {
|
||||
_errorString = "Missing tile URL template";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WMTS::getCapabilities(const QString &url, const QString &file)
|
||||
{
|
||||
QList<Download> dl;
|
||||
|
||||
dl.append(Download(url, file));
|
||||
|
||||
QEventLoop wait;
|
||||
QObject::connect(_downloader, SIGNAL(finished()), &wait, SLOT(quit()));
|
||||
if (_downloader->get(dl))
|
||||
wait.exec();
|
||||
|
||||
if (QFileInfo(file).exists())
|
||||
return true;
|
||||
else {
|
||||
_errorString = "Error downloading capabilities XML file";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool WMTS::load(const QString &file, const WMTS::Setup &setup)
|
||||
{
|
||||
QString capaUrl = setup.rest ? setup.url :
|
||||
QString("%1?service=WMTS&Version=1.0.0&request=GetCapabilities")
|
||||
.arg(setup.url);
|
||||
|
||||
if (!QFileInfo(file).exists())
|
||||
if (!getCapabilities(capaUrl, file))
|
||||
return false;
|
||||
if (!parseCapabilities(file, setup))
|
||||
return false;
|
||||
|
||||
if (!setup.rest)
|
||||
_tileUrl = QString("%1?service=WMTS&Version=1.0.0&request=GetTile"
|
||||
"&Format=%2&Layer=%3&Style=%4&TileMatrixSet=%5&TileMatrix=$z"
|
||||
"&TileRow=$y&TileCol=$x").arg(setup.url).arg(setup.format)
|
||||
.arg(setup.layer).arg(setup.style).arg(setup.set);
|
||||
else {
|
||||
_tileUrl.replace("{Style}", setup.style);
|
||||
_tileUrl.replace("{TileMatrixSet}", setup.set);
|
||||
_tileUrl.replace("{TileMatrix}", "$z");
|
||||
_tileUrl.replace("{TileRow}", "$y");
|
||||
_tileUrl.replace("{TileCol}", "$x");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<WMTS::Zoom> WMTS::zooms() const
|
||||
{
|
||||
QList<Zoom> zooms;
|
||||
QSet<TileMatrix>::const_iterator mi;
|
||||
QSet<MatrixLimits>::const_iterator li;
|
||||
|
||||
for (mi = _matrixes.constBegin(); mi != _matrixes.constEnd(); ++mi) {
|
||||
if ((li = _limits.find(MatrixLimits(mi->id))) == _limits.constEnd())
|
||||
zooms.append(Zoom(mi->id, mi->scaleDenominator, mi->topLeft,
|
||||
mi->tile, mi->matrix, QRect()));
|
||||
else
|
||||
zooms.append(Zoom(Zoom(mi->id, mi->scaleDenominator, mi->topLeft,
|
||||
mi->tile, mi->matrix, li->rect)));
|
||||
}
|
||||
|
||||
qSort(zooms);
|
||||
|
||||
return zooms;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const WMTS::Setup &setup)
|
||||
{
|
||||
dbg.nospace() << "Setup(" << setup.url << ", " << setup.layer << ", "
|
||||
<< setup.set << ", " << setup.style << ", " << setup.format << ", "
|
||||
<< setup.rest << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const WMTS::Zoom &zoom)
|
||||
{
|
||||
dbg.nospace() << "Zoom(" << zoom.id << ", " << zoom.scaleDenominator << ", "
|
||||
<< zoom.topLeft << ", " << zoom.tile << ", " << zoom.matrix << ", "
|
||||
<< zoom.limits << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
145
src/map/wmts.h
Normal file
145
src/map/wmts.h
Normal file
@ -0,0 +1,145 @@
|
||||
#ifndef WMTS_H
|
||||
#define WMTS_H
|
||||
|
||||
#include <QSize>
|
||||
#include <QRect>
|
||||
#include <QSet>
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
#include "common/rectc.h"
|
||||
#include "projection.h"
|
||||
|
||||
class Downloader;
|
||||
class QXmlStreamReader;
|
||||
|
||||
class WMTS
|
||||
{
|
||||
public:
|
||||
struct Setup {
|
||||
QString url;
|
||||
QString layer;
|
||||
QString set;
|
||||
QString style;
|
||||
QString format;
|
||||
bool rest;
|
||||
bool yx;
|
||||
|
||||
Setup(const QString &url, const QString &layer, const QString &set,
|
||||
const QString &style, const QString &format, bool rest, bool yx) :
|
||||
url(url), layer(layer), set(set), style(style), format(format),
|
||||
rest(rest), yx(yx) {}
|
||||
};
|
||||
|
||||
struct Zoom {
|
||||
QString id;
|
||||
qreal scaleDenominator;
|
||||
QPointF topLeft;
|
||||
QSize tile;
|
||||
QSize matrix;
|
||||
QRect limits;
|
||||
|
||||
Zoom() {}
|
||||
Zoom(const QString &id, qreal scaleDenominator, const QPointF &topLeft,
|
||||
const QSize &tile, const QSize &matrix, const QRect &limits) :
|
||||
id(id), scaleDenominator(scaleDenominator), topLeft(topLeft),
|
||||
tile(tile), matrix(matrix), limits(limits) {}
|
||||
bool operator<(const Zoom &other) const
|
||||
{return scaleDenominator > other.scaleDenominator;}
|
||||
};
|
||||
|
||||
bool load(const QString &path, const Setup &setup);
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
const RectC &bounds() const {return _bounds;}
|
||||
QList<Zoom> zooms() const;
|
||||
const Projection &projection() const {return _projection;}
|
||||
QString tileUrl() const {return _tileUrl;}
|
||||
|
||||
static Downloader *downloader() {return _downloader;}
|
||||
static void setDownloader(Downloader *downloader)
|
||||
{_downloader = downloader;}
|
||||
|
||||
private:
|
||||
struct TileMatrix {
|
||||
QString id;
|
||||
qreal scaleDenominator;
|
||||
QPointF topLeft;
|
||||
QSize tile;
|
||||
QSize matrix;
|
||||
|
||||
TileMatrix() : scaleDenominator(0) {}
|
||||
bool operator==(const TileMatrix &other) const
|
||||
{return this->id == other.id;}
|
||||
bool isValid() const
|
||||
{return !id.isEmpty() && scaleDenominator > 0 && tile.isValid()
|
||||
&& matrix.isValid();}
|
||||
};
|
||||
|
||||
struct MatrixLimits {
|
||||
QString id;
|
||||
QRect rect;
|
||||
|
||||
MatrixLimits() {}
|
||||
MatrixLimits(const QString &id) : id(id) {}
|
||||
bool operator==(const MatrixLimits &other) const
|
||||
{return this->id == other.id;}
|
||||
bool isValid() const
|
||||
{return !id.isEmpty() && rect.isValid();}
|
||||
};
|
||||
|
||||
struct CTX {
|
||||
const Setup &setup;
|
||||
QString crs;
|
||||
bool layer;
|
||||
bool style;
|
||||
bool format;
|
||||
bool set;
|
||||
|
||||
CTX(const Setup &setup) : setup(setup), layer(false), style(false),
|
||||
format(false), set(false) {}
|
||||
};
|
||||
|
||||
RectC wgs84BoundingBox(QXmlStreamReader &reader);
|
||||
MatrixLimits tileMatrixLimits(QXmlStreamReader &reader);
|
||||
TileMatrix tileMatrix(QXmlStreamReader &reader, bool yx);
|
||||
QSet<MatrixLimits> tileMatrixSetLimits(QXmlStreamReader &reader);
|
||||
QString style(QXmlStreamReader &reader);
|
||||
void tileMatrixSet(QXmlStreamReader &reader, CTX &ctx);
|
||||
void tileMatrixSetLink(QXmlStreamReader &reader, CTX &ctx);
|
||||
void layer(QXmlStreamReader &reader, CTX &ctx);
|
||||
void contents(QXmlStreamReader &reader, CTX &ctx);
|
||||
void capabilities(QXmlStreamReader &reader, CTX &ctx);
|
||||
bool parseCapabilities(const QString &path, const Setup &setup);
|
||||
bool getCapabilities(const QString &url, const QString &file);
|
||||
bool createProjection(const QString &crs);
|
||||
|
||||
QSet<TileMatrix> _matrixes;
|
||||
QSet<MatrixLimits> _limits;
|
||||
RectC _bounds;
|
||||
Projection _projection;
|
||||
QString _tileUrl;
|
||||
|
||||
QString _errorString;
|
||||
|
||||
static Downloader *_downloader;
|
||||
|
||||
friend uint qHash(const WMTS::TileMatrix &key);
|
||||
friend uint qHash(const WMTS::MatrixLimits &key);
|
||||
};
|
||||
|
||||
inline uint qHash(const WMTS::TileMatrix &key)
|
||||
{
|
||||
return ::qHash(key.id);
|
||||
}
|
||||
|
||||
inline uint qHash(const WMTS::MatrixLimits &key)
|
||||
{
|
||||
return ::qHash(key.id);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const WMTS::Setup &setup);
|
||||
QDebug operator<<(QDebug dbg, const WMTS::Zoom &zoom);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // WMTS_H
|
206
src/map/wmtsmap.cpp
Normal file
206
src/map/wmtsmap.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
#include <QPainter>
|
||||
#include "common/rectc.h"
|
||||
#include "common/wgs84.h"
|
||||
#include "config.h"
|
||||
#include "transform.h"
|
||||
#include "wmts.h"
|
||||
#include "wmtsmap.h"
|
||||
|
||||
|
||||
#define CAPABILITIES_FILE "capabilities.xml"
|
||||
|
||||
WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, QObject *parent)
|
||||
: Map(parent), _name(name), _setup(setup), _zoom(0), _valid(false)
|
||||
{
|
||||
QString dir(TILES_DIR + "/" + _name);
|
||||
QString file = dir + "/" + CAPABILITIES_FILE;
|
||||
|
||||
if (!QDir().mkpath(dir)) {
|
||||
_errorString = "Error creating tiles dir";
|
||||
return;
|
||||
}
|
||||
|
||||
WMTS wmts;
|
||||
if (!wmts.load(file, _setup)) {
|
||||
_errorString = wmts.errorString();
|
||||
return;
|
||||
}
|
||||
_bounds = wmts.bounds();
|
||||
_zooms = wmts.zooms();
|
||||
_projection = wmts.projection();
|
||||
_tileLoader = TileLoader(wmts.tileUrl(), dir);
|
||||
updateTransform();
|
||||
|
||||
_block = false;
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
qreal WMTSMap::sd2res(qreal scaleDenominator) const
|
||||
{
|
||||
return scaleDenominator * 0.28e-3 * _projection.units().fromMeters(1.0);
|
||||
}
|
||||
|
||||
void WMTSMap::updateTransform()
|
||||
{
|
||||
const WMTS::Zoom &z = _zooms.at(_zoom);
|
||||
ReferencePoint tl, br;
|
||||
|
||||
qreal pixelSpan = sd2res(z.scaleDenominator);
|
||||
if (_projection.isGeographic())
|
||||
pixelSpan /= deg2rad(WGS84_RADIUS);
|
||||
QPointF tileSpan(z.tile.width() * pixelSpan, z.tile.height() * pixelSpan);
|
||||
QPointF bottomRight(z.topLeft.x() + tileSpan.x() * z.matrix.width(),
|
||||
z.topLeft.y() - tileSpan.y() * z.matrix.height());
|
||||
|
||||
tl.xy = QPoint(0, 0);
|
||||
tl.pp = z.topLeft;
|
||||
br.xy = QPoint(z.tile.width() * z.matrix.width(),
|
||||
z.tile.height() * z.matrix.height());
|
||||
br.pp = bottomRight;
|
||||
|
||||
QList<ReferencePoint> points;
|
||||
points << tl << br;
|
||||
Transform tr(points);
|
||||
_transform = tr.transform();
|
||||
_inverted = _transform.inverted();
|
||||
}
|
||||
|
||||
void WMTSMap::load()
|
||||
{
|
||||
connect(TileLoader::downloader(), SIGNAL(finished()), this,
|
||||
SLOT(emitLoaded()));
|
||||
}
|
||||
|
||||
void WMTSMap::unload()
|
||||
{
|
||||
disconnect(TileLoader::downloader(), SIGNAL(finished()), this,
|
||||
SLOT(emitLoaded()));
|
||||
}
|
||||
|
||||
void WMTSMap::clearCache()
|
||||
{
|
||||
QString dir(TILES_DIR + "/" + _name);
|
||||
QString file = dir + "/" + CAPABILITIES_FILE;
|
||||
|
||||
_tileLoader.clearCache();
|
||||
|
||||
WMTS wmts;
|
||||
if (!wmts.load(file, _setup))
|
||||
return;
|
||||
_bounds = wmts.bounds();
|
||||
_zooms = wmts.zooms();
|
||||
_projection = wmts.projection();
|
||||
_tileLoader = TileLoader(wmts.tileUrl(), dir);
|
||||
|
||||
if (_zoom >= _zooms.size())
|
||||
_zoom = _zooms.size() - 1;
|
||||
updateTransform();
|
||||
}
|
||||
|
||||
void WMTSMap::emitLoaded()
|
||||
{
|
||||
emit loaded();
|
||||
}
|
||||
|
||||
QRectF WMTSMap::bounds() const
|
||||
{
|
||||
const WMTS::Zoom &z = _zooms.at(_zoom);
|
||||
QRectF tileBounds, bounds;
|
||||
|
||||
tileBounds = (z.limits.isNull()) ?
|
||||
QRectF(QPointF(0, 0), QSize(z.tile.width() * z.matrix.width(),
|
||||
z.tile.height() * z.matrix.height())) : QRectF(QPointF(z.limits.left()
|
||||
* z.tile.width(), z.limits.top() * z.tile.height()), QSize(z.tile.width()
|
||||
* z.limits.width(), z.tile.height() * z.limits.height()));
|
||||
|
||||
bounds = _bounds.isValid() ? QRectF(ll2xy(_bounds.topLeft()),
|
||||
ll2xy(_bounds.bottomRight())) : QRectF();
|
||||
|
||||
return _bounds.isValid() ? tileBounds.intersected(bounds) : tileBounds;
|
||||
}
|
||||
|
||||
int WMTSMap::zoomFit(const QSize &size, const RectC &br)
|
||||
{
|
||||
if (br.isValid()) {
|
||||
QRectF tbr(_projection.ll2xy(br.topLeft()),
|
||||
_projection.ll2xy(br.bottomRight()));
|
||||
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
|
||||
qreal resolution = qMax(qAbs(sc.x()), qAbs(sc.y()));
|
||||
if (_projection.isGeographic())
|
||||
resolution *= deg2rad(WGS84_RADIUS);
|
||||
|
||||
_zoom = 0;
|
||||
for (int i = 0; i < _zooms.size(); i++) {
|
||||
if (sd2res(_zooms.at(i).scaleDenominator) < resolution)
|
||||
break;
|
||||
_zoom = i;
|
||||
}
|
||||
} else
|
||||
_zoom = _zooms.size() - 1;
|
||||
|
||||
updateTransform();
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal WMTSMap::resolution(const QRectF &rect) const
|
||||
{
|
||||
Coordinates tl = xy2ll((rect.topLeft()));
|
||||
Coordinates br = xy2ll(rect.bottomRight());
|
||||
|
||||
qreal ds = tl.distanceTo(br);
|
||||
qreal ps = QLineF(rect.topLeft(), rect.bottomRight()).length();
|
||||
|
||||
return ds/ps;
|
||||
}
|
||||
|
||||
int WMTSMap::zoomIn()
|
||||
{
|
||||
_zoom = qMin(_zoom + 1, _zooms.size() - 1);
|
||||
updateTransform();
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
int WMTSMap::zoomOut()
|
||||
{
|
||||
_zoom = qMax(_zoom - 1, 0);
|
||||
updateTransform();
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
void WMTSMap::draw(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
const WMTS::Zoom &z = _zooms.at(_zoom);
|
||||
QPoint tl = QPoint((int)floor(rect.left() / (qreal)z.tile.width()),
|
||||
(int)floor(rect.top() / (qreal)z.tile.height()));
|
||||
QPoint br = QPoint((int)ceil(rect.right() / (qreal)z.tile.width()),
|
||||
(int)ceil(rect.bottom() / (qreal)z.tile.height()));
|
||||
|
||||
QList<Tile> tiles;
|
||||
for (int i = tl.x(); i < br.x(); i++)
|
||||
for (int j = tl.y(); j < br.y(); j++)
|
||||
tiles.append(Tile(QPoint(i, j), z.id));
|
||||
|
||||
if (_block)
|
||||
_tileLoader.loadTilesSync(tiles);
|
||||
else
|
||||
_tileLoader.loadTilesAsync(tiles);
|
||||
|
||||
for (int i = 0; i < tiles.count(); i++) {
|
||||
Tile &t = tiles[i];
|
||||
QPoint tp(t.xy().x() * z.tile.width(), t.xy().y() * z.tile.height());
|
||||
if (t.pixmap().isNull())
|
||||
painter->fillRect(QRect(tp, z.tile), _backgroundColor);
|
||||
else
|
||||
painter->drawPixmap(tp, t.pixmap());
|
||||
}
|
||||
}
|
||||
|
||||
QPointF WMTSMap::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
return _transform.map(_projection.ll2xy(c));
|
||||
}
|
||||
|
||||
Coordinates WMTSMap::xy2ll(const QPointF &p) const
|
||||
{
|
||||
return _projection.xy2ll(_inverted.map(p));
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user