core/vil/file_formats/vil_nitf2_compound_field_value.cxx
Go to the documentation of this file.
00001 // vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of
00002 // Stellar Science Ltd. Co. (stellarscience.com) for 
00003 // Air Force Research Laboratory, 2005.
00004 
00005 #include "vil_nitf2_compound_field_value.h"
00006 
00007 // not used? #include <vcl_sstream.h>
00008 #include <vcl_iomanip.h>
00009 #include <vcl_string.h>
00010 
00011 #include "vil_nitf2_typed_field_formatter.h"
00012 
00013 //==============================================================================
00014 // Class vil_nitf2_date_time
00015 
00016 vcl_ostream& vil_nitf2_date_time::output(vcl_ostream& os) const
00017 {
00018   os << year << '/'
00019      << vcl_setw(2) << vcl_setfill('0') << month << '/'
00020      << vcl_setw(2) << vcl_setfill('0') << day << ' '
00021      << vcl_setw(2) << vcl_setfill('0') << hour << ':'
00022      << vcl_setw(2) << vcl_setfill('0') << minute << ':';
00023   if (second < 10) os << '0';
00024   if (sec_precision==0) {
00025     os << int(second);
00026   } else if (sec_precision>0) {
00027     os << vcl_fixed << vcl_setprecision(sec_precision) << second;
00028   }
00029   return os;
00030 }
00031 
00032 bool vil_nitf2_date_time::is_valid() const
00033 {
00034   return year > 1900 && year <= 9999 &&
00035          month > 0 && month <= 12 &&
00036          day > 0 && day <= 31 &&
00037          hour >= 0 && hour < 24 &&
00038          minute >=0 && minute < 60 &&
00039          second >= 0.0 && second < 60.0;
00040 }
00041 
00042 bool vil_nitf2_date_time::write(vcl_ostream& output, int field_width) const
00043 {
00044   output << vcl_setw(4) << vcl_noshowpos << vcl_internal << year
00045          << vcl_setw(2) << vcl_noshowpos << vcl_internal << vcl_setfill('0') << month
00046          << vcl_setw(2) << vcl_noshowpos << vcl_internal << vcl_setfill('0') << day;
00047   if (field_width >= 10 && !output.fail()) {
00048     output << vcl_setw(2) << vcl_noshowpos << vcl_internal << vcl_setfill('0') << hour;
00049   }
00050   else
00051     output << "  ";
00052   if (field_width >= 12 && !output.fail()) {
00053     output << vcl_setw(2) << vcl_noshowpos << vcl_internal << vcl_setfill('0') << minute;
00054   }
00055   else
00056     output << "  ";
00057   if (field_width < 14 && !output.fail()) {
00058     // seconds not displayed
00059     output << "  ";
00060   } else if (field_width == 14 && !output.fail()) {
00061     // display integer seconds
00062     output << vcl_setw(2) << vcl_noshowpos << vcl_internal << vcl_setfill('0') << (int)second;
00063   } else if (!output.fail()) {
00064     // display decimal seconds
00065     output << vcl_setw(field_width - 12) << vcl_fixed << vcl_noshowpos << vcl_internal
00066            << vcl_setfill(' ') << vcl_setprecision(field_width - 15) << second;
00067   }
00068   // Return whether all output operations were successful
00069   return !output.fail();
00070 }
00071 
00072 bool vil_nitf2_date_time::read(vcl_istream& input, int field_width, bool& out_blank)
00073 {
00074   bool blank;
00075   vcl_string fieldStr;
00076   bool ok;
00077   ok = vil_nitf2_integer_formatter(4).read_vcl_stream(input, year, blank); out_blank = blank;
00078   ok &= vil_nitf2_integer_formatter(2).read_vcl_stream(input, month, blank); out_blank &= blank;
00079   ok &= vil_nitf2_integer_formatter(2).read_vcl_stream(input, day, blank); out_blank &= blank;
00080   if (field_width >= 10) {
00081     ok &= vil_nitf2_integer_formatter(2).read_vcl_stream(input, hour, blank); out_blank &= blank;
00082   } else { 
00083     hour = 0; 
00084   }
00085   if (field_width >= 12) {
00086     ok &= vil_nitf2_integer_formatter(2).read_vcl_stream(input, minute, blank); out_blank &= blank;
00087   } else {
00088     minute = 0;
00089   }
00090   if (field_width == 14) {
00091     // integer seconds, no decimal point
00092     int intSecond;
00093     ok &= vil_nitf2_integer_formatter(2).read_vcl_stream(input, intSecond, blank); out_blank &= blank;
00094     second = intSecond;
00095   } else if (field_width > 14) {
00096     // decimal seconds
00097     ok &= vil_nitf2_double_formatter(field_width-12, field_width-15, false)
00098       .read_vcl_stream(input, second, blank); out_blank &= blank;
00099   } else {
00100     // no seconds
00101     second = 0.0;
00102   }
00103   return ok && is_valid();
00104 }
00105 
00106 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_date_time& dateTime)
00107 {
00108   return dateTime.output(os);
00109 }
00110 
00111 //==============================================================================
00112 // Class vil_nitf2_location_degrees
00113 
00114 vcl_ostream& vil_nitf2_location_degrees::output(vcl_ostream& os) const
00115 {
00116   os << '(' 
00117      << vcl_fixed << lat_degrees << ", " 
00118      << vcl_fixed << lon_degrees << ')';
00119   return os;
00120 }
00121 
00122 bool vil_nitf2_location_degrees::read(vcl_istream& input, int field_width, bool& out_blank)
00123 {
00124   int lat_width = (field_width-1)/2;
00125   int lon_width = (field_width+1)/2;
00126   bool ok, blank;
00127   ok = vil_nitf2_double_formatter(lat_width, precision, true).read_vcl_stream(input, lat_degrees, blank);
00128   out_blank = blank;
00129   ok &= vil_nitf2_double_formatter(lon_width, precision, true).read_vcl_stream(input, lon_degrees, out_blank);
00130   out_blank &= blank;
00131   return ok && is_valid();
00132 }
00133 
00134 bool vil_nitf2_location_degrees::write(vcl_ostream& output, int field_width)
00135 {
00136   // Could someone remind me again why I didn't just use printf and scanf 
00137   // instead?
00138   output << vcl_setw((field_width-1)/2) << vcl_fixed << vcl_showpos << vcl_internal 
00139          << vcl_setfill('0') <<  vcl_setprecision(precision) << lat_degrees
00140          << vcl_setw((field_width+1)/2) << vcl_fixed << vcl_showpos << vcl_internal
00141          << vcl_setfill('0') << vcl_setprecision(precision) << lon_degrees;
00142   return !output.fail();
00143 }
00144 
00145 bool vil_nitf2_location_degrees::is_valid() const
00146 {
00147   return lat_degrees >= -90.0 && lat_degrees <= 90.0 &&
00148          lon_degrees >= -180.0 && lon_degrees <= 180.0;
00149 }
00150 
00151 
00152 //==============================================================================
00153 // Class vil_nitf2_location
00154 
00155 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_location& loc)
00156 {
00157   return loc.output(os);
00158 }
00159 
00160 //==============================================================================
00161 // Class vil_nitf2_location_dmsh
00162 
00163 vcl_ostream& vil_nitf2_location_dmsh::output(vcl_ostream& os) const
00164 {
00165   os << '(' 
00166      << lat_degrees << ':' << lat_minutes    << ':' 
00167      << lat_seconds << ':' << lat_hemisphere << ", "
00168      << lon_degrees << ':' << lon_minutes    << ':' 
00169      << lon_seconds << ':' << lon_hemisphere << ')';
00170   return os;
00171 }
00172 
00173 bool vil_nitf2_location_dmsh::read(vcl_istream& input, int /* field_width */, bool& out_blank)
00174 {
00175   bool blank;
00176   // Read latitude fields
00177   bool    ok = vil_nitf2_integer_formatter(2).read_vcl_stream(input, lat_degrees, blank); 
00178   if (out_blank) out_blank = blank;
00179   if (ok) ok = vil_nitf2_integer_formatter(2).read_vcl_stream(input, lat_minutes, out_blank); 
00180   if (out_blank) out_blank = blank;
00181   if (ok) ok = vil_nitf2_double_formatter(3+sec_precision, sec_precision, false)
00182                .read_vcl_stream(input, lat_seconds, out_blank);
00183   if (out_blank) out_blank = blank;
00184   if (ok) ok = vil_nitf2_char_formatter().read_vcl_stream(input, lat_hemisphere, out_blank);
00185   if (out_blank) out_blank = blank;
00186   // Read longitude fields (degrees is one digit longer than latitude)
00187   if (ok) ok = vil_nitf2_integer_formatter(3).read_vcl_stream(input, lon_degrees, out_blank);
00188   if (out_blank) out_blank = blank;
00189   if (ok) ok = vil_nitf2_integer_formatter(2).read_vcl_stream(input, lon_minutes, out_blank);
00190   if (out_blank) out_blank = blank;
00191   if (ok) ok = vil_nitf2_double_formatter(3+sec_precision, sec_precision, false)
00192                .read_vcl_stream(input, lon_seconds, out_blank);
00193   if (out_blank) out_blank = blank;
00194   if (ok) ok = vil_nitf2_char_formatter().read_vcl_stream(input,lon_hemisphere, out_blank);
00195   if (out_blank) out_blank = blank;
00196   return ok && is_valid();
00197 }
00198 
00199 bool vil_nitf2_location_dmsh::write(vcl_ostream& output, int /* field_width */)
00200 {
00201   bool ok;
00202   // Write latitude fields
00203   ok = vil_nitf2_integer_formatter(2).write_vcl_stream(output, lat_degrees);
00204   ok &= vil_nitf2_integer_formatter(2).write_vcl_stream(output, lat_minutes);
00205   ok &= vil_nitf2_double_formatter(3+sec_precision, sec_precision, false).write_vcl_stream(output, lat_seconds);
00206   ok &= vil_nitf2_char_formatter().write_vcl_stream(output, lat_hemisphere);
00207   // Write longitude fields (degrees is one digit longer than latitude)
00208   ok &= vil_nitf2_integer_formatter(3).write_vcl_stream(output, lon_degrees);
00209   ok &= vil_nitf2_integer_formatter(2).write_vcl_stream(output, lon_minutes);
00210   ok &= vil_nitf2_double_formatter(3+sec_precision, sec_precision, false).write_vcl_stream(output, lon_seconds);
00211   ok &= vil_nitf2_char_formatter().write_vcl_stream(output, lon_hemisphere);
00212   return ok;
00213 }
00214 
00215 bool vil_nitf2_location_dmsh::is_valid() const
00216 {
00217   return lat_degrees >= -90 && lat_degrees <= 90 &&
00218          lon_degrees >= -180 && lon_degrees <= 180 &&
00219          lat_minutes >= 0 && lat_minutes < 60 &&
00220          lon_minutes >= 0 && lon_minutes < 60 &&
00221          lat_seconds >= 0.0 && lat_seconds < 60.0 &&
00222          lon_seconds >= 0.0 && lon_seconds < 60.0 &&
00223          vcl_string("NnSs").find(lat_hemisphere) != vcl_string::npos &&
00224          vcl_string("EeWw").find(lon_hemisphere) != vcl_string::npos;
00225 }