geopoint.h 4.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#pragma once

#include <string>

#include "ros_bridge/include/message_traits.h"
#include "ros_bridge/rapidjson/include/rapidjson/document.h"

namespace ros_bridge {
//! @brief Namespace containing classes and methodes ros message generation.
namespace messages {
//! @brief Namespace containing classes and methodes for geometry_msgs generation.
namespace geographic_msgs {
//! @brief Namespace containing methodes for geometry_msgs/GeoPoint message generation.
namespace geo_point {

16
std::string messageType();
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149

//! @brief C++ representation of geographic_msgs/GeoPoint.
template<class FloatType = _Float64, class OStream = std::ostream>
class GenericGeoPoint{
public:
    GenericGeoPoint()
        : _latitude(0)
        , _longitude(0)
        , _altitude(0)
    {}
    GenericGeoPoint(const GenericGeoPoint &other)
        : _latitude(other.latitude())
        , _longitude(other.longitude())
        , _altitude(other.altitude())
    {}
    GenericGeoPoint(FloatType latitude, FloatType longitude, FloatType altitude)
        : _latitude(latitude)
        , _longitude(longitude)
        , _altitude(altitude)
    {}

    FloatType latitude()     const {return _latitude;}
    FloatType longitude()    const {return _longitude;}
    FloatType altitude()     const {return _altitude;}

    void setLatitude    (FloatType latitude)    {_latitude  = latitude;}
    void setLongitude   (FloatType longitude)   {_longitude = longitude;}
    void setAltitude    (FloatType altitude)    {_altitude  = altitude;}

    bool operator==(const GenericGeoPoint &p1) {
        return (   p1._latitude == this->_latitude
                && p1._longitude == this->_longitude
                && p1._altitude == this->_altitude);
    }

    bool operator!=(const GenericGeoPoint &p1) {
        return !this->operator==(p1);
    }

    friend OStream& operator<<(OStream& os, const GenericGeoPoint& p)
    {
        os << "lat: " << p._latitude << " lon: " << p._longitude<< " alt: " << p._altitude;
        return os;
    }

private:
    FloatType _latitude;
    FloatType _longitude;
    FloatType _altitude;
};
typedef GenericGeoPoint<> GeoPoint;

namespace detail {

    template <class T>
    auto getAltitude(const T &p, traits::Type2Type<traits::Has3Components>)
    {
        return p.altitude();
    }

    template <class T>
    auto getAltitude(const T &p, traits::Type2Type<traits::Has2Components>)
    {
        (void)p;
        return 0.0;
    }

    template <class T>
    void setAltitude(const rapidjson::Value &doc, T &p, traits::Type2Type<traits::Has3Components>)
    {
        p.setAltitude(doc.GetFloat());
    }

    template <class T>
    void setAltitude(const rapidjson::Value &doc, T &p, traits::Type2Type<traits::Has2Components>)
    {
        (void)doc;
        (void)p;
    }
} // namespace detail

template <class T>
bool toJson(const T&p, rapidjson::Value &value, rapidjson::Document::AllocatorType &allocator)
{
    value.AddMember("latitude", rapidjson::Value().SetFloat((_Float64)p.latitude()), allocator);
    value.AddMember("longitude", rapidjson::Value().SetFloat((_Float64)p.longitude()), allocator);

    typedef typename traits::Select<
            traits::HasMemberAltitude<T>::value,
            traits::Has3Components,
            traits::Has2Components>::Result
            Components; // Check if PointType has 2 or 3 dimensions.
    auto altitude = detail::getAltitude(p, traits::Type2Type<Components>()); // If T has no member altitude() replace it by 0.0;

    value.AddMember("altitude", rapidjson::Value().SetFloat((_Float64)altitude), allocator);
    return true;
}



template <class PointType>
bool fromJson(const rapidjson::Value &value,
              PointType &p)     {
    if (!value.HasMember("latitude") || !value["latitude"].IsFloat()){
        assert(false);
        return false;
    }
    if (!value.HasMember("longitude") || !value["longitude"].IsFloat()){
        assert(false);
        return false;
    }
    if (!value.HasMember("altitude") || !value["altitude"].IsFloat()){
        assert(false);
        return false;
    }

    p.setLatitude(value["latitude"].GetFloat());
    p.setLongitude(value["longitude"].GetFloat());
    typedef typename traits::Select<
            traits::HasMemberSetAltitude<PointType>::value,
            traits::Has3Components,
            traits::Has2Components>::Result
            Components; // Check if PointType has 2 or 3 dimensions.
    detail::setAltitude(value["altitude"], p,  traits::Type2Type<Components>()); // If T has no member altitude() discard doc["altitude"];

    return true;
} // namespace detail


} // namespace geopoint
} // namespace geometry_msgs
} // namespace messages
} // namespace ros_bridge