5

I have got this code to work:

typedef model::point<double, 2, cs::spherical_equatorial<degree> > degree_point;

degree_point FlindersSE(-37.0, 144.0);

and this:

quantity<plane_angle> Flinders = 0.375 * radians; //this works 0.375 radians

But I would like to do degrees minutes and seconds & convert to radians then back again.

I have spent a day trying to understand how the boost system works - examples are a bit thin on the ground, so I was wondering if someone could show a quick example?

Thanks in advance 8+)

Edit

//quantity<degree_base_unit> FlindersSDeg2.value(-37.0);
//quantity< angle::arcminute_base_unit> FlindersSMin = 57.0;
//quantity< angle::arcsecond_base_unit> FlindersSSec = 3.72030;

I guess I need a better understanding of how declaration works. :)

Edit2:

Thanks very much - maybe I spent a whole looking for ways to do it with boost & the facility wasn't there ! I thought it might have been because I found this obsolete code here http://www.boost.org/doc/libs/1_47_0/libs/geometry/doc/doxy/doxygen_input/sourcecode/doxygen_1.cpp

void example_dms()
{
/*
Extension, other coordinate system:
// Construction with degree/minute/seconds
boost::geometry::dms<boost::geometry::east> d1(4, 53, 32.5);

// Explicit conversion to double.
std::cout << d1.as_value() << std::endl;

// Conversion to string, with optional strings
std::cout << d1.get_dms(" deg ", " min ", " sec") << std::endl;

// Combination with latitude/longitude and cardinal directions
{
    using namespace boost::geometry;
    point_ll<double, boost::geometry::cs::geographic<boost::geometry::degree> >        canberra(
        latitude<>(dms<south>(35, 18, 27)),
        longitude<>(dms<east>(149, 7, 27.9)));
    std::cout << canberra << std::endl;
}
*/
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
TheIdeasMan
  • 77
  • 1
  • 7

3 Answers3

2

Here are some conversion methods I use with boost units and angles:

double ToDegrees(const Angle & angle)
{
    return static_cast<boost::units::quantity<boost::units::degree::plane_angle>>(angle).value();
}

double ToRadians(const Angle & angle)
{
    return static_cast<boost::units::quantity<boost::units::si::plane_angle>>(angle).value();
}

These are complemented by type-safe factories:

Angle Degrees(double angleInDegrees)
{
    return angleInDegrees * boost::units::degree::degrees;
}

Angle Radians(double angleInRadians)
{
    return Angle(angleInRadians * boost::units::si::radians);
}

To capture degrees, minutes, seconds, replace degrees doubles above with a conversion struct like this:

struct DMS
{
    DMS(double value)
    {
        degrees = std::floor(value);
        double rem = (value-degrees) * 60;
        minutes = std::floor(rem);
        seconds = (rem-minutes) * 60;
    }

    operator double() const
    {
        return degrees + minutes/60 + seconds/3600;
    }

    double degrees;
    double minutes;
    double seconds;
};
Scott Jones
  • 2,880
  • 13
  • 19
  • Hi Scott, Thanks for the quick reply - cheers. Any ideas on how to do minutes & seconds? I will edit my post to show what I have been trying without success. – TheIdeasMan May 09 '13 at 16:00
  • I'd suggest replacing the double return from ToDegrees and the double angleInDegrees with a simple struct to capture 3 doubles - D, M, S. – Scott Jones May 09 '13 at 16:02
  • Ok, I will give that a go. Is there a way to initialise a boost variable? I have been using C++ awhile but am very new to boost, so maybe I need a fairly explicit example. :) – TheIdeasMan May 09 '13 at 16:11
  • All right, if I use a struct - won't that mean I have to calc the values for deg min sec? I was hoping to get the library to do it. I couldn't find any reasonable tutorials anywhere on the web. – TheIdeasMan May 09 '13 at 16:28
  • Thanks very much - maybe I spent a whole looking for ways to do it with boost & the facility wasn't there ! OK, I did another edit above with some obsolete code.I was thinking there should be a built in library facility for dealing with geographic coords in dms format. – TheIdeasMan May 09 '13 at 17:12
  • Is there any way to use the arcminute_bbase_unit & arcsecond_base_unit types directly? – TheIdeasMan May 09 '13 at 17:19
  • Probably - haven't had a need to go beyond just floating point degrees. – Scott Jones May 09 '13 at 17:52
  • @Scott Jones, can you explain to me, where the `Angle` comes from? I'm new to C++ and Boost. I do know the following: `typedef boost::units::quantity RadiansAngle; typedef boost::units::quantity DegreesAngle;` Is that `Angle` defined by Boost.Units or by yourself? If the latter, how do you declare it? – Florian Wolters Nov 13 '13 at 09:13
  • where the Angle? example pls? – Yen Dang Jun 09 '22 at 05:56
0

Your first type safe factory is not returning an Angle.

Maybe you can try:

return Angle( angleInDegrees * boost::units::degree::degrees);
Tezirg
  • 1,629
  • 1
  • 10
  • 20
dan
  • 1
  • and make sure you have the types right so the proper numerical conversion is done too ( ie PI/180). Use these functions to test:/// theta is radian units (si) template bool isRad(const boost::units::quantity& theta) { return true; } /// theta in other angular units template bool isRad(const boost::units::quantity, Y>& theta) { return false; } – dan May 24 '17 at 17:21
0

and make sure you have the types right so the proper numerical conversion is done too (ie PI/180). Use these functions to test:

///  theta is radian units  (si)
template<class Y>
bool isRad(const boost::units::quantity<si::plane_angle, Y>& theta)
{
    return true;
}
///  theta in other angular units 
template<class System, class Y>
bool isRad(const boost::units::quantity<boost::units::unit<boost::units::plane_angle_dimension, 
System>, Y>& theta)
{
    return false;
} 
dan
  • 1