#include "testing/testing.hpp" #include "indexer/cell_id.hpp" #include "indexer/locality_index.hpp" #include "indexer/locality_index_builder.hpp" #include "indexer/locality_object.hpp" #include "coding/file_container.hpp" #include "coding/mmap_reader.hpp" #include "coding/reader.hpp" #include "geometry/rect2d.hpp" #include "base/osm_id.hpp" #include #include #include #include #include using namespace indexer; using namespace std; namespace { struct LocalityObjectVector { template void ForEach(ToDo && toDo) const { for_each(m_objects.cbegin(), m_objects.cend(), forward(toDo)); } vector m_objects; }; template void BuildGeoObjectsIndex(ObjectsVector const & objects, Writer & writer, string const & tmpFilePrefix) { auto coverLocality = [](indexer::LocalityObject const & o, int cellDepth, uint64_t cellPenaltyArea) { return covering::CoverGeoObject(o, cellDepth, cellPenaltyArea); }; return covering::BuildLocalityIndex( objects, writer, coverLocality, tmpFilePrefix); } using Ids = set; using RankedIds = vector; template Ids GetIds(LocalityIndex const & index, m2::RectD const & rect) { Ids ids; index.ForEachInRect([&ids](osm::Id const & id) { ids.insert(id.EncodedId()); }, rect); return ids; }; template RankedIds GetRankedIds(LocalityIndex const & index, m2::PointD const & center, m2::PointD const & border, uint32_t topSize) { RankedIds ids; index.ForClosestToPoint([&ids](osm::Id const & id) { ids.push_back(id.EncodedId()); }, center, MercatorBounds::DistanceOnEarth(center, border), topSize); return ids; }; UNIT_TEST(BuildLocalityIndexTest) { LocalityObjectVector objects; objects.m_objects.resize(4); objects.m_objects[0].SetForTests(1, m2::PointD{0, 0}); objects.m_objects[1].SetForTests(2, m2::PointD{1, 0}); objects.m_objects[2].SetForTests(3, m2::PointD{1, 1}); objects.m_objects[3].SetForTests(4, m2::PointD{0, 1}); vector localityIndex; MemWriter> writer(localityIndex); BuildGeoObjectsIndex(objects, writer, "tmp"); MemReader reader(localityIndex.data(), localityIndex.size()); indexer::GeoObjectsIndex index(reader); TEST_EQUAL(GetIds(index, m2::RectD{-0.5, -0.5, 0.5, 0.5}), (Ids{1}), ()); TEST_EQUAL(GetIds(index, m2::RectD{0.5, -0.5, 1.5, 1.5}), (Ids{2, 3}), ()); TEST_EQUAL(GetIds(index, m2::RectD{-0.5, -0.5, 1.5, 1.5}), (Ids{1, 2, 3, 4}), ()); } UNIT_TEST(LocalityIndexRankTest) { LocalityObjectVector objects; objects.m_objects.resize(4); objects.m_objects[0].SetForTests(1, m2::PointD{1, 0}); objects.m_objects[1].SetForTests(2, m2::PointD{2, 0}); objects.m_objects[2].SetForTests(3, m2::PointD{3, 0}); objects.m_objects[3].SetForTests(4, m2::PointD{4, 0}); vector localityIndex; MemWriter> writer(localityIndex); BuildGeoObjectsIndex(objects, writer, "tmp"); MemReader reader(localityIndex.data(), localityIndex.size()); indexer::GeoObjectsIndex index(reader); TEST_EQUAL(GetRankedIds(index, m2::PointD{1, 0} /* center */, m2::PointD{4, 0} /* border */, 4 /* topSize */), (vector{1, 2, 3, 4}), ()); TEST_EQUAL(GetRankedIds(index, m2::PointD{1, 0} /* center */, m2::PointD{3, 0} /* border */, 4 /* topSize */), (vector{1, 2, 3}), ()); TEST_EQUAL(GetRankedIds(index, m2::PointD{4, 0} /* center */, m2::PointD{1, 0} /* border */, 4 /* topSize */), (vector{4, 3, 2, 1}), ()); TEST_EQUAL(GetRankedIds(index, m2::PointD{4, 0} /* center */, m2::PointD{1, 0} /* border */, 2 /* topSize */), (vector{4, 3}), ()); TEST_EQUAL(GetRankedIds(index, m2::PointD{3, 0} /* center */, m2::PointD{0, 0} /* border */, 1 /* topSize */), (vector{3}), ()); } UNIT_TEST(LocalityIndexTopSizeTest) { LocalityObjectVector objects; objects.m_objects.resize(4); objects.m_objects[0].SetForTests(1, m2::PointD{1, 0}); objects.m_objects[1].SetForTests(2, m2::PointD{1, 0}); objects.m_objects[2].SetForTests(3, m2::PointD{1, 0}); objects.m_objects[3].SetForTests(4, m2::PointD{1, 0}); vector localityIndex; MemWriter> writer(localityIndex); BuildGeoObjectsIndex(objects, writer, "tmp"); MemReader reader(localityIndex.data(), localityIndex.size()); indexer::GeoObjectsIndex index(reader); TEST_EQUAL(GetRankedIds(index, m2::PointD{1, 0} /* center */, m2::PointD{0, 0} /* border */, 4 /* topSize */) .size(), 4, ()); TEST_EQUAL(GetRankedIds(index, m2::PointD{1, 0} /* center */, m2::PointD{0, 0} /* border */, 3 /* topSize */) .size(), 3, ()); TEST_EQUAL(GetRankedIds(index, m2::PointD{4, 0} /* center */, m2::PointD{0, 0} /* border */, 1 /* topSize */) .size(), 1, ()); } } // namespace