Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Zverev <zverik@textual.ru>2016-07-15 18:01:19 +0300
committerIlya Zverev <zverik@textual.ru>2016-07-19 12:53:21 +0300
commit46a5d58ba1fe3b274df149214fe1bbc7bb97b6e1 (patch)
tree3d9baa51399d40e78102e3e1c7a6add4573c0059
parent989c84e7bb93994a02ba482e83e8ec3a90ff91fa (diff)
[generator] Add region info section to mwms
-rw-r--r--3party/jansson/myjansson.cpp28
-rw-r--r--3party/jansson/myjansson.hpp2
-rw-r--r--defines.hpp3
-rw-r--r--generator/feature_sorter.cpp51
-rw-r--r--generator/generator.pro5
-rw-r--r--generator/region_meta.cpp123
-rw-r--r--generator/region_meta.hpp10
-rw-r--r--generator/search_index_builder.cpp2
-rw-r--r--indexer/data_factory.cpp11
-rw-r--r--indexer/data_factory.hpp4
-rw-r--r--indexer/feature_meta.cpp44
-rw-r--r--indexer/feature_meta.hpp39
-rw-r--r--indexer/index.cpp3
-rw-r--r--indexer/index.hpp1
-rw-r--r--indexer/indexer_tests/feature_metadata_test.cpp23
-rw-r--r--indexer/mwm_set.hpp6
-rwxr-xr-xtools/python/mwm/dump_mwm.py1
-rw-r--r--tools/python/mwm/mwm.py17
18 files changed, 319 insertions, 54 deletions
diff --git a/3party/jansson/myjansson.cpp b/3party/jansson/myjansson.cpp
index f1de73f435..5481a93ceb 100644
--- a/3party/jansson/myjansson.cpp
+++ b/3party/jansson/myjansson.cpp
@@ -81,4 +81,32 @@ void FromJSONObjectOptionalField(json_t * root, string const & field, json_int_t
MYTHROW(my::Json::Exception, ("The field", field, "must contain a json number."));
result = json_integer_value(val);
}
+
+void FromJSONObjectOptionalField(json_t * root, string const & field, bool & result, bool def)
+{
+ if (!json_is_object(root))
+ MYTHROW(my::Json::Exception, ("Bad json object when parsing", field));
+ json_t * val = json_object_get(root, field.c_str());
+ if (!val)
+ {
+ result = def;
+ return;
+ }
+ if (!json_is_boolean(val))
+ MYTHROW(my::Json::Exception, ("The field", field, "must contain a boolean value."));
+ result = json_is_true(val);
+}
+
+void FromJSONObjectOptionalField(json_t * root, string const & field, json_t *& result)
+{
+ json_t * obj = json_object_get(root, field.c_str());
+ if (!obj)
+ {
+ result = nullptr;
+ return;
+ }
+ if (!json_is_object(obj))
+ MYTHROW(my::Json::Exception, ("The field", field, "must contain a json object."));
+ FromJSON(obj, result);
+}
} // namespace my
diff --git a/3party/jansson/myjansson.hpp b/3party/jansson/myjansson.hpp
index 9734a06b1f..634996c365 100644
--- a/3party/jansson/myjansson.hpp
+++ b/3party/jansson/myjansson.hpp
@@ -52,6 +52,8 @@ void FromJSONObject(json_t * root, string const & field, vector<T> & result)
void FromJSONObjectOptionalField(json_t * root, string const & field, string & result);
void FromJSONObjectOptionalField(json_t * root, string const & field, json_int_t & result);
+void FromJSONObjectOptionalField(json_t * root, string const & field, bool & result, bool def = false);
+void FromJSONObjectOptionalField(json_t * root, string const & field, json_t *& result);
template <typename T>
void FromJSONObjectOptionalField(json_t * root, string const & field, vector<T> & result)
diff --git a/defines.hpp b/defines.hpp
index 3f25caee41..328e73a938 100644
--- a/defines.hpp
+++ b/defines.hpp
@@ -27,7 +27,7 @@
#define METADATA_INDEX_FILE_TAG "metaidx"
#define FEATURE_OFFSETS_FILE_TAG "offs"
#define RANKS_FILE_TAG "ranks"
-#define REGION_INFO_FILE_TAG "info"
+#define REGION_INFO_FILE_TAG "rgninfo"
// Temporary addresses section that is used in search index generation.
#define SEARCH_TOKENS_FILE_TAG "addrtags"
@@ -52,6 +52,7 @@
#define CELL2FEATURE_TMP_EXT ".c2f.tmp"
#define COUNTRIES_FILE "countries.txt"
+#define COUNTRIES_META_FILE "countries_meta.txt"
#define COUNTRIES_OBSOLETE_FILE "countries_obsolete.txt"
#define WORLD_FILE_NAME "World"
diff --git a/generator/feature_sorter.cpp b/generator/feature_sorter.cpp
index cec1e45307..3e373d900c 100644
--- a/generator/feature_sorter.cpp
+++ b/generator/feature_sorter.cpp
@@ -1,8 +1,9 @@
#include "generator/feature_sorter.hpp"
-#include "generator/feature_generator.hpp"
#include "generator/feature_builder.hpp"
-#include "generator/tesselator.hpp"
+#include "generator/feature_generator.hpp"
#include "generator/gen_mwm_info.hpp"
+#include "generator/region_meta.hpp"
+#include "generator/tesselator.hpp"
#include "defines.hpp"
@@ -111,14 +112,16 @@ namespace feature
vector<pair<uint32_t, uint32_t>> m_metadataIndex;
DataHeader m_header;
+ RegionData m_regionData;
uint32_t m_versionDate;
gen::OsmID2FeatureID m_osm2ft;
public:
- FeaturesCollector2(string const & fName, DataHeader const & header, uint32_t versionDate)
+ FeaturesCollector2(string const & fName, DataHeader const & header,
+ RegionData const & regionData, uint32_t versionDate)
: FeaturesCollector(fName + DATA_FILE_TAG), m_writer(fName),
- m_header(header), m_versionDate(versionDate)
+ m_header(header), m_regionData(regionData), m_versionDate(versionDate)
{
for (size_t i = 0; i < m_header.GetScalesCount(); ++i)
{
@@ -147,6 +150,12 @@ namespace feature
m_header.Save(w);
}
+ // write region info
+ {
+ FileWriter w = m_writer.GetWriter(REGION_INFO_FILE_TAG);
+ m_regionData.Serialize(w);
+ }
+
// assume like we close files
Flush();
@@ -543,22 +552,6 @@ namespace feature
return static_cast<FeatureBuilder2 &>(fb);
}
- class DoStoreLanguages
- {
- DataHeader & m_header;
- public:
- DoStoreLanguages(DataHeader & header) : m_header(header) {}
- void operator() (string const & s)
- {
- int8_t const i = StringUtf8Multilang::GetLangIndex(s);
- if (i > 0)
- {
- // 0 index is always 'default'
- m_header.AddLanguage(i);
- }
- }
- };
-
bool GenerateFinalFeatures(feature::GenerateInfo const & info, string const & name, int mapType)
{
string const srcFilePath = info.GetTmpFileName(name);
@@ -596,23 +589,15 @@ namespace feature
// type
header.SetType(static_cast<DataHeader::MapType>(mapType));
- // languages
- try
- {
- FileReader reader(info.m_targetDir + "metainfo/" + name + ".meta");
- string buffer;
- reader.ReadAsString(buffer);
- strings::Tokenize(buffer, "|", DoStoreLanguages(header));
- }
- catch (Reader::Exception const &)
- {
- LOG(LWARNING, ("No language file for country:", name));
- }
+ // region data
+ RegionData regionData;
+ if (!ReadRegionData(name, regionData))
+ LOG(LWARNING, ("No extra data for country:", name));
// Transform features from raw format to optimized format.
try
{
- FeaturesCollector2 collector(datFilePath, header, info.m_versionDate);
+ FeaturesCollector2 collector(datFilePath, header, regionData, info.m_versionDate);
for (size_t i = 0; i < midPoints.m_vec.size(); ++i)
{
diff --git a/generator/generator.pro b/generator/generator.pro
index e7b4df410f..3ac4cdfacd 100644
--- a/generator/generator.pro
+++ b/generator/generator.pro
@@ -9,7 +9,8 @@ ROOT_DIR = ..
include($$ROOT_DIR/common.pri)
INCLUDEPATH *= $$ROOT_DIR/3party/gflags/src \
- $$ROOT_DIR/3party/osrm/osrm-backend/include
+ $$ROOT_DIR/3party/osrm/osrm-backend/include \
+ $$ROOT_DIR/3party/jansson/src
QT *= core
@@ -30,6 +31,7 @@ SOURCES += \
osm_element.cpp \
osm_id.cpp \
osm_source.cpp \
+ region_meta.cpp \
routing_generator.cpp \
search_index_builder.cpp \
srtm_parser.cpp \
@@ -63,6 +65,7 @@ HEADERS += \
osm_translator.hpp \
osm_xml_source.hpp \
polygonizer.hpp \
+ region_meta.hpp \
routing_generator.hpp \
search_index_builder.hpp \
srtm_parser.hpp \
diff --git a/generator/region_meta.cpp b/generator/region_meta.cpp
new file mode 100644
index 0000000000..963ed65642
--- /dev/null
+++ b/generator/region_meta.cpp
@@ -0,0 +1,123 @@
+#include "region_meta.hpp"
+
+#include "coding/reader.hpp"
+
+#include "platform/platform.hpp"
+
+#include "3party/jansson/myjansson.hpp"
+
+namespace
+{
+int8_t ParseHolidayReference(string const & ref)
+{
+ if (ref == "easter")
+ return feature::RegionData::PHReference::PH_EASTER;
+ if (ref == "orthodox easter")
+ return feature::RegionData::PHReference::PH_ORTHODOX_EASTER;
+ if (ref == "victoriaDay")
+ return feature::RegionData::PHReference::PH_VICTORIA_DAY;
+ if (ref == "canadaDay")
+ return feature::RegionData::PHReference::PH_CANADA_DAY;
+ return 0;
+}
+} // namespace
+
+namespace feature
+{
+bool ReadRegionDataImpl(string const & countryName, RegionData & data)
+{
+ try
+ {
+ auto reader = GetPlatform().GetReader(COUNTRIES_META_FILE);
+ string buffer;
+ reader->ReadAsString(buffer);
+ my::Json root(buffer.data());
+
+ json_t * jsonData = nullptr;
+ my::FromJSONObjectOptionalField(root.get(), countryName, jsonData);
+ if (!jsonData)
+ return false;
+
+ vector<string> languages;
+ my::FromJSONObjectOptionalField(jsonData, "languages", languages);
+ if (!languages.empty())
+ data.SetLanguages(languages);
+
+ string driving;
+ my::FromJSONObjectOptionalField(jsonData, "driving", driving);
+ if (driving == "l" || driving == "r")
+ data.Set(RegionData::Type::RD_DRIVING, driving);
+
+ string timezone;
+ my::FromJSONObjectOptionalField(jsonData, "timezone", timezone);
+ if (!timezone.empty())
+ data.Set(RegionData::Type::RD_TIMEZONE, timezone);
+
+ bool allow_housenames;
+ my::FromJSONObjectOptionalField(jsonData, "housenames", allow_housenames, false);
+ if (allow_housenames)
+ data.Set(RegionData::Type::RD_ALLOW_HOUSENAMES, "y");
+
+ // Public holidays: an array of arrays of [string/number, number].
+ // See https://github.com/opening-hours/opening_hours.js/blob/master/docs/holidays.md
+ vector<json_t *> holidays;
+ my::FromJSONObjectOptionalField(jsonData, "holidays", holidays);
+ for (json_t * holiday : holidays)
+ {
+ if (!json_is_array(holiday) || json_array_size(holiday) != 2)
+ MYTHROW(my::Json::Exception, ("Holiday must be an array of two elements in", countryName));
+ json_t * reference = json_array_get(holiday, 0);
+ int8_t refId = 0;
+ if (json_is_integer(reference))
+ {
+ refId = json_integer_value(reference);
+ }
+ else if (json_is_string(reference))
+ {
+ refId = ParseHolidayReference(string(json_string_value(reference)));
+ }
+ else
+ {
+ MYTHROW(my::Json::Exception,
+ ("Holiday month reference should be either a string or a number in", countryName));
+ }
+
+ if (refId <= 0)
+ MYTHROW(my::Json::Exception, ("Incorrect month reference in", countryName));
+ if (!json_is_integer(json_array_get(holiday, 1)))
+ MYTHROW(my::Json::Exception, ("Holiday day offset should be a number in", countryName));
+ data.AddPublicHoliday(refId, json_integer_value(json_array_get(holiday, 1)));
+ }
+
+ // TODO(@zverik): Implement formats reading when decided on data types.
+
+ return true;
+ }
+ catch (Reader::Exception const & e)
+ {
+ LOG(LWARNING, ("Error reading", COUNTRIES_META_FILE, ":", e.Msg()));
+ }
+ catch (my::Json::Exception const & e)
+ {
+ LOG(LERROR, ("Error parsing JSON in", COUNTRIES_META_FILE, ":", e.Msg()));
+ }
+ return false;
+}
+
+bool ReadRegionData(string const & countryName, RegionData & data)
+{
+ // When there is a match for a complete countryName, simply relay the call.
+ if (ReadRegionDataImpl(countryName, data))
+ return true;
+
+ // If not, cut parts of a country name from the tail. E.g. "Russia_Moscow" -> "Russia".
+ auto p = countryName.find_last_of('_');
+ while (p != string::npos)
+ {
+ if (ReadRegionDataImpl(countryName.substr(0, p), data))
+ return true;
+ p = p > 0 ? countryName.find_last_of('_', p - 1) : string::npos;
+ }
+ return false;
+}
+} // namespace feature
diff --git a/generator/region_meta.hpp b/generator/region_meta.hpp
new file mode 100644
index 0000000000..1d46b84aec
--- /dev/null
+++ b/generator/region_meta.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "generate_info.hpp"
+
+#include "indexer/feature_meta.hpp"
+
+namespace feature
+{
+bool ReadRegionData(string const & countryName, RegionData & data);
+} // namespace feature
diff --git a/generator/search_index_builder.cpp b/generator/search_index_builder.cpp
index df9903a1cd..016b2a9e2e 100644
--- a/generator/search_index_builder.cpp
+++ b/generator/search_index_builder.cpp
@@ -385,7 +385,7 @@ bool BuildSearchIndexFromDataFile(string const & filename, bool forceRebuild)
{
Platform & platform = GetPlatform();
- FilesContainerR readContainer(platform.GetReader(filename));
+ FilesContainerR readContainer(platform.GetReader(filename, "f"));
if (readContainer.IsExist(SEARCH_INDEX_FILE_TAG) && !forceRebuild)
return true;
diff --git a/indexer/data_factory.cpp b/indexer/data_factory.cpp
index 965f3f1edf..5f1edc82c0 100644
--- a/indexer/data_factory.cpp
+++ b/indexer/data_factory.cpp
@@ -1,7 +1,9 @@
-#include "coding/file_container.hpp"
#include "indexer/data_factory.hpp"
#include "indexer/interval_index.hpp"
#include "indexer/old/interval_index_101.hpp"
+
+#include "coding/file_container.hpp"
+
#include "defines.hpp"
@@ -10,8 +12,11 @@ void IndexFactory::Load(FilesContainerR const & cont)
ReadVersion(cont, m_version);
m_header.Load(cont);
- ReaderSource<FilesContainerR::TReader> src(cont.GetReader(REGION_INFO_FILE_TAG));
- m_region.Deserialize(src);
+ if (cont.IsExist(REGION_INFO_FILE_TAG))
+ {
+ ReaderSource<FilesContainerR::TReader> src(cont.GetReader(REGION_INFO_FILE_TAG));
+ m_regionData.Deserialize(src);
+ }
}
IntervalIndexIFace * IndexFactory::CreateIndex(ModelReaderPtr reader) const
diff --git a/indexer/data_factory.hpp b/indexer/data_factory.hpp
index 3bda00c867..251b1e2323 100644
--- a/indexer/data_factory.hpp
+++ b/indexer/data_factory.hpp
@@ -12,14 +12,14 @@ class IndexFactory
{
version::MwmVersion m_version;
feature::DataHeader m_header;
- feature::RegionData m_region;
+ feature::RegionData m_regionData;
public:
void Load(FilesContainerR const & cont);
inline version::MwmVersion const & GetMwmVersion() const { return m_version; }
inline feature::DataHeader const & GetHeader() const { return m_header; }
- inline feature::RegionData const & GetRegion() const { return m_region; }
+ inline feature::RegionData const & GetRegionData() const { return m_regionData; }
IntervalIndexIFace * CreateIndex(ModelReaderPtr reader) const;
};
diff --git a/indexer/feature_meta.cpp b/indexer/feature_meta.cpp
index 6e614d5cb3..73e9451b2d 100644
--- a/indexer/feature_meta.cpp
+++ b/indexer/feature_meta.cpp
@@ -99,6 +99,50 @@ bool Metadata::TypeFromString(string const & k, Metadata::EType & outType)
return true;
}
+
+void RegionData::SetLanguages(vector<string> const & codes)
+{
+ string value;
+ for (string const & code : codes)
+ {
+ int8_t const lang = StringUtf8Multilang::GetLangIndex(code);
+ if (lang != StringUtf8Multilang::kUnsupportedLanguageCode)
+ value.push_back(lang);
+ }
+ MetadataBase::Set(RegionData::Type::RD_LANGUAGES, value);
+}
+
+void RegionData::GetLanguages(vector<int8_t> & langs) const
+{
+ for (auto const lang : Get(RegionData::Type::RD_LANGUAGES))
+ langs.push_back(lang);
+}
+
+bool RegionData::HasLanguage(int8_t const lang) const
+{
+ for (auto const lng : Get(RegionData::Type::RD_LANGUAGES))
+ {
+ if (lng == lang)
+ return true;
+ }
+ return false;
+}
+
+bool RegionData::IsSingleLanguage(int8_t const lang) const
+{
+ string const value = Get(RegionData::Type::RD_LANGUAGES);
+ if (value.size() != 1)
+ return false;
+ return value.front() == lang;
+}
+
+void RegionData::AddPublicHoliday(int8_t month, int8_t offset)
+{
+ string value = Get(RegionData::Type::RD_PUBLIC_HOLIDAYS);
+ value.push_back(month);
+ value.push_back(offset);
+ Set(RegionData::Type::RD_PUBLIC_HOLIDAYS, value);
+}
} // namespace feature
// Warning: exact osm tag keys should be returned for valid enum values.
diff --git a/indexer/feature_meta.hpp b/indexer/feature_meta.hpp
index 5fccebc38b..85cede6dc5 100644
--- a/indexer/feature_meta.hpp
+++ b/indexer/feature_meta.hpp
@@ -132,13 +132,8 @@ public:
/// Used to normalize tags like "contact:phone" and "phone" to a common metadata enum value.
static bool TypeFromString(string const & osmTagKey, feature::Metadata::EType & outType);
- void Set(EType type, string const & value)
- {
- MetadataBase::Set(type, value);
- }
-
+ void Set(EType type, string const & value) { MetadataBase::Set(type, value); }
void Drop(EType type) { Set(type, string()); }
-
string GetWikiURL() const;
// TODO: Commented code below is now longer neded, but I leave it here
@@ -190,22 +185,40 @@ public:
class RegionData : public MetadataBase
{
public:
- enum Type
+ enum Type : int8_t
{
- RD_LANGUAGES, // list of written languages
- RD_DRIVING, // left- or right-hand driving (letter 'l' or 'r')
- RD_TIMEZONE, // UTC timezone offset, floating signed number of hours: -3, 4.5
- RD_ADDRESS_FORMAT, // address format, re: mapzen
- RD_PHONE_FORMAT, // list of strings in "+N NNN NN-NN-NN" format
+ RD_LANGUAGES, // list of written languages
+ RD_DRIVING, // left- or right-hand driving (letter 'l' or 'r')
+ RD_TIMEZONE, // UTC timezone offset, floating signed number of hours: -3, 4.5
+ RD_ADDRESS_FORMAT, // address format, re: mapzen
+ RD_PHONE_FORMAT, // list of strings in "+N NNN NN-NN-NN" format
RD_POSTCODE_FORMAT, // list of strings in "AAA ANN" format
RD_PUBLIC_HOLIDAYS, // fixed PH dates
RD_ALLOW_HOUSENAMES // 'y' if housenames are commonly used
};
- void Add(Type type, string const & s)
+ // Special values for month references in public holiday definitions.
+ enum PHReference : int8_t
{
+ PH_EASTER = 20,
+ PH_ORTHODOX_EASTER = 21,
+ PH_VICTORIA_DAY = 22,
+ PH_CANADA_DAY = 23
+ };
+
+ void Set(Type type, string const & s)
+ {
+ CHECK_NOT_EQUAL(type, Type::RD_LANGUAGES, ("Please use RegionData::SetLanguages method"));
MetadataBase::Set(type, s);
}
+
+ void SetLanguages(vector<string> const & codes);
+ void GetLanguages(vector<int8_t> & langs) const;
+ bool HasLanguage(int8_t const lang) const;
+ bool IsSingleLanguage(int8_t const lang) const;
+
+ void AddPublicHoliday(int8_t month, int8_t offset);
+ // No public holidays getters until we know what to do with these.
};
} // namespace feature
diff --git a/indexer/index.cpp b/indexer/index.cpp
index 6caaa521f7..6811333464 100644
--- a/indexer/index.cpp
+++ b/indexer/index.cpp
@@ -58,6 +58,9 @@ unique_ptr<MwmInfo> Index::CreateInfo(platform::LocalCountryFile const & localFi
info->m_minScale = static_cast<uint8_t>(scaleR.first);
info->m_maxScale = static_cast<uint8_t>(scaleR.second);
info->m_version = value.GetMwmVersion();
+ // Copying to drop the const qualifier.
+ feature::RegionData regionData(value.GetRegionData());
+ info->m_data = regionData;
return unique_ptr<MwmInfo>(move(info));
}
diff --git a/indexer/index.hpp b/indexer/index.hpp
index 6979d7af10..91351a9c6f 100644
--- a/indexer/index.hpp
+++ b/indexer/index.hpp
@@ -51,6 +51,7 @@ public:
void SetTable(MwmInfoEx & info);
inline feature::DataHeader const & GetHeader() const { return m_factory.GetHeader(); }
+ inline feature::RegionData const & GetRegionData() const { return m_factory.GetRegionData(); }
inline version::MwmVersion const & GetMwmVersion() const { return m_factory.GetMwmVersion(); }
inline string const & GetCountryFileName() const { return m_file.GetCountryFile().GetName(); }
};
diff --git a/indexer/indexer_tests/feature_metadata_test.cpp b/indexer/indexer_tests/feature_metadata_test.cpp
index 1a1771c634..1f88dc780c 100644
--- a/indexer/indexer_tests/feature_metadata_test.cpp
+++ b/indexer/indexer_tests/feature_metadata_test.cpp
@@ -100,3 +100,26 @@ UNIT_TEST(Feature_Metadata_GetWikipedia)
TEST_EQUAL(m.GetWikiURL(), "https://en.wikipedia.org/wiki/Article", ());
#endif
}
+
+UNIT_TEST(Feature_Metadata_RegionData_Languages)
+{
+ {
+ feature::RegionData rd;
+ vector<string> const langs = {"ru", "en", "et"};
+ rd.SetLanguages(langs);
+ TEST(rd.HasLanguage(StringUtf8Multilang::GetLangIndex("ru")), ());
+ TEST(rd.HasLanguage(StringUtf8Multilang::GetLangIndex("en")), ());
+ TEST(rd.HasLanguage(StringUtf8Multilang::GetLangIndex("et")), ());
+ TEST(!rd.HasLanguage(StringUtf8Multilang::GetLangIndex("es")), ());
+ TEST(!rd.IsSingleLanguage(StringUtf8Multilang::GetLangIndex("ru")), ());
+ }
+ {
+ feature::RegionData rd;
+ vector<string> const langs = {"et"};
+ rd.SetLanguages(langs);
+ TEST(rd.HasLanguage(StringUtf8Multilang::GetLangIndex("et")), ());
+ TEST(rd.IsSingleLanguage(StringUtf8Multilang::GetLangIndex("et")), ());
+ TEST(!rd.HasLanguage(StringUtf8Multilang::GetLangIndex("en")), ());
+ TEST(!rd.IsSingleLanguage(StringUtf8Multilang::GetLangIndex("en")), ());
+ }
+}
diff --git a/indexer/mwm_set.hpp b/indexer/mwm_set.hpp
index c924f5dd97..9a334316e2 100644
--- a/indexer/mwm_set.hpp
+++ b/indexer/mwm_set.hpp
@@ -8,6 +8,8 @@
#include "base/macros.hpp"
+#include "indexer/feature_meta.hpp"
+
#include "std/atomic.hpp"
#include "std/deque.hpp"
#include "std/map.hpp"
@@ -66,6 +68,8 @@ public:
MwmTypeT GetType() const;
+ inline feature::RegionData const & GetRegionData() const { return m_data; }
+
/// Returns the lock counter value for test needs.
uint8_t GetNumRefs() const { return m_numRefs; }
@@ -77,6 +81,8 @@ protected:
return result;
}
+ feature::RegionData m_data;
+
platform::LocalCountryFile m_file; ///< Path to the mwm file.
atomic<Status> m_status; ///< Current country status.
uint32_t m_numRefs; ///< Number of active handles.
diff --git a/tools/python/mwm/dump_mwm.py b/tools/python/mwm/dump_mwm.py
index 0147c8dc19..edc891dc64 100755
--- a/tools/python/mwm/dump_mwm.py
+++ b/tools/python/mwm/dump_mwm.py
@@ -17,6 +17,7 @@ for tv in tvv:
v = mwm.read_version()
print('Format: {0}, version: {1}'.format(v['fmt'], v['version'].strftime('%Y-%m-%d %H:%M')))
print('Header: {0}'.format(mwm.read_header()))
+print('Region Info: {0}'.format(mwm.read_region_info()))
print('Metadata count: {0}'.format(len(mwm.read_metadata())))
cross = mwm.read_crossmwm()
diff --git a/tools/python/mwm/mwm.py b/tools/python/mwm/mwm.py
index bb4c941690..65929831bd 100644
--- a/tools/python/mwm/mwm.py
+++ b/tools/python/mwm/mwm.py
@@ -31,6 +31,8 @@ class MWM:
"denomination", "building_levels", "test_id", "ref:sponsored", "price_rate",
"rating", "fuel", "routes"]
+ regiondata = ["languages", "driving", "timezone", "addr_fmt", "phone_fmt", "postcode_fmt", "holidays", "housenames"]
+
def __init__(self, f):
self.f = f
self.coord_size = None
@@ -112,6 +114,21 @@ class MWM:
# COMPLEX READERS
+ def read_region_info(self):
+ if not self.has_tag('rgninfo'):
+ return {}
+ fields = {}
+ self.seek_tag('rgninfo')
+ sz = self.read_varuint()
+ if sz:
+ for i in range(sz):
+ t = self.read_varuint()
+ t = self.regiondata[t] if t < len(self.regiondata) else str(t)
+ fields[t] = self.read_string()
+ if t == 'languages':
+ fields[t] = [self.languages[ord(x)] for x in fields[t]]
+ return fields
+
def read_metadata(self):
"""Reads 'meta' and 'metaidx' sections."""
if not self.has_tag('metaidx'):