diff options
author | Ilya Zverev <zverik@textual.ru> | 2016-07-15 18:01:19 +0300 |
---|---|---|
committer | Ilya Zverev <zverik@textual.ru> | 2016-07-19 12:53:21 +0300 |
commit | 46a5d58ba1fe3b274df149214fe1bbc7bb97b6e1 (patch) | |
tree | 3d9baa51399d40e78102e3e1c7a6add4573c0059 /generator | |
parent | 989c84e7bb93994a02ba482e83e8ec3a90ff91fa (diff) |
[generator] Add region info section to mwms
Diffstat (limited to 'generator')
-rw-r--r-- | generator/feature_sorter.cpp | 51 | ||||
-rw-r--r-- | generator/generator.pro | 5 | ||||
-rw-r--r-- | generator/region_meta.cpp | 123 | ||||
-rw-r--r-- | generator/region_meta.hpp | 10 | ||||
-rw-r--r-- | generator/search_index_builder.cpp | 2 |
5 files changed, 156 insertions, 35 deletions
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; |