Line data Source code
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 58 : static double ReadPrjParams(const std::string §ion,
236 : const std::string &entry,
237 : const std::string &filename)
238 : {
239 116 : std::string str = ReadElement(section, entry, filename);
240 : // string str="";
241 58 : if (!str.empty())
242 13 : return CPLAtof(str.c_str());
243 :
244 45 : return 0.0;
245 : }
246 :
247 5 : static int fetchParams(const std::string &csyFileName, double *padfPrjParams)
248 : {
249 : // Fill all projection parameters with zero
250 70 : for (int i = 0; i < 13; i++)
251 65 : padfPrjParams[i] = 0.0;
252 :
253 : // std::string pszProj = ReadElement("CoordSystem", "Projection",
254 : // csyFileName);
255 : std::string pszEllips =
256 10 : ReadElement("CoordSystem", "Ellipsoid", csyFileName);
257 :
258 : // fetch info about a custom ellipsoid
259 5 : if (STARTS_WITH_CI(pszEllips.c_str(), "User Defined"))
260 : {
261 4 : padfPrjParams[0] = ReadPrjParams("Ellipsoid", "a", csyFileName);
262 4 : padfPrjParams[2] = ReadPrjParams("Ellipsoid", "1/f", csyFileName);
263 : }
264 1 : else if (STARTS_WITH_CI(pszEllips.c_str(), "Sphere"))
265 : {
266 0 : padfPrjParams[0] =
267 0 : ReadPrjParams("CoordSystem", "Sphere Radius", csyFileName);
268 : }
269 :
270 10 : padfPrjParams[3] =
271 5 : ReadPrjParams("Projection", "False Easting", csyFileName);
272 10 : padfPrjParams[4] =
273 5 : ReadPrjParams("Projection", "False Northing", csyFileName);
274 :
275 10 : padfPrjParams[5] =
276 5 : ReadPrjParams("Projection", "Central Parallel", csyFileName);
277 10 : padfPrjParams[6] =
278 5 : ReadPrjParams("Projection", "Central Meridian", csyFileName);
279 :
280 10 : padfPrjParams[7] =
281 5 : ReadPrjParams("Projection", "Standard Parallel 1", csyFileName);
282 10 : padfPrjParams[8] =
283 5 : ReadPrjParams("Projection", "Standard Parallel 2", csyFileName);
284 :
285 5 : padfPrjParams[9] = ReadPrjParams("Projection", "Scale Factor", csyFileName);
286 10 : padfPrjParams[10] =
287 5 : ReadPrjParams("Projection", "Latitude of True Scale", csyFileName);
288 5 : padfPrjParams[11] = ReadPrjParams("Projection", "Zone", csyFileName);
289 10 : padfPrjParams[12] =
290 5 : ReadPrjParams("Projection", ILW_Height_Persp_Center, csyFileName);
291 :
292 10 : return true;
293 : }
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 0 : static int mapTMParams(const std::string &sProj, double dfZone,
305 : double &dfFalseEasting, double &dfCentralMeridian)
306 : {
307 0 : if (STARTS_WITH_CI(sProj.c_str(), "Gauss-Krueger Germany"))
308 : {
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 : }
313 0 : else if (STARTS_WITH_CI(sProj.c_str(), "Gauss-Boaga Italy"))
314 : {
315 0 : if (dfZone == 1)
316 : {
317 0 : dfCentralMeridian = 9;
318 0 : dfFalseEasting = 1500000;
319 : }
320 0 : else if (dfZone == 2)
321 : {
322 0 : dfCentralMeridian = 15;
323 0 : dfFalseEasting = 2520000;
324 : }
325 : else
326 0 : return false;
327 : }
328 0 : else if (STARTS_WITH_CI(sProj.c_str(), "Gauss Colombia"))
329 : {
330 : // Zone number must be in the range 1 to 4
331 0 : dfCentralMeridian = -77.08097220 + (dfZone - 1) * 3;
332 : }
333 0 : return true;
334 : }
335 :
336 : /************************************************************************/
337 : /* scaleFromLATTS() */
338 : /************************************************************************/
339 : /**
340 : * Compute the scale factor from Latitude_Of_True_Scale parameter.
341 : *
342 : **/
343 0 : static void scaleFromLATTS(const std::string &sEllips, double phits,
344 : double &scale)
345 : {
346 0 : if (STARTS_WITH_CI(sEllips.c_str(), "Sphere"))
347 : {
348 0 : scale = cos(phits);
349 : }
350 : else
351 : {
352 0 : const IlwisEllips *piwEllips = iwEllips;
353 0 : double e2 = 0.0;
354 0 : while (piwEllips->pszIlwisEllips)
355 : {
356 0 : if (EQUALN(sEllips.c_str(), piwEllips->pszIlwisEllips,
357 : strlen(piwEllips->pszIlwisEllips)))
358 : {
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 : }
364 0 : piwEllips++;
365 : }
366 0 : scale = cos(phits) / sqrt(1. - e2 * sin(phits) * sin(phits));
367 : }
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 5 : CPLErr ILWISDataset::ReadProjection(const std::string &csyFileName)
385 : {
386 10 : std::string pszEllips;
387 10 : std::string pszDatum;
388 5 : std::string pszProj;
389 :
390 : // translate ILWIS pre-defined coordinate systems
391 5 : if (STARTS_WITH_CI(csyFileName.c_str(), "latlon.csy"))
392 : {
393 0 : pszProj = "LatLon";
394 0 : pszDatum = "";
395 0 : pszEllips = "Sphere";
396 : }
397 5 : else if (STARTS_WITH_CI(csyFileName.c_str(), "LatlonWGS84.csy"))
398 : {
399 0 : pszProj = "LatLon";
400 0 : pszDatum = "WGS 1984";
401 0 : pszEllips = "WGS 84";
402 : }
403 : else
404 : {
405 5 : pszProj = ReadElement("CoordSystem", "Type", csyFileName);
406 5 : if (!STARTS_WITH_CI(pszProj.c_str(), "LatLon"))
407 5 : pszProj = ReadElement("CoordSystem", "Projection", csyFileName);
408 5 : pszDatum = ReadElement("CoordSystem", "Datum", csyFileName);
409 5 : pszEllips = ReadElement("CoordSystem", "Ellipsoid", csyFileName);
410 : }
411 :
412 : /* -------------------------------------------------------------------- */
413 : /* Fetch array containing 13 coordinate system parameters */
414 : /* -------------------------------------------------------------------- */
415 : double padfPrjParams[13];
416 5 : fetchParams(csyFileName, padfPrjParams);
417 :
418 5 : m_oSRS.Clear();
419 : /* -------------------------------------------------------------------- */
420 : /* Operate on the basis of the projection name. */
421 : /* -------------------------------------------------------------------- */
422 5 : if (STARTS_WITH_CI(pszProj.c_str(), "LatLon"))
423 : {
424 : // set datum later
425 : }
426 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Albers EqualArea Conic"))
427 : {
428 0 : m_oSRS.SetProjCS("Albers EqualArea Conic");
429 0 : m_oSRS.SetACEA(padfPrjParams[7], padfPrjParams[8], padfPrjParams[5],
430 : padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]);
431 : }
432 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Azimuthal Equidistant"))
433 : {
434 0 : m_oSRS.SetProjCS("Azimuthal Equidistant");
435 0 : m_oSRS.SetAE(padfPrjParams[5], padfPrjParams[6], padfPrjParams[3],
436 : padfPrjParams[4]);
437 : }
438 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Central Cylindrical"))
439 : {
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 : padfPrjParams[4]);
445 : }
446 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Cassini"))
447 : {
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 : padfPrjParams[4]);
453 : }
454 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "DutchRD"))
455 : {
456 0 : m_oSRS.SetProjCS("DutchRD");
457 0 : m_oSRS.SetStereographic(52.156160556, 5.387638889, 0.9999079, 155000,
458 : 463000);
459 : }
460 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Equidistant Conic"))
461 : {
462 0 : m_oSRS.SetProjCS("Equidistant Conic");
463 0 : m_oSRS.SetEC(padfPrjParams[7], padfPrjParams[8], padfPrjParams[5],
464 : padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]);
465 : }
466 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Gauss-Krueger Germany"))
467 : {
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 : 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 : }
476 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Gauss-Boaga Italy"))
477 : {
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 : padfPrjParams[6]);
483 0 : m_oSRS.SetProjCS("Gauss-Boaga Italy");
484 0 : m_oSRS.SetTM(0, padfPrjParams[6], 0.9996, padfPrjParams[3], 0);
485 : }
486 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Gauss Colombia"))
487 : {
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 : padfPrjParams[6]);
494 0 : m_oSRS.SetProjCS("Gauss Colombia");
495 0 : m_oSRS.SetTM(45.1609259259259, padfPrjParams[6], 1.0, 1000000, 1000000);
496 : }
497 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Gnomonic"))
498 : {
499 0 : m_oSRS.SetProjCS("Gnomonic");
500 0 : m_oSRS.SetGnomonic(padfPrjParams[5], padfPrjParams[6], padfPrjParams[3],
501 : padfPrjParams[4]);
502 : }
503 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Lambert Conformal Conic"))
504 : {
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 : padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]);
509 : }
510 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Lambert Cylind EqualArea"))
511 : {
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 : padfPrjParams[4]);
516 : }
517 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Mercator"))
518 : {
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 : padfPrjParams[3], padfPrjParams[4]);
525 : }
526 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Miller"))
527 : {
528 : // use 0 for CenterLat
529 0 : m_oSRS.SetProjCS("Miller");
530 0 : m_oSRS.SetMC(0, padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]);
531 : }
532 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Mollweide"))
533 : {
534 0 : m_oSRS.SetProjCS("Mollweide");
535 0 : m_oSRS.SetMollweide(padfPrjParams[6], padfPrjParams[3],
536 : padfPrjParams[4]);
537 : }
538 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Orthographic"))
539 : {
540 0 : m_oSRS.SetProjCS("Orthographic");
541 0 : m_oSRS.SetOrthographic(padfPrjParams[5], padfPrjParams[6],
542 : padfPrjParams[3], padfPrjParams[4]);
543 : }
544 10 : else if (STARTS_WITH_CI(pszProj.c_str(), "Plate Carree") ||
545 5 : STARTS_WITH_CI(pszProj.c_str(), "Plate Rectangle"))
546 : {
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 : padfPrjParams[3], padfPrjParams[4]);
552 : }
553 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "PolyConic"))
554 : {
555 : // skip scale factor
556 0 : m_oSRS.SetProjCS("PolyConic");
557 0 : m_oSRS.SetPolyconic(padfPrjParams[5], padfPrjParams[6],
558 : padfPrjParams[3], padfPrjParams[4]);
559 : }
560 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Robinson"))
561 : {
562 0 : m_oSRS.SetProjCS("Robinson");
563 0 : m_oSRS.SetRobinson(padfPrjParams[6], padfPrjParams[3],
564 : padfPrjParams[4]);
565 : }
566 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Sinusoidal"))
567 : {
568 0 : m_oSRS.SetProjCS("Sinusoidal");
569 0 : m_oSRS.SetSinusoidal(padfPrjParams[6], padfPrjParams[3],
570 : padfPrjParams[4]);
571 : }
572 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Stereographic"))
573 : {
574 0 : m_oSRS.SetProjCS("Stereographic");
575 0 : m_oSRS.SetStereographic(padfPrjParams[5], padfPrjParams[6],
576 : padfPrjParams[9], padfPrjParams[3],
577 : padfPrjParams[4]);
578 : }
579 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "Transverse Mercator"))
580 : {
581 0 : m_oSRS.SetProjCS("Transverse Mercator");
582 0 : m_oSRS.SetStereographic(padfPrjParams[5], padfPrjParams[6],
583 : padfPrjParams[9], padfPrjParams[3],
584 : padfPrjParams[4]);
585 : }
586 5 : else if (STARTS_WITH_CI(pszProj.c_str(), "UTM"))
587 : {
588 : std::string pszNH =
589 15 : ReadElement("Projection", "Northern Hemisphere", csyFileName);
590 5 : m_oSRS.SetProjCS("UTM");
591 5 : if (STARTS_WITH_CI(pszNH.c_str(), "Yes"))
592 4 : m_oSRS.SetUTM((int)padfPrjParams[11], 1);
593 : else
594 1 : m_oSRS.SetUTM((int)padfPrjParams[11], 0);
595 : }
596 0 : else if (STARTS_WITH_CI(pszProj.c_str(), "VanderGrinten"))
597 : {
598 0 : m_oSRS.SetVDG(padfPrjParams[6], padfPrjParams[3], padfPrjParams[4]);
599 : }
600 0 : else if (STARTS_WITH_CI(pszProj.c_str(), "GeoStationary Satellite"))
601 : {
602 0 : m_oSRS.SetGEOS(padfPrjParams[6], padfPrjParams[12], padfPrjParams[3],
603 : padfPrjParams[4]);
604 : }
605 0 : else if (STARTS_WITH_CI(pszProj.c_str(), "MSG Perspective"))
606 : {
607 0 : m_oSRS.SetGEOS(padfPrjParams[6], padfPrjParams[12], padfPrjParams[3],
608 : padfPrjParams[4]);
609 : }
610 : else
611 : {
612 0 : m_oSRS.SetLocalCS(pszProj.c_str());
613 : }
614 : /* -------------------------------------------------------------------- */
615 : /* Try to translate the datum/spheroid. */
616 : /* -------------------------------------------------------------------- */
617 :
618 5 : if (!m_oSRS.IsLocal())
619 : {
620 5 : const IlwisDatums *piwDatum = iwDatums;
621 :
622 : // Search for matching datum
623 222 : while (piwDatum->pszIlwisDatum)
624 : {
625 222 : if (EQUALN(pszDatum.c_str(), piwDatum->pszIlwisDatum,
626 : strlen(piwDatum->pszIlwisDatum)))
627 : {
628 10 : OGRSpatialReference oOGR;
629 5 : oOGR.importFromEPSG(piwDatum->nEPSGCode);
630 5 : m_oSRS.CopyGeogCSFrom(&oOGR);
631 5 : break;
632 : }
633 217 : piwDatum++;
634 : } // 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 5 : const IlwisEllips *piwEllips = iwEllips;
643 5 : if (pszEllips.empty())
644 1 : pszEllips = "Sphere";
645 5 : if (!piwDatum->pszIlwisDatum)
646 : {
647 0 : while (piwEllips->pszIlwisEllips)
648 : {
649 0 : if (EQUALN(pszEllips.c_str(), piwEllips->pszIlwisEllips,
650 : strlen(piwEllips->pszIlwisEllips)))
651 : {
652 0 : double dfSemiMajor = piwEllips->semiMajor;
653 0 : if (STARTS_WITH_CI(pszEllips.c_str(), "Sphere") &&
654 0 : padfPrjParams[0] != 0)
655 : {
656 0 : dfSemiMajor = padfPrjParams[0];
657 : }
658 0 : m_oSRS.SetGeogCS(
659 : CPLSPrintf("Unknown datum based upon the %s ellipsoid",
660 0 : piwEllips->pszIlwisEllips),
661 : 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 : }
670 0 : piwEllips++;
671 : } // end of searching for matching ellipsoid
672 : }
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 5 : if (!piwEllips->pszIlwisEllips)
681 : {
682 :
683 0 : if (STARTS_WITH_CI(pszEllips.c_str(), "User Defined"))
684 : {
685 0 : m_oSRS.SetGeogCS(
686 : "Unknown datum based upon the custom ellipsoid",
687 : "Not specified (based on custom ellipsoid)",
688 : "Custom ellipsoid", padfPrjParams[0], padfPrjParams[2],
689 : nullptr, 0, nullptr, 0);
690 : }
691 : else
692 : {
693 : // if cannot find the user defined ellips, default to WGS84
694 0 : m_oSRS.SetWellKnownGeogCS("WGS84");
695 : }
696 : }
697 : } // end of if ( !IsLocal() )
698 :
699 : /* -------------------------------------------------------------------- */
700 : /* Units translation */
701 : /* -------------------------------------------------------------------- */
702 5 : if (m_oSRS.IsLocal() || m_oSRS.IsProjected())
703 : {
704 5 : m_oSRS.SetLinearUnits(SRS_UL_METER, 1.0);
705 : }
706 :
707 10 : return CE_None;
708 : }
709 :
710 0 : static void WriteFalseEastNorth(const std::string &csFileName,
711 : const OGRSpatialReference &oSRS)
712 : {
713 0 : WriteElement("Projection", ILW_False_Easting, csFileName,
714 : oSRS.GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0));
715 0 : WriteElement("Projection", ILW_False_Northing, csFileName,
716 : oSRS.GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0));
717 0 : }
718 :
719 0 : static void WriteProjectionName(const std::string &csFileName,
720 : const std::string &stProjection)
721 : {
722 0 : WriteElement("CoordSystem", "Type", csFileName, "Projection");
723 0 : WriteElement("CoordSystem", "Projection", csFileName, stProjection);
724 0 : }
725 :
726 2 : static void WriteUTM(const std::string &csFileName,
727 : const OGRSpatialReference &oSRS)
728 : {
729 : int bNorth;
730 :
731 2 : int nZone = oSRS.GetUTMZone(&bNorth);
732 2 : WriteElement("CoordSystem", "Type", csFileName, "Projection");
733 2 : WriteElement("CoordSystem", "Projection", csFileName, "UTM");
734 2 : if (bNorth)
735 2 : WriteElement("Projection", "Northern Hemisphere", csFileName, "Yes");
736 : else
737 0 : WriteElement("Projection", "Northern Hemisphere", csFileName, "No");
738 2 : WriteElement("Projection", "Zone", csFileName, nZone);
739 2 : }
740 :
741 0 : static void WriteAlbersConicEqualArea(const std::string &csFileName,
742 : const OGRSpatialReference &oSRS)
743 : {
744 0 : WriteProjectionName(csFileName, "Albers EqualArea Conic");
745 0 : WriteFalseEastNorth(csFileName, oSRS);
746 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
747 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
748 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
749 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
750 0 : WriteElement("Projection", ILW_Standard_Parallel_1, csFileName,
751 : oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0));
752 0 : WriteElement("Projection", ILW_Standard_Parallel_2, csFileName,
753 : oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0));
754 0 : }
755 :
756 0 : static void WriteAzimuthalEquidistant(const std::string &csFileName,
757 : const OGRSpatialReference &oSRS)
758 : {
759 0 : WriteProjectionName(csFileName, "Azimuthal Equidistant");
760 0 : WriteFalseEastNorth(csFileName, oSRS);
761 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
762 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
763 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
764 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
765 0 : WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000");
766 0 : }
767 :
768 0 : static void WriteCylindricalEqualArea(const std::string &csFileName,
769 : const OGRSpatialReference &oSRS)
770 : {
771 0 : WriteProjectionName(csFileName, "Central Cylindrical");
772 0 : WriteFalseEastNorth(csFileName, oSRS);
773 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
774 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
775 0 : }
776 :
777 0 : static void WriteCassiniSoldner(const std::string &csFileName,
778 : const OGRSpatialReference &oSRS)
779 : {
780 0 : WriteProjectionName(csFileName, "Cassini");
781 0 : WriteFalseEastNorth(csFileName, oSRS);
782 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
783 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
784 0 : WriteElement("Projection", ILW_Latitude_True_Scale, csFileName,
785 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
786 0 : WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000");
787 0 : }
788 :
789 0 : static void WriteStereographic(const std::string &csFileName,
790 : const OGRSpatialReference &oSRS)
791 : {
792 0 : WriteProjectionName(csFileName, "Stereographic");
793 0 : WriteFalseEastNorth(csFileName, oSRS);
794 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
795 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
796 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
797 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
798 0 : WriteElement("Projection", ILW_Scale_Factor, csFileName,
799 : oSRS.GetNormProjParm(SRS_PP_SCALE_FACTOR, 0.0));
800 0 : }
801 :
802 0 : static void WriteEquidistantConic(const std::string &csFileName,
803 : const OGRSpatialReference &oSRS)
804 : {
805 0 : WriteProjectionName(csFileName, "Equidistant Conic");
806 0 : WriteFalseEastNorth(csFileName, oSRS);
807 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
808 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
809 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
810 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
811 0 : WriteElement("Projection", ILW_Standard_Parallel_1, csFileName,
812 : oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0));
813 0 : WriteElement("Projection", ILW_Standard_Parallel_2, csFileName,
814 : oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0));
815 0 : }
816 :
817 0 : static void WriteTransverseMercator(const std::string &csFileName,
818 : const OGRSpatialReference &oSRS)
819 : {
820 0 : WriteProjectionName(csFileName, "Transverse Mercator");
821 0 : WriteFalseEastNorth(csFileName, oSRS);
822 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
823 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
824 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
825 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
826 0 : WriteElement("Projection", ILW_Scale_Factor, csFileName,
827 : oSRS.GetNormProjParm(SRS_PP_SCALE_FACTOR, 0.0));
828 0 : }
829 :
830 0 : static void WriteGnomonic(const std::string &csFileName,
831 : const OGRSpatialReference &oSRS)
832 : {
833 0 : WriteProjectionName(csFileName, "Gnomonic");
834 0 : WriteFalseEastNorth(csFileName, oSRS);
835 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
836 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
837 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
838 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
839 0 : }
840 :
841 0 : static void WriteLambertConformalConic(const std::string &csFileName,
842 : const OGRSpatialReference &oSRS)
843 : {
844 0 : WriteProjectionName(csFileName, "Lambert Conformal Conic");
845 0 : WriteFalseEastNorth(csFileName, oSRS);
846 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
847 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
848 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
849 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
850 0 : WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000");
851 0 : }
852 :
853 0 : static void WriteLambertConformalConic2SP(const std::string &csFileName,
854 : const OGRSpatialReference &oSRS)
855 : {
856 0 : WriteProjectionName(csFileName, "Lambert Conformal Conic");
857 0 : WriteFalseEastNorth(csFileName, oSRS);
858 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
859 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
860 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
861 : 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 : oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0));
865 0 : WriteElement("Projection", ILW_Standard_Parallel_2, csFileName,
866 : oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0));
867 0 : }
868 :
869 0 : static void WriteLambertAzimuthalEqualArea(const std::string &csFileName,
870 : const OGRSpatialReference &oSRS)
871 : {
872 0 : WriteProjectionName(csFileName, "Lambert Azimuthal EqualArea");
873 0 : WriteFalseEastNorth(csFileName, oSRS);
874 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
875 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
876 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
877 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
878 0 : }
879 :
880 0 : static void WriteMercator_1SP(const std::string &csFileName,
881 : const OGRSpatialReference &oSRS)
882 : {
883 0 : WriteProjectionName(csFileName, "Mercator");
884 0 : WriteFalseEastNorth(csFileName, oSRS);
885 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
886 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
887 0 : WriteElement("Projection", ILW_Latitude_True_Scale, csFileName,
888 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
889 0 : }
890 :
891 0 : static void WriteMillerCylindrical(const std::string &csFileName,
892 : const OGRSpatialReference &oSRS)
893 : {
894 0 : WriteProjectionName(csFileName, "Miller");
895 0 : WriteFalseEastNorth(csFileName, oSRS);
896 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
897 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
898 0 : }
899 :
900 0 : static void WriteMolleweide(const std::string &csFileName,
901 : const OGRSpatialReference &oSRS)
902 : {
903 0 : WriteProjectionName(csFileName, "Mollweide");
904 0 : WriteFalseEastNorth(csFileName, oSRS);
905 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
906 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
907 0 : }
908 :
909 0 : static void WriteOrthographic(const std::string &csFileName,
910 : const OGRSpatialReference &oSRS)
911 : {
912 0 : WriteProjectionName(csFileName, "Orthographic");
913 0 : WriteFalseEastNorth(csFileName, oSRS);
914 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
915 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
916 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
917 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
918 0 : }
919 :
920 0 : static void WritePlateRectangle(const std::string &csFileName,
921 : const OGRSpatialReference &oSRS)
922 : {
923 0 : WriteProjectionName(csFileName, "Plate Rectangle");
924 0 : WriteFalseEastNorth(csFileName, oSRS);
925 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
926 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
927 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
928 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
929 0 : WriteElement("Projection", ILW_Latitude_True_Scale, csFileName,
930 : "0.0000000000");
931 0 : }
932 :
933 0 : static void WritePolyConic(const std::string &csFileName,
934 : const OGRSpatialReference &oSRS)
935 : {
936 0 : WriteProjectionName(csFileName, "PolyConic");
937 0 : WriteFalseEastNorth(csFileName, oSRS);
938 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
939 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
940 0 : WriteElement("Projection", ILW_Central_Parallel, csFileName,
941 : oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0));
942 0 : WriteElement("Projection", ILW_Scale_Factor, csFileName, "1.0000000000");
943 0 : }
944 :
945 0 : static void WriteRobinson(const std::string &csFileName,
946 : const OGRSpatialReference &oSRS)
947 : {
948 0 : WriteProjectionName(csFileName, "Robinson");
949 0 : WriteFalseEastNorth(csFileName, oSRS);
950 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
951 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
952 0 : }
953 :
954 0 : static void WriteSinusoidal(const std::string &csFileName,
955 : const OGRSpatialReference &oSRS)
956 : {
957 0 : WriteProjectionName(csFileName, "Sinusoidal");
958 0 : WriteFalseEastNorth(csFileName, oSRS);
959 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
960 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
961 0 : }
962 :
963 0 : static void WriteVanderGrinten(const std::string &csFileName,
964 : const OGRSpatialReference &oSRS)
965 : {
966 0 : WriteProjectionName(csFileName, "VanderGrinten");
967 0 : WriteFalseEastNorth(csFileName, oSRS);
968 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
969 : oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0));
970 0 : }
971 :
972 0 : static void WriteGeoStatSat(const std::string &csFileName,
973 : const OGRSpatialReference &oSRS)
974 : {
975 0 : WriteProjectionName(csFileName, "GeoStationary Satellite");
976 0 : WriteFalseEastNorth(csFileName, oSRS);
977 0 : WriteElement("Projection", ILW_Central_Meridian, csFileName,
978 : 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 : 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 31 : CPLErr ILWISDataset::WriteProjection()
994 :
995 : {
996 31 : OGRSpatialReference *poGeogSRS = nullptr;
997 :
998 62 : std::string csFileName = CPLResetExtension(osFileName, "csy");
999 62 : std::string pszBaseName = std::string(CPLGetBasename(osFileName));
1000 : // std::string pszPath = std::string(CPLGetPath( osFileName ));
1001 31 : const bool bHaveSRS = !m_oSRS.IsEmpty();
1002 :
1003 31 : const IlwisDatums *piwDatum = iwDatums;
1004 : // std::string pszEllips;
1005 62 : std::string osDatum;
1006 : // std::string pszProj;
1007 :
1008 : /* -------------------------------------------------------------------- */
1009 : /* Collect datum/ellips information. */
1010 : /* -------------------------------------------------------------------- */
1011 31 : if (bHaveSRS)
1012 : {
1013 31 : poGeogSRS = m_oSRS.CloneGeogCS();
1014 : }
1015 :
1016 62 : std::string grFileName = CPLResetExtension(osFileName, "grf");
1017 31 : std::string csy;
1018 31 : if (poGeogSRS)
1019 : {
1020 31 : csy = pszBaseName + ".csy";
1021 :
1022 31 : WriteElement("Ilwis", "Type", csFileName, "CoordSystem");
1023 31 : const char *pszDatum = poGeogSRS->GetAttrValue("GEOGCS|DATUM");
1024 31 : if (pszDatum)
1025 31 : osDatum = pszDatum;
1026 :
1027 : /* WKT to ILWIS translation */
1028 2058 : while (piwDatum->pszWKTDatum)
1029 : {
1030 2058 : if (EQUALN(osDatum.c_str(), piwDatum->pszWKTDatum,
1031 : strlen(piwDatum->pszWKTDatum)))
1032 : {
1033 62 : WriteElement("CoordSystem", "Datum", csFileName,
1034 31 : piwDatum->pszIlwisDatum);
1035 31 : break;
1036 : }
1037 2027 : piwDatum++;
1038 : } // End of searching for matching datum.
1039 31 : WriteElement("CoordSystem", "Width", csFileName, 28);
1040 : // pszEllips = poGeogSRS->GetAttrValue( "GEOGCS|DATUM|SPHEROID" );
1041 31 : double a = poGeogSRS->GetSemiMajor();
1042 31 : /* b = */ poGeogSRS->GetSemiMinor();
1043 31 : double f = poGeogSRS->GetInvFlattening();
1044 31 : WriteElement("CoordSystem", "Ellipsoid", csFileName, "User Defined");
1045 31 : WriteElement("Ellipsoid", "a", csFileName, a);
1046 31 : WriteElement("Ellipsoid", "1/f", csFileName, f);
1047 : }
1048 : else
1049 0 : csy = "unknown.csy";
1050 :
1051 : /* -------------------------------------------------------------------- */
1052 : /* Determine to write a geo-referencing file for the dataset to create */
1053 : /* -------------------------------------------------------------------- */
1054 31 : 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 31 : WriteElement("GeoRef", "CoordSystem", grFileName, csy);
1058 :
1059 : /* -------------------------------------------------------------------- */
1060 : /* Recognise various projections. */
1061 : /* -------------------------------------------------------------------- */
1062 31 : const char *pszProjName = nullptr;
1063 :
1064 31 : if (bHaveSRS)
1065 31 : pszProjName = m_oSRS.GetAttrValue("PROJCS|PROJECTION");
1066 :
1067 31 : if (pszProjName == nullptr)
1068 : {
1069 29 : if (bHaveSRS && m_oSRS.IsGeographic())
1070 : {
1071 29 : WriteElement("CoordSystem", "Type", csFileName, "LatLon");
1072 : }
1073 : }
1074 2 : else if (m_oSRS.GetUTMZone(nullptr) != 0)
1075 : {
1076 2 : WriteUTM(csFileName, m_oSRS);
1077 : }
1078 0 : else if (EQUAL(pszProjName, SRS_PT_ALBERS_CONIC_EQUAL_AREA))
1079 : {
1080 0 : WriteAlbersConicEqualArea(csFileName, m_oSRS);
1081 : }
1082 0 : else if (EQUAL(pszProjName, SRS_PT_AZIMUTHAL_EQUIDISTANT))
1083 : {
1084 0 : WriteAzimuthalEquidistant(csFileName, m_oSRS);
1085 : }
1086 0 : else if (EQUAL(pszProjName, SRS_PT_CYLINDRICAL_EQUAL_AREA))
1087 : {
1088 0 : WriteCylindricalEqualArea(csFileName, m_oSRS);
1089 : }
1090 0 : else if (EQUAL(pszProjName, SRS_PT_CASSINI_SOLDNER))
1091 : {
1092 0 : WriteCassiniSoldner(csFileName, m_oSRS);
1093 : }
1094 0 : else if (EQUAL(pszProjName, SRS_PT_STEREOGRAPHIC))
1095 : {
1096 0 : WriteStereographic(csFileName, m_oSRS);
1097 : }
1098 0 : else if (EQUAL(pszProjName, SRS_PT_EQUIDISTANT_CONIC))
1099 : {
1100 0 : WriteEquidistantConic(csFileName, m_oSRS);
1101 : }
1102 0 : else if (EQUAL(pszProjName, SRS_PT_TRANSVERSE_MERCATOR))
1103 : {
1104 0 : WriteTransverseMercator(csFileName, m_oSRS);
1105 : }
1106 0 : else if (EQUAL(pszProjName, SRS_PT_GNOMONIC))
1107 : {
1108 0 : WriteGnomonic(csFileName, m_oSRS);
1109 : }
1110 0 : else if (EQUAL(pszProjName, "Lambert_Conformal_Conic"))
1111 : {
1112 0 : WriteLambertConformalConic(csFileName, m_oSRS);
1113 : }
1114 0 : else if (EQUAL(pszProjName, SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP))
1115 : {
1116 0 : WriteLambertConformalConic(csFileName, m_oSRS);
1117 : }
1118 0 : else if (EQUAL(pszProjName, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP))
1119 : {
1120 0 : WriteLambertConformalConic2SP(csFileName, m_oSRS);
1121 : }
1122 0 : else if (EQUAL(pszProjName, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA))
1123 : {
1124 0 : WriteLambertAzimuthalEqualArea(csFileName, m_oSRS);
1125 : }
1126 0 : else if (EQUAL(pszProjName, SRS_PT_MERCATOR_1SP))
1127 : {
1128 0 : WriteMercator_1SP(csFileName, m_oSRS);
1129 : }
1130 0 : else if (EQUAL(pszProjName, SRS_PT_MILLER_CYLINDRICAL))
1131 : {
1132 0 : WriteMillerCylindrical(csFileName, m_oSRS);
1133 : }
1134 0 : else if (EQUAL(pszProjName, SRS_PT_MOLLWEIDE))
1135 : {
1136 0 : WriteMolleweide(csFileName, m_oSRS);
1137 : }
1138 0 : else if (EQUAL(pszProjName, SRS_PT_ORTHOGRAPHIC))
1139 : {
1140 0 : WriteOrthographic(csFileName, m_oSRS);
1141 : }
1142 0 : else if (EQUAL(pszProjName, SRS_PT_EQUIRECTANGULAR))
1143 : {
1144 0 : WritePlateRectangle(csFileName, m_oSRS);
1145 : }
1146 0 : else if (EQUAL(pszProjName, SRS_PT_POLYCONIC))
1147 : {
1148 0 : WritePolyConic(csFileName, m_oSRS);
1149 : }
1150 0 : else if (EQUAL(pszProjName, SRS_PT_ROBINSON))
1151 : {
1152 0 : WriteRobinson(csFileName, m_oSRS);
1153 : }
1154 0 : else if (EQUAL(pszProjName, SRS_PT_SINUSOIDAL))
1155 : {
1156 0 : WriteSinusoidal(csFileName, m_oSRS);
1157 : }
1158 0 : else if (EQUAL(pszProjName, SRS_PT_VANDERGRINTEN))
1159 : {
1160 0 : WriteVanderGrinten(csFileName, m_oSRS);
1161 : }
1162 0 : else if (EQUAL(pszProjName, SRS_PT_GEOSTATIONARY_SATELLITE))
1163 : {
1164 0 : WriteGeoStatSat(csFileName, m_oSRS);
1165 : }
1166 : else
1167 : {
1168 : // Projection unknown by ILWIS
1169 : }
1170 :
1171 : /* -------------------------------------------------------------------- */
1172 : /* Cleanup */
1173 : /* -------------------------------------------------------------------- */
1174 31 : if (poGeogSRS != nullptr)
1175 31 : delete poGeogSRS;
1176 :
1177 62 : return CE_None;
1178 : }
1179 :
1180 : } // namespace GDAL
|