mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-27 21:24:47 +01:00
Added support for prime meridians and angular units to GCS
This commit is contained in:
parent
e9ef68a81c
commit
1739625896
@ -36,7 +36,7 @@ build_script:
|
||||
|
||||
copy pkg\ellipsoids.csv installer
|
||||
|
||||
copy pkg\datums.csv installer
|
||||
copy pkg\gcs.csv installer
|
||||
|
||||
copy pkg\pcs.csv installer
|
||||
|
||||
|
12
gpxsee.pro
12
gpxsee.pro
@ -111,7 +111,10 @@ HEADERS += src/config.h \
|
||||
src/data/fitparser.h \
|
||||
src/data/igcparser.h \
|
||||
src/data/nmeaparser.h \
|
||||
src/data/str2int.h
|
||||
src/data/str2int.h \
|
||||
src/map/gcs.h \
|
||||
src/map/angularunits.h \
|
||||
src/map/primemeridian.h
|
||||
SOURCES += src/main.cpp \
|
||||
src/common/coordinates.cpp \
|
||||
src/common/rectc.cpp \
|
||||
@ -192,7 +195,10 @@ SOURCES += src/main.cpp \
|
||||
src/data/igcparser.cpp \
|
||||
src/data/nmeaparser.cpp \
|
||||
src/data/str2int.cpp \
|
||||
src/map/projection.cpp
|
||||
src/map/projection.cpp \
|
||||
src/map/gcs.cpp \
|
||||
src/map/angularunits.cpp \
|
||||
src/map/primemeridian.cpp
|
||||
RESOURCES += gpxsee.qrc
|
||||
TRANSLATIONS = lang/gpxsee_cs.ts \
|
||||
lang/gpxsee_sv.ts \
|
||||
@ -210,7 +216,7 @@ macx {
|
||||
icons/nmea.icns \
|
||||
pkg/maps.txt \
|
||||
pkg/ellipsoids.csv \
|
||||
pkg/datums.csv \
|
||||
pkg/gcs.csv \
|
||||
pkg/pcs.csv
|
||||
APP_RESOURCES.path = Contents/Resources
|
||||
QMAKE_BUNDLE_DATA += APP_RESOURCES
|
||||
|
283
pkg/datums.csv
283
pkg/datums.csv
@ -1,283 +0,0 @@
|
||||
TWD97,3824,7019,0,0,0
|
||||
IGRS,3889,7019,0,0,0
|
||||
Hermannskogel,3906,7004,653,-212,449
|
||||
MOLDREF99,4023,7019,0,0,0
|
||||
RGRDC 2005,4046,7019,0,0,0
|
||||
REGCAN95,4081,7019,0,0,0
|
||||
GGRS 87,4121,7019,-199.87,74.79,246.62
|
||||
Finland Hayford,4123,7022,-78,-231,-97
|
||||
RT 90,4124,7004,498,-36,568
|
||||
Samboja,4125,7004,-404.78,685.68,45.47
|
||||
Tete,4127,7008,-80,-100,-228
|
||||
Indian 1960,4131,7015,198,881,317
|
||||
FD58,4132,7012,-241.54,-163.64,396.06
|
||||
Old Hawaiian,4135,7008,61,-285,-181
|
||||
Puerto Rico,4139,7008,11,72,-101
|
||||
NAD83(CSRS98),4140,7019,0,0,0
|
||||
Israel 1993,4141,7019,-48,55,52
|
||||
Locodjo 1965,4142,7012,-125,53,467
|
||||
Abidjan 1987,4143,7012,-124.76,53,466.79
|
||||
Kalianpur 1937,4144,7015,214,804,268
|
||||
Kalianpur 1962,4145,7044,283,682,231
|
||||
Kalianpur 1975,4146,7045,295,736,257
|
||||
Hanoi 1972,4147,7024,-17.51,-108.32,-62.39
|
||||
Hartebeeshoek94,4148,7030,0,0,0
|
||||
CH-1903,4149,7004,674,15,405
|
||||
NAD83(HARN),4152,7019,0,0,0
|
||||
ED50(ED77),4154,7022,-117,-132,-164
|
||||
Dabola 1981,4155,7011,-83,37,124
|
||||
Naparima 1955,4158,7022,-0.465,372.095,171.736
|
||||
ELD79,4159,7022,-115.8543,-99.0583,-152.4616
|
||||
Pampa del Castillo,4161,7022,27.5,14,186.4
|
||||
Yemen NGN96,4163,7030,0,0,0
|
||||
South Yemen,4164,7024,-76,-138,67
|
||||
Bissau,4165,7022,-173,253,27
|
||||
NZGD2000,4167,7030,0,0,0
|
||||
Accra,4168,7029,-199,32,322
|
||||
American Samoa 1962,4169,7008,-115,118,426
|
||||
SIRGAS 1995,4170,7019,0,0,0
|
||||
RGF93,4171,7019,0,0,0
|
||||
IRENET95,4173,7019,0,0,0
|
||||
Sierra Leone 1968,4175,7012,-88,4,101
|
||||
Pulkovo 1942(83),4178,7024,26,-121,-78
|
||||
S42,4179,7024,28,-121,-77
|
||||
EST97,4180,7019,0,0,0
|
||||
Observatorio 1966,4182,7022,-425,-169,81
|
||||
Southwest Base,4183,7022,-104,167,-38
|
||||
Sao Braz,4184,7022,-203,141,53
|
||||
REGVEN,4189,7019,0,0,0
|
||||
POSGAR 98,4190,7019,0,0,0
|
||||
Douala 1948,4192,7022,-206.1,-174.7,-87.7
|
||||
Manoca 1962,4193,7011,-70.9,-151.8,-41.4
|
||||
Qornoq 1927,4194,7022,164,138,-189
|
||||
Adindan,4201,7012,-162,-12,206
|
||||
Australian Geodetic 1966,4202,7003,-133,-48,148
|
||||
Australian Geodetic 1984,4203,7003,-134,-48,149
|
||||
Ain el Abd 1970,4204,7022,-150,-251,-2
|
||||
Afgooye,4205,7024,-43,-163,45
|
||||
Lisbon,4207,7022,-304.046,-60.576,103.64
|
||||
Aratu,4208,7022,-151.99,287.04,-147.45
|
||||
Arc 1950,4209,7012,-143,-90,-294
|
||||
Arc 1960,4210,7012,-160,-8,-300
|
||||
Djakarta (Batavia),4211,7004,-377,681,-50
|
||||
Barbados 1938,4212,7012,31.95,300.99,419.19
|
||||
Beduaram,4213,7011,-106,-87,188
|
||||
Beijing 1954,4214,7024,15.8,-154.4,-82.3
|
||||
Bermuda 1957,4216,7008,-73,213,296
|
||||
Bogota Observatory,4218,7022,307,304,-318
|
||||
Camacupa,4220,7012,-50.9,-347.6,-231
|
||||
Campo Inchauspe,4221,7022,-148,136,90
|
||||
Cape,4222,7012,-136,-108,-292
|
||||
Carthage,4223,7012,-263,6,431
|
||||
Chua Astro,4224,7022,-134,229,-29
|
||||
Corrego Alegre,4225,7022,-206,172,-6
|
||||
Deir ez Zor,4227,7011,-190.421,8.532,238.69
|
||||
Old Egyptian,4229,7020,-130,110,-13
|
||||
European 1950,4230,7022,-87,-98,-121
|
||||
Oman,4232,7012,-346,-1,224
|
||||
Gandajika Base,4233,7022,-133,-321,50
|
||||
Hu-Tzu-Shan,4236,7022,-634,-549,-201
|
||||
ID74,4238,7021,-24,-15,5
|
||||
Indian 1954,4239,7015,217,823,299
|
||||
Indian Thailand,4240,7015,214,836,303
|
||||
JAD69,4242,7008,70,207,389.5
|
||||
Kandawala,4244,7015,-97,787,86
|
||||
Kertau 1948,4245,7018,-11,851,5
|
||||
KOC,4246,7012,-294.7,-200.1,525.5
|
||||
La Canoa,4247,7022,-273.5,110.6,-357.9
|
||||
Prov So Amrican 1956,4248,7022,-288,175,-376
|
||||
Leigon,4250,7012,-130,29,364
|
||||
Liberia 1964,4251,7012,-90,40,88
|
||||
Luzon Philippines,4253,7008,-133,-77,-51
|
||||
Prov So Chilean 1963,4254,7022,16,196,93
|
||||
Mahe 1971,4256,7012,41,-220,-134
|
||||
ETRS89,4258,7019,0,0,0
|
||||
Malongo 1987,4259,7022,-254.1,-5.36,-100.29
|
||||
Merchich,4261,7012,31,146,47
|
||||
Massawa,4262,7004,639,405,60
|
||||
Minna,4263,7012,-92,-93,122
|
||||
Mhast,4264,7022,-252.95,-4.11,-96.38
|
||||
M'poraloko,4266,7011,-74,-130,42
|
||||
NAD27 CONUS,4267,7008,-8,160,176
|
||||
NAD83,4269,7019,0,0,0
|
||||
Nahrwan 1967,4270,7012,-249,-156,381
|
||||
Naparima BWI,4271,7022,-2,374,172
|
||||
Geodetic Datum 1949,4272,7022,84,-22,209
|
||||
NZGD1949,4272,7022,84,-22,209
|
||||
NGO1948,4273,7005,315,-217,528
|
||||
Datum 73,4274,7022,-223.237,110.193,36.649
|
||||
NTF France,4275,7011,-168,-60,320
|
||||
Ord Srvy Grt Britn,4277,7001,375,-111,431
|
||||
Israeli,4281,7010,-235,-85,264
|
||||
Pointe Noire,4282,7011,-148,51,-291
|
||||
Australian Geocentric 1994 (GDA94),4283,7019,0,0,0
|
||||
Pulkovo 1942 (1),4284,7024,28,-130,-95
|
||||
Qatar National,4285,7022,-128,-283,22
|
||||
Qornoq,4287,7022,164,138,-189
|
||||
Rijksdriehoeksmeting,4289,7004,593,26,478
|
||||
South American 1969,4291,7036,-57,1,-41
|
||||
Sapper Hill 1943,4292,7022,-355,16,74
|
||||
Schwarzeck,4293,7046,616,97,-251
|
||||
Tananarive,4297,7022,-189,-242,-91
|
||||
Timbalai 1948,4298,7015,-689,691,-46
|
||||
Ireland 1965,4299,7002,506,-122,611
|
||||
Tokyo,4301,7004,-128,481,664
|
||||
Voirol 1875,4304,7011,-73,-247,227
|
||||
Yacare,4309,7022,-155,171,37
|
||||
Yoff,4310,7011,-30,190,89
|
||||
Zanderij,4311,7022,-265,120,-358
|
||||
Austrian,4312,7004,594,84,471
|
||||
Potsdam Rauenberg DHDN,4314,7004,606,23,413
|
||||
Conakry 1905,4315,7011,-23,259,-9
|
||||
NGN,4318,7030,-3.2,-5.7,2.8
|
||||
KUDAMS,4319,7019,-20.8,11.3,2.4
|
||||
WGS 72,4322,7043,0,0,5
|
||||
WGS 84,4326,7030,0,0,0
|
||||
RGSPM06,4463,7019,0,0,0
|
||||
RGM04,4470,7019,0,0,0
|
||||
Cadastre 1997,4475,7022,-381.788,-57.501,-256.673
|
||||
Mexico ITRF92,4483,7019,0,0,0
|
||||
RRAF 1991,4558,7019,0,0,0
|
||||
Antigua 1943,4601,7012,-255,-15,71
|
||||
Dominica 1945,4602,7012,725,685,536
|
||||
Grenada 1953,4603,7012,72,213.7,93
|
||||
Montserrat 1958,4604,7012,174,359,365
|
||||
St. Kitts 1955,4605,7012,9,183,236
|
||||
St. Lucia 1955,4606,7012,-149,128,296
|
||||
St. Vincent 1945,4607,7012,195.671,332.517,274.607
|
||||
JGD2000,4612,7019,0,0,0
|
||||
Segara,4613,7004,-403,684,41
|
||||
Southeast Base,4615,7022,-499,-249,314
|
||||
Marco Astro,4616,7022,-289,-124,60
|
||||
NAD83(CSRS),4617,7019,0,0,0
|
||||
SAD69,4618,7050,-66.87,4.37,-38.52
|
||||
SWEREF99,4619,7019,0,0,0
|
||||
Fort Marigot,4621,7022,137,248,-430
|
||||
Guadeloupe 1948,4622,7022,-467,-16,-300
|
||||
CSG67,4623,7022,-186,230,110
|
||||
RGFG95,4624,7019,0,0,0
|
||||
Martinique 1938,4625,7022,186,482,151
|
||||
Reunion,4626,7022,94,-948,-1262
|
||||
RGR92,4627,7019,0,0,0
|
||||
Tahiti 52,4628,7022,162,117,154
|
||||
IGN72 Nuku Hiva,4630,7022,84,274,65
|
||||
K0 1949,4631,7022,145,-187,103
|
||||
Combani 1950,4632,7022,-382,-59,-262
|
||||
IGN56 Lifou,4633,7022,335.47,222.58,-230.94
|
||||
IGN72 Grand Terre,4634,7022,-13,-348,292
|
||||
Saint Pierre et Miquelon 1950,4638,7008,30,430,368
|
||||
MOP78,4639,7022,253,-132,-127
|
||||
RRAF 1991,4640,7030,0,0,0
|
||||
IGN53 Mare,4641,7022,287.58,177.78,-135.41
|
||||
ST84 Ile des Pins,4642,7022,-13,-348,292
|
||||
NEA74 Noumea,4644,7022,-10.18,-350.43,291.37
|
||||
RGNC 1991,4645,7022,0,0,0
|
||||
Grand Comoros,4646,7022,-963,510,-359
|
||||
Hjorsey 1955,4658,7022,-73,46,-86
|
||||
ISN93,4659,7019,0,0,0
|
||||
LKS92,4661,7019,0,0,0
|
||||
IGN72 Grande Terre,4662,7022,-11.64,-348.6,291.98
|
||||
Porto Santo 1995,4663,7022,-502.862,-247.438,312.724
|
||||
Azores Oriental 1995,4664,7022,-204.619,140.176,55.226
|
||||
Azores Central 1995,4665,7022,-106.226,166.366,-37.893
|
||||
European 1979,4668,7022,-86,-98,-119
|
||||
LKS94,4669,7019,0,0,0
|
||||
IGM95,4670,7030,0,0,0
|
||||
Chatham 1971,4672,7022,175,-38,113
|
||||
SIRGAS 2000,4674,7019,0,0,0
|
||||
Guam 1963,4675,7008,-100,-248,259
|
||||
Indian Bangladesh,4682,7015,289,734,257
|
||||
MAGNA-SIRGAS,4686,7019,0,0,0
|
||||
Maupiti 83,4692,7022,217.037,86.959,23.956
|
||||
Nakhl-e Ghanem,4693,7030,0,-0.15,0.68
|
||||
POSGAR 94,4694,7030,0,0,0
|
||||
Katanga 1955,4695,7008,-103.746,-9.614,-255.95
|
||||
Kerguelen Island,4698,7022,145,-187,103
|
||||
Le Pouce 1934,4699,7012,-770.1,158.4,-498.2
|
||||
IGCB 1955,4701,7012,-79.9,-158,-168.9
|
||||
Mauritania 1999,4702,7019,0,0,0
|
||||
Egypt Gulf of Suez S-650 TL,4706,7020,-146.21,112.63,4.05
|
||||
Astro B4 Sorol Atoll,4707,7022,114,-116,-333
|
||||
Anna 1 Astro 1965,4708,7003,-491,-22,435
|
||||
Astro Beacon 1945,4709,7022,145,75,-272
|
||||
Astro DOS 71/4,4710,7022,-320,550,-494
|
||||
Astronomic Stn 1952,4711,7022,124,-234,-25
|
||||
Ascension Island 1958,4712,7022,-207,107,52
|
||||
Bellevue (IGN),4714,7022,-127,-769,472
|
||||
Canton Astro 1966,4716,7022,298,-304,-375
|
||||
Cape Canaveral,4717,7008,-2,150,181
|
||||
GUX 1 Astro,4718,7022,252,-209,-751
|
||||
Easter Island 1967,4719,7022,211,147,111
|
||||
Fiji 1956,4721,7022,265.025,384.929,-194.046
|
||||
ISTS 073 Astro 1969,4724,7022,208,-435,-229
|
||||
Johnston Island,4725,7022,191,-77,-204
|
||||
L.C. 5 Astro,4726,7008,42,124,147
|
||||
Midway Astro 1961,4727,7022,912,-58,1227
|
||||
Pico De Las Nieves,4728,7022,-307,-92,127
|
||||
Pitcairn Astro 1967,4729,7022,185,165,42
|
||||
Santo (DOS),4730,7022,170,42,84
|
||||
Viti Levu 1916,4731,7012,51,391,-36
|
||||
Wake-Eniwetok 1960,4732,7053,101,52,-39
|
||||
Tristan Astro 1968,4734,7022,-632,438,-609
|
||||
Korea 2000,4737,7019,0,0,0
|
||||
Hong Kong 1963,4739,7022,-156,-271,-189
|
||||
Karbala 1979,4743,7012,70.995,-335.916,262.898
|
||||
Nahrwan 1934,4744,7012,-242.2,-144.9,370.3
|
||||
GR96,4747,7019,0,0,0
|
||||
RGNC91-93,4749,7019,0,0,0
|
||||
ST87 Ouvea,4750,7030,-56.263,16.136,-22.856
|
||||
LGD2006,4754,7022,-208.4058,-109.8777,-2.5764
|
||||
DGN95,4755,7030,0,0,0
|
||||
JAD2001,4758,7030,0,0,0
|
||||
NAD83(NSRS2007),4759,7019,0,0,0
|
||||
HTRS96,4761,7019,0,0,0
|
||||
BDA2000,4762,7030,0,0,0
|
||||
Pitcairn 2006,4763,7030,0,0,0
|
||||
RSRGD2000,4764,7019,0,0,0
|
||||
Slovenia 1996,4765,7019,0,0,0
|
||||
Lisbon (Lisbon),4803,7022,-304.046,-60.576,103.64
|
||||
MGI (Ferro),4805,7004,682,-203,480
|
||||
Rome 1940,4806,7022,-225,-65,9
|
||||
NTF (Paris),4807,7011,-168,-60,320
|
||||
Norsk,4817,7005,278,93,474
|
||||
PTRA08,5013,7019,0,0,0
|
||||
TUREF,5252,7019,0,0,0
|
||||
DRUKREF 03,5264,7019,0,0,0
|
||||
ISN2004,5324,7019,0,0,0
|
||||
POSGAR 2007,5340,7019,0,0,0
|
||||
MARGEN,5354,7019,0,0,0
|
||||
SIRGAS-Chile,5360,7019,0,0,0
|
||||
CR05,5365,7030,0,0,0
|
||||
Peru96,5373,7019,0,0,0
|
||||
SIRGAS-ROU98,5381,7030,0,0,0
|
||||
Ocotepeque 1935,5451,7008,205,96,-98
|
||||
RGAF09,5489,7019,0,0,0
|
||||
SAD69(96),5527,7050,-67.35,3.88,-38.22
|
||||
PNG94,5546,7019,0,0,0
|
||||
FEH2010,5593,7019,0,0,0
|
||||
CIGD11,6135,7019,0,0,0
|
||||
Mexico ITRF2008,6365,7019,0,0,0
|
||||
RDN2008,6706,7019,0,0,0
|
||||
South East Island 1943,6892,7012,-43.685,-179.785,-267.721
|
||||
ONGD14,7373,7019,0,0,0
|
||||
St. Helena Tritan,7881,7030,-0.077,0.079,0.086
|
||||
SHGD2015,7886,7019,0,0,0
|
||||
DOS 1968,,7022,230,-199,-752
|
||||
Egypt,,7022,-130,-117,-151
|
||||
European 1950 (Mean France),,7022,-87,-96,-120
|
||||
European 1950 (Spain and Portugal),,7022,-84,-107,-120
|
||||
Luzon Mindanao,,7008,-133,-79,-72
|
||||
NAD27 Alaska,,7008,-5,135,172
|
||||
NAD27 Bahamas,,7008,-4,154,178
|
||||
NAD27 Canada,,7008,-10,158,187
|
||||
NAD27 Canal Zone,,7008,0,125,201
|
||||
NAD27 Caribbean,,7008,-3,142,183
|
||||
NAD27 Central,,7008,0,125,194
|
||||
NAD27 Cuba,,7008,-9,152,178
|
||||
NAD27 Greenland,,7008,11,114,195
|
||||
NAD27 Mexico,,7008,-12,130,190
|
||||
NAD27 San Salvador,,7008,1,140,165
|
||||
Nahrwn Masirah Ilnd,,7012,-247,-148,369
|
||||
Nahrwn Saudi Arbia,,7012,-231,-196,482
|
||||
Nahrwn United Arab,,7012,-249,-156,381
|
||||
Pulkovo 1942 (2),,7024,28,-130,-95
|
|
@ -11,15 +11,9 @@ Everest 1830 (1937 Adjustment),7015,6377276.345,300.8017
|
||||
Everest 1830 Modified,7018,6377304.063,300.8017
|
||||
GRS 80,7019,6378137.0,298.257222101
|
||||
Helmert 1906,7020,6378200.0,298.3
|
||||
Indonesian,7021,6378160.0,298.247
|
||||
International 1924,7022,6378388.0,297.0
|
||||
Krassovsky 1940,7024,6378245.0,298.3
|
||||
War Office,7029,6378300.0,296.0
|
||||
WGS 84,7030,6378137.0,298.257223563
|
||||
South American 1969,7036,6378160.0,298.25
|
||||
WGS 72,7043,6378135.0,298.26
|
||||
Everest 1830 (1962 Definition),7044,6377301.243,300.8017255
|
||||
Everest 1830 (1975 Definition),7045,6377299.151,300.8017255
|
||||
Bessel 1841 (Namibia),7046,6377483.865,299.1528128
|
||||
GRS 67 Modified,7050,6378160.0,298.25
|
||||
Hough 1960,7053,6378270.0,297.0
|
||||
|
|
121
pkg/gcs.csv
Normal file
121
pkg/gcs.csv
Normal file
@ -0,0 +1,121 @@
|
||||
Adindan,4201,6201,9122,7012,8901,9603,-162,-12,206
|
||||
Afgooye,4205,6205,9122,7024,8901,9603,-43,-163,45
|
||||
Ain el Abd 1970,4204,6204,9122,7022,8901,9603,-150,-251,-2
|
||||
Anna 1 Astro 1965,4708,6708,9122,7003,8901,9603,-491,-22,435
|
||||
Arc 1950,4209,6209,9122,7012,8901,9603,-143,-90,-294
|
||||
Arc 1960,4210,6210,9122,7012,8901,9603,-160,-8,-300
|
||||
Ascension Island 1958,4712,6712,9122,7022,8901,9603,-207,107,52
|
||||
Astro B4 Sorol Atoll,4707,6707,9122,7022,8901,9603,114,-116,-333
|
||||
Astro Beacon 1945,4709,6709,9122,7022,8901,9603,145,75,-272
|
||||
Astro DOS 71/4,4710,6710,9122,7022,8901,9603,-320,550,-494
|
||||
Astronomic Stn 1952,4711,6711,9122,7022,8901,9603,124,-234,-25
|
||||
Australian Geodetic 1966,4202,6202,9122,7003,8901,9603,-133,-48,148
|
||||
Australian Geodetic 1984,4203,6203,9122,7003,8901,9603,-134,-48,149
|
||||
Australian Geocentric 1994 (GDA94),4283,6283,9122,7019,8901,9603,0,0,0
|
||||
Austrian,4312,6312,9122,7004,8901,9603,594,84,471
|
||||
Bellevue (IGN),4714,6714,9122,7022,8901,9603,-127,-769,472
|
||||
Bermuda 1957,4216,6216,9122,7008,8901,9603,-73,213,296
|
||||
Bogota Observatory,4218,6218,9122,7022,8901,9603,307,304,-318
|
||||
Campo Inchauspe,4221,6221,9122,7022,8901,9603,-148,136,90
|
||||
Canton Astro 1966,4716,6716,9122,7022,8901,9603,298,-304,-375
|
||||
Cape,4222,6222,9122,7012,8901,9603,-136,-108,-292
|
||||
Cape Canaveral,4717,6717,9122,7008,8901,9603,-2,150,181
|
||||
Carthage,4223,6223,9122,7012,8901,9603,-263,6,431
|
||||
CH-1903,4149,6149,9122,7004,8901,9603,674,15,405
|
||||
Chatham 1971,4672,6672,9122,7022,8901,9603,175,-38,113
|
||||
Chua Astro,4224,6224,9122,7022,8901,9603,-134,229,-29
|
||||
Corrego Alegre,4225,6225,9122,7022,8901,9603,-206,172,-6
|
||||
Djakarta (Batavia),4211,6211,9122,7004,8901,9603,-377,681,-50
|
||||
DOS 1968,,,9122,7022,8901,9603,230,-199,-752
|
||||
Easter Island 1967,4719,6719,9122,7022,8901,9603,211,147,111
|
||||
Egypt,4199,6199,9122,7022,8901,9603,-130,-117,-151
|
||||
European 1950,4230,6230,9122,7022,8901,9603,-87,-98,-121
|
||||
European 1950 (Mean France),,,9122,7022,8901,9603,-87,-96,-120
|
||||
European 1950 (Spain and Portugal),,,9122,7022,8901,9603,-84,-107,-120
|
||||
European 1979,4668,6668,9122,7022,8901,9603,-86,-98,-119
|
||||
Finland Hayford,4123,6123,9122,7022,8901,9603,-78,-231,-97
|
||||
Gandajika Base,4233,6233,9122,7022,8901,9603,-133,-321,50
|
||||
Geodetic Datum 1949,4272,6272,9122,7022,8901,9603,84,-22,209
|
||||
GGRS 87,4121,6121,9122,7019,8901,9603,-199.87,74.79,246.62
|
||||
Guam 1963,4675,6675,9122,7008,8901,9603,-100,-248,259
|
||||
GUX 1 Astro,4718,6718,9122,7022,8901,9603,252,-209,-751
|
||||
Hartebeeshoek94,4148,6148,9122,7030,8901,9603,0,0,0
|
||||
Hermannskogel,3906,1031,9122,7004,8901,9603,653,-212,449
|
||||
Hjorsey 1955,4658,6658,9122,7022,8901,9603,-73,46,-86
|
||||
Hong Kong 1963,4739,6739,9122,7022,8901,9603,-156,-271,-189
|
||||
Hu-Tzu-Shan,4236,6236,9122,7022,8901,9603,-634,-549,-201
|
||||
Indian Bangladesh,4682,6682,9122,7015,8901,9603,289,734,257
|
||||
Indian Thailand,4240,6240,9122,7015,8901,9603,214,836,303
|
||||
Israeli,4281,6281,9122,7010,8901,9603,-235,-85,264
|
||||
Ireland 1965,4299,6299,9122,7002,8901,9603,506,-122,611
|
||||
ISTS 073 Astro 1969,4724,6724,9122,7022,8901,9603,208,-435,-229
|
||||
Johnston Island,4725,6725,9122,7022,8901,9603,191,-77,-204
|
||||
Kandawala,4244,6244,9122,7015,8901,9603,-97,787,86
|
||||
Kerguelen Island,4698,6698,9122,7022,8901,9603,145,-187,103
|
||||
Kertau 1948,4245,6245,9122,7018,8901,9603,-11,851,5
|
||||
L.C. 5 Astro,4726,6726,9122,7008,8901,9603,42,124,147
|
||||
Liberia 1964,4251,6251,9122,7012,8901,9603,-90,40,88
|
||||
Luzon Mindanao,,,9122,7008,8901,9603,-133,-79,-72
|
||||
Luzon Philippines,4253,6253,9122,7008,8901,9603,-133,-77,-51
|
||||
Mahe 1971,4256,6256,9122,7012,8901,9603,41,-220,-134
|
||||
Marco Astro,4616,6616,9122,7022,8901,9603,-289,-124,60
|
||||
Massawa,4262,6262,9122,7004,8901,9603,639,405,60
|
||||
Merchich,4261,6261,9122,7012,8901,9603,31,146,47
|
||||
Midway Astro 1961,4727,6727,9122,7022,8901,9603,912,-58,1227
|
||||
Minna,4263,6263,9122,7012,8901,9603,-92,-93,122
|
||||
NAD27 Alaska,,,9122,7008,8901,9603,-5,135,172
|
||||
NAD27 Bahamas,,,9122,7008,8901,9603,-4,154,178
|
||||
NAD27 Canada,,,9122,7008,8901,9603,-10,158,187
|
||||
NAD27 Canal Zone,,,9122,7008,8901,9603,0,125,201
|
||||
NAD27 Caribbean,,,9122,7008,8901,9603,-3,142,183
|
||||
NAD27 Central,,,9122,7008,8901,9603,0,125,194
|
||||
NAD27 CONUS,4267,6267,9122,7008,8901,9603,-8,160,176
|
||||
NAD27 Cuba,,,9122,7008,8901,9603,-9,152,178
|
||||
NAD27 Greenland,,,9122,7008,8901,9603,11,114,195
|
||||
NAD27 Mexico,,,9122,7008,8901,9603,-12,130,190
|
||||
NAD27 San Salvador,,,9122,7008,8901,9603,1,140,165
|
||||
NAD83,4269,6269,9122,7019,8901,9603,0,0,0
|
||||
Nahrwn Masirah Ilnd,,,9122,7012,8901,9603,-247,-148,369
|
||||
Nahrwn Saudi Arbia,,,9122,7012,8901,9603,-231,-196,482
|
||||
Nahrwn United Arab,4270,6270,9122,7012,8901,9603,-249,-156,381
|
||||
Naparima BWI,4271,6271,9122,7022,8901,9603,-2,374,172
|
||||
NGO1948,4273,6273,9122,7005,8901,9603,315,-217,528
|
||||
NTF France,4275,6275,9122,7011,8901,9603,-168,-60,320
|
||||
Norsk,4817,6817,9122,7005,8913,9603,278,93,474
|
||||
NZGD1949,4272,6272,9122,7022,8901,9603,84,-22,209
|
||||
NZGD2000,4167,6167,9122,7030,8901,9603,0,0,0
|
||||
Observatorio 1966,4182,6182,9122,7022,8901,9603,-425,-169,81
|
||||
Old Egyptian,4229,6229,9122,7020,8901,9603,-130,110,-13
|
||||
Old Hawaiian,4135,6135,9122,7008,8901,9603,61,-285,-181
|
||||
Oman,4232,6232,9122,7012,8901,9603,-346,-1,224
|
||||
Ord Srvy Grt Britn,4277,6277,9122,7001,8901,9603,375,-111,431
|
||||
Pico De Las Nieves,4728,6728,9122,7022,8901,9603,-307,-92,127
|
||||
Pitcairn Astro 1967,4729,6729,9122,7022,8901,9603,185,165,42
|
||||
Potsdam Rauenberg DHDN,4314,6314,9122,7004,8901,9603,606,23,413
|
||||
Prov So Amrican 1956,4248,6248,9122,7022,8901,9603,-288,175,-376
|
||||
Prov So Chilean 1963,4254,6254,9122,7022,8901,9603,16,196,93
|
||||
Puerto Rico,4139,6139,9122,7008,8901,9603,11,72,-101
|
||||
Pulkovo 1942 (1),4284,6284,9122,7024,8901,9603,28,-130,-95
|
||||
Pulkovo 1942 (2),,,9122,7024,8901,9603,28,-130,-95
|
||||
Qatar National,4285,6285,9122,7022,8901,9603,-128,-283,22
|
||||
Qornoq,4287,6287,9108,7022,8901,9603,164,138,-189
|
||||
Reunion,4626,6626,9122,7022,8901,9603,94,-948,-1262
|
||||
Rijksdriehoeksmeting,4289,6289,9122,7004,8901,9603,593,26,478
|
||||
Rome 1940,4806,6806,9122,7022,8906,9603,-225,-65,9
|
||||
RT 90,4124,6124,9122,7004,8901,9603,498,-36,568
|
||||
S42,4179,6179,9122,7024,8901,9603,28,-121,-77
|
||||
Santo (DOS),4730,6730,9122,7022,8901,9603,170,42,84
|
||||
Sao Braz,4184,6184,9122,7022,8901,9603,-203,141,53
|
||||
Sapper Hill 1943,4292,6292,9122,7022,8901,9603,-355,16,74
|
||||
Schwarzeck,4293,6293,9122,7046,8901,9603,616,97,-251
|
||||
South American 1969,4291,6291,9108,7036,8901,9603,-57,1,-41
|
||||
Southeast Base,4615,6615,9122,7022,8901,9603,-499,-249,314
|
||||
Southwest Base,4183,6183,9122,7022,8901,9603,-104,167,-38
|
||||
Timbalai 1948,4298,6298,9122,7015,8901,9603,-689,691,-46
|
||||
Tokyo,4301,6301,9122,7004,8901,9603,-128,481,664
|
||||
Tristan Astro 1968,4734,6734,9122,7022,8901,9603,-632,438,-609
|
||||
Viti Levu 1916,4731,6731,9122,7012,8901,9603,51,391,-36
|
||||
Wake-Eniwetok 1960,4732,6732,9122,7053,8901,9603,101,52,-39
|
||||
WGS 72,4322,6322,9122,7043,8901,9603,0,0,5
|
||||
Yacare,4309,6309,9122,7022,8901,9603,-155,171,37
|
||||
Zanderij,4311,6311,9122,7022,8901,9603,-265,120,-358
|
|
@ -85,7 +85,7 @@ Section "GPXSee" SEC_APP
|
||||
File "gpxsee.exe"
|
||||
File "maps.txt"
|
||||
File "ellipsoids.csv"
|
||||
File "datums.csv"
|
||||
File "gcs.csv"
|
||||
File "pcs.csv"
|
||||
|
||||
; Create start menu entry and add links
|
||||
|
@ -92,7 +92,7 @@ Section "GPXSee" SEC_APP
|
||||
File "gpxsee.exe"
|
||||
File "maps.txt"
|
||||
File "ellipsoids.csv"
|
||||
File "datums.csv"
|
||||
File "gcs.csv"
|
||||
File "pcs.csv"
|
||||
|
||||
; Create start menu entry and add links
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "map/onlinemap.h"
|
||||
#include "map/downloader.h"
|
||||
#include "map/ellipsoid.h"
|
||||
#include "map/datum.h"
|
||||
#include "map/gcs.h"
|
||||
#include "map/pcs.h"
|
||||
#include "opengl.h"
|
||||
#include "gui.h"
|
||||
@ -69,7 +69,6 @@ bool App::event(QEvent *event)
|
||||
void App::loadDatums()
|
||||
{
|
||||
QString ef, df;
|
||||
bool ok = false;
|
||||
|
||||
if (QFile::exists(USER_ELLIPSOID_FILE))
|
||||
ef = USER_ELLIPSOID_FILE;
|
||||
@ -78,35 +77,17 @@ void App::loadDatums()
|
||||
else
|
||||
qWarning("No ellipsoids file found.");
|
||||
|
||||
if (QFile::exists(USER_DATUM_FILE))
|
||||
df = USER_DATUM_FILE;
|
||||
else if (QFile::exists(GLOBAL_DATUM_FILE))
|
||||
df = GLOBAL_DATUM_FILE;
|
||||
if (QFile::exists(USER_GCS_FILE))
|
||||
df = USER_GCS_FILE;
|
||||
else if (QFile::exists(GLOBAL_GCS_FILE))
|
||||
df = GLOBAL_GCS_FILE;
|
||||
else
|
||||
qWarning("No datums file found.");
|
||||
|
||||
if (!ef.isNull() && !df.isNull()) {
|
||||
if (!Ellipsoid::loadList(ef)) {
|
||||
if (Ellipsoid::errorLine())
|
||||
qWarning("%s: parse error on line %d: %s", qPrintable(ef),
|
||||
Ellipsoid::errorLine(), qPrintable(Ellipsoid::errorString()));
|
||||
else
|
||||
qWarning("%s: %s", qPrintable(ef), qPrintable(
|
||||
Ellipsoid::errorString()));
|
||||
} else {
|
||||
if (!Datum::loadList(df)) {
|
||||
if (Datum::errorLine())
|
||||
qWarning("%s: parse error on line %d: %s", qPrintable(df),
|
||||
Datum::errorLine(), qPrintable(Datum::errorString()));
|
||||
else
|
||||
qWarning("%s: %s", qPrintable(df), qPrintable(
|
||||
Datum::errorString()));
|
||||
Ellipsoid::loadList(ef);
|
||||
GCS::loadList(df);
|
||||
} else
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
qWarning("Maps based on a datum different from WGS84 won't work.");
|
||||
}
|
||||
|
||||
@ -123,12 +104,5 @@ void App::loadPCSs()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PCS::loadList(file)) {
|
||||
if (PCS::errorLine())
|
||||
qWarning("%s: parse error on line %d: %s", qPrintable(file),
|
||||
PCS::errorLine(), qPrintable(PCS::errorString()));
|
||||
else
|
||||
qWarning("%s: %s", qPrintable(file), qPrintable(
|
||||
Datum::errorString()));
|
||||
}
|
||||
PCS::loadList(file);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
#define FONT_SIZE 12 // px
|
||||
|
||||
#define ELLIPSOID_FILE QString("ellipsoids.csv")
|
||||
#define DATUM_FILE QString("datums.csv")
|
||||
#define GCS_FILE QString("gcs.csv")
|
||||
#define PCS_FILE QString("pcs.csv")
|
||||
#define MAP_FILE QString("maps.txt")
|
||||
#define MAP_DIR QString("maps")
|
||||
@ -32,12 +32,12 @@
|
||||
#endif
|
||||
|
||||
#define USER_ELLIPSOID_FILE USER_DIR + QString("/") + ELLIPSOID_FILE
|
||||
#define USER_DATUM_FILE USER_DIR + QString("/") + DATUM_FILE
|
||||
#define USER_GCS_FILE USER_DIR + QString("/") + GCS_FILE
|
||||
#define USER_PCS_FILE USER_DIR + QString("/") + PCS_FILE
|
||||
#define USER_MAP_DIR USER_DIR + QString("/") + MAP_DIR
|
||||
#define USER_POI_DIR USER_DIR + QString("/") + POI_DIR
|
||||
#define GLOBAL_ELLIPSOID_FILE GLOBAL_DIR + QString("/") + ELLIPSOID_FILE
|
||||
#define GLOBAL_DATUM_FILE GLOBAL_DIR + QString("/") + DATUM_FILE
|
||||
#define GLOBAL_GCS_FILE GLOBAL_DIR + QString("/") + GCS_FILE
|
||||
#define GLOBAL_PCS_FILE GLOBAL_DIR + QString("/") + PCS_FILE
|
||||
#define GLOBAL_MAP_DIR GLOBAL_DIR + QString("/") + MAP_DIR
|
||||
#define GLOBAL_POI_DIR GLOBAL_DIR + QString("/") + POI_DIR
|
||||
|
@ -56,7 +56,7 @@ Defense.
|
||||
((clat) / sqrt(one_minus_sqr_es_sin))
|
||||
|
||||
|
||||
AlbersEqual::AlbersEqual(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
AlbersEqual::AlbersEqual(const Ellipsoid *ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double falseEasting, double falseNorthing)
|
||||
{
|
||||
@ -78,7 +78,7 @@ AlbersEqual::AlbersEqual(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
sp1 = deg2rad(standardParallel1);
|
||||
sp2 = deg2rad(standardParallel2);
|
||||
|
||||
_es2 = 2 * _e.flattening() - _e.flattening() * _e.flattening();
|
||||
_es2 = 2 * _e->flattening() - _e->flattening() * _e->flattening();
|
||||
_es = sqrt(_es2);
|
||||
_one_minus_es2 = 1 - _es2;
|
||||
_two_es = 2 * _es;
|
||||
@ -108,7 +108,7 @@ AlbersEqual::AlbersEqual(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
_n = sin_lat1;
|
||||
|
||||
_C = sqr_m1 + _n * q1;
|
||||
_a_over_n = _e.radius() / _n;
|
||||
_a_over_n = _e->radius() / _n;
|
||||
nq0 = _n * q0;
|
||||
_rho0 = (_C < nq0) ? 0 : _a_over_n * sqrt(_C - nq0);
|
||||
}
|
||||
@ -171,7 +171,7 @@ Coordinates AlbersEqual::xy2ll(const QPointF &p) const
|
||||
if (rho != 0.0)
|
||||
theta = atan2(dx, rho0_minus_dy);
|
||||
rho_n = rho * _n;
|
||||
q = (_C - (rho_n * rho_n) / (_e.radius() * _e.radius())) / _n;
|
||||
q = (_C - (rho_n * rho_n) / (_e->radius() * _e->radius())) / _n;
|
||||
qc = 1 - ((_one_minus_es2) / (_two_es)) * log((1.0 - _es) / (1.0 + _es));
|
||||
if (fabs(fabs(qc) - fabs(q)) > 1.0e-6) {
|
||||
q_over_2 = q / 2.0;
|
||||
|
@ -7,7 +7,7 @@
|
||||
class AlbersEqual : public Projection
|
||||
{
|
||||
public:
|
||||
AlbersEqual(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
AlbersEqual(const Ellipsoid *ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double falseEasting, double falseNorthing);
|
||||
|
||||
@ -15,7 +15,7 @@ public:
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
Ellipsoid _e;
|
||||
const Ellipsoid *_e;
|
||||
|
||||
double _latitudeOrigin;
|
||||
double _longitudeOrigin;
|
||||
|
41
src/map/angularunits.cpp
Normal file
41
src/map/angularunits.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "common/coordinates.h"
|
||||
#include "angularunits.h"
|
||||
|
||||
AngularUnits::AngularUnits(int code)
|
||||
{
|
||||
switch (code) {
|
||||
case 9101:
|
||||
_f = 180.0 / M_PI;
|
||||
break;
|
||||
case 9102:
|
||||
case 9107:
|
||||
case 9108:
|
||||
case 9110:
|
||||
case 9122:
|
||||
_f = 1.0;
|
||||
break;
|
||||
case 9103:
|
||||
_f = 1 / 60.0;
|
||||
break;
|
||||
case 9104:
|
||||
_f = 1 / 3600.0;
|
||||
break;
|
||||
case 9105:
|
||||
_f = 180.0 / 200.0;
|
||||
break;
|
||||
case 9106:
|
||||
_f = 180.0 / 200.0;
|
||||
break;
|
||||
case 9109:
|
||||
_f = 180.0 / (M_PI * 1000000.0);
|
||||
break;
|
||||
default:
|
||||
_f = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const AngularUnits &au)
|
||||
{
|
||||
dbg.nospace() << "AngularUnits(" << deg2rad(au._f) << ")";
|
||||
return dbg.maybeSpace();
|
||||
}
|
31
src/map/angularunits.h
Normal file
31
src/map/angularunits.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef ANGULARUNITS_H
|
||||
#define ANGULARUNITS_H
|
||||
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
|
||||
class AngularUnits
|
||||
{
|
||||
public:
|
||||
AngularUnits() : _f(NAN) {}
|
||||
AngularUnits(int code);
|
||||
|
||||
bool isNull() const {return std::isnan(_f);}
|
||||
bool isValid() const {return !std::isnan(_f);}
|
||||
|
||||
double toDegrees(double val) const {return val * _f;}
|
||||
double fromDegrees(double val) const {return val / _f;}
|
||||
|
||||
friend bool operator==(const AngularUnits &au1, const AngularUnits &au2);
|
||||
friend QDebug operator<<(QDebug dbg, const AngularUnits &au);
|
||||
|
||||
private:
|
||||
double _f;
|
||||
};
|
||||
|
||||
inline bool operator==(const AngularUnits &au1, const AngularUnits &au2)
|
||||
{return (au1._f == au2._f);}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const AngularUnits &au);
|
||||
|
||||
#endif // ANGULARUNITS_H
|
@ -1,24 +1,9 @@
|
||||
#include <cmath>
|
||||
#include <QFile>
|
||||
#include "common/wgs84.h"
|
||||
#include "datum.h"
|
||||
|
||||
|
||||
class Datum::Entry {
|
||||
public:
|
||||
Entry(const QString &name, int epsg, const Datum &datum)
|
||||
: _name(name), _epsg(epsg), _datum(datum) {}
|
||||
|
||||
const QString &name() const {return _name;}
|
||||
int epsg() const {return _epsg;}
|
||||
const Datum &datum() const {return _datum;}
|
||||
|
||||
private:
|
||||
QString _name;
|
||||
int _epsg;
|
||||
Datum _datum;
|
||||
};
|
||||
|
||||
static Ellipsoid WGS84e = Ellipsoid(WGS84_RADIUS, WGS84_FLATTENING);
|
||||
static Datum WGS84 = Datum(&WGS84e, 0.0, 0.0, 0.0);
|
||||
|
||||
// Abridged Molodensky transformation
|
||||
static Coordinates molodensky(const Coordinates &c, const Datum &from,
|
||||
@ -37,11 +22,11 @@ static Coordinates molodensky(const Coordinates &c, const Datum &from,
|
||||
double dy = from.dy() - to.dy();
|
||||
double dz = from.dz() - to.dz();
|
||||
|
||||
double from_f = from.ellipsoid().flattening();
|
||||
double to_f = to.ellipsoid().flattening();
|
||||
double from_f = from.ellipsoid()->flattening();
|
||||
double to_f = to.ellipsoid()->flattening();
|
||||
double df = to_f - from_f;
|
||||
double from_a = from.ellipsoid().radius();
|
||||
double to_a = to.ellipsoid().radius();
|
||||
double from_a = from.ellipsoid()->radius();
|
||||
double to_a = to.ellipsoid()->radius();
|
||||
double da = to_a - from_a;
|
||||
double from_esq = from_f * (2.0 - from_f);
|
||||
double adb = 1.0 / (1.0 - from_f);
|
||||
@ -58,138 +43,25 @@ static Coordinates molodensky(const Coordinates &c, const Datum &from,
|
||||
return Coordinates(c.lon() + rad2deg(dlon), c.lat() + rad2deg(dlat));
|
||||
}
|
||||
|
||||
QList<Datum::Entry> Datum::_datums = WGS84();
|
||||
QString Datum::_errorString;
|
||||
int Datum::_errorLine = 0;
|
||||
|
||||
QList<Datum::Entry> Datum::WGS84()
|
||||
Datum::Datum(const Ellipsoid *ellipsoid, double dx, double dy,
|
||||
double dz) : _ellipsoid(ellipsoid), _dx(dx), _dy(dy), _dz(dz)
|
||||
{
|
||||
QList<Datum::Entry> list;
|
||||
list.append(Datum::Entry("WGS 84", 4326,
|
||||
Datum(Ellipsoid(WGS84_RADIUS, WGS84_FLATTENING), 0.0, 0.0, 0.0)));
|
||||
return list;
|
||||
}
|
||||
|
||||
Datum::Datum(const Ellipsoid &ellipsoid, double dx, double dy, double dz)
|
||||
: _ellipsoid(ellipsoid), _dx(dx), _dy(dy), _dz(dz)
|
||||
{
|
||||
_WGS84 = (_ellipsoid.radius() == WGS84_RADIUS
|
||||
&& _ellipsoid.flattening() == WGS84_FLATTENING
|
||||
&& _dx == 0.0 && _dy == 0.0 && _dz == 0.0)
|
||||
? true : false;
|
||||
}
|
||||
|
||||
Datum::Datum(int id)
|
||||
{
|
||||
for (int i = 0; i < _datums.size(); i++) {
|
||||
if (_datums.at(i).epsg() == id) {
|
||||
*this = _datums.at(i).datum();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*this = Datum();
|
||||
}
|
||||
|
||||
Datum::Datum(const QString &name)
|
||||
{
|
||||
for (int i = 0; i < _datums.size(); i++) {
|
||||
if (_datums.at(i).name() == name) {
|
||||
*this = _datums.at(i).datum();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*this = Datum();
|
||||
}
|
||||
|
||||
void Datum::error(const QString &str)
|
||||
{
|
||||
_errorString = str;
|
||||
_datums = WGS84();
|
||||
}
|
||||
|
||||
bool Datum::loadList(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
bool res;
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
error(file.errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
_errorLine = 1;
|
||||
_errorString.clear();
|
||||
|
||||
while (!file.atEnd()) {
|
||||
QByteArray line = file.readLine();
|
||||
QList<QByteArray> list = line.split(',');
|
||||
if (list.size() != 6) {
|
||||
error("Format error");
|
||||
return false;
|
||||
}
|
||||
|
||||
QString f1 = list[1].trimmed();
|
||||
int id = 0;
|
||||
if (!f1.isEmpty()) {
|
||||
id = f1.toInt(&res);
|
||||
if (!res) {
|
||||
error("Invalid datum id");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int eid = list[2].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
error("Invalid ellipsoid id");
|
||||
return false;
|
||||
}
|
||||
double dx = list[3].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
error("Invalid dx");
|
||||
return false;
|
||||
}
|
||||
double dy = list[4].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
error("Invalid dy");
|
||||
return false;
|
||||
}
|
||||
double dz = list[5].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
error("Invalid dz");
|
||||
return false;
|
||||
}
|
||||
|
||||
Ellipsoid e(eid);
|
||||
if (e.isNull()) {
|
||||
error("Unknown ellipsoid ID");
|
||||
return false;
|
||||
}
|
||||
|
||||
Datum d(e, dx, dy, dz);
|
||||
_datums.append(Entry(list[0].trimmed(), id, d));
|
||||
|
||||
_errorLine++;
|
||||
}
|
||||
|
||||
return true;
|
||||
_WGS84 = (*this == WGS84) ? true : false;
|
||||
}
|
||||
|
||||
Coordinates Datum::toWGS84(const Coordinates &c) const
|
||||
{
|
||||
return _WGS84 ? c : molodensky(c, *this, Datum(Ellipsoid(WGS84_RADIUS,
|
||||
WGS84_FLATTENING), 0.0, 0.0, 0.0));
|
||||
return _WGS84 ? c : molodensky(c, *this, WGS84);
|
||||
}
|
||||
|
||||
Coordinates Datum::fromWGS84(const Coordinates &c) const
|
||||
{
|
||||
return _WGS84 ? c : molodensky(c, Datum(Ellipsoid(WGS84_RADIUS,
|
||||
WGS84_FLATTENING), 0.0, 0.0, 0.0), *this);
|
||||
return _WGS84 ? c : molodensky(c, WGS84, *this);
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Datum &datum)
|
||||
{
|
||||
dbg.nospace() << "Datum(" << datum.ellipsoid() << ", " << datum.dx() << ", "
|
||||
<< datum.dy() << ", " << datum.dz() << ")";
|
||||
return dbg.space();
|
||||
return dbg.maybeSpace();
|
||||
}
|
||||
|
@ -10,43 +10,35 @@
|
||||
class Datum
|
||||
{
|
||||
public:
|
||||
Datum() : _ellipsoid(Ellipsoid()), _dx(NAN), _dy(NAN), _dz(NAN),
|
||||
Datum() : _ellipsoid(0), _dx(NAN), _dy(NAN), _dz(NAN),
|
||||
_WGS84(false) {}
|
||||
Datum(const Ellipsoid &ellipsoid, double dx, double dy, double dz);
|
||||
Datum(const QString &name);
|
||||
Datum(int id);
|
||||
Datum(const Ellipsoid *ellipsoid, double dx, double dy, double dz);
|
||||
|
||||
const Ellipsoid &ellipsoid() const {return _ellipsoid;}
|
||||
const Ellipsoid *ellipsoid() const {return _ellipsoid;}
|
||||
double dx() const {return _dx;}
|
||||
double dy() const {return _dy;}
|
||||
double dz() const {return _dz;}
|
||||
|
||||
bool isNull() const
|
||||
{return (_ellipsoid.isNull() && std::isnan(_dx) && std::isnan(_dy)
|
||||
{return (!_ellipsoid && std::isnan(_dx) && std::isnan(_dy)
|
||||
&& std::isnan(_dz));}
|
||||
bool isValid() const
|
||||
{return (_ellipsoid && !std::isnan(_dx) && !std::isnan(_dy)
|
||||
&& !std::isnan(_dz));}
|
||||
|
||||
Coordinates toWGS84(const Coordinates &c) const;
|
||||
Coordinates fromWGS84(const Coordinates &c) const;
|
||||
|
||||
static bool loadList(const QString &path);
|
||||
static const QString &errorString() {return _errorString;}
|
||||
static int errorLine() {return _errorLine;}
|
||||
|
||||
private:
|
||||
class Entry;
|
||||
|
||||
static QList<Entry> WGS84();
|
||||
static void error(const QString &str);
|
||||
|
||||
Ellipsoid _ellipsoid;
|
||||
const Ellipsoid *_ellipsoid;
|
||||
double _dx, _dy, _dz;
|
||||
bool _WGS84;
|
||||
|
||||
static QList<Entry> _datums;
|
||||
static QString _errorString;
|
||||
static int _errorLine;
|
||||
};
|
||||
|
||||
inline bool operator==(const Datum &d1, const Datum &d2)
|
||||
{return (d1.ellipsoid() == d2.ellipsoid() && d1.dx() == d2.dx()
|
||||
&& d1.dy() == d2.dy() && d1.dz() == d2.dz());}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Datum &datum);
|
||||
|
||||
#endif // DATUM_H
|
||||
|
@ -1,77 +1,74 @@
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include "common/wgs84.h"
|
||||
#include "ellipsoid.h"
|
||||
|
||||
QMap<int, Ellipsoid> Ellipsoid::_ellipsoids;
|
||||
QString Ellipsoid::_errorString;
|
||||
int Ellipsoid::_errorLine = 0;
|
||||
QMap<int, Ellipsoid> Ellipsoid::_ellipsoids = WGS84();
|
||||
|
||||
Ellipsoid::Ellipsoid(int id)
|
||||
QMap<int, Ellipsoid> Ellipsoid::WGS84()
|
||||
{
|
||||
QMap<int, Ellipsoid> map;
|
||||
map.insert(7030, Ellipsoid(WGS84_RADIUS, WGS84_FLATTENING));
|
||||
return map;
|
||||
}
|
||||
|
||||
const Ellipsoid *Ellipsoid::ellipsoid(int id)
|
||||
{
|
||||
QMap<int, Ellipsoid>::const_iterator it = _ellipsoids.find(id);
|
||||
|
||||
if (it == _ellipsoids.end())
|
||||
*this = Ellipsoid();
|
||||
return 0;
|
||||
else
|
||||
*this = it.value();
|
||||
return &(it.value());
|
||||
}
|
||||
|
||||
void Ellipsoid::error(const QString &str)
|
||||
{
|
||||
_errorString = str;
|
||||
_ellipsoids.clear();
|
||||
}
|
||||
|
||||
bool Ellipsoid::loadList(const QString &path)
|
||||
void Ellipsoid::loadList(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
bool res;
|
||||
int ln = 0;
|
||||
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
error(file.errorString());
|
||||
return false;
|
||||
qWarning("Error opening ellipsoids file: %s: %s", qPrintable(path),
|
||||
qPrintable(file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
_errorLine = 1;
|
||||
_errorString.clear();
|
||||
|
||||
while (!file.atEnd()) {
|
||||
ln++;
|
||||
|
||||
QByteArray line = file.readLine();
|
||||
QList<QByteArray> list = line.split(',');
|
||||
if (list.size() != 4) {
|
||||
error("Format error");
|
||||
return false;
|
||||
qWarning("%s: %d: Format error", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
int id = list[1].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
error("Invalid ellipsoid id");
|
||||
return false;
|
||||
qWarning("%s: %d: Invalid ellipsoid code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double radius = list[2].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
error("Invalid ellipsoid radius");
|
||||
return false;
|
||||
qWarning("%s: %d: Invalid radius", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double flattening = list[3].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
error("Invalid ellipsoid flattening");
|
||||
return false;
|
||||
qWarning("%s: %d: Invalid flattening", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
Ellipsoid e(radius, 1.0/flattening);
|
||||
_ellipsoids.insert(id, e);
|
||||
|
||||
_errorLine++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Ellipsoid &ellipsoid)
|
||||
{
|
||||
dbg.nospace() << "Ellipsoid(" << ellipsoid.radius() << ", "
|
||||
<< 1.0 / ellipsoid.flattening() << ")";
|
||||
return dbg.space();
|
||||
return dbg.maybeSpace();
|
||||
}
|
||||
|
@ -12,29 +12,29 @@ public:
|
||||
Ellipsoid() : _radius(NAN), _flattening(NAN) {}
|
||||
Ellipsoid(double radius, double flattening)
|
||||
: _radius(radius), _flattening(flattening) {}
|
||||
Ellipsoid(int id);
|
||||
|
||||
double radius() const {return _radius;}
|
||||
double flattening() const {return _flattening;}
|
||||
|
||||
bool isNull() const
|
||||
{return (std::isnan(_radius) && std::isnan(_flattening));}
|
||||
bool isValid() const
|
||||
{return !(std::isnan(_radius) || std::isnan(_flattening));}
|
||||
|
||||
static bool loadList(const QString &path);
|
||||
static const QString &errorString() {return _errorString;}
|
||||
static int errorLine() {return _errorLine;}
|
||||
static const Ellipsoid *ellipsoid(int id);
|
||||
static void loadList(const QString &path);
|
||||
|
||||
private:
|
||||
static void error(const QString &str);
|
||||
|
||||
double _radius;
|
||||
double _flattening;
|
||||
|
||||
static QMap<int, Ellipsoid> WGS84();
|
||||
static QMap<int, Ellipsoid> _ellipsoids;
|
||||
static QString _errorString;
|
||||
static int _errorLine;
|
||||
};
|
||||
|
||||
inline bool operator==(const Ellipsoid &e1, const Ellipsoid &e2)
|
||||
{return (e1.radius() == e2.radius() && e1.flattening() == e2.flattening());}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Ellipsoid &ellipsoid);
|
||||
|
||||
#endif // ELLIPSOID_H
|
||||
|
191
src/map/gcs.cpp
Normal file
191
src/map/gcs.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
#include <QFile>
|
||||
#include "common/wgs84.h"
|
||||
#include "gcs.h"
|
||||
|
||||
|
||||
class GCS::Entry {
|
||||
public:
|
||||
Entry(int id, int gd, const QString &name, const GCS &gcs)
|
||||
: _id(id), _gd(gd), _name(name), _gcs(gcs) {}
|
||||
|
||||
int id() const {return _id;}
|
||||
int gd() const {return _gd;}
|
||||
const QString &name() const {return _name;}
|
||||
const GCS &gcs() const {return _gcs;}
|
||||
|
||||
private:
|
||||
int _id, _gd;
|
||||
QString _name;
|
||||
GCS _gcs;
|
||||
};
|
||||
|
||||
static Ellipsoid WGS84e = Ellipsoid(WGS84_RADIUS, WGS84_FLATTENING);
|
||||
static Datum WGS84d = Datum(&WGS84e, 0.0, 0.0, 0.0);
|
||||
|
||||
static int parameter(const QString &str, bool *res)
|
||||
{
|
||||
QString field = str.trimmed();
|
||||
if (field.isEmpty()) {
|
||||
*res = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return field.toInt(res);
|
||||
}
|
||||
|
||||
QList<GCS::Entry> GCS::_gcss = WGS84();
|
||||
|
||||
QList<GCS::Entry> GCS::WGS84()
|
||||
{
|
||||
QList<GCS::Entry> list;
|
||||
list.append(GCS::Entry(4326, 6326, "WGS 84", GCS(WGS84d, 8901, 9122)));
|
||||
return list;
|
||||
}
|
||||
|
||||
const GCS *GCS::gcs(int id)
|
||||
{
|
||||
for (int i = 0; i < _gcss.size(); i++)
|
||||
if (_gcss.at(i).id() == id)
|
||||
return &(_gcss.at(i).gcs());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const GCS *GCS::gcs(int geodeticDatum, int primeMeridian, int angularUnits)
|
||||
{
|
||||
for (int i = 0; i < _gcss.size(); i++) {
|
||||
const Entry &e = _gcss.at(i);
|
||||
if (e.gd() == geodeticDatum && e.gcs().primeMeridian() == primeMeridian
|
||||
&& e.gcs().angularUnits() == angularUnits)
|
||||
return &(e.gcs());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const GCS *GCS::gcs(const QString &name)
|
||||
{
|
||||
for (int i = 0; i < _gcss.size(); i++)
|
||||
if (_gcss.at(i).name() == name)
|
||||
return &(_gcss.at(i).gcs());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GCS::loadList(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
bool res;
|
||||
int ln = 0;
|
||||
const Ellipsoid *e;
|
||||
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
qWarning("Error opening PCS file: %s: %s", qPrintable(path),
|
||||
qPrintable(file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
while (!file.atEnd()) {
|
||||
ln++;
|
||||
|
||||
QByteArray line = file.readLine();
|
||||
QList<QByteArray> list = line.split(',');
|
||||
if (list.size() < 10) {
|
||||
qWarning("%s: %d: Format error", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
int id = parameter(list[1], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid GCS code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int gd = parameter(list[2], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid geodetic datum code", qPrintable(path),
|
||||
ln);
|
||||
continue;
|
||||
}
|
||||
int au = list[3].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid angular units code", qPrintable(path),
|
||||
ln);
|
||||
continue;
|
||||
}
|
||||
int el = list[4].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid ellipsoid code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int pm = list[5].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid prime meridian code", qPrintable(path),
|
||||
ln);
|
||||
continue;
|
||||
}
|
||||
int ct = list[6].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid coordinates transformation code",
|
||||
qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double dx = list[7].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid dx", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double dy = list[8].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid dy", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double dz = list[9].trimmed().toDouble(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid dz", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(e = Ellipsoid::ellipsoid(el))) {
|
||||
qWarning("%s: %d: Unknown ellipsoid code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
Datum datum;
|
||||
switch (ct) {
|
||||
case 9603:
|
||||
datum = Datum(e, dx, dy, dz);
|
||||
break;
|
||||
default:
|
||||
qWarning("%s: %d: Unknown coordinates transformation method",
|
||||
qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
GCS gcs(datum, pm, au);
|
||||
if (gcs.isValid())
|
||||
_gcss.append(Entry(id, gd, list[0].trimmed(), gcs));
|
||||
else
|
||||
qWarning("%s: %d: Unknown prime meridian/angular units code",
|
||||
qPrintable(path), ln);
|
||||
}
|
||||
}
|
||||
|
||||
Coordinates GCS::toWGS84(const Coordinates &c) const
|
||||
{
|
||||
return datum().toWGS84(Coordinates(_primeMeridian.toGreenwich(c.lon()),
|
||||
c.lat()));
|
||||
}
|
||||
|
||||
Coordinates GCS::fromWGS84(const Coordinates &c) const
|
||||
{
|
||||
Coordinates ds(datum().fromWGS84(c));
|
||||
return Coordinates(_primeMeridian.fromGreenwich(ds.lon()), ds.lat());
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const GCS &gcs)
|
||||
{
|
||||
dbg.nospace() << "GCS(" << gcs.datum() << ", " << gcs.primeMeridian()
|
||||
<< ", " << gcs.angularUnits() << ")";
|
||||
return dbg.maybeSpace();
|
||||
}
|
55
src/map/gcs.h
Normal file
55
src/map/gcs.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef GCS_H
|
||||
#define GCS_H
|
||||
|
||||
#include "datum.h"
|
||||
#include "angularunits.h"
|
||||
#include "primemeridian.h"
|
||||
|
||||
class GCS
|
||||
{
|
||||
public:
|
||||
GCS() {}
|
||||
GCS(const Datum &datum, const PrimeMeridian &primeMeridian,
|
||||
const AngularUnits &angularUnits) : _datum(datum),
|
||||
_primeMeridian(primeMeridian), _angularUnits(angularUnits) {}
|
||||
|
||||
const PrimeMeridian &primeMeridian() const {return _primeMeridian;}
|
||||
const AngularUnits &angularUnits() const {return _angularUnits;}
|
||||
const Datum &datum() const {return _datum;}
|
||||
|
||||
bool isNull() const {return _datum.isNull() && _angularUnits.isNull()
|
||||
&& _primeMeridian.isNull();}
|
||||
bool isValid() const {return _datum.isValid() && _angularUnits.isValid()
|
||||
&& _primeMeridian.isValid();}
|
||||
|
||||
Coordinates toWGS84(const Coordinates &c) const;
|
||||
Coordinates fromWGS84(const Coordinates &c) const;
|
||||
|
||||
|
||||
static const GCS *gcs(int id);
|
||||
static const GCS *gcs(int geodeticDatum, int primeMeridian,
|
||||
int angularUnits);
|
||||
static const GCS *gcs(const QString &name);
|
||||
|
||||
static void loadList(const QString &path);
|
||||
|
||||
private:
|
||||
class Entry;
|
||||
|
||||
static QList<Entry> WGS84();
|
||||
|
||||
Datum _datum;
|
||||
PrimeMeridian _primeMeridian;
|
||||
AngularUnits _angularUnits;
|
||||
|
||||
static QList<Entry> _gcss;
|
||||
};
|
||||
|
||||
inline bool operator==(const GCS &gcs1, const GCS &gcs2)
|
||||
{return (gcs1.datum() == gcs2.datum()
|
||||
&& gcs1.primeMeridian() == gcs2.primeMeridian()
|
||||
&& gcs1.angularUnits() == gcs2.angularUnits());}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const GCS &gcs);
|
||||
|
||||
#endif // GCS_H
|
@ -21,7 +21,8 @@
|
||||
#define GTRasterTypeGeoKey 1025
|
||||
#define GeographicTypeGeoKey 2048
|
||||
#define GeogGeodeticDatumGeoKey 2050
|
||||
#define GeogEllipsoidGeoKey 2056
|
||||
#define GeogPrimeMeridianGeoKey 2051
|
||||
#define GeogAngularUnitsGeoKey 2054
|
||||
#define ProjectedCSTypeGeoKey 3072
|
||||
#define ProjectionGeoKey 3074
|
||||
#define ProjCoordTransGeoKey 3075
|
||||
@ -218,7 +219,8 @@ bool GeoTIFF::readKeys(TIFFFile &file, Ctx &ctx, QMap<quint16, Value> &kv) const
|
||||
case GTRasterTypeGeoKey:
|
||||
case GeogGeodeticDatumGeoKey:
|
||||
case ProjectionGeoKey:
|
||||
case GeogEllipsoidGeoKey:
|
||||
case GeogPrimeMeridianGeoKey:
|
||||
case GeogAngularUnitsGeoKey:
|
||||
if (entry.TIFFTagLocation != 0 || entry.Count != 1)
|
||||
return false;
|
||||
value.SHORT = entry.ValueOffset;
|
||||
@ -260,80 +262,84 @@ bool GeoTIFF::readGeoValue(TIFFFile &file, quint32 offset, quint16 index,
|
||||
return true;
|
||||
}
|
||||
|
||||
Datum GeoTIFF::datum(QMap<quint16, Value> &kv)
|
||||
const GCS *GeoTIFF::gcs(QMap<quint16, Value> &kv)
|
||||
{
|
||||
Datum datum;
|
||||
const GCS *gcs;
|
||||
|
||||
if (IS_SET(kv, GeographicTypeGeoKey)) {
|
||||
datum = Datum(kv.value(GeographicTypeGeoKey).SHORT);
|
||||
if (datum.isNull())
|
||||
if (!(gcs = GCS::gcs(kv.value(GeographicTypeGeoKey).SHORT)))
|
||||
_errorString = QString("%1: unknown GCS")
|
||||
.arg(kv.value(GeographicTypeGeoKey).SHORT);
|
||||
} else if (IS_SET(kv, GeogGeodeticDatumGeoKey)) {
|
||||
datum = Datum(kv.value(GeogGeodeticDatumGeoKey).SHORT - 2000);
|
||||
if (datum.isNull())
|
||||
_errorString = QString("%1: unknown geodetic datum")
|
||||
.arg(kv.value(GeogGeodeticDatumGeoKey).SHORT);
|
||||
} else if (IS_SET(kv, GeogEllipsoidGeoKey)
|
||||
&& kv.value(GeogEllipsoidGeoKey).SHORT == 7019) {
|
||||
datum = Datum(4326);
|
||||
} else
|
||||
_errorString = "Missing datum";
|
||||
int pm = IS_SET(kv, GeogPrimeMeridianGeoKey)
|
||||
? kv.value(GeogPrimeMeridianGeoKey).SHORT : 8901;
|
||||
int au = IS_SET(kv, GeogAngularUnitsGeoKey)
|
||||
? kv.value(GeogAngularUnitsGeoKey).SHORT : 9122;
|
||||
|
||||
return datum;
|
||||
if (!(gcs = GCS::gcs(kv.value(GeogGeodeticDatumGeoKey).SHORT, pm, au)))
|
||||
_errorString = QString("%1+%2: unknown geodetic datum + prime"
|
||||
" meridian combination")
|
||||
.arg(kv.value(GeogGeodeticDatumGeoKey).SHORT)
|
||||
.arg(kv.value(GeogPrimeMeridianGeoKey).SHORT);
|
||||
} else
|
||||
_errorString = "Can not determine GCS";
|
||||
|
||||
return gcs;
|
||||
}
|
||||
|
||||
Projection::Method GeoTIFF::method(QMap<quint16, Value> &kv)
|
||||
{
|
||||
int epsg;
|
||||
int table[] = {0, 9807, 0, 0, 0, 0, 0, 1024, 9801, 9802, 9820,
|
||||
9822};
|
||||
|
||||
if (!IS_SET(kv, ProjCoordTransGeoKey)) {
|
||||
_errorString = "Missing coordinate transformation method";
|
||||
return Projection::Method();
|
||||
}
|
||||
|
||||
quint16 index = kv.value(ProjCoordTransGeoKey).SHORT;
|
||||
epsg = (index >= ARRAY_SIZE(table)) ? 0 : table[index];
|
||||
|
||||
if (!epsg) {
|
||||
_errorString = QString("Unknown coordinate transformation method");
|
||||
switch (kv.value(ProjCoordTransGeoKey).SHORT) {
|
||||
case 1:
|
||||
return Projection::Method(9807);
|
||||
case 7:
|
||||
return Projection::Method(1024);
|
||||
case 8:
|
||||
return Projection::Method(9801);
|
||||
case 9:
|
||||
return Projection::Method(9802);
|
||||
case 10:
|
||||
return Projection::Method(9820);
|
||||
case 11:
|
||||
return Projection::Method(9822);
|
||||
default:
|
||||
_errorString = QString("%1: unknown coordinate transformation method")
|
||||
.arg(kv.value(ProjCoordTransGeoKey).SHORT);
|
||||
return Projection::Method();
|
||||
}
|
||||
|
||||
return Projection::Method(epsg);
|
||||
}
|
||||
|
||||
bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
|
||||
{
|
||||
PCS pcs;
|
||||
|
||||
if (IS_SET(kv, ProjectedCSTypeGeoKey)) {
|
||||
pcs = PCS(kv.value(ProjectedCSTypeGeoKey).SHORT);
|
||||
if (pcs.isNull())
|
||||
const PCS *pcs;
|
||||
if (!(pcs = PCS::pcs(kv.value(ProjectedCSTypeGeoKey).SHORT))) {
|
||||
_errorString = QString("%1: unknown PCS")
|
||||
.arg(kv.value(ProjectedCSTypeGeoKey).SHORT);
|
||||
} else if (IS_SET(kv, GeographicTypeGeoKey)
|
||||
&& IS_SET(kv, ProjectionGeoKey)) {
|
||||
pcs = PCS(kv.value(GeographicTypeGeoKey).SHORT,
|
||||
kv.value(ProjectionGeoKey).SHORT);
|
||||
if (pcs.isNull())
|
||||
_errorString = QString("%1+%2: unknown GCS+projection combination")
|
||||
return false;
|
||||
}
|
||||
_gcs = pcs->gcs();
|
||||
_projection = Projection::projection(_gcs->datum(), pcs->method(),
|
||||
pcs->setup());
|
||||
} else if (IS_SET(kv, ProjectionGeoKey)) {
|
||||
if (!(_gcs = gcs(kv)))
|
||||
return false;
|
||||
const PCS *pcs;
|
||||
if (!(pcs = PCS::pcs(_gcs, kv.value(ProjectionGeoKey).SHORT))) {
|
||||
_errorString = QString("%1: unknown projection code")
|
||||
.arg(kv.value(GeographicTypeGeoKey).SHORT)
|
||||
.arg(kv.value(ProjectionGeoKey).SHORT);
|
||||
} else if (IS_SET(kv, GeogGeodeticDatumGeoKey)
|
||||
&& IS_SET(kv, ProjectionGeoKey)) {
|
||||
pcs = PCS(kv.value(GeogGeodeticDatumGeoKey).SHORT - 2000,
|
||||
kv.value(ProjectionGeoKey).SHORT);
|
||||
if (pcs.isNull())
|
||||
_errorString =
|
||||
QString("%1+%2: unknown geodetic datum+projection combination")
|
||||
.arg(kv.value(GeogGeodeticDatumGeoKey).SHORT)
|
||||
.arg(kv.value(ProjectionGeoKey).SHORT);
|
||||
return false;
|
||||
}
|
||||
_projection = Projection::projection(_gcs->datum(), pcs->method(),
|
||||
pcs->setup());
|
||||
} else {
|
||||
Datum d = datum(kv);
|
||||
if (d.isNull())
|
||||
if (!(_gcs = gcs(kv)))
|
||||
return false;
|
||||
Projection::Method m = method(kv);
|
||||
if (m.isNull())
|
||||
@ -348,24 +354,18 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
|
||||
kv.value(ProjStdParallel1GeoKey).DOUBLE,
|
||||
kv.value(ProjStdParallel2GeoKey).DOUBLE
|
||||
);
|
||||
|
||||
pcs = PCS(d, m, setup);
|
||||
_projection = Projection::projection(_gcs->datum(), m, setup);
|
||||
}
|
||||
|
||||
_datum = pcs.datum();
|
||||
_projection = Projection::projection(pcs.datum(), pcs.method(),
|
||||
pcs.setup());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoTIFF::geographicModel(QMap<quint16, Value> &kv)
|
||||
{
|
||||
_datum = datum(kv);
|
||||
if (_datum.isNull())
|
||||
if (!(_gcs = gcs(kv)))
|
||||
return false;
|
||||
|
||||
_projection = new LatLon();
|
||||
_projection = new LatLon(_gcs->angularUnits());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QTransform>
|
||||
#include <QFile>
|
||||
#include <QMap>
|
||||
#include "datum.h"
|
||||
#include "gcs.h"
|
||||
#include "projection.h"
|
||||
#include "tifffile.h"
|
||||
#include "transform.h"
|
||||
@ -16,7 +16,7 @@ public:
|
||||
|
||||
bool load(const QString &path);
|
||||
|
||||
const Datum &datum() const {return _datum;}
|
||||
const GCS *gcs() const {return _gcs;}
|
||||
Projection *projection() const {return _projection;}
|
||||
const QTransform &transform() const {return _transform;}
|
||||
|
||||
@ -50,13 +50,13 @@ private:
|
||||
bool readGeoValue(TIFFFile &file, quint32 offset, quint16 index,
|
||||
double &val) const;
|
||||
|
||||
Datum datum(QMap<quint16, Value> &kv);
|
||||
const GCS *gcs(QMap<quint16, Value> &kv);
|
||||
Projection::Method method(QMap<quint16, Value> &kv);
|
||||
bool geographicModel(QMap<quint16, Value> &kv);
|
||||
bool projectedModel(QMap<quint16, Value> &kv);
|
||||
|
||||
QTransform _transform;
|
||||
Datum _datum;
|
||||
const GCS *_gcs;
|
||||
Projection *_projection;
|
||||
|
||||
QString _errorString;
|
||||
|
@ -48,18 +48,18 @@ Defense.
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#endif // M_PI_2
|
||||
|
||||
LambertAzimuthal::LambertAzimuthal(const Ellipsoid &ellipsoid,
|
||||
LambertAzimuthal::LambertAzimuthal(const Ellipsoid *ellipsoid,
|
||||
double latitudeOrigin, double longitudeOrigin, double falseEasting,
|
||||
double falseNorthing)
|
||||
{
|
||||
double es2, es4, es6;
|
||||
|
||||
es2 = 2 * ellipsoid.flattening() - ellipsoid.flattening()
|
||||
* ellipsoid.flattening();
|
||||
es2 = 2 * ellipsoid->flattening() - ellipsoid->flattening()
|
||||
* ellipsoid->flattening();
|
||||
|
||||
es4 = es2 * es2;
|
||||
es6 = es4 * es2;
|
||||
_ra = ellipsoid.radius() * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0
|
||||
_ra = ellipsoid->radius() * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0
|
||||
* es6 / 3024.0);
|
||||
_latOrigin = deg2rad(latitudeOrigin);
|
||||
_sinLatOrigin = sin(_latOrigin);
|
||||
|
@ -7,7 +7,7 @@
|
||||
class LambertAzimuthal : public Projection
|
||||
{
|
||||
public:
|
||||
LambertAzimuthal(const Ellipsoid &ellipsoid, double latitudeOrigin,
|
||||
LambertAzimuthal(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double falseEasting, double falseNorthing);
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
|
@ -58,7 +58,7 @@ Defense.
|
||||
(tan(M_PI_4 - lat / 2) / pow((1.0 - essin) / (1.0 + essin), es_over_2))
|
||||
|
||||
|
||||
LambertConic1::LambertConic1(const Ellipsoid &ellipsoid, double latitudeOrigin,
|
||||
LambertConic1::LambertConic1(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double scale, double falseEasting,
|
||||
double falseNorthing)
|
||||
{
|
||||
@ -76,8 +76,8 @@ LambertConic1::LambertConic1(const Ellipsoid &ellipsoid, double latitudeOrigin,
|
||||
_falseEasting = falseEasting;
|
||||
_falseNorthing = falseNorthing;
|
||||
|
||||
es2 = 2.0 * ellipsoid.flattening() - ellipsoid.flattening()
|
||||
* ellipsoid.flattening();
|
||||
es2 = 2.0 * ellipsoid->flattening() - ellipsoid->flattening()
|
||||
* ellipsoid->flattening();
|
||||
_es = sqrt(es2);
|
||||
_es_over_2 = _es / 2.0;
|
||||
|
||||
@ -87,7 +87,7 @@ LambertConic1::LambertConic1(const Ellipsoid &ellipsoid, double latitudeOrigin,
|
||||
m0 = LAMBERT_m(cos(lat_orig), es_sin);
|
||||
_t0 = LAMBERT1_t(lat_orig, es_sin, _es_over_2);
|
||||
|
||||
_rho0 = ellipsoid.radius() * scale * m0 / _n;
|
||||
_rho0 = ellipsoid->radius() * scale * m0 / _n;
|
||||
|
||||
_rho_olat = _rho0;
|
||||
}
|
||||
@ -202,7 +202,7 @@ Coordinates LambertConic1::xy2ll(const QPointF &p) const
|
||||
return Coordinates(rad2deg(lon), rad2deg(lat));
|
||||
}
|
||||
|
||||
LambertConic2::LambertConic2(const Ellipsoid &ellipsoid,
|
||||
LambertConic2::LambertConic2(const Ellipsoid *ellipsoid,
|
||||
double standardParallel1, double standardParallel2, double latitudeOrigin,
|
||||
double longitudeOrigin, double falseEasting, double falseNorthing)
|
||||
{
|
||||
@ -226,8 +226,8 @@ LambertConic2::LambertConic2(const Ellipsoid &ellipsoid,
|
||||
sp2 = deg2rad(standardParallel2);
|
||||
|
||||
if (fabs(sp1 - sp2) > 1.0e-10) {
|
||||
es2 = 2 * ellipsoid.flattening() - ellipsoid.flattening()
|
||||
* ellipsoid.flattening();
|
||||
es2 = 2 * ellipsoid->flattening() - ellipsoid->flattening()
|
||||
* ellipsoid->flattening();
|
||||
es = sqrt(es2);
|
||||
es_over_2 = es / 2.0;
|
||||
|
||||
@ -252,7 +252,7 @@ LambertConic2::LambertConic2(const Ellipsoid &ellipsoid,
|
||||
|
||||
k0 = (m1 / m0) * (pow(t0 / t1, n));
|
||||
|
||||
const_value = ((ellipsoid.radius() * m2) / (n * pow(t2, n)));
|
||||
const_value = ((ellipsoid->radius() * m2) / (n * pow(t2, n)));
|
||||
|
||||
falseNorthing += (const_value * pow(t_olat, n)) - (const_value
|
||||
* pow(t0, n));
|
||||
|
@ -8,7 +8,7 @@ class LambertConic1 : public Projection
|
||||
{
|
||||
public:
|
||||
LambertConic1() {}
|
||||
LambertConic1(const Ellipsoid &ellipsoid, double latitudeOrigin,
|
||||
LambertConic1(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double scale, double falseEasting,
|
||||
double falseNorthing);
|
||||
|
||||
@ -31,7 +31,7 @@ private:
|
||||
class LambertConic2 : public Projection
|
||||
{
|
||||
public:
|
||||
LambertConic2(const Ellipsoid &ellipsoid, double standardParallel1,
|
||||
LambertConic2(const Ellipsoid *ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double falseEasting, double falseNorthing);
|
||||
|
||||
|
@ -2,14 +2,20 @@
|
||||
#define LATLON_H
|
||||
|
||||
#include "projection.h"
|
||||
#include "angularunits.h"
|
||||
|
||||
class LatLon : public Projection
|
||||
{
|
||||
public:
|
||||
LatLon(const AngularUnits &au) : _au(au) {}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const
|
||||
{return QPointF(c.lon(), c.lat());}
|
||||
{return QPointF(_au.fromDegrees(c.lon()), _au.fromDegrees(c.lat()));}
|
||||
virtual Coordinates xy2ll(const QPointF &p) const
|
||||
{return Coordinates(p.x(), p.y());}
|
||||
{return Coordinates(_au.toDegrees(p.x()), _au.toDegrees(p.y()));}
|
||||
|
||||
private:
|
||||
AngularUnits _au;
|
||||
};
|
||||
|
||||
#endif // LATLON_H
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "latlon.h"
|
||||
#include "utm.h"
|
||||
#include "gcs.h"
|
||||
#include "mapfile.h"
|
||||
|
||||
|
||||
@ -151,8 +152,7 @@ bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
|
||||
bool MapFile::createDatum(const QString &datum)
|
||||
{
|
||||
_datum = Datum(datum);
|
||||
if (_datum.isNull()) {
|
||||
if (!(_gcs = GCS::gcs(datum))) {
|
||||
_errorString = QString("%1: Unknown datum").arg(datum);
|
||||
return false;
|
||||
}
|
||||
@ -164,17 +164,17 @@ bool MapFile::createProjection(const QString &name,
|
||||
const Projection::Setup &setup, QList<CalibrationPoint> &points)
|
||||
{
|
||||
if (name == "Mercator")
|
||||
_projection = Projection::projection(_datum, 1024, setup);
|
||||
_projection = Projection::projection(_gcs->datum(), 1024, setup);
|
||||
else if (name == "Transverse Mercator")
|
||||
_projection = Projection::projection(_datum, 9807, setup);
|
||||
_projection = Projection::projection(_gcs->datum(), 9807, setup);
|
||||
else if (name == "Latitude/Longitude")
|
||||
_projection = new LatLon();
|
||||
_projection = new LatLon(9102);
|
||||
else if (name == "Lambert Conformal Conic")
|
||||
_projection = Projection::projection(_datum, 9802, setup);
|
||||
_projection = Projection::projection(_gcs->datum(), 9802, setup);
|
||||
else if (name == "Albers Equal Area")
|
||||
_projection = Projection::projection(_datum, 9822, setup);
|
||||
_projection = Projection::projection(_gcs->datum(), 9822, setup);
|
||||
else if (name == "(A)Lambert Azimuthual Equal Area")
|
||||
_projection = Projection::projection(_datum, 9820, setup);
|
||||
_projection = Projection::projection(_gcs->datum(), 9820, setup);
|
||||
else if (name == "(UTM) Universal Transverse Mercator") {
|
||||
int zone;
|
||||
if (points.first().zone)
|
||||
@ -185,37 +185,42 @@ bool MapFile::createProjection(const QString &name,
|
||||
_errorString = "Can not determine UTM zone";
|
||||
return 0;
|
||||
}
|
||||
_projection = Projection::projection(_datum, 9807, UTM::setup(zone));
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
UTM::setup(zone));
|
||||
} else if (name == "(NZTM2) New Zealand TM 2000")
|
||||
_projection = Projection::projection(_datum, 9807, Projection::Setup(
|
||||
0, 173.0, 0.9996, 1600000, 10000000, NAN, NAN));
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
Projection::Setup(0, 173.0, 0.9996, 1600000, 10000000, NAN, NAN));
|
||||
else if (name == "(BNG) British National Grid")
|
||||
_projection = Projection::projection(_datum, 9807, Projection::Setup(
|
||||
49, -2, 0.999601, 400000, -100000, NAN, NAN));
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
Projection::Setup(49, -2, 0.999601, 400000, -100000, NAN, NAN));
|
||||
else if (name == "(IG) Irish Grid")
|
||||
_projection = Projection::projection(_datum, 9807, Projection::Setup(
|
||||
53.5, -8, 1.000035, 200000, 250000, NAN, NAN));
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
Projection::Setup(53.5, -8, 1.000035, 200000, 250000, NAN, NAN));
|
||||
else if (name == "(SG) Swedish Grid")
|
||||
_projection = Projection::projection(_datum, 9807, Projection::Setup(
|
||||
0, 15.808278, 1, 1500000, 0, NAN, NAN));
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
Projection::Setup(0, 15.808278, 1, 1500000, 0, NAN, NAN));
|
||||
else if (name == "(I) France Zone I")
|
||||
_projection = Projection::projection(_datum, 9802, Projection::Setup(
|
||||
49.5, 2.337229, NAN, 600000, 1200000, 48.598523, 50.395912));
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(49.5, 2.337229, NAN, 600000, 1200000, 48.598523,
|
||||
50.395912));
|
||||
else if (name == "(II) France Zone II")
|
||||
_projection = Projection::projection(_datum, 9802, Projection::Setup(
|
||||
46.8, 2.337229, NAN, 600000, 2200000, 45.898919, 47.696014));
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(46.8, 2.337229, NAN, 600000, 2200000, 45.898919,
|
||||
47.696014));
|
||||
else if (name == "(III) France Zone III")
|
||||
_projection = Projection::projection(_datum, 9802, Projection::Setup(
|
||||
44.1, 2.337229, NAN, 600000, 3200000, 43.199291, 44.996094));
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(44.1, 2.337229, NAN, 600000, 3200000, 43.199291,
|
||||
44.996094));
|
||||
else if (name == "(IV) France Zone IV")
|
||||
_projection = Projection::projection(_datum, 9802, Projection::Setup(
|
||||
42.165, 2.337229, NAN, 234.358, 4185861.369, 41.560388, 42.767663));
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(42.165, 2.337229, NAN, 234.358, 4185861.369,
|
||||
41.560388, 42.767663));
|
||||
else if (name == "(VICGRID) Victoria Australia")
|
||||
_projection = Projection::projection(_datum, 9802, Projection::Setup(
|
||||
-37, 145, NAN, 2500000, 4500000, -36, -38));
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(-37, 145, NAN, 2500000, 4500000, -36, -38));
|
||||
else if (name == "(VG94) VICGRID94 Victoria Australia")
|
||||
_projection = Projection::projection(_datum, 9802, Projection::Setup(
|
||||
-37, 145, NAN, 2500000, 2500000, -36, -38));
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(-37, 145, NAN, 2500000, 2500000, -36, -38));
|
||||
else {
|
||||
_errorString = QString("%1: Unknown map projection").arg(name);
|
||||
return false;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QTransform>
|
||||
#include "datum.h"
|
||||
#include "gcs.h"
|
||||
#include "transform.h"
|
||||
#include "projection.h"
|
||||
|
||||
@ -12,7 +12,7 @@ class MapFile
|
||||
public:
|
||||
bool load(QIODevice &file);
|
||||
|
||||
const Datum &datum() const {return _datum;}
|
||||
const GCS *gcs() const {return _gcs;}
|
||||
Projection *projection() const {return _projection;}
|
||||
const QTransform &transform() const {return _transform;}
|
||||
|
||||
@ -42,9 +42,9 @@ private:
|
||||
QString _image;
|
||||
QSize _size;
|
||||
|
||||
Datum _datum;
|
||||
QTransform _transform;
|
||||
const GCS *_gcs;
|
||||
Projection *_projection;
|
||||
QTransform _transform;
|
||||
|
||||
QString _errorString;
|
||||
};
|
||||
|
@ -138,7 +138,7 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
_name = mf.name();
|
||||
_size = mf.size();
|
||||
_imgPath = mf.image();
|
||||
_datum = mf.datum();
|
||||
_gcs = mf.gcs();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
}
|
||||
@ -152,7 +152,7 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
_name = mf.name();
|
||||
_size = mf.size();
|
||||
_imgPath = mf.image();
|
||||
_datum = mf.datum();
|
||||
_gcs = mf.gcs();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
}
|
||||
@ -164,7 +164,7 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
} else {
|
||||
_name = fi.fileName();
|
||||
_imgPath = fileName;
|
||||
_datum = gt.datum();
|
||||
_gcs = gt.gcs();
|
||||
_projection = gt.projection();
|
||||
_transform = gt.transform();
|
||||
}
|
||||
@ -230,7 +230,7 @@ OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||
|
||||
_name = mf.name();
|
||||
_size = mf.size();
|
||||
_datum = mf.datum();
|
||||
_gcs = mf.gcs();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
|
||||
@ -363,19 +363,19 @@ void OfflineMap::draw(QPainter *painter, const QRectF &rect)
|
||||
QPointF OfflineMap::ll2xy(const Coordinates &c)
|
||||
{
|
||||
if (_ozf.isOpen()) {
|
||||
QPointF p(_transform.map(_projection->ll2xy(_datum.fromWGS84(c))));
|
||||
QPointF p(_transform.map(_projection->ll2xy(_gcs->fromWGS84(c))));
|
||||
return QPointF(p.x() * _scale.x(), p.y() * _scale.y());
|
||||
} else
|
||||
return _transform.map(_projection->ll2xy(_datum.fromWGS84(c)));
|
||||
return _transform.map(_projection->ll2xy(_gcs->fromWGS84(c)));
|
||||
}
|
||||
|
||||
Coordinates OfflineMap::xy2ll(const QPointF &p)
|
||||
{
|
||||
if (_ozf.isOpen()) {
|
||||
return _datum.toWGS84(_projection->xy2ll(_inverted.map(QPointF(p.x()
|
||||
return _gcs->toWGS84(_projection->xy2ll(_inverted.map(QPointF(p.x()
|
||||
/ _scale.x(), p.y() / _scale.y()))));
|
||||
} else
|
||||
return _datum.toWGS84(_projection->xy2ll(_inverted.map(p)));
|
||||
return _gcs->toWGS84(_projection->xy2ll(_inverted.map(p)));
|
||||
}
|
||||
|
||||
QRectF OfflineMap::bounds() const
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <QTransform>
|
||||
#include "common/coordinates.h"
|
||||
#include "datum.h"
|
||||
#include "gcs.h"
|
||||
#include "projection.h"
|
||||
#include "transform.h"
|
||||
#include "map.h"
|
||||
@ -66,7 +66,7 @@ private:
|
||||
QString _name;
|
||||
|
||||
QSize _size;
|
||||
Datum _datum;
|
||||
const GCS *_gcs;
|
||||
Projection *_projection;
|
||||
QTransform _transform, _inverted;
|
||||
|
||||
|
159
src/map/pcs.cpp
159
src/map/pcs.cpp
@ -4,24 +4,18 @@
|
||||
|
||||
class PCS::Entry {
|
||||
public:
|
||||
Entry(int id, int gcs, int proj, const PCS &pcs)
|
||||
: _id(id), _gcs(gcs), _proj(proj), _pcs(pcs) {}
|
||||
Entry(int id, int proj, const PCS &pcs) : _id(id), _proj(proj), _pcs(pcs) {}
|
||||
|
||||
int id() const {return _id;}
|
||||
int gcs() const {return _gcs;}
|
||||
int proj() const {return _proj;}
|
||||
const PCS &pcs() const {return _pcs;}
|
||||
|
||||
private:
|
||||
int _id;
|
||||
int _gcs;
|
||||
int _proj;
|
||||
int _id, _proj;
|
||||
PCS _pcs;
|
||||
};
|
||||
|
||||
QList<PCS::Entry> PCS::_pcss;
|
||||
QString PCS::_errorString;
|
||||
int PCS::_errorLine;
|
||||
|
||||
static double parameter(const QString &str, bool *res)
|
||||
{
|
||||
@ -34,99 +28,114 @@ static double parameter(const QString &str, bool *res)
|
||||
return field.toDouble(res);
|
||||
}
|
||||
|
||||
PCS::PCS(int id)
|
||||
{
|
||||
for (int i = 0; i < _pcss.size(); i++) {
|
||||
if (_pcss.at(i).id() == id) {
|
||||
*this = _pcss.at(i).pcs();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*this = PCS();
|
||||
const PCS *PCS::pcs(int id)
|
||||
{
|
||||
for (int i = 0; i < _pcss.size(); i++)
|
||||
if (_pcss.at(i).id() == id)
|
||||
return &(_pcss.at(i).pcs());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PCS::PCS(int gcs, int proj)
|
||||
const PCS *PCS::pcs(const GCS *gcs, int proj)
|
||||
{
|
||||
for (int i = 0; i < _pcss.size(); i++) {
|
||||
if (_pcss.at(i).gcs() == gcs && _pcss.at(i).proj() == proj) {
|
||||
*this = _pcss.at(i).pcs();
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < _pcss.size(); i++)
|
||||
if (_pcss.at(i).proj() == proj && *(_pcss.at(i).pcs().gcs()) == *gcs)
|
||||
return &(_pcss.at(i).pcs());
|
||||
|
||||
*this = PCS();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PCS::error(const QString &str)
|
||||
{
|
||||
_errorString = str;
|
||||
_pcss.clear();
|
||||
}
|
||||
|
||||
bool PCS::loadList(const QString &path)
|
||||
void PCS::loadList(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
bool res[12];
|
||||
int id, gcs, proj, transform;
|
||||
|
||||
bool res;
|
||||
int ln = 0;
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
error(file.errorString());
|
||||
return false;
|
||||
qWarning("Error opening PCS file: %s: %s", qPrintable(path),
|
||||
qPrintable(file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
_errorLine = 1;
|
||||
_errorString.clear();
|
||||
|
||||
while (!file.atEnd()) {
|
||||
ln++;
|
||||
|
||||
QByteArray line = file.readLine();
|
||||
QList<QByteArray> list = line.split(',');
|
||||
if (list.size() != 12) {
|
||||
error("Format error");
|
||||
return false;
|
||||
qWarning("%s: %d: Format error", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
id = list[1].trimmed().toInt(&res[1]);;
|
||||
gcs = list[2].trimmed().toInt(&res[2]);
|
||||
proj = list[3].trimmed().toInt(&res[3]);
|
||||
transform = list[4].trimmed().toInt(&res[4]);
|
||||
|
||||
Projection::Setup setup(
|
||||
parameter(list[5], &res[5]), parameter(list[6], &res[6]),
|
||||
parameter(list[7], &res[7]), parameter(list[8], &res[8]),
|
||||
parameter(list[9], &res[9]), parameter(list[10], &res[10]),
|
||||
parameter(list[11], &res[11]));
|
||||
|
||||
for (int i = 1; i < 12; i++) {
|
||||
if (!res[i]) {
|
||||
error("Parse error");
|
||||
return false;
|
||||
int id = list[1].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid PCS code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int gcs = list[2].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid GCS code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int proj = list[3].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid projection code", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
int transform = list[4].trimmed().toInt(&res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid coordinate transformation code",
|
||||
qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double lat0 = parameter(list[5], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid latitude origin", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double lon0 = parameter(list[6], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid longitude origin", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double scale = parameter(list[7], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid scale", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double fe = parameter(list[8], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid false easting", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double fn = parameter(list[9], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid false northing", qPrintable(path), ln);
|
||||
continue;
|
||||
}
|
||||
double sp1 = parameter(list[10], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid standard parallel #1", qPrintable(path),
|
||||
ln);
|
||||
continue;
|
||||
}
|
||||
double sp2 = parameter(list[11], &res);
|
||||
if (!res) {
|
||||
qWarning("%s: %d: Invalid standard parallel #2", qPrintable(path),
|
||||
ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
Datum datum(gcs);
|
||||
if (datum.isNull()) {
|
||||
error("Unknown datum");
|
||||
return false;
|
||||
_pcss.append(Entry(id, proj, PCS(GCS::gcs(gcs), transform,
|
||||
Projection::Setup(lat0, lon0, scale, fe, fn, sp1, sp2))));
|
||||
}
|
||||
Projection::Method method(transform);
|
||||
if (method.isNull()) {
|
||||
error("Unknown coordinates transformation method");
|
||||
return false;
|
||||
}
|
||||
|
||||
_pcss.append(Entry(id, gcs, proj, PCS(datum, method, setup)));
|
||||
|
||||
_errorLine++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const PCS &pcs)
|
||||
{
|
||||
dbg.nospace() << "PCS(" << pcs.datum() << ", " << pcs.method()
|
||||
dbg.nospace() << "PCS(" << *pcs.gcs() << ", " << pcs.method()
|
||||
<< ", " << pcs.setup() << ")";
|
||||
return dbg.space();
|
||||
return dbg.maybeSpace();
|
||||
}
|
||||
|
@ -3,44 +3,37 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QList>
|
||||
#include "datum.h"
|
||||
#include "gcs.h"
|
||||
#include "projection.h"
|
||||
|
||||
class PCS
|
||||
{
|
||||
public:
|
||||
PCS() {}
|
||||
PCS(const Datum &datum, const Projection::Method &method,
|
||||
const Projection::Setup &setup)
|
||||
: _datum(datum), _method(method), _setup(setup) {}
|
||||
PCS(int id);
|
||||
PCS(int gcs, int proj);
|
||||
PCS() : _gcs(0) {}
|
||||
PCS(const GCS *gcs, const Projection::Method &m, const Projection::Setup &s)
|
||||
: _gcs(gcs), _method(m), _setup(s) {}
|
||||
PCS(const GCS *gcs, int proj);
|
||||
|
||||
const Datum &datum() const {return _datum;}
|
||||
const GCS *gcs() const {return _gcs;}
|
||||
const Projection::Method &method() const {return _method;}
|
||||
const Projection::Setup &setup() const {return _setup;}
|
||||
|
||||
bool isNull() const
|
||||
{return (_datum.isNull() && _method.isNull());}
|
||||
bool isValid() const
|
||||
{return !(_datum.isNull() || _method.isNull());}
|
||||
{return (_gcs->isNull() && _method.isNull() && _setup.isNull());}
|
||||
|
||||
static bool loadList(const QString &path);
|
||||
static const QString &errorString() {return _errorString;}
|
||||
static int errorLine() {return _errorLine;}
|
||||
static void loadList(const QString &path);
|
||||
static const PCS *pcs(int id);
|
||||
static const PCS *pcs(const GCS *gcs, int proj);
|
||||
|
||||
private:
|
||||
class Entry;
|
||||
|
||||
static void error(const QString &str);
|
||||
|
||||
Datum _datum;
|
||||
const GCS *_gcs;
|
||||
Projection::Method _method;
|
||||
Projection::Setup _setup;
|
||||
|
||||
static QList<Entry> _pcss;
|
||||
static QString _errorString;
|
||||
static int _errorLine;
|
||||
static GCS _nullGCS;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug dbg, const PCS &pcs);
|
||||
|
73
src/map/primemeridian.cpp
Normal file
73
src/map/primemeridian.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "primemeridian.h"
|
||||
|
||||
static double shift(double lon, double offset)
|
||||
{
|
||||
double ret = lon + offset;
|
||||
|
||||
if (ret > 180.0)
|
||||
ret -= 360.0;
|
||||
if (ret < -180)
|
||||
ret += 360.0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PrimeMeridian::PrimeMeridian(int code)
|
||||
{
|
||||
switch (code) {
|
||||
case 8901:
|
||||
_pm = 0.0;
|
||||
break;
|
||||
case 8902:
|
||||
_pm = -9.1319061111;
|
||||
break;
|
||||
case 8903:
|
||||
_pm = 2.3372291666;
|
||||
break;
|
||||
case 8904:
|
||||
_pm = -74.0809166666;
|
||||
break;
|
||||
case 8905:
|
||||
_pm = -3.6879388888;
|
||||
break;
|
||||
case 8906:
|
||||
_pm = 12.4523333333;
|
||||
break;
|
||||
case 8907:
|
||||
_pm = 7.4395833333;
|
||||
break;
|
||||
case 8908:
|
||||
_pm = 106.8077194444;
|
||||
break;
|
||||
case 8909:
|
||||
_pm = -17.6666666666;
|
||||
break;
|
||||
case 8910:
|
||||
_pm = 4.3679750000;
|
||||
break;
|
||||
case 8911:
|
||||
_pm = 18.0582777777;
|
||||
break;
|
||||
case 8913:
|
||||
_pm = 10.7229166666;
|
||||
break;
|
||||
default:
|
||||
_pm = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
double PrimeMeridian::toGreenwich(double val) const
|
||||
{
|
||||
return shift(val, _pm);
|
||||
}
|
||||
|
||||
double PrimeMeridian::fromGreenwich(double val) const
|
||||
{
|
||||
return shift(val, -_pm);
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const PrimeMeridian &pm)
|
||||
{
|
||||
dbg.nospace() << "PrimeMeridian(" << pm._pm << ")";
|
||||
return dbg.maybeSpace();
|
||||
}
|
31
src/map/primemeridian.h
Normal file
31
src/map/primemeridian.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef PRIMEMERIDIAN_H
|
||||
#define PRIMEMERIDIAN_H
|
||||
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
|
||||
class PrimeMeridian
|
||||
{
|
||||
public:
|
||||
PrimeMeridian() : _pm(NAN) {}
|
||||
PrimeMeridian(int code);
|
||||
|
||||
bool isNull() const {return std::isnan(_pm);}
|
||||
bool isValid() const {return !std::isnan(_pm);}
|
||||
|
||||
double toGreenwich(double val) const;
|
||||
double fromGreenwich(double val) const;
|
||||
|
||||
friend bool operator==(const PrimeMeridian &pm1, const PrimeMeridian &pm2);
|
||||
friend QDebug operator<<(QDebug dbg, const PrimeMeridian &pm);
|
||||
|
||||
private:
|
||||
double _pm;
|
||||
};
|
||||
|
||||
inline bool operator==(const PrimeMeridian &pm1, const PrimeMeridian &pm2)
|
||||
{return (pm1._pm == pm2._pm);}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const PrimeMeridian &pm);
|
||||
|
||||
#endif // PRIMEMERIDIAN_H
|
@ -27,7 +27,7 @@ Projection::Method::Method(int id)
|
||||
Projection *Projection::projection(const Datum &datum, const Method &method,
|
||||
const Setup &setup)
|
||||
{
|
||||
const Ellipsoid &ellipsoid = datum.ellipsoid();
|
||||
const Ellipsoid *ellipsoid = datum.ellipsoid();
|
||||
|
||||
switch (method.id()) {
|
||||
case 9807:
|
||||
@ -66,11 +66,11 @@ QDebug operator<<(QDebug dbg, const Projection::Setup &setup)
|
||||
<< setup.longitudeOrigin() << ", " << setup.scale() << ", "
|
||||
<< setup.falseEasting() << ", " << setup.falseNorthing() << ", "
|
||||
<< setup.standardParallel1() << ", " << setup.standardParallel2() << ")";
|
||||
return dbg.space();
|
||||
return dbg.maybeSpace();
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Projection::Method &method)
|
||||
{
|
||||
dbg.nospace() << "Method(" << method.id() << ")";
|
||||
return dbg.space();
|
||||
return dbg.maybeSpace();
|
||||
}
|
||||
|
@ -30,6 +30,11 @@ public:
|
||||
double standardParallel1() const {return _standardParallel1;}
|
||||
double standardParallel2() const {return _standardParallel2;}
|
||||
|
||||
bool isNull() const {return std::isnan(_latitudeOrigin)
|
||||
&& std::isnan(_longitudeOrigin) && std::isnan(_scale)
|
||||
&& std::isnan(_falseEasting) && std::isnan(_falseNorthing)
|
||||
&& std::isnan(_standardParallel1) && std::isnan(_standardParallel2);}
|
||||
|
||||
private:
|
||||
double _latitudeOrigin;
|
||||
double _longitudeOrigin;
|
||||
|
@ -47,17 +47,17 @@ Defense.
|
||||
|
||||
|
||||
#define SPHSN(lat) \
|
||||
((double)(_e.radius() / sqrt(1.e0 - _es * pow(sin(lat), 2))))
|
||||
((double)(_e->radius() / sqrt(1.e0 - _es * pow(sin(lat), 2))))
|
||||
#define SPHTMD(lat) \
|
||||
((double)(_ap * lat - _bp * sin(2.e0 * lat) + _cp * sin(4.e0 * lat) \
|
||||
- _dp * sin(6.e0 * lat) + _ep * sin(8.e0 * lat)))
|
||||
#define DENOM(lat) \
|
||||
((double)(sqrt(1.e0 - _es * pow(sin(lat),2))))
|
||||
#define SPHSR(lat) \
|
||||
((double)(_e.radius() * (1.e0 - _es) / pow(DENOM(lat), 3)))
|
||||
((double)(_e->radius() * (1.e0 - _es) / pow(DENOM(lat), 3)))
|
||||
|
||||
|
||||
TransverseMercator::TransverseMercator(const Ellipsoid &ellipsoid,
|
||||
TransverseMercator::TransverseMercator(const Ellipsoid *ellipsoid,
|
||||
double latitudeOrigin, double longitudeOrigin, double scale,
|
||||
double falseEasting, double falseNorthing)
|
||||
{
|
||||
@ -72,24 +72,24 @@ TransverseMercator::TransverseMercator(const Ellipsoid &ellipsoid,
|
||||
_falseEasting = falseEasting;
|
||||
_falseNorthing = falseNorthing;
|
||||
|
||||
_es = 2 * _e.flattening() - _e.flattening() * _e.flattening();
|
||||
_es = 2 * _e->flattening() - _e->flattening() * _e->flattening();
|
||||
_ebs = (1 / (1 - _es)) - 1;
|
||||
|
||||
b = _e.radius() * (1 - _e.flattening());
|
||||
b = _e->radius() * (1 - _e->flattening());
|
||||
|
||||
tn = (_e.radius() - b) / (_e.radius() + b);
|
||||
tn = (_e->radius() - b) / (_e->radius() + b);
|
||||
tn2 = tn * tn;
|
||||
tn3 = tn2 * tn;
|
||||
tn4 = tn3 * tn;
|
||||
tn5 = tn4 * tn;
|
||||
|
||||
_ap = _e.radius() * (1.e0 - tn + 5.e0 * (tn2 - tn3) / 4.e0 + 81.e0
|
||||
_ap = _e->radius() * (1.e0 - tn + 5.e0 * (tn2 - tn3) / 4.e0 + 81.e0
|
||||
* (tn4 - tn5) / 64.e0);
|
||||
_bp = 3.e0 * _e.radius() * (tn - tn2 + 7.e0 * (tn3 - tn4) / 8.e0 + 55.e0
|
||||
_bp = 3.e0 * _e->radius() * (tn - tn2 + 7.e0 * (tn3 - tn4) / 8.e0 + 55.e0
|
||||
* tn5 / 64.e0 ) / 2.e0;
|
||||
_cp = 15.e0 * _e.radius() * (tn2 - tn3 + 3.e0 * (tn4 - tn5 ) / 4.e0) / 16.0;
|
||||
_dp = 35.e0 * _e.radius() * (tn3 - tn4 + 11.e0 * tn5 / 16.e0) / 48.e0;
|
||||
_ep = 315.e0 * _e.radius() * (tn4 - tn5) / 512.e0;
|
||||
_cp = 15.e0 * _e->radius() * (tn2 - tn3 + 3.e0 * (tn4 - tn5 ) / 4.e0) / 16.0;
|
||||
_dp = 35.e0 * _e->radius() * (tn3 - tn4 + 11.e0 * tn5 / 16.e0) / 48.e0;
|
||||
_ep = 315.e0 * _e->radius() * (tn4 - tn5) / 512.e0;
|
||||
}
|
||||
|
||||
QPointF TransverseMercator::ll2xy(const Coordinates &c) const
|
||||
|
@ -7,7 +7,7 @@
|
||||
class TransverseMercator : public Projection
|
||||
{
|
||||
public:
|
||||
TransverseMercator(const Ellipsoid &ellipsoid, double latitudeOrigin,
|
||||
TransverseMercator(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double scale, double falseEasting,
|
||||
double falseNorthing);
|
||||
|
||||
@ -15,7 +15,7 @@ public:
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
Ellipsoid _e;
|
||||
const Ellipsoid *_e;
|
||||
double _longitudeOrigin;
|
||||
double _latitudeOrigin;
|
||||
double _scale;
|
||||
|
Loading…
Reference in New Issue
Block a user