Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Byko-Ianko <bykoianko@gmail.com>2016-11-17 14:30:16 +0300
committerGitHub <noreply@github.com>2016-11-17 14:30:16 +0300
commit915d8130a778955455e899b973a1b93479c8ba36 (patch)
tree1eea309b5d8d78e2d8a374fe41b86b8848496110 /storage
parent05f4288f2c753f07279925ec0ba0f3fcbc34fac1 (diff)
parent647bc20a338d26108726e40770b8d6779a636e51 (diff)
Merge pull request #4738 from rokuz/intersection-mwm-rect
Added getting mwms by rect
Diffstat (limited to 'storage')
-rw-r--r--storage/country_info_getter.cpp52
-rw-r--r--storage/country_info_getter.hpp9
-rw-r--r--storage/storage_tests/country_info_getter_test.cpp26
3 files changed, 87 insertions, 0 deletions
diff --git a/storage/country_info_getter.cpp b/storage/country_info_getter.cpp
index 3994e618e5..7d07f860cf 100644
--- a/storage/country_info_getter.cpp
+++ b/storage/country_info_getter.cpp
@@ -59,6 +59,23 @@ TCountryId CountryInfoGetter::GetRegionCountryId(m2::PointD const & pt) const
return id != kInvalidId ? m_countries[id].m_countryId : kInvalidCountryId;
}
+vector<TCountryId> CountryInfoGetter::GetRegionsCountryIdByRect(m2::RectD const & rect) const
+{
+ size_t constexpr kAverageSize = 10;
+
+ vector<TCountryId> result;
+ result.reserve(kAverageSize);
+ for (size_t id = 0; id < m_countries.size(); ++id)
+ {
+ if (rect.IsRectInside(m_countries[id].m_rect) ||
+ (rect.IsIntersect(m_countries[id].m_rect) && IsIntersectedByRegionImpl(id, rect)))
+ {
+ result.push_back(m_countries[id].m_countryId);
+ }
+ }
+ return result;
+}
+
void CountryInfoGetter::GetRegionsCountryId(m2::PointD const & pt, TCountriesVec & closestCoutryIds)
{
double const kLookupRadiusM = 30 /* km */ * 1000;
@@ -297,6 +314,35 @@ bool CountryInfoReader::IsBelongToRegionImpl(size_t id, m2::PointD const & pt) c
return WithRegion(id, contains);
}
+bool CountryInfoReader::IsIntersectedByRegionImpl(size_t id, m2::RectD const & rect) const
+{
+ vector<pair<m2::PointD, m2::PointD>> edges =
+ {
+ {rect.LeftTop(), rect.RightTop()},
+ {rect.RightTop(), rect.RightBottom()},
+ {rect.RightBottom(), rect.LeftBottom()},
+ {rect.LeftBottom(), rect.LeftTop()}
+ };
+ auto contains = [&edges](vector<m2::RegionD> const & regions)
+ {
+ for (auto const & region : regions)
+ {
+ for (auto const & edge : edges)
+ {
+ m2::PointD result;
+ if (region.FindIntersection(edge.first, edge.second, result))
+ return true;
+ }
+ }
+ return false;
+ };
+
+ if (WithRegion(id, contains))
+ return true;
+
+ return IsBelongToRegionImpl(id, rect.Center());
+}
+
bool CountryInfoReader::IsCloseEnough(size_t id, m2::PointD const & pt, double distance)
{
m2::RectD const lookupRect = MercatorBounds::RectByCenterXYAndSizeInMeters(pt, distance);
@@ -347,6 +393,12 @@ bool CountryInfoGetterForTesting::IsBelongToRegionImpl(size_t id,
return m_countries[id].m_rect.IsPointInside(pt);
}
+bool CountryInfoGetterForTesting::IsIntersectedByRegionImpl(size_t id, m2::RectD const & rect) const
+{
+ CHECK_LESS(id, m_countries.size(), ());
+ return rect.IsIntersect(m_countries[id].m_rect);
+}
+
bool CountryInfoGetterForTesting::IsCloseEnough(size_t id, m2::PointD const & pt, double distance)
{
CHECK_LESS(id, m_countries.size(), ());
diff --git a/storage/country_info_getter.hpp b/storage/country_info_getter.hpp
index 3acda1a2d8..a4a42818c2 100644
--- a/storage/country_info_getter.hpp
+++ b/storage/country_info_getter.hpp
@@ -36,6 +36,10 @@ public:
// string.
TCountryId GetRegionCountryId(m2::PointD const & pt) const;
+ // Returns vector of countries file names without an extension for
+ // countries belong to |rect|.
+ vector<TCountryId> GetRegionsCountryIdByRect(m2::RectD const & rect) const;
+
// Returns a list of country ids by a |pt| in mercator.
// |closestCoutryIds| is filled with country ids of mwm which covers |pt| or close to it.
// |closestCoutryIds| is not filled with country world.mwm country id and with custom mwm.
@@ -96,6 +100,9 @@ protected:
// Returns true when |pt| belongs to a country identified by |id|.
virtual bool IsBelongToRegionImpl(size_t id, m2::PointD const & pt) const = 0;
+ // Returns true when |rect| intersects a country identified by |id|.
+ virtual bool IsIntersectedByRegionImpl(size_t id, m2::RectD const & rect) const = 0;
+
// Returns true when the distance from |pt| to country identified by |id| less then |distance|.
virtual bool IsCloseEnough(size_t id, m2::PointD const & pt, double distance) = 0;
@@ -144,6 +151,7 @@ protected:
// CountryInfoGetter overrides:
void ClearCachesImpl() const override;
bool IsBelongToRegionImpl(size_t id, m2::PointD const & pt) const override;
+ bool IsIntersectedByRegionImpl(size_t id, m2::RectD const & rect) const override;
bool IsCloseEnough(size_t id, m2::PointD const & pt, double distance) override;
template <typename TFn>
@@ -172,6 +180,7 @@ protected:
// CountryInfoGetter overrides:
void ClearCachesImpl() const override;
bool IsBelongToRegionImpl(size_t id, m2::PointD const & pt) const override;
+ bool IsIntersectedByRegionImpl(size_t id, m2::RectD const & rect) const override;
bool IsCloseEnough(size_t id, m2::PointD const & pt, double distance) override;
};
} // namespace storage
diff --git a/storage/storage_tests/country_info_getter_test.cpp b/storage/storage_tests/country_info_getter_test.cpp
index b093123980..46398cc2d6 100644
--- a/storage/storage_tests/country_info_getter_test.cpp
+++ b/storage/storage_tests/country_info_getter_test.cpp
@@ -7,6 +7,8 @@
#include "storage/storage.hpp"
#include "geometry/mercator.hpp"
+#include "geometry/point2d.hpp"
+#include "geometry/rect2d.hpp"
#include "platform/mwm_version.hpp"
#include "platform/platform.hpp"
@@ -14,6 +16,7 @@
#include "base/logging.hpp"
#include "std/unique_ptr.hpp"
+#include "std/vector.hpp"
using namespace storage;
@@ -45,6 +48,29 @@ UNIT_TEST(CountryInfoGetter_GetByPoint_Smoke)
TEST_EQUAL(info.m_name, "Japan, Kinki", ());
}
+UNIT_TEST(CountryInfoGetter_GetRegionsCountryIdByRect_Smoke)
+{
+ auto const getter = CreateCountryInfoGetter();
+
+ m2::PointD const p = MercatorBounds::FromLatLon(53.9022651, 27.5618818);
+
+ // Inside mwm.
+ m2::PointD const halfSize = m2::PointD(0.1, 0.1);
+ auto countries = getter->GetRegionsCountryIdByRect(m2::RectD(p - halfSize, p + halfSize));
+ TEST_EQUAL(countries, vector<storage::TCountryId> { "Belarus" }, ());
+
+ // Several countries.
+ m2::PointD const halfSize2 = m2::PointD(5.0, 5.0);
+ auto countries2 = getter->GetRegionsCountryIdByRect(m2::RectD(p - halfSize2, p + halfSize2));
+ auto expected = vector<storage::TCountryId> { "Belarus", "Latvia", "Lithuania", "Poland",
+ "Russia_Central", "Russia_Northwestern", "Ukraine" };
+ TEST_EQUAL(countries2, expected, ());
+
+ // No one found.
+ auto countries3 = getter->GetRegionsCountryIdByRect(m2::RectD(-halfSize, halfSize));
+ TEST_EQUAL(countries3, vector<storage::TCountryId>{}, ());
+}
+
UNIT_TEST(CountryInfoGetter_ValidName_Smoke)
{
string buffer;