diff options
author | Sergey Magidovich <mgsergio@mapswithme.com> | 2017-08-17 16:17:11 +0300 |
---|---|---|
committer | Yuri Gorshenin <mipt.vi002@gmail.com> | 2017-10-02 15:15:20 +0300 |
commit | 331632c3b5e7557d1ab96261ca52338c40080d60 (patch) | |
tree | fb3466e571502b319462a338d509ce8e2cdeac5c | |
parent | 7a2464a0076383e88c6fe1444eba0ec33d5eb005 (diff) |
Add possibility to mark a path as ignored.
4 files changed, 114 insertions, 59 deletions
diff --git a/openlr/openlr_match_quality/openlr_assessment_tool/mainwindow.cpp b/openlr/openlr_match_quality/openlr_assessment_tool/mainwindow.cpp index 7e47f89d67..99452fb775 100644 --- a/openlr/openlr_match_quality/openlr_assessment_tool/mainwindow.cpp +++ b/openlr/openlr_match_quality/openlr_assessment_tool/mainwindow.cpp @@ -274,12 +274,19 @@ MainWindow::MainWindow(Framework & framework) m_mapWidget->SetMode(MapWidget::Mode::Normal); }, QKeySequence("Ctrl+R")); + m_ignorePathAction = fileMenu->addAction("Ignore path", + [this] { + m_trafficMode->IgnorePath(); + m_mapWidget->SetMode(MapWidget::Mode::Normal); + }, + QKeySequence("Ctrl+I")); m_closeTrafficSampleAction->setEnabled(false /* enabled */); m_saveTrafficSampleAction->setEnabled(false /* enabled */); m_startEditingAction->setEnabled(false /* enabled */); m_commitPathAction->setEnabled(false /* enabled */); m_cancelPathAction->setEnabled(false /* enabled */); + m_ignorePathAction->setEnabled(false /* enabled */); } void MainWindow::CreateTrafficPanel(string const & dataFilePath) @@ -336,6 +343,7 @@ void MainWindow::OnOpenTrafficSample() m_closeTrafficSampleAction->setEnabled(true /* enabled */); m_saveTrafficSampleAction->setEnabled(true /* enabled */); m_startEditingAction->setEnabled(true /* enabled */); + m_ignorePathAction->setEnabled(true /* enabled */); } void MainWindow::OnCloseTrafficSample() @@ -349,6 +357,7 @@ void MainWindow::OnCloseTrafficSample() m_startEditingAction->setEnabled(false /* enabled */); m_commitPathAction->setEnabled(false /* enabled */); m_cancelPathAction->setEnabled(false /* enabled */); + m_ignorePathAction->setEnabled(false /* enabled */); DestroyTrafficPanel(); } @@ -372,4 +381,5 @@ void MainWindow::OnPathEditingStop() { m_commitPathAction->setEnabled(false /* enabled */); m_cancelPathAction->setEnabled(false /* enabled */); + m_cancelPathAction->setEnabled(false /* enabled */); } diff --git a/openlr/openlr_match_quality/openlr_assessment_tool/mainwindow.hpp b/openlr/openlr_match_quality/openlr_assessment_tool/mainwindow.hpp index bc4855afb9..efcf6f4c4d 100644 --- a/openlr/openlr_match_quality/openlr_assessment_tool/mainwindow.hpp +++ b/openlr/openlr_match_quality/openlr_assessment_tool/mainwindow.hpp @@ -45,6 +45,7 @@ private: QAction * m_startEditingAction = nullptr; QAction * m_commitPathAction = nullptr; QAction * m_cancelPathAction = nullptr; + QAction * m_ignorePathAction = nullptr; MapWidget * m_mapWidget = nullptr; }; diff --git a/openlr/openlr_match_quality/openlr_assessment_tool/traffic_mode.cpp b/openlr/openlr_match_quality/openlr_assessment_tool/traffic_mode.cpp index d53fa4a75a..f8d39fc7ce 100644 --- a/openlr/openlr_match_quality/openlr_assessment_tool/traffic_mode.cpp +++ b/openlr/openlr_match_quality/openlr_assessment_tool/traffic_mode.cpp @@ -120,37 +120,31 @@ TrafficMode::TrafficMode(std::string const & dataFileName, { for (auto const xpathNode : segments) { - m_segments.emplace_back(); - auto const xmlSegment = xpathNode.node(); - auto & segment = m_segments.back(); - { - // TODO(mgsergio): Unify error handling interface of openlr_xml_mode and decoded_path parsers. - auto const partnerSegment = xmlSegment.child("reportSegments"); - if (!openlr::SegmentFromXML(partnerSegment, segment.GetPartnerSegment())) - MYTHROW(TrafficModeError, ("An error occured while parsing: can't parse segment")); + openlr::Path matchedPath; + openlr::Path fakePath; + openlr::Path goldenPath; - segment.SetPartnerXML(partnerSegment); - } + openlr::LinearSegment segment; + + // TODO(mgsergio): Unify error handling interface of openlr_xml_mode and decoded_path parsers. + auto const partnerSegmentXML = xmlSegment.child("reportSegments"); + if (!openlr::SegmentFromXML(partnerSegmentXML, segment)) + MYTHROW(TrafficModeError, ("An error occured while parsing: can't parse segment")); if (auto const route = xmlSegment.child("Route")) - { - auto & path = segment.GetMatchedPath(); - path.emplace(); - openlr::PathFromXML(route, m_index, *path); - } + openlr::PathFromXML(route, m_index, matchedPath); if (auto const route = xmlSegment.child("FakeRoute")) - { - auto & path = segment.GetFakePath(); - path.emplace(); - openlr::PathFromXML(route, m_index, *path); - } + openlr::PathFromXML(route, m_index, fakePath); if (auto const route = xmlSegment.child("GoldenRoute")) + openlr::PathFromXML(route, m_index, goldenPath); + + m_segments.emplace_back(segment, matchedPath, fakePath, goldenPath, partnerSegmentXML); + if (auto const status = xmlSegment.child("Ignored")) { - auto & path = segment.GetGoldenPath(); - path.emplace(); - openlr::PathFromXML(route, m_index, *path); + if (status.text().as_bool()) + m_segments.back().Ignore(); } } } @@ -174,20 +168,24 @@ bool TrafficMode::SaveSampleAs(std::string const & fileName) const auto segment = result.append_child("Segment"); segment.append_copy(sc.GetPartnerXMLSegment()); - if (auto const & path = sc.GetMatchedPath()) + if (sc.GetStatus() == SegmentCorrespondence::Status::Ignored) + { + result.append_child("Ignored").text() = true; + } + if (!sc.GetMatchedPath().empty()) { auto node = segment.append_child("Route"); - openlr::PathToXML(*path, node); + openlr::PathToXML(sc.GetMatchedPath(), node); } - if (auto const & path = sc.GetFakePath()) + if (!sc.GetFakePath().empty()) { auto node = segment.append_child("FakeRoute"); - openlr::PathToXML(*path, node); + openlr::PathToXML(sc.GetFakePath(), node); } - if (auto const & path = sc.GetGoldenPath()) + if (!sc.GetGoldenPath().empty()) { auto node = segment.append_child("GoldenRoute"); - openlr::PathToXML(*path, node); + openlr::PathToXML(sc.GetGoldenPath(), node); } } @@ -236,10 +234,10 @@ void TrafficMode::OnItemSelected(QItemSelection const & selected, QItemSelection // TODO(mgsergio): Use a better way to set viewport and scale. m_drawerDelegate->SetViewportCenter(viewportCenter); m_drawerDelegate->DrawEncodedSegment(partnerSegment); - if (auto const & path = m_currentSegment->GetMatchedPath()) - m_drawerDelegate->DrawDecodedSegments(GetPoints(*path)); - if (auto const & path = m_currentSegment->GetGoldenPath()) - m_drawerDelegate->DrawGoldenPath(GetPoints(*path)); + if (!m_currentSegment->GetMatchedPath().empty()) + m_drawerDelegate->DrawDecodedSegments(GetPoints(m_currentSegment->GetMatchedPath())); + if (!m_currentSegment->GetGoldenPath().empty()) + m_drawerDelegate->DrawGoldenPath(GetPoints(m_currentSegment->GetGoldenPath())); } Qt::ItemFlags TrafficMode::flags(QModelIndex const & index) const @@ -257,7 +255,7 @@ void TrafficMode::StartBuildingPath() if (m_buildingPath) MYTHROW(TrafficModeError, ("Path building already in progress.")); - if (m_currentSegment->GetGoldenPath()) + if (!m_currentSegment->GetGoldenPath().empty()) { auto const btn = QMessageBox::question( nullptr, @@ -267,7 +265,7 @@ void TrafficMode::StartBuildingPath() return; } - m_currentSegment->GetGoldenPath() = boost::none; + m_currentSegment->SetGoldenPath({}); m_buildingPath = true; m_drawerDelegate->ClearGoldenPath(); @@ -337,26 +335,48 @@ void TrafficMode::CommitPath() ); } - m_currentSegment->GetGoldenPath() = path; + m_currentSegment->SetGoldenPath(path); m_goldenPath.clear(); } void TrafficMode::RollBackPath() { CHECK(m_currentSegment, ("No segments selected")); + CHECK(m_buildingPath, ("No path building is in progress.")); - // TODO(mgsergio): CHECK ? - if (!m_buildingPath) - MYTHROW(TrafficModeError, ("No path building is in progress.")); + m_buildingPath = false; + + // TODO(mgsergio): Add a method for common visual manipulations. + m_drawerDelegate->ClearAllVisualizedPoints(); + m_drawerDelegate->ClearGoldenPath(); + if (!m_currentSegment->GetGoldenPath().empty()) + m_drawerDelegate->DrawGoldenPath(GetPoints(m_currentSegment->GetGoldenPath())); + + m_goldenPath.clear(); + emit EditingStopped(); +} + +void TrafficMode::IgnorePath() +{ + CHECK(m_currentSegment, ("No segments selected")); + + if (!m_currentSegment->GetGoldenPath().empty()) + { + auto const btn = QMessageBox::question( + nullptr, + "Override warning", + "The selected segment has a golden path. Do you want to discard it?"); + if (btn == QMessageBox::No) + return; + } m_buildingPath = false; // TODO(mgsergio): Add a method for common visual manipulations. m_drawerDelegate->ClearAllVisualizedPoints(); m_drawerDelegate->ClearGoldenPath(); - if (auto const & path = m_currentSegment->GetGoldenPath()) - m_drawerDelegate->DrawGoldenPath(GetPoints(*path)); + m_currentSegment->Ignore(); m_goldenPath.clear(); emit EditingStopped(); } diff --git a/openlr/openlr_match_quality/openlr_assessment_tool/traffic_mode.hpp b/openlr/openlr_match_quality/openlr_assessment_tool/traffic_mode.hpp index 209214bebb..eb13692745 100644 --- a/openlr/openlr_match_quality/openlr_assessment_tool/traffic_mode.hpp +++ b/openlr/openlr_match_quality/openlr_assessment_tool/traffic_mode.hpp @@ -15,8 +15,6 @@ #include <unordered_map> #include <utility> -#include <boost/optional.hpp> - #include <QAbstractTableModel> #include <Qt> @@ -59,7 +57,12 @@ private: class SegmentCorrespondence { public: - SegmentCorrespondence() = default; + enum class Status + { + Untouched, + Assessed, + Ignored + }; SegmentCorrespondence(SegmentCorrespondence const & sc) { @@ -71,37 +74,55 @@ public: m_partnerXMLDoc.reset(sc.m_partnerXMLDoc); m_partnerXMLSegment = m_partnerXMLDoc.child("reportSegments"); + + m_status = sc.m_status; } - boost::optional<openlr::Path> const & GetMatchedPath() const { return m_matchedPath; } - boost::optional<openlr::Path> & GetMatchedPath() { return m_matchedPath; } + SegmentCorrespondence(openlr::LinearSegment const & segment, + openlr::Path const & matchedPath, + openlr::Path const & fakePath, + openlr::Path const & goldenPath, + pugi::xml_node const & partnerSegmentXML) : m_partnerSegment(segment) + , m_matchedPath(matchedPath) + , m_fakePath(fakePath) + { + SetGoldenPath(goldenPath); + + m_partnerXMLDoc.append_copy(partnerSegmentXML); + m_partnerXMLSegment = m_partnerXMLDoc.child("reportSegments"); + CHECK(m_partnerXMLSegment, ("Node should contain <reportSegments> part")); + } - boost::optional<openlr::Path> const & GetFakePath() const { return m_fakePath; } - boost::optional<openlr::Path> & GetFakePath() { return m_fakePath; } + openlr::Path const & GetMatchedPath() const { return m_matchedPath; } + openlr::Path const & GetFakePath() const { return m_fakePath; } - boost::optional<openlr::Path> const & GetGoldenPath() const { return m_goldenPath; } - boost::optional<openlr::Path> & GetGoldenPath() { return m_goldenPath; } + openlr::Path const & GetGoldenPath() const { return m_goldenPath; } + void SetGoldenPath(openlr::Path const & p) { + m_goldenPath = p; + m_status = p.empty() ? Status::Untouched : Status::Assessed; + } openlr::LinearSegment const & GetPartnerSegment() const { return m_partnerSegment; } - openlr::LinearSegment & GetPartnerSegment() { return m_partnerSegment; } uint32_t GetPartnerSegmentId() const { return m_partnerSegment.m_segmentId; } pugi::xml_document const & GetPartnerXML() const { return m_partnerXMLDoc; } pugi::xml_node const & GetPartnerXMLSegment() const { return m_partnerXMLSegment; } - void SetPartnerXML(pugi::xml_node const & n) + + Status GetStatus() const { return m_status; } + + void Ignore() { - m_partnerXMLDoc.append_copy(n); - m_partnerXMLSegment = m_partnerXMLDoc.child("reportSegments"); - CHECK(m_partnerXMLSegment, ("Node should contain <reportSegments> part")); + m_status = Status::Ignored; + m_goldenPath.clear(); } private: openlr::LinearSegment m_partnerSegment; - // TODO(mgsergio): Maybe get rid of boost::optional and rely on emptiness of the path instead? - boost::optional<openlr::Path> m_matchedPath; - boost::optional<openlr::Path> m_fakePath; - boost::optional<openlr::Path> m_goldenPath; + + openlr::Path m_matchedPath; + openlr::Path m_fakePath; + openlr::Path m_goldenPath; // A dirty hack to save back SegmentCorrespondence. // TODO(mgsergio): Consider unifying xml serialization with one used in openlr_stat. @@ -109,6 +130,8 @@ private: // This is used by GetPartnerXMLSegment shortcut to return const ref. pugi::xml_node is // just a wrapper so returning by value won't guarantee constness. pugi::xml_node m_partnerXMLSegment; + + Status m_status = Status::Untouched; }; /// This class is used to delegate segments drawing to the DrapeEngine. @@ -188,6 +211,7 @@ public: void PopPoint(); void CommitPath(); void RollBackPath(); + void IgnorePath(); size_t GetPointsCount() const; m2::PointD const & GetPoint(size_t const index) const; |