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 */
|