osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarth/Units

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #ifndef OSGEARTH_UNITS_H
00020 #define OSGEARTH_UNITS_H 1
00021 
00022 #include <osgEarth/Common>
00023 
00024 namespace osgEarth
00025 {
00026     class OSGEARTH_EXPORT Units
00027     {
00028     public:
00029         // linear
00030         static const Units CENTIMETERS;
00031         static const Units DATA_MILES;
00032         static const Units FATHOMS;
00033         static const Units FEET;
00034         static const Units FEET_US_SURVEY;  // http://www.wsdot.wa.gov/reference/metrics/foottometer.htm
00035         static const Units INCHES;
00036         static const Units KILOFEET;
00037         static const Units KILOMETERS;
00038         static const Units KILOYARDS;
00039         static const Units METERS;
00040         static const Units MILES;           // statute miles
00041         static const Units MILLIMETERS;
00042         static const Units NAUTICAL_MILES;
00043         static const Units YARDS;
00044 
00045         // angular
00046         static const Units BAM;
00047         static const Units DEGREES;
00048         static const Units NATO_MILS; // http://www.convertworld.com/en/angle/Mil+(NATO).html
00049         static const Units RADIANS;
00050 
00051         // temporal
00052         static const Units DAYS;
00053         static const Units HOURS;
00054         static const Units MICROSECONDS;
00055         static const Units MILLISECONDS;
00056         static const Units MINUTES;
00057         static const Units SECONDS;
00058         static const Units WEEKS;
00059 
00060         // speed
00061         static const Units FEET_PER_SECOND;
00062         static const Units YARDS_PER_SECOND;
00063         static const Units METERS_PER_SECOND;
00064         static const Units KILOMETERS_PER_SECOND;
00065         static const Units KILOMETERS_PER_HOUR;
00066         static const Units MILES_PER_HOUR;
00067         static const Units DATA_MILES_PER_HOUR;
00068         static const Units KNOTS;
00069 
00070         enum Type { TYPE_LINEAR, TYPE_ANGULAR, TYPE_TEMPORAL, TYPE_SPEED, TYPE_INVALID };
00071 
00072     public:
00073 
00074         static bool convert( const Units& from, const Units& to, double input, double& output ) {
00075             if ( canConvert(from, to) ) {
00076                 if ( from._type == TYPE_LINEAR || from._type == TYPE_ANGULAR || from._type == TYPE_TEMPORAL )
00077                     convertSimple( from, to, input, output );
00078                 else if ( from._type == TYPE_SPEED )
00079                     convertSpeed( from, to, input, output );
00080                 return true;
00081             }
00082             return false;
00083         }
00084 
00085         static double convert( const Units& from, const Units& to, double input ) {
00086             double output;
00087             convert( from, to, input, output );
00088             return output;
00089         }
00090 
00091         static bool canConvert( const Units& from, const Units& to ) {
00092             return from._type == to._type;
00093         }
00094 
00095         bool canConvert( const Units& to ) const {
00096             return _type == to._type;
00097         }
00098 
00099         bool convertTo( const Units& to, double input, double& output )  const {
00100             return convert( *this, to, input, output );
00101         }
00102 
00103         double convertTo( const Units& to, double input ) const {
00104             return convert( *this, to, input );
00105         }
00106         
00107         const std::string& getName() const { return _name; }
00108 
00109         const std::string& getAbbr() const { return _abbr; }
00110 
00111         const Type& getType() const { return _type; }
00112 
00113         bool operator == ( const Units& rhs ) const {
00114             return _type == rhs._type && _toBase == rhs._toBase; }
00115         
00116         bool operator != ( const Units& rhs ) const {
00117             return _type != rhs._type || _toBase != rhs._toBase; }
00118 
00119         bool isLinear() const { return _type == TYPE_LINEAR; }
00120 
00121         bool isAngular() const { return _type == TYPE_ANGULAR; }
00122 
00123         bool isTemporal() const { return _type == TYPE_TEMPORAL; }
00124 
00125         bool isSpeed() const { return _type == TYPE_SPEED; }
00126 
00127     public:
00128 
00129         // Make a new unit definition (LINEAR, ANGULAR, TEMPORAL)
00130         Units( const std::string& name, const std::string& abbr, const Type& type, double toBase );
00131 
00132         // Maks a new unit definition (SPEED)
00133         Units( const std::string& name, const std::string& abbr, const Units& distance, const Units& time );
00134 
00135         Units() : _type(TYPE_INVALID) { }
00136 
00137     private:
00138 
00139         static void convertSimple( const Units& from, const Units& to, double input, double& output ) {
00140             output = input * from._toBase / to._toBase;
00141         }
00142         static void convertSpeed( const Units& from, const Units& to, double input, double& output ) {
00143             double t = from._distance->convertTo( *to._distance, input );
00144             output = to._time->convertTo( *from._time, t );
00145         }
00146 
00147 
00148         std::string _name, _abbr;
00149         Type _type;
00150         double _toBase;
00151         const Units* _distance;
00152         const Units* _time;
00153     };
00154 
00155     struct Linear;
00156 
00157     template<typename T>
00158     class qualified_double
00159     {
00160     public:
00161         qualified_double<T>( double value, const Units& units ) : _value(value), _units(units) { }
00162 
00163         qualified_double<T>( const T& rhs ) : _value(rhs._value), _units(rhs._units) { }
00164 
00165         void set( double value, const Units& units ) {
00166             _value = value;
00167             _units = units;
00168         }
00169 
00170         T& operator = ( const T& rhs ) {
00171             if ( _units.canConvert(rhs._units) )
00172                 _value = rhs.as(_units);
00173             return static_cast<T&>(*this);
00174         }
00175 
00176         T operator + ( const T& rhs ) const {
00177             return _units.canConvert(rhs._units) ?
00178                 T(_value + rhs.as(_units), _units) :
00179                 T(0, Units());
00180         }
00181 
00182         T operator - ( const T& rhs ) const {
00183             return _units.canConvert(rhs._units) ? 
00184                 T(_value - rhs.as(_units), _units) :
00185                 T(0, Units());
00186         }
00187 
00188         bool operator == ( const T& rhs ) const {
00189             return _units.canConvert( rhs._units ) && rhs.as(_units) == _value;
00190         }
00191 
00192         bool operator != ( const T& rhs ) const {
00193             return !_units.canConvert(rhs._units) || rhs.as(_units) != _value;
00194         }
00195 
00196         bool operator < ( const T& rhs ) const {
00197             return _units.canConvert(rhs._units) && _value < rhs.as(_units);
00198         }
00199 
00200         bool operator > ( const T& rhs ) const {
00201             return _units.canConvert(rhs._units) && _value > rhs.as(_units);
00202         }
00203 
00204         double as( const Units& convertTo ) const {
00205             return _units.convertTo( convertTo, _value );
00206         }
00207 
00208         const Units& getUnits() const { return _units; }
00209 
00210     private:
00211         double _value;
00212         Units  _units;
00213     };
00214 
00215     struct Linear : public qualified_double<Linear> {
00216         Linear() : qualified_double<Linear>(0, Units::METERS) { }
00217         Linear(double value, const Units& units) : qualified_double<Linear>(value, units) { }
00218     };
00219 
00220     struct Angular : public qualified_double<Angular> {
00221         Angular() : qualified_double<Angular>(0, Units::DEGREES) { }
00222         Angular(double value) : qualified_double<Angular>(value, Units::DEGREES) { }
00223         Angular(double value, const Units& units) : qualified_double<Angular>(value, units) { }
00224     };
00225 
00226     struct Temporal : public qualified_double<Temporal> {
00227         Temporal() : qualified_double<Temporal>(0, Units::SECONDS) { }
00228         Temporal(double value, const Units& units) : qualified_double<Temporal>(value, units) { }
00229     };
00230 
00231     struct Speed : public qualified_double<Speed> {
00232         Speed() : qualified_double<Speed>(0, Units::METERS_PER_SECOND) { }
00233         Speed(double value, const Units& units) : qualified_double<Speed>(value, units) { }
00234     };
00235 }
00236 
00237 #endif // OSGEARTH_UNITS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines