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

Generated by: LCOV version 1.14