diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index a268f22a1..adfac2118 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -266,12 +266,21 @@ void TrafficManager::UpdateViewport(ScreenBase const & screen) UpdateActiveMwms(screen.ClipRect(), m_lastDrapeMwmsByRect, m_activeDrapeMwms); } +std::string TrafficManager::GetMwmFilters(std::set & mwms) +{ + std::vector rects; + for (auto mwmId : mwms) + rects.push_back(mwmId.GetInfo()->m_bordersRect); + return traffxml::FiltersToXml(rects); +} + // TODO make this work with multiple sources (e.g. Android) bool TrafficManager::Subscribe(std::set & mwms) { // TODO what if we’re subscribed already? + std::string filterList = GetMwmFilters(mwms); // TODO - LOG(LINFO, ("Would subscribe to", mwms)); + LOG(LINFO, ("Would subscribe to:\n", filterList)); m_subscriptionId = "placeholder_subscription_id"; m_isPollNeeded = true; // would be false if we got a feed here return true; @@ -280,9 +289,11 @@ bool TrafficManager::Subscribe(std::set & mwms) // TODO make this work with multiple sources (e.g. Android) bool TrafficManager::ChangeSubscription(std::set & mwms) { - // TODO what if we’re not subscribed yet? + if (!IsSubscribed()) + return false; + std::string filterList = GetMwmFilters(mwms); // TODO - LOG(LINFO, ("Would change subscription", m_subscriptionId, "to", mwms)); + LOG(LINFO, ("Would change subscription", m_subscriptionId, "to:\n", filterList)); m_isPollNeeded = true; // would be false if we got a feed here return true; } @@ -290,6 +301,7 @@ bool TrafficManager::ChangeSubscription(std::set & mwms) bool TrafficManager::SetSubscriptionArea() { std::set activeMwms; + if (!IsSubscribed()) { { diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp index 678e33de4..3cfd5f0db 100644 --- a/map/traffic_manager.hpp +++ b/map/traffic_manager.hpp @@ -183,6 +183,14 @@ private: traffic::TrafficInfo::Availability m_lastAvailability; }; + /** + * @brief Returns a TraFF filter list for a set of MWMs. + * + * @param mwms The MWMs for which a filter list is to be created. + * @return A `filter_list` in XML format. + */ + std::string GetMwmFilters(std::set & mwms); + /** * @brief Subscribes to a traffic service. * diff --git a/traffxml/traff_model.hpp b/traffxml/traff_model.hpp index 291319c4f..50a08e646 100644 --- a/traffxml/traff_model.hpp +++ b/traffxml/traff_model.hpp @@ -395,6 +395,22 @@ struct TraffMessage using TraffFeed = std::vector; +// TODO Capabilities + +/* + * Filter: currently not implemented. + * We only use bbox, for which we have a suitable data type. + * min_road_class is not needed as we do not filter by road class. + */ + +/* + * TraffSubscription: currently not implemented. + * We just store the ID as a string. + * Filters are only by bbox, not by min_road_class. The list is auto-generated from the list of + * active MWMs and changes exactly when the active MWM set changes, eliminating the need to store + * the full filter list. + */ + /** * @brief Guess the distance to the next point. * diff --git a/traffxml/traff_model_xml.cpp b/traffxml/traff_model_xml.cpp index 1bc634648..d0511bb24 100644 --- a/traffxml/traff_model_xml.cpp +++ b/traffxml/traff_model_xml.cpp @@ -643,4 +643,16 @@ bool ParseTraff(pugi::xml_document const & document, TraffFeed & feed) } return result; } + +std::string FiltersToXml(std::vector & bboxRects) +{ + std::ostringstream os; + for (auto rect : bboxRects) + os << std::format("\n", + mercator::YToLat(rect.minY()), + mercator::XToLon(rect.minX()), + mercator::YToLat(rect.maxY()), + mercator::XToLon(rect.maxX())); + return os.str(); +} } // namespace openlr diff --git a/traffxml/traff_model_xml.hpp b/traffxml/traff_model_xml.hpp index ed090f7ce..b60cadc6f 100644 --- a/traffxml/traff_model_xml.hpp +++ b/traffxml/traff_model_xml.hpp @@ -2,6 +2,11 @@ #include "traffxml/traff_model.hpp" +#include "geometry/rect2d.hpp" + +#include +#include + namespace pugi { class xml_document; @@ -11,4 +16,20 @@ class xml_node; namespace traffxml { bool ParseTraff(pugi::xml_document const & document, TraffFeed & feed); + +/** + * @brief Generates a list of XML `filter` elements from a vector of rects representing bboxes. + * + * The resulting string can be placed inside a TraFF XML `filter_list` element or can be passed as + * an extra to an Android intent. + * + * It will have one `filter` element for each element in `bboxRects`, although simplification may + * be applied to reduce the number of rects (currently not implemented). + * + * The `min_road_class` attribute is not used. + * + * @param bboxRects The rectangles, each of which represents a bounding box. + * @return A string of XML `filter` elements. + */ +std::string FiltersToXml(std::vector & bboxRects); } // namespace traffxml