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