diff --git a/search/search_quality/assessment_tool/CMakeLists.txt b/search/search_quality/assessment_tool/CMakeLists.txt index 0ba92f9b21..faad856967 100644 --- a/search/search_quality/assessment_tool/CMakeLists.txt +++ b/search/search_quality/assessment_tool/CMakeLists.txt @@ -13,6 +13,8 @@ set( context.hpp edits.cpp edits.hpp + feature_info_dialog.cpp + feature_info_dialog.hpp helpers.cpp helpers.hpp main_model.cpp diff --git a/search/search_quality/assessment_tool/feature_info_dialog.cpp b/search/search_quality/assessment_tool/feature_info_dialog.cpp new file mode 100644 index 0000000000..116a419afa --- /dev/null +++ b/search/search_quality/assessment_tool/feature_info_dialog.cpp @@ -0,0 +1,114 @@ +#include "search/search_quality/assessment_tool/feature_info_dialog.hpp" + +#include "search/result.hpp" + +#include "indexer/classificator.hpp" +#include "indexer/feature.hpp" +#include "indexer/feature_algo.hpp" + +#include "coding/multilang_utf8_string.hpp" + +#include "geometry/latlon.hpp" + +#include "base/assert.hpp" +#include "base/string_utils.hpp" + +#include +#include +#include + +#include +#include +#include +#include + +using namespace std; + +namespace +{ +QLabel * MakeSelectableLabel(string const & s) +{ + auto * result = new QLabel(QString::fromStdString(s)); + result->setTextInteractionFlags(Qt::TextSelectableByMouse); + return result; +} +} // namespace + +FeatureInfoDialog::FeatureInfoDialog(QWidget * parent, FeatureType & ft, + search::AddressInfo const & address, string const & locale) + : QDialog(parent) +{ + auto * layout = new QGridLayout(); + + { + auto const & id = ft.GetID(); + CHECK(id.IsValid(), ()); + + auto * label = new QLabel("id:"); + auto * content = MakeSelectableLabel(id.GetMwmName() + ", " + strings::to_string(id.m_index)); + + AddRow(*layout, label, content); + } + + { + auto * label = new QLabel("lat lon:"); + auto const ll = MercatorBounds::ToLatLon(feature::GetCenter(ft)); + auto const ss = strings::to_string_dac(ll.lat, 5) + " " + strings::to_string_dac(ll.lon, 5); + auto * content = MakeSelectableLabel(ss); + + AddRow(*layout, label, content); + } + + { + int8_t const localeCode = StringUtf8Multilang::GetLangIndex(locale); + vector codes = {{StringUtf8Multilang::kDefaultCode, StringUtf8Multilang::kEnglishCode}}; + if (localeCode != StringUtf8Multilang::kUnsupportedLanguageCode && + ::find(codes.begin(), codes.end(), localeCode) == codes.end()) + { + codes.push_back(localeCode); + } + + for (auto const & code : codes) + { + string name; + if (!ft.GetName(code, name)) + continue; + + auto const * lang = StringUtf8Multilang::GetLangByCode(code); + CHECK(lang, ("Can't find lang by code:", code)); + auto * label = new QLabel(QString::fromStdString(string(lang) + ":")); + auto * content = MakeSelectableLabel(name); + + AddRow(*layout, label, content); + } + } + + { + auto const & c = classif(); + + vector types; + ft.ForEachType([&](uint32_t type) { types.push_back(c.GetReadableObjectName(type)); }); + + if (!types.empty()) + { + auto * label = new QLabel("types:"); + auto * content = MakeSelectableLabel(strings::JoinStrings(types, " " /* delimiter */)); + + AddRow(*layout, label, content); + } + } + + { + auto * label = new QLabel("address:"); + auto * content = MakeSelectableLabel(address.FormatAddress()); + + AddRow(*layout, label, content); + } + + auto * ok = new QPushButton("OK"); + ok->setDefault(true); + connect(ok, &QPushButton::clicked, [&]() { accept(); }); + AddRow(*layout, ok); + + setLayout(layout); +} diff --git a/search/search_quality/assessment_tool/feature_info_dialog.hpp b/search/search_quality/assessment_tool/feature_info_dialog.hpp new file mode 100644 index 0000000000..7b39251c20 --- /dev/null +++ b/search/search_quality/assessment_tool/feature_info_dialog.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +#include + +class FeatureType; + +namespace search +{ +struct AddressInfo; +} + +class FeatureInfoDialog : public QDialog +{ + Q_OBJECT +public: + FeatureInfoDialog(QWidget * parent, FeatureType & ft, search::AddressInfo const & address, + std::string const & locale); + +private: + void AddElems(QGridLayout & layout, int row, int col, QWidget * widget) + { + layout.addWidget(widget, row, col); + } + + template + void AddElems(QGridLayout & layout, int row, int col, QWidget * widget, Args *... args) + { + AddElems(layout, row, col, widget); + AddElems(layout, row, col + 1, args...); + } + + template + void AddRow(QGridLayout & layout, Args *... args) + { + AddElems(layout, m_numRows /* row */, 0 /* col */, args...); + ++m_numRows; + } + + int m_numRows = 0; +}; diff --git a/search/search_quality/assessment_tool/main_view.cpp b/search/search_quality/assessment_tool/main_view.cpp index 1aae7b2601..5e030d2a80 100644 --- a/search/search_quality/assessment_tool/main_view.cpp +++ b/search/search_quality/assessment_tool/main_view.cpp @@ -1,5 +1,6 @@ #include "search/search_quality/assessment_tool/main_view.hpp" +#include "search/search_quality/assessment_tool/feature_info_dialog.hpp" #include "search/search_quality/assessment_tool/helpers.hpp" #include "search/search_quality/assessment_tool/model.hpp" #include "search/search_quality/assessment_tool/results_view.hpp" @@ -12,6 +13,8 @@ #include "map/framework.hpp" #include "map/place_page_info.hpp" +#include "indexer/feature_algo.hpp" + #include "geometry/mercator.hpp" #include "base/assert.hpp" @@ -48,8 +51,23 @@ MainView::MainView(Framework & framework) : m_framework(framework) m_framework.SetMapSelectionListeners( [this](place_page::Info const & info) { auto const & selectedFeature = info.GetID(); - if (selectedFeature.IsValid()) - m_selectedFeature = selectedFeature; + if (!selectedFeature.IsValid()) + return; + m_selectedFeature = selectedFeature; + + if (m_skipFeatureInfoDialog) + { + m_skipFeatureInfoDialog = false; + return; + } + + FeatureType ft; + if (!m_framework.GetFeatureByID(selectedFeature, ft)) + return; + + auto const address = m_framework.GetAddressInfoAtPoint(feature::GetCenter(ft)); + FeatureInfoDialog dialog(this /* parent */, ft, address, m_sampleLocale); + dialog.exec(); }, [this](bool /* switchFullScreenMode */) { m_selectedFeature = FeatureID(); }); } @@ -84,6 +102,8 @@ void MainView::OnSearchCompleted() void MainView::ShowSample(size_t sampleIndex, search::Sample const & sample, bool positionAvailable, m2::PointD const & position, bool hasEdits) { + m_sampleLocale = sample.m_locale; + MoveViewportToRect(sample.m_viewport); m_sampleView->SetContents(sample, positionAvailable, position); @@ -122,6 +142,7 @@ void MainView::ClearSearchResultMarks() { m_sampleView->ClearSearchResultMarks() void MainView::MoveViewportToResult(search::Result const & result) { + m_skipFeatureInfoDialog = true; m_framework.SelectSearchResult(result, false /* animation */); } @@ -186,6 +207,9 @@ void MainView::Clear() m_sampleView->Clear(); SetSampleDockTitle(false /* hasEdits */); + + m_skipFeatureInfoDialog = false; + m_sampleLocale.clear(); } void MainView::closeEvent(QCloseEvent * event) diff --git a/search/search_quality/assessment_tool/main_view.hpp b/search/search_quality/assessment_tool/main_view.hpp index 59968fc668..fc228d4df9 100644 --- a/search/search_quality/assessment_tool/main_view.hpp +++ b/search/search_quality/assessment_tool/main_view.hpp @@ -123,4 +123,7 @@ private: State m_state = State::BeforeSearch; FeatureID m_selectedFeature; + + bool m_skipFeatureInfoDialog = false; + std::string m_sampleLocale; }; diff --git a/search/search_quality/features_collector_tool/features_collector_tool.cpp b/search/search_quality/features_collector_tool/features_collector_tool.cpp index 36cfdea799..f87fe86676 100644 --- a/search/search_quality/features_collector_tool/features_collector_tool.cpp +++ b/search/search_quality/features_collector_tool/features_collector_tool.cpp @@ -123,7 +123,7 @@ int main(int argc, char * argv[]) LOG(LINFO, ("writable dir =", platform.WritableDir())); LOG(LINFO, ("resources dir =", platform.ResourcesDir())); - Storage storage(countriesFile, FLAGS_mwm_path); + Storage storage(countriesFile); storage.Init(&DidDownload, &WillDelete); auto infoGetter = CountryInfoReader::CreateCountryInfoReader(platform); infoGetter->InitAffiliationsInfo(&storage.GetAffiliations()); @@ -177,8 +177,6 @@ int main(int argc, char * argv[]) { auto const & sample = samples[i]; - engine.SetLocale(sample.m_locale); - search::SearchParams params; sample.FillSearchParams(params); TestSearchRequest request(engine, params); @@ -217,6 +215,7 @@ int main(int argc, char * argv[]) if (FLAGS_stats_path.empty()) { + cerr << string(34, '=') << " Statistics " << string(34, '=') << endl; DisplayStats(cerr, samples, stats); } else diff --git a/search/search_quality/matcher.cpp b/search/search_quality/matcher.cpp index 7afac4dbc0..b015843dad 100644 --- a/search/search_quality/matcher.cpp +++ b/search/search_quality/matcher.cpp @@ -4,6 +4,7 @@ #include "indexer/feature.hpp" #include "indexer/feature_algo.hpp" +#include "indexer/search_string_utils.hpp" #include "base/string_utils.hpp" @@ -66,7 +67,7 @@ bool Matcher::Matches(Sample::Result const & golden, FeatureType & ft) else { ft.ForEachName([&golden, &nameMatches](int8_t /* lang */, string const & name) { - if (golden.m_name == strings::MakeUniString(name)) + if (NormalizeAndSimplifyString(ToUtf8(golden.m_name)) == NormalizeAndSimplifyString(name)) { nameMatches = true; return base::ControlFlow::Break; @@ -75,8 +76,13 @@ bool Matcher::Matches(Sample::Result const & golden, FeatureType & ft) }); } - return nameMatches && golden.m_houseNumber == houseNumber && - MercatorBounds::DistanceOnEarth(golden.m_pos, center) < kToleranceMeters; + bool houseNumberMatches = true; + if (!golden.m_houseNumber.empty() && !houseNumber.empty()) + houseNumberMatches = golden.m_houseNumber == houseNumber; + + return nameMatches && houseNumberMatches && + MercatorBounds::DistanceOnEarth(golden.m_pos, center) < + kToleranceMeters; } bool Matcher::Matches(Sample::Result const & golden, search::Result const & actual) diff --git a/search/search_quality/sample.cpp b/search/search_quality/sample.cpp index 827b78657d..be9fa5ae44 100644 --- a/search/search_quality/sample.cpp +++ b/search/search_quality/sample.cpp @@ -195,7 +195,9 @@ void Sample::FillSearchParams(search::SearchParams & params) const if (m_posAvailable) params.m_position = m_pos; + params.m_needAddress = true; params.m_suggestsEnabled = false; + params.m_needHighlighting = false; } void FromJSONObject(json_t * root, string const & field, Sample::Result::Relevance & relevance) diff --git a/search/search_quality/search_quality_tool/search_quality_tool.cpp b/search/search_quality/search_quality_tool/search_quality_tool.cpp index b670b08488..a60f8a31cd 100644 --- a/search/search_quality/search_quality_tool/search_quality_tool.cpp +++ b/search/search_quality/search_quality_tool/search_quality_tool.cpp @@ -368,7 +368,7 @@ int main(int argc, char * argv[]) LOG(LINFO, ("writable dir =", platform.WritableDir())); LOG(LINFO, ("resources dir =", platform.ResourcesDir())); - Storage storage(countriesFile, FLAGS_mwm_path); + Storage storage(countriesFile); storage.Init(&DidDownload, &WillDelete); auto infoGetter = CountryInfoReader::CreateCountryInfoReader(platform); infoGetter->InitAffiliationsInfo(&storage.GetAffiliations());