1 /**********************************************************************
2 *
3 * geo_get.c -- Public routines for GEOTIFF GeoKey access.
4 *
5 * Written By: Niles D. Ritter.
6 *
7 * copyright (c) 1995 Niles D. Ritter
8 *
9 * Permission granted to use this software, so long as this copyright
10 * notice accompanies any products derived therefrom.
11 *
12 * Revision History;
13 *
14 * 20 June, 1995 Niles D. Ritter New
15 * 3 July, 1995 Greg Martin Fix strings and index
16 * 6 July, 1995 Niles D. Ritter Unfix indexing.
17 *
18 **********************************************************************/
19
20 #include "geotiff.h" /* public interface */
21 #include "geo_tiffp.h" /* external TIFF interface */
22 #include "geo_keyp.h" /* private interface */
23
24 /* return the Header info of this geotiff file */
25
26 void GTIFDirectoryInfo(GTIF *gtif, int version[3], int *keycount)
27 {
28 if (version)
29 {
30 version[0] = gtif->gt_version;
31 version[1] = gtif->gt_rev_major;
32 version[2] = gtif->gt_rev_minor;
33 }
34 if (keycount) *keycount = gtif->gt_num_keys;
35 }
36
37
GTIFFree(GTIF * gtif)38 int GTIFKeyInfo(GTIF *gtif, geokey_t key, int *size, tagtype_t* type)
39 {
40 int nIndex = gtif->gt_keyindex[ key ];
41 GeoKey *keyptr;
42
43 if (!nIndex) return 0;
44
45 keyptr = gtif->gt_keys + nIndex;
46 if (size) *size = (int) keyptr->gk_size;
47 if (type) *type = keyptr->gk_type;
48
49 return (int)keyptr->gk_count;
50 }
51
52 /**
53
54 This function reads the value of a single GeoKey from a GeoTIFF file.
55
56 @param gtif The geotiff information handle from GTIFNew().
57
58 @param thekey The geokey_t name (such as ProjectedCSTypeGeoKey).
59 This must come from the list of legal geokey_t values
60 (an enumeration) listed below.
61
62 @param val The <b>val</b> argument is a pointer to the
63 variable into which the value should be read. The type of the variable
64 varies depending on the geokey_t given. While there is no ready mapping
65 of geokey_t values onto types, in general code values are of type <i>short</i>,
66 citations are strings, and everything else is of type <i>double</i>. Note
67 that pointer's to <i>int</i> should never be passed to GTIFKeyGet() for
68 integer values as they will be shorts, and the int's may not be properly
69 initialized (and will be grossly wrong on MSB systems).
70
71 @param nIndex Indicates how far into the list of values
72 for this geokey to offset. Should normally be zero.
73
74 @param count Indicates how many values
75 to read. At this time all keys except for strings have only one value,
76 so <b>nIndex</b> should be zero, and <b>count</b> should be one.
77
78 @return The GTIFKeyGet() function returns the number of values read. Normally
79 this would be one if successful or zero if the key doesn't exist for this
80 file.
81
82 From geokeys.inc we see the following geokey_t values are possible:<p>
83
84 <pre>
85 -- 6.2.1 GeoTIFF Configuration Keys --
86
87 ValuePair( GTModelTypeGeoKey, 1024) -- Section 6.3.1.1 Codes --
88 ValuePair( GTRasterTypeGeoKey, 1025) -- Section 6.3.1.2 Codes --
89 ValuePair( GTCitationGeoKey, 1026) -- documentation --
90
91 -- 6.2.2 Geographic CS Parameter Keys --
92
93 ValuePair( GeographicTypeGeoKey, 2048) -- Section 6.3.2.1 Codes --
94 ValuePair( GeogCitationGeoKey, 2049) -- documentation --
95 ValuePair( GeogGeodeticDatumGeoKey, 2050) -- Section 6.3.2.2 Codes --
96 ValuePair( GeogPrimeMeridianGeoKey, 2051) -- Section 6.3.2.4 codes --
97 ValuePair( GeogLinearUnitsGeoKey, 2052) -- Section 6.3.1.3 Codes --
98 ValuePair( GeogLinearUnitSizeGeoKey, 2053) -- meters --
99 ValuePair( GeogAngularUnitsGeoKey, 2054) -- Section 6.3.1.4 Codes --
100 ValuePair( GeogAngularUnitSizeGeoKey, 2055) -- radians --
101 ValuePair( GeogEllipsoidGeoKey, 2056) -- Section 6.3.2.3 Codes --
102 ValuePair( GeogSemiMajorAxisGeoKey, 2057) -- GeogLinearUnits --
103 ValuePair( GeogSemiMinorAxisGeoKey, 2058) -- GeogLinearUnits --
104 ValuePair( GeogInvFlatteningGeoKey, 2059) -- ratio --
105 ValuePair( GeogAzimuthUnitsGeoKey, 2060) -- Section 6.3.1.4 Codes --
106 ValuePair( GeogPrimeMeridianLongGeoKey, 2061) -- GeoAngularUnit --
107
108 -- 6.2.3 Projected CS Parameter Keys --
109 -- Several keys have been renamed,--
110 -- and the deprecated names aliased for backward compatibility --
111
112 ValuePair( ProjectedCSTypeGeoKey, 3072) -- Section 6.3.3.1 codes --
113 ValuePair( PCSCitationGeoKey, 3073) -- documentation --
114 ValuePair( ProjectionGeoKey, 3074) -- Section 6.3.3.2 codes --
115 ValuePair( ProjCoordTransGeoKey, 3075) -- Section 6.3.3.3 codes --
116 ValuePair( ProjLinearUnitsGeoKey, 3076) -- Section 6.3.1.3 codes --
117 ValuePair( ProjLinearUnitSizeGeoKey, 3077) -- meters --
118 ValuePair( ProjStdParallel1GeoKey, 3078) -- GeogAngularUnit --
119 ValuePair( ProjStdParallelGeoKey,ProjStdParallel1GeoKey) -- ** alias ** --
120 ValuePair( ProjStdParallel2GeoKey, 3079) -- GeogAngularUnit --
121 ValuePair( ProjNatOriginLongGeoKey, 3080) -- GeogAngularUnit --
122 ValuePair( ProjOriginLongGeoKey,ProjNatOriginLongGeoKey) -- ** alias ** --
123 ValuePair( ProjNatOriginLatGeoKey, 3081) -- GeogAngularUnit --
124 ValuePair( ProjOriginLatGeoKey,ProjNatOriginLatGeoKey) -- ** alias ** --
125 ValuePair( ProjFalseEastingGeoKey, 3082) -- ProjLinearUnits --
126 ValuePair( ProjFalseNorthingGeoKey, 3083) -- ProjLinearUnits --
127 ValuePair( ProjFalseOriginLongGeoKey, 3084) -- GeogAngularUnit --
128 ValuePair( ProjFalseOriginLatGeoKey, 3085) -- GeogAngularUnit --
129 ValuePair( ProjFalseOriginEastingGeoKey, 3086) -- ProjLinearUnits --
130 ValuePair( ProjFalseOriginNorthingGeoKey, 3087) -- ProjLinearUnits --
131 ValuePair( ProjCenterLongGeoKey, 3088) -- GeogAngularUnit --
132 ValuePair( ProjCenterLatGeoKey, 3089) -- GeogAngularUnit --
133 ValuePair( ProjCenterEastingGeoKey, 3090) -- ProjLinearUnits --
134 ValuePair( ProjCenterNorthingGeoKey, 3091) -- ProjLinearUnits --
135 ValuePair( ProjScaleAtNatOriginGeoKey, 3092) -- ratio --
136 ValuePair( ProjScaleAtOriginGeoKey,ProjScaleAtNatOriginGeoKey) -- ** alias ** --
137 ValuePair( ProjScaleAtCenterGeoKey, 3093) -- ratio --
138 ValuePair( ProjAzimuthAngleGeoKey, 3094) -- GeogAzimuthUnit --
139 ValuePair( ProjStraightVertPoleLongGeoKey, 3095) -- GeogAngularUnit --
140
141 6.2.4 Vertical CS Keys
142
143 ValuePair( VerticalCSTypeGeoKey, 4096) -- Section 6.3.4.1 codes --
144 ValuePair( VerticalCitationGeoKey, 4097) -- documentation --
145 ValuePair( VerticalDatumGeoKey, 4098) -- Section 6.3.4.2 codes --
146 ValuePair( VerticalUnitsGeoKey, 4099) -- Section 6.3.1 (.x) codes --
147 </pre>
148 */
149
150 int GTIFKeyGet(GTIF *gtif, geokey_t thekey, void *val, int nIndex, int count)
151 {
152 int kindex = gtif->gt_keyindex[ thekey ];
153 GeoKey *key;
154 gsize_t size;
155 char *data;
156 tagtype_t type;
157
158 if (!kindex) return 0;
159
160 key = gtif->gt_keys+kindex;
161 if (!count) count = (int) (key->gk_count - nIndex);
162 if (count <=0) return 0;
163 if (count > key->gk_count) count = (int) key->gk_count;
164 size = key->gk_size;
165 type = key->gk_type;
166
167 if (count==1 && type==TYPE_SHORT) data = (char *)&key->gk_data;
168 else data = key->gk_data;
169
170 _GTIFmemcpy( val, data + nIndex*size, count*size );
171
172 if (type==TYPE_ASCII)
173 ((char *)val)[count-1] = '\0'; /* replace last char with NULL */
174
175 return count;
176 }
177
178 /************************************************************************/
179 /* GTIFKeyGetInternal() */
180 /************************************************************************/
181
182 static int GTIFKeyGetInternal( GTIF *psGTIF, geokey_t key,
183 void* pData,
184 int nIndex,
185 int nCount,
186 tagtype_t expected_tagtype )
187 {
188 tagtype_t tagtype;
189 if( !GTIFKeyInfo(psGTIF, key, NULL, &tagtype) )
190 return 0;
191 if( tagtype != expected_tagtype )
192 {
193 if( psGTIF->gt_error_callback )
194 {
195 psGTIF->gt_error_callback(
196 psGTIF,
197 LIBGEOTIFF_WARNING,
198 "Expected key %s to be of type %s. Got %s",
199 GTIFKeyName(key), GTIFTypeName(expected_tagtype),
200 GTIFTypeName(tagtype));
201 }
202 return 0;
203 }
204 return GTIFKeyGet( psGTIF, key, pData, nIndex, nCount );
205 }
206
207 /************************************************************************/
208 /* GTIFKeyGetASCII() */
209 /************************************************************************/
210
211 /**
212 * This function reads the value of a single GeoKey of type ASCII from a GeoTIFF file.
213 *
214 * Same as GTIFGetKey() except that it adds checking that the key read is of the
215 * expected type.
216 */
217 int GTIFKeyGetASCII( GTIF *gtif, geokey_t key, char* szStr, int szStrMaxLen )
218 {
219 return GTIFKeyGetInternal( gtif, key, szStr, 0, szStrMaxLen, TYPE_ASCII );
220 }
221
222 /************************************************************************/
223 /* GTIFKeyGetSHORT() */
224 /************************************************************************/
225
226 /**
227 * This function reads the value of a single GeoKey of type SHORT from a GeoTIFF file.
228 *
229 * Same as GTIFGetKey() except that it adds checking that the key read is of the
230 * expected type.
231 */
232 int GTIFKeyGetSHORT( GTIF *gtif, geokey_t key, unsigned short* pnVal, int nIndex,
233 int nCount )
234 {
235 return GTIFKeyGetInternal(gtif, key, pnVal, nIndex, nCount, TYPE_SHORT);
236 }
237
238 /************************************************************************/
239 /* GDALGTIFKeyGetDOUBLE() */
240 /************************************************************************/
241
242 /**
243 * This function reads the value of a single GeoKey of type DOUBLE from a GeoTIFF file.
244 *
245 * Same as GTIFGetKey() except that it adds checking that the key read is of the
246 * expected type.
247 */
248 int GTIFKeyGetDOUBLE( GTIF *gtif, geokey_t key, double* pdfVal, int nIndex,
249 int nCount )
250 {
251 return GTIFKeyGetInternal(gtif, key, pdfVal, nIndex, nCount, TYPE_DOUBLE);
252 }
253