forked from organicmaps/organicmaps
[bookmarks] Add address getting routine for input point.
This commit is contained in:
parent
56dd086174
commit
2da592bcb0
6 changed files with 384 additions and 141 deletions
341
map/address_finder.cpp
Normal file
341
map/address_finder.cpp
Normal file
|
@ -0,0 +1,341 @@
|
|||
#include "framework.hpp"
|
||||
|
||||
#include "../indexer/classificator.hpp"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class FeatureInfoT
|
||||
{
|
||||
double m_dist;
|
||||
|
||||
public:
|
||||
FeatureInfoT(double d, feature::TypesHolder & types, string & name, m2::PointD const & pt)
|
||||
: m_dist(d), m_types(types), m_pt(pt)
|
||||
{
|
||||
m_name.swap(name);
|
||||
}
|
||||
|
||||
bool operator<(FeatureInfoT const & rhs) const
|
||||
{
|
||||
return (m_dist < rhs.m_dist);
|
||||
}
|
||||
|
||||
void Swap(FeatureInfoT & rhs)
|
||||
{
|
||||
swap(m_dist, rhs.m_dist);
|
||||
m_name.swap(rhs.m_name);
|
||||
swap(m_types, rhs.m_types);
|
||||
}
|
||||
|
||||
string m_name;
|
||||
feature::TypesHolder m_types;
|
||||
m2::PointD m_pt;
|
||||
};
|
||||
|
||||
void swap(FeatureInfoT & i1, FeatureInfoT & i2)
|
||||
{
|
||||
i1.Swap(i2);
|
||||
}
|
||||
|
||||
class DoGetFeatureInfoBase
|
||||
{
|
||||
protected:
|
||||
virtual double GetCompareEpsilon(feature::EGeomType type) const = 0;
|
||||
virtual double NeedProcess(feature::TypesHolder const & types) const = 0;
|
||||
|
||||
static double GetCompareEpsilonImpl(feature::EGeomType type, double eps)
|
||||
{
|
||||
using namespace feature;
|
||||
switch (type)
|
||||
{
|
||||
case GEOM_POINT: return 0.0 * eps;
|
||||
case GEOM_LINE: return 1.0 * eps;
|
||||
case GEOM_AREA: return 2.0 * eps;
|
||||
default:
|
||||
ASSERT ( false, () );
|
||||
return numeric_limits<double>::max();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
DoGetFeatureInfoBase(m2::PointD const & pt, double eps, int scale)
|
||||
: m_pt(pt), m_eps(eps), m_scale(scale)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (FeatureType const & f)
|
||||
{
|
||||
feature::TypesHolder types(f);
|
||||
if (NeedProcess(types))
|
||||
{
|
||||
double const d = f.GetDistance(m_pt, m_scale);
|
||||
ASSERT_GREATER_OR_EQUAL(d, 0.0, ());
|
||||
|
||||
if (d <= m_eps)
|
||||
{
|
||||
string defName, intName;
|
||||
f.GetPreferredDrawableNames(defName, intName);
|
||||
|
||||
feature::EGeomType const geomType = types.GetGeoType();
|
||||
m2::PointD const pt = (geomType == feature::GEOM_POINT) ? f.GetCenter() : m2::PointD();
|
||||
|
||||
m_cont.push_back(FeatureInfoT(d + GetCompareEpsilon(geomType), types, defName, pt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SortResults()
|
||||
{
|
||||
sort(m_cont.begin(), m_cont.end());
|
||||
}
|
||||
|
||||
protected:
|
||||
m2::PointD m_pt;
|
||||
double m_eps;
|
||||
int m_scale;
|
||||
|
||||
vector<FeatureInfoT> m_cont;
|
||||
};
|
||||
|
||||
class DoGetFeatureTypes : public DoGetFeatureInfoBase
|
||||
{
|
||||
protected:
|
||||
virtual double GetCompareEpsilon(feature::EGeomType type) const
|
||||
{
|
||||
return GetCompareEpsilonImpl(type, m_eps);
|
||||
}
|
||||
virtual double NeedProcess(feature::TypesHolder const &) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
DoGetFeatureTypes(m2::PointD const & pt, double eps, int scale)
|
||||
: DoGetFeatureInfoBase(pt, eps, scale)
|
||||
{
|
||||
}
|
||||
|
||||
void GetFeatureTypes(size_t count, vector<string> & types)
|
||||
{
|
||||
SortResults();
|
||||
|
||||
Classificator const & c = classif();
|
||||
|
||||
for (size_t i = 0; i < min(count, m_cont.size()); ++i)
|
||||
for (size_t j = 0; j < m_cont[i].m_types.Size(); ++j)
|
||||
types.push_back(c.GetFullObjectName(m_cont[i].m_types[j]));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void Framework::GetFeatureTypes(m2::PointD pt, vector<string> & types) const
|
||||
{
|
||||
pt = m_navigator.ShiftPoint(pt);
|
||||
|
||||
int const sm = 20;
|
||||
m2::RectD pixR(m2::PointD(pt.x - sm, pt.y - sm), m2::PointD(pt.x + sm, pt.y + sm));
|
||||
|
||||
m2::RectD glbR;
|
||||
m_navigator.Screen().PtoG(pixR, glbR);
|
||||
|
||||
int const scale = GetDrawScale();
|
||||
DoGetFeatureTypes getTypes(m_navigator.Screen().PtoG(pt),
|
||||
max(glbR.SizeX(), glbR.SizeY()) / 2.0,
|
||||
scale);
|
||||
|
||||
m_model.ForEachFeature(glbR, getTypes, scale);
|
||||
|
||||
getTypes.GetFeatureTypes(5, types);
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class DoGetAddressInfo : public DoGetFeatureInfoBase
|
||||
{
|
||||
public:
|
||||
class TypeChecker
|
||||
{
|
||||
vector<uint32_t> m_localities, m_streets, m_buildings;
|
||||
|
||||
template <size_t count, size_t ind>
|
||||
void FillMatch(char const * (& arr)[count][ind], vector<uint32_t> & vec)
|
||||
{
|
||||
STATIC_ASSERT ( count > 0 );
|
||||
STATIC_ASSERT ( ind > 0 );
|
||||
|
||||
Classificator const & c = classif();
|
||||
|
||||
vec.reserve(count);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
vector<string> v(arr[i], arr[i] + ind);
|
||||
vec.push_back(c.GetTypeByPath(v));
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsMatchImpl(vector<uint32_t> const & vec, feature::TypesHolder const & types)
|
||||
{
|
||||
for (size_t i = 0; i < types.Size(); ++i)
|
||||
{
|
||||
uint32_t type = types[i];
|
||||
ftype::TruncValue(type, 2);
|
||||
|
||||
if (find(vec.begin(), vec.end(), type) != vec.end())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
TypeChecker()
|
||||
{
|
||||
char const * arrLocalities[][2] = {
|
||||
{ "place", "city" },
|
||||
{ "place", "town" },
|
||||
{ "place", "village" }
|
||||
//{ "place", "hamlet" }
|
||||
};
|
||||
|
||||
char const * arrStreet[][2] = {
|
||||
{ "highway", "primary" },
|
||||
{ "highway", "secondary" },
|
||||
{ "highway", "residential" },
|
||||
{ "highway", "tertiary" },
|
||||
{ "highway", "living_street" },
|
||||
{ "highway", "service" }
|
||||
};
|
||||
|
||||
char const * arrBuilding[][1] = {
|
||||
{ "building" }
|
||||
};
|
||||
|
||||
FillMatch(arrLocalities, m_localities);
|
||||
FillMatch(arrStreet, m_streets);
|
||||
FillMatch(arrBuilding, m_buildings);
|
||||
}
|
||||
|
||||
bool IsLocality(feature::TypesHolder const & types) const
|
||||
{
|
||||
return IsMatchImpl(m_localities, types);
|
||||
}
|
||||
bool IsStreet(feature::TypesHolder const & types) const
|
||||
{
|
||||
return IsMatchImpl(m_streets, types);
|
||||
}
|
||||
bool IsBuilding(feature::TypesHolder const & types) const
|
||||
{
|
||||
return IsMatchImpl(m_buildings, types);
|
||||
}
|
||||
};
|
||||
|
||||
TypeChecker const & m_checker;
|
||||
bool m_doLocalities;
|
||||
|
||||
protected:
|
||||
virtual double GetCompareEpsilon(feature::EGeomType type) const
|
||||
{
|
||||
return GetCompareEpsilonImpl(type, 5.0 * MercatorBounds::degreeInMetres);
|
||||
}
|
||||
virtual double NeedProcess(feature::TypesHolder const & types) const
|
||||
{
|
||||
return (!m_doLocalities ||
|
||||
(types.GetGeoType() == feature::GEOM_POINT && m_checker.IsLocality(types)));
|
||||
}
|
||||
|
||||
public:
|
||||
DoGetAddressInfo(m2::PointD const & pt, double eps, int scale,
|
||||
TypeChecker const & checker)
|
||||
: DoGetFeatureInfoBase(pt, eps, scale),
|
||||
m_checker(checker), m_doLocalities(false)
|
||||
{
|
||||
}
|
||||
|
||||
void PrepareForLocalities()
|
||||
{
|
||||
m_doLocalities = true;
|
||||
m_cont.clear();
|
||||
}
|
||||
|
||||
void FillAddress(Framework::AddressInfo & info)
|
||||
{
|
||||
SortResults();
|
||||
|
||||
for (size_t i = 0; i < m_cont.size(); ++i)
|
||||
{
|
||||
bool const isStreet = m_checker.IsStreet(m_cont[i].m_types);
|
||||
//bool const isBuilding = m_checker.IsBuilding(m_cont[i].m_types);
|
||||
|
||||
if (info.m_street.empty() && isStreet)
|
||||
info.m_street = m_cont[i].m_name;
|
||||
|
||||
//if (info.m_house.empty() && isBuilding)
|
||||
// info.m_house = m_cont[i].m_house;
|
||||
|
||||
if (info.m_name.empty())
|
||||
{
|
||||
if (m_cont[i].m_types.GetGeoType() != feature::GEOM_LINE)
|
||||
info.m_name = m_cont[i].m_name;
|
||||
}
|
||||
|
||||
if (!(info.m_street.empty() || info.m_name.empty()))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FillLocality(Framework::AddressInfo & info, Framework const & fm)
|
||||
{
|
||||
SortResults();
|
||||
|
||||
for (size_t i = 0; i < m_cont.size(); ++i)
|
||||
{
|
||||
if (!m_cont[i].m_name.empty() && fm.GetCountryName(m_cont[i].m_pt) == info.m_country)
|
||||
{
|
||||
info.m_city = m_cont[i].m_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void Framework::GetAddressInfo(m2::PointD pt, AddressInfo & info) const
|
||||
{
|
||||
pt = m_navigator.Screen().PtoG(m_navigator.ShiftPoint(pt));
|
||||
|
||||
info.m_country = GetCountryName(pt);
|
||||
if (info.m_country.empty())
|
||||
{
|
||||
LOG(LINFO, ("Can't find region for point ", pt));
|
||||
return;
|
||||
}
|
||||
|
||||
int const scale = scales::GetUpperScale();
|
||||
double const addressR = 200.0;
|
||||
double const localityR = 20000;
|
||||
|
||||
static DoGetAddressInfo::TypeChecker checker;
|
||||
|
||||
// first of all - get an address
|
||||
{
|
||||
DoGetAddressInfo getAddress(pt, addressR, scale, checker);
|
||||
|
||||
m_model.ForEachFeature(
|
||||
MercatorBounds::RectByCenterXYAndSizeInMeters(pt, addressR), getAddress, scale);
|
||||
|
||||
getAddress.FillAddress(info);
|
||||
}
|
||||
|
||||
// now - get the locality
|
||||
{
|
||||
DoGetAddressInfo getLocality(pt, localityR, scale, checker);
|
||||
getLocality.PrepareForLocalities();
|
||||
|
||||
m_model.ForEachFeature(
|
||||
MercatorBounds::RectByCenterXYAndSizeInMeters(pt, localityR), getLocality, scale);
|
||||
|
||||
getLocality.FillLocality(info, *this);
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@
|
|||
#include "../indexer/categories_holder.hpp"
|
||||
#include "../indexer/feature.hpp"
|
||||
#include "../indexer/scales.hpp"
|
||||
#include "../indexer/classificator.hpp"
|
||||
|
||||
#include "../coding/parse_xml.hpp" // LoadFromKML
|
||||
|
||||
|
@ -395,24 +394,8 @@ void Framework::SetNeedRedraw(bool flag)
|
|||
|
||||
void Framework::Invalidate(bool doForceUpdate)
|
||||
{
|
||||
if (m_renderPolicy)
|
||||
{
|
||||
m_renderPolicy->SetForceUpdate(doForceUpdate);
|
||||
m_renderPolicy->GetWindowHandle()->invalidate();
|
||||
m_renderPolicy->SetInvalidRect(m2::AnyRectD(m2::RectD(MercatorBounds::minX,
|
||||
MercatorBounds::minY,
|
||||
MercatorBounds::maxX,
|
||||
MercatorBounds::maxY)));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hasPendingInvalidate = true;
|
||||
m_doForceUpdate = doForceUpdate;
|
||||
m_invalidRect = m2::AnyRectD(m2::RectD(MercatorBounds::minX,
|
||||
MercatorBounds::minY,
|
||||
MercatorBounds::maxX,
|
||||
MercatorBounds::maxY));
|
||||
}
|
||||
InvalidateRect(m2::RectD(MercatorBounds::minX, MercatorBounds::minY,
|
||||
MercatorBounds::maxX, MercatorBounds::maxY), doForceUpdate);
|
||||
}
|
||||
|
||||
void Framework::InvalidateRect(m2::RectD const & rect, bool doForceUpdate)
|
||||
|
@ -481,7 +464,8 @@ int Framework::GetDrawScale() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*double Framework::GetCurrentScale() const
|
||||
/*
|
||||
double Framework::GetCurrentScale() const
|
||||
{
|
||||
m2::PointD textureCenter(m_navigator.Screen().PixelRect().Center());
|
||||
m2::RectD glbRect;
|
||||
|
@ -491,7 +475,8 @@ int Framework::GetDrawScale() const
|
|||
textureCenter + m2::PointD(scaleEtalonSize / 2, scaleEtalonSize / 2)),
|
||||
glbRect);
|
||||
return scales::GetScaleLevelD(glbRect);
|
||||
}*/
|
||||
}
|
||||
*/
|
||||
|
||||
RenderPolicy::TRenderFn Framework::DrawModelFn()
|
||||
{
|
||||
|
@ -620,7 +605,7 @@ void Framework::SetViewportCenter(m2::PointD const & pt)
|
|||
|
||||
static int const theMetersFactor = 6;
|
||||
|
||||
void Framework::CheckMinGlobalRect(m2::RectD & rect)
|
||||
void Framework::CheckMinGlobalRect(m2::RectD & rect) const
|
||||
{
|
||||
m2::RectD const minRect = MercatorBounds::RectByCenterXYAndSizeInMeters(
|
||||
rect.Center(), theMetersFactor * m_metresMinWidth);
|
||||
|
@ -754,7 +739,7 @@ void Framework::StopDrag(DragEvent const & e)
|
|||
{
|
||||
m2::PointD const pt = m_navigator.ShiftPoint(e.Pos());
|
||||
|
||||
m_navigator.StopDrag(pt, 0./*m_timer.ElapsedSeconds()*/, true);
|
||||
m_navigator.StopDrag(pt, ElapsedSeconds(), true);
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
|
||||
|
@ -900,7 +885,7 @@ void Framework::StopScale(ScaleEvent const & e)
|
|||
// LOG(LINFO, ("StopScale", e.Pt1(), e.Pt2()));
|
||||
}
|
||||
|
||||
search::Engine * Framework::GetSearchEngine()
|
||||
search::Engine * Framework::GetSearchEngine() const
|
||||
{
|
||||
// Classical "double check" synchronization pattern.
|
||||
if (!m_pSearchEngine)
|
||||
|
@ -921,6 +906,11 @@ search::Engine * Framework::GetSearchEngine()
|
|||
return m_pSearchEngine.get();
|
||||
}
|
||||
|
||||
string Framework::GetCountryName(m2::PointD const & pt) const
|
||||
{
|
||||
return GetSearchEngine()->GetCountryName(pt);
|
||||
}
|
||||
|
||||
void Framework::PrepareSearch(bool hasPt, double lat, double lon)
|
||||
{
|
||||
GetSearchEngine()->PrepareSearch(GetCurrentViewport(), hasPt, lat, lon);
|
||||
|
@ -931,7 +921,7 @@ void Framework::Search(search::SearchParams const & params)
|
|||
GetSearchEngine()->Search(params, GetCurrentViewport());
|
||||
}
|
||||
|
||||
bool Framework::GetCurrentPosition(double & lat, double & lon)
|
||||
bool Framework::GetCurrentPosition(double & lat, double & lon) const
|
||||
{
|
||||
if (m_locationState.IsValidPosition())
|
||||
{
|
||||
|
@ -1035,116 +1025,7 @@ void Framework::DeleteOldMaps()
|
|||
m_lowestMapVersion = MAXIMUM_VERSION_TO_DELETE + 1;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class DoGetFeatureTypes
|
||||
{
|
||||
typedef vector<string> TypesC;
|
||||
|
||||
class DistanceT
|
||||
{
|
||||
double m_dist;
|
||||
|
||||
public:
|
||||
DistanceT(double d, TypesC & types) : m_dist(d)
|
||||
{
|
||||
m_types.swap(types);
|
||||
}
|
||||
|
||||
bool operator<(DistanceT const & rhs) const
|
||||
{
|
||||
return (m_dist < rhs.m_dist);
|
||||
}
|
||||
|
||||
TypesC m_types;
|
||||
};
|
||||
|
||||
class DoParseTypes
|
||||
{
|
||||
Classificator const & m_c;
|
||||
|
||||
public:
|
||||
DoParseTypes() : m_c(classif()) {}
|
||||
|
||||
void operator() (uint32_t t)
|
||||
{
|
||||
m_types.push_back(m_c.GetFullObjectName(t));
|
||||
}
|
||||
|
||||
TypesC m_types;
|
||||
};
|
||||
|
||||
double GetCompareEpsilon(feature::EGeomType type) const
|
||||
{
|
||||
using namespace feature;
|
||||
switch (type)
|
||||
{
|
||||
case GEOM_POINT: return 0.0 * m_eps;
|
||||
case GEOM_LINE: return 1.0 * m_eps;
|
||||
case GEOM_AREA: return 2.0 * m_eps;
|
||||
default:
|
||||
ASSERT ( false, () );
|
||||
return numeric_limits<double>::max();
|
||||
}
|
||||
}
|
||||
|
||||
m2::PointD m_pt;
|
||||
double m_eps;
|
||||
int m_scale;
|
||||
|
||||
vector<DistanceT> m_cont;
|
||||
|
||||
public:
|
||||
DoGetFeatureTypes(m2::PointD const & pt, double eps, int scale)
|
||||
: m_pt(pt), m_eps(eps), m_scale(scale)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (FeatureType const & f)
|
||||
{
|
||||
double const d = f.GetDistance(m_pt, m_scale);
|
||||
ASSERT_GREATER_OR_EQUAL(d, 0.0, ());
|
||||
|
||||
if (d <= m_eps)
|
||||
{
|
||||
DoParseTypes doParse;
|
||||
f.ForEachTypeRef(doParse);
|
||||
|
||||
m_cont.push_back(DistanceT(d + GetCompareEpsilon(f.GetFeatureType()), doParse.m_types));
|
||||
}
|
||||
}
|
||||
|
||||
void GetFeatureTypes(size_t count, TypesC & types)
|
||||
{
|
||||
sort(m_cont.begin(), m_cont.end());
|
||||
|
||||
for (size_t i = 0; i < min(count, m_cont.size()); ++i)
|
||||
types.insert(types.end(), m_cont[i].m_types.begin(), m_cont[i].m_types.end());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void Framework::GetFeatureTypes(m2::PointD pt, vector<string> & types) const
|
||||
{
|
||||
pt = m_navigator.ShiftPoint(pt);
|
||||
|
||||
int const sm = 20;
|
||||
m2::RectD pixR(m2::PointD(pt.x - sm, pt.y - sm), m2::PointD(pt.x + sm, pt.y + sm));
|
||||
|
||||
m2::RectD glbR;
|
||||
m_navigator.Screen().PtoG(pixR, glbR);
|
||||
|
||||
int const scale = GetDrawScale();
|
||||
DoGetFeatureTypes getTypes(m_navigator.Screen().PtoG(pt),
|
||||
max(glbR.SizeX() / 2.0, glbR.SizeY() / 2.0),
|
||||
scale);
|
||||
|
||||
m_model.ForEachFeature(glbR, getTypes, scale);
|
||||
|
||||
getTypes.GetFeatureTypes(5, types);
|
||||
}
|
||||
|
||||
string Framework::GetCountryCodeByPosition(double lat, double lon)
|
||||
string Framework::GetCountryCodeByPosition(double lat, double lon) const
|
||||
{
|
||||
return GetSearchEngine()->GetCountryCode(m2::PointD(
|
||||
MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat)));
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace search { class Result; }
|
|||
class Framework
|
||||
{
|
||||
protected:
|
||||
scoped_ptr<search::Engine> m_pSearchEngine;
|
||||
mutable scoped_ptr<search::Engine> m_pSearchEngine;
|
||||
model::FeaturesFetcher m_model;
|
||||
Navigator m_navigator;
|
||||
|
||||
|
@ -158,18 +158,20 @@ public:
|
|||
|
||||
private:
|
||||
inline m2::RectD GetCurrentViewport() const { return m_navigator.Screen().ClipRect(); }
|
||||
search::Engine * GetSearchEngine();
|
||||
search::Engine * GetSearchEngine() const;
|
||||
|
||||
void CheckMinGlobalRect(m2::RectD & r);
|
||||
void CheckMinGlobalRect(m2::RectD & r) const;
|
||||
|
||||
public:
|
||||
void PrepareSearch(bool hasPt, double lat = 0.0, double lon = 0.0);
|
||||
void Search(search::SearchParams const & params);
|
||||
bool GetCurrentPosition(double & lat, double & lon);
|
||||
bool GetCurrentPosition(double & lat, double & lon) const;
|
||||
void ShowSearchResult(search::Result const & res);
|
||||
|
||||
string GetCountryName(m2::PointD const & pt) const;
|
||||
|
||||
/// @return country code in ISO 3166-1 alpha-2 format (two small letters) or empty string
|
||||
string GetCountryCodeByPosition(double lat, double lon);
|
||||
string GetCountryCodeByPosition(double lat, double lon) const;
|
||||
|
||||
void SetMaxWorldRect();
|
||||
|
||||
|
@ -199,8 +201,18 @@ public:
|
|||
Invalidate(true);
|
||||
}
|
||||
|
||||
/// @name
|
||||
/// @param[in] pt Current touch point in device pixel coordinates.
|
||||
//@{
|
||||
void GetFeatureTypes(m2::PointD pt, vector<string> & types) const;
|
||||
|
||||
struct AddressInfo
|
||||
{
|
||||
string m_country, m_city, m_street, m_house, m_name;
|
||||
};
|
||||
void GetAddressInfo(m2::PointD pt, AddressInfo & info) const;
|
||||
//@}
|
||||
|
||||
virtual void BeginPaint(shared_ptr<PaintEvent> const & e);
|
||||
/// Function for calling from platform dependent-paint function.
|
||||
virtual void DoPaint(shared_ptr<PaintEvent> const & e);
|
||||
|
|
|
@ -84,7 +84,8 @@ SOURCES += \
|
|||
queued_renderer.cpp \
|
||||
events.cpp \
|
||||
basic_tiling_render_policy.cpp \
|
||||
render_policy_mt.cpp
|
||||
render_policy_mt.cpp \
|
||||
address_finder.cpp
|
||||
|
||||
!iphone*:!bada*:!android* {
|
||||
HEADERS += qgl_render_context.hpp
|
||||
|
|
|
@ -277,4 +277,11 @@ string Engine::GetCountryCode(m2::PointD const & pt) const
|
|||
return info.m_flag;
|
||||
}
|
||||
|
||||
string Engine::GetCountryName(m2::PointD const & pt) const
|
||||
{
|
||||
storage::CountryInfo info;
|
||||
m_pData->m_infoGetter.GetRegionInfo(pt, info);
|
||||
return info.m_name;
|
||||
}
|
||||
|
||||
} // namespace search
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
|
||||
string GetCountryFile(m2::PointD const & pt) const;
|
||||
string GetCountryCode(m2::PointD const & pt) const;
|
||||
string GetCountryName(m2::PointD const & pt) const;
|
||||
|
||||
private:
|
||||
static const int RESULTS_COUNT = 15;
|
||||
|
|
Loading…
Add table
Reference in a new issue