LCOV - code coverage report
Current view: top level - frmts/ilwis - ilwiscoordinatesystem.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 143 444 32.2 %
Date: 2024-11-21 22:18:42 Functions: 5 30 16.7 %

          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 &section,
     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

Generated by: LCOV version 1.14