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