LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/geoconcept - geoconcept_syscoord.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 260 391 66.5 %
Date: 2024-04-29 01:40:10 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  * $Id: geoconcept_syscoord.c$
       3             :  *
       4             :  * Name:     geoconcept_syscoord.c
       5             :  * Project:  OpenGIS Simple Features Reference Implementation
       6             :  * Purpose:  Implements translation between Geoconcept SysCoord
       7             :  *           and OGRSpatialRef format
       8             :  * Language: C
       9             :  *
      10             :  **********************************************************************
      11             :  * Copyright (c) 2007,  Geoconcept and IGN
      12             :  * Copyright (c) 2008-2010, Even Rouault <even dot rouault at spatialys.com>
      13             :  *
      14             :  * Permission is hereby granted, free of charge, to any person obtaining a
      15             :  * copy of this software and associated documentation files (the "Software"),
      16             :  * to deal in the Software without restriction, including without limitation
      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18             :  * and/or sell copies of the Software, and to permit persons to whom the
      19             :  * Software is furnished to do so, subject to the following conditions:
      20             :  *
      21             :  * The above copyright notice and this permission notice shall be included
      22             :  * in all copies or substantial portions of the Software.
      23             :  *
      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      27             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      30             :  * DEALINGS IN THE SOFTWARE.
      31             :  **********************************************************************/
      32             : 
      33             : #include "geoconcept_syscoord.h"
      34             : #include "cpl_string.h"
      35             : 
      36             : /* -------------------------------------------------------------------- */
      37             : /*      GCSRS globals                                                   */
      38             : /* -------------------------------------------------------------------- */
      39             : 
      40             : /*
      41             :  * The following information came from GEO CONCEPT PROJECTION files,
      42             :  * aka GCP files.
      43             :  * A lot of information has been added to these GCP. There are mostly
      44             :  * noticed as FIXME in the source.
      45             :  */
      46             : 
      47             : static const GCSysCoord gk_asSysCoordList[] =
      48             :     /*
      49             :      * pszSysCoordName, pszUnit, dfPM, dfLambda0, dfPhi0, dfk0, dfX0, dfY0,
      50             :      * dfPhi1, dfPhi2, nDatumID, nProjID, coordSystemID, timeZoneValue
      51             :      *
      52             :      * #12, #14, #15, #17 : parameters listed below are "generic" ...
      53             :      *
      54             :      * Geoconcept uses cos(lat_ts) as scale factor, but
      55             :      * cos(lat_ts)==cos(-lat_ts) : I then set dfPhi1 with lat_ts
      56             :      */
      57             :     {{"Lambert 2 extended", NULL, 2.337229166667, 0.000000000, 46.80000000,
      58             :       0.99987742000, 600000.000, 2200000.000, 0.0, 0.0, 13, 2, 1, -1},
      59             :      {"Lambert 1", NULL, 2.337229166667, 0.000000000, 49.50000000,
      60             :       0.99987734000, 600000.000, 200000.000, 0.0, 0.0, 13, 2, 2, -1},
      61             :      {"Lambert 2", NULL, 2.337229166667, 0.000000000, 46.80000000,
      62             :       0.99987742000, 600000.000, 200000.000, 0.0, 0.0, 13, 2, 3, -1},
      63             :      {"Lambert 3", NULL, 2.337229166667, 0.000000000, 44.10000000,
      64             :       0.99987750000, 600000.000, 200000.000, 0.0, 0.0, 13, 2, 4, -1},
      65             :      {"Lambert 4", NULL, 2.337229166667, 0.000000000, 42.16500000,
      66             :       0.99994471000, 234.358, 185861.369, 0.0, 0.0, 13, 2, 5, -1},
      67             :      {"Bonne NTF", NULL, 2.337222222222, 0.000000000, 48.86000000,
      68             :       1.00000000000, 0.000, 0.000, 0.0, 0.0, 1, 3, 11, -1},
      69             :      {"UTM Nord - ED50", NULL, 0.000000000000, 0.000000000, 0.00000000,
      70             :       0.99960000000, 500000.000, 0.000, 0.0, 0.0, 14, 1, 12, 0},
      71             :      {"Plate carr"
      72             :       "\xe9"
      73             :       "e",
      74             :       NULL, 0.000000000000, 0.000000000, 0.00000000, 0.00000000000, 0.000,
      75             :       0.000, 0.0, 0.0, 11, 4, 13, -1},
      76             :      {"MGRS (Military UTM)", NULL, 0.000000000000, 0.000000000, 0.00000000,
      77             :       0.99960000000, 0.000, 0.000, 0.0, 0.0, 4, 11, 14, -1},
      78             :      {"UTM Sud - WGS84", NULL, 0.000000000000, 0.000000000, 0.00000000,
      79             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 4, 1, 15, 0},
      80             :      {"National GB projection", NULL, 0.000000000000, -2.000000000, 49.00000000,
      81             :       0.99960127170, 400000.000, -100000.000, 0.0, 0.0, 12, 12, 16, -1},
      82             :      {"UTM Nord - WGS84", NULL, 0.000000000000, 0.000000000, 0.00000000,
      83             :       0.99960000000, 500000.000, 0.000, 0.0, 0.0, 4, 1, 17, 0},
      84             :      {"UTM Nord - WGS84", NULL, 0.000000000000, 0.000000000, 0.00000000,
      85             :       0.99960000000, 500000.000, 0.000, 0.0, 0.0, 9990, 1, 17, 0},
      86             :      {"Lambert 2 "
      87             :       "\xe9"
      88             :       "tendu - sans grille",
      89             :       NULL, 2.337229166667, 0.000000000, 46.80000000, 0.99987742000, 600000.000,
      90             :       2200000.000, 0.0, 0.0, 1, 2, 91, -1},
      91             :      {"Lambert 1 - sans grille", NULL, 2.337229166667, 0.000000000, 49.50000000,
      92             :       0.99987734000, 600000.000, 200000.000, 0.0, 0.0, 1, 2, 92, -1},
      93             :      {"Lambert 2 - sans grille", NULL, 2.337229166667, 0.000000000, 46.80000000,
      94             :       0.99987742000, 600000.000, 200000.000, 0.0, 0.0, 1, 2, 93, -1},
      95             :      {"Lambert 3 - sans grille", NULL, 2.337229166667, 0.000000000, 44.10000000,
      96             :       0.99987750000, 600000.000, 200000.000, 0.0, 0.0, 1, 2, 94, -1},
      97             :      {"Lambert 4 - sans grille", NULL, 2.337229166667, 0.000000000, 42.16500000,
      98             :       0.99994471000, 234.358, 185861.369, 0.0, 0.0, 1, 2, 95, -1},
      99             :      {"(Long/Lat) NTF", "d", 0.000000000000, 0.000000000, 0.00000000,
     100             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 1, 0, 100, -1},
     101             :      {"(Long/Lat) WGS84", "d", 0.000000000000, 0.000000000, 0.00000000,
     102             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 4, 0, 101, -1},
     103             :      {"(Long/Lat) ED50", "d", 0.000000000000, 0.000000000, 0.00000000,
     104             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 14, 0, 102, -1},
     105             :      {"(Long/Lat) Australian 1984", "d", 0.000000000000, 0.000000000,
     106             :       0.00000000, 0.00000000000, 0.000, 0.000, 0.0, 0.0, 7, 0, 103, -1},
     107             :      {"(Long/Lat) Airy", "d", 0.000000000000, 0.000000000, 0.00000000,
     108             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 12, 0, 104, -1},
     109             :      {"(Long/Lat) NTF Paris (gr)", "gr", 2.337229166667, 0.000000000,
     110             :       0.00000000, 0.00000000000, 0.000, 0.000, 0.0, 0.0, 1, 0, 105, -1},
     111             :      {"(Long/Lat) WGS 72", "d", 0.000000000000, 0.000000000, 0.00000000,
     112             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 3, 0, 107, -1},
     113             :      {"Geoportail MILLER", NULL, 0.000000000000, 0.000000000, 0.00000000,
     114             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 4, 24, 222, -1},
     115             :      {"IGN-RRAFGUADU20", NULL, 0.000000000000, -63.000000000, 0.00000000,
     116             :       0.99960000000, 500000.000, 0.000, 0.0, 0.0, 9984, 1, 501,
     117             :       -1}, /* FIXME does not exist in IGNF, use IGN-UTM20W84GUAD instead */
     118             :      {"IGN-RRAFMARTU20", NULL, 0.000000000000, -63.000000000, 0.00000000,
     119             :       0.99960000000, 500000.000, 0.000, 0.0, 0.0, 9984, 1, 502,
     120             :       -1}, /* FIXME does not exist in IGNF, use IGN-UTM20W84MART instead, never
     121             :               reached cause identical to 501:-1 */
     122             :      {"IGN-RGM04UTM38S", NULL, 0.000000000000, 45.000000000, 0.00000000,
     123             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9984, 1, 503,
     124             :       -1}, /* FIXME 5030 datum changed into 9984 */
     125             :      {"IGN-RGR92UTM40S", NULL, 0.000000000000, 57.000000000, 0.00000000,
     126             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9984, 1, 504, -1},
     127             :      {"IGN-UTM22RGFG95", NULL, 0.000000000000, -51.000000000, 0.00000000,
     128             :       0.99960000000, 500000.000, 0.000, 0.0, 0.0, 9984, 1, 505, -1},
     129             :      {"IGN-UTM01SWG84", NULL, 0.000000000000, -177.000000000, 0.00000000,
     130             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9984, 1, 506,
     131             :       -1}, /* never reached cause identical to 15:1 */
     132             :      {"IGN-RGSPM06U21", NULL, 0.000000000000, -57.000000000, 0.00000000,
     133             :       0.99960000000, 500000.000, 0.000, 0.0, 0.0, 9984, 1, 507, -1},
     134             :      {"IGN-RGPFUTM5S", NULL, 0.000000000000, -153.000000000, 0.00000000,
     135             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9984, 1, 508, -1},
     136             :      {"IGN-RGPFUTM6S", NULL, 0.000000000000, -147.000000000, 0.00000000,
     137             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9984, 1, 509, -1},
     138             :      {"IGN-RGPFUTM7S", NULL, 0.000000000000, -141.000000000, 0.00000000,
     139             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9984, 1, 510, -1},
     140             :      {"IGN-CROZ63UTM39S", NULL, 0.000000000000, 51.000000000, 0.00000000,
     141             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9983, 1, 511, -1},
     142             :      {"IGN-WGS84UTM1S", NULL, 0.000000000000, -177.000000000, 0.00000000,
     143             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 4, 1, 512, -1},
     144             :      {"IGN-RGNCUTM57S", NULL, 0.000000000000, 159.000000000, 0.00000000,
     145             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9984, 1, 513, -1},
     146             :      {"IGN-RGNCUTM58S", NULL, 0.000000000000, 165.000000000, 0.00000000,
     147             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9984, 1, 514, -1},
     148             :      {"IGN-RGNCUTM59S", NULL, 0.000000000000, 171.000000000, 0.00000000,
     149             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9984, 1, 515, -1},
     150             :      {"IGN-KERG62UTM42S", NULL, 0.000000000000, 69.000000000, 0.00000000,
     151             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 9988, 1, 516, -1},
     152             :      {"IGN-REUN47GAUSSL", NULL, 0.000000000000, 55.533333333, -21.11666667,
     153             :       1.00000000000, 160000.000, 50000.000, 0.0, 0.0, 2, 19, 520, -1},
     154             :      {"Lambert 1 Carto", NULL, 2.337229166667, 0.000000000, 49.50000000,
     155             :       0.99987734000, 600000.000, 1200000.000, 0.0, 0.0, 13, 2, 1002, -1},
     156             :      {"Lambert 2 Carto", NULL, 2.337229166667, 0.000000000, 46.80000000,
     157             :       0.99987742000, 600000.000, 2200000.000, 0.0, 0.0, 13, 2, 1003,
     158             :       -1}, /* never reached cause identical to 1:-1 */
     159             :      {"Lambert 3 Carto", NULL, 2.337229166667, 0.000000000, 44.10000000,
     160             :       0.99987750000, 600000.000, 3200000.000, 0.0, 0.0, 13, 2, 1004, -1},
     161             :      {"Lambert 4 Carto", NULL, 2.337229166667, 0.000000000, 42.16500000,
     162             :       0.99994471000, 234.358, 4185861.369, 0.0, 0.0, 13, 2, 1005, -1},
     163             :      {"Lambert 93", NULL, 0.000000000000, 3.000000000, 46.50000000,
     164             :       0.00000000000, 700000.000, 6600000.000, 44.0, 49.0, 9984, 18, 1006, -1},
     165             :      {"IGN-RGNCLAM", NULL, 0.000000000000, 166.000000000, -21.30000000,
     166             :       0.00000000000, 400000.000, 300000.000, -20.4, -22.2, 9984, 18, 1007,
     167             :       -1}, /* Added in GCP */
     168             :      {"Lambert 1 Carto - sans grille", NULL, 2.337229166667, 0.000000000,
     169             :       49.50000000, 0.99987734000, 600000.000, 1200000.000, 0.0, 0.0, 1, 2, 1092,
     170             :       -1},
     171             :      {"Lambert 2 Carto - sans grille", NULL, 2.337229166667, 0.000000000,
     172             :       46.80000000, 0.99987742000, 600000.000, 2200000.000, 0.0, 0.0, 1, 2, 1093,
     173             :       -1},
     174             :      {"Lambert 3 Carto - sans grille", NULL, 2.337229166667, 0.000000000,
     175             :       44.10000000, 0.99987750000, 600000.000, 3200000.000, 0.0, 0.0, 1, 2, 1094,
     176             :       -1},
     177             :      {"Lambert 4 Carto - sans grille", NULL, 2.337229166667, 0.000000000,
     178             :       42.16500000, 0.99994471000, 234.358, 185861.369, 0.0, 0.0, 1, 2, 1095,
     179             :       -1},
     180             :      {"Suisse", NULL, 0.000000000000, 7.439583333, 46.95240556, 1.00000000000,
     181             :       600000.000, 200000.000, 0.0, 0.0, 2, 25, 1556, -1},
     182             :      {"Geoportail France", NULL, 0.000000000000, 0.000000000, 0.00000000,
     183             :       0.68835457569, 0.000, 0.000, 46.5, 0.0, 9984, 26, 2012, -1},
     184             :      {"Geoportail Antilles", NULL, 0.000000000000, 0.000000000, 0.00000000,
     185             :       0.96592582629, 0.000, 0.000, 15.0, 0.0, 9984, 26, 2016, -1},
     186             :      {"Geoportail Guyane", NULL, 0.000000000000, 0.000000000, 0.00000000,
     187             :       0.99756405026, 0.000, 0.000, 4.0, 0.0, 9984, 26, 2017, -1},
     188             :      {"Geoportail Reunion", NULL, 0.000000000000, 0.000000000, 0.00000000,
     189             :       0.93358042649, 0.000, 0.000, -21.0, 0.0, 9984, 26, 2018, -1},
     190             :      {"Geoportail Mayotte", NULL, 0.000000000000, 0.000000000, 0.00000000,
     191             :       0.97814760073, 0.000, 0.000, -12.0, 0.0, 9984, 26, 2019, -1},
     192             :      {"Geoportail ST Pierre et Miquelon", NULL, 0.000000000000, 0.000000000,
     193             :       0.00000000, 0.68199836006, 0.000, 0.000, 47.0, 0.0, 9984, 26, 2020, -1},
     194             :      {"Geoportail Nouvelle Caledonie", NULL, 0.000000000000, 0.000000000,
     195             :       0.00000000, 0.92718385456, 0.000, 0.000, -22.0, 0.0, 9984, 26, 2021, -1},
     196             :      {"Geoportail Wallis", NULL, 0.000000000000, 0.000000000, 0.00000000,
     197             :       0.97029572627, 0.000, 0.000, -14.0, 0.0, 9984, 26, 2022, -1},
     198             :      {"Geoportail Polynesie", NULL, 0.000000000000, 0.000000000, 0.00000000,
     199             :       0.96592582628, 0.000, 0.000, -15.0, 0.0, 9984, 26, 2023, -1},
     200             :      {"Mercator sur sph"
     201             :       "\xe8"
     202             :       "re WGS84",
     203             :       NULL, 0.000000000000, 0.000000000, 0.00000000, 1.00000000000, 0.000,
     204             :       0.000, 0.0, 0.0, 2015, 21, 2027, -1},
     205             :      {"(Long/Lat) RGF 93", "d", 0.000000000000, 0.000000000, 0.00000000,
     206             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 13, 0, 2028, -1},
     207             :      {"(Long/Lat) ITRS-89", "d", 0.000000000000, 0.000000000, 0.00000000,
     208             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 9984, 0, 2028, -1},
     209             :      {"Geoportail Crozet", NULL, 0.000000000000, 0.000000000, 0.00000000,
     210             :       0.69465837046, 0.000, 0.000, -46.0, 0.0, 9984, 26, 2040,
     211             :       -1}, /* FIXME : wrong scale factor was 0.69088241108 */
     212             :      {"Geoportail Kerguelen", NULL, 0.000000000000, 0.000000000, 0.00000000,
     213             :       0.64944804833, 0.000, 0.000, -49.5, 0.0, 9984, 26, 2042,
     214             :       -1}, /* FIXME : wrong scale factor was 0.67815966987 */
     215             :      {"Lambert CC 42", NULL, 0.000000000000, 3.000000000, 42.00000000,
     216             :       0.00000000000, 1700000.000, 1200000.000, 41.2, 42.8, 9984, 18, 2501, -1},
     217             :      {"Lambert CC 43", NULL, 0.000000000000, 3.000000000, 43.00000000,
     218             :       0.00000000000, 1700000.000, 2200000.000, 42.2, 43.8, 9984, 18, 2502, -1},
     219             :      {"Lambert CC 44", NULL, 0.000000000000, 3.000000000, 44.00000000,
     220             :       0.00000000000, 1700000.000, 3200000.000, 43.2, 44.8, 9984, 18, 2503, -1},
     221             :      {"Lambert CC 45", NULL, 0.000000000000, 3.000000000, 45.00000000,
     222             :       0.00000000000, 1700000.000, 4200000.000, 44.2, 45.8, 9984, 18, 2504, -1},
     223             :      {"Lambert CC 46", NULL, 0.000000000000, 3.000000000, 46.00000000,
     224             :       0.00000000000, 1700000.000, 5200000.000, 45.2, 46.8, 9984, 18, 2505, -1},
     225             :      {"Lambert CC 47", NULL, 0.000000000000, 3.000000000, 47.00000000,
     226             :       0.00000000000, 1700000.000, 6200000.000, 46.2, 47.8, 9984, 18, 2506, -1},
     227             :      {"Lambert CC 48", NULL, 0.000000000000, 3.000000000, 48.00000000,
     228             :       0.00000000000, 1700000.000, 7200000.000, 47.2, 48.8, 9984, 18, 2507, -1},
     229             :      {"Lambert CC 49", NULL, 0.000000000000, 3.000000000, 49.00000000,
     230             :       0.00000000000, 1700000.000, 8200000.000, 48.2, 49.8, 9984, 18, 2508, -1},
     231             :      {"Lambert CC 50", NULL, 0.000000000000, 3.000000000, 50.00000000,
     232             :       0.00000000000, 1700000.000, 9200000.000, 49.2, 50.8, 9984, 18, 2509, -1},
     233             :      {"(Long/Lat) IGN-RGM04GEO", "d", 0.000000000000, 0.000000000, 0.00000000,
     234             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 9984, 0, 10001, -1},
     235             :      {"(Long/Lat) IGN-RGFG95GEO", "d", 0.000000000000, 0.000000000, 0.00000000,
     236             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 9984, 0, 10002,
     237             :       -1}, /* never reached, identical to 10001:-1 */
     238             :      {"(Long/Lat) IGN-WGS84RRAFGEO", "d", 0.000000000000, 0.000000000,
     239             :       0.00000000, 0.00000000000, 0.000, 0.000, 0.0, 0.0, 9984, 0, 10003,
     240             :       -1}, /* never reached, identical to 10001:-1 */
     241             :      {"(Long/Lat) IGN-RGR92GEO", "d", 0.000000000000, 0.000000000, 0.00000000,
     242             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 9984, 0, 10004,
     243             :       -1}, /* never reached, identical to 10001:-1 */
     244             :      {"(Long/Lat) IGN-WGS84G", "d", 0.000000000000, 0.000000000, 0.00000000,
     245             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 4, 0, 10005, -1},
     246             :      {"(Long/Lat) CROZ63GEO", "d", 0.000000000000, 0.000000000, 0.00000000,
     247             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 4, 0, 10006, -1},
     248             :      {"(Long/Lat) RGSPM06GEO", "d", 0.000000000000, 0.000000000, 0.00000000,
     249             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 9984, 0, 10007,
     250             :       -1}, /* never reached, identical to 10001:-1 */
     251             :      {"(Long/Lat) RGPFGEO", "d", 0.000000000000, 0.000000000, 0.00000000,
     252             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 9984, 0, 10008,
     253             :       -1}, /* never reached, identical to 10001:-1 */
     254             :      {"(Long/Lat) RGNCGEO", "d", 0.000000000000, 0.000000000, 0.00000000,
     255             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 9984, 0, 10009,
     256             :       -1}, /* never reached, identical to 10001:-1 */
     257             :      {"(Long/Lat) KER62GEO", "d", 0.000000000000, 0.000000000, 0.00000000,
     258             :       0.00000000000, 0.000, 0.000, 0.0, 0.0, 9988, 0, 10010, -1},
     259             :      {"UTM Sud - ED50", NULL, 0.000000000000, 0.000000000, 0.00000000,
     260             :       0.99960000000, 500000.000, 10000000.000, 0.0, 0.0, 14, 1, 99912,
     261             :       0}, /* FIXME allow retrieving 12:0 - See _findSysCoord_GCSRS() */
     262             :      {NULL, NULL, 0.000000000000, 0.000000000, 0.00000000, 0.00000000000, 0.000,
     263             :       0.000, 0.0, 0.0, -1, -1, -1, -1}};
     264             : 
     265             : static const GCProjectionInfo gk_asProjList[] =
     266             :     /*
     267             :      * pszProjName, nSphere, nProjID
     268             :      */
     269             :     {{"Geographic shift", 0, 0},
     270             :      {"UTM", 0, 1},
     271             :      {"Lambert Conform Conic", 0, 2},
     272             :      {"Bonne", 0, 3},
     273             :      {"Plate carr"
     274             :       "\xe9"
     275             :       "e",
     276             :       0, 4},
     277             :      {"MGRS (Military UTM)", 0, 11},
     278             :      {"Transversal Mercator", 0, 12},
     279             :      {"Lambert secant", 0, 18},
     280             :      {"Gauss Laborde", 1, 19},
     281             :      {"Polyconic", 0, 20},
     282             :      {"Direct Mercator", 0, 21},
     283             :      {"Stereographic oblic", 1, 22},
     284             :      {"Miller", 0, 24},
     285             :      {"Mercator oblic", 1, 25},
     286             :      {"Equi rectangular", 1, 26},
     287             : 
     288             :      {NULL, 0, -1}};
     289             : 
     290             : static const GCDatumInfo gk_asDatumList[] =
     291             :     /*
     292             :      * pszDatumName, dfShiftX, dfShiftY, dfShiftZ, dfRotX, dfRotY, dfRotZ,
     293             :      * dfScaleFactor, dfFA, dfFlattening, nEllipsoidID, nDatumID
     294             :      */
     295             :     /*
     296             :      * Wrong dx, dy, dz :
     297             :      * IGN-RGM04GEO, was -217, -216, 67
     298             :      * IGN-RGFG95GEO, was -2, -2, 2
     299             :      * IGN-RGSPM06GEO, was -125.593, 143.763, -194.558
     300             :      *
     301             :      * #1 and #13 are identical
     302             :      * #8, #11, #2015 are spherical views of #4
     303             :      * #5030, #5031 and #5032 are identical
     304             :      * FIXME : #5030, #5031, #5032 are ITRS89 compliant, so "compatible" with
     305             :      * #4, better use #9999 as ellipsoid
     306             :      * FIXME : #9999 to #9986 added
     307             :      */
     308             :     {{"NTF (Clarke 1880)", -168.0000, -60.0000, 320.0000, 0.00000, 0.00000,
     309             :       0.00000, 0.0, -112.200, -54.7388e-6, 3, 1},
     310             :      {"ED50 France (International 1909)", -84.0000, -97.0000, -117.0000,
     311             :       0.00000, 0.00000, 0.00000, 0.0, -251.000, -14.1927e-6, 5, 2},
     312             :      {"WGS 72", 0.0000, 12.0000, 6.0000, 0.00000, 0.00000, 0.00000, 0.0, 2.000,
     313             :       0.0312e-6, 6, 3},
     314             :      {"WGS_1984", 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000, 0.0, 0.000,
     315             :       0.0, 9999, 4},
     316             :      {"ED 79", -83.0000, -95.0000, -116.0000, 0.00000, 0.00000, 0.00000, 0.0,
     317             :       -251.000, -14.1927e-6, 5, 5},
     318             :      {"Australian Geodetic 1966", -133.0000, -48.0000, 148.0000, 0.00000,
     319             :       0.00000, 0.00000, 0.0, -23.000, -0.0081e-6, 7, 6},
     320             :      {"Australian Geodetic 1984", -134.0000, -48.0000, 149.0000, 0.00000,
     321             :       0.00000, 0.00000, 0.0, -23.000, -0.0081e-6, 7, 7},
     322             :      {"Sphere", 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000, 0.0, 0.000,
     323             :       0.0, 1, 8},
     324             :      {"Sphere DCW", 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000, 0.0,
     325             :       0.000, 0.0, 1, 11},
     326             :      {"Airy", 375.0000, -111.0000, 431.0000, 0.00000, 0.00000, 0.00000, 0.0,
     327             :       573.604, 11.96002325e-6, 8, 12},
     328             :      {"NTF-Grille", -168.0000, -60.0000, 320.0000, 0.00000, 0.00000, 0.00000,
     329             :       0.0, -112.200, -54.7388e-6, 3, 13},
     330             :      {"ED50 (International 1909)", -87.0000, -98.0000, -121.0000, 0.00000,
     331             :       0.00000, 0.00000, 0.0, -251.000, -14.1927e-6, 5, 14},
     332             :      {"WGS 84 sur sphere", 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000,
     333             :       0.0, 0.000, 0.0, 1, 2015},
     334             :      {"IGN-RGM04GEO", 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000, 0.0,
     335             :       0.000, 0.0, 4, 5030},
     336             :      {"IGN-RGFG95GEO", 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000, 0.0,
     337             :       0.000, 0.0, 4, 5031},
     338             :      {"IGN-RGSPM06GEO", 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000, 0.0,
     339             :       0.000, 0.0, 4, 5032},
     340             :      {"IGN-WALL78", 253.0000, -133.0000, -127.0000, 0.00000, 0.00000, 0.00000,
     341             :       0.0, -251.000, -14.1927e-6, 5, 9999}, /* FIXME */
     342             :      {"IGN-TAHA", 72.4380, 345.9180, 79.4860, -1.60450, -0.88230, -0.55650,
     343             :       1.3746e-6, -251.000, -14.1927e-6, 5, 9998}, /* FIXME */
     344             :      {"IGN-MOOREA87", 215.9820, 149.5930, 176.2290, 3.26240, 1.69200, 1.15710,
     345             :       10.47730e-6, -251.000, -14.1927e-6, 5, 9997}, /* FIXME */
     346             :      {"IGN-TAHI51", 162.0000, 117.0000, 154.0000, 0.00000, 0.00000, 0.00000,
     347             :       0.0, -251.000, -14.1927e-6, 5, 9996}, /* FIXME */
     348             :      {"IGN-NUKU72", 165.7320, 216.7200, 180.5050, -0.64340, -0.45120, -0.07910,
     349             :       7.42040e-6, -251.000, -14.1927e-6, 5, 9995}, /* FIXME */
     350             :      {"IGN-IGN63", 410.7210, 55.0490, 80.7460, -2.57790, -2.35140, -0.66640,
     351             :       17.33110e-6, -251.000, -14.1927e-6, 5, 9994}, /* FIXME */
     352             :      {"IGN-MART38", 126.9260, 547.9390, 130.4090, -2.78670, 5.16124, -0.85844,
     353             :       13.82265e-6, -251.000, -14.1927e-6, 5, 9993}, /* FIXME */
     354             :      {"IGN-GUAD48", -472.2900, -5.6300, -304.1200, 0.43620, -0.83740, 0.25630,
     355             :       1.89840e-6, -251.000, -14.1927e-6, 5, 9992}, /* FIXME */
     356             :      {"IGN-GUADFM49", 136.5960, 248.1480, -429.7890, 0.00000, 0.00000, 0.00000,
     357             :       0.0, -251.000, -14.1927e-6, 5, 9991}, /* FIXME */
     358             :      {"IGN-STPM50", -95.5930, 573.7630, 173.4420, -0.96020, 1.25100, -1.39180,
     359             :       42.62650e-6, -69.400, -37.2957e-6, 2, 9990}, /* FIXME */
     360             :      {"IGN-CSG67", -193.0660, 236.9930, 105.4470, 0.48140, -0.80740, 0.12760,
     361             :       1.56490e-6, -251.000, -14.1927e-6, 5, 9989}, /* FIXME */
     362             :      {"IGN-KERG62", 145.0000, -187.0000, 103.0000, 0.00000, 0.00000, 0.00000,
     363             :       0.0, -251.000, -14.1927e-6, 5, 9988}, /* FIXME */
     364             :      {"IGN-REUN47", 789.5240, -626.4860, -89.9040, 0.60060, 76.79460, -10.57880,
     365             :       -32.32410e-6, -251.000, -14.1927e-6, 5, 9987}, /* FIXME */
     366             :      {"IGN-MAYO50", -599.9280, -275.5520, -195.6650, 0.08350, 0.47150, -0.06020,
     367             :       -49.28140e-6, -251.000, -14.1927e-6, 5, 9986}, /* FIXME */
     368             :      {"IGN-TAHI79", 221.5250, 152.9480, 176.7680, 2.38470, 1.38960, 0.87700,
     369             :       11.47410e-6, -251.000, -14.1927e-6, 5, 9985}, /* FIXME */
     370             :      {"ITRS-89", 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000, 0.0, 0.000,
     371             :       0.0, 4, 9984},
     372             :      {"IGN-CROZ63", 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000, 0.0,
     373             :       -251.000, -14.1927e-6, 5,
     374             :       9983}, /* FIXME added cause the Bursa-Wolf parameters are not known */
     375             : 
     376             :      {NULL, 0.0000, 0.0000, 0.0000, 0.00000, 0.00000, 0.00000, 0.0, 0.000, 0.0,
     377             :       -1, -1}};
     378             : 
     379             : static const GCSpheroidInfo gk_asSpheroidList[] =
     380             :     /*
     381             :      * pszSpheroidName, dfA, dfE, nEllipsoidID
     382             :      *
     383             :      * cause Geoconcept assimilates WGS84 and GRS80, WGS84 is added to the list
     384             :      */
     385             :     {{"Sphere", 6378137.0000, 0.00000000000000, 1},
     386             :      {"Clarke 1866", 6378206.4000, 0.08227185423947,
     387             :       2}, /* Wrong, semi-major was 6378249.4000     */
     388             :      {"Clarke 1880", 6378249.2000, 0.08248325676300,
     389             :       3}, /* Wrong, eccentricity was 0.082483256945 */
     390             :      {"GRS 80", 6378137.0000, 0.08181919104300,
     391             :       4}, /* Wrong, eccentricity was 0.081819191060 */
     392             :      {"International 1909", 6378388.0000, 0.08199188997900, 5},
     393             :      {"WGS 72", 6378135.0000, 0.08181881201777, 6},
     394             :      {"Australian National", 6378160.0000, 0.08182017998700, 7},
     395             :      {"Airy", 6377563.3960, 0.08167337387420, 8},
     396             :      {"WGS 84", 6378137.0000, 0.08181919084262, 9999},
     397             : 
     398             :      {NULL, 0, 0, -1}};
     399             : 
     400             : /* -------------------------------------------------------------------- */
     401             : /*      GCSRS API Prototypes                                            */
     402             : /* -------------------------------------------------------------------- */
     403             : 
     404             : /* -------------------------------------------------------------------- */
     405          32 : static int GCSRSAPI_CALL _areCompatibleSpheroids_GCSRS(int id1, int id2)
     406             : {
     407          32 :     if (id1 == id2)
     408           2 :         return TRUE;
     409             : 
     410          30 :     switch (id1)
     411             :     {
     412           6 :         case 4:
     413             :         case 9999:
     414             :             switch (id2)
     415             :             {
     416           6 :                 case 4:
     417             :                 case 9999:
     418           6 :                     return TRUE;
     419           0 :                 default:
     420           0 :                     break;
     421             :             }
     422           0 :             break;
     423          24 :         default:
     424          24 :             break;
     425             :     }
     426             : 
     427          24 :     return FALSE;
     428             : } /* _areCompatibleSpheroids_GCSRS */
     429             : 
     430             : /* -------------------------------------------------------------------- */
     431          88 : static int GCSRSAPI_CALL _areCompatibleDatums_GCSRS(int id1, int id2)
     432             : {
     433          88 :     if (id1 == id2)
     434           8 :         return TRUE;
     435             : 
     436          80 :     switch (id1)
     437             :     {
     438          22 :         case 1: /* NTF */
     439             :         case 13:
     440             :             switch (id2)
     441             :             {
     442           0 :                 case 1:
     443             :                 case 13:
     444           0 :                     return TRUE;
     445          22 :                 default:
     446          22 :                     break;
     447             :             }
     448          22 :             break;
     449           6 :         case 2: /* ED50 */
     450             :         case 14:
     451             :         case 9983:
     452             :         case 9985:
     453             :         case 9986:
     454             :         case 9987:
     455             :         case 9989:
     456             :         case 9991:
     457             :         case 9992:
     458             :         case 9993:
     459             :         case 9994:
     460             :         case 9995:
     461             :         case 9997:
     462             :         case 9998:
     463             :         case 9999:
     464             :             switch (id2)
     465             :             {
     466           0 :                 case 2:
     467             :                 case 14:
     468             :                 case 9983:
     469             :                 case 9985:
     470             :                 case 9986:
     471             :                 case 9987:
     472             :                 case 9989:
     473             :                 case 9991:
     474             :                 case 9992:
     475             :                 case 9993:
     476             :                 case 9994:
     477             :                 case 9995:
     478             :                 case 9997:
     479             :                 case 9998:
     480             :                 case 9999:
     481           0 :                     return TRUE;
     482           6 :                 default:
     483           6 :                     break;
     484             :             }
     485           6 :             break;
     486          45 :         case 4: /* WGS84 - ITRS89  */
     487             :         case 8:
     488             :         case 11:
     489             :         case 2015:
     490             :         case 5030:
     491             :         case 5031:
     492             :         case 5032:
     493             :         case 9984:
     494             :             switch (id2)
     495             :             {
     496          45 :                 case 4:
     497             :                 case 8:
     498             :                 case 11:
     499             :                 case 2015:
     500             :                 case 5030:
     501             :                 case 5031:
     502             :                 case 5032:
     503             :                 case 9984:
     504          45 :                     return TRUE;
     505           0 :                 default:
     506           0 :                     break;
     507             :             }
     508           0 :             break;
     509           7 :         default:
     510           7 :             break;
     511             :     }
     512             : 
     513          35 :     return FALSE;
     514             : } /* _areCompatibleDatums_GCSRS */
     515             : 
     516             : #define CPLDebugSpheroid_GCSRS(e)                                              \
     517             :     CPLDebug("GEOCONCEPT", "SemiMajor:%.4f;Eccentricity:%.10f;",               \
     518             :              GetInfoSpheroidSemiMajor_GCSRS(e),                                \
     519             :              GetInfoSpheroidExcentricity_GCSRS(e));
     520             : 
     521             : /* -------------------------------------------------------------------- */
     522             : static const GCSpheroidInfo GCSRSAPI_CALL1(*)
     523           1 :     _findSpheroid_GCSRS(double a, double rf)
     524             : {
     525           1 :     int iSpheroid, iResol = 0, nResol = 2;
     526             :     const GCSpheroidInfo *ell;
     527           1 :     double e, p[] = {1e-10, 1e-8};
     528             : 
     529             :     /* f = 1 - sqrt(1 - e^2) */
     530           1 :     e = (rf == 0.0) ? 0.0 : 1.0 / rf;
     531           1 :     e = sqrt(e * (2.0 - e));
     532           1 : ell_relax:
     533           1 :     for (iSpheroid = 0, ell = &(gk_asSpheroidList[0]);
     534           9 :          GetInfoSpheroidID_GCSRS(ell) != -1;
     535           8 :          iSpheroid++, ell = &(gk_asSpheroidList[iSpheroid]))
     536             :     {
     537           9 :         if (fabs(GetInfoSpheroidSemiMajor_GCSRS(ell) - a) > 1e-4)
     538           6 :             continue;
     539           3 :         if (fabs(GetInfoSpheroidExcentricity_GCSRS(ell) - e) > p[iResol])
     540           2 :             continue;
     541           1 :         break;
     542             :     }
     543           1 :     if (GetInfoSpheroidID_GCSRS(ell) == -1 && iResol != nResol - 1)
     544             :     {
     545           0 :         iResol++;
     546           0 :         goto ell_relax;
     547             :     }
     548             : 
     549           1 :     return ell;
     550             : } /* _findSpheroid_GCSRS */
     551             : 
     552             : #define CPLDebugDatum_GCSRS(d)                                                 \
     553             :     CPLDebug("GEOCONCEPT",                                                     \
     554             :              "ID:%d;ShiftX:%.4f;ShiftY:%.4f;ShiftZ:%.4f;DiffA:%.4f;"           \
     555             :              "DiffFlattening:%.7f;",                                           \
     556             :              GetInfoDatumID_GCSRS((d)), GetInfoDatumShiftX_GCSRS((d)),         \
     557             :              GetInfoDatumShiftY_GCSRS((d)), GetInfoDatumShiftZ_GCSRS((d)),     \
     558             :              GetInfoDatumDiffA_GCSRS((d)),                                     \
     559             :              GetInfoDatumDiffFlattening_GCSRS((d)));
     560             : 
     561             : /* -------------------------------------------------------------------- */
     562             : static const GCDatumInfo GCSRSAPI_CALL1(*)
     563           1 :     _findDatum_GCSRS(double dx, double dy, double dz, double a, double f)
     564             : {
     565           1 :     int iDatum, bRelax = FALSE;
     566             :     const GCDatumInfo *datum;
     567             : 
     568           1 : datum_relax:
     569           1 :     for (iDatum = 0, datum = &(gk_asDatumList[0]);
     570           4 :          GetInfoDatumID_GCSRS(datum) != -1;
     571           3 :          iDatum++, datum = &(gk_asDatumList[iDatum]))
     572             :     {
     573           4 :         if (!bRelax)
     574             :         {
     575           4 :             if (fabs(GetInfoDatumShiftX_GCSRS(datum) - dx) > 1e-4)
     576           2 :                 continue;
     577           2 :             if (fabs(GetInfoDatumShiftY_GCSRS(datum) - dy) > 1e-4)
     578           1 :                 continue;
     579           1 :             if (fabs(GetInfoDatumShiftZ_GCSRS(datum) - dz) > 1e-4)
     580           0 :                 continue;
     581             :         }
     582           1 :         if (fabs(GetInfoDatumDiffA_GCSRS(datum) - (6378137.0000 - a)) > 1e-4)
     583           0 :             continue;
     584           1 :         if (fabs(GetInfoDatumDiffFlattening_GCSRS(datum) -
     585           1 :                  (0.003352779565406696648 - f)) > 1e-7)
     586           0 :             continue;
     587           1 :         break;
     588             :     }
     589           1 :     if (GetInfoDatumID_GCSRS(datum) == -1 && !bRelax)
     590             :     {
     591             :         /*
     592             :          * FIXME : when both nadgrids and towgs84 are defined, bursa-wolf
     593             :          * parameters are lost ! if the projection and the ellipsoid are known,
     594             :          * one can retrieve the datum Try relaxed search ...
     595             :          */
     596           0 :         bRelax = TRUE;
     597           0 :         goto datum_relax;
     598             :     }
     599             : 
     600           1 :     return datum;
     601             : } /* _findDatum_GCSRS */
     602             : 
     603             : /* -------------------------------------------------------------------- */
     604             : static const GCProjectionInfo GCSRSAPI_CALL1(*)
     605           1 :     _findProjection_GCSRS(const char *p, double lat_ts)
     606             : {
     607             :     int iProj;
     608             :     const GCProjectionInfo *proj;
     609             : 
     610           1 :     for (iProj = 0, proj = &(gk_asProjList[0]); GetInfoProjID_GCSRS(proj) != -1;
     611           0 :          iProj++, proj = &(gk_asProjList[iProj]))
     612             :     {
     613           1 :         if (iProj == 0 && p == NULL)
     614           1 :             break;
     615           0 :         if (iProj == 1 && (EQUAL(p, SRS_PT_TRANSVERSE_MERCATOR) ||
     616           0 :                            EQUAL(p, SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED)))
     617             :             break;
     618           0 :         if (iProj == 2 && EQUAL(p, SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP))
     619           0 :             break;
     620           0 :         if (iProj == 3 && EQUAL(p, SRS_PT_BONNE))
     621           0 :             break;
     622           0 :         if (iProj == 4 && EQUAL(p, SRS_PT_EQUIRECTANGULAR) && lat_ts == 0.0)
     623           0 :             break;
     624             :         /* FIXME : iProj==6 ? */
     625           0 :         if (iProj == 7 &&
     626           0 :             (EQUAL(p, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) ||
     627           0 :              EQUAL(p, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM)))
     628             :             break;
     629           0 :         if (iProj == 8 && EQUAL(p, SRS_PT_GAUSSSCHREIBERTMERCATOR))
     630           0 :             break;
     631           0 :         if (iProj == 9 && EQUAL(p, SRS_PT_POLYCONIC))
     632           0 :             break;
     633             :         /* FIXME
     634             :         if( iProj==10 &&
     635             :             ( EQUAL(p,SRS_PT_MERCATOR_1SP) ||
     636             :               EQUAL(p,SRS_PT_MERCATOR_2SP) ) )
     637             :           break;
     638             :          */
     639           0 :         if (iProj == 11 && (EQUAL(p, SRS_PT_OBLIQUE_STEREOGRAPHIC) ||
     640           0 :                             EQUAL(p, SRS_PT_POLAR_STEREOGRAPHIC)))
     641             :             break;
     642           0 :         if (iProj == 12 && EQUAL(p, SRS_PT_MILLER_CYLINDRICAL))
     643           0 :             break;
     644             :         /* FIXME
     645             :         if( iProj==13 &&
     646             :             ( EQUAL(p,SRS_PT_HOTINE_OBLIQUE_MERCATOR) ||
     647             :               EQUAL(p,SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN)
     648             :         || EQUAL(p,SRS_PT_LABORDE_OBLIQUE_MERCATOR) ) ) break;
     649             :          */
     650           0 :         if (iProj == 14 && EQUAL(p, SRS_PT_EQUIRECTANGULAR) && lat_ts != 0.0)
     651           0 :             break;
     652             :     }
     653             : 
     654           1 :     return proj;
     655             : } /* _findProjection_GCSRS */
     656             : 
     657             : #define CPLDebugSysCoord_GCSRS(m, s)                                           \
     658             :     CPLDebug(                                                                  \
     659             :         "GEOCONCEPT",                                                          \
     660             :         "[%s]ID=%d;Zone=%d;DatumID=%d;ProjID=%d;PrimeMeridian=%.10f;"          \
     661             :         "CentralMeridian=%.10f;LatitudeOfOrigin=%.10f;StandardParallel1=%."    \
     662             :         "10f;StandardParallel2=%.10f;ScaleFactor=%.10f;FalseEasting=%.10f;"    \
     663             :         "FalseNorthing=%.10f;",                                                \
     664             :         (m) ? (m) : "", GetSysCoordSystemID_GCSRS((s)),                        \
     665             :         GetSysCoordTimeZone_GCSRS((s)), GetSysCoordDatumID_GCSRS((s)),         \
     666             :         GetSysCoordProjID_GCSRS((s)), GetSysCoordPrimeMeridian_GCSRS((s)),     \
     667             :         GetSysCoordCentralMeridian_GCSRS((s)),                                 \
     668             :         GetSysCoordLatitudeOfOrigin_GCSRS((s)),                                \
     669             :         GetSysCoordStandardParallel1_GCSRS((s)),                               \
     670             :         GetSysCoordStandardParallel2_GCSRS((s)),                               \
     671             :         GetSysCoordScaleFactor_GCSRS((s)), GetSysCoordFalseEasting_GCSRS((s)), \
     672             :         GetSysCoordFalseNorthing_GCSRS((s)));
     673             : 
     674             : /* -------------------------------------------------------------------- */
     675           1 : static GCSysCoord GCSRSAPI_CALL1(*) _findSysCoord_GCSRS(GCSysCoord *theSysCoord)
     676             : {
     677           1 :     int iSysCoord, bestSysCoord = -1;
     678             :     const GCSysCoord *gcsc;
     679             : 
     680           1 :     if (!theSysCoord)
     681           0 :         return NULL;
     682             : 
     683           1 :     SetSysCoordSystemID_GCSRS(theSysCoord, -1);
     684           1 :     SetSysCoordTimeZone_GCSRS(theSysCoord, -1);
     685           1 :     CPLDebugSysCoord_GCSRS(NULL, theSysCoord);
     686           1 :     for (iSysCoord = 0, gcsc = &(gk_asSysCoordList[0]);
     687          89 :          GetSysCoordSystemID_GCSRS(gcsc) != -1;
     688          88 :          iSysCoord++, gcsc = &(gk_asSysCoordList[iSysCoord]))
     689             :     {
     690          88 :         if (!_areCompatibleDatums_GCSRS(GetSysCoordDatumID_GCSRS(gcsc),
     691             :                                         GetSysCoordDatumID_GCSRS(theSysCoord)))
     692          35 :             continue;
     693             : 
     694          53 :         if (GetSysCoordProjID_GCSRS(gcsc) !=
     695          53 :             GetSysCoordProjID_GCSRS(theSysCoord))
     696          42 :             continue;
     697             : 
     698          11 :         if (fabs(GetSysCoordPrimeMeridian_GCSRS(gcsc) -
     699          11 :                  GetSysCoordPrimeMeridian_GCSRS(theSysCoord)) > 1e-8)
     700           0 :             continue;
     701             : 
     702          11 :         if (fabs(GetSysCoordCentralMeridian_GCSRS(gcsc) -
     703          11 :                  GetSysCoordCentralMeridian_GCSRS(theSysCoord)) > 1e-8)
     704             :         {
     705             :             /* UTM family: central meridian is the 6* zone - 183 (in degrees) */
     706           0 :             if (GetSysCoordProjID_GCSRS(gcsc) == 1 &&
     707             :                 /* generic UTM definition */
     708           0 :                 GetSysCoordCentralMeridian_GCSRS(gcsc) == 0.0)
     709             :             {
     710             :                 /* go on */
     711             :             }
     712             :             else
     713             :             {
     714           0 :                 continue;
     715             :             }
     716             :         }
     717          11 :         if (fabs(GetSysCoordLatitudeOfOrigin_GCSRS(gcsc) -
     718          11 :                  GetSysCoordLatitudeOfOrigin_GCSRS(theSysCoord)) > 1e-8)
     719           0 :             continue;
     720             : 
     721          11 :         if (fabs(GetSysCoordStandardParallel1_GCSRS(gcsc) -
     722          11 :                  GetSysCoordStandardParallel1_GCSRS(theSysCoord)) > 1e-8)
     723           0 :             continue;
     724          11 :         if (fabs(GetSysCoordStandardParallel2_GCSRS(gcsc) -
     725          11 :                  GetSysCoordStandardParallel2_GCSRS(theSysCoord)) > 1e-8)
     726           0 :             continue;
     727             : 
     728          11 :         if (fabs(GetSysCoordScaleFactor_GCSRS(gcsc) -
     729          11 :                  GetSysCoordScaleFactor_GCSRS(theSysCoord)) > 1e-8)
     730           0 :             continue;
     731             : 
     732          11 :         if (fabs(GetSysCoordFalseEasting_GCSRS(gcsc) -
     733          11 :                  GetSysCoordFalseEasting_GCSRS(theSysCoord)) > 1e-4)
     734           0 :             continue;
     735          11 :         if (fabs(GetSysCoordFalseNorthing_GCSRS(gcsc) -
     736          11 :                  GetSysCoordFalseNorthing_GCSRS(theSysCoord)) > 1e-4)
     737           0 :             continue;
     738             : 
     739             :         /* Found a candidate : */
     740          11 :         if (bestSysCoord == -1)
     741             :         {
     742           1 :             bestSysCoord = iSysCoord;
     743             :         }
     744             :         else
     745             :         {
     746          10 :             switch (GetSysCoordProjID_GCSRS(gcsc))
     747             :             {
     748          10 :                 case 0: /* long/lat */
     749          10 :                     if (GetSysCoordDatumID_GCSRS(gcsc) ==
     750          10 :                             GetSysCoordDatumID_GCSRS(theSysCoord) &&
     751           2 :                         GetSysCoordDatumID_GCSRS(
     752             :                             &(gk_asSysCoordList[bestSysCoord])) !=
     753           2 :                             GetSysCoordDatumID_GCSRS(
     754             :                                 theSysCoord)) /* exact match */
     755             :                     {
     756           0 :                         bestSysCoord = iSysCoord;
     757             :                     }
     758          10 :                     break;
     759           0 :                 case 1: /* UTM family: central meridian is the 6* zone - 183 (in
     760             :                            degrees) */
     761           0 :                     if (GetSysCoordCentralMeridian_GCSRS(gcsc) != 0.0 &&
     762           0 :                         GetSysCoordDatumID_GCSRS(gcsc) ==
     763           0 :                             GetSysCoordDatumID_GCSRS(theSysCoord) &&
     764           0 :                         GetSysCoordDatumID_GCSRS(
     765             :                             &(gk_asSysCoordList[bestSysCoord])) !=
     766           0 :                             GetSysCoordDatumID_GCSRS(
     767             :                                 theSysCoord)) /* exact match */
     768             :                     {
     769           0 :                         bestSysCoord = iSysCoord;
     770             :                     }
     771           0 :                     break;
     772           0 :                 default:
     773           0 :                     break;
     774             :             }
     775             :         }
     776             :     }
     777             :     /* Seems to be the right Geoconcept system: */
     778           1 :     if (bestSysCoord >= 0)
     779             :     {
     780           1 :         gcsc = &(gk_asSysCoordList[bestSysCoord]);
     781           1 :         switch (GetSysCoordSystemID_GCSRS(gcsc))
     782             :         {
     783           0 :             case 99912: /* hack */
     784           0 :                 SetSysCoordSystemID_GCSRS(theSysCoord, 12);
     785           0 :                 break;
     786           1 :             default:
     787           1 :                 SetSysCoordSystemID_GCSRS(theSysCoord,
     788             :                                           GetSysCoordSystemID_GCSRS(gcsc));
     789           1 :                 break;
     790             :         }
     791           1 :         SetSysCoordTimeZone_GCSRS(theSysCoord, GetSysCoordTimeZone_GCSRS(gcsc));
     792           1 :         if (GetSysCoordName_GCSRS(gcsc))
     793           1 :             SetSysCoordName_GCSRS(theSysCoord, GetSysCoordName_GCSRS(gcsc));
     794           1 :         if (GetSysCoordUnit_GCSRS(gcsc))
     795           1 :             SetSysCoordUnit_GCSRS(theSysCoord, GetSysCoordUnit_GCSRS(gcsc));
     796             :     }
     797             : 
     798           1 :     return theSysCoord;
     799             : } /* _findSysCoord_GCSRS */
     800             : 
     801             : /* -------------------------------------------------------------------- */
     802          18 : static void GCSRSAPI_CALL _InitSysCoord_GCSRS(GCSysCoord *theSysCoord)
     803             : {
     804          18 :     SetSysCoordSystemID_GCSRS(theSysCoord, -1);
     805          18 :     SetSysCoordTimeZone_GCSRS(theSysCoord, -1);
     806          18 :     SetSysCoordName_GCSRS(theSysCoord, NULL);
     807          18 :     SetSysCoordUnit_GCSRS(theSysCoord, NULL);
     808          18 :     SetSysCoordCentralMeridian_GCSRS(theSysCoord, 0.0);
     809          18 :     SetSysCoordLatitudeOfOrigin_GCSRS(theSysCoord, 0.0);
     810          18 :     SetSysCoordStandardParallel1_GCSRS(theSysCoord, 0.0);
     811          18 :     SetSysCoordStandardParallel2_GCSRS(theSysCoord, 0.0);
     812          18 :     SetSysCoordScaleFactor_GCSRS(theSysCoord, 0.0);
     813          18 :     SetSysCoordFalseEasting_GCSRS(theSysCoord, 0.0);
     814          18 :     SetSysCoordFalseNorthing_GCSRS(theSysCoord, 0.0);
     815          18 :     SetSysCoordDatumID_GCSRS(theSysCoord, -1);
     816          18 :     SetSysCoordProjID_GCSRS(theSysCoord, -1);
     817          18 :     SetSysCoordPrimeMeridian_GCSRS(theSysCoord, 0);
     818          18 : } /* _InitSysCoord_GCSRS */
     819             : 
     820             : /* -------------------------------------------------------------------- */
     821           9 : GCSysCoord GCSRSAPI_CALL1(*) CreateSysCoord_GCSRS(int srsid, int nTimezone)
     822             : {
     823             :     int iSysCoord;
     824             :     GCSysCoord *theSysCoord;
     825             :     const GCSysCoord *gcsc;
     826             : 
     827           9 :     if (!(theSysCoord = VSI_MALLOC_VERBOSE(sizeof(GCSysCoord))))
     828             :     {
     829           0 :         return NULL;
     830             :     }
     831           9 :     _InitSysCoord_GCSRS(theSysCoord);
     832           9 :     if (srsid >= 0)
     833             :     {
     834           8 :         for (iSysCoord = 0, gcsc = &(gk_asSysCoordList[0]);
     835         184 :              GetSysCoordSystemID_GCSRS(gcsc) != -1;
     836         176 :              iSysCoord++, gcsc = &(gk_asSysCoordList[iSysCoord]))
     837             :         {
     838         184 :             if (srsid == GetSysCoordSystemID_GCSRS(gcsc))
     839             :             {
     840           8 :                 SetSysCoordSystemID_GCSRS(theSysCoord, srsid);
     841           8 :                 SetSysCoordTimeZone_GCSRS(theSysCoord, nTimezone);
     842           8 :                 if (GetSysCoordName_GCSRS(gcsc))
     843           8 :                     SetSysCoordName_GCSRS(theSysCoord,
     844             :                                           GetSysCoordName_GCSRS(gcsc));
     845           8 :                 if (GetSysCoordUnit_GCSRS(gcsc))
     846           2 :                     SetSysCoordUnit_GCSRS(theSysCoord,
     847             :                                           GetSysCoordUnit_GCSRS(gcsc));
     848           8 :                 SetSysCoordCentralMeridian_GCSRS(
     849             :                     theSysCoord, GetSysCoordCentralMeridian_GCSRS(gcsc));
     850           8 :                 SetSysCoordLatitudeOfOrigin_GCSRS(
     851             :                     theSysCoord, GetSysCoordLatitudeOfOrigin_GCSRS(gcsc));
     852           8 :                 SetSysCoordStandardParallel1_GCSRS(
     853             :                     theSysCoord, GetSysCoordStandardParallel1_GCSRS(gcsc));
     854           8 :                 SetSysCoordStandardParallel2_GCSRS(
     855             :                     theSysCoord, GetSysCoordStandardParallel2_GCSRS(gcsc));
     856           8 :                 SetSysCoordScaleFactor_GCSRS(
     857             :                     theSysCoord, GetSysCoordScaleFactor_GCSRS(gcsc));
     858           8 :                 SetSysCoordFalseEasting_GCSRS(
     859             :                     theSysCoord, GetSysCoordFalseEasting_GCSRS(gcsc));
     860           8 :                 SetSysCoordFalseNorthing_GCSRS(
     861             :                     theSysCoord, GetSysCoordFalseNorthing_GCSRS(gcsc));
     862           8 :                 SetSysCoordDatumID_GCSRS(theSysCoord,
     863             :                                          GetSysCoordDatumID_GCSRS(gcsc));
     864           8 :                 SetSysCoordProjID_GCSRS(theSysCoord,
     865             :                                         GetSysCoordProjID_GCSRS(gcsc));
     866           8 :                 break;
     867             :             }
     868             :         }
     869             :     }
     870             : 
     871           9 :     return theSysCoord;
     872             : } /* CreateSysCoord_GCSRS */
     873             : 
     874             : /* -------------------------------------------------------------------- */
     875           9 : static void GCSRSAPI_CALL _ReInitSysCoord_GCSRS(GCSysCoord *theSysCoord)
     876             : {
     877           9 :     _InitSysCoord_GCSRS(theSysCoord);
     878           9 : } /* _ReInitSysCoord_GCSRS */
     879             : 
     880             : /* -------------------------------------------------------------------- */
     881           9 : void GCSRSAPI_CALL DestroySysCoord_GCSRS(GCSysCoord **theSysCoord)
     882             : {
     883           9 :     _ReInitSysCoord_GCSRS(*theSysCoord);
     884           9 :     CPLFree(*theSysCoord);
     885           9 :     *theSysCoord = NULL;
     886           9 : } /* DestroySysCoord_GCSRS */
     887             : 
     888             : /* -------------------------------------------------------------------- */
     889             : GCSysCoord GCSRSAPI_CALL1(*)
     890           1 :     OGRSpatialReference2SysCoord_GCSRS(OGRSpatialReferenceH poSR)
     891             : {
     892           1 :     char *pszProj4 = NULL;
     893           1 :     const GCSpheroidInfo *ell = NULL;
     894           1 :     const GCDatumInfo *datum = NULL;
     895           1 :     const GCProjectionInfo *gcproj = NULL;
     896             :     double a, rf, f, p[7];
     897           1 :     GCSysCoord *syscoord = NULL;
     898             : 
     899           1 :     if (!poSR)
     900           0 :         return NULL;
     901             : 
     902           1 :     pszProj4 = NULL;
     903           1 :     OSRExportToProj4(poSR, &pszProj4);
     904           1 :     if (!pszProj4)
     905           0 :         pszProj4 = CPLStrdup("");
     906             : 
     907           1 :     CPLDebug("GEOCONCEPT", "SRS : %s", pszProj4);
     908             : 
     909           1 :     if (!(syscoord = CreateSysCoord_GCSRS(-1, -1)))
     910             :     {
     911           0 :         goto onError;
     912             :     }
     913           1 :     SetSysCoordPrimeMeridian_GCSRS(syscoord, OSRGetPrimeMeridian(poSR, NULL));
     914             : 
     915           1 :     a = OSRGetSemiMajor(poSR, NULL);
     916           1 :     rf = OSRGetInvFlattening(poSR, NULL);
     917           1 :     ell = _findSpheroid_GCSRS(a, rf);
     918           1 :     if (GetInfoSpheroidID_GCSRS(ell) == -1)
     919             :     {
     920           0 :         CPLDebug("GEOCONCEPT", "Unsupported ellipsoid : %.4f %.10f", a, rf);
     921           0 :         goto onError;
     922             :     }
     923           1 :     CPLDebug("GEOCONCEPT", "ellipsoid found : %s",
     924             :              GetInfoSpheroidName_GCSRS(ell));
     925             : 
     926           1 :     OSRGetTOWGS84(poSR, p, 7);
     927           1 :     f = 1.0 - sqrt(1.0 - GetInfoSpheroidExcentricity_GCSRS(ell) *
     928           1 :                              GetInfoSpheroidExcentricity_GCSRS(ell));
     929           1 :     datum = _findDatum_GCSRS(p[0], p[1], p[2],
     930             :                              GetInfoSpheroidSemiMajor_GCSRS(ell), f);
     931           1 :     if (GetInfoDatumID_GCSRS(datum) == -1)
     932             :     {
     933           0 :         CPLDebug("GEOCONCEPT",
     934             :                  "Unsupported datum : %.4f %.4f; %.4f a=%.4f rf=%.10f", p[0],
     935             :                  p[1], p[2], a, rf);
     936           0 :         goto onError;
     937             :     }
     938             :     /* FIXME : WGS 84 and GRS 80 assimilation by Geoconcept : */
     939           1 :     if (GetInfoSpheroidID_GCSRS(ell) == 4) /* GRS 80 */
     940             :     {
     941           0 :         datum = &(gk_asDatumList[31]);
     942             :     }
     943           1 :     else if (GetInfoSpheroidID_GCSRS(ell) == 9999) /* WGS 84 */
     944             :     {
     945           1 :         datum = &(gk_asDatumList[3]);
     946             :     }
     947           1 :     CPLDebug("GEOCONCEPT", "datum found : %s", GetInfoDatumName_GCSRS(datum));
     948           1 :     SetSysCoordDatumID_GCSRS(syscoord, GetInfoDatumID_GCSRS(datum));
     949             : 
     950           2 :     gcproj = _findProjection_GCSRS(
     951           1 :         OSRIsGeographic(poSR) ? NULL : OSRGetAttrValue(poSR, "PROJECTION", 0),
     952             :         OSRGetProjParm(poSR, SRS_PP_PSEUDO_STD_PARALLEL_1, 0.0, NULL));
     953           1 :     if (GetInfoProjID_GCSRS(gcproj) == -1)
     954             :     {
     955           0 :         CPLDebug("GEOCONCEPT", "Unsupported projection : %s",
     956           0 :                  OSRIsGeographic(poSR)
     957             :                      ? "GEOCS"
     958           0 :                      : OSRGetAttrValue(poSR, "PROJECTION", 0));
     959           0 :         goto onError;
     960             :     }
     961           1 :     CPLDebug("GEOCONCEPT", "projection : %s", GetInfoProjName_GCSRS(gcproj));
     962           1 :     SetSysCoordProjID_GCSRS(syscoord, GetInfoProjID_GCSRS(gcproj));
     963             : 
     964             :     /* then overwrite them with projection specific parameters ... */
     965           1 :     if (OSRIsProjected(poSR))
     966             :     {
     967             :         double v;
     968             : 
     969           0 :         SetSysCoordPrimeMeridian_GCSRS(syscoord,
     970             :                                        OSRGetPrimeMeridian(poSR, NULL));
     971           0 :         SetSysCoordCentralMeridian_GCSRS(
     972             :             syscoord, OSRGetProjParm(poSR, SRS_PP_CENTRAL_MERIDIAN, 0.0, NULL));
     973           0 :         SetSysCoordLatitudeOfOrigin_GCSRS(
     974             :             syscoord,
     975             :             OSRGetProjParm(poSR, SRS_PP_LATITUDE_OF_ORIGIN, 0.0, NULL));
     976           0 :         SetSysCoordStandardParallel1_GCSRS(
     977             :             syscoord,
     978             :             OSRGetProjParm(poSR, SRS_PP_STANDARD_PARALLEL_1, 0.0, NULL));
     979           0 :         SetSysCoordStandardParallel2_GCSRS(
     980             :             syscoord,
     981             :             OSRGetProjParm(poSR, SRS_PP_STANDARD_PARALLEL_2, 0.0, NULL));
     982           0 :         SetSysCoordFalseEasting_GCSRS(
     983             :             syscoord, OSRGetProjParm(poSR, SRS_PP_FALSE_EASTING, 0.0, NULL));
     984           0 :         SetSysCoordFalseNorthing_GCSRS(
     985             :             syscoord, OSRGetProjParm(poSR, SRS_PP_FALSE_NORTHING, 0.0, NULL));
     986           0 :         if ((v = OSRGetProjParm(poSR, SRS_PP_SCALE_FACTOR, 0.0, NULL)) != 0.0)
     987             :         {
     988           0 :             SetSysCoordScaleFactor_GCSRS(syscoord, v);
     989             :         }
     990           0 :         if ((v = OSRGetProjParm(poSR, SRS_PP_PSEUDO_STD_PARALLEL_1, 0.0,
     991             :                                 NULL)) != 0.0)
     992             :         {
     993             :             /* should be SRS_PT_EQUIRECTANGULAR : */
     994           0 :             SetSysCoordScaleFactor_GCSRS(syscoord, cos(v * M_PI / 180.0));
     995           0 :             SetSysCoordStandardParallel1_GCSRS(
     996             :                 syscoord, v); /* allow keeping lat_ts sign */
     997             :         }
     998             :     }
     999             : 
    1000             :     /* Retrieve the syscoord : */
    1001           1 :     if (!_findSysCoord_GCSRS(syscoord))
    1002             :     {
    1003           0 :         CPLDebug("GEOCONCEPT", "invalid syscoord ?!");
    1004           0 :         goto onError;
    1005             :     }
    1006           1 :     if (GetSysCoordSystemID_GCSRS(syscoord) == -1)
    1007             :     {
    1008           0 :         CPLDebug("GEOCONCEPT", "Cannot find syscoord");
    1009           0 :         goto onError;
    1010             :     }
    1011             :     /* when SRS_PT_TRANSVERSE_MERCATOR, get zone : */
    1012           1 :     if (GetSysCoordTimeZone_GCSRS(syscoord) == 0)
    1013             :     {
    1014           0 :         int pbNorth = 1;
    1015           0 :         SetSysCoordTimeZone_GCSRS(syscoord, OSRGetUTMZone(poSR, &pbNorth));
    1016             :     }
    1017             : 
    1018           1 :     if (pszProj4)
    1019             :     {
    1020           1 :         CPLFree(pszProj4);
    1021             :     }
    1022           1 :     CPLDebug("GEOCONCEPT", "SysCoord value: %d:%d",
    1023           1 :              GetSysCoordSystemID_GCSRS(syscoord),
    1024           1 :              GetSysCoordTimeZone_GCSRS(syscoord));
    1025             : 
    1026           1 :     return syscoord;
    1027             : 
    1028           0 : onError:
    1029           0 :     if (pszProj4)
    1030             :     {
    1031           0 :         CPLDebug("GEOCONCEPT", "Unhandled spatial reference system '%s'.",
    1032             :                  pszProj4);
    1033           0 :         CPLFree(pszProj4);
    1034             :     }
    1035           0 :     if (syscoord)
    1036             :     {
    1037           0 :         DestroySysCoord_GCSRS(&syscoord);
    1038             :     }
    1039           0 :     return NULL;
    1040             : } /* OGRSpatialReference2SysCoord_GCSRS */
    1041             : 
    1042             : /* -------------------------------------------------------------------- */
    1043             : OGRSpatialReferenceH GCSRSAPI_CALL
    1044           8 : SysCoord2OGRSpatialReference_GCSRS(GCSysCoord *syscoord)
    1045             : {
    1046             :     OGRSpatialReferenceH poSR;
    1047           8 :     const GCDatumInfo *datum = NULL;
    1048           8 :     const GCSpheroidInfo *ell = NULL;
    1049             :     int i;
    1050             :     double f;
    1051             : 
    1052           8 :     poSR = OSRNewSpatialReference(NULL);
    1053           8 :     OSRSetAxisMappingStrategy(poSR, OAMS_TRADITIONAL_GIS_ORDER);
    1054             : 
    1055           8 :     if (syscoord && GetSysCoordSystemID_GCSRS(syscoord) != -1)
    1056             :     {
    1057           8 :         switch (GetSysCoordProjID_GCSRS(syscoord))
    1058             :         {
    1059           2 :             case 0: /* long/lat */
    1060           2 :                 break;
    1061           4 :             case 1:  /* UTM */
    1062             :             case 11: /* MGRS */
    1063             :             case 12: /* TM */
    1064           4 :                 OSRSetTM(poSR, GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1065             :                          GetSysCoordCentralMeridian_GCSRS(syscoord),
    1066             :                          GetSysCoordScaleFactor_GCSRS(syscoord),
    1067             :                          GetSysCoordFalseEasting_GCSRS(syscoord),
    1068             :                          GetSysCoordFalseNorthing_GCSRS(syscoord));
    1069           4 :                 break;
    1070           0 :             case 2: /* LCC 1SP */
    1071           0 :                 OSRSetLCC1SP(poSR, GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1072             :                              GetSysCoordCentralMeridian_GCSRS(syscoord),
    1073             :                              GetSysCoordScaleFactor_GCSRS(syscoord),
    1074             :                              GetSysCoordFalseEasting_GCSRS(syscoord),
    1075             :                              GetSysCoordFalseNorthing_GCSRS(syscoord));
    1076           0 :                 break;
    1077           0 :             case 3: /* Bonne */
    1078           0 :                 OSRSetBonne(poSR, GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1079             :                             GetSysCoordCentralMeridian_GCSRS(syscoord),
    1080             :                             GetSysCoordFalseEasting_GCSRS(syscoord),
    1081             :                             GetSysCoordFalseNorthing_GCSRS(syscoord));
    1082           0 :                 break;
    1083           0 :             case 4: /* Plate Caree */
    1084           0 :                 OSRSetEquirectangular(
    1085             :                     poSR, GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1086             :                     GetSysCoordCentralMeridian_GCSRS(syscoord),
    1087             :                     GetSysCoordFalseEasting_GCSRS(syscoord),
    1088             :                     GetSysCoordFalseNorthing_GCSRS(syscoord));
    1089           0 :                 break;
    1090           2 :             case 18: /* LCC 2SP */
    1091           2 :                 OSRSetLCC(poSR, GetSysCoordStandardParallel1_GCSRS(syscoord),
    1092             :                           GetSysCoordStandardParallel2_GCSRS(syscoord),
    1093             :                           GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1094             :                           GetSysCoordCentralMeridian_GCSRS(syscoord),
    1095             :                           GetSysCoordFalseEasting_GCSRS(syscoord),
    1096             :                           GetSysCoordFalseNorthing_GCSRS(syscoord));
    1097           2 :                 break;
    1098           0 :             case 19: /* Gauss Schreiber : Reunion */
    1099           0 :                 OSRSetGaussSchreiberTMercator(
    1100             :                     poSR, GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1101             :                     GetSysCoordCentralMeridian_GCSRS(syscoord),
    1102             :                     GetSysCoordScaleFactor_GCSRS(syscoord),
    1103             :                     GetSysCoordFalseEasting_GCSRS(syscoord),
    1104             :                     GetSysCoordFalseNorthing_GCSRS(syscoord));
    1105           0 :                 break;
    1106           0 :             case 20: /* Polyconic */
    1107           0 :                 OSRSetPolyconic(poSR,
    1108             :                                 GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1109             :                                 GetSysCoordCentralMeridian_GCSRS(syscoord),
    1110             :                                 GetSysCoordFalseEasting_GCSRS(syscoord),
    1111             :                                 GetSysCoordFalseNorthing_GCSRS(syscoord));
    1112           0 :                 break;
    1113           0 :             case 21: /* Direct Mercator */
    1114           0 :                 OSRSetMercator(poSR,
    1115             :                                GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1116             :                                GetSysCoordCentralMeridian_GCSRS(syscoord),
    1117             :                                GetSysCoordScaleFactor_GCSRS(syscoord),
    1118             :                                GetSysCoordFalseEasting_GCSRS(syscoord),
    1119             :                                GetSysCoordFalseNorthing_GCSRS(syscoord));
    1120           0 :                 break;
    1121           0 :             case 22: /* Stereographic oblic */
    1122           0 :                 OSRSetOS(poSR, GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1123             :                          GetSysCoordCentralMeridian_GCSRS(syscoord),
    1124             :                          GetSysCoordScaleFactor_GCSRS(syscoord),
    1125             :                          GetSysCoordFalseEasting_GCSRS(syscoord),
    1126             :                          GetSysCoordFalseNorthing_GCSRS(syscoord));
    1127           0 :                 break;
    1128           0 :             case 24: /* Miller */
    1129           0 :                 OSRSetMC(poSR, GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1130             :                          GetSysCoordCentralMeridian_GCSRS(syscoord),
    1131             :                          GetSysCoordFalseEasting_GCSRS(syscoord),
    1132             :                          GetSysCoordFalseNorthing_GCSRS(syscoord));
    1133           0 :                 break;
    1134           0 :             case 26: /* Equi rectangular */
    1135           0 :                 OSRSetEquirectangular2(
    1136             :                     poSR, GetSysCoordLatitudeOfOrigin_GCSRS(syscoord),
    1137             :                     GetSysCoordCentralMeridian_GCSRS(syscoord),
    1138             :                     GetSysCoordStandardParallel1_GCSRS(syscoord),
    1139             :                     GetSysCoordFalseEasting_GCSRS(syscoord),
    1140             :                     GetSysCoordFalseNorthing_GCSRS(syscoord));
    1141           0 :                 break;
    1142           0 :             default:
    1143           0 :                 break;
    1144             :         }
    1145           8 :         if (GetSysCoordProjID_GCSRS(syscoord) > 0)
    1146           6 :             OSRSetProjCS(poSR, GetSysCoordName_GCSRS(syscoord));
    1147             : 
    1148           8 :         for (i = 0, datum = &(gk_asDatumList[0]);
    1149          88 :              GetInfoDatumID_GCSRS(datum) != -1;
    1150          80 :              i++, datum = &(gk_asDatumList[i]))
    1151             :         {
    1152          88 :             if (GetInfoDatumID_GCSRS(datum) ==
    1153          88 :                 GetSysCoordDatumID_GCSRS(syscoord))
    1154           8 :                 break;
    1155             :         }
    1156           8 :         for (i = 0, ell = &(gk_asSpheroidList[0]);
    1157          32 :              GetInfoSpheroidID_GCSRS(ell) != -1;
    1158          24 :              i++, ell = &(gk_asSpheroidList[i]))
    1159             :         {
    1160          32 :             if (_areCompatibleSpheroids_GCSRS(
    1161             :                     GetInfoSpheroidID_GCSRS(ell),
    1162             :                     GetInfoDatumSpheroidID_GCSRS(datum)))
    1163           8 :                 break;
    1164             :         }
    1165             :         /* FIXME : WGS 84 and GRS 80 assimilation by Geoconcept : */
    1166           8 :         if (GetInfoDatumID_GCSRS(datum) == 4) /* WGS 84 */
    1167             :         {
    1168           6 :             ell = &(gk_asSpheroidList[8]);
    1169             :         }
    1170           2 :         else if (GetInfoDatumID_GCSRS(datum) == 9984) /* GRS 80 */
    1171             :         {
    1172           2 :             ell = &(gk_asSpheroidList[3]);
    1173             :         }
    1174           8 :         f = 1.0 - sqrt(1.0 - GetInfoSpheroidExcentricity_GCSRS(ell) *
    1175           8 :                                  GetInfoSpheroidExcentricity_GCSRS(ell));
    1176          48 :         OSRSetGeogCS(
    1177             :             poSR,
    1178           8 :             GetSysCoordProjID_GCSRS(syscoord) != 0 ||
    1179           2 :                     !GetSysCoordName_GCSRS(syscoord)
    1180             :                 ? "unnamed"
    1181             :                 : GetSysCoordName_GCSRS(syscoord),
    1182           8 :             GetInfoDatumID_GCSRS(datum) >= 0 ? GetInfoDatumName_GCSRS(datum)
    1183             :                                              : "unknown",
    1184           8 :             GetInfoSpheroidID_GCSRS(ell) >= 0 ? GetInfoSpheroidName_GCSRS(ell)
    1185             :                                               : "unknown",
    1186           8 :             GetInfoSpheroidID_GCSRS(ell) >= 0
    1187             :                 ? GetInfoSpheroidSemiMajor_GCSRS(ell)
    1188             :                 : 6378137.0,
    1189           8 :             GetInfoSpheroidID_GCSRS(ell) >= 0 ? (f == 0 ? 0 : 1 / f)
    1190             :                                               : 298.257223563,
    1191             :             "Greenwich", GetSysCoordPrimeMeridian_GCSRS(syscoord),
    1192             :             SRS_UA_DEGREE, CPLAtof(SRS_UA_DEGREE_CONV));
    1193             :         /* As Geoconcept uses Molodensky, we've got only 3 out of 7 params for
    1194             :          * Bursa-Wolf : */
    1195             :         /* the 4 missing Bursa-Wolf parameters have been added to the
    1196             :          * gk_asDatumList !      */
    1197           8 :         if (GetInfoProjID_GCSRS(syscoord) > 0 &&
    1198           6 :             GetInfoDatumID_GCSRS(datum) != -1)
    1199             :         {
    1200           6 :             OSRSetTOWGS84(poSR, GetInfoDatumShiftX_GCSRS(datum),
    1201             :                           GetInfoDatumShiftY_GCSRS(datum),
    1202             :                           GetInfoDatumShiftZ_GCSRS(datum),
    1203             :                           GetInfoDatumRotationX_GCSRS(datum),
    1204             :                           GetInfoDatumRotationY_GCSRS(datum),
    1205             :                           GetInfoDatumRotationZ_GCSRS(datum),
    1206           6 :                           1e6 * GetInfoDatumScaleFactor_GCSRS(datum));
    1207             :         }
    1208             :     }
    1209             : 
    1210             :     /* -------------------------------------------------------------------- */
    1211             :     /*      Report on translation.                                          */
    1212             :     /* -------------------------------------------------------------------- */
    1213             :     {
    1214             :         char *pszWKT;
    1215             : 
    1216           8 :         OSRExportToWkt(poSR, &pszWKT);
    1217           8 :         if (pszWKT != NULL)
    1218             :         {
    1219           8 :             CPLDebug("GEOCONCEPT",
    1220             :                      "This SysCoord value: %d:%d was translated to : %s",
    1221             :                      syscoord ? GetSysCoordSystemID_GCSRS(syscoord) : -1,
    1222             :                      syscoord ? GetSysCoordTimeZone_GCSRS(syscoord) : -1,
    1223             :                      pszWKT);
    1224           8 :             CPLFree(pszWKT);
    1225             :         }
    1226             :     }
    1227             : 
    1228           8 :     return poSR;
    1229             : } /* SysCoord2OGRSpatialReference_GCSRS */

Generated by: LCOV version 1.14