00001
00002 #include "vpgl_nitf_rational_camera.h"
00003
00004
00005
00006
00007
00008
00009 #include <vcl_cstdlib.h>
00010 #include <vil/vil_load.h>
00011 #include <vcl_cmath.h>
00012 #include <vcl_cstring.h>
00013 #include <vcl_cctype.h>
00014
00015 #include <vil/file_formats/vil_nitf2_image.h>
00016
00017
00018 static int to_int (const char* in_string,int size)
00019 {
00020 int value = 0;
00021 while (size--)
00022 value = (value*10) + (*in_string++ - '0');
00023 return value;
00024 }
00025
00026
00027 static int geostr_to_double(const char* in_string, double* val, vpgl_nitf_rational_camera::geopt_coord c)
00028 {
00029
00030 int length;
00031 int deg, min;
00032 float fsec;
00033 const char* orig = in_string;
00034
00035
00036 char sposdir, cposdir, snegdir, cnegdir;
00037 int maxval;
00038
00039 if (c == vpgl_nitf_rational_camera::LAT)
00040 {
00041 sposdir='n';
00042 cposdir='N';
00043 snegdir='s';
00044 cnegdir='S';
00045 maxval=90;
00046 }
00047 else
00048 {
00049 sposdir='e';
00050 cposdir='E';
00051 snegdir='w';
00052 cnegdir='W';
00053 maxval=180;
00054 }
00055
00056 while ((*in_string == ' ') || (*in_string == '\t'))
00057 ++in_string;
00058
00059 for (length=0; vcl_isdigit (*in_string) && length<15; ++length)
00060 ++in_string;
00061 if (length>14) return 0;
00062
00063
00064
00065 if (length>3)
00066 {
00067 if (length < 5)
00068 return 0;
00069
00070
00071 if ((min = to_int (in_string-4, 2)) >= 60 || min<0)
00072 return 0;
00073
00074
00075 if ((deg = to_int (in_string-length, length-4)) > maxval || deg<0)
00076 return 0;
00077
00078
00079 in_string-=2;
00080 char* temp = new char[2];
00081 for (length=0;
00082 (*in_string=='.' || vcl_isdigit (*in_string)) && length<15;
00083 ++length)
00084 ++in_string;
00085 if (length>14) return 0;
00086
00087 vcl_strncpy(temp,in_string-length,length);
00088 if ( (fsec = (float)vcl_atof(temp)) >= 60.0f || fsec<0.0f)
00089 return 0;
00090 delete [] temp;
00091
00092
00093 while ((*in_string == ' ') || (*in_string == '\t'))
00094 ++in_string;
00095
00096
00097 *val = deg;
00098 *val += ((double)(min))/(60.0);
00099 *val += ((double)(fsec))/(3600.0);
00100
00101
00102 if ( *in_string==sposdir || *in_string==cposdir) {}
00103 else if ( *in_string==snegdir || *in_string==cnegdir) {*val = -(*val);}
00104 else return 0;
00105
00106 ++in_string;
00107
00108 return in_string-orig;
00109 }
00110 else
00111 if (*in_string == 'd')
00112 {
00113
00114 if (length > 3)
00115 return 0;
00116 if ((deg = to_int (in_string-length, length)) > maxval || deg<0)
00117 return 0;
00118
00119
00120 ++in_string;
00121 while ((*in_string == ' ') || (*in_string == '\t'))
00122 ++in_string;
00123
00124
00125 for (length=0; vcl_isdigit (*in_string) && length<15; ++in_string, ++length) ;
00126 if (length>14) return 0;
00127 if (length > 2)
00128 return 0;
00129 if ((min = to_int (in_string-length, length)) >= 60 || min<0)
00130 return 0;
00131
00132
00133 ++in_string;
00134 while ((*in_string == ' ') || (*in_string == '\t'))
00135 ++in_string;
00136
00137
00138 char* temp= new char[2];
00139 for (length=0;
00140 (*in_string=='.' || vcl_isdigit (*in_string)) && length<15;
00141 ++length)
00142 ++in_string;
00143 if (length>14) return 0;
00144
00145 vcl_strncpy(temp,in_string-length,length);
00146 if ( (fsec = (float)vcl_atof(temp)) >= 60.0f || fsec<0.0f)
00147 return 0;
00148 delete temp;
00149
00150
00151 ++in_string;
00152 while ((*in_string == ' ') || (*in_string == '\t'))
00153 ++in_string;
00154
00155
00156 *val = deg;
00157 *val += ((double)(min))/(60.0);
00158 *val += ((double)(fsec))/(3600.0);
00159
00160
00161 if ( *in_string==sposdir || *in_string==cposdir) {}
00162 else if ( *in_string==snegdir || *in_string==cnegdir) {*val = -(*val);}
00163 else return 0;
00164
00165 ++in_string;
00166
00167 return in_string-orig;
00168 }
00169 else
00170 if (*in_string == ' ' || *in_string == '-' || *in_string == '+'
00171 || *in_string == '.' || *in_string == '\0')
00172 {
00173 char* temp= new char[2];
00174 in_string=orig;
00175
00176
00177 while ((*in_string == ' ') || (*in_string == '\t'))
00178 ++in_string;
00179
00180
00181 for (length=0;
00182 (*in_string=='+' ||*in_string=='-' || *in_string=='.' ||
00183 vcl_isdigit (*in_string)) && length<15;
00184 ++length)
00185 ++in_string;
00186 if (length>14) return 0;
00187
00188
00189 vcl_strncpy(temp,in_string-length,length);
00190 *val = vcl_atof(temp);
00191 if (vcl_fabs(*val)>float(maxval)) return 0;
00192 delete temp;
00193
00194 ++in_string;
00195
00196 return in_string-orig;
00197 }
00198 else
00199 return 0;
00200 }
00201
00202
00203 static int geostr_to_latlon(const char* str, double* lat, double* lon)
00204 {
00205 int latstrlen=geostr_to_double(str,lat,vpgl_nitf_rational_camera::LAT);
00206 if (latstrlen == 0) return 0;
00207 str += latstrlen;
00208 int lonstrlen=geostr_to_double(str,lon,vpgl_nitf_rational_camera::LON);
00209 if ( lonstrlen == 0) return 0;
00210
00211 return latstrlen+lonstrlen;
00212 }
00213
00214
00215
00216 void vpgl_nitf_rational_camera::set_order_b(int* ord)
00217 {
00218 ord[0] = 11;
00219 ord[1] = 14;
00220 ord[2] = 17;
00221 ord[3] = 7;
00222 ord[4] = 12;
00223 ord[5] = 10;
00224 ord[6] = 4;
00225 ord[7] = 13;
00226 ord[8] = 5;
00227 ord[9] = 1;
00228 ord[10] = 15;
00229 ord[11] = 18;
00230 ord[12] = 8;
00231 ord[13] = 16;
00232 ord[14] = 6;
00233 ord[15] = 2;
00234 ord[16] = 19;
00235 ord[17] = 9;
00236 ord[18] = 3;
00237 ord[19] = 0;
00238 }
00239
00240 bool vpgl_nitf_rational_camera::
00241 init(vil_nitf2_image* nitf_image, bool verbose)
00242 {
00243 vcl_vector< vil_nitf2_image_subheader* > headers = nitf_image->get_image_headers();
00244 vil_nitf2_image_subheader* hdr = headers[0];
00245
00246 double tre_data[90];
00247
00248 for (int i=0; i<90; i++) tre_data[i] = 0;
00249
00250
00251 bool success =
00252 hdr->get_rpc_params(nitf_rational_type_, image_id_, image_igeolo_, tre_data);
00253 if (!success)
00254 {
00255 vcl_cout << "Failed to get rational camera parameters from nitf image in"
00256 << " vgpl_nitf_rational_camera\n";
00257 return false;
00258 }
00259
00260 if (verbose)
00261 vcl_cout << " nitf_rational type " << nitf_rational_type_ << '\n'
00262 << " Image Id " << image_id_ << '\n'
00263 << " IGEOLO " << image_igeolo_ << '\n';
00264
00265 double ULlat, ULlon;
00266 double URlat, URlon;
00267 double LLlat, LLlon;
00268 double LRlat, LRlon;
00269
00270
00271 geostr_to_latlon (image_igeolo_.c_str(), &ULlat, &ULlon);
00272 geostr_to_latlon (image_igeolo_.c_str()+15, &URlat, &URlon);
00273 geostr_to_latlon (image_igeolo_.c_str()+30, &LRlat, &LRlon);
00274 geostr_to_latlon (image_igeolo_.c_str()+45, &LLlat, &LLlon);
00275
00276 ul_[LAT]=ULlat; ul_[LON]=ULlon;
00277 ur_[LAT]=URlat; ur_[LON]=URlon;
00278 ll_[LAT]=LLlat; ll_[LON]=LLlon;
00279 lr_[LAT]=LRlat; lr_[LON]=LRlon;
00280
00281 if (verbose)
00282 vcl_cout << "ULlon " << ULlon << " ULlat " << ULlat << '\n'
00283 << "URlon " << URlon << " URlat " << URlat << '\n'
00284 << "LRlon " << LRlon << " LRlat " << LRlat << '\n'
00285 << "LLlon " << LLlon << " lLlat " << LLlat << '\n';
00286 int ord[20];
00287
00288 if (nitf_rational_type_ == "RPC00A")
00289 set_order_b(ord);
00290 else if (nitf_rational_type_ == "RPC00B")
00291 set_order_b(ord);
00292 else
00293 {
00294 vcl_cout << "Unknown rational type from nitf image in"
00295 << " vgpl_nitf_rational_camera\n";
00296 return false;
00297 }
00298
00299
00300
00301 for (int i=0; i<20; i++)
00302 {
00303 rational_coeffs_[2][i] = tre_data[ord[i]];
00304 rational_coeffs_[3][i] = tre_data[ord[i] + 20];
00305 rational_coeffs_[0][i] = tre_data[ord[i] + 40];
00306 rational_coeffs_[1][i] = tre_data[ord[i] + 60];
00307 }
00308
00309 scale_offsets_[X_INDX].set_scale(tre_data[88]);
00310 scale_offsets_[X_INDX].set_offset(tre_data[83]);
00311 scale_offsets_[Y_INDX].set_scale(tre_data[87]);
00312 scale_offsets_[Y_INDX].set_offset(tre_data[82]);
00313 scale_offsets_[Z_INDX].set_scale(tre_data[89]);
00314 scale_offsets_[Z_INDX].set_offset(tre_data[84]);
00315 scale_offsets_[U_INDX].set_scale(tre_data[86]);
00316 scale_offsets_[U_INDX].set_offset(tre_data[81]);
00317 scale_offsets_[V_INDX].set_scale(tre_data[85]);
00318 scale_offsets_[V_INDX].set_offset(tre_data[80]);
00319
00320 double correction_u_off,correction_v_off;
00321 success=hdr->get_correction_offset(correction_u_off,correction_v_off);
00322
00323 if (success)
00324 {
00325 scale_offsets_[U_INDX].set_offset(scale_offsets_[U_INDX].offset()-correction_u_off);
00326 scale_offsets_[V_INDX].set_offset(scale_offsets_[V_INDX].offset()-correction_v_off);
00327 }
00328 return true;
00329 }
00330
00331 vpgl_nitf_rational_camera::vpgl_nitf_rational_camera() {
00332 }
00333
00334
00335 vpgl_nitf_rational_camera::
00336 vpgl_nitf_rational_camera(vcl_string const& nitf_image_path,
00337 bool verbose)
00338 {
00339
00340 vil_image_resource_sptr image =
00341 vil_load_image_resource(nitf_image_path.c_str());
00342 if (!image)
00343 {
00344 vcl_cout << "Image load failed in vpgl_nitf_rational_camera_constructor\n";
00345 return ;
00346 }
00347 vcl_string format = image->file_format();
00348 vcl_string prefix = format.substr(0,4);
00349 if (prefix != "nitf")
00350 {
00351 vcl_cout << "not a nitf image in vpgl_nitf_rational_camera_constructor\n";
00352 return;
00353 }
00354
00355 vil_nitf2_image* nitf_image = (vil_nitf2_image*)image.ptr();
00356
00357 if (!this->init(nitf_image, verbose))
00358 return;
00359 vpgl_scale_offset<double> z = scale_offsets_[Z_INDX];
00360 double z_off = z.offset();
00361 if (verbose)
00362 {
00363 double ul_u=0, ul_v=0, ur_u=0, ur_v=0, ll_u=0, ll_v=0, lr_u=0, lr_v=0;
00364
00365 this->project(ul_[LON], ul_[LAT], z_off, ul_u, ul_v);
00366 vcl_cout << "Upper left image corner(" << ul_u << ' ' << ul_v << ")\n";
00367
00368 this->project(ur_[LON], ur_[LAT], z_off, ur_u, ur_v);
00369 vcl_cout << "Upper right image corner(" << ur_u << ' ' << ur_v << ")\n";
00370
00371 this->project(ll_[LON], ll_[LAT], z_off, ll_u, ll_v);
00372 vcl_cout << "Lower left image corner(" << ll_u << ' ' << ll_v << ")\n";
00373
00374 this->project(lr_[LON], lr_[LAT], z_off, lr_u, lr_v);
00375 vcl_cout << "Lower right image corner(" << lr_u << ' ' << lr_v << ")\n";
00376 }
00377 }
00378
00379 vpgl_nitf_rational_camera::
00380 vpgl_nitf_rational_camera(vil_nitf2_image* nitf_image, bool verbose)
00381 {
00382
00383 if (!this->init(nitf_image, verbose))
00384 return;
00385
00386 if (verbose)
00387 vcl_cout << *this;
00388 vpgl_scale_offset<double> z = scale_offsets_[Z_INDX];
00389 double z_off = z.offset();
00390 if (verbose)
00391 {
00392 double ul_u=0, ul_v=0, ur_u=0, ur_v=0, ll_u=0, ll_v=0, lr_u=0, lr_v=0;
00393
00394 this->project(ul_[LON], ul_[LAT], z_off, ul_u, ul_v);
00395 vcl_cout << "Upper left image corner(" << ul_u << ' ' << ul_v << ")\n";
00396
00397 this->project(ur_[LON], ur_[LAT], z_off, ur_u, ur_v);
00398 vcl_cout << "Upper right image corner(" << ur_u << ' ' << ur_v << ")\n";
00399
00400 this->project(ll_[LON], ll_[LAT], z_off, ll_u, ll_v);
00401 vcl_cout << "Lower left image corner(" << ll_u << ' ' << ll_v << ")\n";
00402
00403 this->project(lr_[LON], lr_[LAT], z_off, lr_u, lr_v);
00404 vcl_cout << "Lower right image corner(" << lr_u << ' ' << lr_v << ")\n";
00405 }
00406 }
00407
00408