/src/gdal/frmts/gtiff/libgeotiff/geo_names.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * geo_names.c |
3 | | * |
4 | | * This encapsulates all of the value-naming mechanism of |
5 | | * libgeotiff. |
6 | | * |
7 | | * Written By: Niles Ritter |
8 | | * |
9 | | * copyright (c) 1995 Niles D. Ritter |
10 | | * |
11 | | * Permission granted to use this software, so long as this copyright |
12 | | * notice accompanies any products derived therefrom. |
13 | | * |
14 | | */ |
15 | | |
16 | | #include "geotiffio.h" |
17 | | #include "geonames.h" |
18 | | #include "geo_tiffp.h" /* for tag names */ |
19 | | #include "geo_keyp.h" |
20 | | |
21 | | #include "proj.h" |
22 | | |
23 | | static const KeyInfo _formatInfo[] = { |
24 | | {TYPE_BYTE, "Byte"}, |
25 | | {TYPE_SHORT, "Short"}, |
26 | | {TYPE_LONG, "Long"}, |
27 | | {TYPE_RATIONAL,"Rational"}, |
28 | | {TYPE_ASCII, "Ascii"}, |
29 | | {TYPE_FLOAT, "Float"}, |
30 | | {TYPE_DOUBLE, "Double"}, |
31 | | {TYPE_SBYTE, "SignedByte"}, |
32 | | {TYPE_SSHORT, "SignedShort"}, |
33 | | {TYPE_SLONG, "SignedLong"}, |
34 | | {TYPE_UNKNOWN, "Unknown"}, |
35 | | END_LIST |
36 | | }; |
37 | | |
38 | | static const KeyInfo _tagInfo[] = { |
39 | | {GTIFF_PIXELSCALE, "ModelPixelScaleTag"}, |
40 | | {GTIFF_TRANSMATRIX, "ModelTransformationTag"}, |
41 | | {GTIFF_TIEPOINTS, "ModelTiepointTag"}, |
42 | | /* This alias maps the Intergraph symbol to the current tag */ |
43 | | {GTIFF_TRANSMATRIX, "IntergraphMatrixTag"}, |
44 | | END_LIST |
45 | | }; |
46 | | |
47 | | static const char *FindName(const KeyInfo *info,int key) |
48 | 0 | { |
49 | 0 | while (info->ki_key>=0 && info->ki_key != key) info++; |
50 | |
|
51 | 0 | if (info->ki_key<0) |
52 | 0 | { |
53 | 0 | static char errmsg[80]; |
54 | 0 | sprintf(errmsg,"Unknown-%d", key ); |
55 | 0 | return errmsg; |
56 | 0 | } |
57 | 0 | return info->ki_name; |
58 | 0 | } |
59 | | |
60 | | char *GTIFKeyName(geokey_t key) |
61 | 0 | { |
62 | 0 | return (char*) FindName( &_keyInfo[0],key); |
63 | 0 | } |
64 | | |
65 | | const char* GTIFKeyNameEx(GTIF* gtif, geokey_t key) |
66 | 0 | { |
67 | 0 | const KeyInfo *info; |
68 | 0 | if( gtif->gt_version == GEOTIFF_SPEC_1_0_VERSION && |
69 | 0 | gtif->gt_rev_major == GEOTIFF_SPEC_1_0_KEY_REVISION && |
70 | 0 | gtif->gt_rev_minor == GEOTIFF_SPEC_1_0_MINOR_REVISION ) |
71 | 0 | { |
72 | 0 | info = &_keyInfo[0]; |
73 | 0 | } |
74 | 0 | else |
75 | 0 | { |
76 | 0 | info = &_keyInfoV11[0]; |
77 | 0 | } |
78 | 0 | while (info->ki_key>=0 && info->ki_key != (int)key) info++; |
79 | 0 | if (info->ki_key<0) |
80 | 0 | { |
81 | 0 | sprintf(gtif->szTmpBufferForGTIFValueNameEx,"Unknown-%d", key ); |
82 | 0 | return gtif->szTmpBufferForGTIFValueNameEx; |
83 | 0 | } |
84 | 0 | return info->ki_name; |
85 | 0 | } |
86 | | |
87 | | char *GTIFTypeName(tagtype_t type) |
88 | 0 | { |
89 | 0 | return (char*) FindName( &_formatInfo[0],type); |
90 | 0 | } |
91 | | |
92 | | char *GTIFTagName(int tag) |
93 | 0 | { |
94 | 0 | return (char*) FindName( &_tagInfo[0],tag); |
95 | 0 | } |
96 | | |
97 | | static const KeyInfo* FindTable(geokey_t key) |
98 | 0 | { |
99 | 0 | const KeyInfo *info; |
100 | |
|
101 | 0 | switch (key) |
102 | 0 | { |
103 | | /* All codes using linear/angular/whatever units */ |
104 | 0 | case GeogLinearUnitsGeoKey: |
105 | 0 | case ProjLinearUnitsGeoKey: |
106 | 0 | case GeogAngularUnitsGeoKey: |
107 | 0 | case GeogAzimuthUnitsGeoKey: |
108 | 0 | case VerticalUnitsGeoKey: |
109 | 0 | info=_geounitsValue; break; |
110 | | |
111 | | /* put other key-dependent lists here */ |
112 | 0 | case GTModelTypeGeoKey: info=_modeltypeValue; break; |
113 | 0 | case GTRasterTypeGeoKey: info=_rastertypeValue; break; |
114 | 0 | case GeographicTypeGeoKey: info=_geographicValue; break; |
115 | 0 | case GeogGeodeticDatumGeoKey: info=_geodeticdatumValue; break; |
116 | 0 | case GeogEllipsoidGeoKey: info=_ellipsoidValue; break; |
117 | 0 | case GeogPrimeMeridianGeoKey: info=_primemeridianValue; break; |
118 | 0 | case ProjectedCSTypeGeoKey: info=_pcstypeValue; break; |
119 | 0 | case ProjectionGeoKey: info=_projectionValue; break; |
120 | 0 | case ProjCoordTransGeoKey: info=_coordtransValue; break; |
121 | 0 | case VerticalCSTypeGeoKey: info=_vertcstypeValue; break; |
122 | 0 | case VerticalDatumGeoKey: info=_vdatumValue; break; |
123 | | |
124 | | /* And if all else fails... */ |
125 | 0 | default: info = _csdefaultValue;break; |
126 | 0 | } |
127 | | |
128 | 0 | return info; |
129 | 0 | } |
130 | | |
131 | | char *GTIFValueName(geokey_t key, int value) |
132 | 0 | { |
133 | |
|
134 | 0 | return (char*) FindName(FindTable(key), value); |
135 | 0 | } |
136 | | |
137 | | static void GetNameFromDatabase(GTIF* gtif, |
138 | | const char* pszCode, |
139 | | PJ_CATEGORY category, |
140 | | char* pszOut, |
141 | | size_t nOutSize) |
142 | 0 | { |
143 | 0 | PJ* obj = proj_create_from_database( |
144 | 0 | gtif->pj_context, "EPSG", pszCode, category, |
145 | 0 | FALSE, NULL); |
146 | 0 | if( obj ) |
147 | 0 | { |
148 | 0 | const char* pszName = proj_get_name(obj); |
149 | 0 | if( pszName ) |
150 | 0 | { |
151 | 0 | size_t nToCopy = MIN(strlen(pszName), nOutSize - 1); |
152 | 0 | memcpy(pszOut, pszName, nToCopy); |
153 | 0 | pszOut[nToCopy] = 0; |
154 | 0 | } |
155 | 0 | proj_destroy(obj); |
156 | 0 | } |
157 | 0 | else |
158 | 0 | { |
159 | 0 | pszOut[0] = 0; |
160 | 0 | } |
161 | 0 | } |
162 | | |
163 | | const char *GTIFValueNameEx(GTIF* gtif, geokey_t key, int value) |
164 | 0 | { |
165 | 0 | int useHardcodedTables = 0; |
166 | |
|
167 | 0 | if( value == KvUndefined || value == KvUserDefined ) |
168 | 0 | { |
169 | 0 | useHardcodedTables = 1; |
170 | 0 | } |
171 | 0 | else if( gtif->gt_version == GEOTIFF_SPEC_1_0_VERSION && |
172 | 0 | gtif->gt_rev_major == GEOTIFF_SPEC_1_0_KEY_REVISION && |
173 | 0 | gtif->gt_rev_minor == GEOTIFF_SPEC_1_0_MINOR_REVISION ) |
174 | 0 | { |
175 | 0 | useHardcodedTables = 1; |
176 | 0 | } |
177 | 0 | else if( key == GTModelTypeGeoKey || |
178 | 0 | key == GTRasterTypeGeoKey || |
179 | 0 | key == ProjCoordTransGeoKey ) |
180 | 0 | { |
181 | 0 | useHardcodedTables = 1; |
182 | 0 | } |
183 | 0 | else if( key == VerticalCSTypeGeoKey && |
184 | 0 | value >= 5001 && value <= 5033 ) |
185 | 0 | { |
186 | 0 | useHardcodedTables = 1; |
187 | 0 | } |
188 | |
|
189 | 0 | const KeyInfo *info = FindTable(key); |
190 | 0 | if( useHardcodedTables ) |
191 | 0 | { |
192 | 0 | while (info->ki_key>=0 && info->ki_key != value) info++; |
193 | 0 | } |
194 | |
|
195 | 0 | if ( !useHardcodedTables || info->ki_key<0 ) |
196 | 0 | { |
197 | 0 | sprintf(gtif->szTmpBufferForGTIFValueNameEx,"Unknown-%d", value ); |
198 | |
|
199 | 0 | if( gtif->pj_context == NULL ) |
200 | 0 | { |
201 | 0 | gtif->pj_context = proj_context_create(); |
202 | 0 | if( gtif->pj_context ) |
203 | 0 | { |
204 | 0 | gtif->own_pj_context = TRUE; |
205 | 0 | } |
206 | 0 | } |
207 | 0 | if( gtif->pj_context ) |
208 | 0 | { |
209 | 0 | char szCode[12]; |
210 | 0 | char szName[120]; |
211 | |
|
212 | 0 | szName[0] = 0; |
213 | 0 | sprintf(szCode, "%d", value); |
214 | |
|
215 | 0 | switch (key) |
216 | 0 | { |
217 | | /* All codes using linear/angular/whatever units */ |
218 | 0 | case GeogLinearUnitsGeoKey: |
219 | 0 | case ProjLinearUnitsGeoKey: |
220 | 0 | case GeogAngularUnitsGeoKey: |
221 | 0 | case GeogAzimuthUnitsGeoKey: |
222 | 0 | case VerticalUnitsGeoKey: |
223 | 0 | { |
224 | 0 | const char* pszName = NULL; |
225 | 0 | if( proj_uom_get_info_from_database(gtif->pj_context, |
226 | 0 | "EPSG", szCode, &pszName, NULL, NULL) && pszName ) |
227 | 0 | { |
228 | 0 | strncpy(szName, pszName, sizeof(szName)); |
229 | 0 | szName[sizeof(szName)-1] = 0; |
230 | 0 | } |
231 | 0 | break; |
232 | 0 | } |
233 | | |
234 | 0 | case GeogGeodeticDatumGeoKey: |
235 | 0 | case VerticalDatumGeoKey: |
236 | 0 | GetNameFromDatabase(gtif, szCode, PJ_CATEGORY_DATUM, |
237 | 0 | szName, sizeof(szName)); |
238 | 0 | break; |
239 | | |
240 | 0 | case GeogEllipsoidGeoKey: |
241 | 0 | GetNameFromDatabase(gtif, szCode, PJ_CATEGORY_ELLIPSOID, |
242 | 0 | szName, sizeof(szName)); |
243 | 0 | break; |
244 | | |
245 | 0 | case GeogPrimeMeridianGeoKey: |
246 | 0 | GetNameFromDatabase(gtif, szCode, |
247 | 0 | PJ_CATEGORY_PRIME_MERIDIAN, |
248 | 0 | szName, sizeof(szName)); |
249 | 0 | break; |
250 | | |
251 | 0 | case GeographicTypeGeoKey: |
252 | 0 | case ProjectedCSTypeGeoKey: |
253 | 0 | case VerticalCSTypeGeoKey: |
254 | 0 | GetNameFromDatabase(gtif, szCode, |
255 | 0 | PJ_CATEGORY_CRS, |
256 | 0 | szName, sizeof(szName)); |
257 | 0 | break; |
258 | | |
259 | 0 | case ProjectionGeoKey: |
260 | 0 | GetNameFromDatabase(gtif, szCode, |
261 | 0 | PJ_CATEGORY_COORDINATE_OPERATION, |
262 | 0 | szName, sizeof(szName)); |
263 | 0 | break; |
264 | | |
265 | 0 | default: |
266 | 0 | break; |
267 | 0 | } |
268 | | |
269 | 0 | if( szName[0] != 0 ) |
270 | 0 | { |
271 | 0 | sprintf(gtif->szTmpBufferForGTIFValueNameEx, |
272 | 0 | "Code-%d (%s)", value, szName ); |
273 | 0 | } |
274 | |
|
275 | 0 | } |
276 | | |
277 | 0 | return gtif->szTmpBufferForGTIFValueNameEx; |
278 | 0 | } |
279 | 0 | return info->ki_name; |
280 | 0 | } |
281 | | |
282 | | /* |
283 | | * Inverse Utilities (name->code) |
284 | | */ |
285 | | |
286 | | |
287 | | static int FindCode(const KeyInfo *info,const char *key) |
288 | 0 | { |
289 | 0 | while (info->ki_key>=0 && strcmp(info->ki_name,key) ) info++; |
290 | |
|
291 | 0 | if (info->ki_key<0) |
292 | 0 | { |
293 | | /* not a registered key; might be generic code */ |
294 | 0 | if (!strncmp(key,"Unknown-",8)) |
295 | 0 | { |
296 | 0 | int code=-1; |
297 | 0 | sscanf(key,"Unknown-%d",&code); |
298 | 0 | return code; |
299 | 0 | } else if (!strncmp(key,"Code-",5)) |
300 | 0 | { |
301 | 0 | int code=-1; |
302 | 0 | sscanf(key,"Code-%d",&code); |
303 | 0 | return code; |
304 | 0 | } |
305 | 0 | else return -1; |
306 | 0 | } |
307 | 0 | return info->ki_key; |
308 | 0 | } |
309 | | |
310 | | int GTIFKeyCode(const char *key) |
311 | 0 | { |
312 | 0 | int ret = FindCode( &_keyInfo[0],key); |
313 | 0 | if( ret < 0 ) |
314 | 0 | ret = FindCode( &_keyInfoV11[0],key); |
315 | 0 | return ret; |
316 | 0 | } |
317 | | |
318 | | int GTIFTypeCode(const char *type) |
319 | 0 | { |
320 | 0 | return FindCode( &_formatInfo[0],type); |
321 | 0 | } |
322 | | |
323 | | int GTIFTagCode(const char *tag) |
324 | 0 | { |
325 | 0 | return FindCode( &_tagInfo[0],tag); |
326 | 0 | } |
327 | | |
328 | | |
329 | | /* |
330 | | * The key must be determined with GTIFKeyCode() before |
331 | | * the name can be encoded. |
332 | | */ |
333 | | int GTIFValueCode(geokey_t key, const char *name) |
334 | 0 | { |
335 | 0 | return FindCode(FindTable(key),name); |
336 | 0 | } |