Compare commits
86 Commits
13.17
...
c4b85ef493
Author | SHA1 | Date | |
---|---|---|---|
c4b85ef493 | |||
c425be3741 | |||
09d0b281c2 | |||
ff25f02965 | |||
27401d58b7 | |||
da2b6661f6 | |||
de76eafdfb | |||
19cda6fbd5 | |||
6803ee0324 | |||
43271d9ff8 | |||
6bd83780cd | |||
c4d07b5f12 | |||
b28217a026 | |||
1af2c130b0 | |||
ca0d859c6d | |||
947d2d62b3 | |||
11677f5e35 | |||
6ef6644260 | |||
f6f9e4146d | |||
d1401bc302 | |||
488e5e1cac | |||
ff4f3eea60 | |||
d46ac8435e | |||
15fbd6d35e | |||
7de180d580 | |||
bd37521ca0 | |||
4445976cb9 | |||
76b14c23c6 | |||
3b4376cc03 | |||
41b1ec3605 | |||
4476998333 | |||
5940a2ced4 | |||
33c45f845a | |||
6f12f91cb1 | |||
55de85579c | |||
86f98aca42 | |||
56425a3318 | |||
d045fed086 | |||
31cd65f15e | |||
089ccfde71 | |||
a0ce50e7e4 | |||
031d82f689 | |||
99f620f101 | |||
5f3203d638 | |||
33cc1df601 | |||
5ef29bf827 | |||
6f029d81a0 | |||
90395a32dd | |||
d4b10b091c | |||
6210d1b983 | |||
5e71715f22 | |||
648f90f230 | |||
324168340b | |||
3e1bddbcfd | |||
b069d2ac3f | |||
9b46845568 | |||
f814d1f5a3 | |||
0f05dd6ba3 | |||
8a069f113e | |||
bfe31023e0 | |||
779f98a206 | |||
a660cbd463 | |||
7df3eea21a | |||
6d3eb310bc | |||
0c7296e006 | |||
36aacfc44e | |||
01dfbb3706 | |||
8ec895271a | |||
e8b4105365 | |||
28fdc89346 | |||
86d11b9a9f | |||
2eeeb965dc | |||
07435a3fdc | |||
a48b46d0fb | |||
bd8d2267c7 | |||
48396e254b | |||
625ee42eb4 | |||
5945ceaa09 | |||
7728dba605 | |||
275a9a2683 | |||
ff50ffa003 | |||
026ef5854d | |||
501fd03511 | |||
f6a14e6008 | |||
4417b3d5e2 | |||
8780a40b9f |
@ -1,4 +1,4 @@
|
||||
version: 13.17.{build}
|
||||
version: 13.20.{build}
|
||||
|
||||
configuration:
|
||||
- Release
|
||||
@ -12,8 +12,8 @@ environment:
|
||||
- QTDIR: C:\Qt\5.15\msvc2019_64
|
||||
OPENSSLDIR: C:\OpenSSL-v111-Win64\bin
|
||||
NSISDEF: /DOPENSSL /DANGLE
|
||||
- QTDIR: C:\Qt\6.5\msvc2019_64
|
||||
OPENSSLDIR: C:\OpenSSL-v30-Win64\bin
|
||||
- QTDIR: C:\Qt\6.7\msvc2019_64
|
||||
OPENSSLDIR: C:\OpenSSL-v32-Win64\bin
|
||||
NSISDEF: /DQT6 /DOPENSSL
|
||||
|
||||
install:
|
||||
|
8
.github/workflows/codeql.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
@ -26,7 +26,7 @@ jobs:
|
||||
sudo apt-get install qtbase5-dev qtbase5-private-dev qtbase5-dev-tools qt5-qmake qttools5-dev-tools libqt5opengl5-dev qtpositioning5-dev libqt5svg5-dev libqt5serialport5-dev
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@ -37,9 +37,9 @@ jobs:
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
4
.github/workflows/osx.yml
vendored
@ -8,7 +8,7 @@ on:
|
||||
jobs:
|
||||
qt5:
|
||||
name: GPXSee Qt5 build
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-12
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@ -39,7 +39,7 @@ jobs:
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: '6.6.1'
|
||||
version: '6.7.0'
|
||||
modules: qtpositioning qtserialport qtimageformats
|
||||
- name: Create localization
|
||||
run: lrelease gpxsee.pro
|
||||
|
@ -2116,7 +2116,6 @@ UCS-2000 / Ukraine TM zone 12,6386,5561,6379
|
||||
UCS-2000 / Ukraine TM zone 13,6387,5561,6380
|
||||
Cayman Islands National Grid 2011,6391,6135,6390
|
||||
NAD83(2011) / Alaska Albers,6393,6318,15021
|
||||
NAD83(2011) / Alaska zone 1,6394,6318,15031
|
||||
NAD83(2011) / Alaska zone 2,6395,6318,15032
|
||||
NAD83(2011) / Alaska zone 3,6396,6318,15033
|
||||
NAD83(2011) / Alaska zone 4,6397,6318,15034
|
||||
@ -2219,7 +2218,6 @@ NAD83(2011) / Michigan Central,6493,6318,12142
|
||||
NAD83(2011) / Michigan Central (ft),6494,6318,15334
|
||||
NAD83(2011) / Michigan North,6495,6318,12141
|
||||
NAD83(2011) / Michigan North (ft),6496,6318,15333
|
||||
NAD83(2011) / Michigan Oblique Mercator,6497,6318,12150
|
||||
NAD83(2011) / Michigan South,6498,6318,12143
|
||||
NAD83(2011) / Michigan South (ft),6499,6318,15335
|
||||
NAD83(2011) / Minnesota Central,6500,6318,12232
|
||||
@ -2378,8 +2376,6 @@ NAD83(2011) / Oregon Canyonville-Grants Pass zone (m),6802,6318,6749
|
||||
NAD83(2011) / Oregon Canyonville-Grants Pass zone (ft),6803,6318,6750
|
||||
NAD83(2011) / Oregon Columbia River East zone (m),6806,6318,6751
|
||||
NAD83(2011) / Oregon Columbia River East zone (ft),6807,6318,6752
|
||||
NAD83(2011) / Oregon Columbia River West zone (m),6810,6318,6753
|
||||
NAD83(2011) / Oregon Columbia River West zone (ft),6811,6318,6754
|
||||
NAD83(2011) / Oregon Cottage Grove-Canyonville zone (m),6814,6318,6755
|
||||
NAD83(2011) / Oregon Cottage Grove-Canyonville zone (ft),6815,6318,6756
|
||||
NAD83(2011) / Oregon Dufur-Madras zone (m),6818,6318,6757
|
||||
@ -2394,8 +2390,6 @@ NAD83(2011) / Oregon La Grande zone (m),6834,6318,6765
|
||||
NAD83(2011) / Oregon La Grande zone (ft),6835,6318,6766
|
||||
NAD83(2011) / Oregon Ontario zone (m),6838,6318,6767
|
||||
NAD83(2011) / Oregon Ontario zone (ft),6839,6318,6768
|
||||
NAD83(2011) / Oregon Coast zone (m),6842,6318,6769
|
||||
NAD83(2011) / Oregon Coast zone (ft),6843,6318,6770
|
||||
NAD83(2011) / Oregon Pendleton zone (m),6846,6318,6771
|
||||
NAD83(2011) / Oregon Pendleton zone (ft),6847,6318,6772
|
||||
NAD83(2011) / Oregon Pendleton-La Grande zone (m),6850,6318,6773
|
||||
@ -2754,7 +2748,6 @@ NAD27 / MTM zone 10,7991,4267,17710
|
||||
Malongo 1987 / UTM zone 33S,7992,4259,16133
|
||||
WGS 84 / TM Zone 20N (ftUS),8035,4326,8033
|
||||
WGS 84 / TM Zone 21N (ftUS),8036,4326,8034
|
||||
NAD83(2011) / PCCS zone 1 (ft),8065,6318,8061
|
||||
NAD83(2011) / PCCS zone 2 (ft),8066,6318,8062
|
||||
NAD83(2011) / PCCS zone 3 (ft),8067,6318,8063
|
||||
NAD83(2011) / PCCS zone 4 (ft),8068,6318,8064
|
||||
@ -2963,7 +2956,6 @@ Pulkovo 1995 / Gauss-Kruger zone 29,20029,4200,16229
|
||||
Pulkovo 1995 / Gauss-Kruger zone 30,20030,4200,16230
|
||||
Pulkovo 1995 / Gauss-Kruger zone 31,20031,4200,16231
|
||||
Pulkovo 1995 / Gauss-Kruger zone 32,20032,4200,16232
|
||||
NAD83(2011) / Amtrak NECCS21 (ft),20050,6318,10148
|
||||
Pulkovo 1995 / Gauss-Kruger 4N,20064,4200,16304
|
||||
Pulkovo 1995 / Gauss-Kruger 5N,20065,4200,16305
|
||||
Pulkovo 1995 / Gauss-Kruger 6N,20066,4200,16306
|
||||
|
|
@ -283,6 +283,42 @@ Map Grid of Australia zone 44,6728,9001,9807,4400,8801,0,9102,8802,81,9102,8805,
|
||||
Map Grid of Australia zone 46,6729,9001,9807,4400,8801,0,9102,8802,93,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
|
||||
Map Grid of Australia zone 47,6730,9001,9807,4400,8801,0,9102,8802,99,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
|
||||
Map Grid of Australia zone 59,6731,9001,9807,4400,8801,0,9102,8802,171,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
|
||||
Oregon Baker zone (meter),6741,9001,9807,4499,8801,44.3,9110,8802,-117.5,9110,8805,1.00016,9201,8806,40000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Baker zone (international foot),6742,9002,9807,4495,8801,44.3,9110,8802,-117.5,9110,8805,1.00016,9201,8806,131233.5958,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Bend-Klamath Falls zone (meter),6743,9001,9807,4499,8801,41.45,9110,8802,-121.45,9110,8805,1.0002,9201,8806,80000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Bend-Klamath Falls zone (international foot),6744,9002,9807,4495,8801,41.45,9110,8802,-121.45,9110,8805,1.0002,9201,8806,262467.1916,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Bend-Redmond-Prineville zone (meter),6745,9001,9801,4499,8801,44.4,9110,8802,-121.15,9110,8805,1.00012,9201,8806,80000.0,9001,8807,130000.0,9001,,,,,,
|
||||
Oregon Bend-Redmond-Prineville zone (international foot),6746,9002,9801,4495,8801,44.4,9110,8802,-121.15,9110,8805,1.00012,9201,8806,262467.1916,9002,8807,426509.1864,9002,,,,,,
|
||||
Oregon Bend-Burns zone (meter),6747,9001,9801,4499,8801,43.4,9110,8802,-119.45,9110,8805,1.0002,9201,8806,120000.0,9001,8807,60000.0,9001,,,,,,
|
||||
Oregon Bend-Burns zone (international foot),6748,9002,9801,4495,8801,43.4,9110,8802,-119.45,9110,8805,1.0002,9201,8806,393700.7874,9002,8807,196850.3937,9002,,,,,,
|
||||
Oregon Canyonville-Grants Pass zone (meter),6749,9001,9807,4499,8801,42.3,9110,8802,-123.2,9110,8805,1.00007,9201,8806,40000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Canyonville-Grants Pass zone (international foot),6750,9002,9807,4495,8801,42.3,9110,8802,-123.2,9110,8805,1.00007,9201,8806,131233.5958,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Columbia River East zone (meter),6751,9001,9801,4499,8801,45.4,9110,8802,-120.3,9110,8805,1.000008,9201,8806,150000.0,9001,8807,30000.0,9001,,,,,,
|
||||
Oregon Columbia River East zone (international foot),6752,9002,9801,4495,8801,45.4,9110,8802,-120.3,9110,8805,1.000008,9201,8806,492125.9843,9002,8807,98425.1969,9002,,,,,,
|
||||
Oregon Cottage Grove-Canyonville zone (meter),6755,9001,9807,4499,8801,42.5,9110,8802,-123.2,9110,8805,1.000023,9201,8806,50000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Cottage Grove-Canyonville zone (international foot),6756,9002,9807,4495,8801,42.5,9110,8802,-123.2,9110,8805,1.000023,9201,8806,164041.9948,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Dufur-Madras zone (meter),6757,9001,9807,4499,8801,44.3,9110,8802,-121.0,9110,8805,1.00011,9201,8806,80000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Dufur-Madras zone (international foot),6758,9002,9807,4495,8801,44.3,9110,8802,-121.0,9110,8805,1.00011,9201,8806,262467.1916,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Eugene zone (meter),6759,9001,9807,4499,8801,43.45,9110,8802,-123.1,9110,8805,1.000015,9201,8806,50000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Eugene zone (international foot),6760,9002,9807,4495,8801,43.45,9110,8802,-123.1,9110,8805,1.000015,9201,8806,164041.9948,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Grants Pass-Ashland zone (meter),6761,9001,9807,4499,8801,41.45,9110,8802,-123.2,9110,8805,1.000043,9201,8806,50000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Grants Pass-Ashland zone (international foot),6762,9002,9807,4495,8801,41.45,9110,8802,-123.2,9110,8805,1.000043,9201,8806,164041.9948,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Gresham-Warm Springs zone (meter),6763,9001,9807,4499,8801,45.0,9110,8802,-122.2,9110,8805,1.00005,9201,8806,10000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Gresham-Warm Springs zone (international foot),6764,9002,9807,4495,8801,45.0,9110,8802,-122.2,9110,8805,1.00005,9201,8806,32808.399,9002,8807,0.0,9002,,,,,,
|
||||
Oregon La Grande zone (meter),6765,9001,9807,4499,8801,45.0,9102,8802,-118.0,9102,8805,1.00013,9201,8806,40000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon La Grande zone (international foot),6766,9002,9807,4495,8801,45.0,9102,8802,-118.0,9102,8805,1.00013,9201,8806,131233.5958,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Ontario zone (meter),6767,9001,9807,4499,8801,43.15,9110,8802,-117.0,9110,8805,1.0001,9201,8806,80000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Ontario zone (international foot),6768,9002,9807,4495,8801,43.15,9110,8802,-117.0,9110,8805,1.0001,9201,8806,262467.1916,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Pendleton zone (meter),6771,9001,9807,4499,8801,45.15,9110,8802,-119.1,9110,8805,1.000045,9201,8806,60000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Pendleton zone (international foot),6772,9001,9807,4495,8801,45.15,9110,8802,-119.1,9110,8805,1.000045,9201,8806,196850.3937,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Pendleton-La Grande zone (meter),6773,9001,9807,4499,8801,45.05,9110,8802,-118.2,9110,8805,1.000175,9201,8806,30000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Pendleton-La Grande zone (international foot),6774,9002,9807,4495,8801,45.05,9110,8802,-118.2,9110,8805,1.000175,9201,8806,98425.1969,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Portland zone (meter),6775,9001,9801,4499,8801,45.3,9110,8802,-122.45,9110,8805,1.000002,9201,8806,100000.0,9001,8807,50000.0,9001,,,,,,
|
||||
Oregon Portland zone (international foot),6776,9002,9801,4495,8801,45.3,9110,8802,-122.45,9110,8805,1.000002,9201,8806,328083.9895,9002,8807,164041.9948,9002,,,,,,
|
||||
Oregon Salem zone (meter),6777,9001,9807,4499,8801,44.2,9110,8802,-123.05,9110,8805,1.00001,9201,8806,50000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Salem zone (international foot),6778,9002,9807,4495,8801,44.2,9110,8802,-123.05,9110,8805,1.00001,9201,8806,164041.9948,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Santiam Pass zone (meter),6779,9001,9807,4499,8801,44.05,9110,8802,-122.3,9110,8805,1.000155,9201,8806,0.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Santiam Pass zone (international foot),6780,9002,9807,4495,8801,44.05,9110,8802,-122.3,9110,8805,1.000155,9201,8806,0.0,9002,8807,0.0,9002,,,,,,
|
||||
Albania TM 2010,6869,9001,9807,4530,8801,0,9102,8802,20,9102,8805,1,9201,8806,500000,9001,8807,0,9001,,,,,,
|
||||
Italy zone,6877,9001,9807,4500,8801,0,9102,8802,12,9102,8805,0.9985,9201,8806,7000000,9001,8807,0,9001,,,,,,
|
||||
Italy zone 12,6878,9001,9807,4500,8801,0,9102,8802,12,9102,8805,1,9201,8806,3000000,9001,8807,0,9001,,,,,,
|
||||
@ -295,7 +331,159 @@ Vietnam TM-3 zone 482,6953,9001,9807,4400,8801,0,9102,8802,105,9102,8805,0.9999,
|
||||
Vietnam TM-3 zone 491,6954,9001,9807,4400,8801,0,9102,8802,108,9102,8805,0.9999,9201,8806,0,9001,8807,500000,9001,,,,,,
|
||||
Vietnam TM-3 Da Nang zone,6955,9001,9807,4400,8801,0,9110,8802,107.45,9110,8805,0.9999,9201,8806,0,9001,8807,500000,9001,,,,,,
|
||||
Albania LCC 2010,6961,9001,9802,4530,8821,41,9102,8822,20,9102,8823,39,9102,8824,43,9102,8826,0,9001,8827,0,9001,,,
|
||||
City and County of San Francisco CS13 (meters),6994,9001,9807,4499,8801,37.75,9102,8802,-122.45,9102,8805,1.000007,9202,8806,48000.0,9001,8807,24000.0,9001,,,,,,
|
||||
City and County of San Francisco CS13 (US Survey feet),6995,9003,9807,4497,8801,37.75,9102,8802,-122.45,9102,8805,1.000007,9202,8806,157480.0,9003,8807,78740.0,9003,,,,,,
|
||||
Iowa regional zone 1 Spencer,7043,9003,9801,4497,8801,43.12,9110,8802,-95.15,9110,8805,1.000052,9201,8806,11500000.0,9003,8807,9600000.0,9003,,,,,,
|
||||
Iowa regional zone 2 Mason City,7044,9003,9801,4497,8801,43.1,9110,8802,-92.45,9110,8805,1.000043,9201,8806,12500000.0,9003,8807,9800000.0,9003,,,,,,
|
||||
Iowa regional zone 3 Elkader,7045,9003,9807,4497,8801,40.15,9110,8802,-91.12,9110,8805,1.000035,9201,8806,13500000.0,9003,8807,8300000.0,9003,,,,,,
|
||||
Iowa regional zone 4 Sioux City-Iowa Falls,7046,9003,9801,4497,8801,42.32,9110,8802,-94.5,9110,8805,1.000045,9201,8806,14500000.0,9003,8807,8600000.0,9003,,,,,,
|
||||
Iowa regional zone 5 Waterloo,7047,9003,9801,4497,8801,42.39,9110,8802,-92.15,9110,8805,1.000032,9201,8806,15500000.0,9003,8807,8900000.0,9003,,,,,,
|
||||
Iowa regional zone 6 Council Bluffs,7048,9003,9807,4497,8801,40.15,9110,8802,-95.44,9110,8805,1.000039,9201,8806,16500000.0,9003,8807,6600000.0,9003,,,,,,
|
||||
Iowa regional zone 7 Carroll-Atlantic,7049,9003,9807,4497,8801,40.15,9110,8802,-94.38,9110,8805,1.000045,9201,8806,17500000.0,9003,8807,6800000.0,9003,,,,,,
|
||||
Iowa regional zone 8 Ames-Des Moines,7050,9003,9807,4497,8801,40.15,9110,8802,-93.43,9110,8805,1.000033,9201,8806,18500000.0,9003,8807,7000000.0,9003,,,,,,
|
||||
Iowa regional zone 9 Newton,7051,9003,9807,4497,8801,40.15,9110,8802,-92.49,9110,8805,1.000027,9201,8806,19500000.0,9003,8807,7200000.0,9003,,,,,,
|
||||
Iowa regional zone 10 Cedar Rapids,7052,9003,9801,4497,8801,41.5,9110,8802,-91.4,9110,8805,1.00002,9201,8806,20500000.0,9003,8807,8000000.0,9003,,,,,,
|
||||
Iowa regional zone 11 Dubuque-Davenport,7053,9003,9807,4497,8801,40.15,9110,8802,-90.32,9110,8805,1.000027,9201,8806,21500000.0,9003,8807,7600000.0,9003,,,,,,
|
||||
Iowa regional zone 12 Red Oak-Ottumwa,7054,9003,9801,4497,8801,40.55,9110,8802,-93.45,9110,8805,1.000037,9201,8806,22500000.0,9003,8807,6200000.0,9003,,,,,,
|
||||
Iowa regional zone 13 Fairfield,7055,9003,9807,4497,8801,40.15,9110,8802,-91.55,9110,8805,1.00002,9201,8806,23500000.0,9003,8807,6400000.0,9003,,,,,,
|
||||
Iowa regional zone 14 Burlington,7056,9003,9807,4497,8801,40.15,9110,8802,-91.15,9110,8805,1.000018,9201,8806,24500000.0,9003,8807,6200000.0,9003,,,,,,
|
||||
Montana Blackfeet St Mary Valley (meter),7089,9001,9807,4499,8801,48.3,9110,8802,-112.3,9110,8805,1.00016,9201,8806,150000.0,9001,8807,0.0,9001,,,,,,
|
||||
Montana Blackfeet St Mary Valley (international foot),7090,9002,9807,4495,8801,48.3,9110,8802,-112.3,9110,8805,1.00016,9201,8806,492125.9843,9002,8807,0.0,9002,,,,,,
|
||||
Montana Blackfeet (meter),7091,9001,9807,4499,8801,48.0,9110,8802,-112.3,9110,8805,1.00019,9201,8806,100000.0,9001,8807,0.0,9001,,,,,,
|
||||
Montana Blackfeet (international foot),7092,9002,9807,4495,8801,48.0,9110,8802,-112.3,9110,8805,1.00019,9201,8806,328083.9895,9002,8807,0.0,9002,,,,,,
|
||||
Montana Milk River (meter),7093,9001,9801,4499,8801,48.3,9110,8802,-111.0,9110,8805,1.000145,9201,8806,150000.0,9001,8807,200000.0,9001,,,,,,
|
||||
Montana Milk River (international foot),7094,9002,9801,4495,8801,48.3,9110,8802,-111.0,9110,8805,1.000145,9201,8806,492125.9843,9002,8807,656167.979,9002,,,,,,
|
||||
Montana Fort Belknap (meter),7095,9001,9801,4499,8801,48.3,9110,8802,-108.3,9110,8805,1.00012,9201,8806,200000.0,9001,8807,150000.0,9001,,,,,,
|
||||
Montana Fort Belknap (international foot),7096,9002,9801,4495,8801,48.3,9110,8802,-108.3,9110,8805,1.00012,9201,8806,656167.979,9002,8807,492125.9843,9002,,,,,,
|
||||
Montana Fort Peck Assiniboine (meter),7097,9001,9801,4499,8801,48.2,9110,8802,-105.3,9110,8805,1.00012,9201,8806,200000.0,9001,8807,100000.0,9001,,,,,,
|
||||
Montana Fort Peck Assiniboine (international foot),7098,9002,9801,4495,8801,48.2,9110,8802,-105.3,9110,8805,1.00012,9201,8806,656167.979,9002,8807,328083.9895,9002,,,,,,
|
||||
Montana Fort Peck Sioux (meter),7099,9001,9801,4499,8801,48.2,9110,8802,-105.3,9110,8805,1.00009,9201,8806,100000.0,9001,8807,50000.0,9001,,,,,,
|
||||
Montana Fort Peck Sioux (international foot),7100,9002,9801,4495,8801,48.2,9110,8802,-105.3,9110,8805,1.00009,9201,8806,328083.9895,9002,8807,164041.9938,9002,,,,,,
|
||||
Montana Crow (meter),7101,9001,9807,4499,8801,44.45,9110,8802,-107.45,9110,8805,1.000148,9201,8806,200000.0,9001,8807,0.0,9001,,,,,,
|
||||
Montana Crow (international foot),7102,9002,9807,4495,8801,44.45,9110,8802,-107.45,9110,8805,1.000148,9201,8806,656167.979,9002,8807,0.0,9002,,,,,,
|
||||
Montana Bobcat (meter),7103,9001,9801,4499,8801,46.15,9110,8802,-111.15,9110,8805,1.000185,9201,8806,100000.0,9001,8807,100000.0,9001,,,,,,
|
||||
Montana Bobcat (international foot),7104,9002,9801,4495,8801,46.15,9110,8802,-111.15,9110,8805,1.000185,9201,8806,328083.9895,9002,8807,328083.9895,9002,,,,,,
|
||||
Montana Billings (meter),7105,9001,9801,4499,8801,45.47,9110,8802,-108.25,9110,8805,1.0001515,9201,8806,200000.0,9001,8807,50000.0,9001,,,,,,
|
||||
Montana Billings (international foot),7106,9002,9801,4495,8801,45.47,9110,8802,-108.25,9110,8805,1.0001515,9201,8806,656167.979,9002,8807,164041.9948,9002,,,,,,
|
||||
Wyoming Wind River (meter),7107,9001,9807,4499,8801,42.4,9110,8802,-108.2,9110,8805,1.00024,9201,8806,100000.0,9001,8807,0.0,9001,,,,,,
|
||||
Wyoming Wind River (US survey foot),7108,9003,9807,4497,8801,42.4,9110,8802,-108.2,9110,8805,1.00024,9201,8806,328083.3333,9003,8807,0.0,9003,,,,,,
|
||||
City and County of San Francisco CS13 (meter),7129,9001,9807,4499,8801,37.75,9102,8802,-122.45,9102,8805,1.000007,9201,8806,48000.0,9001,8807,24000.0,9001,,,,,,
|
||||
City and County of San Francisco CS13 (US survey foot),7130,9003,9807,4497,8801,37.75,9102,8802,-122.45,9102,8805,1.000007,9201,8806,157480.0,9003,8807,78740.0,9003,,,,,,
|
||||
Palestine Grid modified,7141,9001,9807,4400,8801,31.4402749,9110,8802,35.124349,9110,8805,1,9201,8806,170251.555,9001,8807,126867.909,9001,,,,,,
|
||||
InGCS Adams (m),7143,9001,9807,4499,8801,40.33,9110,8802,-84.57,9110,8805,1.000034,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Adams (ftUS),7144,9003,9807,4497,8801,40.33,9110,8802,-84.57,9110,8805,1.000034,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Allen (m),7145,9001,9807,4499,8801,40.54,9110,8802,-85.03,9110,8805,1.000031,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Allen (ftUS),7146,9003,9807,4497,8801,40.54,9110,8802,-85.03,9110,8805,1.000031,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Bartholomew (m),7147,9001,9807,4499,8801,39.0,9110,8802,-85.51,9110,8805,1.000026,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Bartholomew (ftUS),7148,9003,9807,4497,8801,39.0,9110,8802,-85.51,9110,8805,1.000026,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Benton (m),7149,9001,9807,4499,8801,40.27,9110,8802,-87.18,9110,8805,1.000029,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Benton (ftUS),7150,9003,9807,4497,8801,40.27,9110,8802,-87.18,9110,8805,1.000029,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Blackford-Delaware (m),7151,9001,9807,4499,8801,40.03,9110,8802,-85.24,9110,8805,1.000038,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Blackford-Delaware (ftUS),7152,9003,9807,4497,8801,40.03,9110,8802,-85.24,9110,8805,1.000038,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Boone-Hendricks (m),7153,9001,9807,4499,8801,39.36,9110,8802,-86.3,9110,8805,1.000036,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Boone-Hendricks (ftUS),7154,9003,9807,4497,8801,39.36,9110,8802,-86.3,9110,8805,1.000036,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Brown (m),7155,9001,9807,4499,8801,39.0,9110,8802,-86.18,9110,8805,1.00003,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Brown (ftUS),7156,9003,9807,4497,8801,39.0,9110,8802,-86.18,9110,8805,1.00003,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Carroll (m),7157,9001,9807,4499,8801,40.24,9110,8802,-86.39,9110,8805,1.000026,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Carroll (ftUS),7158,9003,9807,4497,8801,40.24,9110,8802,-86.39,9110,8805,1.000026,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Cass (m),7159,9001,9807,4499,8801,40.33,9110,8802,-86.24,9110,8805,1.000028,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Cass (ftUS),7160,9003,9807,4497,8801,40.33,9110,8802,-86.24,9110,8805,1.000028,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Clark-Floyd-Scott (m),7161,9001,9807,4499,8801,38.09,9110,8802,-85.36,9110,8805,1.000021,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Clark-Floyd-Scott (ftUS),7162,9003,9807,4497,8801,38.09,9110,8802,-85.36,9110,8805,1.000021,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Clay (m),7163,9001,9807,4499,8801,39.09,9110,8802,-87.09,9110,8805,1.000024,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Clay (ftUS),7164,9003,9807,4497,8801,39.09,9110,8802,-87.09,9110,8805,1.000024,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Clinton (m),7165,9001,9807,4499,8801,40.09,9110,8802,-86.36,9110,8805,1.000032,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Clinton (ftUS),7166,9003,9807,4497,8801,40.09,9110,8802,-86.36,9110,8805,1.000032,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Crawford-Lawrence-Orange (m),7167,9001,9807,4499,8801,38.06,9110,8802,-86.3,9110,8805,1.000025,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Crawford-Lawrence-Orange (ftUS),7168,9003,9807,4497,8801,38.06,9110,8802,-86.3,9110,8805,1.000025,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Daviess-Greene (m),7169,9001,9807,4499,8801,38.27,9110,8802,-87.06,9110,8805,1.000018,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Daviess-Greene (ftUS),7170,9003,9807,4497,8801,38.27,9110,8802,-87.06,9110,8805,1.000018,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Dearborn-Ohio-Switzerland (m),7171,9001,9807,4499,8801,38.39,9110,8802,-84.54,9110,8805,1.000029,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Dearborn-Ohio-Switzerland (ftUS),7172,9003,9807,4497,8801,38.39,9110,8802,-84.54,9110,8805,1.000029,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Decatur-Rush (m),7173,9001,9807,4499,8801,39.06,9110,8802,-85.39,9110,8805,1.000036,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Decatur-Rush (ftUS),7174,9003,9807,4497,8801,39.06,9110,8802,-85.39,9110,8805,1.000036,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS DeKalb (m),7175,9001,9807,4499,8801,41.15,9110,8802,-84.57,9110,8805,1.000036,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS DeKalb (ftUS),7176,9003,9807,4497,8801,41.15,9110,8802,-84.57,9110,8805,1.000036,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Dubois-Martin (m),7177,9001,9807,4499,8801,38.12,9110,8802,-86.57,9110,8805,1.00002,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Dubois-Martin (ftUS),7178,9003,9807,4497,8801,38.12,9110,8802,-86.57,9110,8805,1.00002,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Elkhart-Kosciusko-Wabash (m),7179,9001,9807,4499,8801,40.39,9110,8802,-85.51,9110,8805,1.000033,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Elkhart-Kosciusko-Wabash (ftUS),7180,9003,9807,4497,8801,40.39,9110,8802,-85.51,9110,8805,1.000033,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Fayette-Franklin-Union (m),7181,9001,9807,4499,8801,39.15,9110,8802,-85.03,9110,8805,1.000038,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Fayette-Franklin-Union (ftUS),7182,9003,9807,4497,8801,39.15,9110,8802,-85.03,9110,8805,1.000038,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Fountain-Warren (m),7183,9001,9807,4499,8801,39.57,9110,8802,-87.18,9110,8805,1.000025,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Fountain-Warren (ftUS),7184,9003,9807,4497,8801,39.57,9110,8802,-87.18,9110,8805,1.000025,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Fulton-Marshall-St. Joseph (m),7185,9001,9807,4499,8801,40.54,9110,8802,-86.18,9110,8805,1.000031,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Fulton-Marshall-St. Joseph (ftUS),7186,9003,9807,4497,8801,40.54,9110,8802,-86.18,9110,8805,1.000031,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Gibson (m),7187,9001,9807,4499,8801,38.09,9110,8802,-87.39,9110,8805,1.000013,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Gibson (ftUS),7188,9003,9807,4497,8801,38.09,9110,8802,-87.39,9110,8805,1.000013,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Grant (m),7189,9001,9807,4499,8801,40.21,9110,8802,-85.42,9110,8805,1.000034,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Grant (ftUS),7190,9003,9807,4497,8801,40.21,9110,8802,-85.42,9110,8805,1.000034,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Hamilton-Tipton (m),7191,9001,9807,4499,8801,39.54,9110,8802,-86.0,9110,8805,1.000034,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Hamilton-Tipton (ftUS),7192,9003,9807,4497,8801,39.54,9110,8802,-86.0,9110,8805,1.000034,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Hancock-Madison (m),7193,9001,9807,4499,8801,39.39,9110,8802,-85.48,9110,8805,1.000036,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Hancock-Madison (ftUS),7194,9003,9807,4497,8801,39.39,9110,8802,-85.48,9110,8805,1.000036,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Harrison-Washington (m),7195,9001,9807,4499,8801,37.57,9110,8802,-86.09,9110,8805,1.000027,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Harrison-Washington (ftUS),7196,9003,9807,4497,8801,37.57,9110,8802,-86.09,9110,8805,1.000027,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Henry (m),7197,9001,9807,4499,8801,39.45,9110,8802,-85.27,9110,8805,1.000043,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Henry (ftUS),7198,9003,9807,4497,8801,39.45,9110,8802,-85.27,9110,8805,1.000043,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Howard-Miami (m),7199,9001,9807,4499,8801,40.21,9110,8802,-86.09,9110,8805,1.000031,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Howard-Miami (ftUS),7200,9003,9807,4497,8801,40.21,9110,8802,-86.09,9110,8805,1.000031,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Huntington-Whitley (m),7201,9001,9807,4499,8801,40.39,9110,8802,-85.3,9110,8805,1.000034,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Huntington-Whitley (ftUS),7202,9003,9807,4497,8801,40.39,9110,8802,-85.3,9110,8805,1.000034,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Jackson (m),7203,9001,9807,4499,8801,38.42,9110,8802,-85.57,9110,8805,1.000022,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Jackson (ftUS),7204,9003,9807,4497,8801,38.42,9110,8802,-85.57,9110,8805,1.000022,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Jasper-Porter (m),7205,9001,9807,4499,8801,40.42,9110,8802,-87.06,9110,8805,1.000027,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Jasper-Porter (ftUS),7206,9003,9807,4497,8801,40.42,9110,8802,-87.06,9110,8805,1.000027,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Jay (m),7207,9001,9807,4499,8801,40.18,9110,8802,-85.0,9110,8805,1.000038,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Jay (ftUS),7208,9003,9807,4497,8801,40.18,9110,8802,-85.0,9110,8805,1.000038,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Jefferson (m),7209,9001,9807,4499,8801,38.33,9110,8802,-85.21,9110,8805,1.000028,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Jefferson (ftUS),7210,9003,9807,4497,8801,38.33,9110,8802,-85.21,9110,8805,1.000028,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Jennings (m),7211,9001,9807,4499,8801,38.48,9110,8802,-85.48,9110,8805,1.000025,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Jennings (ftUS),7212,9003,9807,4497,8801,38.48,9110,8802,-85.48,9110,8805,1.000025,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Johnson-Marion (m),7213,9001,9807,4499,8801,39.18,9110,8802,-86.09,9110,8805,1.000031,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Johnson-Marion (ftUS),7214,9003,9807,4497,8801,39.18,9110,8802,-86.09,9110,8805,1.000031,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Knox (m),7215,9001,9807,4499,8801,38.24,9110,8802,-87.27,9110,8805,1.000015,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Knox (ftUS),7216,9003,9807,4497,8801,38.24,9110,8802,-87.27,9110,8805,1.000015,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS LaGrange-Noble (m),7217,9001,9807,4499,8801,41.15,9110,8802,-85.27,9110,8805,1.000037,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS LaGrange-Noble (ftUS),7218,9003,9807,4497,8801,41.15,9110,8802,-85.27,9110,8805,1.000037,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Lake-Newton (m),7219,9001,9807,4499,8801,40.42,9110,8802,-87.24,9110,8805,1.000026,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Lake-Newton (ftUS),7220,9003,9807,4497,8801,40.42,9110,8802,-87.24,9110,8805,1.000026,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS LaPorte-Pulaski-Starke (m),7221,9001,9807,4499,8801,40.54,9110,8802,-86.45,9110,8805,1.000027,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS LaPorte-Pulaski-Starke (ftUS),7222,9003,9807,4497,8801,40.54,9110,8802,-86.45,9110,8805,1.000027,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Monroe-Morgan (m),7223,9001,9807,4499,8801,38.57,9110,8802,-86.3,9110,8805,1.000028,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Monroe-Morgan (ftUS),7224,9003,9807,4497,8801,38.57,9110,8802,-86.3,9110,8805,1.000028,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Montgomery-Putnam (m),7225,9001,9807,4499,8801,39.27,9110,8802,-86.57,9110,8805,1.000031,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Montgomery-Putnam (ftUS),7226,9003,9807,4497,8801,39.27,9110,8802,-86.57,9110,8805,1.000031,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Owen (m),7227,9001,9807,4499,8801,39.09,9110,8802,-86.54,9110,8805,1.000026,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Owen (ftUS),7228,9003,9807,4497,8801,39.09,9110,8802,-86.54,9110,8805,1.000026,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Parke-Vermillion (m),7229,9001,9807,4499,8801,39.36,9110,8802,-87.21,9110,8805,1.000022,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Parke-Vermillion (ftUS),7230,9003,9807,4497,8801,39.36,9110,8802,-87.21,9110,8805,1.000022,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Perry (m),7231,9001,9807,4499,8801,37.48,9110,8802,-86.42,9110,8805,1.00002,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Perry (ftUS),7232,9003,9807,4497,8801,37.48,9110,8802,-86.42,9110,8805,1.00002,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Pike-Warrick (m),7233,9001,9807,4499,8801,37.51,9110,8802,-87.18,9110,8805,1.000015,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Pike-Warrick (ftUS),7234,9003,9807,4497,8801,37.51,9110,8802,-87.18,9110,8805,1.000015,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Posey (m),7235,9001,9807,4499,8801,37.45,9110,8802,-87.57,9110,8805,1.000013,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Posey (ftUS),7236,9003,9807,4497,8801,37.45,9110,8802,-87.57,9110,8805,1.000013,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Randolph-Wayne (m),7237,9001,9807,4499,8801,39.42,9110,8802,-85.03,9110,8805,1.000044,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Randolph-Wayne (ftUS),7238,9003,9807,4497,8801,39.42,9110,8802,-85.03,9110,8805,1.000044,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Ripley (m),7239,9001,9807,4499,8801,38.54,9110,8802,-85.18,9110,8805,1.000038,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Ripley (ftUS),7240,9003,9807,4497,8801,38.54,9110,8802,-85.18,9110,8805,1.000038,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Shelby (m),7241,9001,9807,4499,8801,39.18,9110,8802,-85.54,9110,8805,1.00003,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Shelby (ftUS),7242,9003,9807,4497,8801,39.18,9110,8802,-85.54,9110,8805,1.00003,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Spencer (m),7243,9001,9807,4499,8801,37.45,9110,8802,-87.03,9110,8805,1.000014,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Spencer (ftUS),7244,9003,9807,4497,8801,37.45,9110,8802,-87.03,9110,8805,1.000014,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Steuben (m),7245,9001,9807,4499,8801,41.3,9110,8802,-85.0,9110,8805,1.000041,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Steuben (ftUS),7246,9003,9807,4497,8801,41.3,9110,8802,-85.0,9110,8805,1.000041,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Sullivan (m),7247,9001,9807,4499,8801,38.54,9110,8802,-87.3,9110,8805,1.000017,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Sullivan (ftUS),7248,9003,9807,4497,8801,38.54,9110,8802,-87.3,9110,8805,1.000017,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Tippecanoe-White (m),7249,9001,9807,4499,8801,40.12,9110,8802,-86.54,9110,8805,1.000026,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Tippecanoe-White (ftUS),7250,9003,9807,4497,8801,40.12,9110,8802,-86.54,9110,8805,1.000026,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Vanderburgh (m),7251,9001,9807,4499,8801,37.48,9110,8802,-87.33,9110,8805,1.000015,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Vanderburgh (ftUS),7252,9003,9807,4497,8801,37.48,9110,8802,-87.33,9110,8805,1.000015,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Vigo (m),7253,9001,9807,4499,8801,39.15,9110,8802,-87.27,9110,8805,1.00002,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Vigo (ftUS),7254,9003,9807,4497,8801,39.15,9110,8802,-87.27,9110,8805,1.00002,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
InGCS Wells (m),7255,9001,9807,4499,8801,40.33,9110,8802,-85.15,9110,8805,1.000034,9201,8806,240000.0,9001,8807,36000.0,9001,,,,,,
|
||||
InGCS Wells (ftUS),7256,9003,9807,4497,8801,40.33,9110,8802,-85.15,9110,8805,1.000034,9201,8806,787400.0,9003,8807,118110.0,9003,,,,,,
|
||||
WISCRS Ashland County (m),7378,9001,9807,4499,8801,45.4222,9110,8802,-90.372,9110,8805,1.0000495683,9201,8806,172821.9461,9001,8807,0.0017,9001,,,,,,
|
||||
WISCRS Ashland County (ftUS),7379,9003,9807,4497,8801,45.4222,9110,8802,-90.372,9110,8805,1.0000495683,9201,8806,567000.001,9003,8807,0.006,9003,,,,,,
|
||||
WISCRS Bayfield County (m),7380,9001,9801,4499,8801,46.4010734158,9110,8802,-91.091,9110,8805,1.0000331195,9201,8806,228600.4575,9001,8807,148551.4837,9001,,,,,,
|
||||
@ -372,6 +560,8 @@ WISCRS Wood County (m),7482,9001,9801,4499,8801,44.214534369,9110,8802,-90,9110,
|
||||
WISCRS Wood County (ftUS),7483,9003,9801,4497,8801,44.214534369,9110,8802,-90,9110,8805,1.0000421209,9201,8806,684000.001,9003,8807,441566.551,9003,,,,,,
|
||||
WISCRS Adams and Juneau Counties (m),7484,9001,9807,4499,8801,43.22,9110,8802,-90,9110,8805,1.0000365285,9201,8806,147218.6942,9001,8807,0.0037,9001,,,,,,
|
||||
WISCRS Adams and Juneau Counties (ftUS),7485,9003,9807,4497,8801,43.22,9110,8802,-90,9110,8805,1.0000365285,9201,8806,482999.999,9003,8807,0.012,9003,,,,,,
|
||||
"WISCRS Calumet, Fond du Lac, Outagamie and Winnebago Counties (m)",7486,9001,9807,4499,8801,42.431,9110,8802,-88.3,9110,8805,1.0000286569,9201,8806,244754.8893,9001,8807,0.0049,9001,,,,,,
|
||||
"WISCRS Calumet, Fond du Lac, Outagamie and Winnebago Counties (ftUS)",7487,9003,9807,4497,8801,42.431,9110,8802,-88.3,9110,8805,1.0000286569,9201,8806,802999.999,9003,8807,0.016,9003,,,,,,
|
||||
WISCRS Columbia County (m),7488,9001,9801,4499,8801,43.2745167925,9110,8802,-89.234,9110,8805,1.00003498,9201,8806,169164.3381,9001,8807,111569.6134,9001,,,,,,
|
||||
WISCRS Columbia County (ftUS),7489,9003,9801,4497,8801,43.2745167925,9110,8802,-89.234,9110,8805,1.00003498,9201,8806,554999.999,9003,8807,366041.307,9003,,,,,,
|
||||
WISCRS Crawford County (m),7490,9001,9801,4499,8801,43.1200200178,9110,8802,-90.562,9110,8805,1.0000349151,9201,8806,113690.6274,9001,8807,53703.1201,9001,,,,,,
|
||||
@ -388,6 +578,10 @@ WISCRS Green Lake and Marquette Counties (m),7500,9001,9801,4499,8801,43.4825200
|
||||
WISCRS Green Lake and Marquette Counties (ftUS),7501,9003,9801,4497,8801,43.4825200424,9110,8802,-89.143,9110,8805,1.0000344057,9201,8806,495000,9003,8807,259746.132,9003,,,,,,
|
||||
WISCRS Iowa County (m),7502,9001,9807,4499,8801,42.322,9110,8802,-90.094,9110,8805,1.0000394961,9201,8806,113081.0261,9001,8807,0.0045,9001,,,,,,
|
||||
WISCRS Iowa County (ftUS),7503,9003,9807,4497,8801,42.322,9110,8802,-90.094,9110,8805,1.0000394961,9201,8806,371000,9003,8807,0.015,9003,,,,,,
|
||||
"WISCRS Kenosha, Milwaukee, Ozaukee and Racine Counties (m)",7504,9001,9807,4499,8801,42.13,9110,8802,-87.534,9110,8805,1.0000260649,9201,8806,185928.3728,9001,8807,0.0009,9001,,,,,,
|
||||
"WISCRS Kenosha, Milwaukee, Ozaukee and Racine Counties (ftUS)",7505,9003,9807,4497,8801,42.13,9110,8802,-87.534,9110,8805,1.0000260649,9201,8806,610000.003,9003,8807,0.003,9003,,,,,,
|
||||
"WISCRS Kewaunee, Manitowoc and Sheboygan Counties (m)",7506,9001,9807,4499,8801,43.16,9110,8802,-87.33,9110,8805,1.0000233704,9201,8806,79857.7614,9001,8807,0.0012,9001,,,,,,
|
||||
"WISCRS Kewaunee, Manitowoc and Sheboygan Counties (ftUS)",7507,9003,9807,4497,8801,43.16,9110,8802,-87.33,9110,8805,1.0000233704,9201,8806,262000.006,9003,8807,0.004,9003,,,,,,
|
||||
WISCRS La Crosse County (m),7508,9001,9807,4499,8801,43.2704,9110,8802,-91.19,9110,8805,1.0000319985,9201,8806,130454.6598,9001,8807,0.0033,9001,,,,,,
|
||||
WISCRS La Crosse County (ftUS),7509,9003,9807,4497,8801,43.2704,9110,8802,-91.19,9110,8805,1.0000319985,9201,8806,427999.996,9003,8807,0.011,9003,,,,,,
|
||||
WISCRS Monroe County (m),7510,9001,9801,4499,8801,44.0000266143,9110,8802,-90.383,9110,8805,1.0000434122,9201,8806,204521.209,9001,8807,121923.9861,9001,,,,,,
|
||||
@ -452,6 +646,73 @@ St. Helena Local Grid 1971,7875,9001,9807,4400,8801,-15.58,9110,8802,-5.43,9110,
|
||||
St. Helena Local Grid (Tritan),7876,9001,9807,4400,8801,-15.58,9110,8802,-5.43,9110,8805,1,9201,8806,299483.737,9001,8807,2000527.879,9001,,,,,,
|
||||
TM Zone 20N (US survey feet),8033,9003,9807,4497,8801,0,9102,8802,-63,9102,8805,0.9996,9201,8806,1640416.667,9003,8807,0,9003,,,,,,
|
||||
TM Zone 21N (US survey feet),8034,9003,9807,4497,8801,0,9102,8802,-57,9102,8805,0.9996,9201,8806,1640416.667,9003,8807,0,9003,,,,,,
|
||||
Pima County zone 2 Central (ft),8062,9002,9807,4495,8801,31.15,9110,8802,-112.1,9110,8805,1.00009,9201,8806,1800000.0,9002,8807,1000000.0,9002,,,,,,
|
||||
Pima County zone 3 West (ft),8063,9002,9807,4495,8801,31.3,9110,8802,-113.1,9110,8805,1.000055,9201,8806,600000.0,9002,8807,0.0,9002,,,,,,
|
||||
Pima County zone 4 Mt. Lemmon (ft),8064,9002,9801,4495,8801,30.3,9110,8802,-110.45,9110,8805,0.9998,9201,8806,30000.0,9002,8807,-620000.0,9002,,,,,,
|
||||
Oregon Burns-Harper zone (meter),8273,9001,9807,4499,8801,43.3,9110,8802,-117.4,9110,8805,1.00014,9201,8806,90000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Burns-Harper zone (international foot),8274,9002,9807,4495,8801,43.3,9110,8802,-117.4,9110,8805,1.00014,9201,8806,295275.5906,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Canyon City-Burns zone (meter),8275,9001,9807,4499,8801,43.3,9110,8802,-119.0,9110,8805,1.00022,9201,8806,20000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Canyon City-Burns zone (international foot),8276,9002,9807,4495,8801,43.3,9110,8802,-119.0,9110,8805,1.00022,9201,8806,65616.7979,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Coast Range North zone (meter),8277,9001,9801,4499,8801,45.35,9110,8802,-123.25,9110,8805,1.000045,9201,8806,30000.0,9001,8807,20000.0,9001,,,,,,
|
||||
Oregon Coast Range North zone (international foot),8278,9002,9801,4495,8801,45.35,9110,8802,-123.25,9110,8805,1.000045,9201,8806,98425.1969,9002,8807,65616.7979,9002,,,,,,
|
||||
Oregon Dayville-Prairie City zone (meter),8279,9001,9807,4499,8801,44.15,9110,8802,-119.38,9110,8805,1.00012,9201,8806,20000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Dayville-Prairie City zone (international foot),8280,9002,9807,4495,8801,44.15,9110,8802,-119.38,9110,8805,1.00012,9201,8806,65616.7979,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Denio-Burns zone (meter),8281,9001,9807,4499,8801,41.45,9110,8802,-118.25,9110,8805,1.00019,9201,8806,80000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Denio-Burns zone (international foot),8282,9002,9807,4495,8801,41.45,9110,8802,-118.25,9110,8805,1.00019,9201,8806,262467.1916,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Halfway zone (meter),8283,9001,9801,4499,8801,45.15,9110,8802,-117.15,9110,8805,1.000085,9201,8806,40000.0,9001,8807,70000.0,9001,,,,,,
|
||||
Oregon Halfway zone (international foot),8284,9002,9801,4495,8801,45.15,9110,8802,-117.15,9110,8805,1.000085,9201,8806,131233.5958,9002,8807,229658.7927,9002,,,,,,
|
||||
Oregon Medford-Diamond Lake zone (meter),8285,9001,9801,4499,8801,42.0,9110,8802,-122.15,9110,8805,1.00004,9201,8806,60000.0,9001,8807,-60000.0,9001,,,,,,
|
||||
Oregon Medford-Diamond Lake zone (international foot),8286,9002,9801,4495,8801,42.0,9110,8802,-122.15,9110,8805,1.00004,9201,8806,196850.3937,9002,8807,-196850.3937,9002,,,,,,
|
||||
Oregon Mitchell zone (meter),8287,9001,9801,4499,8801,47.0,9110,8802,-120.15,9110,8805,0.99927,9201,8806,30000.0,9001,8807,290000.0,9001,,,,,,
|
||||
Oregon Mitchell zone (international foot),8288,9002,9801,4495,8801,47.0,9110,8802,-120.15,9110,8805,0.99927,9201,8806,98425.1969,9002,8807,951443.5696,9002,,,,,,
|
||||
Oregon North Central zone (meter),8289,9001,9801,4499,8801,46.1,9110,8802,-120.3,9110,8805,1.0,9201,8806,100000.0,9001,8807,140000.0,9001,,,,,,
|
||||
Oregon North Central zone (international foot),8290,9002,9801,4495,8801,46.1,9110,8802,-120.3,9110,8805,1.0,9201,8806,328083.9895,9002,8807,459317.5853,9002,,,,,,
|
||||
Oregon Ochoco Summit zone (meter),8291,9001,9801,4499,8801,43.3,9110,8802,-120.3,9110,8805,1.00006,9201,8806,40000.0,9001,8807,-80000.0,9001,,,,,,
|
||||
Oregon Ochoco Summit zone (international foot),8292,9002,9801,4495,8801,43.3,9110,8802,-120.3,9110,8805,1.00006,9201,8806,131233.5958,9002,8807,-262467.1916,9002,,,,,,
|
||||
Oregon Owyhee zone (meter),8293,9001,9807,4499,8801,41.45,9110,8802,-117.35,9110,8805,1.00018,9201,8806,70000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Owyhee zone (international foot),8294,9002,9807,4495,8801,41.45,9110,8802,-117.35,9110,8805,1.00018,9201,8806,229658.7927,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Pilot Rock-Ukiah zone (meter),8295,9001,9801,4499,8801,46.1,9110,8802,-119.0,9110,8805,1.000025,9201,8806,50000.0,9001,8807,130000.0,9001,,,,,,
|
||||
Oregon Pilot Rock-Ukiah zone (international foot),8296,9002,9801,4495,8801,46.1,9110,8802,-119.0,9110,8805,1.000025,9201,8806,164041.9948,9002,8807,426509.1864,9002,,,,,,
|
||||
Oregon Prairie City-Brogan zone (meter),8297,9001,9801,4499,8801,44.0,9110,8802,-118.0,9110,8805,1.00017,9201,8806,60000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Prairie City-Brogan zone (international foot),8298,9002,9801,4495,8801,44.0,9110,8802,-118.0,9110,8805,1.00017,9201,8806,196850.3937,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Riley-Lakeview zone (meter),8299,9001,9807,4499,8801,41.45,9110,8802,-120.2,9110,8805,1.000215,9201,8806,70000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Riley-Lakeview zone (international foot),8300,9002,9807,4495,8801,41.45,9110,8802,-120.2,9110,8805,1.000215,9201,8806,229658.7927,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Siskiyou Pass zone (meter),8301,9001,9801,4499,8801,42.3,9110,8802,-122.35,9110,8805,1.00015,9201,8806,10000.0,9001,8807,60000.0,9001,,,,,,
|
||||
Oregon Siskiyou Pass zone (international foot),8302,9002,9801,4495,8801,42.3,9110,8802,-122.35,9110,8805,1.00015,9201,8806,32808.399,9002,8807,196850.3937,9002,,,,,,
|
||||
Oregon Ukiah-Fox zone (meter),8303,9001,9801,4499,8801,45.15,9110,8802,-119.0,9110,8805,1.00014,9201,8806,30000.0,9001,8807,90000.0,9001,,,,,,
|
||||
Oregon Ukiah-Fox zone (international foot),8304,9002,9801,4495,8801,45.15,9110,8802,-119.0,9110,8805,1.00014,9201,8806,98425.1969,9002,8807,295275.5906,9002,,,,,,
|
||||
Oregon Wallowa zone (meter),8305,9001,9807,4495,8801,45.15,9110,8802,-117.3,9110,8805,1.000195,9201,8806,60000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Wallowa zone (international foot),8306,9002,9807,4495,8801,45.15,9110,8802,-117.3,9110,8805,1.000195,9201,8806,196850.3937,9002,8807,0.0,9002,,,,,,
|
||||
Oregon Warner Highway zone (meter),8307,9001,9801,4499,8801,42.3,9110,8802,-120.0,9110,8805,1.000245,9201,8806,40000.0,9001,8807,60000.0,9001,,,,,,
|
||||
Oregon Warner Highway zone (international foot),8308,9002,9801,4495,8801,42.3,9110,8802,-120.0,9110,8805,1.000245,9201,8806,131233.5958,9002,8807,196850.3937,9002,,,,,,
|
||||
Oregon Willamette Pass zone (meter),8309,9001,9807,4499,8801,43.0,9110,8802,-122.0,9110,8805,1.000223,9201,8806,20000.0,9001,8807,0.0,9001,,,,,,
|
||||
Oregon Willamette Pass zone (international foot),8310,9002,9807,4495,8801,43.0,9110,8802,-122.0,9110,8805,1.000223,9201,8806,65616.7979,9002,8807,0.0,9002,,,,,,
|
||||
NCRS Las Vegas zone (m),8373,9001,9807,4499,8801,36.15,9110,8802,-114.58,9110,8805,1.0001,9201,8806,100000.0,9001,8807,200000.0,9001,,,,,,
|
||||
NCRS Las Vegas zone (ftUS),8374,9003,9807,4497,8801,36.15,9110,8802,-114.58,9110,8805,1.0001,9201,8806,328083.3333,9003,8807,656166.6667,9003,,,,,,
|
||||
NCRS Las Vegas high elevation zone (m),8375,9001,9807,4499,8801,36.15,9110,8802,-114.58,9110,8805,1.000135,9201,8806,300000.0,9001,8807,400000.0,9001,,,,,,
|
||||
NCRS Las Vegas high elevation zone (ftUS),8376,9003,9807,4497,8801,36.15,9110,8802,-114.58,9110,8805,1.000135,9201,8806,984250.0,9003,8807,1312333.3333,9003,,,,,,
|
||||
Kansas regional zone 1 Goodland (ftUS),8458,9003,9807,4497,8801,37.3,9110,8802,-101.36,9110,8805,1.000156,9201,8806,1500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 2 Colby (ftUS),8459,9003,9807,4497,8801,37.3,9110,8802,-100.57,9110,8805,1.000134,9201,8806,2500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 3 Oberlin (ftUS),8490,9003,9807,4497,8801,37.3,9110,8802,-100.21,9110,8805,1.000116,9201,8806,3500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 4 Hays (ftUS),8491,9003,9807,4497,8801,37.3,9110,8802,-99.27,9110,8805,1.000082,9201,8806,4500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 5 Great Bend (ftUS),8492,9003,9807,4497,8801,37.3,9110,8802,-98.4,9110,8805,1.000078,9201,8806,5500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 6 Beliot (ftUS),8493,9003,9807,4497,8801,37.3,9110,8802,-98.09,9110,8805,1.000068,9201,8806,6500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 7 Salina (ftUS),8494,9003,9807,4497,8801,37.3,9110,8802,-97.2,9110,8805,1.000049,9201,8806,7500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 8 Manhattan (ftUS),8495,9003,9801,4497,8801,39.1,9110,8802,-96.3,9110,8805,1.000044,9201,8806,8500000.0,9003,8807,600000.0,9003,,,,,,
|
||||
Kansas regional zone 9 Emporia (ftUS),8498,9003,9801,4497,8801,38.3,9110,8802,-96.3,9110,8805,1.00005,9201,8806,9500000.0,9003,8807,300000.0,9003,,,,,,
|
||||
Kansas regional zone 10 Atchison (ftUS),8499,9003,9801,4497,8801,39.38,9110,8802,-95.45,9110,8805,1.00004,9201,8806,10500000.0,9003,8807,700000.0,9003,,,,,,
|
||||
Kansas regional zone 11 Kansas City (ftUS),8500,9003,9801,4497,8801,39.06,9110,8802,-95.15,9110,8805,1.000033,9201,8806,11500000.0,9003,8807,600000.0,9003,,,,,,
|
||||
Kansas regional zone 12 Ulysses (ftUS),8501,9003,9807,4497,8801,36.45,9110,8802,-101.25,9110,8805,1.00014,9201,8806,12500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 13 Garden City (ftUS),8502,9003,9807,4497,8801,36.45,9110,8802,-100.24,9110,8805,1.000109,9201,8806,13500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 14 Dodge City (ftUS),8503,9003,9807,4497,8801,36.45,9110,8802,-99.4,9110,8805,1.000097,9201,8806,14500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 15 Larned (ftUS),8504,9003,9807,4497,8801,36.45,9110,8802,-99.12,9110,8805,1.000087,9201,8806,15500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 16 Pratt (ftUS),8505,9003,9807,4497,8801,36.45,9110,8802,-98.33,9110,8805,1.000069,9201,8806,16500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 17 Wichita (ftUS),8506,9003,9801,4497,8801,37.46,9110,8802,-97.3,9110,8805,1.000059,9201,8806,17500000.0,9003,8807,400000.0,9003,,,,,,
|
||||
Kansas regional zone 18 Arkansas City (ftUS),8507,9003,9801,4497,8801,37.11,9110,8802,-97.3,9110,8805,1.000055,9201,8806,18500000.0,9003,8807,200000.0,9003,,,,,,
|
||||
Kansas regional zone 19 Coffeyville (ftUS),8515,9003,9807,4497,8801,36.45,9110,8802,-95.58,9110,8805,1.000034,9201,8806,19500000.0,9003,8807,0.0,9003,,,,,,
|
||||
Kansas regional zone 20 Pittsburg (ftUS),8516,9003,9807,4497,8801,36.45,9110,8802,-95.05,9110,8805,1.000031,9201,8806,20500000.0,9003,8807,0.0,9003,,,,,,
|
||||
SPCS83 Alabama East zone (US survey foot),9746,9003,9807,4497,8801,30.3,9110,8802,-85.5,9110,8805,0.99996,9201,8806,656166.667,9003,8807,0.0,9003,,,,,,
|
||||
SPCS83 Alabama West zone (US survey foot),9747,9003,9807,4497,8801,30.0,9110,8802,-87.3,9110,8805,0.999933333,9201,8806,1968500.0,9003,8807,0.0,9003,,,,,,
|
||||
Alabama CS27 East zone,10101,9003,9807,4497,8801,30.3,9110,8802,-85.5,9110,8805,0.99996,9201,8806,500000,9003,8807,0,9003,,,,,,
|
||||
Alabama CS27 West zone,10102,9003,9807,4497,8801,30,9110,8802,-87.3,9110,8805,0.999933333,9201,8806,500000,9003,8807,0,9003,,,,,,
|
||||
SPCS83 Alabama East zone (meters),10131,9001,9807,4499,8801,30.3,9110,8802,-85.5,9110,8805,0.99996,9201,8806,200000,9001,8807,0,9001,,,,,,
|
||||
@ -512,6 +773,39 @@ Illinois CS27 East zone,11201,9003,9807,4497,8801,36.4,9110,8802,-88.2,9110,8805
|
||||
Illinois CS27 West zone,11202,9003,9807,4497,8801,36.4,9110,8802,-90.1,9110,8805,0.999941177,9201,8806,500000,9003,8807,0,9003,,,,,,
|
||||
SPCS83 Illinois East zone (meters),11231,9001,9807,4499,8801,36.4,9110,8802,-88.2,9110,8805,0.999975,9201,8806,300000,9001,8807,0,9001,,,,,,
|
||||
SPCS83 Illinois West zone (meters),11232,9001,9807,4499,8801,36.4,9110,8802,-90.1,9110,8805,0.999941177,9201,8806,700000,9001,8807,0,9001,,,,,,
|
||||
Illinois Coordinate System of 1983 Aurora zone (US survey foot),11233,9003,9807,1053,8801,41.15,9110,8802,-88.3,9110,8805,1.00003,9201,8806,3773000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Chicago zone (US survey foot),11234,9003,9807,1053,8801,41.15,9110,8802,-87.48,9110,8805,1.000023,9201,8806,4757000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Moline zone (US survey foot),11235,9003,9801,1053,8801,41.33,9110,8802,-90.36,9110,8805,1.000024,9201,8806,5741000.0,9003,8807,755000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Sterling zone (US survey foot),11236,9003,9801,1053,8801,41.33,9110,8802,-90.03,9110,8805,1.00002,9201,8806,6726000.0,9003,8807,755000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Ottawa zone (US survey foot),11237,9003,9801,1053,8801,41.18,9110,8802,-89.03,9110,8805,1.000023,9201,8806,7743000.0,9003,8807,755000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Joliet zone (US survey foot),11238,9003,9807,1053,8801,40.33,9110,8802,-88.0,9110,8805,1.000022,9201,8806,8694000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Monmouth zone (US survey foot),11239,9003,9807,1053,8801,40.12,9110,8802,-90.51,9110,8805,1.000024,9201,8806,9678000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Galesburg zone (US survey foot),11240,9003,9807,1053,8801,37.15,9110,8802,-90.06,9110,8805,1.000023,9201,8806,230000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Peoria zone (US survey foot),11241,9003,9807,1053,8801,37.24,9110,8802,-89.39,9110,8805,1.000023,9201,8806,1378000.0,9003,8807,622000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Eureka zone (US survey foot),11242,9003,9807,1053,8801,37.27,9110,8802,-89.18,9110,8805,1.000025,9201,8806,2756000.0,9003,8807,427000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Bloomington zone (US survey foot),11243,9003,9801,1053,8801,40.3,9110,8802,-88.51,9110,8805,1.000031,9201,8806,3773000.0,9003,8807,1739000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Pontiac zone (US survey foot),11244,9003,9801,1053,8801,40.54,9110,8802,-88.33,9110,8805,1.000025,9201,8806,4757000.0,9003,8807,1739000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Watseka zone (US survey foot),11245,9003,9801,1053,8801,40.45,9110,8802,-87.57,9110,8805,1.000024,9201,8806,5741000.0,9003,8807,1739000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Quincy zone (US survey foot),11246,9003,9807,1053,8801,36.45,9110,8802,-91.15,9110,8805,1.000023,9201,8806,6726000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Macomb zone (US survey foot),11247,9003,9807,1053,8801,36.48,9110,8802,-90.36,9110,8805,1.000024,9201,8806,7710000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Lincoln zone (US survey foot),11248,9003,9801,1053,8801,40.09,9110,8802,-89.48,9110,8805,1.000018,9201,8806,8760000.0,9003,8807,1739000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Decatur zone (US survey foot),11249,9003,9807,1053,8801,36.18,9110,8802,-88.48,9110,8805,1.000024,9201,8806,9678000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Champaign zone (US survey foot),11250,9003,9801,1053,8801,40.09,9110,8802,-88.0,9110,8805,1.000026,9201,8806,328000.0,9003,8807,2822000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Jacksonville zone (US survey foot),11251,9003,9801,1053,8801,39.39,9110,8802,-90.36,9110,8805,1.000023,9201,8806,1247000.0,9003,8807,2822000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Springfield zone (US survey foot),11252,9003,9801,1053,8801,39.45,9110,8802,-89.39,9110,8805,1.000022,9201,8806,2329000.0,9003,8807,2887000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Charleston zone (US survey foot),11253,9003,9801,1053,8801,39.39,9110,8802,-88.0,9110,8805,1.000024,9201,8806,3773000.0,9003,8807,2756000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Jerseyville zone (US survey foot),11254,9003,9807,1053,8801,32.51,9110,8802,-90.3,9110,8805,1.000019,9201,8806,4757000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Carlinville zone (US survey foot),11255,9003,9801,1053,8801,39.18,9110,8802,-90.09,9110,8805,1.00002,9201,8806,5741000.0,9003,8807,2756000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Taylorville zone (US survey foot),11256,9003,9807,1053,8801,33.09,9110,8802,-89.24,9110,8805,1.000023,9201,8806,6726000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Effingham zone (US survey foot),11257,9003,9801,1053,8801,38.57,9110,8802,-89.0,9110,8805,1.000019,9201,8806,7710000.0,9003,8807,2756000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Robinson zone (US survey foot),11258,9003,9801,1053,8801,39.06,9110,8802,-88.0,9110,8805,1.000017,9201,8806,8694000.0,9003,8807,2756000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Belleville zone (US survey foot),11259,9003,9807,1053,8801,32.21,9110,8802,-90.0,9110,8805,1.000016,9201,8806,9678000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Mount Vernon zone (US survey foot),11260,9003,9801,1053,8801,38.27,9110,8802,-89.09,9110,8805,1.000015,9201,8806,328000.0,9003,8807,3773000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Olney zone (US survey foot),11261,9003,9801,1053,8801,38.33,9110,8802,-88.09,9110,8805,1.000013,9201,8806,1247000.0,9003,8807,3773000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Carbondale zone (US survey foot),11262,9003,9801,1053,8801,37.54,9110,8802,-88.57,9110,8805,1.000012,9201,8806,2395000.0,9003,8807,3773000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Metropolis zone (US survey foot),11263,9003,9801,1053,8801,37.12,9110,8802,-88.54,9110,8805,1.00001,9201,8806,3642000.0,9003,8807,3839000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Freeport zone (US survey foot),11264,9003,9801,1053,8801,42.12,9110,8802,-89.57,9110,8805,1.000029,9201,8806,1804000.0,9003,8807,755000.0,9003,,,,,,
|
||||
Illinois Coordinate System of 1983 Rockford zone (US survey foot),11265,9003,9807,1053,8801,41.15,9110,8802,-89.15,9110,8805,1.000029,9201,8806,2822000.0,9003,8807,492000.0,9003,,,,,,
|
||||
Indiana CS27 East zone,11301,9003,9807,4497,8801,37.3,9110,8802,-85.4,9110,8805,0.999966667,9201,8806,500000,9003,8807,0,9003,,,,,,
|
||||
Indiana CS27 West zone,11302,9003,9807,4497,8801,37.3,9110,8802,-87.05,9110,8805,0.999966667,9201,8806,500000,9003,8807,0,9003,,,,,,
|
||||
SPCS83 Indiana East zone (meters),11331,9001,9807,4499,8801,37.3,9110,8802,-85.4,9110,8805,0.999966667,9201,8806,100000,9001,8807,250000,9001,,,,,,
|
||||
|
|
11
gpxsee.pro
@ -3,7 +3,7 @@ unix:!macx:!android {
|
||||
} else {
|
||||
TARGET = GPXSee
|
||||
}
|
||||
VERSION = 13.17
|
||||
VERSION = 13.20
|
||||
|
||||
|
||||
QT += core \
|
||||
@ -128,6 +128,10 @@ HEADERS += src/common/config.h \
|
||||
src/map/ENC/objects.h \
|
||||
src/map/ENC/rastertile.h \
|
||||
src/map/ENC/style.h \
|
||||
src/map/IMG/dem.h \
|
||||
src/map/IMG/demfile.h \
|
||||
src/map/IMG/demtile.h \
|
||||
src/map/IMG/jls.h \
|
||||
src/map/IMG/section.h \
|
||||
src/map/IMG/zoom.h \
|
||||
src/map/conversion.h \
|
||||
@ -135,6 +139,7 @@ HEADERS += src/common/config.h \
|
||||
src/map/encjob.h \
|
||||
src/map/encmap.h \
|
||||
src/map/ENC/iso8211.h \
|
||||
src/map/filter.h \
|
||||
src/map/gemfmap.h \
|
||||
src/map/gmifile.h \
|
||||
src/map/oruxmap.h \
|
||||
@ -345,10 +350,14 @@ SOURCES += src/main.cpp \
|
||||
src/map/ENC/mapdata.cpp \
|
||||
src/map/ENC/rastertile.cpp \
|
||||
src/map/ENC/style.cpp \
|
||||
src/map/IMG/dem.cpp \
|
||||
src/map/IMG/demfile.cpp \
|
||||
src/map/IMG/jls.cpp \
|
||||
src/map/conversion.cpp \
|
||||
src/map/encatlas.cpp \
|
||||
src/map/encmap.cpp \
|
||||
src/map/ENC/iso8211.cpp \
|
||||
src/map/filter.cpp \
|
||||
src/map/gemfmap.cpp \
|
||||
src/map/gmifile.cpp \
|
||||
src/map/oruxmap.cpp \
|
||||
|
@ -4,7 +4,7 @@ while read e; do
|
||||
IFS=":"; set $e
|
||||
|
||||
EXT=`echo $1 | tr /a-z/ /A-Z/`
|
||||
sed -e "s/\$EXTENSION/$EXT/" -e "s/\$COLOR/$2/" icon-template.svg > $1.svg
|
||||
sed -e "s/\$EXT/$EXT/" -e "s/\$COLOR/$2/" icon-template.svg > $1.svg
|
||||
|
||||
ICONSET=$1.iconset
|
||||
mkdir $ICONSET
|
||||
|
@ -4,7 +4,7 @@ while read e; do
|
||||
IFS=":"; set $e
|
||||
|
||||
EXT=`echo $1 | tr /a-z/ /A-Z/`
|
||||
sed -e "s/\$EXTENSION/$EXT/" -e "s/\$COLOR/$2/" icon-template.svg > $1.svg
|
||||
sed -e "s/\$EXT/$EXT/" -e "s/\$COLOR/$2/" icon-template.svg > $1.svg
|
||||
convert -density 400 -background none $1.svg -define icon:auto-resize $1.ico
|
||||
rm $1.svg
|
||||
done < extensions
|
||||
|
@ -13,8 +13,8 @@
|
||||
<g transform="translate(16.573463,124.9782)">
|
||||
<rect y="0" x="0" id="textrect" height="50" width="120" style="fill:$COLOR;fill-opacity:1;stroke:none;"/>
|
||||
<!--
|
||||
<text y="28" x="60" dominant-baseline="central" text-anchor="middle" style="fill:#FFFFFF;font-size:39px;font-family:Helvetica;font-weight:bold;">$EXTENSION</text>
|
||||
<text y="28" x="60" dominant-baseline="central" text-anchor="middle" style="fill:#FFFFFF;font-size:39px;font-family:Helvetica;font-weight:bold;">$EXT</text>
|
||||
-->
|
||||
<text y="25" x="60" dy="0.36em" text-anchor="middle" style="fill:#FFFFFF;font-size:39px;font-family:Helvetica;font-weight:bold;">$EXTENSION</text>
|
||||
<text y="25" x="60" dy="0.36em" text-anchor="middle" style="fill:#FFFFFF;font-size:39px;font-family:Helvetica;font-weight:bold;">$EXT</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
icons/symbols/Alert.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 987 B After Width: | Height: | Size: 884 B |
BIN
icons/symbols/Checkpoint.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
icons/symbols/Danger.png
Normal file
After Width: | Height: | Size: 767 B |
BIN
icons/symbols/First Aid.png
Normal file
After Width: | Height: | Size: 606 B |
BIN
icons/symbols/First Category.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 747 B After Width: | Height: | Size: 824 B |
Before Width: | Height: | Size: 724 B After Width: | Height: | Size: 822 B |
Before Width: | Height: | Size: 724 B After Width: | Height: | Size: 822 B |
BIN
icons/symbols/Food.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
icons/symbols/Fourth Category.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
icons/symbols/Gear.png
Normal file
After Width: | Height: | Size: 976 B |
BIN
icons/symbols/Hors Category.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
icons/symbols/Info.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
icons/symbols/Left.png
Normal file
After Width: | Height: | Size: 810 B |
BIN
icons/symbols/Meeting Spot.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/symbols/Obstacle.png
Normal file
After Width: | Height: | Size: 863 B |
BIN
icons/symbols/Overlook.png
Normal file
After Width: | Height: | Size: 821 B |
BIN
icons/symbols/Rest Area.png
Normal file
After Width: | Height: | Size: 918 B |
BIN
icons/symbols/Right.png
Normal file
After Width: | Height: | Size: 821 B |
BIN
icons/symbols/Second Category.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
icons/symbols/Segment End.png
Normal file
After Width: | Height: | Size: 792 B |
BIN
icons/symbols/Segment Start.png
Normal file
After Width: | Height: | Size: 724 B |
BIN
icons/symbols/Service.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
icons/symbols/Sharp Curve.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
icons/symbols/Sharp Left.png
Normal file
After Width: | Height: | Size: 942 B |
BIN
icons/symbols/Sharp Right.png
Normal file
After Width: | Height: | Size: 909 B |
BIN
icons/symbols/Shelter.png
Normal file
After Width: | Height: | Size: 764 B |
BIN
icons/symbols/Slight Left.png
Normal file
After Width: | Height: | Size: 826 B |
BIN
icons/symbols/Slight Right.png
Normal file
After Width: | Height: | Size: 825 B |
BIN
icons/symbols/Sprint.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
icons/symbols/Steep Incline.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
icons/symbols/Store.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/symbols/Straight.png
Normal file
After Width: | Height: | Size: 791 B |
BIN
icons/symbols/Third Category.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
icons/symbols/Toilet.png
Normal file
After Width: | Height: | Size: 989 B |
BIN
icons/symbols/Transport.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
icons/symbols/U-Turn.png
Normal file
After Width: | Height: | Size: 989 B |
BIN
icons/symbols/Valley.png
Normal file
After Width: | Height: | Size: 1018 B |
BIN
icons/symbols/Water.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 747 B After Width: | Height: | Size: 824 B |
@ -577,7 +577,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="471"/>
|
||||
<source>Show hillshading</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Показывать отмывку рельефа</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="480"/>
|
||||
@ -832,7 +832,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1986"/>
|
||||
<source>DEM tiles download limit exceeded. If you really need data for such a huge area, download the files manually.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Превышен лимит загрузки DEM тайлов. Если вам действительно нужны данные для такой огромной области, загрузите файлы вручную.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="2002"/>
|
||||
@ -882,12 +882,12 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="457"/>
|
||||
<source>Download data DEM</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Скачать данные DEM</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="463"/>
|
||||
<source>Download map DEM</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Скачать карту DEM</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="739"/>
|
||||
@ -951,10 +951,10 @@
|
||||
<message numerus="yes">
|
||||
<location filename="../src/GUI/gui.cpp" line="1989"/>
|
||||
<source>Download %n DEM tiles?</source>
|
||||
<translation type="unfinished">
|
||||
<numerusform></numerusform>
|
||||
<numerusform></numerusform>
|
||||
<numerusform></numerusform>
|
||||
<translation>
|
||||
<numerusform>Скачать %n DEM тайл?</numerusform>
|
||||
<numerusform>Скачать %n DEM тайла?</numerusform>
|
||||
<numerusform>Скачать %n DEM тайлов?</numerusform>
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -769,12 +769,12 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="457"/>
|
||||
<source>Download data DEM</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Завантажити дані DEM</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="463"/>
|
||||
<source>Download map DEM</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Завантажити карту DEM</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="698"/>
|
||||
|
@ -571,12 +571,12 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="457"/>
|
||||
<source>Download data DEM</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>下载 DEM 数据</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="463"/>
|
||||
<source>Download map DEM</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>下载 DEM 地图</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="468"/>
|
||||
@ -586,7 +586,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="471"/>
|
||||
<source>Show hillshading</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>显示山体阴影</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="480"/>
|
||||
@ -1034,13 +1034,13 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="1986"/>
|
||||
<source>DEM tiles download limit exceeded. If you really need data for such a huge area, download the files manually.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>已超过 DEM 瓦片下载限额。如您确需大量数据,请手动下载。</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../src/GUI/gui.cpp" line="1989"/>
|
||||
<source>Download %n DEM tiles?</source>
|
||||
<translation type="unfinished">
|
||||
<numerusform></numerusform>
|
||||
<translation>
|
||||
<numerusform>下载 %n DEM 瓦片?</numerusform>
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -269,6 +269,7 @@
|
||||
<root-XML namespaceURI="http://www.gpxsee.org/map/1.2" localName="map"/>
|
||||
<root-XML namespaceURI="http://www.gpxsee.org/map/1.3" localName="map"/>
|
||||
<root-XML namespaceURI="http://www.gpxsee.org/map/1.4" localName="map"/>
|
||||
<root-XML namespaceURI="http://www.gpxsee.org/map/1.5" localName="map"/>
|
||||
<glob pattern="*.xml"/>
|
||||
</mime-type>
|
||||
|
||||
|
@ -1712,7 +1712,7 @@
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.gpxsee.map</string>
|
||||
<key>UTTypeReferenceURL</key>
|
||||
<string>http://www.gpxsee.org/map/1.4/</string>
|
||||
<string>http://www.gpxsee.org/map/1.5/</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>GPXSee Map Definition File</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
|
@ -37,7 +37,7 @@ Unicode true
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "13.17"
|
||||
!define VERSION "13.20"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||
|
@ -29,9 +29,9 @@ App::App(int &argc, char **argv) : QApplication(argc, argv)
|
||||
{
|
||||
#if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
|
||||
setApplicationName(APP_NAME);
|
||||
#else
|
||||
#else // Q_OS_WIN32 || Q_OS_MAC
|
||||
setApplicationName(QString(APP_NAME).toLower());
|
||||
#endif
|
||||
#endif // Q_OS_WIN32 || Q_OS_MAC
|
||||
setApplicationVersion(APP_VERSION);
|
||||
|
||||
QTranslator *app = new QTranslator(this);
|
||||
@ -65,6 +65,9 @@ App::App(int &argc, char **argv) : QApplication(argc, argv)
|
||||
loadPCSs();
|
||||
Waypoint::loadSymbolIcons(ProgramPaths::symbolsDir());
|
||||
|
||||
#if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
|
||||
QIcon::setThemeName(APP_NAME);
|
||||
#endif // Q_OS_WIN32 || Q_OS_MAC
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
|
||||
QIcon::setFallbackThemeName(APP_NAME);
|
||||
#endif // QT 5.12
|
||||
|
@ -471,7 +471,6 @@ void GUI::createActions()
|
||||
_drawHillShadingAction = new QAction(tr("Show hillshading"), this);
|
||||
_drawHillShadingAction->setMenuRole(QAction::NoRole);
|
||||
_drawHillShadingAction->setCheckable(true);
|
||||
_drawHillShadingAction->setEnabled(false);
|
||||
connect(_drawHillShadingAction, &QAction::triggered, _mapView,
|
||||
&MapView::drawHillShading);
|
||||
|
||||
@ -2249,8 +2248,7 @@ void GUI::updateDataDEMDownloadAction()
|
||||
void GUI::updateMapDEMDownloadAction()
|
||||
{
|
||||
_downloadMapDEMAction->setEnabled(!_dem->url().isEmpty()
|
||||
&& _map->usesDEM() && !_dem->checkTiles(_map->llBounds()));
|
||||
_drawHillShadingAction->setEnabled(_map->usesDEM());
|
||||
&& !_dem->checkTiles(_map->llBounds()));
|
||||
}
|
||||
|
||||
void GUI::setTimeType(TimeType type)
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <QClipboard>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QGeoPositionInfoSource>
|
||||
#include "common/dem.h"
|
||||
#include "data/poi.h"
|
||||
#include "data/data.h"
|
||||
#include "map/map.h"
|
||||
@ -1181,9 +1180,7 @@ void MapView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (_cursorCoordinates->isVisible()) {
|
||||
Coordinates c(_map->xy2ll(mapToScene(event->pos())));
|
||||
DEM::lock();
|
||||
_cursorCoordinates->setCoordinates(c, DEM::elevation(c));
|
||||
DEM::unlock();
|
||||
_cursorCoordinates->setCoordinates(c, _map->elevation(c));
|
||||
}
|
||||
|
||||
QGraphicsView::mouseMoveEvent(event);
|
||||
|
@ -727,14 +727,14 @@ QWidget *OptionsDialog::createSystemPage()
|
||||
_enableHTTP2->setChecked(_options.enableHTTP2);
|
||||
|
||||
_pixmapCache = new QSpinBox();
|
||||
_pixmapCache->setMinimum(16);
|
||||
_pixmapCache->setMaximum(2048);
|
||||
_pixmapCache->setMinimum(64);
|
||||
_pixmapCache->setMaximum(4096);
|
||||
_pixmapCache->setSuffix(UNIT_SPACE + tr("MB"));
|
||||
_pixmapCache->setValue(_options.pixmapCache);
|
||||
|
||||
_demCache = new QSpinBox();
|
||||
_demCache->setMinimum(64);
|
||||
_demCache->setMaximum(2048);
|
||||
_demCache->setMaximum(4096);
|
||||
_demCache->setSuffix(UNIT_SPACE + tr("MB"));
|
||||
_demCache->setValue(_options.demCache);
|
||||
|
||||
|
@ -174,7 +174,7 @@ SETTING(markerInfo, "markerInfo", MarkerInfoItem::None );
|
||||
SETTING(useStyles, "styles", true );
|
||||
|
||||
/* DEM */
|
||||
SETTING(drawHillShading, "hillshading", false );
|
||||
SETTING(drawHillShading, "hillshading", true );
|
||||
|
||||
/* Position */
|
||||
SETTING(showPosition, "show", false );
|
||||
|
@ -13,15 +13,18 @@ static Qt::PenStyle styles[] = {Qt::SolidLine, Qt::DashLine, Qt::DotLine,
|
||||
|
||||
QIcon StyleComboBox::icon(Qt::PenStyle style)
|
||||
{
|
||||
QPixmap pm(iconSize());
|
||||
qreal ratio(devicePixelRatioF());
|
||||
QSize size(iconSize());
|
||||
QPixmap pm(size * ratio);
|
||||
pm.setDevicePixelRatio(ratio);
|
||||
pm.fill(Qt::transparent);
|
||||
|
||||
QBrush brush(QPalette().brush(QPalette::Active, QPalette::WindowText));
|
||||
QPen pen(brush, pm.height() / LINE_WIDTH_RATIO, style);
|
||||
QPen pen(brush, size.height() / LINE_WIDTH_RATIO, style);
|
||||
|
||||
QPainter painter(&pm);
|
||||
painter.setPen(pen);
|
||||
painter.drawLine(0, pm.height() / 2, pm.width(), pm.height() / 2);
|
||||
painter.drawLine(0, size.height() / 2, size.width(), size.height() / 2);
|
||||
|
||||
return QIcon(pm);
|
||||
}
|
||||
|
@ -170,8 +170,7 @@ void WaypointItem::paint(QPainter *painter,
|
||||
if (_font.bold())
|
||||
painter->drawPixmap(-_icon->width() * 0.625, icon.isNull()
|
||||
? -_icon->height() * 1.25 : -_icon->height() * 0.625,
|
||||
_icon->scaled(_icon->width() * 1.25, _icon->height() * 1.25,
|
||||
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
_icon->scaled(_icon->width() * 1.25, _icon->height() * 1.25));
|
||||
else
|
||||
painter->drawPixmap(-_icon->width()/2.0, icon.isNull()
|
||||
? -_icon->height() : -_icon->height()/2, *_icon);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
WARNING: This code uses internal Qt API - the QZipReader class for reading
|
||||
ZIP files - and things may break if Qt changes the API. For Qt5 this is not
|
||||
a problem as we can "see the future" now and there are no changes in all
|
||||
@ -65,7 +65,7 @@ QString DEM::Tile::lonStr() const
|
||||
return QString("%1%2").arg(ew).arg(qAbs(_lon), 3, 10, QChar('0'));
|
||||
}
|
||||
|
||||
QString DEM::Tile::baseName() const
|
||||
QString DEM::Tile::fileName() const
|
||||
{
|
||||
return QString("%1%2.hgt").arg(latStr(), lonStr());
|
||||
}
|
||||
@ -75,7 +75,7 @@ DEM::TileCache DEM::_data;
|
||||
|
||||
void DEM::setCacheSize(int size)
|
||||
{
|
||||
_data.setMaxCost(size * 1024);
|
||||
_data.setMaxCost(size);
|
||||
}
|
||||
|
||||
void DEM::setDir(const QString &path)
|
||||
@ -108,15 +108,15 @@ double DEM::height(const Coordinates &c, const Entry *e)
|
||||
|
||||
DEM::Entry *DEM::loadTile(const Tile &tile)
|
||||
{
|
||||
QString bn(tile.baseName());
|
||||
QString fn(QDir(_dir).absoluteFilePath(bn));
|
||||
QString zn(fn + ".zip");
|
||||
QString fileName(tile.fileName());
|
||||
QString path(QDir(_dir).absoluteFilePath(fileName));
|
||||
QString zipPath(path + ".zip");
|
||||
|
||||
if (QFileInfo::exists(zn)) {
|
||||
QZipReader zip(zn, QIODevice::ReadOnly);
|
||||
return new Entry(zip.fileData(bn));
|
||||
if (QFileInfo::exists(zipPath)) {
|
||||
QZipReader zip(zipPath, QIODevice::ReadOnly);
|
||||
return new Entry(zip.fileData(fileName));
|
||||
} else {
|
||||
QFile file(fn);
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qWarning("%s: %s", qPrintable(file.fileName()),
|
||||
qPrintable(file.errorString()));
|
||||
@ -138,7 +138,7 @@ double DEM::elevation(const Coordinates &c)
|
||||
if (!e) {
|
||||
e = loadTile(tile);
|
||||
ele = height(c, e);
|
||||
_data.insert(tile, e, e->data().size());
|
||||
_data.insert(tile, e, e->data().size() / 1024);
|
||||
} else
|
||||
ele = height(c, e);
|
||||
|
||||
@ -147,15 +147,15 @@ double DEM::elevation(const Coordinates &c)
|
||||
|
||||
QList<Area> DEM::tiles()
|
||||
{
|
||||
static const QRegularExpression re("([NS])([0-9]{2})([EW])([0-9]{3})");
|
||||
static const QRegularExpression re(
|
||||
"^([NS])([0-9]{2})([EW])([0-9]{3})(\\.hgt|\\.hgt\\.zip)$");
|
||||
QDir dir(_dir);
|
||||
QFileInfoList files(dir.entryInfoList(QDir::Files | QDir::Readable));
|
||||
QLocale l(QLocale::system());
|
||||
QList<Area> list;
|
||||
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
QString basename(files.at(i).baseName());
|
||||
QRegularExpressionMatch match(re.match(basename));
|
||||
QRegularExpressionMatch match(re.match(files.at(i).fileName()));
|
||||
if (!match.hasMatch())
|
||||
continue;
|
||||
|
||||
@ -167,7 +167,7 @@ QList<Area> DEM::tiles()
|
||||
lon = -lon;
|
||||
|
||||
Area area(RectC(Coordinates(lon, lat + 1), Coordinates(lon + 1, lat)));
|
||||
area.setName(basename);
|
||||
area.setName(files.at(i).baseName());
|
||||
area.setDescription(files.at(i).suffix().toUpper() + ", "
|
||||
+ l.formattedDataSize(files.at(i).size()));
|
||||
area.setStyle(PolygonStyle(QColor(0xFF, 0, 0, 0x40),
|
||||
@ -182,7 +182,7 @@ QList<Area> DEM::tiles()
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const DEM::Tile &tile)
|
||||
{
|
||||
dbg.nospace() << "Tile(" << tile.baseName() << ")";
|
||||
dbg.nospace() << "Tile(" << tile.fileName() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
|
||||
QString lonStr() const;
|
||||
QString latStr() const;
|
||||
QString baseName() const;
|
||||
QString fileName() const;
|
||||
|
||||
bool operator==(const Tile &other) const
|
||||
{
|
||||
|
@ -110,7 +110,7 @@ QUrl DEMLoader::tileUrl(const DEM::Tile &tile) const
|
||||
|
||||
QString DEMLoader::tileFile(const DEM::Tile &tile) const
|
||||
{
|
||||
return _dir.absoluteFilePath(tile.baseName());
|
||||
return _dir.absoluteFilePath(tile.fileName());
|
||||
}
|
||||
|
||||
void DEMLoader::setAuthorization(const Authorization &authorization)
|
||||
|
@ -14,22 +14,27 @@ bool CSVParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
bool ok;
|
||||
|
||||
while (!csv.atEnd()) {
|
||||
if (!csv.readEntry(entry) || entry.size() < 3) {
|
||||
if (!csv.readEntry(entry)) {
|
||||
_errorString = "Parse error";
|
||||
_errorLine = csv.line();
|
||||
return false;
|
||||
}
|
||||
if (entry.size() < 3) {
|
||||
_errorString = "Invalid column count";
|
||||
_errorLine = csv.line() - 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
double lon = entry.at(0).toDouble(&ok);
|
||||
if (!ok || (lon < -180.0 || lon > 180.0)) {
|
||||
_errorString = "Invalid longitude";
|
||||
_errorLine = csv.line();
|
||||
_errorLine = csv.line() - 1;
|
||||
return false;
|
||||
}
|
||||
double lat = entry.at(1).toDouble(&ok);
|
||||
if (!ok || (lat < -90.0 || lat > 90.0)) {
|
||||
_errorString = "Invalid latitude";
|
||||
_errorLine = csv.line();
|
||||
_errorLine = csv.line() - 1;
|
||||
return false;
|
||||
}
|
||||
Waypoint wp(Coordinates(lon, lat));
|
||||
|
@ -159,7 +159,7 @@ bool CUPParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
return false;
|
||||
}
|
||||
|
||||
_errorLine = csv.line();
|
||||
_errorLine = csv.line() - 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -106,7 +106,7 @@ Data::Data(const QString &fileName, bool tryUnknown)
|
||||
_errorLine = 0;
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
_errorString = qPrintable(file.errorString());
|
||||
_errorString = file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
SegmentData segment;
|
||||
};
|
||||
|
||||
static QMap<int, QString> coursePointDescInit()
|
||||
static QMap<int, QString> coursePointSymbolsInit()
|
||||
{
|
||||
QMap<int, QString> map;
|
||||
|
||||
@ -76,28 +76,70 @@ static QMap<int, QString> coursePointDescInit()
|
||||
map.insert(6, "Left");
|
||||
map.insert(7, "Right");
|
||||
map.insert(8, "Straight");
|
||||
map.insert(9, "First aid");
|
||||
map.insert(10, "Fourth category");
|
||||
map.insert(11, "Third category");
|
||||
map.insert(12, "Second category");
|
||||
map.insert(13, "First category");
|
||||
map.insert(14, "Hors category");
|
||||
map.insert(9, "First Aid");
|
||||
map.insert(10, "Fourth Category");
|
||||
map.insert(11, "Third Category");
|
||||
map.insert(12, "Second Category");
|
||||
map.insert(13, "First Category");
|
||||
map.insert(14, "Hors Category");
|
||||
map.insert(15, "Sprint");
|
||||
map.insert(16, "Left fork");
|
||||
map.insert(17, "Right fork");
|
||||
map.insert(18, "Middle fork");
|
||||
map.insert(19, "Slight left");
|
||||
map.insert(20, "Sharp left");
|
||||
map.insert(21, "Slight right");
|
||||
map.insert(22, "Sharp right");
|
||||
map.insert(16, "Left Fork");
|
||||
map.insert(17, "Right Fork");
|
||||
map.insert(18, "Middle Fork");
|
||||
map.insert(19, "Slight Left");
|
||||
map.insert(20, "Sharp Left");
|
||||
map.insert(21, "Slight Right");
|
||||
map.insert(22, "Sharp Right");
|
||||
map.insert(23, "U-Turn");
|
||||
map.insert(24, "Segment start");
|
||||
map.insert(25, "Segment end");
|
||||
map.insert(24, "Segment Start");
|
||||
map.insert(25, "Segment End");
|
||||
map.insert(27, "Campground");
|
||||
map.insert(28, "Aid Station");
|
||||
map.insert(29, "Rest Area");
|
||||
map.insert(30, "General Distance");
|
||||
map.insert(31, "Service");
|
||||
map.insert(32, "Energy Gel");
|
||||
map.insert(33, "Sports Drink");
|
||||
map.insert(34, "Mile Marker");
|
||||
map.insert(35, "Checkpoint");
|
||||
map.insert(36, "Shelter");
|
||||
map.insert(37, "Meeting Spot");
|
||||
map.insert(38, "Overlook");
|
||||
map.insert(39, "Toilet");
|
||||
map.insert(40, "Shower");
|
||||
map.insert(41, "Gear");
|
||||
map.insert(42, "Sharp Curve");
|
||||
map.insert(43, "Steep Incline");
|
||||
map.insert(44, "Tunnel");
|
||||
map.insert(45, "Bridge");
|
||||
map.insert(46, "Obstacle");
|
||||
map.insert(47, "Crossing");
|
||||
map.insert(48, "Store");
|
||||
map.insert(49, "Transition");
|
||||
map.insert(50, "Navaid");
|
||||
map.insert(51, "Transport");
|
||||
map.insert(52, "Alert");
|
||||
map.insert(53, "Info");
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static QMap<int, QString> coursePointDesc = coursePointDescInit();
|
||||
static QMap<int, QString> locationPointSymbolsInit()
|
||||
{
|
||||
QMap<int, QString> map;
|
||||
|
||||
/* The location symbols are a typical GARMIN mess. Every GPS unit
|
||||
has probably its own list, so we only add a few generic icons seen
|
||||
"in the wild" most often. */
|
||||
map.insert(94, "Flag, Blue");
|
||||
map.insert(95, "Flag, Green");
|
||||
map.insert(96, "Flag, Red");
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static QMap<int, QString> coursePointSymbols = coursePointSymbolsInit();
|
||||
static QMap<int, QString> locationPointSymbols = locationPointSymbolsInit();
|
||||
|
||||
|
||||
bool FITParser::readData(QFile *file, char *data, size_t size)
|
||||
@ -244,7 +286,7 @@ bool FITParser::readField(CTX &ctx, Field *field, QVariant &val, bool &valid)
|
||||
ctx.len -= field->size;
|
||||
ret = (ba.size() == field->size);
|
||||
val = ret ? ba : QString();
|
||||
valid = !ba.isEmpty();}
|
||||
valid = (!ba.isEmpty() && ba.at(0) != 0);}
|
||||
break;
|
||||
default:
|
||||
ret = skipValue(ctx, field->size);
|
||||
@ -330,8 +372,8 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
|
||||
} else if (def->globalId == COURSE_POINT) {
|
||||
switch (field->id) {
|
||||
case 1:
|
||||
waypoint.setTimestamp(QDateTime::fromSecsSinceEpoch(val.toUInt()
|
||||
+ 631065600, Qt::UTC));
|
||||
waypoint.setTimestamp(QDateTime::fromSecsSinceEpoch(
|
||||
val.toUInt() + 631065600, Qt::UTC));
|
||||
break;
|
||||
case 2:
|
||||
waypoint.rcoordinates().setLat(
|
||||
@ -342,7 +384,7 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
|
||||
(val.toInt() / (double)0x7fffffff) * 180);
|
||||
break;
|
||||
case 5:
|
||||
waypoint.setDescription(coursePointDesc.value(val.toUInt()));
|
||||
waypoint.setSymbol(coursePointSymbols.value(val.toUInt()));
|
||||
break;
|
||||
case 6:
|
||||
waypoint.setName(val.toString());
|
||||
@ -361,6 +403,9 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
|
||||
waypoint.rcoordinates().setLon(
|
||||
(val.toInt() / (double)0x7fffffff) * 180);
|
||||
break;
|
||||
case 3:
|
||||
waypoint.setSymbol(locationPointSymbols.value(val.toUInt()));
|
||||
break;
|
||||
case 4:
|
||||
waypoint.setElevation((val.toUInt() / 5.0) - 500);
|
||||
break;
|
||||
@ -386,8 +431,8 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
|
||||
}
|
||||
} else if (def->globalId == RECORD_MESSAGE) {
|
||||
if (ctx.trackpoint.coordinates().isValid()) {
|
||||
ctx.trackpoint.setTimestamp(QDateTime::fromSecsSinceEpoch(ctx.timestamp
|
||||
+ 631065600, Qt::UTC));
|
||||
ctx.trackpoint.setTimestamp(QDateTime::fromSecsSinceEpoch(
|
||||
ctx.timestamp + 631065600, Qt::UTC));
|
||||
ctx.trackpoint.setRatio(ctx.ratio);
|
||||
ctx.segment.append(ctx.trackpoint);
|
||||
ctx.trackpoint = Trackpoint();
|
||||
@ -478,8 +523,7 @@ bool FITParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
if (!parseRecord(ctx))
|
||||
return false;
|
||||
|
||||
tracks.append(TrackData());
|
||||
tracks.last().append(ctx.segment);
|
||||
tracks.append(ctx.segment);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,11 +1,19 @@
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include "map/crs.h"
|
||||
#include "geojsonparser.h"
|
||||
|
||||
#define MARKER_SIZE_MEDIUM 12
|
||||
#define MARKER_SIZE_SMALL 8
|
||||
#define MARKER_SIZE_LARGE 16
|
||||
|
||||
#define PROJ(object, parent) \
|
||||
((object).isNull() ? (parent) : (object))
|
||||
|
||||
/*
|
||||
* Mapbox Simple Style
|
||||
* https://github.com/mapbox/simplestyle-spec
|
||||
*/
|
||||
static int markerSize(const QString &str)
|
||||
{
|
||||
if (str == "small")
|
||||
@ -104,12 +112,80 @@ static void setWaypointProperties(Waypoint &waypoint,
|
||||
waypoint.setStyle(PointStyle(color, size));
|
||||
}
|
||||
|
||||
/*
|
||||
* Mapbox Coordinate Properties
|
||||
* https://github.com/mapbox/geojson-coordinate-properties
|
||||
*/
|
||||
static QDateTime timestamp(const QJsonValue &data)
|
||||
{
|
||||
if (data.isString())
|
||||
return QDateTime::fromString(data.toString(), Qt::ISODate);
|
||||
else if (data.isDouble())
|
||||
return QDateTime::fromMSecsSinceEpoch((qint64)data.toDouble());
|
||||
else
|
||||
return QDateTime();
|
||||
}
|
||||
|
||||
static double hr(const QJsonValue &data)
|
||||
{
|
||||
return data.isDouble() ? data.toDouble() : NAN;
|
||||
}
|
||||
|
||||
static void setSegmentProperties(SegmentData &segment, int segno,
|
||||
const QJsonValue &properties)
|
||||
{
|
||||
if (properties.isObject()) {
|
||||
QJsonObject o(properties.toObject());
|
||||
|
||||
if (o["coordinateProperties"].isObject()) {
|
||||
QJsonObject cp(o["coordinateProperties"].toObject());
|
||||
if (cp["times"].isArray()) {
|
||||
QJsonArray times(cp["times"].toArray());
|
||||
|
||||
if (segno >= 0) {
|
||||
if (times.size() > segno) {
|
||||
QJsonArray seg(times.at(segno).toArray());
|
||||
if (seg.size() == segment.size()) {
|
||||
for (int i = 0; i < seg.size(); i++)
|
||||
segment[i].setTimestamp(timestamp(seg.at(i)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (times.size() == segment.size()) {
|
||||
for (int i = 0; i < times.size(); i++)
|
||||
segment[i].setTimestamp(timestamp(times.at(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cp["heart"].isArray()) {
|
||||
QJsonArray heart(cp["heart"].toArray());
|
||||
|
||||
if (segno >= 0) {
|
||||
if (heart.size() > segno) {
|
||||
QJsonArray seg(heart.at(segno).toArray());
|
||||
if (seg.size() == segment.size()) {
|
||||
for (int i = 0; i < seg.size(); i++)
|
||||
segment[i].setHeartRate(hr(seg.at(i)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (heart.size() == segment.size()) {
|
||||
for (int i = 0; i < heart.size(); i++)
|
||||
segment[i].setHeartRate(hr(heart.at(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool isWS(char c)
|
||||
{
|
||||
return (c == 0x20 || c == 0x09 || c == 0x0A || c == 0x0D) ? true : false;
|
||||
}
|
||||
|
||||
static bool isJSONObject(QFile *file)
|
||||
static bool possiblyJSONObject(QFile *file)
|
||||
{
|
||||
char c;
|
||||
|
||||
@ -125,6 +201,44 @@ static bool isJSONObject(QFile *file)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::a2c(const QJsonArray &data, const Projection &proj,
|
||||
Coordinates &c)
|
||||
{
|
||||
c = (data.count() >= 2 && data.at(0).isDouble() && data.at(1).isDouble())
|
||||
? proj.xy2ll(PointD(data.at(0).toDouble(), data.at(1).toDouble()))
|
||||
: Coordinates();
|
||||
|
||||
if (c.isValid())
|
||||
return true;
|
||||
else {
|
||||
QJsonDocument doc(QJsonDocument::fromVariant(data.toVariantList()));
|
||||
_errorString = QString("%1: invalid coordinates")
|
||||
.arg(QString::fromUtf8(doc.toJson(QJsonDocument::Compact)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool GeoJSONParser::crs(const QJsonObject &object, Projection &proj)
|
||||
{
|
||||
if (!object.contains("crs"))
|
||||
return true;
|
||||
|
||||
QJsonObject crsObj(object["crs"].toObject());
|
||||
if (crsObj["type"].toString() != "name" || !crsObj.contains("properties")) {
|
||||
_errorString = "Invalid crs object";
|
||||
return false;
|
||||
}
|
||||
QString str(crsObj["properties"].toObject()["name"].toString());
|
||||
proj = CRS::projection(str);
|
||||
|
||||
if (proj.isValid())
|
||||
return true;
|
||||
else {
|
||||
_errorString = QString("%1: unknown CRS").arg(str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GeoJSONParser::Type GeoJSONParser::type(const QJsonObject &json)
|
||||
{
|
||||
QString str(json["type"].toString());
|
||||
@ -151,206 +265,329 @@ GeoJSONParser::Type GeoJSONParser::type(const QJsonObject &json)
|
||||
return Unknown;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::point(const QJsonArray &coordinates, Waypoint &waypoint,
|
||||
const QJsonValue &properties)
|
||||
bool GeoJSONParser::point(const QJsonObject &object, const Projection &parent,
|
||||
const QJsonValue &properties, QVector<Waypoint> &waypoints)
|
||||
{
|
||||
if (coordinates.count() < 2 || !coordinates.at(0).isDouble()
|
||||
|| !coordinates.at(1).isDouble()) {
|
||||
_errorString = "Invalid Point Coordinates";
|
||||
if (!object.contains("coordinates")) {
|
||||
_errorString = "Missing Point coordinates array";
|
||||
return false;
|
||||
}
|
||||
if (object["coordinates"].isNull())
|
||||
return true;
|
||||
QJsonArray coordinates(object["coordinates"].toArray());
|
||||
if (coordinates.isEmpty())
|
||||
return true;
|
||||
Projection proj;
|
||||
if (!crs(object, proj))
|
||||
return false;
|
||||
|
||||
setWaypointProperties(waypoint, properties);
|
||||
Coordinates c;
|
||||
if (!a2c(coordinates, PROJ(proj, parent), c))
|
||||
return false;
|
||||
|
||||
waypoint.setCoordinates(Coordinates(coordinates.at(0).toDouble(),
|
||||
coordinates.at(1).toDouble()));
|
||||
Waypoint waypoint(c);
|
||||
if (coordinates.count() == 3 && coordinates.at(2).isDouble())
|
||||
waypoint.setElevation(coordinates.at(2).toDouble());
|
||||
setWaypointProperties(waypoint, properties);
|
||||
waypoints.append(waypoint);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::multiPoint(const QJsonArray &coordinates,
|
||||
QVector<Waypoint> &waypoints, const QJsonValue &properties)
|
||||
bool GeoJSONParser::multiPoint(const QJsonObject &object,
|
||||
const Projection &parent, const QJsonValue &properties,
|
||||
QVector<Waypoint> &waypoints)
|
||||
{
|
||||
if (!object.contains("coordinates")) {
|
||||
_errorString = "Missing MultiPoint coordinates array";
|
||||
return false;
|
||||
}
|
||||
if (object["coordinates"].isNull())
|
||||
return true;
|
||||
QJsonArray coordinates(object["coordinates"].toArray());
|
||||
Projection proj;
|
||||
if (!crs(object, proj))
|
||||
return false;
|
||||
Coordinates c;
|
||||
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
if (!coordinates.at(i).isArray()) {
|
||||
_errorString = "Invalid MultiPoint coordinates";
|
||||
_errorString = "Invalid MultiPoint data";
|
||||
return false;
|
||||
} else {
|
||||
waypoints.resize(waypoints.size() + 1);
|
||||
if (!point(coordinates.at(i).toArray(), waypoints.last(), properties))
|
||||
QJsonArray data(coordinates.at(i).toArray());
|
||||
if (!a2c(data, PROJ(proj, parent), c))
|
||||
return false;
|
||||
|
||||
Waypoint waypoint(c);
|
||||
if (data.count() == 3 && data.at(2).isDouble())
|
||||
waypoint.setElevation(data.at(2).toDouble());
|
||||
setWaypointProperties(waypoint, properties);
|
||||
waypoints.append(waypoint);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::lineString(const QJsonArray &coordinates,
|
||||
SegmentData &segment)
|
||||
bool GeoJSONParser::lineString(const QJsonObject &object,
|
||||
const Projection &parent, const QJsonValue &properties,
|
||||
QList<TrackData> &tracks)
|
||||
{
|
||||
if (!object.contains("coordinates")) {
|
||||
_errorString = "Missing LineString coordinates array";
|
||||
return false;
|
||||
}
|
||||
if (object["coordinates"].isNull())
|
||||
return true;
|
||||
QJsonArray coordinates(object["coordinates"].toArray());
|
||||
if (coordinates.isEmpty())
|
||||
return true;
|
||||
Projection proj;
|
||||
if (!crs(object, proj))
|
||||
return false;
|
||||
SegmentData segment;
|
||||
Coordinates c;
|
||||
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
QJsonArray point(coordinates.at(i).toArray());
|
||||
if (point.count() < 2 || !point.at(0).isDouble()
|
||||
|| !point.at(1).isDouble()) {
|
||||
_errorString = "Invalid LineString coordinates";
|
||||
if (!coordinates.at(i).isArray()) {
|
||||
_errorString = "Invalid LineString data";
|
||||
return false;
|
||||
}
|
||||
|
||||
Trackpoint t(Coordinates(point.at(0).toDouble(),
|
||||
point.at(1).toDouble()));
|
||||
if (point.count() == 3 && point.at(2).isDouble())
|
||||
t.setElevation(point.at(2).toDouble());
|
||||
QJsonArray data(coordinates.at(i).toArray());
|
||||
if (!a2c(data, PROJ(proj, parent), c))
|
||||
return false;
|
||||
|
||||
Trackpoint t(c);
|
||||
if (data.count() == 3 && data.at(2).isDouble())
|
||||
t.setElevation(data.at(2).toDouble());
|
||||
segment.append(t);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::lineString(const QJsonArray &coordinates, TrackData &track,
|
||||
const QJsonValue &properties)
|
||||
{
|
||||
setSegmentProperties(segment, -1, properties);
|
||||
TrackData track(segment);
|
||||
setTrackProperties(track, properties);
|
||||
|
||||
track.append(SegmentData());
|
||||
|
||||
lineString(coordinates, track.last());
|
||||
tracks.append(track);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::multiLineString(const QJsonArray &coordinates,
|
||||
TrackData &track, const QJsonValue &properties)
|
||||
bool GeoJSONParser::multiLineString(const QJsonObject &object,
|
||||
const Projection &parent, const QJsonValue &properties,
|
||||
QList<TrackData> &tracks)
|
||||
{
|
||||
setTrackProperties(track, properties);
|
||||
if (!object.contains("coordinates")) {
|
||||
_errorString = "Missing MultiLineString coordinates array";
|
||||
return false;
|
||||
}
|
||||
if (object["coordinates"].isNull())
|
||||
return true;
|
||||
QJsonArray coordinates(object["coordinates"].toArray());
|
||||
if (coordinates.isEmpty())
|
||||
return true;
|
||||
Projection proj;
|
||||
if (!crs(object, proj))
|
||||
return false;
|
||||
TrackData track;
|
||||
Coordinates c;
|
||||
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
if (!coordinates.at(i).isArray()) {
|
||||
_errorString = "Invalid MultiLineString coordinates";
|
||||
_errorString = "Invalid MultiLineString data";
|
||||
return false;
|
||||
} else {
|
||||
track.append(SegmentData());
|
||||
if (!lineString(coordinates.at(i).toArray(), track.last()))
|
||||
return false;
|
||||
SegmentData segment;
|
||||
|
||||
QJsonArray ls(coordinates.at(i).toArray());
|
||||
for (int j = 0; j < ls.size(); j++) {
|
||||
if (!ls.at(j).isArray()) {
|
||||
_errorString = "Invalid MultiLineString LineString data";
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonArray data(ls.at(j).toArray());
|
||||
if (!a2c(data, PROJ(proj, parent), c))
|
||||
return false;
|
||||
|
||||
Trackpoint t(c);
|
||||
if (data.count() == 3 && data.at(2).isDouble())
|
||||
t.setElevation(data.at(2).toDouble());
|
||||
segment.append(t);
|
||||
}
|
||||
|
||||
setSegmentProperties(segment, track.size(), properties);
|
||||
track.append(segment);
|
||||
}
|
||||
}
|
||||
|
||||
setTrackProperties(track, properties);
|
||||
tracks.append(track);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::polygon(const QJsonArray &coordinates, ::Polygon &pg)
|
||||
bool GeoJSONParser::polygon(const QJsonObject &object, const Projection &parent,
|
||||
const QJsonValue &properties, QList<Area> &areas)
|
||||
{
|
||||
if (!object.contains("coordinates")) {
|
||||
_errorString = "Missing Polygon coordinates array";
|
||||
return false;
|
||||
}
|
||||
if (object["coordinates"].isNull())
|
||||
return true;
|
||||
QJsonArray coordinates(object["coordinates"].toArray());
|
||||
if (coordinates.isEmpty())
|
||||
return true;
|
||||
Projection proj;
|
||||
if (!crs(object, proj))
|
||||
return false;
|
||||
::Polygon poly;
|
||||
Coordinates c;
|
||||
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
if (!coordinates.at(i).isArray()) {
|
||||
_errorString = "Invalid Polygon linear ring";
|
||||
return false;
|
||||
}
|
||||
|
||||
const QJsonArray lr(coordinates.at(i).toArray());
|
||||
QJsonArray lr(coordinates.at(i).toArray());
|
||||
QVector<Coordinates> data;
|
||||
|
||||
for (int j = 0; j < lr.size(); j++) {
|
||||
QJsonArray point(lr.at(j).toArray());
|
||||
if (point.count() < 2 || !point.at(0).isDouble()
|
||||
|| !point.at(1).isDouble()) {
|
||||
_errorString = "Invalid Polygon linear ring coordinates";
|
||||
if (!lr.at(j).isArray()) {
|
||||
_errorString = "Invalid Polygon linear ring data";
|
||||
return false;
|
||||
}
|
||||
data.append(Coordinates(point.at(0).toDouble(),
|
||||
point.at(1).toDouble()));
|
||||
|
||||
QJsonArray point(lr.at(j).toArray());
|
||||
if (!a2c(point, PROJ(proj, parent), c))
|
||||
return false;
|
||||
|
||||
data.append(c);
|
||||
}
|
||||
|
||||
pg.append(data);
|
||||
poly.append(data);
|
||||
}
|
||||
|
||||
Area area(poly);
|
||||
setAreaProperties(area, properties);
|
||||
areas.append(area);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::polygon(const QJsonArray &coordinates, Area &area,
|
||||
const QJsonValue &properties)
|
||||
bool GeoJSONParser::multiPolygon(const QJsonObject &object,
|
||||
const Projection &parent, const QJsonValue &properties, QList<Area> &areas)
|
||||
{
|
||||
setAreaProperties(area, properties);
|
||||
|
||||
::Polygon p;
|
||||
if (!polygon(coordinates, p))
|
||||
if (!object.contains("coordinates")) {
|
||||
_errorString = "Missing MultiPolygon coordinates array";
|
||||
return false;
|
||||
area.append(p);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::multiPolygon(const QJsonArray &coordinates,
|
||||
Area &area, const QJsonValue &properties)
|
||||
{
|
||||
setAreaProperties(area, properties);
|
||||
}
|
||||
if (object["coordinates"].isNull())
|
||||
return true;
|
||||
QJsonArray coordinates(object["coordinates"].toArray());
|
||||
if (coordinates.isEmpty())
|
||||
return true;
|
||||
Projection proj;
|
||||
if (!crs(object, proj))
|
||||
return false;
|
||||
Area area;
|
||||
Coordinates c;
|
||||
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
if (!coordinates.at(i).isArray()) {
|
||||
_errorString = "Invalid MultiPolygon coordinates";
|
||||
_errorString = "Invalid MultiPolygon data";
|
||||
return false;
|
||||
} else {
|
||||
::Polygon p;
|
||||
if (!polygon(coordinates.at(i).toArray(), p))
|
||||
return false;
|
||||
area.append(p);
|
||||
::Polygon poly;
|
||||
|
||||
QJsonArray polygon(coordinates.at(i).toArray());
|
||||
for (int j = 0; j < polygon.size(); j++) {
|
||||
if (!polygon.at(j).isArray()) {
|
||||
_errorString = "Invalid MultiPolygon linear ring";
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonArray lr(polygon.at(j).toArray());
|
||||
QVector<Coordinates> data;
|
||||
|
||||
for (int k = 0; k < lr.size(); k++) {
|
||||
if (!lr.at(k).isArray()) {
|
||||
_errorString = "Invalid MultiPolygon linear ring data";
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonArray point(lr.at(k).toArray());
|
||||
if (!a2c(point, PROJ(proj, parent), c))
|
||||
return false;
|
||||
|
||||
data.append(c);
|
||||
}
|
||||
|
||||
poly.append(data);
|
||||
}
|
||||
|
||||
area.append(poly);
|
||||
}
|
||||
}
|
||||
|
||||
setAreaProperties(area, properties);
|
||||
areas.append(area);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::geometryCollection(const QJsonObject &json,
|
||||
QList<TrackData> &tracks, QList<Area> &areas,
|
||||
QVector<Waypoint> &waypoints, const QJsonValue &properties)
|
||||
bool GeoJSONParser::geometryCollection(const QJsonObject &object,
|
||||
const Projection &parent, const QJsonValue &properties,
|
||||
QList<TrackData> &tracks, QList<Area> &areas, QVector<Waypoint> &waypoints)
|
||||
{
|
||||
if (!json.contains("geometries") || !json["geometries"].isArray()) {
|
||||
if (!object["geometries"].isArray()) {
|
||||
_errorString = "Invalid/missing GeometryCollection geometries array";
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonArray geometries(json["geometries"].toArray());
|
||||
QJsonArray geometries(object["geometries"].toArray());
|
||||
Projection proj;
|
||||
if (!crs(object, proj))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < geometries.size(); i++) {
|
||||
QJsonObject geometry(geometries.at(i).toObject());
|
||||
|
||||
switch (type(geometry)) {
|
||||
case Point:
|
||||
waypoints.resize(waypoints.size() + 1);
|
||||
if (!point(geometry["coordinates"].toArray(), waypoints.last(),
|
||||
properties))
|
||||
if (!point(geometry, PROJ(proj, parent), properties,
|
||||
waypoints))
|
||||
return false;
|
||||
break;
|
||||
case MultiPoint:
|
||||
if (!multiPoint(geometry["coordinates"].toArray(), waypoints,
|
||||
properties))
|
||||
if (!multiPoint(geometry, PROJ(proj, parent), properties,
|
||||
waypoints))
|
||||
return false;
|
||||
break;
|
||||
case LineString:
|
||||
tracks.append(TrackData());
|
||||
if (!lineString(geometry["coordinates"].toArray(),
|
||||
tracks.last(), properties))
|
||||
if (!lineString(geometry, PROJ(proj, parent), properties,
|
||||
tracks))
|
||||
return false;
|
||||
break;
|
||||
case MultiLineString:
|
||||
tracks.append(TrackData());
|
||||
if (!multiLineString(geometry["coordinates"].toArray(),
|
||||
tracks.last(), properties))
|
||||
if (!multiLineString(geometry, PROJ(proj, parent), properties,
|
||||
tracks))
|
||||
return false;
|
||||
break;
|
||||
case Polygon:
|
||||
areas.append(Area());
|
||||
if (!polygon(geometry["coordinates"].toArray(), areas.last(),
|
||||
properties))
|
||||
if (!polygon(geometry, PROJ(proj, parent), properties, areas))
|
||||
return false;
|
||||
break;
|
||||
case MultiPolygon:
|
||||
areas.append(Area());
|
||||
if (!multiPolygon(geometry["coordinates"].toArray(),
|
||||
areas.last(), properties))
|
||||
if (!multiPolygon(geometry, PROJ(proj, parent), properties,
|
||||
areas))
|
||||
return false;
|
||||
break;
|
||||
case GeometryCollection:
|
||||
if (!geometryCollection(geometry, tracks, areas, waypoints,
|
||||
properties))
|
||||
if (!geometryCollection(geometry, PROJ(proj, parent),
|
||||
properties, tracks, areas, waypoints))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
@ -363,38 +600,40 @@ bool GeoJSONParser::geometryCollection(const QJsonObject &json,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoJSONParser::feature(const QJsonObject &json, QList<TrackData> &tracks,
|
||||
QList<Area> &areas, QVector<Waypoint> &waypoints)
|
||||
bool GeoJSONParser::feature(const QJsonObject &object, const Projection &parent,
|
||||
QList<TrackData> &tracks, QList<Area> &areas, QVector<Waypoint> &waypoints)
|
||||
{
|
||||
QJsonValue properties(json["properties"]);
|
||||
QJsonObject geometry(json["geometry"].toObject());
|
||||
if (object["geometry"].isNull())
|
||||
return true;
|
||||
if (!object["geometry"].isObject()) {
|
||||
_errorString = "Invalid/missing Feature geometry object";
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonValue properties(object["properties"]);
|
||||
QJsonObject geometry(object["geometry"].toObject());
|
||||
Projection proj;
|
||||
if (!crs(object, proj))
|
||||
return false;
|
||||
|
||||
switch (type(geometry)) {
|
||||
case Point:
|
||||
waypoints.resize(waypoints.size() + 1);
|
||||
return point(geometry["coordinates"].toArray(), waypoints.last(),
|
||||
properties);
|
||||
return point(geometry, PROJ(proj, parent), properties, waypoints);
|
||||
case MultiPoint:
|
||||
return multiPoint(geometry["coordinates"].toArray(), waypoints,
|
||||
properties);
|
||||
return multiPoint(geometry, PROJ(proj, parent), properties,
|
||||
waypoints);
|
||||
case LineString:
|
||||
tracks.append(TrackData());
|
||||
return lineString(geometry["coordinates"].toArray(), tracks.last(),
|
||||
properties);
|
||||
return lineString(geometry, PROJ(proj, parent), properties, tracks);
|
||||
case MultiLineString:
|
||||
tracks.append(TrackData());
|
||||
return multiLineString(geometry["coordinates"].toArray(),
|
||||
tracks.last(), properties);
|
||||
return multiLineString(geometry, PROJ(proj, parent), properties,
|
||||
tracks);
|
||||
case GeometryCollection:
|
||||
return geometryCollection(geometry, tracks, areas, waypoints);
|
||||
return geometryCollection(geometry, PROJ(proj, parent), properties,
|
||||
tracks, areas, waypoints);
|
||||
case Polygon:
|
||||
areas.append(Area());
|
||||
return polygon(geometry["coordinates"].toArray(), areas.last(),
|
||||
properties);
|
||||
return polygon(geometry, PROJ(proj, parent), properties, areas);
|
||||
case MultiPolygon:
|
||||
areas.append(Area());
|
||||
return multiPolygon(geometry["coordinates"].toArray(), areas.last(),
|
||||
properties);
|
||||
return multiPolygon(geometry, PROJ(proj, parent), properties, areas);
|
||||
default:
|
||||
_errorString = geometry["type"].toString()
|
||||
+ ": invalid/missing Feature geometry";
|
||||
@ -402,18 +641,23 @@ bool GeoJSONParser::feature(const QJsonObject &json, QList<TrackData> &tracks,
|
||||
}
|
||||
}
|
||||
|
||||
bool GeoJSONParser::featureCollection(const QJsonObject &json,
|
||||
QList<TrackData> &tracks, QList<Area> &areas,
|
||||
bool GeoJSONParser::featureCollection(const QJsonObject &object,
|
||||
const Projection &parent, QList<TrackData> &tracks, QList<Area> &areas,
|
||||
QVector<Waypoint> &waypoints)
|
||||
{
|
||||
if (!json.contains("features") || !json["features"].isArray()) {
|
||||
if (!object["features"].isArray()) {
|
||||
_errorString = "Invalid/missing FeatureCollection features array";
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonArray features(json["features"].toArray());
|
||||
QJsonArray features(object["features"].toArray());
|
||||
Projection proj;
|
||||
if (!crs(object, proj))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < features.size(); i++)
|
||||
if (!feature(features.at(i).toObject(), tracks, areas, waypoints))
|
||||
if (!feature(features.at(i).toObject(), PROJ(proj, parent), tracks,
|
||||
areas, waypoints))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -425,7 +669,7 @@ bool GeoJSONParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
{
|
||||
Q_UNUSED(routes);
|
||||
|
||||
if (!isJSONObject(file)) {
|
||||
if (!possiblyJSONObject(file)) {
|
||||
_errorString = "Not a GeoJSON file";
|
||||
return false;
|
||||
} else
|
||||
@ -435,42 +679,39 @@ bool GeoJSONParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
QJsonDocument doc(QJsonDocument::fromJson(file->readAll(), &error));
|
||||
|
||||
if (doc.isNull()) {
|
||||
_errorString = "JSON parse error: " + error.errorString() + " ["
|
||||
+ QString::number(error.offset) + "]";
|
||||
_errorString = QString("JSON parse error on offset %1: %2")
|
||||
.arg(QString::number(error.offset), error.errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject json(doc.object());
|
||||
QJsonObject object(doc.object());
|
||||
Projection proj(GCS::WGS84());
|
||||
|
||||
switch (type(json)) {
|
||||
switch (type(object)) {
|
||||
case Point:
|
||||
waypoints.resize(waypoints.size() + 1);
|
||||
return point(json["coordinates"].toArray(), waypoints.last());
|
||||
return point(object, proj, QJsonValue(), waypoints);
|
||||
case MultiPoint:
|
||||
return multiPoint(json["coordinates"].toArray(), waypoints);
|
||||
return multiPoint(object, proj, QJsonValue(), waypoints);
|
||||
case LineString:
|
||||
tracks.append(TrackData());
|
||||
return lineString(json["coordinates"].toArray(), tracks.last());
|
||||
return lineString(object, proj, QJsonValue(), tracks);
|
||||
case MultiLineString:
|
||||
tracks.append(TrackData());
|
||||
return multiLineString(json["coordinates"].toArray(), tracks.last());
|
||||
return multiLineString(object, proj, QJsonValue(), tracks);
|
||||
case GeometryCollection:
|
||||
return geometryCollection(json, tracks, areas, waypoints);
|
||||
return geometryCollection(object, proj, QJsonValue(), tracks, areas,
|
||||
waypoints);
|
||||
case Feature:
|
||||
return feature(json, tracks, areas, waypoints);
|
||||
return feature(object, proj, tracks, areas, waypoints);
|
||||
case FeatureCollection:
|
||||
return featureCollection(json, tracks, areas, waypoints);
|
||||
return featureCollection(object, proj, tracks, areas, waypoints);
|
||||
case Polygon:
|
||||
areas.append(Area());
|
||||
return polygon(json["coordinates"].toArray(), areas.last());
|
||||
return polygon(object, proj, QJsonValue(), areas);
|
||||
case MultiPolygon:
|
||||
areas.append(Area());
|
||||
return multiPolygon(json["coordinates"].toArray(), areas.last());
|
||||
return multiPolygon(object, proj, QJsonValue(), areas);
|
||||
case Unknown:
|
||||
if (json["type"].toString().isNull())
|
||||
if (object["type"].toString().isNull())
|
||||
_errorString = "Not a GeoJSON file";
|
||||
else
|
||||
_errorString = json["type"].toString()
|
||||
_errorString = object["type"].toString()
|
||||
+ ": unknown GeoJSON object";
|
||||
return false;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
class QJsonObject;
|
||||
class QJsonArray;
|
||||
class Projection;
|
||||
|
||||
class GeoJSONParser : public Parser
|
||||
{
|
||||
@ -29,28 +30,29 @@ private:
|
||||
FeatureCollection
|
||||
};
|
||||
|
||||
bool a2c(const QJsonArray &data, const Projection &proj, Coordinates &c);
|
||||
Type type(const QJsonObject &json);
|
||||
bool point(const QJsonArray &coordinates, Waypoint &waypoint,
|
||||
const QJsonValue &properties = QJsonValue());
|
||||
bool multiPoint(const QJsonArray &coordinates,
|
||||
QVector<Waypoint> &waypoints, const QJsonValue &properties = QJsonValue());
|
||||
bool lineString(const QJsonArray &coordinates, SegmentData &segment);
|
||||
bool lineString(const QJsonArray &coordinates, TrackData &track,
|
||||
const QJsonValue &properties = QJsonValue());
|
||||
bool multiLineString(const QJsonArray &coordinates,
|
||||
TrackData &track, const QJsonValue &properties = QJsonValue());
|
||||
bool polygon(const QJsonArray &coordinates, ::Polygon &pg);
|
||||
bool polygon(const QJsonArray &coordinates, Area &area,
|
||||
const QJsonValue &properties = QJsonValue());
|
||||
bool multiPolygon(const QJsonArray &coordinates, Area &area,
|
||||
const QJsonValue &properties = QJsonValue());
|
||||
bool geometryCollection(const QJsonObject &json, QList<TrackData> &tracks,
|
||||
QList<Area> &areas, QVector<Waypoint> &waypoints,
|
||||
const QJsonValue &properties = QJsonValue());
|
||||
bool feature(const QJsonObject &json, QList<TrackData> &tracks,
|
||||
QList<Area> &areas, QVector<Waypoint> &waypoints);
|
||||
bool featureCollection(const QJsonObject &json, QList<TrackData> &tracks,
|
||||
bool crs(const QJsonObject &object, Projection &proj);
|
||||
bool point(const QJsonObject &object, const Projection &parent,
|
||||
const QJsonValue &properties, QVector<Waypoint> &waypoints);
|
||||
bool multiPoint(const QJsonObject &object, const Projection &parent,
|
||||
const QJsonValue &properties, QVector<Waypoint> &waypoints);
|
||||
bool lineString(const QJsonObject &coordinates, const Projection &parent,
|
||||
const QJsonValue &properties, QList<TrackData> &tracks);
|
||||
bool multiLineString(const QJsonObject &object, const Projection &proj,
|
||||
const QJsonValue &properties, QList<TrackData> &tracks);
|
||||
bool polygon(const QJsonObject &object, const Projection &parent,
|
||||
const QJsonValue &properties, QList<Area> &areas);
|
||||
bool multiPolygon(const QJsonObject &object, const Projection &proj,
|
||||
const QJsonValue &properties, QList<Area> &areas);
|
||||
bool geometryCollection(const QJsonObject &json, const Projection &parent,
|
||||
const QJsonValue &properties, QList<TrackData> &tracks,
|
||||
QList<Area> &areas, QVector<Waypoint> &waypoints);
|
||||
bool feature(const QJsonObject &json, const Projection &parent,
|
||||
QList<TrackData> &tracks, QList<Area> &areas,
|
||||
QVector<Waypoint> &waypoints);
|
||||
bool featureCollection(const QJsonObject &object, const Projection &parent,
|
||||
QList<TrackData> &tracks, QList<Area> &areas, QVector<Waypoint> &waypoints);
|
||||
|
||||
QString _errorString;
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "map/pcs.h"
|
||||
#include "map/gcs.h"
|
||||
#include "map/utm.h"
|
||||
#include "map/projection.h"
|
||||
#include "gpsdumpparser.h"
|
||||
|
||||
static double dms2dd(const QStringList &dms)
|
||||
|
@ -76,6 +76,9 @@ void GPXParser::tpExtension(Trackpoint &trackpoint)
|
||||
trackpoint.setHeartRate(number());
|
||||
else if (_reader.name() == QLatin1String("atemp"))
|
||||
trackpoint.setTemperature(number());
|
||||
else if (_reader.name() == QLatin1String("wtemp")
|
||||
&& !trackpoint.hasTemperature())
|
||||
trackpoint.setTemperature(number());
|
||||
else if (_reader.name() == QLatin1String("cad"))
|
||||
trackpoint.setCadence(number());
|
||||
else if (_reader.name() == QLatin1String("speed"))
|
||||
|
@ -247,8 +247,7 @@ bool IGCParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
ctx.date = QDate(1970, 1, 1);
|
||||
}
|
||||
if (!track) {
|
||||
tracks.append(TrackData());
|
||||
tracks.last().append(SegmentData());
|
||||
tracks.append(SegmentData());
|
||||
ctx.time = QTime(0, 0);
|
||||
track = true;
|
||||
}
|
||||
|
@ -123,6 +123,8 @@ void TCXParser::waypointData(Waypoint &waypoint)
|
||||
waypoint.setElevation(number());
|
||||
else if (_reader.name() == QLatin1String("Time"))
|
||||
waypoint.setTimestamp(time());
|
||||
else if (_reader.name() == QLatin1String("PointType"))
|
||||
waypoint.setSymbol(_reader.readElementText());
|
||||
else
|
||||
_reader.skipCurrentElement();
|
||||
}
|
||||
|
@ -13,6 +13,13 @@ typedef QVector<Trackpoint> SegmentData;
|
||||
class TrackData : public QList<SegmentData>
|
||||
{
|
||||
public:
|
||||
TrackData() {}
|
||||
TrackData(const SegmentData &segment)
|
||||
{
|
||||
reserve(1);
|
||||
append(segment);
|
||||
}
|
||||
|
||||
const QString &name() const {return _name;}
|
||||
const QString &description() const {return _desc;}
|
||||
const QString &comment() const {return _comment;}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "common/textcodec.h"
|
||||
#include "common/textcodec.h"
|
||||
#include "map/gcs.h"
|
||||
#include "twonavparser.h"
|
||||
|
||||
@ -151,8 +151,7 @@ bool TwoNavParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
}
|
||||
|
||||
if (!track) {
|
||||
tracks.append(TrackData());
|
||||
tracks.last().append(SegmentData());
|
||||
tracks.append(SegmentData());
|
||||
track = true;
|
||||
}
|
||||
|
||||
|
@ -399,7 +399,7 @@ void RasterTile::render()
|
||||
//painter.setPen(Qt::red);
|
||||
//painter.setBrush(Qt::NoBrush);
|
||||
//painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
//painter.drawRect(QRect(_rect.topLeft(), _pixmap.size()));
|
||||
//painter.drawRect(_rect);
|
||||
|
||||
_pixmap.convertFromImage(img);
|
||||
}
|
||||
|
@ -76,7 +76,6 @@ private:
|
||||
bool readBytesAligned(quint32 bytes, quint32 &val);
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
bool BitStream1::read(quint32 bits, T &val)
|
||||
{
|
||||
|
112
src/map/IMG/dem.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
#include "dem.h"
|
||||
|
||||
using namespace IMG;
|
||||
|
||||
#define DELTA 1e-9 /* ensure col+1/row+1 is in the next tile */
|
||||
|
||||
static double interpolate(double dx, double dy, double p0, double p1, double p2,
|
||||
double p3)
|
||||
{
|
||||
return p0 * (1.0 - dx) * (1.0 - dy) + p1 * dx * (1.0 - dy)
|
||||
+ p2 * dy * (1.0 - dx) + p3 * dx * dy;
|
||||
}
|
||||
|
||||
static double val(const Matrix<qint16> &m, int row, int col)
|
||||
{
|
||||
qint16 v = m.at(row, col);
|
||||
return (v == -32768) ? NAN : (double)v;
|
||||
}
|
||||
|
||||
bool DEM::edgeCb(const MapData::Elevation *e, void *context)
|
||||
{
|
||||
EdgeCTX *ctx = (EdgeCTX*)context;
|
||||
|
||||
double x = (ctx->c.lon() - e->rect.left()) / e->xr;
|
||||
double y = (e->rect.top() - ctx->c.lat()) / e->yr;
|
||||
int row = qMin((int)y, e->m.h() - 1);
|
||||
int col = qMin((int)x, e->m.w() - 1);
|
||||
|
||||
ctx->ele = val(e->m, row, col);
|
||||
|
||||
return std::isnan(ctx->ele);
|
||||
}
|
||||
|
||||
double DEM::edge(const DEMTRee &tree, const Coordinates &c)
|
||||
{
|
||||
double min[2], max[2];
|
||||
double ele = NAN;
|
||||
EdgeCTX ctx(c, ele);
|
||||
|
||||
min[0] = c.lon();
|
||||
min[1] = c.lat();
|
||||
max[0] = c.lon();
|
||||
max[1] = c.lat();
|
||||
|
||||
tree.Search(min, max, edgeCb, &ctx);
|
||||
|
||||
return ele;
|
||||
}
|
||||
|
||||
double DEM::elevation(const DEMTRee &tree, const MapData::Elevation *e,
|
||||
const Coordinates &c)
|
||||
{
|
||||
double x = (c.lon() - e->rect.left()) / e->xr;
|
||||
double y = (e->rect.top() - c.lat()) / e->yr;
|
||||
int row = qMin((int)y, e->m.h() - 1);
|
||||
int col = qMin((int)x, e->m.w() - 1);
|
||||
|
||||
double p0 = val(e->m, row, col);
|
||||
double p1 = (col == e->m.w() - 1)
|
||||
? edge(tree, Coordinates(e->rect.left() + (col + 1) * e->xr + DELTA,
|
||||
e->rect.top() - row * e->yr))
|
||||
: val(e->m, row, col + 1);
|
||||
double p2 = (row == e->m.h() - 1)
|
||||
? edge(tree, Coordinates(e->rect.left() + col * e->xr,
|
||||
e->rect.top() - (row + 1) * e->yr - DELTA))
|
||||
: val(e->m, row + 1, col);
|
||||
double p3 = ((col == e->m.w() - 1) || (row == e->m.h() - 1))
|
||||
? edge(tree, Coordinates(e->rect.left() + (col + 1) * e->xr + DELTA,
|
||||
e->rect.top() - (row + 1) * e->yr - DELTA))
|
||||
: val(e->m, row + 1, col + 1);
|
||||
|
||||
return interpolate(x - col, y - row, p0, p1, p2, p3);
|
||||
}
|
||||
|
||||
void DEM::buildTree(const QList<MapData::Elevation> &tiles, DEMTRee &tree)
|
||||
{
|
||||
double min[2], max[2];
|
||||
|
||||
for (int i = 0; i < tiles.size(); i++) {
|
||||
const MapData::Elevation &e = tiles.at(i);
|
||||
|
||||
min[0] = e.rect.left();
|
||||
min[1] = e.rect.bottom();
|
||||
max[0] = e.rect.right();
|
||||
max[1] = e.rect.top();
|
||||
|
||||
tree.Insert(min, max, &e);
|
||||
}
|
||||
}
|
||||
|
||||
bool DEM::elevationCb(const MapData::Elevation *e, void *context)
|
||||
{
|
||||
ElevationCTX *ctx = (ElevationCTX*)context;
|
||||
|
||||
ctx->ele = elevation(ctx->tree, e, ctx->c);
|
||||
return std::isnan(ctx->ele);
|
||||
}
|
||||
|
||||
void DEM::searchTree(const DEMTRee &tree, const Coordinates &c,
|
||||
double &ele)
|
||||
{
|
||||
double min[2], max[2];
|
||||
ElevationCTX ctx(tree, c, ele);
|
||||
|
||||
min[0] = c.lon();
|
||||
min[1] = c.lat();
|
||||
max[0] = c.lon();
|
||||
max[1] = c.lat();
|
||||
|
||||
ele = NAN;
|
||||
tree.Search(min, max, elevationCb, &ctx);
|
||||
}
|
44
src/map/IMG/dem.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef IMG_DEM_H
|
||||
#define IMG_DEM_H
|
||||
|
||||
#include "common/rtree.h"
|
||||
#include "mapdata.h"
|
||||
|
||||
namespace IMG {
|
||||
|
||||
class DEM {
|
||||
public:
|
||||
|
||||
typedef RTree<const MapData::Elevation*, double, 2> DEMTRee;
|
||||
|
||||
static void buildTree(const QList<MapData::Elevation> &tiles, DEMTRee &tree);
|
||||
static void searchTree(const DEMTRee &tree, const Coordinates &c,
|
||||
double &ele);
|
||||
|
||||
private:
|
||||
struct ElevationCTX {
|
||||
ElevationCTX(const DEMTRee &tree, const Coordinates &c, double &ele)
|
||||
: tree(tree), c(c), ele(ele) {}
|
||||
|
||||
const DEMTRee &tree;
|
||||
const Coordinates &c;
|
||||
double &ele;
|
||||
};
|
||||
|
||||
struct EdgeCTX {
|
||||
EdgeCTX(const Coordinates &c, double &ele) : c(c), ele(ele) {}
|
||||
|
||||
const Coordinates &c;
|
||||
double &ele;
|
||||
};
|
||||
|
||||
static double edge(const DEMTRee &tree, const Coordinates &c);
|
||||
static double elevation(const DEMTRee &tree, const MapData::Elevation *e,
|
||||
const Coordinates &c);
|
||||
static bool elevationCb(const MapData::Elevation *e, void *context);
|
||||
static bool edgeCb(const MapData::Elevation *e, void *context);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // IMG_DEM_H
|
187
src/map/IMG/demfile.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include "common/garmin.h"
|
||||
#include "jls.h"
|
||||
#include "demfile.h"
|
||||
|
||||
using namespace IMG;
|
||||
using namespace Garmin;
|
||||
|
||||
static qint16 limit(const DEMTile *tile, quint16 factor)
|
||||
{
|
||||
quint8 f1 = (tile->flags() & 1) != 0;
|
||||
qint16 l = f1 ? tile->diff() - factor : tile->diff() + 1;
|
||||
|
||||
if (tile->flags() > 1) {
|
||||
for (int i = 1; i < 8; i++) {
|
||||
if (((tile->flags() >> i) & 1) != 0)
|
||||
l = (l - 1) - (factor << f1);
|
||||
}
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void DEMFile::clear()
|
||||
{
|
||||
_levels.clear();
|
||||
}
|
||||
|
||||
bool DEMFile::load(Handle &hdl)
|
||||
{
|
||||
quint32 u32, zoomData;
|
||||
quint16 zooms, zoomDataSize;
|
||||
|
||||
if (!(seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _flags)
|
||||
&& readUInt16(hdl, zooms) && readUInt32(hdl, u32)
|
||||
&& readUInt16(hdl, zoomDataSize) && readUInt32(hdl, zoomData)))
|
||||
return false;
|
||||
|
||||
_levels.reserve(zooms);
|
||||
|
||||
for (quint16 i = 0; i < zooms; i++) {
|
||||
quint32 pixelWidth, pixelHeight, pixelWidth2, pixelHeight2, table, cols,
|
||||
rows, xr, yr, data;
|
||||
qint32 lon, lat;
|
||||
quint16 encoding, size, factor;
|
||||
qint16 minHeight, maxHeight;
|
||||
quint8 layer, level;
|
||||
QList<DEMTile> tiles;
|
||||
|
||||
if (!(seek(hdl, zoomData + i * zoomDataSize) && readUInt8(hdl, layer)
|
||||
&& readUInt8(hdl, level) && readUInt32(hdl, pixelHeight)
|
||||
&& readUInt32(hdl, pixelWidth) && readUInt32(hdl, pixelHeight2)
|
||||
&& readUInt32(hdl, pixelWidth2) && readUInt16(hdl, factor)
|
||||
&& readUInt32(hdl, cols) && readUInt32(hdl, rows)
|
||||
&& readUInt16(hdl, encoding) && readUInt16(hdl, size)
|
||||
&& readUInt32(hdl, table) && readUInt32(hdl, data)
|
||||
&& readInt32(hdl, lon) && readInt32(hdl, lat)
|
||||
&& readUInt32(hdl, yr) && readUInt32(hdl, xr)
|
||||
&& readInt16(hdl, minHeight) && readInt16(hdl, maxHeight)))
|
||||
return false;
|
||||
|
||||
if (layer)
|
||||
continue;
|
||||
|
||||
if (!seek(hdl, table))
|
||||
return false;
|
||||
|
||||
tiles.reserve((rows + 1) * (cols + 1));
|
||||
|
||||
for (quint32 i = 0; i < rows + 1; i++) {
|
||||
for (quint32 j = 0; j < cols + 1; j++) {
|
||||
qint32 x = lon + j * pixelWidth * xr;
|
||||
qint32 y = lat - i * pixelHeight * yr;
|
||||
quint32 w = (j == cols) ? (pixelWidth2 + 1) : pixelWidth;
|
||||
quint32 h = (i == rows) ? (pixelHeight2 + 1) : pixelHeight;
|
||||
RectC r(Coordinates(toWGS32(x), toWGS32(y)),
|
||||
Coordinates(toWGS32(x + w * xr), toWGS32(y - h * yr)));
|
||||
|
||||
quint32 offset;
|
||||
qint16 base;
|
||||
quint16 diff;
|
||||
quint8 flags = 0;
|
||||
|
||||
if (!readVUInt32(hdl, (encoding & 0x3) + 1, offset))
|
||||
return false;
|
||||
if (encoding & 0x4) {
|
||||
if (!readInt16(hdl, base))
|
||||
return false;
|
||||
} else {
|
||||
if (!readInt8(hdl, base))
|
||||
return false;
|
||||
}
|
||||
if (encoding & 0x8) {
|
||||
if (!readUInt16(hdl, diff))
|
||||
return false;
|
||||
} else {
|
||||
if (!readUInt8(hdl, diff))
|
||||
return false;
|
||||
}
|
||||
if ((encoding & 0x10) && !readUInt8(hdl, flags))
|
||||
return false;
|
||||
|
||||
tiles.append(DEMTile(r, w, h, offset, base, diff, flags));
|
||||
}
|
||||
}
|
||||
|
||||
_levels.append(Level(RectC(tiles.first().rect().topLeft(),
|
||||
tiles.last().rect().bottomRight()), toWGS32(xr), toWGS32(yr),
|
||||
toWGS32(pixelWidth * xr), toWGS32(pixelHeight* yr),
|
||||
data, rows + 1, cols + 1, factor, level, minHeight, maxHeight, tiles));
|
||||
}
|
||||
|
||||
return !_levels.isEmpty();
|
||||
}
|
||||
|
||||
QList<const DEMTile*> DEMFile::tiles(const RectC &rect, int level) const
|
||||
{
|
||||
const Level &lvl = _levels.at(level);
|
||||
QList<const DEMTile*> ret;
|
||||
|
||||
RectC ir(lvl.rect & rect);
|
||||
double left = (ir.left() - lvl.rect.left()) / lvl.txr;
|
||||
double top = (lvl.rect.top() - ir.top()) / lvl.tyr;
|
||||
double right = (ir.right() - lvl.rect.left()) / lvl.txr;
|
||||
double bottom = (lvl.rect.top() - ir.bottom()) / lvl.tyr;
|
||||
quint32 t = qMin((quint32)top, lvl.rows - 1);
|
||||
quint32 l = qMin((quint32)left, lvl.cols - 1);
|
||||
quint32 b = qMin((quint32)bottom, lvl.rows - 1);
|
||||
quint32 r = qMin((quint32)right, lvl.cols - 1);
|
||||
|
||||
ret.reserve((b - t + 1) * (r - l + 1));
|
||||
|
||||
for (quint32 i = t; i <= b; i++)
|
||||
for (quint32 j = l; j <= r; j++)
|
||||
ret.append(&lvl.tiles.at(lvl.cols * i + j));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DEMFile::level(const Zoom &zoom) const
|
||||
{
|
||||
for (int i = 0; i < _levels.size(); i++)
|
||||
if (_levels.at(i).level >= zoom.level())
|
||||
return i;
|
||||
|
||||
return _levels.size() - 1;
|
||||
}
|
||||
|
||||
MapData::Elevation *DEMFile::elevations(Handle &hdl, int level,
|
||||
const DEMTile *tile)
|
||||
{
|
||||
const Level &l = _levels.at(level);
|
||||
MapData::Elevation *ele = new MapData::Elevation();
|
||||
ele->rect = tile->rect();
|
||||
ele->xr = l.xr;
|
||||
ele->yr = l.yr;
|
||||
|
||||
if (!tile->diff()) {
|
||||
ele->m = Matrix<qint16>(tile->h(), tile->w(),
|
||||
tile->flags() ? -32768 : meters(tile->base()));
|
||||
return ele;
|
||||
}
|
||||
|
||||
if (!seek(hdl, tile->offset() + l.data))
|
||||
return ele;
|
||||
|
||||
quint16 lim = limit(tile, l.factor);
|
||||
Matrix<qint16> m(tile->h(), tile->w());
|
||||
JLS jls(tile->diff(), l.factor);
|
||||
if (jls.decode(this, hdl, m)) {
|
||||
for (int i = 0; i < m.size(); i++) {
|
||||
if (m.at(i) >= lim)
|
||||
m.at(i) = -32768;
|
||||
else {
|
||||
m.at(i) += tile->base();
|
||||
if (m.at(i) < l.minHeight)
|
||||
m.at(i) = l.minHeight;
|
||||
if (m.at(i) > l.maxHeight)
|
||||
m.at(i) = l.maxHeight;
|
||||
m.at(i) = meters(m.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
ele->m = m;
|
||||
}
|
||||
|
||||
return ele;
|
||||
}
|
58
src/map/IMG/demfile.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef DEMFILE_H
|
||||
#define DEMFILE_H
|
||||
|
||||
#include "common/rtree.h"
|
||||
#include "subfile.h"
|
||||
#include "demtile.h"
|
||||
|
||||
namespace IMG {
|
||||
|
||||
class DEMFile : public SubFile
|
||||
{
|
||||
public:
|
||||
DEMFile(const IMGData *img) : SubFile(img) {}
|
||||
DEMFile(const QString *path) : SubFile(path) {}
|
||||
DEMFile(const SubFile *gmp, quint32 offset) : SubFile(gmp, offset) {}
|
||||
|
||||
bool load(Handle &hdl);
|
||||
void clear();
|
||||
MapData::Elevation *elevations(Handle &hdl, int level, const DEMTile *tile);
|
||||
|
||||
int level(const Zoom &zoom) const;
|
||||
QList<const DEMTile *> tiles(const RectC &rect, int level) const;
|
||||
|
||||
private:
|
||||
struct Level {
|
||||
Level() {}
|
||||
Level(const RectC &rect, double xr, double yr, double txr, double tyr,
|
||||
quint32 data, quint32 rows, quint32 cols, quint16 factor,
|
||||
quint8 level, qint16 minHeight, qint16 maxHeight,
|
||||
const QList<DEMTile> &tiles)
|
||||
: rect(rect), xr(xr), yr(yr), txr(txr), tyr(tyr), data(data),
|
||||
rows(rows), cols(cols), factor(factor), level(level),
|
||||
minHeight(minHeight), maxHeight(maxHeight), tiles(tiles) {}
|
||||
|
||||
RectC rect;
|
||||
double xr, yr;
|
||||
double txr, tyr;
|
||||
quint32 data;
|
||||
quint32 rows, cols;
|
||||
quint16 factor;
|
||||
quint8 level;
|
||||
qint16 minHeight;
|
||||
qint16 maxHeight;
|
||||
QList<DEMTile> tiles;
|
||||
};
|
||||
|
||||
qint16 meters(qint16 val)
|
||||
{
|
||||
return (_flags & 1) ? (qint16)qRound(val * 0.3048) : val;
|
||||
}
|
||||
|
||||
quint32 _flags;
|
||||
QVector<Level> _levels;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DEMFILE_H
|
36
src/map/IMG/demtile.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef DEMTILE_H
|
||||
#define DEMTILE_H
|
||||
|
||||
#include "common/rectc.h"
|
||||
|
||||
namespace IMG {
|
||||
|
||||
class DEMTile {
|
||||
public:
|
||||
DEMTile(const RectC &rect, quint32 w, quint32 h, quint32 offset,
|
||||
qint16 base, quint16 diff, quint8 flags)
|
||||
: _rect(rect), _w(w), _h(h), _offset(offset), _base(base),
|
||||
_diff(diff), _flags(flags) {}
|
||||
|
||||
const RectC &rect() const {return _rect;}
|
||||
quint32 w() const {return _w;}
|
||||
quint32 h() const {return _h;}
|
||||
|
||||
quint32 offset() const {return _offset;}
|
||||
qint16 base() const {return _base;}
|
||||
quint16 diff() const {return _diff;}
|
||||
quint8 flags() const {return _flags;}
|
||||
|
||||
private:
|
||||
RectC _rect;
|
||||
quint32 _w, _h;
|
||||
|
||||
quint32 _offset;
|
||||
qint16 _base;
|
||||
quint16 _diff;
|
||||
quint8 _flags;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DEMTILE_H
|
@ -7,6 +7,9 @@ using namespace IMG;
|
||||
|
||||
static SubFile::Type tileType(const QString &suffix)
|
||||
{
|
||||
/* Note: we do not load NOD files from non-NT maps as we have no usage
|
||||
for them */
|
||||
|
||||
if (!suffix.compare("TRE"))
|
||||
return SubFile::TRE;
|
||||
else if (!suffix.compare("RGN"))
|
||||
@ -15,10 +18,12 @@ static SubFile::Type tileType(const QString &suffix)
|
||||
return SubFile::LBL;
|
||||
else if (!suffix.compare("TYP"))
|
||||
return SubFile::TYP;
|
||||
else if (!suffix.compare("GMP"))
|
||||
return SubFile::GMP;
|
||||
else if (!suffix.compare("NET"))
|
||||
return SubFile::NET;
|
||||
else if (!suffix.compare("DEM"))
|
||||
return SubFile::DEM;
|
||||
else if (!suffix.compare("GMP"))
|
||||
return SubFile::GMP;
|
||||
else
|
||||
return SubFile::Unknown;
|
||||
}
|
||||
@ -101,6 +106,7 @@ bool GMAPData::loadTile(const QDir &dir)
|
||||
_tileTree.Insert(min, max, tile);
|
||||
|
||||
_bounds |= tile->bounds();
|
||||
_hasDEM |= tile->hasDem();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ using namespace IMG;
|
||||
|
||||
static SubFile::Type tileType(const char str[3])
|
||||
{
|
||||
/* Note: we do not load NOD files from non-NT maps as we have no usage
|
||||
for them */
|
||||
|
||||
if (!memcmp(str, "TRE", 3))
|
||||
return SubFile::TRE;
|
||||
else if (!memcmp(str, "RGN", 3))
|
||||
@ -16,10 +19,12 @@ static SubFile::Type tileType(const char str[3])
|
||||
return SubFile::LBL;
|
||||
else if (!memcmp(str, "TYP", 3))
|
||||
return SubFile::TYP;
|
||||
else if (!memcmp(str, "GMP", 3))
|
||||
return SubFile::GMP;
|
||||
else if (!memcmp(str, "NET", 3))
|
||||
return SubFile::NET;
|
||||
else if (!memcmp(str, "DEM", 3))
|
||||
return SubFile::DEM;
|
||||
else if (!memcmp(str, "GMP", 3))
|
||||
return SubFile::GMP;
|
||||
else
|
||||
return SubFile::Unknown;
|
||||
}
|
||||
@ -156,6 +161,7 @@ bool IMGData::createTileTree(const TileMap &tileMap)
|
||||
_tileTree.Insert(min, max, tile);
|
||||
|
||||
_bounds |= tile->bounds();
|
||||
_hasDEM |= tile->hasDem();
|
||||
}
|
||||
|
||||
return (_tileTree.Count() > 0);
|
||||
|
334
src/map/IMG/jls.cpp
Normal file
@ -0,0 +1,334 @@
|
||||
#include <cmath>
|
||||
#include "jls.h"
|
||||
|
||||
using namespace IMG;
|
||||
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
static const quint8 Z[] = {
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
static const quint8 J[] = {
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
|
||||
JLS::JLS(quint16 maxval, quint16 near)
|
||||
{
|
||||
_maxval = maxval;
|
||||
_near = near;
|
||||
|
||||
_range = ((_maxval + _near * 2) / (_near * 2 + 1)) + 1;
|
||||
_qbpp = ceil(log2(_range));
|
||||
quint8 bpp = max(2, ceil(log2(_maxval + 1)));
|
||||
quint8 LIMIT = 2 * (bpp + max(8, bpp));
|
||||
_limit = LIMIT - _qbpp - 1;
|
||||
}
|
||||
|
||||
bool JLS::processRunMode(BitStream &bs, quint16 col, quint16 &samples)
|
||||
{
|
||||
quint8 z;
|
||||
quint16 cnt = 0;
|
||||
|
||||
while (true) {
|
||||
if ((qint32)bs.value() < 0) {
|
||||
z = Z[(bs.value() >> 0x18) ^ 0xff];
|
||||
|
||||
for (quint8 i = 0; i < z; i++) {
|
||||
cnt = cnt + _rg;
|
||||
|
||||
if (cnt <= col && _runIndex < 31) {
|
||||
_runIndex++;
|
||||
_rk = J[_runIndex];
|
||||
_rg = 1U << _rk;
|
||||
}
|
||||
|
||||
if (cnt >= col) {
|
||||
if (!bs.read(i + 1))
|
||||
return 3;
|
||||
|
||||
samples = col;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else
|
||||
z = 0;
|
||||
|
||||
if (z != 8) {
|
||||
if (!bs.read(z + 1))
|
||||
return false;
|
||||
|
||||
if (_rk) {
|
||||
samples = (bs.value() >> (32 - _rk)) + cnt;
|
||||
if (!bs.read(_rk))
|
||||
return false;
|
||||
} else
|
||||
samples = cnt;
|
||||
|
||||
_lrk = _rk + 1;
|
||||
if (_runIndex != 0) {
|
||||
_runIndex--;
|
||||
_rk = J[_runIndex];
|
||||
_rg = 1U << _rk;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!bs.read(8))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool JLS::decodeError(BitStream &bs, quint8 limit, quint8 k, uint &MErrval)
|
||||
{
|
||||
quint8 cnt = 0;
|
||||
MErrval = 0;
|
||||
|
||||
while ((int)bs.value() >= 0) {
|
||||
cnt = Z[bs.value() >> 0x18];
|
||||
MErrval += cnt;
|
||||
if (bs.value() >> 0x18 != 0)
|
||||
break;
|
||||
|
||||
if (!bs.read(8))
|
||||
return false;
|
||||
|
||||
cnt = 0;
|
||||
}
|
||||
|
||||
if (!bs.read(cnt + 1))
|
||||
return false;
|
||||
|
||||
if (MErrval < limit) {
|
||||
if (k != 0) {
|
||||
MErrval = (bs.value() >> (0x20 - k)) + (MErrval << k);
|
||||
if (!bs.read(k))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
MErrval = (bs.value() >> (0x20 - _qbpp)) + 1;
|
||||
if (!bs.read(_qbpp))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JLS::readLine(BitStream &bs)
|
||||
{
|
||||
quint8 ictx, rctx;
|
||||
quint8 k;
|
||||
uint MErrval;
|
||||
int Errval;
|
||||
int Rx;
|
||||
int Ra = _last[1];
|
||||
int Rb = _last[1];
|
||||
int Rc = _last[0];
|
||||
uint col = 1;
|
||||
|
||||
*_current = _last[1];
|
||||
|
||||
do {
|
||||
if (abs(Rb - Ra) > _near) {
|
||||
int Px = Ra + Rb - Rc;
|
||||
if (Px < 0)
|
||||
Px = 0;
|
||||
else if (Px > _maxval)
|
||||
Px = _maxval;
|
||||
|
||||
for (k = 0; _n[1] << k < _a[1]; k++)
|
||||
;
|
||||
|
||||
if (!decodeError(bs, _limit, k, MErrval))
|
||||
return false;
|
||||
|
||||
int mes, meh;
|
||||
if (MErrval & 1) {
|
||||
meh = (MErrval + 1) >> 1;
|
||||
mes = -meh;
|
||||
} else {
|
||||
meh = MErrval >> 1;
|
||||
mes = meh;
|
||||
}
|
||||
if ((_near == 0) && (k == 0) && (_b[1] * 2 <= -_n[1])) {
|
||||
meh = mes + 1;
|
||||
mes = -mes - 1;
|
||||
if (MErrval & 1)
|
||||
meh = mes;
|
||||
} else
|
||||
mes = mes * (_near * 2 + 1);
|
||||
|
||||
Errval = (Ra < Rb) ? mes : -mes;
|
||||
Rx = Px + Errval;
|
||||
|
||||
if (Rx < -_near)
|
||||
Rx += (_near * 2 + 1) * _range;
|
||||
else if (Rx > _maxval + _near)
|
||||
Rx -= (_near * 2 + 1) * _range;
|
||||
|
||||
if (Rx < 0)
|
||||
Rx = 0;
|
||||
if (Rx > _maxval)
|
||||
Rx = _maxval;
|
||||
|
||||
_a[1] = _a[1] + meh;
|
||||
_b[1] = _b[1] + mes;
|
||||
if (_n[1] == 0x40) {
|
||||
_a[1] = _a[1] >> 1;
|
||||
if (_b[1] >= 0)
|
||||
_b[1] = _b[1] >> 1;
|
||||
else
|
||||
_b[1] = -((1 - _b[1]) >> 1);
|
||||
_n[1] = 0x21;
|
||||
} else
|
||||
_n[1] = _n[1] + 1;
|
||||
|
||||
if (_b[1] <= -_n[1]) {
|
||||
_b[1] = _b[1] + _n[1];
|
||||
if (_b[1] <= -_n[1])
|
||||
_b[1] = 1 - _n[1];
|
||||
} else if (_b[1] > 0) {
|
||||
_b[1] = _b[1] - _n[1];
|
||||
if (_b[1] > 0)
|
||||
_b[1] = 0;
|
||||
}
|
||||
|
||||
Rc = Rb;
|
||||
Rb = _last[col + 1];
|
||||
} else {
|
||||
quint16 samples;
|
||||
if (!processRunMode(bs, _w - col + 1, samples))
|
||||
return false;
|
||||
|
||||
if (samples != 0) {
|
||||
for (int i = 0; i < samples; i++) {
|
||||
if (col > _w)
|
||||
return false;
|
||||
_current[col] = Ra;
|
||||
col++;
|
||||
}
|
||||
|
||||
if (col > _w)
|
||||
break;
|
||||
|
||||
Rc = _last[col];
|
||||
Rb = _last[col + 1];
|
||||
} else {
|
||||
Rc = Rb;
|
||||
Rb = _last[col + 1];
|
||||
}
|
||||
|
||||
rctx = (abs(Rc - Ra) <= _near);
|
||||
quint16 TEMP = _a[rctx + 2];
|
||||
if (rctx)
|
||||
TEMP += _n[rctx + 2] >> 1;
|
||||
ictx = rctx | 2;
|
||||
|
||||
for (k = 0; _n[rctx + 2] << k < TEMP; k++)
|
||||
;
|
||||
|
||||
if (!decodeError(bs, _limit - _lrk, k, MErrval))
|
||||
return false;
|
||||
|
||||
quint16 s = ((k == 0) && (rctx || MErrval)) ?
|
||||
(_b[ictx] * 2 < _n[ictx]) : 0;
|
||||
|
||||
Errval = MErrval + rctx + s;
|
||||
int evh;
|
||||
if ((Errval & 1) == 0) {
|
||||
Errval = Errval / 2;
|
||||
evh = Errval;
|
||||
} else {
|
||||
Errval = s - ((Errval + 1) >> 1);
|
||||
evh = -Errval;
|
||||
_b[ictx] = _b[ictx] + 1;
|
||||
}
|
||||
|
||||
Errval *= (_near * 2 + 1);
|
||||
if (!rctx) {
|
||||
if (Ra == Rc)
|
||||
return false;
|
||||
|
||||
if (Ra < Rc)
|
||||
Rx = Rc + Errval;
|
||||
else
|
||||
Rx = Rc - Errval;
|
||||
} else
|
||||
Rx = Ra + Errval;
|
||||
|
||||
if (Rx < -_near)
|
||||
Rx += (_near * 2 + 1) * _range;
|
||||
else if (Rx > _maxval + _near)
|
||||
Rx -= (_near * 2 + 1) * _range;
|
||||
|
||||
if (Rx < 0)
|
||||
Rx = 0;
|
||||
if (Rx > _maxval)
|
||||
Rx = _maxval;
|
||||
|
||||
_a[ictx] = _a[ictx] + (evh - rctx);
|
||||
if (_n[ictx] == 0x40) {
|
||||
_a[ictx] = _a[ictx] >> 1;
|
||||
if (_b[ictx] >= 0)
|
||||
_b[ictx] = _b[ictx] >> 1;
|
||||
else
|
||||
_b[ictx] = -((1 - _b[ictx]) >> 1);
|
||||
_n[ictx] = 0x21;
|
||||
} else
|
||||
_n[ictx] = _n[ictx] + 1;
|
||||
}
|
||||
|
||||
_current[col] = Rx;
|
||||
|
||||
Ra = Rx;
|
||||
col = col + 1;
|
||||
} while (col <= _w);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JLS::decode(const SubFile *file, SubFile::Handle &hdl, Matrix<qint16> &img)
|
||||
{
|
||||
BitStream bs(file, hdl);
|
||||
if (!bs.init())
|
||||
return false;
|
||||
|
||||
_w = img.w();
|
||||
_data = QVector<quint16>((_w + 3) * 2);
|
||||
_last = _data.data();
|
||||
_current = _data.data() + (_w + 3);
|
||||
|
||||
_runIndex = 0;
|
||||
_rk = 0;
|
||||
_rg = 1;
|
||||
_lrk = 0;
|
||||
|
||||
quint16 A = max(2, (_range + 32) / 64);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
_a[i] = A;
|
||||
_b[i] = 0;
|
||||
_n[i] = 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < img.h(); i++) {
|
||||
if (!readLine(bs))
|
||||
return false;
|
||||
|
||||
memcpy(&img.at(i, 0), _current + 1, _w * sizeof(quint16));
|
||||
|
||||
quint16 *tmp = _last;
|
||||
_last = _current;
|
||||
_current = tmp;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
85
src/map/IMG/jls.h
Normal file
@ -0,0 +1,85 @@
|
||||
#ifndef IMG_JLS_H
|
||||
#define IMG_JLS_H
|
||||
|
||||
#include <QVector>
|
||||
#include "map/matrix.h"
|
||||
#include "subfile.h"
|
||||
|
||||
namespace IMG {
|
||||
|
||||
class JLS
|
||||
{
|
||||
public:
|
||||
JLS(quint16 maxval, quint16 near);
|
||||
|
||||
bool decode(const SubFile *file, SubFile::Handle &hdl, Matrix<qint16> &img);
|
||||
|
||||
private:
|
||||
class BitStream
|
||||
{
|
||||
public:
|
||||
BitStream(const SubFile *file, SubFile::Handle &hdl)
|
||||
: _file(file), _hdl(hdl) {}
|
||||
|
||||
bool init()
|
||||
{
|
||||
if (!_file->readVUInt32SW(_hdl, 4, _value))
|
||||
return false;
|
||||
_shift = (quint8)-8;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read(quint8 bits)
|
||||
{
|
||||
quint8 data;
|
||||
|
||||
_value <<= bits;
|
||||
_shift += bits;
|
||||
|
||||
while (-1 < (qint8)_shift) {
|
||||
if (!_file->readByte(_hdl, &data))
|
||||
return false;
|
||||
|
||||
_value |= (quint32)data << _shift;
|
||||
_shift -= 8;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
quint32 value() const {return _value;}
|
||||
|
||||
private:
|
||||
const SubFile *_file;
|
||||
SubFile::Handle &_hdl;
|
||||
quint32 _value;
|
||||
quint8 _shift;
|
||||
};
|
||||
|
||||
bool readLine(BitStream &bs);
|
||||
bool processRunMode(BitStream &bs, quint16 col, quint16 &samples);
|
||||
bool decodeError(BitStream &bs, quint8 limit, quint8 k, uint &MErrval);
|
||||
|
||||
quint16 _maxval;
|
||||
quint16 _near;
|
||||
quint16 _range;
|
||||
quint8 _qbpp;
|
||||
quint8 _limit;
|
||||
|
||||
quint8 _runIndex;
|
||||
quint8 _rk;
|
||||
quint16 _rg;
|
||||
quint16 _n[4];
|
||||
quint16 _a[4];
|
||||
qint16 _b[4];
|
||||
quint8 _lrk;
|
||||
|
||||
quint16 _w;
|
||||
QVector<quint16> _data;
|
||||
quint16 *_current;
|
||||
quint16 *_last;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // IMG_JLS_H
|
@ -5,55 +5,36 @@
|
||||
using namespace Garmin;
|
||||
using namespace IMG;
|
||||
|
||||
enum Charset {Normal, Symbol, Special};
|
||||
|
||||
static quint8 NORMAL_CHARS[] = {
|
||||
' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '~', '~', '~', ' ', ' ',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '~', '~', '~', '~', '~', '~'
|
||||
};
|
||||
|
||||
static quint8 SYMBOL_CHARS[] = {
|
||||
'@', '!', '"', '#', '$', '%', '&', '\'',
|
||||
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'~', '~', '~', '~', '~', '~', '~', '~',
|
||||
'~', '~', ':', ';', '<', '=', '>', '?',
|
||||
'~', '~', '~', '~', '~', '~', '~', '~',
|
||||
'~', '~', '~', '[', '\\', ']', '^', '_'
|
||||
};
|
||||
|
||||
static quint8 SPECIAL_CHARS[] = {
|
||||
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', '~', '~', '~', '~', '~',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '~', '~', '~', '~', '~', '~'
|
||||
};
|
||||
|
||||
static bool isAllUpperCase(const QString &str)
|
||||
{
|
||||
if (str.isEmpty())
|
||||
return false;
|
||||
for (int i = 0; i < str.size(); i++)
|
||||
if (str.at(i).isLetter() && !(str.at(i).isUpper()
|
||||
|| str.at(i) == QChar(0x00DF)))
|
||||
|
||||
for (int i = 0; i < str.size(); i++) {
|
||||
QChar c(str.at(i));
|
||||
|
||||
if (c.isLetter() && !(c.isUpper() || c == QChar(0x00DF)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static QString capitalized(const QString &str)
|
||||
{
|
||||
QString ret(str);
|
||||
for (int i = 0; i < str.size(); i++)
|
||||
if (i && !str.at(i-1).isSpace())
|
||||
ret[i] = str.at(i).toLower();
|
||||
else
|
||||
ret[i] = str.at(i);
|
||||
QString ret;
|
||||
|
||||
ret.resize(str.size());
|
||||
|
||||
if (!str.isEmpty())
|
||||
ret[0] = str.at(0);
|
||||
|
||||
for (int i = 1; i < str.size(); i++) {
|
||||
QChar last(str.at(i-1));
|
||||
QChar c(str.at(i));
|
||||
|
||||
ret[i] = (last.isSpace() || last == '(') ? c : c.toLower();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -65,11 +46,10 @@ static QByteArray ft2m(const QByteArray &str)
|
||||
return ok ? QByteArray::number(qRound(number * 0.3048)) : str;
|
||||
}
|
||||
|
||||
|
||||
LBLFile::~LBLFile()
|
||||
{
|
||||
delete _huffmanText;
|
||||
delete[] _table;
|
||||
delete[] _rasters;
|
||||
}
|
||||
|
||||
bool LBLFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
||||
@ -93,10 +73,10 @@ bool LBLFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
||||
return false;
|
||||
|
||||
if (size && recordSize) {
|
||||
_table = new quint32[size / recordSize];
|
||||
_table.resize(size / recordSize);
|
||||
if (!seek(hdl, offset))
|
||||
return false;
|
||||
for (quint32 i = 0; i < size / recordSize; i++) {
|
||||
for (int i = 0; i < _table.size(); i++) {
|
||||
if (!readVUInt32(hdl, recordSize, _table[i]))
|
||||
return false;
|
||||
}
|
||||
@ -129,12 +109,10 @@ bool LBLFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
||||
|
||||
void LBLFile::clear()
|
||||
{
|
||||
_table = QVector<quint32>();
|
||||
_rasters = QVector<Image>();
|
||||
delete _huffmanText;
|
||||
delete[] _table;
|
||||
delete[] _rasters;
|
||||
_huffmanText = 0;
|
||||
_table = 0;
|
||||
_rasters = 0;
|
||||
}
|
||||
|
||||
Label LBLFile::str2label(const QVector<quint8> &str, bool capitalize,
|
||||
@ -183,10 +161,35 @@ Label LBLFile::str2label(const QVector<quint8> &str, bool capitalize,
|
||||
Label LBLFile::label6b(const SubFile *file, Handle &fileHdl, quint32 size,
|
||||
bool capitalize, bool convert) const
|
||||
{
|
||||
enum Charset {Normal, Symbol, Special};
|
||||
static const quint8 NORMAL_CHARS[] = {
|
||||
' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '~', '~', '~', ' ', ' ',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '~', '~', '~', '~', '~', '~'
|
||||
};
|
||||
static const quint8 SYMBOL_CHARS[] = {
|
||||
'@', '!', '"', '#', '$', '%', '&', '\'',
|
||||
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'~', '~', '~', '~', '~', '~', '~', '~',
|
||||
'~', '~', ':', ';', '<', '=', '>', '?',
|
||||
'~', '~', '~', '~', '~', '~', '~', '~',
|
||||
'~', '~', '~', '[', '\\', ']', '^', '_'
|
||||
};
|
||||
static const quint8 SPECIAL_CHARS[] = {
|
||||
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', '~', '~', '~', '~', '~',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '~', '~', '~', '~', '~', '~'
|
||||
};
|
||||
Shield::Type shieldType = Shield::None;
|
||||
QByteArray label, shieldLabel;
|
||||
QByteArray *bap = &label;
|
||||
Charset curCharSet = Normal;
|
||||
Charset charset = Normal;
|
||||
quint8 b1, b2, b3;
|
||||
int split = -1;
|
||||
|
||||
@ -198,7 +201,7 @@ Label LBLFile::label6b(const SubFile *file, Handle &fileHdl, quint32 size,
|
||||
int c[]= {b1>>2, (b1&0x3)<<4|b2>>4, (b2&0xF)<<2|b3>>6, b3&0x3F};
|
||||
|
||||
for (int cpt = 0; cpt < 4; cpt++) {
|
||||
if (c[cpt] > 0x2f || (curCharSet == Normal && c[cpt] == 0x1d)) {
|
||||
if (c[cpt] > 0x2f || (charset == Normal && c[cpt] == 0x1d)) {
|
||||
if (split >= 0)
|
||||
label = label.left(split) + ft2m(label.mid(split));
|
||||
else if (convert)
|
||||
@ -207,12 +210,12 @@ Label LBLFile::label6b(const SubFile *file, Handle &fileHdl, quint32 size,
|
||||
return Label(capitalize && isAllUpperCase(text)
|
||||
? capitalized(text) : text, Shield(shieldType, shieldLabel));
|
||||
}
|
||||
switch (curCharSet) {
|
||||
switch (charset) {
|
||||
case Normal:
|
||||
if (c[cpt] == 0x1c)
|
||||
curCharSet = Symbol;
|
||||
charset = Symbol;
|
||||
else if (c[cpt] == 0x1b)
|
||||
curCharSet = Special;
|
||||
charset = Special;
|
||||
else if (c[cpt] >= 0x1e && c[cpt] <= 0x1f) {
|
||||
if (bap == &shieldLabel)
|
||||
bap = &label;
|
||||
@ -233,11 +236,11 @@ Label LBLFile::label6b(const SubFile *file, Handle &fileHdl, quint32 size,
|
||||
break;
|
||||
case Symbol:
|
||||
bap->append(SYMBOL_CHARS[c[cpt]]);
|
||||
curCharSet = Normal;
|
||||
charset = Normal;
|
||||
break;
|
||||
case Special:
|
||||
bap->append(SPECIAL_CHARS[c[cpt]]);
|
||||
curCharSet = Normal;
|
||||
charset = Normal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -266,42 +269,41 @@ Label LBLFile::label8b(const SubFile *file, Handle &fileHdl, quint32 size,
|
||||
Label LBLFile::labelHuffman(Handle &hdl, const SubFile *file, Handle &fileHdl,
|
||||
quint32 size, bool capitalize, bool convert)
|
||||
{
|
||||
QVector<quint8> tpl;
|
||||
|
||||
if (!_huffmanText->decode(file, fileHdl, size, tpl))
|
||||
return Label();
|
||||
if (!_table.size())
|
||||
return str2label(tpl, capitalize, convert);
|
||||
|
||||
|
||||
QVector<quint8> str;
|
||||
|
||||
if (!_huffmanText->decode(file, fileHdl, size, str))
|
||||
return Label();
|
||||
if (!_table)
|
||||
return str2label(str, capitalize, convert);
|
||||
for (int i = 0; i < tpl.size(); i++) {
|
||||
quint8 c(tpl.at(i));
|
||||
quint32 val = (c < _table.size()) ? _table.at(c) : 0;
|
||||
|
||||
|
||||
QVector<quint8> str2;
|
||||
for (int i = 0; i < str.size(); i++) {
|
||||
quint32 val = _table[str.at(i)];
|
||||
if (val) {
|
||||
quint32 off = _base.offset + ((val & 0x7fffff) << _shift);
|
||||
if (!seek(hdl, off))
|
||||
if (str.size() && str.back() == '\0')
|
||||
str.back() = ' ';
|
||||
else if (str.size())
|
||||
str.append(' ');
|
||||
|
||||
quint32 offset = _base.offset + ((val & 0x7fffff) << _shift);
|
||||
quint32 limit = _base.offset + _base.size - offset;
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
|
||||
if (str2.size() && str2.back() == '\0')
|
||||
str2[str2.size() - 1] = ' ';
|
||||
else if (str2.size())
|
||||
str2.append(' ');
|
||||
|
||||
if (!_huffmanText->decode(this, hdl, _base.offset + _base.size - off,
|
||||
str2))
|
||||
if (!_huffmanText->decode(this, hdl, limit, str))
|
||||
return Label();
|
||||
} else {
|
||||
if (str.at(i) == 7) {
|
||||
str2.append(0);
|
||||
break;
|
||||
}
|
||||
if (str2.size() && str2.back() == '\0')
|
||||
str2[str2.size() - 1] = ' ';
|
||||
str2.append(str.at(i));
|
||||
if (str.size() && str.back() == '\0')
|
||||
str.back() = ' ';
|
||||
|
||||
str.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return str2label(str2, capitalize, convert);
|
||||
return str2label(str, capitalize, convert);
|
||||
}
|
||||
|
||||
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize,
|
||||
@ -347,15 +349,15 @@ bool LBLFile::loadRasterTable(Handle &hdl, quint32 offset, quint32 size,
|
||||
quint32 recordSize)
|
||||
{
|
||||
quint32 prev, cur;
|
||||
quint32 imgCount = size / recordSize;
|
||||
|
||||
_imgCount = size / recordSize;
|
||||
_imgIdSize = byteSize(_imgCount - 1);
|
||||
_rasters = new Image[_imgCount];
|
||||
_imgIdSize = byteSize(imgCount - 1);
|
||||
_rasters.resize(imgCount);
|
||||
|
||||
if (!(seek(hdl, offset) && readVUInt32(hdl, recordSize, prev)))
|
||||
return false;
|
||||
|
||||
for (quint32 i = 1; i < _imgCount; i++) {
|
||||
for (quint32 i = 1; i < imgCount; i++) {
|
||||
if (!readVUInt32(hdl, recordSize, cur))
|
||||
return false;
|
||||
|
||||
@ -365,8 +367,8 @@ bool LBLFile::loadRasterTable(Handle &hdl, quint32 offset, quint32 size,
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
_rasters[_imgCount-1].offset = prev;
|
||||
_rasters[_imgCount-1].size = _img.size - prev;
|
||||
_rasters[imgCount-1].offset = prev;
|
||||
_rasters[imgCount-1].size = _img.size - prev;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -375,14 +377,14 @@ QPixmap LBLFile::image(Handle &hdl, quint32 id) const
|
||||
{
|
||||
QPixmap pm;
|
||||
|
||||
if (id >= _imgCount)
|
||||
if ((int)id >= _rasters.size())
|
||||
return pm;
|
||||
|
||||
if (!seek(hdl, _img.offset + _rasters[id].offset))
|
||||
if (!seek(hdl, _img.offset + _rasters.at(id).offset))
|
||||
return pm;
|
||||
QByteArray ba;
|
||||
ba.resize(_rasters[id].size);
|
||||
if (!read(hdl, ba.data(), _rasters[id].size))
|
||||
ba.resize(_rasters.at(id).size);
|
||||
if (!read(hdl, ba.data(), ba.size()))
|
||||
return pm;
|
||||
|
||||
pm.loadFromData(ba, "jpeg");
|
||||
|
@ -16,14 +16,14 @@ class LBLFile : public SubFile
|
||||
{
|
||||
public:
|
||||
LBLFile(const IMGData *img)
|
||||
: SubFile(img), _huffmanText(0), _table(0), _rasters(0), _imgIdSize(0),
|
||||
_poiShift(0), _shift(0), _encoding(0) {}
|
||||
: SubFile(img), _huffmanText(0), _imgIdSize(0), _poiShift(0), _shift(0),
|
||||
_encoding(0) {}
|
||||
LBLFile(const QString *path)
|
||||
: SubFile(path), _huffmanText(0), _table(0), _rasters(0), _imgIdSize(0),
|
||||
_poiShift(0), _shift(0), _encoding(0) {}
|
||||
: SubFile(path), _huffmanText(0), _imgIdSize(0), _poiShift(0), _shift(0),
|
||||
_encoding(0) {}
|
||||
LBLFile(const SubFile *gmp, quint32 offset)
|
||||
: SubFile(gmp, offset), _huffmanText(0), _table(0), _rasters(0),
|
||||
_imgIdSize(0), _poiShift(0), _shift(0), _encoding(0) {}
|
||||
: SubFile(gmp, offset), _huffmanText(0), _imgIdSize(0), _poiShift(0),
|
||||
_shift(0), _encoding(0) {}
|
||||
~LBLFile();
|
||||
|
||||
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
|
||||
@ -55,11 +55,10 @@ private:
|
||||
quint32 recordSize);
|
||||
|
||||
HuffmanText *_huffmanText;
|
||||
quint32 *_table;
|
||||
Image *_rasters;
|
||||
QVector<Image> _rasters;
|
||||
QVector<quint32> _table;
|
||||
TextCodec _codec;
|
||||
Section _base, _poi, _img;
|
||||
quint32 _imgCount;
|
||||
quint8 _imgIdSize;
|
||||
quint8 _poiShift;
|
||||
quint8 _shift;
|
||||
|
@ -7,29 +7,37 @@
|
||||
|
||||
using namespace IMG;
|
||||
|
||||
#define CACHED_SUBDIVS_COUNT 2048 // ~32MB for both caches together
|
||||
#define CACHED_SUBDIVS_COUNT 2048 // ~32MB for both caches together
|
||||
#define CACHED_DEMTILES_COUNT 1024 // ~32MB
|
||||
|
||||
bool MapData::polyCb(VectorTile *tile, void *context)
|
||||
{
|
||||
PolyCTX *ctx = (PolyCTX*)context;
|
||||
tile->polys(ctx->rect, ctx->zoom, ctx->polygons, ctx->lines,
|
||||
ctx->polyCache, ctx->lock);
|
||||
ctx->cache, ctx->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapData::pointCb(VectorTile *tile, void *context)
|
||||
{
|
||||
PointCTX *ctx = (PointCTX*)context;
|
||||
tile->points(ctx->rect, ctx->zoom, ctx->points, ctx->pointCache, ctx->lock);
|
||||
tile->points(ctx->rect, ctx->zoom, ctx->points, ctx->cache, ctx->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapData::elevationCb(VectorTile *tile, void *context)
|
||||
{
|
||||
ElevationCTX *ctx = (ElevationCTX*)context;
|
||||
tile->elevations(ctx->rect, ctx->zoom, ctx->elevations, ctx->cache, ctx->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
MapData::MapData(const QString &fileName)
|
||||
: _fileName(fileName), _typ(0), _style(0), _valid(false)
|
||||
: _fileName(fileName), _typ(0), _style(0), _hasDEM(false), _valid(false)
|
||||
{
|
||||
_polyCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
||||
_pointCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
||||
_demCache.setMaxCost(CACHED_DEMTILES_COUNT);
|
||||
}
|
||||
|
||||
MapData::~MapData()
|
||||
@ -69,6 +77,19 @@ void MapData::points(const RectC &rect, int bits, QList<Point> *points)
|
||||
_tileTree.Search(min, max, pointCb, &ctx);
|
||||
}
|
||||
|
||||
void MapData::elevations(const RectC &rect, int bits, QList<Elevation> *elevations)
|
||||
{
|
||||
ElevationCTX ctx(rect, zoom(bits), elevations, &_demCache, &_demLock);
|
||||
double min[2], max[2];
|
||||
|
||||
min[0] = rect.left();
|
||||
min[1] = rect.bottom();
|
||||
max[0] = rect.right();
|
||||
max[1] = rect.top();
|
||||
|
||||
_tileTree.Search(min, max, elevationCb, &ctx);
|
||||
}
|
||||
|
||||
void MapData::load(qreal ratio)
|
||||
{
|
||||
Q_ASSERT(!_style);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "common/rtree.h"
|
||||
#include "common/range.h"
|
||||
#include "common/hash.h"
|
||||
#include "map/matrix.h"
|
||||
#include "label.h"
|
||||
#include "raster.h"
|
||||
#include "zoom.h"
|
||||
@ -20,6 +21,7 @@ class Style;
|
||||
class SubDiv;
|
||||
class SubFile;
|
||||
class VectorTile;
|
||||
class DEMTile;
|
||||
|
||||
class MapData
|
||||
{
|
||||
@ -55,6 +57,13 @@ public:
|
||||
{return id < other.id;}
|
||||
};
|
||||
|
||||
struct Elevation {
|
||||
Matrix<qint16> m;
|
||||
RectC rect;
|
||||
double xr;
|
||||
double yr;
|
||||
};
|
||||
|
||||
MapData(const QString &fileName);
|
||||
virtual ~MapData();
|
||||
|
||||
@ -65,10 +74,13 @@ public:
|
||||
void polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||
QList<Poly> *lines);
|
||||
void points(const RectC &rect, int bits, QList<Point> *points);
|
||||
void elevations(const RectC &rect, int bits, QList<Elevation> *elevations);
|
||||
|
||||
void load(qreal ratio);
|
||||
void clear();
|
||||
|
||||
bool hasDEM() const {return _hasDEM;}
|
||||
|
||||
const QString &fileName() const {return _fileName;}
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
@ -87,6 +99,7 @@ protected:
|
||||
TileTree _tileTree;
|
||||
QList<Zoom> _zooms;
|
||||
Range _zoomLevels;
|
||||
bool _hasDEM;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
@ -103,34 +116,48 @@ private:
|
||||
|
||||
typedef QCache<const SubDiv*, Polys> PolyCache;
|
||||
typedef QCache<const SubDiv*, QList<Point> > PointCache;
|
||||
typedef QCache<const DEMTile*, Elevation> ElevationCache;
|
||||
|
||||
struct PolyCTX
|
||||
{
|
||||
PolyCTX(const RectC &rect, const Zoom &zoom,
|
||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||
PolyCache *polyCache, QMutex *lock)
|
||||
PolyCache *cache, QMutex *lock)
|
||||
: rect(rect), zoom(zoom), polygons(polygons), lines(lines),
|
||||
polyCache(polyCache), lock(lock) {}
|
||||
cache(cache), lock(lock) {}
|
||||
|
||||
const RectC ▭
|
||||
const Zoom &zoom;
|
||||
QList<MapData::Poly> *polygons;
|
||||
QList<MapData::Poly> *lines;
|
||||
PolyCache *polyCache;
|
||||
PolyCache *cache;
|
||||
QMutex *lock;
|
||||
};
|
||||
|
||||
struct PointCTX
|
||||
{
|
||||
PointCTX(const RectC &rect, const Zoom &zoom,
|
||||
QList<MapData::Point> *points, PointCache *pointCache, QMutex *lock)
|
||||
: rect(rect), zoom(zoom), points(points), pointCache(pointCache),
|
||||
lock(lock) {}
|
||||
QList<MapData::Point> *points, PointCache *cache, QMutex *lock)
|
||||
: rect(rect), zoom(zoom), points(points), cache(cache), lock(lock) {}
|
||||
|
||||
const RectC ▭
|
||||
const Zoom &zoom;
|
||||
QList<MapData::Point> *points;
|
||||
PointCache *pointCache;
|
||||
PointCache *cache;
|
||||
QMutex *lock;
|
||||
};
|
||||
|
||||
struct ElevationCTX
|
||||
{
|
||||
ElevationCTX(const RectC &rect, const Zoom &zoom,
|
||||
QList<Elevation> *elevations, ElevationCache *cache, QMutex *lock)
|
||||
: rect(rect), zoom(zoom), elevations(elevations), cache(cache),
|
||||
lock(lock) {}
|
||||
|
||||
const RectC ▭
|
||||
const Zoom &zoom;
|
||||
QList<Elevation> *elevations;
|
||||
ElevationCache *cache;
|
||||
QMutex *lock;
|
||||
};
|
||||
|
||||
@ -138,10 +165,12 @@ private:
|
||||
|
||||
static bool polyCb(VectorTile *tile, void *context);
|
||||
static bool pointCb(VectorTile *tile, void *context);
|
||||
static bool elevationCb(VectorTile *tile, void *context);
|
||||
|
||||
PolyCache _polyCache;
|
||||
PointCache _pointCache;
|
||||
QMutex _lock;
|
||||
ElevationCache _demCache;
|
||||
QMutex _lock, _demLock;
|
||||
|
||||
friend class VectorTile;
|
||||
};
|
||||
|
@ -7,8 +7,10 @@
|
||||
#include "map/bitmapline.h"
|
||||
#include "map/rectd.h"
|
||||
#include "map/hillshading.h"
|
||||
#include "map/filter.h"
|
||||
#include "style.h"
|
||||
#include "lblfile.h"
|
||||
#include "dem.h"
|
||||
#include "rastertile.h"
|
||||
|
||||
using namespace IMG;
|
||||
@ -27,6 +29,8 @@ using namespace IMG;
|
||||
#define ROAD 0
|
||||
#define WATER 1
|
||||
|
||||
#define BLUR_RADIUS 3
|
||||
|
||||
static const QColor textColor(Qt::black);
|
||||
static const QColor haloColor(Qt::white);
|
||||
static const QColor shieldColor(Qt::white);
|
||||
@ -107,7 +111,8 @@ static bool rectNearPolygon(const QPolygonF &polygon, const QRectF &rect)
|
||||
|| polygon.containsPoint(rect.bottomRight(), Qt::OddEvenFill)));
|
||||
}
|
||||
|
||||
const QFont *RasterTile::poiFont(Style::FontSize size, int zoom, bool extended)
|
||||
const QFont *RasterTile::poiFont(Style::FontSize size, int zoom,
|
||||
bool extended) const
|
||||
{
|
||||
if (zoom > 25)
|
||||
size = Style::Normal;
|
||||
@ -122,7 +127,7 @@ const QFont *RasterTile::poiFont(Style::FontSize size, int zoom, bool extended)
|
||||
}
|
||||
}
|
||||
|
||||
void RasterTile::ll2xy(QList<MapData::Poly> &polys)
|
||||
void RasterTile::ll2xy(QList<MapData::Poly> &polys) const
|
||||
{
|
||||
for (int i = 0; i < polys.size(); i++) {
|
||||
MapData::Poly &poly = polys[i];
|
||||
@ -133,7 +138,7 @@ void RasterTile::ll2xy(QList<MapData::Poly> &polys)
|
||||
}
|
||||
}
|
||||
|
||||
void RasterTile::ll2xy(QList<MapData::Point> &points)
|
||||
void RasterTile::ll2xy(QList<MapData::Point> &points) const
|
||||
{
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
QPointF p(ll2xy(points.at(i).coordinates));
|
||||
@ -142,7 +147,7 @@ void RasterTile::ll2xy(QList<MapData::Point> &points)
|
||||
}
|
||||
|
||||
void RasterTile::drawPolygons(QPainter *painter,
|
||||
const QList<MapData::Poly> &polygons)
|
||||
const QList<MapData::Poly> &polygons) const
|
||||
{
|
||||
QCache<const LBLFile *, SubFile::Handle> hc(16);
|
||||
|
||||
@ -177,7 +182,9 @@ void RasterTile::drawPolygons(QPainter *painter,
|
||||
|
||||
//painter->setPen(Qt::blue);
|
||||
//painter->setBrush(Qt::NoBrush);
|
||||
//painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
//painter->drawRect(QRectF(tl, br));
|
||||
//painter->setRenderHint(QPainter::Antialiasing);
|
||||
} else {
|
||||
const Style::Polygon &style = _data->style()->polygon(poly.type);
|
||||
|
||||
@ -189,7 +196,8 @@ void RasterTile::drawPolygons(QPainter *painter,
|
||||
}
|
||||
}
|
||||
|
||||
void RasterTile::drawLines(QPainter *painter, const QList<MapData::Poly> &lines)
|
||||
void RasterTile::drawLines(QPainter *painter,
|
||||
const QList<MapData::Poly> &lines) const
|
||||
{
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
|
||||
@ -218,7 +226,7 @@ void RasterTile::drawLines(QPainter *painter, const QList<MapData::Poly> &lines)
|
||||
}
|
||||
|
||||
void RasterTile::drawTextItems(QPainter *painter,
|
||||
const QList<TextItem*> &textItems)
|
||||
const QList<TextItem*> &textItems) const
|
||||
{
|
||||
for (int i = 0; i < textItems.size(); i++)
|
||||
textItems.at(i)->paint(painter);
|
||||
@ -446,30 +454,56 @@ void RasterTile::fetchData(QList<MapData::Poly> &polygons,
|
||||
_data->points(pointRectD.toRectC(_proj, 20), _zoom, &points);
|
||||
}
|
||||
|
||||
Matrix RasterTile::elevation() const
|
||||
MatrixD RasterTile::elevation(int extend) const
|
||||
{
|
||||
Matrix m(_rect.height() + 2, _rect.width() + 2);
|
||||
|
||||
int left = _rect.left() - 1;
|
||||
int right = _rect.right() + 1;
|
||||
int top = _rect.top() - 1;
|
||||
int bottom = _rect.bottom() + 1;
|
||||
|
||||
MatrixD m(_rect.height() + 2 * extend, _rect.width() + 2 * extend);
|
||||
QVector<Coordinates> ll;
|
||||
|
||||
int left = _rect.left() - extend;
|
||||
int right = _rect.right() + extend;
|
||||
int top = _rect.top() - extend;
|
||||
int bottom = _rect.bottom() + extend;
|
||||
|
||||
ll.reserve(m.w() * m.h());
|
||||
for (int y = top; y <= bottom; y++) {
|
||||
for (int y = top; y <= bottom; y++)
|
||||
for (int x = left; x <= right; x++)
|
||||
ll.append(xy2ll(QPointF(x, y)));
|
||||
|
||||
if (_data->hasDEM()) {
|
||||
RectC rect;
|
||||
QList<MapData::Elevation> tiles;
|
||||
DEMTRee tree;
|
||||
|
||||
for (int i = 0; i < ll.size(); i++)
|
||||
rect = rect.united(ll.at(i));
|
||||
// Extra margin for always including the next DEM tile on the map tile
|
||||
// edges (the DEM tile resolution is usally 0.5-15% of the map tile)
|
||||
double factor = 6 - (_zoom - 24) * 1.7;
|
||||
_data->elevations(rect.adjusted(0, 0, rect.width() / factor,
|
||||
-rect.height() / factor), _zoom, &tiles);
|
||||
|
||||
DEM::buildTree(tiles, tree);
|
||||
for (int i = 0; i < ll.size(); i++)
|
||||
DEM::searchTree(tree, ll.at(i), m.at(i));
|
||||
} else {
|
||||
::DEM::lock();
|
||||
for (int i = 0; i < ll.size(); i++)
|
||||
m.at(i) = ::DEM::elevation(ll.at(i));
|
||||
::DEM::unlock();
|
||||
}
|
||||
|
||||
DEM::lock();
|
||||
for (int i = 0; i < ll.size(); i++)
|
||||
m.m(i) = DEM::elevation(ll.at(i));
|
||||
DEM::unlock();
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void RasterTile::drawHillShading(QPainter *painter) const
|
||||
{
|
||||
if (_hillShading && _zoom >= 18 && _zoom <= 24) {
|
||||
MatrixD dem(Filter::blur(elevation(BLUR_RADIUS + 1), BLUR_RADIUS));
|
||||
QImage img(HillShading::render(dem, BLUR_RADIUS + 1));
|
||||
painter->drawImage(_rect.x(), _rect.y(), img);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterTile::render()
|
||||
{
|
||||
QImage img(_rect.width() * _ratio, _rect.height() * _ratio,
|
||||
@ -501,14 +535,14 @@ void RasterTile::render()
|
||||
painter.translate(-_rect.x(), -_rect.y());
|
||||
|
||||
drawPolygons(&painter, polygons);
|
||||
if (_hillShading && _zoom >= 18 && _zoom <= 24)
|
||||
painter.drawImage(_rect.x(), _rect.y(), HillShading::render(elevation()));
|
||||
drawHillShading(&painter);
|
||||
drawLines(&painter, lines);
|
||||
drawTextItems(&painter, textItems);
|
||||
|
||||
qDeleteAll(textItems);
|
||||
|
||||
//painter.setPen(Qt::red);
|
||||
//painter.setBrush(Qt::NoBrush);
|
||||
//painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
//painter.drawRect(_rect);
|
||||
|
||||
|
@ -30,18 +30,36 @@ public:
|
||||
void render();
|
||||
|
||||
private:
|
||||
typedef RTree<const MapData::Elevation*, double, 2> DEMTRee;
|
||||
|
||||
struct ElevationCTX {
|
||||
ElevationCTX(const DEMTRee &tree, const Coordinates &c, double &ele)
|
||||
: tree(tree), c(c), ele(ele) {}
|
||||
|
||||
const DEMTRee &tree;
|
||||
const Coordinates &c;
|
||||
double &ele;
|
||||
};
|
||||
struct EdgeCTX {
|
||||
EdgeCTX(const Coordinates &c, double &ele) : c(c), ele(ele) {}
|
||||
|
||||
const Coordinates &c;
|
||||
double &ele;
|
||||
};
|
||||
|
||||
void fetchData(QList<MapData::Poly> &polygons, QList<MapData::Poly> &lines,
|
||||
QList<MapData::Point> &points);
|
||||
QPointF ll2xy(const Coordinates &c) const
|
||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||
Coordinates xy2ll(const QPointF &p) const
|
||||
{return _proj.xy2ll(_transform.img2proj(p));}
|
||||
void ll2xy(QList<MapData::Poly> &polys);
|
||||
void ll2xy(QList<MapData::Point> &points);
|
||||
void ll2xy(QList<MapData::Poly> &polys) const;
|
||||
void ll2xy(QList<MapData::Point> &points) const;
|
||||
|
||||
void drawPolygons(QPainter *painter, const QList<MapData::Poly> &polygons);
|
||||
void drawLines(QPainter *painter, const QList<MapData::Poly> &lines);
|
||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||
void drawPolygons(QPainter *painter, const QList<MapData::Poly> &polygons) const;
|
||||
void drawLines(QPainter *painter, const QList<MapData::Poly> &lines) const;
|
||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems) const;
|
||||
void drawHillShading(QPainter *painter) const;
|
||||
|
||||
void processPolygons(const QList<MapData::Poly> &polygons,
|
||||
QList<TextItem *> &textItems);
|
||||
@ -55,9 +73,9 @@ private:
|
||||
QList<TextItem*> &textItems, const QImage (&arrows)[2]);
|
||||
|
||||
const QFont *poiFont(Style::FontSize size = Style::Normal,
|
||||
int zoom = -1, bool extended = false);
|
||||
int zoom = -1, bool extended = false) const;
|
||||
|
||||
Matrix elevation() const;
|
||||
MatrixD elevation(int extend) const;
|
||||
|
||||
Projection _proj;
|
||||
Transform _transform;
|
||||
|
@ -187,7 +187,7 @@ void Style::defaultPolygonStyle()
|
||||
_polygons[TYPE(0x14)] = Polygon(QBrush(QColor(0xca, 0xdf, 0xaf)));
|
||||
_polygons[TYPE(0x15)] = Polygon(QBrush(QColor(0xca, 0xdf, 0xaf)));
|
||||
_polygons[TYPE(0x16)] = Polygon(QBrush(QColor(0x9a, 0xc2, 0x69),
|
||||
Qt::Dense5Pattern));
|
||||
Qt::BDiagPattern));
|
||||
_polygons[TYPE(0x17)] = Polygon(QBrush(QColor(0xe4, 0xef, 0xcf)));
|
||||
_polygons[TYPE(0x18)] = Polygon(QBrush(QColor(0xe3, 0xed, 0xc6)));
|
||||
_polygons[TYPE(0x19)] = Polygon(QBrush(QColor(0xe3, 0xed, 0xc6)),
|
||||
@ -195,9 +195,9 @@ void Style::defaultPolygonStyle()
|
||||
_polygons[TYPE(0x1a)] = Polygon(QBrush(QColor(0, 0, 0), Qt::Dense6Pattern),
|
||||
QPen(QColor(0xcd, 0xcc, 0xc4), 1));
|
||||
_polygons[TYPE(0x1e)] = Polygon(QBrush(QColor(0x9a, 0xc2, 0x69),
|
||||
Qt::Dense5Pattern));
|
||||
Qt::BDiagPattern));
|
||||
_polygons[TYPE(0x1f)] = Polygon(QBrush(QColor(0x9a, 0xc2, 0x69),
|
||||
Qt::Dense5Pattern));
|
||||
Qt::BDiagPattern));
|
||||
_polygons[TYPE(0x28)] = Polygon(QBrush(QColor(0x9f, 0xc4, 0xe1)));
|
||||
_polygons[TYPE(0x32)] = Polygon(QBrush(QColor(0x9f, 0xc4, 0xe1)));
|
||||
_polygons[TYPE(0x3c)] = Polygon(QBrush(QColor(0x9f, 0xc4, 0xe1)));
|
||||
|
@ -13,7 +13,7 @@ namespace IMG {
|
||||
class SubFile
|
||||
{
|
||||
public:
|
||||
enum Type {Unknown, TRE, RGN, LBL, NET, NOD, TYP, GMP};
|
||||
enum Type {Unknown, TRE, RGN, LBL, NET, NOD, DEM, TYP, GMP};
|
||||
|
||||
class Handle
|
||||
{
|
||||
@ -76,6 +76,16 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool readInt8(Handle &handle, T &val) const
|
||||
{
|
||||
quint8 b;
|
||||
if (!readByte(handle, &b))
|
||||
return false;
|
||||
val = (qint8)b;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool readUInt16(Handle &handle, T &val) const
|
||||
{
|
||||
@ -90,7 +100,7 @@ public:
|
||||
{
|
||||
if (!readUInt16(handle, (quint16&)val))
|
||||
return false;
|
||||
if((quint16)val > 0x7FFF)
|
||||
if ((quint16)val > 0x7FFF)
|
||||
val = (val & 0x7FFF) - 0x8000;
|
||||
return true;
|
||||
}
|
||||
@ -125,6 +135,11 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readInt32(Handle &handle, qint32 &val) const
|
||||
{
|
||||
return readUInt32(handle, (quint32&)val);
|
||||
}
|
||||
|
||||
bool readVUInt32SW(Handle &hdl, quint32 bytes, quint32 &val) const
|
||||
{
|
||||
quint8 b;
|
||||
|
@ -18,7 +18,6 @@ static void copyPoints(const RectC &rect, QList<MapData::Point> *src,
|
||||
dst->append(src->at(j));
|
||||
}
|
||||
|
||||
|
||||
SubFile *VectorTile::file(SubFile::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
@ -32,6 +31,8 @@ SubFile *VectorTile::file(SubFile::Type type)
|
||||
return _net;
|
||||
case SubFile::NOD:
|
||||
return _nod;
|
||||
case SubFile::DEM:
|
||||
return _dem;
|
||||
case SubFile::GMP:
|
||||
return _gmp;
|
||||
default:
|
||||
@ -53,11 +54,12 @@ bool VectorTile::init()
|
||||
bool VectorTile::initGMP()
|
||||
{
|
||||
SubFile::Handle hdl(_gmp);
|
||||
quint32 tre, rgn, lbl, net, nod;
|
||||
quint32 tre, rgn, lbl, net, nod, dem;
|
||||
|
||||
if (!(_gmp->seek(hdl, 0x19) && _gmp->readUInt32(hdl, tre)
|
||||
&& _gmp->readUInt32(hdl, rgn) && _gmp->readUInt32(hdl, lbl)
|
||||
&& _gmp->readUInt32(hdl, net) && _gmp->readUInt32(hdl, nod)))
|
||||
&& _gmp->readUInt32(hdl, net) && _gmp->readUInt32(hdl, nod)
|
||||
&& _gmp->readUInt32(hdl, dem)))
|
||||
return false;
|
||||
|
||||
_tre = tre ? new TREFile(_gmp, tre) : 0;
|
||||
@ -65,6 +67,7 @@ bool VectorTile::initGMP()
|
||||
_lbl = lbl ? new LBLFile(_gmp, lbl) : 0;
|
||||
_net = net ? new NETFile(_gmp, net) : 0;
|
||||
_nod = nod ? new NODFile(_gmp, nod) : 0;
|
||||
_dem = dem ? new DEMFile(_gmp, dem) : 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -88,6 +91,18 @@ bool VectorTile::load(SubFile::Handle &rgnHdl, SubFile::Handle &lblHdl,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VectorTile::loadDem(SubFile::Handle &hdl)
|
||||
{
|
||||
_demLoaded = -1;
|
||||
|
||||
if (!_dem || !_dem->load(hdl))
|
||||
return false;
|
||||
|
||||
_demLoaded = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VectorTile::clear()
|
||||
{
|
||||
_tre->clear();
|
||||
@ -96,13 +111,16 @@ void VectorTile::clear()
|
||||
_lbl->clear();
|
||||
if (_net)
|
||||
_net->clear();
|
||||
if (_dem)
|
||||
_dem->clear();
|
||||
|
||||
_loaded = 0;
|
||||
_demLoaded = 0;
|
||||
}
|
||||
|
||||
void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||
MapData::PolyCache *polyCache, QMutex *lock)
|
||||
MapData::PolyCache *cache, QMutex *lock)
|
||||
{
|
||||
SubFile::Handle *rgnHdl = 0, *lblHdl = 0, *netHdl = 0, *nodHdl = 0,
|
||||
*nodHdl2 = 0;
|
||||
@ -131,7 +149,7 @@ void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
||||
for (int i = 0; i < subdivs.size(); i++) {
|
||||
SubDiv *subdiv = subdivs.at(i);
|
||||
|
||||
MapData::Polys *polys = polyCache->object(subdiv);
|
||||
MapData::Polys *polys = cache->object(subdiv);
|
||||
if (!polys) {
|
||||
quint32 shift = _tre->shift(subdiv->bits());
|
||||
QList<MapData::Poly> p, l;
|
||||
@ -165,7 +183,7 @@ void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
||||
|
||||
copyPolys(rect, &p, polygons);
|
||||
copyPolys(rect, &l, lines);
|
||||
polyCache->insert(subdiv, new MapData::Polys(p, l));
|
||||
cache->insert(subdiv, new MapData::Polys(p, l));
|
||||
} else {
|
||||
copyPolys(rect, &(polys->polygons), polygons);
|
||||
copyPolys(rect, &(polys->lines), lines);
|
||||
@ -178,8 +196,7 @@ void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
||||
}
|
||||
|
||||
void VectorTile::points(const RectC &rect, const Zoom &zoom,
|
||||
QList<MapData::Point> *points, QCache<const SubDiv *,
|
||||
QList<MapData::Point> > *pointCache, QMutex *lock)
|
||||
QList<MapData::Point> *points, MapData::PointCache *cache, QMutex *lock)
|
||||
{
|
||||
SubFile::Handle *rgnHdl = 0, *lblHdl = 0;
|
||||
|
||||
@ -207,7 +224,7 @@ void VectorTile::points(const RectC &rect, const Zoom &zoom,
|
||||
for (int i = 0; i < subdivs.size(); i++) {
|
||||
SubDiv *subdiv = subdivs.at(i);
|
||||
|
||||
QList<MapData::Point> *pl = pointCache->object(subdiv);
|
||||
QList<MapData::Point> *pl = cache->object(subdiv);
|
||||
if (!pl) {
|
||||
QList<MapData::Point> p;
|
||||
|
||||
@ -226,7 +243,7 @@ void VectorTile::points(const RectC &rect, const Zoom &zoom,
|
||||
_rgn->extPointObjects(*rgnHdl, subdiv, _lbl, *lblHdl, &p);
|
||||
|
||||
copyPoints(rect, &p, points);
|
||||
pointCache->insert(subdiv, new QList<MapData::Point>(p));
|
||||
cache->insert(subdiv, new QList<MapData::Point>(p));
|
||||
} else
|
||||
copyPoints(rect, pl, points);
|
||||
}
|
||||
@ -236,6 +253,57 @@ void VectorTile::points(const RectC &rect, const Zoom &zoom,
|
||||
delete rgnHdl; delete lblHdl;
|
||||
}
|
||||
|
||||
void VectorTile::elevations(const RectC &rect, const Zoom &zoom,
|
||||
QList<MapData::Elevation> *elevations, MapData::ElevationCache *cache,
|
||||
QMutex *lock)
|
||||
{
|
||||
SubFile::Handle *hdl = 0;
|
||||
|
||||
lock->lock();
|
||||
|
||||
if (_demLoaded < 0) {
|
||||
lock->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_demLoaded) {
|
||||
hdl = new SubFile::Handle(_dem);
|
||||
|
||||
if (!loadDem(*hdl)) {
|
||||
lock->unlock();
|
||||
delete hdl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Shift the DEM level to get better data then what the map defines for
|
||||
// the given zoom (we prefer rendering quality rather than speed). For
|
||||
// maps with a single level this has no effect.
|
||||
int level = qMax(0, _dem->level(zoom) - 1);
|
||||
QList<const DEMTile*> tiles(_dem->tiles(rect, level));
|
||||
for (int i = 0; i < tiles.size(); i++) {
|
||||
const DEMTile *tile = tiles.at(i);
|
||||
MapData::Elevation *el = cache->object(tile);
|
||||
|
||||
if (!el) {
|
||||
if (!hdl)
|
||||
hdl = new SubFile::Handle(_dem);
|
||||
|
||||
el = _dem->elevations(*hdl, level, tile);
|
||||
if (!el->m.isNull())
|
||||
elevations->append(*el);
|
||||
cache->insert(tile, el);
|
||||
} else {
|
||||
if (!el->m.isNull())
|
||||
elevations->append(*el);
|
||||
}
|
||||
}
|
||||
|
||||
lock->unlock();
|
||||
|
||||
delete hdl;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const VectorTile &tile)
|
||||
{
|
||||
|
@ -6,17 +6,19 @@
|
||||
#include "lblfile.h"
|
||||
#include "netfile.h"
|
||||
#include "nodfile.h"
|
||||
#include "demfile.h"
|
||||
|
||||
namespace IMG {
|
||||
|
||||
class VectorTile {
|
||||
public:
|
||||
VectorTile()
|
||||
: _tre(0), _rgn(0), _lbl(0), _net(0), _nod(0), _gmp(0), _loaded(0) {}
|
||||
: _tre(0), _rgn(0), _lbl(0), _net(0), _nod(0), _dem(0), _gmp(0),
|
||||
_loaded(0), _demLoaded(0) {}
|
||||
~VectorTile()
|
||||
{
|
||||
delete _tre; delete _rgn; delete _lbl; delete _net; delete _nod;
|
||||
delete _gmp;
|
||||
delete _dem; delete _gmp;
|
||||
}
|
||||
|
||||
bool init();
|
||||
@ -24,21 +26,25 @@ public:
|
||||
|
||||
const RectC &bounds() const {return _tre->bounds();}
|
||||
QVector<Zoom> zooms() const {return _tre->zooms();}
|
||||
bool hasDem() const {return _dem != 0;}
|
||||
|
||||
SubFile *file(SubFile::Type type);
|
||||
|
||||
void polys(const RectC &rect, const Zoom &zoom,
|
||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||
MapData::PolyCache *polyCache, QMutex *lock);
|
||||
MapData::PolyCache *cache, QMutex *lock);
|
||||
void points(const RectC &rect, const Zoom &zoom,
|
||||
QList<MapData::Point> *points, QCache<const SubDiv*,
|
||||
QList<MapData::Point> > *pointCache, QMutex *lock);
|
||||
QList<MapData::Point> *points, MapData::PointCache *cache, QMutex *lock);
|
||||
void elevations(const RectC &rect, const Zoom &zoom,
|
||||
QList<MapData::Elevation> *elevations, MapData::ElevationCache *cache,
|
||||
QMutex *lock);
|
||||
|
||||
static bool isTileFile(SubFile::Type type)
|
||||
{
|
||||
return (type == SubFile::TRE || type == SubFile::LBL
|
||||
|| type == SubFile::RGN || type == SubFile::NET
|
||||
|| type == SubFile::NOD || type == SubFile::GMP);
|
||||
|| type == SubFile::NOD || type == SubFile::DEM
|
||||
|| type == SubFile::GMP);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -60,6 +66,9 @@ public:
|
||||
case SubFile::NOD:
|
||||
_nod = new NODFile(container);
|
||||
return _nod;
|
||||
case SubFile::DEM:
|
||||
_dem = new DEMFile(container);
|
||||
return _dem;
|
||||
case SubFile::GMP:
|
||||
_gmp = new SubFile(container);
|
||||
return _gmp;
|
||||
@ -72,15 +81,17 @@ private:
|
||||
bool initGMP();
|
||||
bool load(SubFile::Handle &rgnHdl, SubFile::Handle &lblHdl,
|
||||
SubFile::Handle &netHdl, SubFile::Handle &nodHdl);
|
||||
bool loadDem(SubFile::Handle &demHdl);
|
||||
|
||||
TREFile *_tre;
|
||||
RGNFile *_rgn;
|
||||
LBLFile *_lbl;
|
||||
NETFile *_net;
|
||||
NODFile *_nod;
|
||||
DEMFile *_dem;
|
||||
SubFile *_gmp;
|
||||
|
||||
int _loaded;
|
||||
int _loaded, _demLoaded;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -303,20 +303,20 @@ bool BSBMap::createProjection(const QString &datum, const QString &proj,
|
||||
}
|
||||
|
||||
if (!proj.compare("MERCATOR", Qt::CaseInsensitive)) {
|
||||
Projection::Setup setup(0, c.lon(), NAN, 0, 0, NAN, NAN);
|
||||
Conversion::Setup setup(0, c.lon(), NAN, 0, 0, NAN, NAN);
|
||||
pcs = PCS(gcs, Conversion(9804, setup, 9001));
|
||||
} else if (!proj.compare("TRANSVERSE MERCATOR", Qt::CaseInsensitive)) {
|
||||
Projection::Setup setup(0, params[1], params[2], 0, 0, NAN, NAN);
|
||||
Conversion::Setup setup(0, params[1], params[2], 0, 0, NAN, NAN);
|
||||
pcs = PCS(gcs, Conversion(9807, setup, 9001));
|
||||
} else if (!proj.compare("UNIVERSAL TRANSVERSE MERCATOR",
|
||||
Qt::CaseInsensitive)) {
|
||||
Projection::Setup setup(0, params[0], 0.9996, 500000, 0, NAN, NAN);
|
||||
Conversion::Setup setup(0, params[0], 0.9996, 500000, 0, NAN, NAN);
|
||||
pcs = PCS(gcs, Conversion(9807, setup, 9001));
|
||||
} else if (!proj.compare("LAMBERT CONFORMAL CONIC", Qt::CaseInsensitive)) {
|
||||
Projection::Setup setup(0, params[0], NAN, 0, 0, params[2], params[3]);
|
||||
Conversion::Setup setup(0, params[0], NAN, 0, 0, params[2], params[3]);
|
||||
pcs = PCS(gcs, Conversion(9802, setup, 9001));
|
||||
} else if (!proj.compare("POLYCONIC", Qt::CaseInsensitive)) {
|
||||
Projection::Setup setup(0, params[0], NAN, 0, 0, NAN, NAN);
|
||||
Conversion::Setup setup(0, params[0], NAN, 0, 0, NAN, NAN);
|
||||
pcs = PCS(gcs, Conversion(9818, setup, 9001));
|
||||
} else {
|
||||
_errorString = proj + ": Unknown/missing projection";
|
||||
|