diff options
-rw-r--r-- | android/jni/com/mapswithme/maps/Framework.cpp | 6 | ||||
-rw-r--r-- | android/src/com/mapswithme/maps/Framework.java | 2 | ||||
-rw-r--r-- | android/src/com/mapswithme/maps/editor/EditorFragment.java | 2 | ||||
-rw-r--r-- | base/base_tests/stl_helpers_test.cpp | 121 | ||||
-rw-r--r-- | base/internal/message.hpp | 6 | ||||
-rw-r--r-- | base/stl_helpers.hpp | 31 | ||||
-rw-r--r-- | generator/generator_tests_support/test_feature.cpp | 22 | ||||
-rw-r--r-- | generator/generator_tests_support/test_feature.hpp | 12 | ||||
-rw-r--r-- | indexer/editable_map_object.cpp | 17 | ||||
-rw-r--r-- | indexer/editable_map_object.hpp | 4 | ||||
-rw-r--r-- | indexer/indexer_tests/osm_editor_test.cpp | 31 | ||||
-rw-r--r-- | indexer/osm_editor.cpp | 5 | ||||
-rw-r--r-- | iphone/Maps/Classes/Editor/MWMEditorViewController.mm | 1 | ||||
-rw-r--r-- | search/processor.cpp | 3 | ||||
-rw-r--r-- | search/retrieval.cpp | 19 | ||||
-rw-r--r-- | search/search_integration_tests/search_edited_features_test.cpp | 65 | ||||
-rw-r--r-- | search/search_tests_support/test_results_matching.cpp | 2 | ||||
-rw-r--r-- | search/search_tests_support/test_results_matching.hpp | 5 |
18 files changed, 267 insertions, 87 deletions
diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 37db6c3b21..2dec5eb700 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -713,6 +713,12 @@ Java_com_mapswithme_maps_Framework_nativeGetDrawScale(JNIEnv * env, jclass) return static_cast<jint>(frm()->GetDrawScale()); } +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_Framework_nativeUpdateUserViewportChanged(JNIEnv * env, jclass) +{ + frm()->UpdateUserViewportChanged(); +} + JNIEXPORT jdoubleArray JNICALL Java_com_mapswithme_maps_Framework_nativeGetScreenRectCenter(JNIEnv * env, jclass) { diff --git a/android/src/com/mapswithme/maps/Framework.java b/android/src/com/mapswithme/maps/Framework.java index 77c4f028fe..baac6d2441 100644 --- a/android/src/com/mapswithme/maps/Framework.java +++ b/android/src/com/mapswithme/maps/Framework.java @@ -99,6 +99,8 @@ public class Framework public static native void nativeShowTrackRect(int category, int track); public static native int nativeGetDrawScale(); + + public static native int nativeUpdateUserViewportChanged(); @Size(2) public static native double[] nativeGetScreenRectCenter(); diff --git a/android/src/com/mapswithme/maps/editor/EditorFragment.java b/android/src/com/mapswithme/maps/editor/EditorFragment.java index fc5db7dc49..0e569818bc 100644 --- a/android/src/com/mapswithme/maps/editor/EditorFragment.java +++ b/android/src/com/mapswithme/maps/editor/EditorFragment.java @@ -22,6 +22,7 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; +import com.mapswithme.maps.Framework; import com.mapswithme.maps.R; import com.mapswithme.maps.base.BaseMwmFragment; import com.mapswithme.maps.bookmarks.data.Metadata.MetadataType; @@ -620,6 +621,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe public void onClick(DialogInterface dialog, int which) { Editor.nativeRollbackMapObject(); + Framework.nativeUpdateUserViewportChanged(); mParent.onBackPressed(); } }) diff --git a/base/base_tests/stl_helpers_test.cpp b/base/base_tests/stl_helpers_test.cpp index af47c7e5fb..029df6af98 100644 --- a/base/base_tests/stl_helpers_test.cpp +++ b/base/base_tests/stl_helpers_test.cpp @@ -3,6 +3,7 @@ #include "base/stl_helpers.hpp" #include "std/algorithm.hpp" +#include "std/deque.hpp" #include "std/utility.hpp" #include "std/vector.hpp" @@ -19,95 +20,109 @@ private: int m_v; }; -UNIT_TEST(LessBy) +template <template <typename...> class Cont> +void TestSortUnique() { { - using TValue = pair<int, int>; - - vector<TValue> v = {{2, 2}, {0, 4}, {3, 1}, {4, 0}, {1, 3}}; - sort(v.begin(), v.end(), my::LessBy(&TValue::first)); - for (size_t i = 0; i < v.size(); ++i) - TEST_EQUAL(i, v[i].first, ()); + Cont<int> actual = {1, 2, 1, 4, 3, 5, 2, 7, 1}; + my::SortUnique(actual); + Cont<int> const expected = {1, 2, 3, 4, 5, 7}; + TEST_EQUAL(actual, expected, ()); + } + { + using Value = int; + using Pair = pair<Value, int>; + Cont<Pair> d = + {{1, 22}, {2, 33}, {1, 23}, {4, 54}, {3, 34}, {5, 23}, {2, 23}, {7, 32}, {1, 12}}; - vector<TValue const *> pv; - for (auto const & p : v) - pv.push_back(&p); + my::SortUnique(d, my::LessBy(&Pair::first), my::EqualsBy(&Pair::first)); - sort(pv.begin(), pv.end(), my::LessBy(&TValue::second)); - for (size_t i = 0; i < pv.size(); ++i) - TEST_EQUAL(i, pv[i]->second, ()); + Cont<Value> const expected = {1, 2, 3, 4, 5, 7}; + TEST_EQUAL(d.size(), expected.size(), ()); + for (size_t i = 0; i < d.size(); ++i) + TEST_EQUAL(d[i].first, expected[i], (i)); } - { - vector<Int> v; - for (int i = 9; i >= 0; --i) - v.emplace_back(i); + using Value = double; + using Pair = pair<Value, int>; + Cont<Pair> d = + {{0.5, 11}, {1000.99, 234}, {0.5, 23}, {1234.56789, 54}, {1000.99, 34}}; - sort(v.begin(), v.end(), my::LessBy(&Int::Get)); - for (size_t i = 0; i < v.size(); ++i) - TEST_EQUAL(v[i].Get(), static_cast<int>(i), ()); + my::SortUnique(d, my::LessBy(&Pair::first), my::EqualsBy(&Pair::first)); + + Cont<Value> const expected = {0.5, 1000.99, 1234.56789}; + TEST_EQUAL(d.size(), expected.size(), ()); + for (size_t i = 0; i < d.size(); ++i) + TEST_EQUAL(d[i].first, expected[i], (i)); } } -UNIT_TEST(EqualsBy) +template <template <typename...> class Cont> +void TestEqualsBy() { { - using TValue = pair<int, int>; - vector<TValue> actual = {{1, 2}, {1, 3}, {2, 100}, {3, 7}, {3, 8}, {2, 500}}; - actual.erase(unique(actual.begin(), actual.end(), my::EqualsBy(&TValue::first)), actual.end()); + using Value = pair<int, int>; + Cont<Value> actual = {{1, 2}, {1, 3}, {2, 100}, {3, 7}, {3, 8}, {2, 500}}; + actual.erase(unique(actual.begin(), actual.end(), my::EqualsBy(&Value::first)), actual.end()); - vector<int> const expected = {{1, 2, 3, 2}}; + Cont<int> const expected = {{1, 2, 3, 2}}; TEST_EQUAL(expected.size(), actual.size(), ()); for (size_t i = 0; i < actual.size(); ++i) TEST_EQUAL(expected[i], actual[i].first, ()); } { - vector<Int> actual; + Cont<Int> actual; for (auto const v : {0, 0, 1, 2, 2, 0}) actual.emplace_back(v); actual.erase(unique(actual.begin(), actual.end(), my::EqualsBy(&Int::Get)), actual.end()); - vector<int> const expected = {{0, 1, 2, 0}}; + Cont<int> const expected = {{0, 1, 2, 0}}; TEST_EQUAL(expected.size(), actual.size(), ()); for (size_t i = 0; i < actual.size(); ++i) TEST_EQUAL(expected[i], actual[i].Get(), ()); } } -UNIT_TEST(SortUnique) +UNIT_TEST(LessBy) { { - vector<int> actual = {1, 2, 1, 4, 3, 5, 2, 7, 1}; - my::SortUnique(actual); - vector<int> const expected = {1, 2, 3, 4, 5, 7}; - TEST_EQUAL(actual, expected, ()); - } - { - using TValue = int; - using TPair = pair<TValue, int>; - vector<TPair> v = - {{1, 22}, {2, 33}, {1, 23}, {4, 54}, {3, 34}, {5, 23}, {2, 23}, {7, 32}, {1, 12}}; + using Value = pair<int, int>; - my::SortUnique<TPair>(v, my::LessBy(&TPair::first), my::EqualsBy(&TPair::first)); + vector<Value> v = {{2, 2}, {0, 4}, {3, 1}, {4, 0}, {1, 3}}; + sort(v.begin(), v.end(), my::LessBy(&Value::first)); + for (size_t i = 0; i < v.size(); ++i) + TEST_EQUAL(i, v[i].first, ()); - vector<TValue> const expected = {1, 2, 3, 4, 5, 7}; - TEST_EQUAL(v.size(), expected.size(), ()); - for (int i = 0; i < v.size(); ++i) - TEST_EQUAL(v[i].first, expected[i], (i)); + vector<Value const *> pv; + for (auto const & p : v) + pv.push_back(&p); + + sort(pv.begin(), pv.end(), my::LessBy(&Value::second)); + for (size_t i = 0; i < pv.size(); ++i) + TEST_EQUAL(i, pv[i]->second, ()); } - { - using TValue = double; - using TPair = pair<TValue, int>; - vector<TPair> v = - {{0.5, 11}, {1000.99, 234}, {0.5, 23}, {1234.56789, 54}, {1000.99, 34}}; - my::SortUnique<TPair>(v, my::LessBy(&TPair::first), my::EqualsBy(&TPair::first)); + { + vector<Int> v; + for (int i = 9; i >= 0; --i) + v.emplace_back(i); - vector<TValue> const expected = {0.5, 1000.99, 1234.56789}; - TEST_EQUAL(v.size(), expected.size(), ()); - for (int i = 0; i < v.size(); ++i) - TEST_EQUAL(v[i].first, expected[i], (i)); + sort(v.begin(), v.end(), my::LessBy(&Int::Get)); + for (size_t i = 0; i < v.size(); ++i) + TEST_EQUAL(v[i].Get(), static_cast<int>(i), ()); } } + +UNIT_TEST(EqualsBy_VectorTest) +{ + TestEqualsBy<vector>(); + TestEqualsBy<deque>(); +} + +UNIT_TEST(SortUnique_VectorTest) +{ + TestSortUnique<vector>(); + TestSortUnique<deque>(); +} } // namespace diff --git a/base/internal/message.hpp b/base/internal/message.hpp index ee6487b9cd..f9775a9a15 100644 --- a/base/internal/message.hpp +++ b/base/internal/message.hpp @@ -1,5 +1,6 @@ #pragma once #include "std/array.hpp" +#include "std/deque.hpp" #include "std/functional.hpp" #include "std/initializer_list.hpp" #include "std/iterator.hpp" @@ -100,6 +101,11 @@ template <typename T> inline string DebugPrint(vector<T> const & v) return ::my::impl::DebugPrintSequence(v.begin(), v.end()); } +template <typename T> inline string DebugPrint(deque<T> const & d) +{ + return ::my::impl::DebugPrintSequence(d.begin(), d.end()); +} + template <typename T> inline string DebugPrint(list<T> const & v) { return ::my::impl::DebugPrintSequence(v.begin(), v.end()); diff --git a/base/stl_helpers.hpp b/base/stl_helpers.hpp index 0121e12613..3a667766de 100644 --- a/base/stl_helpers.hpp +++ b/base/stl_helpers.hpp @@ -5,7 +5,6 @@ #include "std/utility.hpp" #include "std/vector.hpp" - namespace my { namespace impl @@ -80,28 +79,28 @@ struct Equals<false, T, C> }; } // namespace impl -// Sorts and removes duplicate entries from |v|. -template <typename T> -void SortUnique(vector<T> & v) +// Sorts and removes duplicate entries from |c|. +template <typename Cont> +void SortUnique(Cont & c) { - sort(v.begin(), v.end()); - v.erase(unique(v.begin(), v.end()), v.end()); + sort(c.begin(), c.end()); + c.erase(unique(c.begin(), c.end()), c.end()); } -// Sorts according to |comp| and removes duplicate entries according to |pred| from |v|. -// Note. If several entries are equal according to |pred| an arbitrary entry of them -// is left in |v| after a call of this function. -template <typename T, typename TLess, typename TEquals> -void SortUnique(vector<T> & v, TLess && less, TEquals && equals) +// Sorts according to |less| and removes duplicate entries according to |equals| from |c|. +// Note. If several entries are equal according to |less| an arbitrary entry of them +// is left in |c| after a call of this function. +template <class Cont, typename Less, typename Equals> +void SortUnique(Cont & c, Less && less, Equals && equals) { - sort(v.begin(), v.end(), forward<TLess>(less)); - v.erase(unique(v.begin(), v.end(), forward<TEquals>(equals)), v.end()); + sort(c.begin(), c.end(), forward<Less>(less)); + c.erase(unique(c.begin(), c.end(), forward<Equals>(equals)), c.end()); } -template <typename T, class TFn> -void EraseIf(vector<T> & v, TFn && fn) +template <class Cont, class Fn> +void EraseIf(Cont & c, Fn && fn) { - v.erase(remove_if(v.begin(), v.end(), forward<TFn>(fn)), v.end()); + c.erase(remove_if(c.begin(), c.end(), forward<Fn>(fn)), c.end()); } // Creates a comparer being able to compare two instances of class C diff --git a/generator/generator_tests_support/test_feature.cpp b/generator/generator_tests_support/test_feature.cpp index ea8f24329f..bf645e3735 100644 --- a/generator/generator_tests_support/test_feature.cpp +++ b/generator/generator_tests_support/test_feature.cpp @@ -3,10 +3,14 @@ #include "generator/feature_builder.hpp" #include "indexer/classificator.hpp" +#include "indexer/editable_map_object.hpp" #include "indexer/feature.hpp" #include "indexer/feature_algo.hpp" +#include "indexer/feature_decl.hpp" #include "indexer/feature_meta.hpp" #include "indexer/ftypes_matcher.hpp" +#include "indexer/mwm_set.hpp" +#include "indexer/osm_editor.hpp" #include "coding/multilang_utf8_string.hpp" @@ -162,6 +166,24 @@ TestPOI::TestPOI(m2::PointD const & center, string const & name, string const & m_types = {{"railway", "station"}}; } +// static +pair<TestPOI, FeatureID> TestPOI::AddWithEditor(osm::Editor & editor, MwmSet::MwmId const & mwmId, + string const & enName, m2::PointD const & pt) +{ + TestPOI poi(pt, enName, "en"); + + osm::EditableMapObject emo; + editor.CreatePoint(classif().GetTypeByPath({"shop", "bakery"}), pt, mwmId, emo); + + StringUtf8Multilang names; + names.AddString(StringUtf8Multilang::GetLangIndex("en"), enName); + emo.SetName(names); + emo.SetTestId(poi.GetId()); + + editor.SaveEditedFeature(emo); + return {poi, emo.GetID()}; +} + void TestPOI::Serialize(FeatureBuilder1 & fb) const { TestFeature::Serialize(fb); diff --git a/generator/generator_tests_support/test_feature.hpp b/generator/generator_tests_support/test_feature.hpp index fb345505ed..2c5af1e267 100644 --- a/generator/generator_tests_support/test_feature.hpp +++ b/generator/generator_tests_support/test_feature.hpp @@ -1,13 +1,22 @@ #pragma once +#include "indexer/feature_decl.hpp" +#include "indexer/mwm_set.hpp" + #include "geometry/point2d.hpp" #include "std/string.hpp" +#include "std/utility.hpp" #include "std/vector.hpp" class FeatureBuilder1; class FeatureType; +namespace osm +{ +class Editor; +} + namespace generator { namespace tests_support @@ -91,6 +100,9 @@ class TestPOI : public TestFeature public: TestPOI(m2::PointD const & center, string const & name, string const & lang); + static pair<TestPOI, FeatureID> AddWithEditor(osm::Editor & editor, MwmSet::MwmId const & mwmId, + string const & enName, m2::PointD const & pt); + // TestFeature overrides: void Serialize(FeatureBuilder1 & fb) const override; string ToString() const override; diff --git a/indexer/editable_map_object.cpp b/indexer/editable_map_object.cpp index 85be3f9419..800e8bb41c 100644 --- a/indexer/editable_map_object.cpp +++ b/indexer/editable_map_object.cpp @@ -9,7 +9,7 @@ #include "std/cctype.hpp" #include "std/cmath.hpp" - +#include "std/sstream.hpp" namespace { @@ -285,6 +285,21 @@ string EditableMapObject::GetWikipedia() const return m_metadata.Get(feature::Metadata::FMD_WIKIPEDIA); } +uint64_t EditableMapObject::GetTestId() const +{ + istringstream iss(m_metadata.Get(feature::Metadata::FMD_TEST_ID)); + uint64_t id; + iss >> id; + return id; +} + +void EditableMapObject::SetTestId(uint64_t id) +{ + ostringstream oss; + oss << id; + m_metadata.Set(feature::Metadata::FMD_TEST_ID, oss.str()); +} + void EditableMapObject::SetEditableProperties(osm::EditableProperties const & props) { m_editableProperties = props; diff --git a/indexer/editable_map_object.hpp b/indexer/editable_map_object.hpp index 0ae8e39714..feaefc4619 100644 --- a/indexer/editable_map_object.hpp +++ b/indexer/editable_map_object.hpp @@ -110,6 +110,10 @@ public: string GetPostcode() const; string GetWikipedia() const; + // These two methods should only be used in tests. + uint64_t GetTestId() const; + void SetTestId(uint64_t id); + void SetEditableProperties(osm::EditableProperties const & props); // void SetFeatureID(FeatureID const & fid); void SetName(StringUtf8Multilang const & name); diff --git a/indexer/indexer_tests/osm_editor_test.cpp b/indexer/indexer_tests/osm_editor_test.cpp index b3e3592d0f..27534b0c51 100644 --- a/indexer/indexer_tests/osm_editor_test.cpp +++ b/indexer/indexer_tests/osm_editor_test.cpp @@ -403,8 +403,8 @@ void EditorTest::GetFeatureStatusTest() TEST_EQUAL(editor.GetFeatureStatus(ft.GetID()), osm::Editor::FeatureStatus::Deleted, ()); }); - osm::EditableMapObject emo; - CreateCafeAtPoint({3.0, 3.0}, mwmId, emo); + osm::EditableMapObject emo; + CreateCafeAtPoint({1.5, 1.5}, mwmId, emo); TEST_EQUAL(editor.GetFeatureStatus(emo.GetID()), osm::Editor::FeatureStatus::Created, ()); } @@ -417,6 +417,8 @@ void EditorTest::IsFeatureUploadedTest() { TestCafe cafe(m2::PointD(1.0, 1.0), "London Cafe", "en"); builder.Add(cafe); + + builder.Add(TestPOI(m2::PointD(10, 10), "Corner Post", "default")); }); ForEachCafeAtPoint(m_index, m2::PointD(1.0, 1.0), [&editor](FeatureType & ft) @@ -445,6 +447,8 @@ void EditorTest::DeleteFeatureTest() { TestCafe cafe(m2::PointD(1.0, 1.0), "London Cafe", "en"); builder.Add(cafe); + + builder.Add(TestPOI(m2::PointD(10, 10), "Corner Post", "default")); }); osm::EditableMapObject emo; @@ -471,6 +475,8 @@ void EditorTest::ClearAllLocalEditsTest() { TestCafe cafe(m2::PointD(1.0, 1.0), "London Cafe", "en"); builder.Add(cafe); + + builder.Add(TestPOI(m2::PointD(10, 10), "Corner Post", "default")); }); osm::EditableMapObject emo; @@ -500,6 +506,8 @@ void EditorTest::GetFeaturesByStatusTest() builder.Add(cafe); builder.Add(unnamedCafe); builder.Add(someCafe); + + builder.Add(TestPOI(m2::PointD(10, 10), "Corner Post", "default")); }); FeatureID modifiedId, deletedId, obsoleteId, createdId; @@ -700,6 +708,8 @@ void EditorTest::GetStatsTest() builder.Add(TestCafe(m2::PointD(3.0, 3.0), "London Cafe", "en")); builder.Add(TestCafe(m2::PointD(4.0, 4.0), "London Cafe", "en")); builder.Add(TestCafe(m2::PointD(5.0, 5.0), "London Cafe", "en")); + + builder.Add(TestPOI(m2::PointD(10, 10), "Corner Post", "default")); }); auto stats = editor.GetStats(); @@ -754,6 +764,8 @@ void EditorTest::IsCreatedFeatureTest() auto const mwmId = ConstructTestMwm([](TestMwmBuilder & builder) { builder.Add(TestCafe(m2::PointD(1.0, 1.0), "London Cafe", "en")); + + builder.Add(TestPOI(m2::PointD(10, 10), "Corner Post", "default")); }); ForEachCafeAtPoint(m_index, m2::PointD(1.0, 1.0), [&editor](FeatureType & ft) @@ -774,6 +786,8 @@ void EditorTest::ForEachFeatureInMwmRectAndScaleTest() auto const mwmId = ConstructTestMwm([](TestMwmBuilder & builder) { builder.Add(TestCafe(m2::PointD(1.0, 1.0), "London Cafe", "en")); + + builder.Add(TestPOI(m2::PointD(100, 100), "Corner Post", "default")); }); { @@ -850,6 +864,8 @@ void EditorTest::LoadMapEditsTest() { builder.Add(TestCafe(m2::PointD(0.0, 0.0), "London Cafe", "en")); builder.Add(TestCafe(m2::PointD(1.0, 1.0), "London Cafe", "en")); + + builder.Add(TestPOI(m2::PointD(100, 100), "Corner Post", "default")); }); auto const rfMwmId = BuildMwm("RF", [](TestMwmBuilder & builder) @@ -858,6 +874,8 @@ void EditorTest::LoadMapEditsTest() builder.Add(TestCafe(m2::PointD(7.0, 7.0), "Moscow Cafe2", "en")); builder.Add(TestCafe(m2::PointD(4.0, 4.0), "Moscow Cafe3", "en")); builder.Add(TestCafe(m2::PointD(6.0, 6.0), "Moscow Cafe4", "en")); + + builder.Add(TestPOI(m2::PointD(100, 100), "Corner Post", "default")); }); vector<FeatureID> features; @@ -984,6 +1002,8 @@ void EditorTest::SaveEditedFeatureTest() auto const mwmId = ConstructTestMwm([](TestMwmBuilder & builder) { builder.Add(TestCafe(m2::PointD(1.0, 1.0), "London Cafe1", "en")); + + builder.Add(TestPOI(m2::PointD(10, 10), "Corner Post", "default")); }); osm::EditableMapObject emo; @@ -1127,12 +1147,7 @@ UNIT_CLASS_TEST(EditorTest, CreateNoteTest) { EditorTest::CreateNoteTest(); } - -UNIT_CLASS_TEST(EditorTest, LoadMapEditstest) -{ - EditorTest::LoadMapEditsTest(); -} - +UNIT_CLASS_TEST(EditorTest, LoadMapEditsTest) { EditorTest::LoadMapEditsTest(); } UNIT_CLASS_TEST(EditorTest, SaveEditedFeatureTest) { EditorTest::SaveEditedFeatureTest(); diff --git a/indexer/osm_editor.cpp b/indexer/osm_editor.cpp index e804dee125..1f2681caa8 100644 --- a/indexer/osm_editor.cpp +++ b/indexer/osm_editor.cpp @@ -1054,6 +1054,11 @@ FeatureID Editor::GenerateNewFeatureId(MwmSet::MwmId const & id) bool Editor::CreatePoint(uint32_t type, m2::PointD const & mercator, MwmSet::MwmId const & id, EditableMapObject & outFeature) { ASSERT(id.IsAlive(), ("Please check that feature is created in valid MWM file before calling this method.")); + if (!id.GetInfo()->m_limitRect.IsPointInside(mercator)) + { + LOG(LERROR, ("Attempt to create a feature outside of the MWM's bounding box.")); + return false; + } outFeature.SetMercator(mercator); outFeature.SetID(GenerateNewFeatureId(id)); outFeature.SetType(type); diff --git a/iphone/Maps/Classes/Editor/MWMEditorViewController.mm b/iphone/Maps/Classes/Editor/MWMEditorViewController.mm index 063ea2bae8..9a060ce207 100644 --- a/iphone/Maps/Classes/Editor/MWMEditorViewController.mm +++ b/iphone/Maps/Classes/Editor/MWMEditorViewController.mm @@ -992,6 +992,7 @@ void registerCellsForTableView(vector<MWMPlacePageCellType> const & cells, UITab if (!f.RollBackChanges(fid)) NSAssert(false, @"We shouldn't call this if we can't roll back!"); + f.UpdateUserViewportChanged(); [self backTap]; }; diff --git a/search/processor.cpp b/search/processor.cpp index 9dd4deaf98..4c96b0c704 100644 --- a/search/processor.cpp +++ b/search/processor.cpp @@ -377,6 +377,7 @@ void Processor::ForEachCategoryType(StringSliceBase const & slice, ToDo && todo) void Processor::Search(SearchParams const & params, m2::RectD const & viewport) { + SetMode(params.m_mode); bool const viewportSearch = m_mode == Mode::Viewport; bool rankPivotIsSet = false; @@ -399,8 +400,8 @@ void Processor::Search(SearchParams const & params, m2::RectD const & viewport) SetMinDistanceOnMapBetweenResults(params.m_minDistanceOnMapBetweenResults); - SetMode(params.m_mode); SetSuggestsEnabled(params.m_suggestsEnabled); + SetInputLocale(params.m_inputLocale); ASSERT(!params.m_query.empty(), ()); diff --git a/search/retrieval.cpp b/search/retrieval.cpp index fb0587d3a4..2c25219706 100644 --- a/search/retrieval.cpp +++ b/search/retrieval.cpp @@ -263,14 +263,25 @@ unique_ptr<coding::CompressedBitVector> RetrievePostcodeFeaturesImpl( // Retrieves from the geometry index corresponding to handle all // features from |coverage|. unique_ptr<coding::CompressedBitVector> RetrieveGeometryFeaturesImpl( - MwmContext const & context, my::Cancellable const & cancellable, - covering::IntervalsT const & coverage, int scale) + MwmContext const & context, my::Cancellable const & cancellable, m2::RectD const & rect, + int scale) { + EditedFeaturesHolder holder(context.GetId()); + + covering::IntervalsT coverage; + CoverRect(rect, scale, coverage); + vector<uint64_t> features; FeaturesCollector collector(cancellable, features); context.ForEachIndex(coverage, scale, collector); + + holder.ForEachModifiedOrCreated([&](FeatureType & ft, uint64_t index) { + auto const center = feature::GetCenter(ft); + if (rect.IsPointInside(center)) + features.push_back(index); + }); return SortFeaturesAndBuildCBV(move(features)); } @@ -338,8 +349,6 @@ unique_ptr<coding::CompressedBitVector> RetrieveGeometryFeatures( MwmContext const & context, my::Cancellable const & cancellable, m2::RectD const & rect, int scale) { - covering::IntervalsT coverage; - CoverRect(rect, scale, coverage); - return RetrieveGeometryFeaturesImpl(context, cancellable, coverage, scale); + return RetrieveGeometryFeaturesImpl(context, cancellable, rect, scale); } } // namespace search diff --git a/search/search_integration_tests/search_edited_features_test.cpp b/search/search_integration_tests/search_edited_features_test.cpp index bd3ed5c7f0..003ecb2c08 100644 --- a/search/search_integration_tests/search_edited_features_test.cpp +++ b/search/search_integration_tests/search_edited_features_test.cpp @@ -59,4 +59,69 @@ UNIT_CLASS_TEST(SearchEditedFeaturesTest, Smoke) TEST(ResultsMatch("wifi bar quahog", rules), ()); } } + +UNIT_CLASS_TEST(SearchEditedFeaturesTest, SearchInViewport) +{ + TestCity city(m2::PointD(0, 0), "Canterlot", "default", 100 /* rank */); + TestPOI bakery0(m2::PointD(0, 0), "Bakery 0", "default"); + TestPOI cornerPost(m2::PointD(100, 100), "Corner Post", "default"); + auto & editor = osm::Editor::Instance(); + + BuildWorld([&](TestMwmBuilder & builder) { builder.Add(city); }); + + auto const countryId = BuildCountry("Equestria", [&](TestMwmBuilder & builder) { + builder.Add(bakery0); + builder.Add(cornerPost); + }); + + auto const tmp1 = TestPOI::AddWithEditor(editor, countryId, "bakery1", {1.0, 1.0}); + TestPOI const & bakery1 = tmp1.first; + FeatureID const & id1 = tmp1.second; + auto const tmp2 = TestPOI::AddWithEditor(editor, countryId, "bakery2", {2.0, 2.0}); + TestPOI const & bakery2 = tmp2.first; + FeatureID const & id2 = tmp2.second; + auto const tmp3 = TestPOI::AddWithEditor(editor, countryId, "bakery3", {3.0, 3.0}); + TestPOI const & bakery3 = tmp3.first; + FeatureID const & id3 = tmp3.second; + UNUSED_VALUE(id2); + + SetViewport(m2::RectD(-1.0, -1.0, 4.0, 4.0)); + { + TRules const rules = {ExactMatch(countryId, bakery0), ExactMatch(countryId, bakery1), + ExactMatch(countryId, bakery2), ExactMatch(countryId, bakery3)}; + + TEST(ResultsMatch("bakery", Mode::Viewport, rules), ()); + } + + SetViewport(m2::RectD(-2.0, -2.0, -1.0, -1.0)); + { + TRules const rules = {}; + + TEST(ResultsMatch("bakery", Mode::Viewport, rules), ()); + } + + SetViewport(m2::RectD(-1.0, -1.0, 1.5, 1.5)); + { + TRules const rules = {ExactMatch(countryId, bakery0), ExactMatch(countryId, bakery1)}; + + TEST(ResultsMatch("bakery", Mode::Viewport, rules), ()); + } + + SetViewport(m2::RectD(1.5, 1.5, 4.0, 4.0)); + { + TRules const rules = {ExactMatch(countryId, bakery2), ExactMatch(countryId, bakery3)}; + + TEST(ResultsMatch("bakery", Mode::Viewport, rules), ()); + } + + editor.DeleteFeature(id1); + editor.DeleteFeature(id3); + + SetViewport(m2::RectD(-1.0, -1.0, 4.0, 4.0)); + { + TRules const rules = {ExactMatch(countryId, bakery0), ExactMatch(countryId, bakery2)}; + + TEST(ResultsMatch("bakery", Mode::Viewport, rules), ()); + } +} } // namespace diff --git a/search/search_tests_support/test_results_matching.cpp b/search/search_tests_support/test_results_matching.cpp index 34d8a3e1b9..ccbfa55b7f 100644 --- a/search/search_tests_support/test_results_matching.cpp +++ b/search/search_tests_support/test_results_matching.cpp @@ -13,7 +13,7 @@ namespace search { namespace tests_support { -ExactMatchingRule::ExactMatchingRule(MwmSet::MwmId const & mwmId, TestFeature & feature) +ExactMatchingRule::ExactMatchingRule(MwmSet::MwmId const & mwmId, TestFeature const & feature) : m_mwmId(mwmId), m_feature(feature) { } diff --git a/search/search_tests_support/test_results_matching.hpp b/search/search_tests_support/test_results_matching.hpp index 24505d369e..3a776d48ca 100644 --- a/search/search_tests_support/test_results_matching.hpp +++ b/search/search_tests_support/test_results_matching.hpp @@ -35,7 +35,8 @@ public: class ExactMatchingRule : public MatchingRule { public: - ExactMatchingRule(MwmSet::MwmId const & mwmId, generator::tests_support::TestFeature & feature); + ExactMatchingRule(MwmSet::MwmId const & mwmId, + generator::tests_support::TestFeature const & feature); // MatchingRule overrides: bool Matches(FeatureType const & feature) const override; @@ -43,7 +44,7 @@ public: private: MwmSet::MwmId m_mwmId; - generator::tests_support::TestFeature & m_feature; + generator::tests_support::TestFeature const & m_feature; }; class AlternativesMatchingRule : public MatchingRule |