00001 #include "vil_geotiff_header.h"
00002
00003
00004 #include <vcl_cassert.h>
00005 #include <vcl_cstdlib.h>
00006 #include <vcl_iostream.h>
00007 #include <geo_tiffp.h>
00008 #include <geotiffio.h>
00009 #include <geovalues.h>
00010
00011 vil_geotiff_header::vil_geotiff_header(TIFF* tif) : tif_(tif)
00012 {
00013 if (tif) {
00014 gtif_ = GTIFNew(tif);
00015 if (gtif_) {
00016 GTIFPrint(gtif_, 0, 0);
00017
00018
00019 int version[3];
00020 GTIFDirectoryInfo(gtif_, version, &number_of_geokeys_);
00021 key_directory_version_ = (unsigned short)version[0];
00022 key_revision_ = (unsigned short)version[1];
00023 minor_revision_ = (unsigned short)version[2];
00024 }
00025 }
00026 }
00027
00028 bool vil_geotiff_header::gtif_tiepoints(vcl_vector<vcl_vector<double> > &tiepoints)
00029 {
00030 double* points=0;
00031 short count;
00032 if (TIFFGetField(tif_, GTIFF_TIEPOINTS, &count, &points) < 0)
00033 return false;
00034
00035
00036
00037
00038
00039
00040 assert((count % 6) == 0);
00041 for (unsigned short i=0; i<count; ) {
00042 vcl_vector<double> tiepoint(6);
00043 tiepoint[0] = points[i++];
00044 tiepoint[1] = points[i++];
00045 tiepoint[2] = points[i++];
00046 tiepoint[3] = points[i++];
00047 tiepoint[4] = points[i++];
00048 tiepoint[5] = points[i++];
00049 tiepoints.push_back(tiepoint);
00050 }
00051 return true;
00052 }
00053
00054 bool vil_geotiff_header::gtif_pixelscale(double &scale_x, double &scale_y, double &scale_z)
00055 {
00056 double *data;
00057 short count;
00058 if (TIFFGetField(tif_, GTIFF_PIXELSCALE, &count, &data )) {
00059 assert (count == 3);
00060 scale_x = data[0];
00061 scale_y = data[1];
00062 scale_z = data[2];
00063 return true;
00064 }
00065 else
00066 return false;
00067 }
00068
00069 bool vil_geotiff_header::gtif_trans_matrix (double* &trans_matrix)
00070 {
00071 short count;
00072 if (TIFFGetField(tif_, GTIFF_TRANSMATRIX, &count, &trans_matrix )) {
00073 assert (count == 16);
00074 return true;
00075 }
00076 else
00077 return false;
00078 }
00079
00080 bool vil_geotiff_header::gtif_modeltype (modeltype_t& type)
00081 {
00082 geocode_t model;
00083 if (!GTIFKeyGet(gtif_, GTModelTypeGeoKey, &model, 0, 1)) {
00084 vcl_cerr << "NO Model Type defined!!!!\n";
00085 return false;
00086 }
00087 else {
00088 type = static_cast<modeltype_t> (model);
00089 return true;
00090 }
00091 }
00092
00093 bool vil_geotiff_header::gtif_rastertype (rastertype_t& type)
00094 {
00095 geocode_t raster;
00096 if (!GTIFKeyGet(gtif_, GTRasterTypeGeoKey, &raster, 0, 1)) {
00097 vcl_cerr << "NO Raster Type, failure!!!!\n";
00098 return false;
00099 }
00100 else {
00101 type = static_cast<rastertype_t> (raster);
00102 return true;
00103 }
00104 }
00105
00106 bool vil_geotiff_header::geounits (geounits_t& units)
00107 {
00108 short nGeogUOMLinear;
00109 if (!GTIFKeyGet(gtif_, GeogLinearUnitsGeoKey, &nGeogUOMLinear, 0, 1 )) {
00110 vcl_cerr << "NO GEOUNITS, failure!!!!\n";
00111 return false;
00112 }
00113 else {
00114 units = static_cast<geounits_t> (nGeogUOMLinear);
00115 return true;
00116 }
00117 }
00118
00119 bool vil_geotiff_header::PCS_WGS84_UTM_zone(int &zone, GTIF_HEMISPH &hemisph)
00120 {
00121 modeltype_t type;
00122 if (gtif_modeltype(type) && type == ModelTypeProjected)
00123 {
00124 void *value;
00125 int size;
00126 int length;
00127 tagtype_t ttype;
00128 get_key_value(ProjectedCSTypeGeoKey, &value, size, length, ttype);
00129
00130
00131
00132
00133 assert ((length == 1) && (ttype == TYPE_SHORT));
00134
00135 short *val = static_cast<short*> (value);
00136 if ((*val < PCS_WGS84_UTM_zone_1N ) || ((*val > PCS_WGS84_UTM_zone_60S ))) {
00137 return false;
00138 }
00139
00140 #if 0
00141 int zone;
00142 int hemisph;
00143 #endif // 0
00144 if ((*val >= PCS_WGS84_UTM_zone_1N) && (*val <= PCS_WGS84_UTM_zone_60N)) {
00145 zone = *val - 32600;
00146 hemisph = NORTH;
00147 }
00148 else if ((*val >= PCS_WGS84_UTM_zone_1S) && (*val <= PCS_WGS84_UTM_zone_60S)) {
00149 zone = *val - 32700;
00150 hemisph = SOUTH;
00151 }
00152 return true;
00153 }
00154 else {
00155 hemisph = UNDEF;
00156 return false;
00157 }
00158 }
00159
00160
00161 bool vil_geotiff_header::GCS_WGS84_MET_DEG()
00162 {
00163 modeltype_t type;
00164 if (gtif_modeltype(type) && type == ModelTypeGeographic) {
00165 void *value; int size; int length; tagtype_t ttype;
00166
00167 get_key_value(GeogLinearUnitsGeoKey, &value, size, length, ttype);
00168 assert ((length == 1) && (ttype == TYPE_SHORT));
00169 short *val = static_cast<short*> (value);
00170
00171 if (*val != Linear_Meter) {
00172 vcl_cerr << "Linear units are not in Meters!\n";
00173 return false;
00174 }
00175
00176 get_key_value(GeogAngularUnitsGeoKey, &value, size, length, ttype);
00177 assert ((length == 1) && (ttype == TYPE_SHORT));
00178 val = static_cast<short*> (value);
00179
00180 if (*val != Angular_Degree) {
00181 vcl_cerr << "Angular units are not in Degrees!\n";
00182 return false;
00183 }
00184
00185 return true;
00186 }
00187 return false;
00188 }
00189
00190
00191 bool vil_geotiff_header::PCS_NAD83_UTM_zone(int &zone, GTIF_HEMISPH &hemisph)
00192 {
00193 modeltype_t type;
00194 if (gtif_modeltype(type) && type == ModelTypeProjected)
00195 {
00196 void *value;
00197 int size;
00198 int length;
00199 tagtype_t ttype;
00200 get_key_value(ProjectedCSTypeGeoKey, &value, size, length, ttype);
00201
00202 assert ((length == 1) && (ttype == TYPE_SHORT));
00203
00204 short *val = static_cast<short*> (value);
00205 if ((*val < PCS_NAD83_UTM_zone_3N ) || ((*val > PCS_NAD83_Missouri_West ))) {
00206 vcl_cerr << "NOT in RANGE PCS_NAD83_UTM_zone_3N and PCS_NAD83_Missouri_West!\n";
00207 return false;
00208 }
00209 zone = *val - 26900;
00210 hemisph = NORTH;
00211
00212 return true;
00213 }
00214 else {
00215 hemisph = UNDEF;
00216 return false;
00217 }
00218 }
00219
00220
00221 bool vil_geotiff_header::get_key_value(geokey_t key, void** value,
00222 int& size, int& length, tagtype_t& type)
00223 {
00224 length = GTIFKeyInfo(gtif_, key, &size, &type);
00225
00226
00227 if (length == 0) {
00228
00229 vcl_cerr << "KeyID=" << (short int)key << " is not valid\n";
00230 return false;
00231 }
00232 else {
00233 *value = vcl_malloc(size*length);
00234 GTIFKeyGet(gtif_, key, *value, 0, length);
00235 return true;
00236 }
00237 }