co-maps/libs/search/reverse_geocoder.hpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

181 lines
6.3 KiB
C++
Raw Permalink Normal View History

2025-11-22 13:58:55 +01:00
#pragma once
#include "indexer/feature_decl.hpp"
#include "indexer/house_to_street_iface.hpp"
#include "storage/storage_defines.hpp"
#include "coding/string_utf8_multilang.hpp"
#include <memory>
#include <optional>
#include <string>
#include <vector>
class FeatureType;
class DataSource;
namespace storage
{
class CountryInfoGetter;
} // namespace storage
namespace search
{
class MwmContext;
class CityFinder;
class RegionInfoGetter;
class ReverseGeocoder
{
DataSource const & m_dataSource;
struct Object
{
FeatureID m_id;
double m_distanceMeters;
std::string m_name;
Object() : m_distanceMeters(-1.0) {}
Object(FeatureID const & id, double dist, std::string_view name) : m_id(id), m_distanceMeters(dist), m_name(name) {}
inline bool IsValid() const { return m_id.IsValid(); }
};
friend std::string DebugPrint(Object const & obj);
public:
/// All "Nearby" functions work in this lookup radius.
static int constexpr kLookupRadiusM = 500;
explicit ReverseGeocoder(DataSource const & dataSource);
struct Street : public Object
{
StringUtf8Multilang m_multilangName;
Street() = default;
Street(FeatureID const & id, double dist, std::string_view name, StringUtf8Multilang const & multilangName)
: Object(id, dist, name)
, m_multilangName(multilangName)
{}
};
using Place = Street;
struct Building : public Object
{
m2::PointD m_center;
// To investigate possible errors.
// There are no houses in (0, 0) coordinates.
Building() : m_center(0, 0) {}
Building(FeatureID const & id, double dist, std::string const & number, m2::PointD const & center)
: Object(id, dist, number)
, m_center(center)
{}
};
struct Address
{
Building m_building;
Street m_street;
std::string const & GetHouseNumber() const { return m_building.m_name; }
std::string const & GetStreetName() const { return m_street.m_name; }
double GetDistance() const { return m_building.m_distanceMeters; }
bool IsValid() const { return m_building.IsValid() && m_street.IsValid(); }
// 7 vulica Frunze
std::string FormatAddress() const;
};
struct RegionAddress
{
// CountryId is set in case when FeatureID is not found or belongs to World.wmw
// and we can't get country name from it.
storage::CountryId m_countryId;
FeatureID m_featureId;
bool IsValid() const;
std::string GetCountryName() const;
bool operator==(RegionAddress const & rhs) const;
bool operator!=(RegionAddress const & rhs) const;
bool operator<(RegionAddress const & rhs) const;
};
friend std::string DebugPrint(Address const & addr);
/// Returns a feature id of street from |streets| whose name best matches |keyName|
/// or empty value if the match was not found.
static std::optional<uint32_t> GetMatchedStreetIndex(std::string_view keyName, std::vector<Street> const & streets);
/// @return Sorted by distance streets vector for the specified MwmId.
/// Parameter |includeSquaresAndSuburbs| needed for backward compatibility:
/// existing mwms operate on streets without squares and suburbs.
static std::vector<Street> GetNearbyStreets(search::MwmContext & context, m2::PointD const & center,
double radiusM = kLookupRadiusM, bool ignoreEditedStatus = false);
std::vector<Street> GetNearbyStreets(MwmSet::MwmId const & id, m2::PointD const & center) const;
std::vector<Street> GetNearbyStreets(FeatureType & ft) const;
static std::vector<Place> GetNearbyPlaces(search::MwmContext & context, m2::PointD const & center, double radiusM, bool ignoreEditedStatus = false);
/// @return feature street name.
/// Returns empty string when there is no street the feature belongs to.
std::string GetFeatureStreetName(FeatureType & ft) const;
/// Same with GetFeatureStreetName but gets street from mwm only (not editor).
std::string GetOriginalFeatureStreetName(FeatureID const & fid) const;
/// For |houseId| with street information sets |streetId| to FeatureID of street corresponding to
/// |houseId| and returns true. Returs false otherwise.
bool GetOriginalStreetByHouse(FeatureType & house, FeatureID & streetId) const;
/// @return The nearest exact address where building has house number and valid street match.
void GetNearbyAddress(m2::PointD const & center, Address & addr) const;
/// @param[in] placeAsStreet Use house->place index same as streets to define address.
/// Looks like it should be always true, but keep a param for now.
/// @{
/// @param[out] addr The nearest exact address where building is at most |maxDistanceM| far from |center|,
/// has house number and valid street (place) match.
void GetNearbyAddress(m2::PointD const & center, double maxDistanceM, Address & addr,
bool placeAsStreet = false) const;
/// @param[out] addr The exact address of a feature.
/// @returns false if can't extruct address or ft have no house number.
bool GetExactAddress(FeatureType & ft, Address & addr, bool placeAsStreet = false) const;
/// @}
bool GetExactAddress(FeatureID const & fid, Address & addr) const;
/// Returns the nearest region address where mwm or exact city is known.
static RegionAddress GetNearbyRegionAddress(m2::PointD const & center, storage::CountryInfoGetter const & infoGetter,
CityFinder & cityFinder);
std::string GetLocalizedRegionAddress(RegionAddress const & addr, RegionInfoGetter const & nameGetter) const;
private:
/// Helper class to incapsulate house 2 street table reloading.
class HouseTable
{
public:
explicit HouseTable(DataSource const & dataSource, bool placeAsStreet = false)
: m_dataSource(dataSource)
, m_placeAsStreet(placeAsStreet)
{}
std::optional<HouseToStreetTable::Result> Get(FeatureID const & fid);
private:
DataSource const & m_dataSource;
MwmSet::MwmHandle m_handle;
bool m_placeAsStreet;
};
/// Ignores changes from editor if |ignoreEdits| is true.
bool GetNearbyAddress(HouseTable & table, Building const & bld, bool ignoreEdits, Address & addr) const;
/// @return Sorted by distance houses vector with valid house number.
void GetNearbyBuildings(m2::PointD const & center, double maxDistanceM, std::vector<Building> & buildings) const;
static Building FromFeature(FeatureType & ft, double distMeters);
};
} // namespace search