#pragma once #include #include #include #include "GeodataProviders/IHierarchiesProvider.h" class IRegionsHierarchyDataProvider; /** A class that lets you know if a region belongs to one RegionID region with another RegionID. * Information about the hierarchy of regions is downloaded from a text file. * Can on request update the data. */ class RegionsHierarchy : private boost::noncopyable { private: /// Relationship parent; 0, if there are no parents, the usual lookup table. using RegionParents = std::vector; /// type of region using RegionTypes = std::vector; /// depth in the tree, starting from the country (country: 1, root: 0) using RegionDepths = std::vector; /// population of the region. If more than 2 ^ 32 - 1, then it is equated to this maximum. using RegionPopulations = std::vector; /// region -> parent region RegionParents parents; /// region -> city, including it or 0, if there is none RegionParents city; /// region -> country including it or 0, if there is none RegionParents country; /// region -> area that includes it or 0, if not RegionParents area; /// region -> district, including it or 0, if there is none RegionParents district; /// region -> the continent (the first when climbing in the hierarchy of regions), including it or 0, if there is none RegionParents continent; /// region -> the continent (the latter when you climb the hierarchy of regions), including it or 0, if there is none RegionParents top_continent; /// region -> population or 0, if unknown. RegionPopulations populations; /// region - depth in the tree RegionDepths depths; IRegionsHierarchyDataSourcePtr data_source; public: RegionsHierarchy(IRegionsHierarchyDataSourcePtr data_source_); /// Reloads, if necessary, the hierarchy of regions. Not threadsafe. void reload(); bool in(RegionID lhs, RegionID rhs) const { if (lhs >= parents.size()) return false; while (lhs != 0 && lhs != rhs) lhs = parents[lhs]; return lhs != 0; } RegionID toCity(RegionID region) const { if (region >= city.size()) return 0; return city[region]; } RegionID toCountry(RegionID region) const { if (region >= country.size()) return 0; return country[region]; } RegionID toArea(RegionID region) const { if (region >= area.size()) return 0; return area[region]; } RegionID toDistrict(RegionID region) const { if (region >= district.size()) return 0; return district[region]; } RegionID toContinent(RegionID region) const { if (region >= continent.size()) return 0; return continent[region]; } RegionID toTopContinent(RegionID region) const { if (region >= top_continent.size()) return 0; return top_continent[region]; } RegionID toParent(RegionID region) const { if (region >= parents.size()) return 0; return parents[region]; } RegionDepth getDepth(RegionID region) const { if (region >= depths.size()) return 0; return depths[region]; } RegionPopulation getPopulation(RegionID region) const { if (region >= populations.size()) return 0; return populations[region]; } };