#pragma once #include #include "ros_bridge/include/message_traits.h" #include #include 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 { std::string messageType(); namespace { const char *lonKey = "longitude"; const char *latKey = "latitude"; const char *altKey = "altitude"; } // namespace //! @brief C++ representation of geographic_msgs/GeoPoint. template 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 auto getAltitude(const T &p, traits::Type2Type) { return p.altitude(); } template auto getAltitude(const T &p, traits::Type2Type) { (void)p; return 0.0; } template void setAltitude(const QJsonValue &o, T &p, traits::Type2Type) { p.setAltitude(o.toDouble()); } template void setAltitude(const QJsonValue &o, T &p, traits::Type2Type) { (void)o; (void)p; } } // namespace detail template bool toJson(const T &p, QJsonObject &value) { value[latKey] = p.latitude(); value[lonKey] = p.longitude(); typedef typename traits::Select::value, traits::Has3Components, traits::Has2Components>::Result Components; // Check if PointType has 2 or 3 dimensions. auto altitude = detail::getAltitude( p, traits::Type2Type()); // If T has no member altitude() // replace it by 0.0; value[altKey] = altitude; return true; } template bool fromJson(const QJsonObject &value, PointType &p) { if (!value.contains("latitude") || !value["latitude"].isDouble()) { return false; } if (!value.contains("longitude") || !value["longitude"].isDouble()) { return false; } if (!value.contains("altitude") || !value["altitude"].isDouble()) { return false; } p.setLatitude(value["latitude"].toDouble()); p.setLongitude(value["longitude"].toDouble()); typedef typename traits::Select::value, traits::Has3Components, traits::Has2Components>::Result Components; // Check if PointType has 2 or 3 dimensions. detail::setAltitude( value["altitude"], p, traits::Type2Type()); // If T has no member altitude() discard // doc["altitude"]; return true; } // namespace detail } // namespace geo_point } // namespace geographic_msgs } // namespace messages } // namespace ros_bridge