Line data Source code
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 636 : static const char *FindName(const KeyInfo *info,int key)
48 : {
49 16198 : while (info->ki_key>=0 && info->ki_key != key) info++;
50 :
51 636 : if (info->ki_key<0)
52 : {
53 : static char errmsg[80];
54 0 : sprintf(errmsg,"Unknown-%d", key );
55 0 : return errmsg;
56 : }
57 636 : return info->ki_name;
58 : }
59 :
60 636 : char *GTIFKeyName(geokey_t key)
61 : {
62 636 : return (char*) FindName( &_keyInfo[0],key);
63 : }
64 :
65 0 : const char* GTIFKeyNameEx(GTIF* gtif, geokey_t key)
66 : {
67 : 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 : {
72 0 : info = &_keyInfo[0];
73 : }
74 : else
75 : {
76 0 : info = &_keyInfoV11[0];
77 : }
78 0 : while (info->ki_key>=0 && info->ki_key != (int)key) info++;
79 0 : if (info->ki_key<0)
80 : {
81 0 : sprintf(gtif->szTmpBufferForGTIFValueNameEx,"Unknown-%d", key );
82 0 : return gtif->szTmpBufferForGTIFValueNameEx;
83 : }
84 0 : return info->ki_name;
85 : }
86 :
87 0 : char *GTIFTypeName(tagtype_t type)
88 : {
89 0 : return (char*) FindName( &_formatInfo[0],type);
90 : }
91 :
92 0 : char *GTIFTagName(int tag)
93 : {
94 0 : return (char*) FindName( &_tagInfo[0],tag);
95 : }
96 :
97 20 : static const KeyInfo* FindTable(geokey_t key)
98 : {
99 : const KeyInfo *info;
100 :
101 20 : switch (key)
102 : {
103 : /* All codes using linear/angular/whatever units */
104 4 : case GeogLinearUnitsGeoKey:
105 : case ProjLinearUnitsGeoKey:
106 : case GeogAngularUnitsGeoKey:
107 : case GeogAzimuthUnitsGeoKey:
108 : case VerticalUnitsGeoKey:
109 4 : info=_geounitsValue; break;
110 :
111 : /* put other key-dependent lists here */
112 2 : case GTModelTypeGeoKey: info=_modeltypeValue; break;
113 2 : case GTRasterTypeGeoKey: info=_rastertypeValue; break;
114 2 : case GeographicTypeGeoKey: info=_geographicValue; break;
115 2 : case GeogGeodeticDatumGeoKey: info=_geodeticdatumValue; break;
116 2 : case GeogEllipsoidGeoKey: info=_ellipsoidValue; break;
117 0 : case GeogPrimeMeridianGeoKey: info=_primemeridianValue; break;
118 2 : case ProjectedCSTypeGeoKey: info=_pcstypeValue; break;
119 2 : case ProjectionGeoKey: info=_projectionValue; break;
120 2 : 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 : }
127 :
128 20 : return info;
129 : }
130 :
131 0 : char *GTIFValueName(geokey_t key, int value)
132 : {
133 :
134 0 : return (char*) FindName(FindTable(key), value);
135 : }
136 :
137 0 : static void GetNameFromDatabase(GTIF* gtif,
138 : const char* pszCode,
139 : PJ_CATEGORY category,
140 : char* pszOut,
141 : size_t nOutSize)
142 : {
143 0 : PJ* obj = proj_create_from_database(
144 : gtif->pj_context, "EPSG", pszCode, category,
145 : FALSE, NULL);
146 0 : if( obj )
147 : {
148 0 : const char* pszName = proj_get_name(obj);
149 0 : if( pszName )
150 : {
151 0 : size_t nToCopy = MIN(strlen(pszName), nOutSize - 1);
152 0 : memcpy(pszOut, pszName, nToCopy);
153 0 : pszOut[nToCopy] = 0;
154 : }
155 0 : proj_destroy(obj);
156 : }
157 : else
158 : {
159 0 : pszOut[0] = 0;
160 : }
161 0 : }
162 :
163 20 : const char *GTIFValueNameEx(GTIF* gtif, geokey_t key, int value)
164 : {
165 20 : int useHardcodedTables = 0;
166 :
167 20 : if( value == KvUndefined || value == KvUserDefined )
168 : {
169 10 : useHardcodedTables = 1;
170 : }
171 10 : else if( gtif->gt_version == GEOTIFF_SPEC_1_0_VERSION &&
172 10 : gtif->gt_rev_major == GEOTIFF_SPEC_1_0_KEY_REVISION &&
173 10 : gtif->gt_rev_minor == GEOTIFF_SPEC_1_0_MINOR_REVISION )
174 : {
175 10 : useHardcodedTables = 1;
176 : }
177 0 : else if( key == GTModelTypeGeoKey ||
178 0 : key == GTRasterTypeGeoKey ||
179 : key == ProjCoordTransGeoKey )
180 : {
181 0 : useHardcodedTables = 1;
182 : }
183 0 : else if( key == VerticalCSTypeGeoKey &&
184 0 : value >= 5001 && value <= 5033 )
185 : {
186 0 : useHardcodedTables = 1;
187 : }
188 :
189 20 : const KeyInfo *info = FindTable(key);
190 20 : if( useHardcodedTables )
191 : {
192 152 : while (info->ki_key>=0 && info->ki_key != value) info++;
193 : }
194 :
195 20 : if ( !useHardcodedTables || info->ki_key<0 )
196 : {
197 0 : sprintf(gtif->szTmpBufferForGTIFValueNameEx,"Unknown-%d", value );
198 :
199 0 : if( gtif->pj_context == NULL )
200 : {
201 0 : gtif->pj_context = proj_context_create();
202 0 : if( gtif->pj_context )
203 : {
204 0 : gtif->own_pj_context = TRUE;
205 : }
206 : }
207 0 : if( gtif->pj_context )
208 : {
209 : char szCode[12];
210 : char szName[120];
211 :
212 0 : szName[0] = 0;
213 0 : sprintf(szCode, "%d", value);
214 :
215 0 : switch (key)
216 : {
217 : /* All codes using linear/angular/whatever units */
218 0 : case GeogLinearUnitsGeoKey:
219 : case ProjLinearUnitsGeoKey:
220 : case GeogAngularUnitsGeoKey:
221 : case GeogAzimuthUnitsGeoKey:
222 : case VerticalUnitsGeoKey:
223 : {
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 : {
228 0 : strncpy(szName, pszName, sizeof(szName));
229 0 : szName[sizeof(szName)-1] = 0;
230 : }
231 0 : break;
232 : }
233 :
234 0 : case GeogGeodeticDatumGeoKey:
235 : case VerticalDatumGeoKey:
236 0 : GetNameFromDatabase(gtif, szCode, PJ_CATEGORY_DATUM,
237 : szName, sizeof(szName));
238 0 : break;
239 :
240 0 : case GeogEllipsoidGeoKey:
241 0 : GetNameFromDatabase(gtif, szCode, PJ_CATEGORY_ELLIPSOID,
242 : szName, sizeof(szName));
243 0 : break;
244 :
245 0 : case GeogPrimeMeridianGeoKey:
246 0 : GetNameFromDatabase(gtif, szCode,
247 : PJ_CATEGORY_PRIME_MERIDIAN,
248 : szName, sizeof(szName));
249 0 : break;
250 :
251 0 : case GeographicTypeGeoKey:
252 : case ProjectedCSTypeGeoKey:
253 : case VerticalCSTypeGeoKey:
254 0 : GetNameFromDatabase(gtif, szCode,
255 : PJ_CATEGORY_CRS,
256 : szName, sizeof(szName));
257 0 : break;
258 :
259 0 : case ProjectionGeoKey:
260 0 : GetNameFromDatabase(gtif, szCode,
261 : PJ_CATEGORY_COORDINATE_OPERATION,
262 : szName, sizeof(szName));
263 0 : break;
264 :
265 0 : default:
266 0 : break;
267 : }
268 :
269 0 : if( szName[0] != 0 )
270 : {
271 0 : sprintf(gtif->szTmpBufferForGTIFValueNameEx,
272 : "Code-%d (%s)", value, szName );
273 : }
274 :
275 : }
276 :
277 0 : return gtif->szTmpBufferForGTIFValueNameEx;
278 : }
279 20 : return info->ki_name;
280 : }
281 :
282 : /*
283 : * Inverse Utilities (name->code)
284 : */
285 :
286 :
287 0 : static int FindCode(const KeyInfo *info,const char *key)
288 : {
289 0 : while (info->ki_key>=0 && strcmp(info->ki_name,key) ) info++;
290 :
291 0 : if (info->ki_key<0)
292 : {
293 : /* not a registered key; might be generic code */
294 0 : if (!strncmp(key,"Unknown-",8))
295 : {
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 : {
301 0 : int code=-1;
302 0 : sscanf(key,"Code-%d",&code);
303 0 : return code;
304 : }
305 0 : else return -1;
306 : }
307 0 : return info->ki_key;
308 : }
309 :
310 0 : int GTIFKeyCode(const char *key)
311 : {
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 : }
317 :
318 0 : int GTIFTypeCode(const char *type)
319 : {
320 0 : return FindCode( &_formatInfo[0],type);
321 : }
322 :
323 0 : int GTIFTagCode(const char *tag)
324 : {
325 0 : return FindCode( &_tagInfo[0],tag);
326 : }
327 :
328 :
329 : /*
330 : * The key must be determined with GTIFKeyCode() before
331 : * the name can be encoded.
332 : */
333 0 : int GTIFValueCode(geokey_t key, const char *name)
334 : {
335 0 : return FindCode(FindTable(key),name);
336 : }
|