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:
authorvng <viktor.govako@gmail.com>2015-12-22 13:57:16 +0300
committerSergey Yershov <yershov@corp.mail.ru>2016-03-23 16:03:16 +0300
commit2fe8fee598e31e2a456b09208b2d53eeb69df0c9 (patch)
tree6354377d1817bbab9e8374238c87996e95574c3d /search/reverse_geocoder.cpp
parent21370ee3d9635139c460addabdf60abb559369c7 (diff)
[search] Get street name and house number from point.
Diffstat (limited to 'search/reverse_geocoder.cpp')
-rw-r--r--search/reverse_geocoder.cpp104
1 files changed, 78 insertions, 26 deletions
diff --git a/search/reverse_geocoder.cpp b/search/reverse_geocoder.cpp
index 7fa17a951f..b01866d2cc 100644
--- a/search/reverse_geocoder.cpp
+++ b/search/reverse_geocoder.cpp
@@ -1,6 +1,8 @@
#include "reverse_geocoder.hpp"
#include "search_string_utils.hpp"
+#include "search/v2/house_to_street_table.hpp"
+
#include "indexer/feature.hpp"
#include "indexer/feature_algo.hpp"
#include "indexer/ftypes_matcher.hpp"
@@ -13,34 +15,27 @@ namespace search
{
namespace
{
-size_t constexpr kMaxStreetIndex = 16;
size_t constexpr kSimilarityThresholdPercent = 10;
-
-/// @todo Need to check projection here?
-double CalculateMinDistance(FeatureType const & ft, m2::PointD const & pt)
-{
- ASSERT_EQUAL(ft.GetFeatureType(), feature::GEOM_LINE, ());
-
- double res = numeric_limits<double>::max();
- ft.ForEachPoint([&] (m2::PointD const & p)
- {
- double const d = MercatorBounds::DistanceOnEarth(p, pt);
- if (d < res)
- res = d;
- }, FeatureType::BEST_GEOMETRY);
-
- return res;
-}
+int const kQueryScale = scales::GetUpperScale();
} // namespace
// static
double const ReverseGeocoder::kLookupRadiusM = 500.0;
+// static
+m2::RectD ReverseGeocoder::GetLookupRect(m2::PointD const & center)
+{
+ return MercatorBounds::RectByCenterXYAndSizeInMeters(center, kLookupRadiusM);
+}
+
void ReverseGeocoder::GetNearbyStreets(FeatureType const & addrFt, vector<Street> & streets)
{
- m2::PointD const & center = feature::GetCenter(addrFt);
- m2::RectD const rect = MercatorBounds::RectByCenterXYAndSizeInMeters(
- center, kLookupRadiusM);
+ GetNearbyStreets(feature::GetCenter(addrFt), streets);
+}
+
+void ReverseGeocoder::GetNearbyStreets(m2::PointD const & center, vector<Street> & streets)
+{
+ m2::RectD const rect = GetLookupRect(center);
auto const addStreet = [&](FeatureType const & ft)
{
@@ -56,25 +51,49 @@ void ReverseGeocoder::GetNearbyStreets(FeatureType const & addrFt, vector<Street
return;
ASSERT(!name.empty(), ());
- streets.push_back({ft.GetID(), CalculateMinDistance(ft, center), name});
+ streets.push_back({ft.GetID(), feature::GetMinDistance(ft, center), name});
};
- m_index.ForEachInRect(addStreet, rect, scales::GetUpperScale());
+ m_index.ForEachInRect(addStreet, rect, kQueryScale);
sort(streets.begin(), streets.end(), my::CompareBy(&Street::m_distanceMeters));
}
+void ReverseGeocoder::GetNearbyBuildings(m2::PointD const & center, vector<Building> & buildings)
+{
+ // Seems like a copy-paste here of the GetNearbyStreets function.
+ // Trying to factor out common logic will cause many variables logic.
+
+ m2::RectD const rect = GetLookupRect(center);
+
+ auto const addBld = [&](FeatureType const & ft)
+ {
+ if (!ftypes::IsBuildingChecker::Instance()(ft))
+ return;
+
+ // Skip empty house nubers.
+ string const number = ft.GetHouseNumber();
+ if (number.empty())
+ return;
+
+ buildings.push_back({ft.GetID(), feature::GetMinDistance(ft, center),
+ number, feature::GetCenter(ft)});
+ };
+
+ m_index.ForEachInRect(addBld, rect, kQueryScale);
+ sort(buildings.begin(), buildings.end(), my::CompareBy(&Building::m_distanceMeters));
+}
+
// static
size_t ReverseGeocoder::GetMatchedStreetIndex(string const & keyName,
vector<Street> const & streets)
{
strings::UniString const expected = strings::MakeUniString(keyName);
- // Do limit possible return values.
- size_t const count = min(streets.size(), kMaxStreetIndex);
-
// Find the exact match or the best match in kSimilarityTresholdPercent limit.
+ size_t const count = streets.size();
size_t result = count;
size_t minPercent = kSimilarityThresholdPercent + 1;
+
for (size_t i = 0; i < count; ++i)
{
string key;
@@ -98,6 +117,39 @@ size_t ReverseGeocoder::GetMatchedStreetIndex(string const & keyName,
}
}
- return (result < count ? result : streets.size());
+ return result;
}
+
+void ReverseGeocoder::GetNearbyAddress(m2::PointD const & center,
+ Building & building, Street & street)
+{
+ vector<Building> buildings;
+ GetNearbyBuildings(center, buildings);
+
+ vector<Street> streets;
+ unique_ptr<search::v2::HouseToStreetTable> table;
+ MwmSet::MwmId mwmId;
+
+ for (auto const & b : buildings)
+ {
+ if (!table || mwmId != b.m_id.m_mwmId)
+ {
+ auto handle = m_index.GetMwmHandleById(b.m_id.m_mwmId);
+ auto value = handle.GetValue<MwmValue>();
+ if (value)
+ table = search::v2::HouseToStreetTable::Load(*value);
+ }
+
+ GetNearbyStreets(b.m_center, streets);
+
+ uint32_t const ind = table->Get(b.m_id.m_index);
+ if (ind < streets.size())
+ {
+ building = b;
+ street = streets[ind];
+ return;
+ }
+ }
+}
+
} // namespace search