2016-01-15 02:47:19 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2017-01-21 04:24:28 +00:00
|
|
|
|
#include <vector>
|
|
|
|
|
#include <boost/noncopyable.hpp>
|
|
|
|
|
#include <common/Common.h>
|
2016-01-15 02:47:19 +00:00
|
|
|
|
#include <common/singleton.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define REGION_TYPE_CITY 6
|
|
|
|
|
#define REGION_TYPE_AREA 5
|
|
|
|
|
#define REGION_TYPE_DISTRICT 4
|
|
|
|
|
#define REGION_TYPE_COUNTRY 3
|
|
|
|
|
#define REGION_TYPE_CONTINENT 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Класс, позволяющий узнавать, принадлежит ли регион с одним RegionID региону с другим RegionID.
|
|
|
|
|
* Информацию об иерархии регионов загружает из текстового файла.
|
|
|
|
|
* Умеет, по запросу, обновлять данные.
|
|
|
|
|
*/
|
|
|
|
|
class RegionsHierarchy : private boost::noncopyable
|
|
|
|
|
{
|
|
|
|
|
private:
|
2017-01-21 04:24:28 +00:00
|
|
|
|
time_t file_modification_time = 0;
|
2016-01-15 02:47:19 +00:00
|
|
|
|
|
2016-10-27 17:53:47 +00:00
|
|
|
|
using RegionID = UInt32;
|
|
|
|
|
using RegionType = UInt8;
|
|
|
|
|
using RegionDepth = UInt8;
|
2016-05-28 10:35:44 +00:00
|
|
|
|
using RegionPopulation = UInt32;
|
2016-01-15 02:47:19 +00:00
|
|
|
|
|
|
|
|
|
/// отношение parent; 0, если родителей нет - обычная lookup таблица.
|
2016-05-28 10:35:44 +00:00
|
|
|
|
using RegionParents = std::vector<RegionID>;
|
2016-01-15 02:47:19 +00:00
|
|
|
|
/// тип региона
|
2016-05-28 10:35:44 +00:00
|
|
|
|
using RegionTypes = std::vector<RegionType>;
|
2016-01-15 02:47:19 +00:00
|
|
|
|
/// глубина в дереве, начиная от страны (страна: 1, корень: 0)
|
2016-05-28 10:35:44 +00:00
|
|
|
|
using RegionDepths = std::vector<RegionDepth>;
|
2016-01-15 02:47:19 +00:00
|
|
|
|
/// население региона. Если больше 2^32 - 1, то приравнивается к этому максимуму.
|
2016-05-28 10:35:44 +00:00
|
|
|
|
using RegionPopulations = std::vector<RegionPopulation>;
|
2016-01-15 02:47:19 +00:00
|
|
|
|
|
|
|
|
|
/// регион -> родительский регион
|
|
|
|
|
RegionParents parents;
|
|
|
|
|
/// регион -> город, включающий его или 0, если такого нет
|
|
|
|
|
RegionParents city;
|
|
|
|
|
/// регион -> страна, включающая его или 0, если такого нет
|
|
|
|
|
RegionParents country;
|
|
|
|
|
/// регион -> область, включающая его или 0, если такой нет
|
|
|
|
|
RegionParents area;
|
|
|
|
|
/// регион -> округ, включающий его или 0, если такого нет
|
|
|
|
|
RegionParents district;
|
2016-02-01 20:18:13 +00:00
|
|
|
|
/// регион -> континет (первый при подъёме по иерархии регионов), включающий его или 0, если такого нет
|
2016-01-15 02:47:19 +00:00
|
|
|
|
RegionParents continent;
|
2016-02-01 20:18:13 +00:00
|
|
|
|
/// регион -> континет (последний при подъёме по иерархии регионов), включающий его или 0, если такого нет
|
|
|
|
|
RegionParents top_continent;
|
2016-01-15 02:47:19 +00:00
|
|
|
|
|
|
|
|
|
/// регион -> население или 0, если неизвестно.
|
|
|
|
|
RegionPopulations populations;
|
|
|
|
|
|
|
|
|
|
/// регион - глубина в дереве
|
|
|
|
|
RegionDepths depths;
|
|
|
|
|
|
2017-01-21 04:24:28 +00:00
|
|
|
|
/// path to file with data
|
|
|
|
|
std::string path;
|
2016-01-15 02:47:19 +00:00
|
|
|
|
|
2017-01-21 04:24:28 +00:00
|
|
|
|
public:
|
|
|
|
|
RegionsHierarchy();
|
|
|
|
|
RegionsHierarchy(const std::string & path_);
|
2016-01-15 02:47:19 +00:00
|
|
|
|
|
|
|
|
|
/// Перезагружает, при необходимости, иерархию регионов. Непотокобезопасно.
|
2017-01-21 04:24:28 +00:00
|
|
|
|
void reload();
|
2016-01-15 02:47:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool in(RegionID lhs, RegionID rhs) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (lhs >= parents.size())
|
2016-01-15 02:47:19 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
while (lhs != 0 && lhs != rhs)
|
|
|
|
|
lhs = parents[lhs];
|
|
|
|
|
|
|
|
|
|
return lhs != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegionID toCity(RegionID region) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (region >= city.size())
|
2016-01-15 02:47:19 +00:00
|
|
|
|
return 0;
|
|
|
|
|
return city[region];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegionID toCountry(RegionID region) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (region >= country.size())
|
2016-01-15 02:47:19 +00:00
|
|
|
|
return 0;
|
|
|
|
|
return country[region];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegionID toArea(RegionID region) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (region >= area.size())
|
2016-01-15 02:47:19 +00:00
|
|
|
|
return 0;
|
|
|
|
|
return area[region];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegionID toDistrict(RegionID region) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (region >= district.size())
|
2016-01-15 02:47:19 +00:00
|
|
|
|
return 0;
|
|
|
|
|
return district[region];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegionID toContinent(RegionID region) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (region >= continent.size())
|
2016-01-15 02:47:19 +00:00
|
|
|
|
return 0;
|
|
|
|
|
return continent[region];
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-01 20:18:13 +00:00
|
|
|
|
RegionID toTopContinent(RegionID region) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (region >= top_continent.size())
|
2016-02-01 20:18:13 +00:00
|
|
|
|
return 0;
|
|
|
|
|
return top_continent[region];
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-15 02:47:19 +00:00
|
|
|
|
RegionID toParent(RegionID region) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (region >= parents.size())
|
2016-01-15 02:47:19 +00:00
|
|
|
|
return 0;
|
|
|
|
|
return parents[region];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegionDepth getDepth(RegionID region) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (region >= depths.size())
|
2016-01-15 02:47:19 +00:00
|
|
|
|
return 0;
|
|
|
|
|
return depths[region];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegionPopulation getPopulation(RegionID region) const
|
|
|
|
|
{
|
2016-10-27 17:53:47 +00:00
|
|
|
|
if (region >= populations.size())
|
2016-01-15 02:47:19 +00:00
|
|
|
|
return 0;
|
|
|
|
|
return populations[region];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RegionsHierarchySingleton : public Singleton<RegionsHierarchySingleton>, public RegionsHierarchy
|
|
|
|
|
{
|
|
|
|
|
friend class Singleton<RegionsHierarchySingleton>;
|
|
|
|
|
protected:
|
|
|
|
|
RegionsHierarchySingleton()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|