mirror of
https://codeberg.org/comaps/comaps
synced 2026-01-07 21:13:55 +00:00
committed by
Konstantin Pastbin
parent
c9cbb64f12
commit
76ffc99abd
191
libs/search/reverse_geocoder.hpp
Normal file
191
libs/search/reverse_geocoder.hpp
Normal file
@@ -0,0 +1,191 @@
|
||||
#pragma once
|
||||
|
||||
#include "indexer/house_to_street_iface.hpp"
|
||||
#include "indexer/feature_decl.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);
|
||||
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);
|
||||
|
||||
/// @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
|
||||
Reference in New Issue
Block a user