contrib/gel/mrc/vpgl/bgeo/bgeo_lvcs.h
Go to the documentation of this file.
00001 #ifndef bgeo_lvcs_h_
00002 #define bgeo_lvcs_h_
00003 //-----------------------------------------------------------------------------
00004 //:
00005 // \file
00006 // \brief A geographic coordinate system
00007 // \author J. L. Mundy
00008 // \date December 31, 2005
00009 //
00010 //      lvcs is used to convert between a local vertical coordinate system
00011 //      any of the many Earth global coordinate systems. In the full
00012 //      constructor the user can establish the geographic coordinates of
00013 //      the origin and define which standard geo-coordinate system is to
00014 //      be used, e.g. wgs84.  The full constructor allows the specification
00015 //      of latitude and longitude scale factors in radians/meter.  If these
00016 //      scale factors are set to 0, then they will be computed using the
00017 //      location of the origin on the Earth's surface and the geoid
00018 //      specification.
00019 //
00020 //      original authors (c. 1992)
00021 //             Rajiv Gupta and Bill Hoffman
00022 //      with modifications by Rupert Curwen (1996)
00023 //             GE Corporate Research and Development
00024 /////////////////////////////////////////////////////////////////////////////
00025 #include <vcl_iostream.h>
00026 #include <vsl/vsl_binary_io.h>
00027 #include <vbl/vbl_ref_count.h>
00028 #include <vpgl/bgeo/bgeo_dll.h>
00029 class bgeo_lvcs : public vbl_ref_count
00030 {
00031   // PUBLIC INTERFACE----------------------------------------------------------
00032 
00033  public:
00034   enum LenUnits {FEET, METERS};
00035   enum AngUnits {RADIANS, DEG};
00036   enum cs_names { wgs84 =0, nad27n, wgs72, NumNames};
00037   GEO_DLL_DATA static const char* cs_name_strings[];
00038   static bgeo_lvcs::cs_names str_to_enum(const char*);
00039   // Constructors/Initializers/Destructors-------------------------------------
00040   bgeo_lvcs(double orig_lat=0,    //!< latitude of LVCS orig in radians.
00041        double orig_lon=0,         //!< longitude of LVCS  orig in radians.
00042        double orig_elev=0,        //!< elev of orig LVCS  in radians.
00043        cs_names cs_name=wgs84,    //!< nad27n, wgs84, wgs72
00044        double lat_scale=0,        //!< radians/meter along lat (custom geoid)
00045        double lon_scale=0,        //!< radians/meter along lon (custom geoid)
00046        AngUnits  ang_unit = DEG,  //!< angle units
00047        LenUnits len_unit=METERS,  //!< input in LVCS in these lenght units.
00048        double lox=0,              //!< Origin in local co-ordinates.
00049        double loy=0,              //!< Origin in local co-ordinates.
00050        double theta=0);           //!< Radians from y axis to north in local co-ordinates.
00051 
00052   bgeo_lvcs(double orig_lat,
00053        double orig_lon,
00054        double orig_elev, //!< simplified interface
00055        cs_names cs_name,
00056        AngUnits  ang_unit = DEG,
00057        LenUnits len_unit=METERS);
00058 
00059   bgeo_lvcs(double lat_low, double lon_low,  //!< lower corner bounding geo_rectangle
00060        double lat_high, double lon_high,//!< upper corner bounding geo_rectangle
00061        double elev,                     //!< elevation of all rectangle corners
00062        cs_names cs_name=wgs84,
00063        AngUnits ang_unit=DEG, LenUnits elev_unit=METERS);
00064 
00065   bgeo_lvcs(const bgeo_lvcs&);
00066   bgeo_lvcs& operator=(const bgeo_lvcs&);
00067 
00068 
00069   // Utility Methods-----------------------------------------------------------
00070   void local_to_global(const double lx, const double ly, const double lz,
00071                                cs_names cs_name,
00072                                double& lon, double& lat, double& gz,
00073                                AngUnits output_ang_unit=DEG,
00074                                LenUnits output_len_unit=METERS);
00075 
00076   void global_to_local(const double lon, const double lat, const double gz,
00077                        cs_names cs_name,
00078                        double& lx, double& ly, double& lz,
00079                        AngUnits output_ang_unit=DEG,
00080                        LenUnits output_len_unit=METERS);
00081 
00082   void radians_to_degrees(double& lon, double& lat, double& z);
00083   double radians_to_degrees(const double val);
00084   void degrees_to_dms(double, int& degrees, int& minutes, double& seconds);
00085   void radians_to_dms(double, int& degrees, int& minutes, double& seconds);
00086 
00087   // accessors
00088   void get_origin(double& lat, double& lon, double& elev) const;
00089   void get_scale(double& lat, double& lon) const;
00090   void get_transform(double& lox, double& loy, double& theta) const;
00091   void set_transform(const double lox, const double loy, const double theta);
00092   void set_origin(const double lon, const double lat, const double elev);
00093   cs_names get_cs_name() const;
00094   inline LenUnits local_length_unit() const{return this->localXYZUnit_;}
00095   inline AngUnits geo_angle_unit() const {return this->geo_angle_unit_;}
00096   void print(vcl_ostream&) const;
00097   bool save(vcl_string fname) { vcl_ofstream of(fname.c_str()); if (of) { print(of); return true; } return false; }
00098   void read(vcl_istream& strm);
00099   friend vcl_ostream& operator << (vcl_ostream& os, const bgeo_lvcs& local_coord_sys);
00100   friend vcl_istream& operator >> (vcl_istream& os, bgeo_lvcs& local_coord_sys);
00101   bool operator==(bgeo_lvcs const& r) const;
00102   // binary IO
00103 
00104   //: Binary save self to stream.
00105   virtual void b_write(vsl_b_ostream &os) const;
00106 
00107   //: Binary load self from stream.
00108   virtual void b_read(vsl_b_istream &is);
00109 
00110   void x_write(vcl_ostream &os, vcl_string element_name) const;
00111 
00112   // INTERNALS-----------------------------------------------------------------
00113 
00114  protected:
00115   void compute_scale();
00116   void local_transform(double& x, double& y);
00117   void inverse_local_transform(double& x, double& y);
00118   void set_angle_conversions(AngUnits ang_unit, double& to_radians,
00119                              double& to_degrees);
00120   void set_length_conversions(LenUnits len_unit, double& to_meters,
00121                               double& to_feet);
00122  private:
00123 
00124   // Data Members--------------------------------------------------------------
00125 
00126  protected:
00127   cs_names local_cs_name_;    //!< Name of local frame's coord system ("nad27n", "wgs84" etc.)
00128   double localCSOriginLat_;   //!< Lat (in radians) of the origin
00129   double localCSOriginLon_;   //!< Lon (in radians) of the origin
00130   double localCSOriginElev_;  //!< Elev (in radians) of the origin
00131   double lat_scale_;          //!< radians/meter along lat at the origin)
00132   double lon_scale_;          //!< radians/meter along lon at the origin)
00133   AngUnits geo_angle_unit_;   //!< lat lon angle unit (degrees or radians)
00134   LenUnits localXYZUnit_;     //!< Input (x,y,z) unit (meters or feet) in local CS
00135   double lox_;                //!< Origin in local co-ordinates.
00136   double loy_;                //!< Origin in local co-ordinates.
00137   double theta_;              //!< Direction of north in radians.
00138 };
00139 
00140 //: return the scale for lat lon and elevation
00141 inline void bgeo_lvcs::get_scale(double& lat, double& lon) const
00142 {
00143   lat = lat_scale_;
00144   lon = lon_scale_;
00145 }
00146 
00147 //: return the coordinate system
00148 inline bgeo_lvcs::cs_names bgeo_lvcs::get_cs_name() const
00149 { return local_cs_name_; }
00150 
00151 
00152 //: return the origin of the local system
00153 inline void bgeo_lvcs::get_origin(double& lat, double& lon, double& elev) const
00154 {
00155   lat = localCSOriginLat_;
00156   lon = localCSOriginLon_;
00157   elev = localCSOriginElev_;
00158 }
00159 
00160 //------------------------------------------------------------
00161 //: Return the compass alignment transform.
00162 inline void bgeo_lvcs::get_transform(double& lox, double& loy, double& theta) const
00163 {
00164   lox = lox_;
00165   loy = loy_;
00166   theta = theta_;
00167 }
00168 
00169 //------------------------------------------------------------
00170 //: Set the compass alignment transform.
00171 inline void bgeo_lvcs::set_transform(const double lox, const double loy,
00172                                      const double theta)
00173 {
00174   lox_ = lox;
00175   loy_ = loy;
00176   theta_ = theta;
00177 }
00178 
00179 //------------------------------------------------------------
00180 //: Set the origin of the local system
00181 inline void bgeo_lvcs::set_origin(const double lon, const double lat, const double elev)
00182 {
00183     localCSOriginLon_ = lon;
00184     localCSOriginLat_ = lat;
00185     localCSOriginElev_ = elev;
00186 }
00187 
00188 inline void bgeo_lvcs::radians_to_dms(double rad, int& degrees, int& minutes, double& seconds)
00189 {
00190   degrees_to_dms(radians_to_degrees(rad), degrees,  minutes, seconds);
00191 }
00192 #endif // bgeo_lvcs_h_
00193