/src/gdal/frmts/ilwis/ilwiscoordinatesystem.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Purpose: Translation from ILWIS coordinate system information. |
4 | | * Author: Lichun Wang, lichun@itc.nl |
5 | | * |
6 | | ****************************************************************************** |
7 | | * Copyright (c) 2004, ITC |
8 | | * Copyright (c) 2008-2012, Even Rouault <even dot rouault at spatialys.com> |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | #include "cpl_conv.h" |
13 | | #include "ilwisdataset.h" |
14 | | |
15 | | #include <string> |
16 | | |
17 | | namespace GDAL |
18 | | { |
19 | | |
20 | | typedef struct |
21 | | { |
22 | | const char *pszIlwisDatum; |
23 | | const char *pszWKTDatum; |
24 | | int nEPSGCode; |
25 | | } IlwisDatums; |
26 | | |
27 | | typedef struct |
28 | | { |
29 | | const char *pszIlwisEllips; |
30 | | int nEPSGCode; |
31 | | double semiMajor; |
32 | | double invFlattening; |
33 | | } IlwisEllips; |
34 | | |
35 | | static const IlwisDatums iwDatums[] = { |
36 | | {"Adindan", "Adindan", 4201}, |
37 | | {"Afgooye", "Afgooye", 4205}, |
38 | | // AGREF --- skipped |
39 | | {"Ain el Abd 1970", "Ain_el_Abd_1970", 4204}, |
40 | | {"American Samoa 1962", "American_Samoa_1962", 4169}, |
41 | | // Anna 1 Astro 1965 --- skipped |
42 | | {"Antigua Island Astro 1943", "Antigua_1943", 4601}, |
43 | | {"Arc 1950", "Arc_1950", 4209}, // Arc 1950 |
44 | | {"Arc 1960", "Arc_1960", 4210}, // Arc 1960 |
45 | | // Ascension Island 1958 |
46 | | // Astro Beacon E 1945 |
47 | | // Astro DOS 71/4 |
48 | | // Astro Tern Island (FRIG) 1961 |
49 | | // Astronomical Station 1952 |
50 | | {"Australian Geodetic 1966", "Australian_Geodetic_Datum_1966", 4202}, |
51 | | {"Australian Geodetic 1984", "Australian_Geodetic_Datum_1984", 4203}, |
52 | | // Ayabelle Lighthouse |
53 | | // Bellevue (IGN) |
54 | | {"Bermuda 1957", "Bermuda_1957", 4216}, |
55 | | {"Bissau", "Bissau", 4165}, |
56 | | {"Bogota Observatory (1975)", "Bogota", 4218}, |
57 | | {"Bukit Rimpah", "Bukit_Rimpah", 4219}, |
58 | | // Camp Area Astro |
59 | | {"Campo Inchauspe", "Campo_Inchauspe", 4221}, |
60 | | // Canton Astro 1966 |
61 | | {"Cape", "Cape", 4222}, |
62 | | // Cape Canaveral |
63 | | {"Carthage", "Carthage", 4223}, |
64 | | {"CH1903", "CH1903", 4149}, |
65 | | // Chatham Island Astro 1971 |
66 | | {"Chua Astro", "Chua", 4224}, |
67 | | {"Corrego Alegre", "Corrego_Alegre", 4225}, |
68 | | // Croatia |
69 | | // D-PAF (Orbits) |
70 | | {"Dabola", "Dabola_1981", 4155}, |
71 | | // Deception Island |
72 | | // Djakarta (Batavia) |
73 | | // DOS 1968 |
74 | | // Easter Island 1967 |
75 | | // Estonia 1937 |
76 | | {"European 1950 (ED 50)", "European_Datum_1950", 4154}, |
77 | | // European 1979 (ED 79 |
78 | | // Fort Thomas 1955 |
79 | | {"Gan 1970", "Gandajika_1970", 4233}, |
80 | | // Geodetic Datum 1949 |
81 | | // Graciosa Base SW 1948 |
82 | | // Guam 1963 |
83 | | {"Gunung Segara", "Gunung_Segara", 4613}, |
84 | | // GUX 1 Astro |
85 | | {"Herat North", "Herat_North", 4255}, |
86 | | // Hermannskogel |
87 | | // Hjorsey 1955 |
88 | | // Hong Kong 1963 |
89 | | {"Hu-Tzu-Shan", "Hu_Tzu_Shan", 4236}, |
90 | | // Indian (Bangladesh) |
91 | | // Indian (India, Nepal) |
92 | | // Indian (Pakistan) |
93 | | {"Indian 1954", "Indian_1954", 4239}, |
94 | | {"Indian 1960", "Indian_1960", 4131}, |
95 | | {"Indian 1975", "Indian_1975", 4240}, |
96 | | {"Indonesian 1974", "Indonesian_Datum_1974", 4238}, |
97 | | // Ireland 1965 |
98 | | // ISTS 061 Astro 1968 |
99 | | // ISTS 073 Astro 1969 |
100 | | // Johnston Island 1961 |
101 | | {"Kandawala", "Kandawala", 4244}, |
102 | | // Kerguelen Island 1949 |
103 | | {"Kertau 1948", "Kertau", 4245}, |
104 | | // Kusaie Astro 1951 |
105 | | // L. C. 5 Astro 1961 |
106 | | {"Leigon", "Leigon", 4250}, |
107 | | {"Liberia 1964", "Liberia_1964", 4251}, |
108 | | {"Luzon", "Luzon_1911", 4253}, |
109 | | // M'Poraloko |
110 | | {"Mahe 1971", "Mahe_1971", 4256}, |
111 | | {"Massawa", "Massawa", 4262}, |
112 | | {"Merchich", "Merchich", 4261}, |
113 | | {"MGI (Hermannskogel)", "Militar_Geographische_Institute", 4312}, |
114 | | // Midway Astro 1961 |
115 | | {"Minna", "Minna", 4263}, |
116 | | {"Montserrat Island Astro 1958", "Montserrat_1958", 4604}, |
117 | | {"Nahrwan", "Nahrwan_1967", 4270}, |
118 | | {"Naparima BWI", "Naparima_1955", 4158}, |
119 | | {"North American 1927 (NAD 27)", "North_American_Datum_1927", 4267}, |
120 | | {"North American 1983 (NAD 83)", "North_American_Datum_1983", 4269}, |
121 | | // North Sahara 1959 |
122 | | {"NTF (Nouvelle Triangulation de France)", |
123 | | "Nouvelle_Triangulation_Francaise", 4807}, |
124 | | // Observatorio Meteorologico 1939 |
125 | | // Old Egyptian 1907 |
126 | | {"Old Hawaiian", "Old_Hawaiian", 4135}, |
127 | | // Oman |
128 | | // Ordnance Survey Great Britain 1936 |
129 | | // Pico de las Nieves |
130 | | // Pitcairn Astro 1967 |
131 | | // Point 58 |
132 | | {"Pointe Noire 1948", "Pointe_Noire", 4282}, |
133 | | {"Porto Santo 1936", "Porto_Santo", 4615}, |
134 | | // Potsdam (Rauenburg) |
135 | | {"Potsdam (Rauenburg)", "Deutsches_Hauptdreiecksnetz", 4314}, |
136 | | {"Provisional South American 1956", "Provisional_South_American_Datum_1956", |
137 | | 4248}, |
138 | | // Provisional South Chilean 1963 |
139 | | {"Puerto Rico", "Puerto_Rico", 4139}, |
140 | | {"Pulkovo 1942", "Pulkovo_1942", 4178}, |
141 | | //{ "Qatar National", "Qatar_National_Datum_1995", 4614 }, |
142 | | {"Qornoq", "Qornoq", 4287}, |
143 | | {"Puerto Rico", "Puerto_Rico", 4139}, |
144 | | // Reunion |
145 | | {"Rome 1940", "Monte_Mario", 4806}, |
146 | | {"RT90", "Rikets_koordinatsystem_1990", 4124}, |
147 | | {"Rijks Driehoeksmeting", "Amersfoort", 4289}, |
148 | | {"S-42 (Pulkovo 1942)", "Pulkovo_1942", 4178}, |
149 | | //{ "S-JTSK", "Jednotne_Trigonometricke_Site_Katastralni", 4156 }, |
150 | | // Santo (DOS) 1965 |
151 | | // Sao Braz |
152 | | {"Sapper Hill 1943", "Sapper_Hill_1943", 4292}, |
153 | | {"Schwarzeck", "Schwarzeck", 4293}, |
154 | | {"Selvagem Grande 1938", "Selvagem_Grande", 4616}, |
155 | | // vSGS 1985 |
156 | | // Sierra Leone 1960 |
157 | | {"South American 1969", "South_American_Datum_1969", 4291}, |
158 | | // South Asia |
159 | | {"Tananarive Observatory 1925", "Tananarive_1925", 4297}, |
160 | | {"Timbalai 1948", "Timbalai_1948", 4298}, |
161 | | {"Tokyo", "Tokyo", 4301}, |
162 | | // Tristan Astro 1968 |
163 | | // Viti Levu 1916 |
164 | | {"Voirol 1874", "Voirol_1875", 4304}, |
165 | | // Voirol 1960 |
166 | | // Wake Island Astro 1952 |
167 | | // Wake-Eniwetok 1960 |
168 | | {"WGS 1972", "WGS_1972", 4322}, |
169 | | {"WGS 1984", "WGS_1984", 4326}, |
170 | | {"Yacare", "Yacare", 4309}, |
171 | | {"Zanderij", "Zanderij", 4311}, |
172 | | {nullptr, nullptr, 0}}; |
173 | | |
174 | | static const IlwisEllips iwEllips[] = { |
175 | | {"Sphere", 7035, 6371007, 0.0}, // rad 6370997 m (normal sphere) |
176 | | {"Airy 1830", 7031, 6377563.396, 299.3249646}, |
177 | | {"Modified Airy", 7002, 6377340.189, 299.3249646}, |
178 | | {"ATS77", 7204, 6378135.0, 298.257000006}, |
179 | | {"Australian National", 7003, 6378160, 298.249997276}, |
180 | | {"Bessel 1841", 7042, 6377397.155, 299.1528128}, |
181 | | {"Bessel 1841 (Japan By Law)", 7046, 6377397.155, 299.152815351}, |
182 | | {"Bessel 1841 (Namibia)", 7006, 6377483.865, 299.1528128}, |
183 | | {"Clarke 1866", 7008, 6378206.4, 294.9786982}, |
184 | | {"Clarke 1880", 7034, 6378249.145, 293.465}, |
185 | | {"Clarke 1880 (IGN)", 7011, 6378249.2, 293.466}, |
186 | | // FIXME: D-PAF (Orbits) --- skipped |
187 | | // FIXME: Du Plessis Modified --- skipped |
188 | | // FIXME: Du Plessis Reconstituted --- skipped |
189 | | {"Everest (India 1830)", 7015, 6377276.345, 300.8017}, |
190 | | // Everest (India 1956) --- skipped |
191 | | // Everest (Malaysia 1969) --- skipped |
192 | | {"Everest (E. Malaysia and Brunei)", 7016, 6377298.556, 300.8017}, |
193 | | {"Everest (Malay. and Singapore 1948)", 7018, 6377304.063, 300.8017}, |
194 | | {"Everest (Pakistan)", 7044, 6377309.613, 300.8017}, |
195 | | // Everest (Sabah Sarawak) --- skipped |
196 | | // Fischer 1960 --- skipped |
197 | | // Fischer 1960 (Modified) --- skipped |
198 | | // Fischer 1968 --- skipped |
199 | | {"GRS 80", 7019, 6378137, 298.257222101}, |
200 | | {"Helmert 1906", 7020, 6378200, 298.3}, |
201 | | // Hough 1960 --- skipped |
202 | | {"Indonesian 1974", 7021, 6378160, 298.247}, |
203 | | {"International 1924", 7022, 6378388, 297}, |
204 | | {"Krassovsky 1940", 7024, 6378245, 298.3}, |
205 | | // New_International 1967 |
206 | | // SGS 85 |
207 | | // South American 1969 |
208 | | // WGS 60 |
209 | | // WGS 66 |
210 | | {"WGS 72", 7020, 6378135.0, 298.259998590}, |
211 | | {"WGS 84", 7030, 6378137, 298.257223563}, |
212 | | {nullptr, 0, 0.0, 0.0}}; |
213 | | |
214 | | #ifndef R2D |
215 | | #define R2D (180 / M_PI) |
216 | | #endif |
217 | | #ifndef D2R |
218 | | #define D2R (M_PI / 180) |
219 | | #endif |
220 | | |
221 | | /* ==================================================================== */ |
222 | | /* Some "standard" std::strings. */ |
223 | | /* ==================================================================== */ |
224 | | |
225 | | static const char ILW_False_Easting[] = "False Easting"; |
226 | | static const char ILW_False_Northing[] = "False Northing"; |
227 | | static const char ILW_Central_Meridian[] = "Central Meridian"; |
228 | | static const char ILW_Central_Parallel[] = "Central Parallel"; |
229 | | static const char ILW_Standard_Parallel_1[] = "Standard Parallel 1"; |
230 | | static const char ILW_Standard_Parallel_2[] = "Standard Parallel 2"; |
231 | | static const char ILW_Scale_Factor[] = "Scale Factor"; |
232 | | static const char ILW_Latitude_True_Scale[] = "Latitude of True Scale"; |
233 | | static const char ILW_Height_Persp_Center[] = "Height Persp. Center"; |
234 | | |
235 | | static double ReadPrjParams(const std::string §ion, |
236 | | const std::string &entry, |
237 | | const std::string &filename) |
238 | 0 | { |
239 | 0 | std::string str = ReadElement(section, entry, filename); |
240 | | // string str=""; |
241 | 0 | if (!str.empty()) |
242 | 0 | return CPLAtof(str.c_str()); |
243 | | |
244 | 0 | return 0.0; |
245 | 0 | } |
246 | | |
247 | | static int fetchParams(const std::string &csyFileName, double *padfPrjParams) |
248 | 0 | { |
249 | | // Fill all projection parameters with zero |
250 | 0 | for (int i = 0; i < 13; i++) |
251 | 0 | padfPrjParams[i] = 0.0; |
252 | | |
253 | | // std::string pszProj = ReadElement("CoordSystem", "Projection", |
254 | | // csyFileName); |
255 | 0 | std::string pszEllips = |
256 | 0 | ReadElement("CoordSystem", "Ellipsoid", csyFileName); |
257 | | |
258 | | // fetch info about a custom ellipsoid |
259 | 0 | if (STARTS_WITH_CI(pszEllips.c_str(), "User Defined")) |
260 | 0 | { |
261 | 0 | padfPrjParams[0] = ReadPrjParams("Ellipsoid", "a", csyFileName); |
262 | 0 | padfPrjParams[2] = ReadPrjParams("Ellipsoid", "1/f", csyFileName); |
263 | 0 | } |
264 | 0 | else if (STARTS_WITH_CI(pszEllips.c_str(), "Sphere")) |
265 | 0 | { |
266 | 0 | padfPrjParams[0] = |
267 | 0 | ReadPrjParams("CoordSystem", "Sphere Radius", csyFileName); |
268 | 0 | } |
269 | |
|
270 | 0 | padfPrjParams[3] = |
271 | 0 | ReadPrjParams("Projection", "False Easting", csyFileName); |
272 | 0 | padfPrjParams[4] = |
273 | 0 | ReadPrjParams("Projection", "False Northing", csyFileName); |
274 | |
|
275 | 0 | padfPrjParams[5] = |
276 | 0 | ReadPrjParams("Projection", "Central Parallel", csyFileName); |
277 | 0 | padfPrjParams[6] = |
278 | 0 | ReadPrjParams("Projection", "Central Meridian", csyFileName); |
279 | |
|
280 | 0 | padfPrjParams[7] = |
281 | 0 | ReadPrjParams("Projection", "Standard Parallel 1", csyFileName); |
282 | 0 | padfPrjParams[8] = |
283 | 0 | ReadPrjParams("Projection", "Standard Parallel 2", csyFileName); |
284 | |
|
285 | 0 | padfPrjParams[9] = ReadPrjParams("Projection", "Scale Factor", csyFileName); |
286 | 0 | padfPrjParams[10] = |
287 | 0 | ReadPrjParams("Projection", "Latitude of True Scale", csyFileName); |
288 | 0 | padfPrjParams[11] = ReadPrjParams("Projection", "Zone", csyFileName); |
289 | 0 | padfPrjParams[12] = |
290 | 0 | ReadPrjParams("Projection", ILW_Height_Persp_Center, csyFileName); |
291 | |
|
292 | 0 | return true; |
293 | 0 | } |
294 | | |
295 | | /************************************************************************/ |
296 | | /* mapTMParams */ |
297 | | /************************************************************************/ |
298 | | /** |
299 | | * fetch the parameters from ILWIS projection definition for |
300 | | * --- Gauss-Krueger Germany. |
301 | | * --- Gauss Colombia |
302 | | * --- Gauss-Boaga Italy |
303 | | **/ |
304 | | static int mapTMParams(const std::string &sProj, double dfZone, |
305 | | double &dfFalseEasting, double &dfCentralMeridian) |
306 | 0 | { |
307 | 0 | if (STARTS_WITH_CI(sProj.c_str(), "Gauss-Krueger Germany")) |
308 | 0 | { |
309 | | // Zone number must be in the range 1 to 3 |
310 | 0 | dfCentralMeridian = 6.0 + (dfZone - 1) * 3; |
311 | 0 | dfFalseEasting = 2500000 + (dfZone - 1) * 1000000; |
312 | 0 | } |
313 | 0 | else if (STARTS_WITH_CI(sProj.c_str(), "Gauss-Boaga Italy")) |
314 | 0 | { |
315 | 0 | if (dfZone == 1) |
316 | 0 | { |
317 | 0 | dfCentralMeridian = 9; |
318 | 0 | dfFalseEasting = 1500000; |
319 | 0 | } |
320 | 0 | else if (dfZone == 2) |
321 | 0 | { |
322 | 0 | dfCentralMeridian = 15; |
323 | 0 | dfFalseEasting = 2520000; |
324 | 0 | } |
325 | 0 | else |
326 | 0 | return false; |
327 | 0 | } |
328 | 0 | else if (STARTS_WITH_CI(sProj.c_str(), "Gauss Colombia")) |
329 | 0 | { |
330 | | // Zone number must be in the range 1 to 4 |
331 | 0 | dfCentralMeridian = -77.08097220 + (dfZone - 1) * 3; |
332 | 0 | } |
333 | 0 | return true; |
334 | 0 | } |
335 | | |
336 | | /************************************************************************/ |
337 | | /* scaleFromLATTS() */ |
338 | | /************************************************************************/ |
339 | | /** |
340 | | * Compute the scale factor from Latitude_Of_True_Scale parameter. |
341 | | * |
342 | | **/ |
343 | | static void scaleFromLATTS(const std::string &sEllips, double phits, |
344 | | double &scale) |
345 | 0 | { |
346 | 0 | if (STARTS_WITH_CI(sEllips.c_str(), "Sphere")) |
347 | 0 | { |
348 | 0 | scale = cos(phits); |
349 | 0 | } |
350 | 0 | else |
351 | 0 | { |
352 | 0 | const IlwisEllips *piwEllips = iwEllips; |
353 | 0 | double e2 = 0.0; |
354 | 0 | while (piwEllips->pszIlwisEllips) |
355 | 0 | { |
356 | 0 | if (EQUALN(sEllips.c_str(), piwEllips->pszIlwisEllips, |
357 | 0 | strlen(piwEllips->pszIlwisEllips))) |
358 | 0 | { |
359 | 0 | double a = piwEllips->semiMajor; |
360 | 0 | double b = a * (1 - piwEllips->invFlattening); |
361 | 0 | e2 = (a * a - b * b) / (a * a); |
362 | 0 | break; |
363 | 0 | } |
364 | 0 | piwEllips++; |
365 | 0 | } |
366 | 0 | scale = cos(phits) / sqrt(1. - e2 * sin(phits) * sin(phits)); |
367 | 0 | } |
368 | 0 | } |
369 | | |
370 | | /************************************************************************/ |
371 | | /* ReadProjection() */ |
372 | | /************************************************************************/ |
373 | | |
374 | | /** |
375 | | * Import coordinate system from ILWIS projection definition. |
376 | | * |
377 | | * The method will import projection definition in ILWIS, |
378 | | * It uses 13 parameters to define the coordinate system |
379 | | * and datum/ellipsoid specified in the padfPrjParams array. |
380 | | * |
381 | | * @param csyFileName Name of .csy file |
382 | | **/ |
383 | | |
384 | | CPLErr ILWISDataset::ReadProjection(const std::string &csyFileName) |
385 | 0 | { |
386 | 0 | std::string pszEllips; |
387 | 0 | std::string pszDatum; |
388 | 0 | std::string pszProj; |
389 | | |
390 | | // translate ILWIS pre-defined coordinate systems |
391 | 0 | if (STARTS_WITH_CI(csyFileName.c_str(), "latlon.csy")) |
392 | 0 | { |
393 | 0 | pszProj = "LatLon"; |
394 | 0 | pszDatum = ""; |
395 | 0 | pszEllips = "Sphere"; |
396 | 0 | } |
397 | 0 | else if (STARTS_WITH_CI(csyFileName.c_str(), "LatlonWGS84.csy")) |
398 | 0 | { |
399 | 0 | pszProj = "LatLon"; |
400 | 0 | pszDatum = "WGS 1984"; |
401 | 0 | pszEllips = "WGS 84"; |
402 | 0 | } |
403 | 0 | else |
404 | 0 | { |
405 | 0 | pszProj = ReadElement("CoordSystem", "Type", csyFileName); |
406 | 0 | if (!STARTS_WITH_CI(pszProj.c_str(), "LatLon")) |
407 | 0 | pszProj = ReadElement("CoordSystem", "Projection", csyFileName); |
408 | 0 | pszDatum = ReadElement("CoordSystem", "Datum", csyFileName); |
409 | 0 | pszEllips = ReadElement("CoordSystem", "Ellipsoid", csyFileName); |
410 | 0 | } |
411 | | |
412 | | /* -------------------------------------------------------------------- */ |
413 | | /* Fetch array containing 13 coordinate system parameters */ |
414 | | /* -------------------------------------------------------------------- */ |
415 | 0 | double padfPrjParams[13]; |
416 | 0 | fetchParams(csyFileName, padfPrjParams); |
417 | |
|
418 | 0 | m_oSRS.Clear(); |
419 | | /* -------------------------------------------------------------------- */ |
420 | | /* Operate on the basis of the projection name. */ |
421 | | /* -------------------------------------------------------------------- */ |
422 | 0 | if (STARTS_WITH_CI(pszProj.c_str(), "LatLon")) |
423 | 0 | { |
424 | | // set datum later |
425 | 0 | } |
426 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Albers EqualArea Conic")) |
427 | 0 | { |
428 | 0 | m_oSRS.SetProjCS("Albers EqualArea Conic"); |
429 | 0 | m_oSRS.SetACEA(padfPrjParams[7], padfPrjParams[8], padfPrjParams[5], |
430 | 0 | padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]); |
431 | 0 | } |
432 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Azimuthal Equidistant")) |
433 | 0 | { |
434 | 0 | m_oSRS.SetProjCS("Azimuthal Equidistant"); |
435 | 0 | m_oSRS.SetAE(padfPrjParams[5], padfPrjParams[6], padfPrjParams[3], |
436 | 0 | padfPrjParams[4]); |
437 | 0 | } |
438 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Central Cylindrical")) |
439 | 0 | { |
440 | | // Use Central Parallel for dfStdP1 |
441 | | // padfPrjParams[5] is always to zero |
442 | 0 | m_oSRS.SetProjCS("Central Cylindrical"); |
443 | 0 | m_oSRS.SetCEA(padfPrjParams[5], padfPrjParams[6], padfPrjParams[3], |
444 | 0 | padfPrjParams[4]); |
445 | 0 | } |
446 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Cassini")) |
447 | 0 | { |
448 | | // Use Latitude_Of_True_Scale for dfCenterLat |
449 | | // Scale Factor 1.0 should always be defined |
450 | 0 | m_oSRS.SetProjCS("Cassini"); |
451 | 0 | m_oSRS.SetCS(padfPrjParams[10], padfPrjParams[6], padfPrjParams[3], |
452 | 0 | padfPrjParams[4]); |
453 | 0 | } |
454 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "DutchRD")) |
455 | 0 | { |
456 | 0 | m_oSRS.SetProjCS("DutchRD"); |
457 | 0 | m_oSRS.SetStereographic(52.156160556, 5.387638889, 0.9999079, 155000, |
458 | 0 | 463000); |
459 | 0 | } |
460 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Equidistant Conic")) |
461 | 0 | { |
462 | 0 | m_oSRS.SetProjCS("Equidistant Conic"); |
463 | 0 | m_oSRS.SetEC(padfPrjParams[7], padfPrjParams[8], padfPrjParams[5], |
464 | 0 | padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]); |
465 | 0 | } |
466 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Gauss-Krueger Germany")) |
467 | 0 | { |
468 | | // FalseNorthing and CenterLat are always set to 0 |
469 | | // Scale 1.0 is defined |
470 | | // FalseEasting and CentralMeridian are defined by the selected zone |
471 | 0 | mapTMParams("Gauss-Krueger Germany", padfPrjParams[11], |
472 | 0 | padfPrjParams[3], padfPrjParams[6]); |
473 | 0 | m_oSRS.SetProjCS("Gauss-Krueger Germany"); |
474 | 0 | m_oSRS.SetTM(0, padfPrjParams[6], 1.0, padfPrjParams[3], 0); |
475 | 0 | } |
476 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Gauss-Boaga Italy")) |
477 | 0 | { |
478 | | // FalseNorthing and CenterLat are always set to 0 |
479 | | // Scale 0.9996 is defined |
480 | | // FalseEasting and CentralMeridian are defined by the selected zone |
481 | 0 | mapTMParams("Gauss-Boaga Italy", padfPrjParams[11], padfPrjParams[3], |
482 | 0 | padfPrjParams[6]); |
483 | 0 | m_oSRS.SetProjCS("Gauss-Boaga Italy"); |
484 | 0 | m_oSRS.SetTM(0, padfPrjParams[6], 0.9996, padfPrjParams[3], 0); |
485 | 0 | } |
486 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Gauss Colombia")) |
487 | 0 | { |
488 | | // 1000000 used for FalseNorthing and FalseEasting |
489 | | // 1.0 used for scale |
490 | | // CenterLat is defined 45.1609259259259 |
491 | | // CentralMeridian is defined by the selected zone |
492 | 0 | mapTMParams("Gauss Colombia", padfPrjParams[11], padfPrjParams[3], |
493 | 0 | padfPrjParams[6]); |
494 | 0 | m_oSRS.SetProjCS("Gauss Colombia"); |
495 | 0 | m_oSRS.SetTM(45.1609259259259, padfPrjParams[6], 1.0, 1000000, 1000000); |
496 | 0 | } |
497 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Gnomonic")) |
498 | 0 | { |
499 | 0 | m_oSRS.SetProjCS("Gnomonic"); |
500 | 0 | m_oSRS.SetGnomonic(padfPrjParams[5], padfPrjParams[6], padfPrjParams[3], |
501 | 0 | padfPrjParams[4]); |
502 | 0 | } |
503 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Lambert Conformal Conic")) |
504 | 0 | { |
505 | | // should use 1.0 for scale factor in Ilwis definition |
506 | 0 | m_oSRS.SetProjCS("Lambert Conformal Conic"); |
507 | 0 | m_oSRS.SetLCC(padfPrjParams[7], padfPrjParams[8], padfPrjParams[5], |
508 | 0 | padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]); |
509 | 0 | } |
510 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Lambert Cylind EqualArea")) |
511 | 0 | { |
512 | | // Latitude_Of_True_Scale used for dfStdP1 ? |
513 | 0 | m_oSRS.SetProjCS("Lambert Conformal Conic"); |
514 | 0 | m_oSRS.SetCEA(padfPrjParams[10], padfPrjParams[6], padfPrjParams[3], |
515 | 0 | padfPrjParams[4]); |
516 | 0 | } |
517 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Mercator")) |
518 | 0 | { |
519 | | // use 0 for CenterLat, scale is computed from the |
520 | | // Latitude_Of_True_Scale |
521 | 0 | scaleFromLATTS(pszEllips, padfPrjParams[10], padfPrjParams[9]); |
522 | 0 | m_oSRS.SetProjCS("Mercator"); |
523 | 0 | m_oSRS.SetMercator(0, padfPrjParams[6], padfPrjParams[9], |
524 | 0 | padfPrjParams[3], padfPrjParams[4]); |
525 | 0 | } |
526 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Miller")) |
527 | 0 | { |
528 | | // use 0 for CenterLat |
529 | 0 | m_oSRS.SetProjCS("Miller"); |
530 | 0 | m_oSRS.SetMC(0, padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]); |
531 | 0 | } |
532 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Mollweide")) |
533 | 0 | { |
534 | 0 | m_oSRS.SetProjCS("Mollweide"); |
535 | 0 | m_oSRS.SetMollweide(padfPrjParams[6], padfPrjParams[3], |
536 | 0 | padfPrjParams[4]); |
537 | 0 | } |
538 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Orthographic")) |
539 | 0 | { |
540 | 0 | m_oSRS.SetProjCS("Orthographic"); |
541 | 0 | m_oSRS.SetOrthographic(padfPrjParams[5], padfPrjParams[6], |
542 | 0 | padfPrjParams[3], padfPrjParams[4]); |
543 | 0 | } |
544 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Plate Carree") || |
545 | 0 | STARTS_WITH_CI(pszProj.c_str(), "Plate Rectangle")) |
546 | 0 | { |
547 | | // set 0.0 for CenterLat for Plate Carree projection |
548 | | // skip Latitude_Of_True_Scale for Plate Rectangle projection definition |
549 | 0 | m_oSRS.SetProjCS(pszProj.c_str()); |
550 | 0 | m_oSRS.SetEquirectangular(padfPrjParams[5], padfPrjParams[6], |
551 | 0 | padfPrjParams[3], padfPrjParams[4]); |
552 | 0 | } |
553 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "PolyConic")) |
554 | 0 | { |
555 | | // skip scale factor |
556 | 0 | m_oSRS.SetProjCS("PolyConic"); |
557 | 0 | m_oSRS.SetPolyconic(padfPrjParams[5], padfPrjParams[6], |
558 | 0 | padfPrjParams[3], padfPrjParams[4]); |
559 | 0 | } |
560 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Robinson")) |
561 | 0 | { |
562 | 0 | m_oSRS.SetProjCS("Robinson"); |
563 | 0 | m_oSRS.SetRobinson(padfPrjParams[6], padfPrjParams[3], |
564 | 0 | padfPrjParams[4]); |
565 | 0 | } |
566 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Sinusoidal")) |
567 | 0 | { |
568 | 0 | m_oSRS.SetProjCS("Sinusoidal"); |
569 | 0 | m_oSRS.SetSinusoidal(padfPrjParams[6], padfPrjParams[3], |
570 | 0 | padfPrjParams[4]); |
571 | 0 | } |
572 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Stereographic")) |
573 | 0 | { |
574 | 0 | m_oSRS.SetProjCS("Stereographic"); |
575 | 0 | m_oSRS.SetStereographic(padfPrjParams[5], padfPrjParams[6], |
576 | 0 | padfPrjParams[9], padfPrjParams[3], |
577 | 0 | padfPrjParams[4]); |
578 | 0 | } |
579 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "Transverse Mercator")) |
580 | 0 | { |
581 | 0 | m_oSRS.SetProjCS("Transverse Mercator"); |
582 | 0 | m_oSRS.SetStereographic(padfPrjParams[5], padfPrjParams[6], |
583 | 0 | padfPrjParams[9], padfPrjParams[3], |
584 | 0 | padfPrjParams[4]); |
585 | 0 | } |
586 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "UTM")) |
587 | 0 | { |
588 | 0 | std::string pszNH = |
589 | 0 | ReadElement("Projection", "Northern Hemisphere", csyFileName); |
590 | 0 | m_oSRS.SetProjCS("UTM"); |
591 | 0 | if (STARTS_WITH_CI(pszNH.c_str(), "Yes")) |
592 | 0 | m_oSRS.SetUTM((int)padfPrjParams[11], 1); |
593 | 0 | else |
594 | 0 | m_oSRS.SetUTM((int)padfPrjParams[11], 0); |
595 | 0 | } |
596 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "VanderGrinten")) |
597 | 0 | { |
598 | 0 | m_oSRS.SetVDG(padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]); |
599 | 0 | } |
600 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "GeoStationary Satellite")) |
601 | 0 | { |
602 | 0 | m_oSRS.SetGEOS(padfPrjParams[6], padfPrjParams[12], padfPrjParams[3], |
603 | 0 | padfPrjParams[4]); |
604 | 0 | } |
605 | 0 | else if (STARTS_WITH_CI(pszProj.c_str(), "MSG Perspective")) |
606 | 0 | { |
607 | 0 | m_oSRS.SetGEOS(padfPrjParams[6], padfPrjParams[12], padfPrjParams[3], |
608 | 0 | padfPrjParams[4]); |
609 | 0 | } |
610 | 0 | else |
611 | 0 | { |
612 | 0 | m_oSRS.SetLocalCS(pszProj.c_str()); |
613 | 0 | } |
614 | | /* -------------------------------------------------------------------- */ |
615 | | /* Try to translate the datum/spheroid. */ |
616 | | /* -------------------------------------------------------------------- */ |
617 | |
|
618 | 0 | if (!m_oSRS.IsLocal()) |
619 | 0 | { |
620 | 0 | const IlwisDatums *piwDatum = iwDatums; |
621 | | |
622 | | // Search for matching datum |
623 | 0 | while (piwDatum->pszIlwisDatum) |
624 | 0 | { |
625 | 0 | if (EQUALN(pszDatum.c_str(), piwDatum->pszIlwisDatum, |
626 | 0 | strlen(piwDatum->pszIlwisDatum))) |
627 | 0 | { |
628 | 0 | OGRSpatialReference oOGR; |
629 | 0 | oOGR.importFromEPSG(piwDatum->nEPSGCode); |
630 | 0 | m_oSRS.CopyGeogCSFrom(&oOGR); |
631 | 0 | break; |
632 | 0 | } |
633 | 0 | piwDatum++; |
634 | 0 | } // End of searching for matching datum. |
635 | | |
636 | | /* -------------------------------------------------------------------- |
637 | | */ |
638 | | /* If no matching for datum definition, fetch info about an */ |
639 | | /* ellipsoid. semi major axis is always returned in meters */ |
640 | | /* -------------------------------------------------------------------- |
641 | | */ |
642 | 0 | const IlwisEllips *piwEllips = iwEllips; |
643 | 0 | if (pszEllips.empty()) |
644 | 0 | pszEllips = "Sphere"; |
645 | 0 | if (!piwDatum->pszIlwisDatum) |
646 | 0 | { |
647 | 0 | while (piwEllips->pszIlwisEllips) |
648 | 0 | { |
649 | 0 | if (EQUALN(pszEllips.c_str(), piwEllips->pszIlwisEllips, |
650 | 0 | strlen(piwEllips->pszIlwisEllips))) |
651 | 0 | { |
652 | 0 | double dfSemiMajor = piwEllips->semiMajor; |
653 | 0 | if (STARTS_WITH_CI(pszEllips.c_str(), "Sphere") && |
654 | 0 | padfPrjParams[0] != 0) |
655 | 0 | { |
656 | 0 | dfSemiMajor = padfPrjParams[0]; |
657 | 0 | } |
658 | 0 | m_oSRS.SetGeogCS( |
659 | 0 | CPLSPrintf("Unknown datum based upon the %s ellipsoid", |
660 | 0 | piwEllips->pszIlwisEllips), |
661 | 0 | CPLSPrintf("Not specified (based on %s spheroid)", |
662 | 0 | piwEllips->pszIlwisEllips), |
663 | 0 | piwEllips->pszIlwisEllips, dfSemiMajor, |
664 | 0 | piwEllips->invFlattening, nullptr, 0.0, nullptr, 0.0); |
665 | 0 | m_oSRS.SetAuthority("SPHEROID", "EPSG", |
666 | 0 | piwEllips->nEPSGCode); |
667 | |
|
668 | 0 | break; |
669 | 0 | } |
670 | 0 | piwEllips++; |
671 | 0 | } // end of searching for matching ellipsoid |
672 | 0 | } |
673 | | |
674 | | /* -------------------------------------------------------------------- |
675 | | */ |
676 | | /* If no matching for ellipsoid definition, fetch info about an */ |
677 | | /* user defined ellipsoid. If cannot find, default to WGS 84 */ |
678 | | /* -------------------------------------------------------------------- |
679 | | */ |
680 | 0 | if (!piwEllips->pszIlwisEllips) |
681 | 0 | { |
682 | |
|
683 | 0 | if (STARTS_WITH_CI(pszEllips.c_str(), "User Defined")) |
684 | 0 | { |
685 | 0 | m_oSRS.SetGeogCS( |
686 | 0 | "Unknown datum based upon the custom ellipsoid", |
687 | 0 | "Not specified (based on custom ellipsoid)", |
688 | 0 | "Custom ellipsoid", padfPrjParams[0], padfPrjParams[2], |
689 | 0 | nullptr, 0, nullptr, 0); |
690 | 0 | } |
691 | 0 | else |
692 | 0 | { |
693 | | // if cannot find the user defined ellips, default to WGS84 |
694 | 0 | m_oSRS.SetWellKnownGeogCS("WGS84"); |
695 | 0 | } |
696 | 0 | } |
697 | 0 | } // end of if ( !IsLocal() ) |
698 | | |
699 | | /* -------------------------------------------------------------------- */ |
700 | | /* Units translation */ |
701 | | /* -------------------------------------------------------------------- */ |
702 | 0 | if (m_oSRS.IsLocal() || m_oSRS.IsProjected()) |
703 | 0 | { |
704 | 0 | m_oSRS.SetLinearUnits(SRS_UL_METER, 1.0); |
705 | 0 | } |
706 | |
|
707 | 0 | return CE_None; |
708 | 0 | } |
709 | | |
710 | | static void WriteFalseEastNorth(const std::string &csFileName, |
711 | | const OGRSpatialReference &oSRS) |
712 | 0 | { |
713 | 0 | WriteElement("Projection", ILW_False_Easting, csFileName, |
714 | 0 | oSRS.GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0)); |
715 | 0 | WriteElement("Projection", ILW_False_Northing, csFileName, |
716 | 0 | oSRS.GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0)); |
717 | 0 | } |
718 | | |
719 | | static void WriteProjectionName(const std::string &csFileName, |
720 | | const std::string &stProjection) |
721 | 0 | { |
722 | 0 | WriteElement("CoordSystem", "Type", csFileName, "Projection"); |
723 | 0 | WriteElement("CoordSystem", "Projection", csFileName, stProjection); |
724 | 0 | } |
725 | | |
726 | | static void WriteUTM(const std::string &csFileName, |
727 | | const OGRSpatialReference &oSRS) |
728 | 0 | { |
729 | 0 | int bNorth; |
730 | |
|
731 | 0 | int nZone = oSRS.GetUTMZone(&bNorth); |
732 | 0 | WriteElement("CoordSystem", "Type", csFileName, "Projection"); |
733 | 0 | WriteElement("CoordSystem", "Projection", csFileName, "UTM"); |
734 | 0 | if (bNorth) |
735 | 0 | WriteElement("Projection", "Northern Hemisphere", csFileName, "Yes"); |
736 | 0 | else |
737 | 0 | WriteElement("Projection", "Northern Hemisphere", csFileName, "No"); |
738 | 0 | WriteElement("Projection", "Zone", csFileName, nZone); |
739 | 0 | } |
740 | | |
741 | | static void WriteAlbersConicEqualArea(const std::string &csFileName, |
742 | | const OGRSpatialReference &oSRS) |
743 | 0 | { |
744 | 0 | WriteProjectionName(csFileName, "Albers EqualArea Conic"); |
745 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
746 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
747 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
748 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
749 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
750 | 0 | WriteElement("Projection", ILW_Standard_Parallel_1, csFileName, |
751 | 0 | oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0)); |
752 | 0 | WriteElement("Projection", ILW_Standard_Parallel_2, csFileName, |
753 | 0 | oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0)); |
754 | 0 | } |
755 | | |
756 | | static void WriteAzimuthalEquidistant(const std::string &csFileName, |
757 | | const OGRSpatialReference &oSRS) |
758 | 0 | { |
759 | 0 | WriteProjectionName(csFileName, "Azimuthal Equidistant"); |
760 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
761 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
762 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
763 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
764 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
765 | 0 | WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000"); |
766 | 0 | } |
767 | | |
768 | | static void WriteCylindricalEqualArea(const std::string &csFileName, |
769 | | const OGRSpatialReference &oSRS) |
770 | 0 | { |
771 | 0 | WriteProjectionName(csFileName, "Central Cylindrical"); |
772 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
773 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
774 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
775 | 0 | } |
776 | | |
777 | | static void WriteCassiniSoldner(const std::string &csFileName, |
778 | | const OGRSpatialReference &oSRS) |
779 | 0 | { |
780 | 0 | WriteProjectionName(csFileName, "Cassini"); |
781 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
782 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
783 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
784 | 0 | WriteElement("Projection", ILW_Latitude_True_Scale, csFileName, |
785 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
786 | 0 | WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000"); |
787 | 0 | } |
788 | | |
789 | | static void WriteStereographic(const std::string &csFileName, |
790 | | const OGRSpatialReference &oSRS) |
791 | 0 | { |
792 | 0 | WriteProjectionName(csFileName, "Stereographic"); |
793 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
794 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
795 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
796 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
797 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
798 | 0 | WriteElement("Projection", ILW_Scale_Factor, csFileName, |
799 | 0 | oSRS.GetNormProjParm(SRS_PP_SCALE_FACTOR, 0.0)); |
800 | 0 | } |
801 | | |
802 | | static void WriteEquidistantConic(const std::string &csFileName, |
803 | | const OGRSpatialReference &oSRS) |
804 | 0 | { |
805 | 0 | WriteProjectionName(csFileName, "Equidistant Conic"); |
806 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
807 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
808 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
809 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
810 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
811 | 0 | WriteElement("Projection", ILW_Standard_Parallel_1, csFileName, |
812 | 0 | oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0)); |
813 | 0 | WriteElement("Projection", ILW_Standard_Parallel_2, csFileName, |
814 | 0 | oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0)); |
815 | 0 | } |
816 | | |
817 | | static void WriteTransverseMercator(const std::string &csFileName, |
818 | | const OGRSpatialReference &oSRS) |
819 | 0 | { |
820 | 0 | WriteProjectionName(csFileName, "Transverse Mercator"); |
821 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
822 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
823 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
824 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
825 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
826 | 0 | WriteElement("Projection", ILW_Scale_Factor, csFileName, |
827 | 0 | oSRS.GetNormProjParm(SRS_PP_SCALE_FACTOR, 0.0)); |
828 | 0 | } |
829 | | |
830 | | static void WriteGnomonic(const std::string &csFileName, |
831 | | const OGRSpatialReference &oSRS) |
832 | 0 | { |
833 | 0 | WriteProjectionName(csFileName, "Gnomonic"); |
834 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
835 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
836 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
837 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
838 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
839 | 0 | } |
840 | | |
841 | | static void WriteLambertConformalConic(const std::string &csFileName, |
842 | | const OGRSpatialReference &oSRS) |
843 | 0 | { |
844 | 0 | WriteProjectionName(csFileName, "Lambert Conformal Conic"); |
845 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
846 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
847 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
848 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
849 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
850 | 0 | WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000"); |
851 | 0 | } |
852 | | |
853 | | static void WriteLambertConformalConic2SP(const std::string &csFileName, |
854 | | const OGRSpatialReference &oSRS) |
855 | 0 | { |
856 | 0 | WriteProjectionName(csFileName, "Lambert Conformal Conic"); |
857 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
858 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
859 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
860 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
861 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
862 | 0 | WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000"); |
863 | 0 | WriteElement("Projection", ILW_Standard_Parallel_1, csFileName, |
864 | 0 | oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0)); |
865 | 0 | WriteElement("Projection", ILW_Standard_Parallel_2, csFileName, |
866 | 0 | oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0)); |
867 | 0 | } |
868 | | |
869 | | static void WriteLambertAzimuthalEqualArea(const std::string &csFileName, |
870 | | const OGRSpatialReference &oSRS) |
871 | 0 | { |
872 | 0 | WriteProjectionName(csFileName, "Lambert Azimuthal EqualArea"); |
873 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
874 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
875 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
876 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
877 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
878 | 0 | } |
879 | | |
880 | | static void WriteMercator_1SP(const std::string &csFileName, |
881 | | const OGRSpatialReference &oSRS) |
882 | 0 | { |
883 | 0 | WriteProjectionName(csFileName, "Mercator"); |
884 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
885 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
886 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
887 | 0 | WriteElement("Projection", ILW_Latitude_True_Scale, csFileName, |
888 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
889 | 0 | } |
890 | | |
891 | | static void WriteMillerCylindrical(const std::string &csFileName, |
892 | | const OGRSpatialReference &oSRS) |
893 | 0 | { |
894 | 0 | WriteProjectionName(csFileName, "Miller"); |
895 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
896 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
897 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
898 | 0 | } |
899 | | |
900 | | static void WriteMolleweide(const std::string &csFileName, |
901 | | const OGRSpatialReference &oSRS) |
902 | 0 | { |
903 | 0 | WriteProjectionName(csFileName, "Mollweide"); |
904 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
905 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
906 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
907 | 0 | } |
908 | | |
909 | | static void WriteOrthographic(const std::string &csFileName, |
910 | | const OGRSpatialReference &oSRS) |
911 | 0 | { |
912 | 0 | WriteProjectionName(csFileName, "Orthographic"); |
913 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
914 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
915 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
916 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
917 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
918 | 0 | } |
919 | | |
920 | | static void WritePlateRectangle(const std::string &csFileName, |
921 | | const OGRSpatialReference &oSRS) |
922 | 0 | { |
923 | 0 | WriteProjectionName(csFileName, "Plate Rectangle"); |
924 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
925 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
926 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
927 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
928 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
929 | 0 | WriteElement("Projection", ILW_Latitude_True_Scale, csFileName, |
930 | 0 | "0.0000000000"); |
931 | 0 | } |
932 | | |
933 | | static void WritePolyConic(const std::string &csFileName, |
934 | | const OGRSpatialReference &oSRS) |
935 | 0 | { |
936 | 0 | WriteProjectionName(csFileName, "PolyConic"); |
937 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
938 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
939 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
940 | 0 | WriteElement("Projection", ILW_Central_Parallel, csFileName, |
941 | 0 | oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0)); |
942 | 0 | WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000"); |
943 | 0 | } |
944 | | |
945 | | static void WriteRobinson(const std::string &csFileName, |
946 | | const OGRSpatialReference &oSRS) |
947 | 0 | { |
948 | 0 | WriteProjectionName(csFileName, "Robinson"); |
949 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
950 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
951 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
952 | 0 | } |
953 | | |
954 | | static void WriteSinusoidal(const std::string &csFileName, |
955 | | const OGRSpatialReference &oSRS) |
956 | 0 | { |
957 | 0 | WriteProjectionName(csFileName, "Sinusoidal"); |
958 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
959 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
960 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
961 | 0 | } |
962 | | |
963 | | static void WriteVanderGrinten(const std::string &csFileName, |
964 | | const OGRSpatialReference &oSRS) |
965 | 0 | { |
966 | 0 | WriteProjectionName(csFileName, "VanderGrinten"); |
967 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
968 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
969 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
970 | 0 | } |
971 | | |
972 | | static void WriteGeoStatSat(const std::string &csFileName, |
973 | | const OGRSpatialReference &oSRS) |
974 | 0 | { |
975 | 0 | WriteProjectionName(csFileName, "GeoStationary Satellite"); |
976 | 0 | WriteFalseEastNorth(csFileName, oSRS); |
977 | 0 | WriteElement("Projection", ILW_Central_Meridian, csFileName, |
978 | 0 | oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0)); |
979 | 0 | WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000"); |
980 | 0 | WriteElement("Projection", ILW_Height_Persp_Center, csFileName, |
981 | 0 | oSRS.GetNormProjParm(SRS_PP_SATELLITE_HEIGHT, 35785831.0)); |
982 | 0 | } |
983 | | |
984 | | /************************************************************************/ |
985 | | /* WriteProjection() */ |
986 | | /************************************************************************/ |
987 | | /** |
988 | | * Export coordinate system in ILWIS projection definition. |
989 | | * |
990 | | * Converts the loaded coordinate reference system into ILWIS projection |
991 | | * definition to the extent possible. |
992 | | */ |
993 | | CPLErr ILWISDataset::WriteProjection() |
994 | | |
995 | 0 | { |
996 | 0 | OGRSpatialReference *poGeogSRS = nullptr; |
997 | |
|
998 | 0 | std::string csFileName = CPLResetExtensionSafe(osFileName, "csy"); |
999 | 0 | std::string pszBaseName = std::string(CPLGetBasenameSafe(osFileName)); |
1000 | | // std::string pszPath = std::string(CPLGetPathSafe( osFileName )); |
1001 | 0 | const bool bHaveSRS = !m_oSRS.IsEmpty(); |
1002 | |
|
1003 | 0 | const IlwisDatums *piwDatum = iwDatums; |
1004 | | // std::string pszEllips; |
1005 | 0 | std::string osDatum; |
1006 | | // std::string pszProj; |
1007 | | |
1008 | | /* -------------------------------------------------------------------- */ |
1009 | | /* Collect datum/ellips information. */ |
1010 | | /* -------------------------------------------------------------------- */ |
1011 | 0 | if (bHaveSRS) |
1012 | 0 | { |
1013 | 0 | poGeogSRS = m_oSRS.CloneGeogCS(); |
1014 | 0 | } |
1015 | |
|
1016 | 0 | std::string grFileName = CPLResetExtensionSafe(osFileName, "grf"); |
1017 | 0 | std::string csy; |
1018 | 0 | if (poGeogSRS) |
1019 | 0 | { |
1020 | 0 | csy = pszBaseName + ".csy"; |
1021 | |
|
1022 | 0 | WriteElement("Ilwis", "Type", csFileName, "CoordSystem"); |
1023 | 0 | const char *pszDatum = poGeogSRS->GetAttrValue("GEOGCS|DATUM"); |
1024 | 0 | if (pszDatum) |
1025 | 0 | osDatum = pszDatum; |
1026 | | |
1027 | | /* WKT to ILWIS translation */ |
1028 | 0 | while (piwDatum->pszWKTDatum) |
1029 | 0 | { |
1030 | 0 | if (EQUALN(osDatum.c_str(), piwDatum->pszWKTDatum, |
1031 | 0 | strlen(piwDatum->pszWKTDatum))) |
1032 | 0 | { |
1033 | 0 | WriteElement("CoordSystem", "Datum", csFileName, |
1034 | 0 | piwDatum->pszIlwisDatum); |
1035 | 0 | break; |
1036 | 0 | } |
1037 | 0 | piwDatum++; |
1038 | 0 | } // End of searching for matching datum. |
1039 | 0 | WriteElement("CoordSystem", "Width", csFileName, 28); |
1040 | | // pszEllips = poGeogSRS->GetAttrValue( "GEOGCS|DATUM|SPHEROID" ); |
1041 | 0 | double a = poGeogSRS->GetSemiMajor(); |
1042 | 0 | /* b = */ poGeogSRS->GetSemiMinor(); |
1043 | 0 | double f = poGeogSRS->GetInvFlattening(); |
1044 | 0 | WriteElement("CoordSystem", "Ellipsoid", csFileName, "User Defined"); |
1045 | 0 | WriteElement("Ellipsoid", "a", csFileName, a); |
1046 | 0 | WriteElement("Ellipsoid", "1/f", csFileName, f); |
1047 | 0 | } |
1048 | 0 | else |
1049 | 0 | csy = "unknown.csy"; |
1050 | | |
1051 | | /* -------------------------------------------------------------------- */ |
1052 | | /* Determine to write a geo-referencing file for the dataset to create */ |
1053 | | /* -------------------------------------------------------------------- */ |
1054 | 0 | if (adfGeoTransform[0] != 0.0 || adfGeoTransform[1] != 1.0 || |
1055 | 0 | adfGeoTransform[2] != 0.0 || adfGeoTransform[3] != 0.0 || |
1056 | 0 | adfGeoTransform[4] != 0.0 || fabs(adfGeoTransform[5]) != 1.0) |
1057 | 0 | WriteElement("GeoRef", "CoordSystem", grFileName, csy); |
1058 | | |
1059 | | /* -------------------------------------------------------------------- */ |
1060 | | /* Recognise various projections. */ |
1061 | | /* -------------------------------------------------------------------- */ |
1062 | 0 | const char *pszProjName = nullptr; |
1063 | |
|
1064 | 0 | if (bHaveSRS) |
1065 | 0 | pszProjName = m_oSRS.GetAttrValue("PROJCS|PROJECTION"); |
1066 | |
|
1067 | 0 | if (pszProjName == nullptr) |
1068 | 0 | { |
1069 | 0 | if (bHaveSRS && m_oSRS.IsGeographic()) |
1070 | 0 | { |
1071 | 0 | WriteElement("CoordSystem", "Type", csFileName, "LatLon"); |
1072 | 0 | } |
1073 | 0 | } |
1074 | 0 | else if (m_oSRS.GetUTMZone(nullptr) != 0) |
1075 | 0 | { |
1076 | 0 | WriteUTM(csFileName, m_oSRS); |
1077 | 0 | } |
1078 | 0 | else if (EQUAL(pszProjName, SRS_PT_ALBERS_CONIC_EQUAL_AREA)) |
1079 | 0 | { |
1080 | 0 | WriteAlbersConicEqualArea(csFileName, m_oSRS); |
1081 | 0 | } |
1082 | 0 | else if (EQUAL(pszProjName, SRS_PT_AZIMUTHAL_EQUIDISTANT)) |
1083 | 0 | { |
1084 | 0 | WriteAzimuthalEquidistant(csFileName, m_oSRS); |
1085 | 0 | } |
1086 | 0 | else if (EQUAL(pszProjName, SRS_PT_CYLINDRICAL_EQUAL_AREA)) |
1087 | 0 | { |
1088 | 0 | WriteCylindricalEqualArea(csFileName, m_oSRS); |
1089 | 0 | } |
1090 | 0 | else if (EQUAL(pszProjName, SRS_PT_CASSINI_SOLDNER)) |
1091 | 0 | { |
1092 | 0 | WriteCassiniSoldner(csFileName, m_oSRS); |
1093 | 0 | } |
1094 | 0 | else if (EQUAL(pszProjName, SRS_PT_STEREOGRAPHIC)) |
1095 | 0 | { |
1096 | 0 | WriteStereographic(csFileName, m_oSRS); |
1097 | 0 | } |
1098 | 0 | else if (EQUAL(pszProjName, SRS_PT_EQUIDISTANT_CONIC)) |
1099 | 0 | { |
1100 | 0 | WriteEquidistantConic(csFileName, m_oSRS); |
1101 | 0 | } |
1102 | 0 | else if (EQUAL(pszProjName, SRS_PT_TRANSVERSE_MERCATOR)) |
1103 | 0 | { |
1104 | 0 | WriteTransverseMercator(csFileName, m_oSRS); |
1105 | 0 | } |
1106 | 0 | else if (EQUAL(pszProjName, SRS_PT_GNOMONIC)) |
1107 | 0 | { |
1108 | 0 | WriteGnomonic(csFileName, m_oSRS); |
1109 | 0 | } |
1110 | 0 | else if (EQUAL(pszProjName, "Lambert_Conformal_Conic")) |
1111 | 0 | { |
1112 | 0 | WriteLambertConformalConic(csFileName, m_oSRS); |
1113 | 0 | } |
1114 | 0 | else if (EQUAL(pszProjName, SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP)) |
1115 | 0 | { |
1116 | 0 | WriteLambertConformalConic(csFileName, m_oSRS); |
1117 | 0 | } |
1118 | 0 | else if (EQUAL(pszProjName, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP)) |
1119 | 0 | { |
1120 | 0 | WriteLambertConformalConic2SP(csFileName, m_oSRS); |
1121 | 0 | } |
1122 | 0 | else if (EQUAL(pszProjName, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA)) |
1123 | 0 | { |
1124 | 0 | WriteLambertAzimuthalEqualArea(csFileName, m_oSRS); |
1125 | 0 | } |
1126 | 0 | else if (EQUAL(pszProjName, SRS_PT_MERCATOR_1SP)) |
1127 | 0 | { |
1128 | 0 | WriteMercator_1SP(csFileName, m_oSRS); |
1129 | 0 | } |
1130 | 0 | else if (EQUAL(pszProjName, SRS_PT_MILLER_CYLINDRICAL)) |
1131 | 0 | { |
1132 | 0 | WriteMillerCylindrical(csFileName, m_oSRS); |
1133 | 0 | } |
1134 | 0 | else if (EQUAL(pszProjName, SRS_PT_MOLLWEIDE)) |
1135 | 0 | { |
1136 | 0 | WriteMolleweide(csFileName, m_oSRS); |
1137 | 0 | } |
1138 | 0 | else if (EQUAL(pszProjName, SRS_PT_ORTHOGRAPHIC)) |
1139 | 0 | { |
1140 | 0 | WriteOrthographic(csFileName, m_oSRS); |
1141 | 0 | } |
1142 | 0 | else if (EQUAL(pszProjName, SRS_PT_EQUIRECTANGULAR)) |
1143 | 0 | { |
1144 | 0 | WritePlateRectangle(csFileName, m_oSRS); |
1145 | 0 | } |
1146 | 0 | else if (EQUAL(pszProjName, SRS_PT_POLYCONIC)) |
1147 | 0 | { |
1148 | 0 | WritePolyConic(csFileName, m_oSRS); |
1149 | 0 | } |
1150 | 0 | else if (EQUAL(pszProjName, SRS_PT_ROBINSON)) |
1151 | 0 | { |
1152 | 0 | WriteRobinson(csFileName, m_oSRS); |
1153 | 0 | } |
1154 | 0 | else if (EQUAL(pszProjName, SRS_PT_SINUSOIDAL)) |
1155 | 0 | { |
1156 | 0 | WriteSinusoidal(csFileName, m_oSRS); |
1157 | 0 | } |
1158 | 0 | else if (EQUAL(pszProjName, SRS_PT_VANDERGRINTEN)) |
1159 | 0 | { |
1160 | 0 | WriteVanderGrinten(csFileName, m_oSRS); |
1161 | 0 | } |
1162 | 0 | else if (EQUAL(pszProjName, SRS_PT_GEOSTATIONARY_SATELLITE)) |
1163 | 0 | { |
1164 | 0 | WriteGeoStatSat(csFileName, m_oSRS); |
1165 | 0 | } |
1166 | 0 | else |
1167 | 0 | { |
1168 | | // Projection unknown by ILWIS |
1169 | 0 | } |
1170 | | |
1171 | | /* -------------------------------------------------------------------- */ |
1172 | | /* Cleanup */ |
1173 | | /* -------------------------------------------------------------------- */ |
1174 | 0 | if (poGeogSRS != nullptr) |
1175 | 0 | delete poGeogSRS; |
1176 | |
|
1177 | 0 | return CE_None; |
1178 | 0 | } |
1179 | | |
1180 | | } // namespace GDAL |