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:
authorSergey Yershov <yershov@corp.mail.ru>2014-12-25 20:32:07 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:35:26 +0300
commit8f6b34bdb4e0e3ffb4010d5bd44df96bb4467a22 (patch)
tree2a02f3ce859edf2397c83d1fd2f3e48efa0b9bc0
parentaf6bd463306aad0bc7154d5550a298a104bad143 (diff)
Moved work with metadata to separated files
-rw-r--r--defines.hpp4
-rw-r--r--generator/feature_builder.hpp2
-rw-r--r--generator/feature_sorter.cpp38
-rw-r--r--generator/generator_tests/metadata_test.cpp153
-rw-r--r--generator/osm2meta.cpp1
-rw-r--r--generator/osm2meta.hpp111
-rw-r--r--generator/osm2type.cpp42
-rw-r--r--generator/xml_element.cpp51
-rw-r--r--indexer/feature.cpp10
-rw-r--r--indexer/feature.hpp9
-rw-r--r--indexer/feature_data.cpp13
-rw-r--r--indexer/feature_data.hpp51
-rw-r--r--indexer/feature_loader.cpp15
-rw-r--r--indexer/feature_loader.hpp2
-rw-r--r--indexer/feature_loader_base.cpp8
-rw-r--r--indexer/feature_loader_base.hpp6
-rw-r--r--indexer/feature_meta.cpp1
-rw-r--r--indexer/feature_meta.hpp108
-rw-r--r--indexer/old/feature_loader_101.hpp2
19 files changed, 454 insertions, 173 deletions
diff --git a/defines.hpp b/defines.hpp
index 74defadd37..f051d8b5fa 100644
--- a/defines.hpp
+++ b/defines.hpp
@@ -12,8 +12,8 @@
#define SEARCH_INDEX_FILE_TAG "sdx"
#define HEADER_FILE_TAG "header"
#define VERSION_FILE_TAG "version"
-#define ADDITIONAL_INFO_FILE_TAG "ainf"
-#define ADDITIONAL_INFO_INDEX_FILE_TAG "ainfidx"
+#define METADATA_FILE_TAG "meta"
+#define METADATA_INDEX_FILE_TAG "metaidx"
#define ROUTING_MATRIX_FILE_TAG "mercedes"
#define ROUTING_EDGEDATA_FILE_TAG "daewoo"
diff --git a/generator/feature_builder.hpp b/generator/feature_builder.hpp
index c62e308d7d..dc3de46bb6 100644
--- a/generator/feature_builder.hpp
+++ b/generator/feature_builder.hpp
@@ -39,7 +39,7 @@ public:
void AddPolygon(vector<m2::PointD> & poly);
//@}
- inline FeatureParams::AdditionalInfoT const & GetAdditionalInfo() const { return m_params.m_additional_info; }
+ inline feature::FeatureMetadata const & GetMetadata() const { return m_params.GetMetadata(); }
inline feature::EGeomType GetGeomType() const { return m_params.GetGeomType(); }
diff --git a/generator/feature_sorter.cpp b/generator/feature_sorter.cpp
index 098648c50c..c423f15c9a 100644
--- a/generator/feature_sorter.cpp
+++ b/generator/feature_sorter.cpp
@@ -90,9 +90,9 @@ namespace feature
vector<FileWriter*> m_geoFile, m_trgFile;
- unique_ptr<FileWriter> m_AdditionalInfoWriter;
+ unique_ptr<FileWriter> m_MetadataWriter;
- vector<pair<uint32_t, uint32_t>> m_AdditionalInfoIndex;
+ vector<pair<uint32_t, uint32_t>> m_MetadataIndex;
DataHeader m_header;
@@ -102,7 +102,7 @@ namespace feature
FeaturesCollector2(string const & fName, DataHeader const & header)
: FeaturesCollector(fName + DATA_FILE_TAG), m_writer(fName), m_header(header)
{
- m_AdditionalInfoWriter.reset(new FileWriter(fName + ADDITIONAL_INFO_FILE_TAG));
+ m_MetadataWriter.reset(new FileWriter(fName + METADATA_FILE_TAG));
for (size_t i = 0; i < m_header.GetScalesCount(); ++i)
{
@@ -155,10 +155,10 @@ namespace feature
}
- FileWriter ainf_index = m_writer.GetWriter(ADDITIONAL_INFO_INDEX_FILE_TAG);
- ainf_index.Write(m_AdditionalInfoIndex.data(), m_AdditionalInfoIndex.size()*(sizeof(uint32_t)*2));
- m_AdditionalInfoWriter->Flush();
- m_writer.Write(m_AdditionalInfoWriter->GetName(), ADDITIONAL_INFO_FILE_TAG);
+ FileWriter metadata_index = m_writer.GetWriter(METADATA_INDEX_FILE_TAG);
+ metadata_index.Write(m_MetadataIndex.data(), m_MetadataIndex.size()*(sizeof(uint32_t)*2));
+ m_MetadataWriter->Flush();
+ m_writer.Write(m_MetadataWriter->GetName(), METADATA_FILE_TAG);
m_writer.Finish();
@@ -526,31 +526,17 @@ namespace feature
uint32_t const ftID = WriteFeatureBase(holder.m_buffer.m_buffer, fb);
- ProcessFeatureAdditionalInfo(ftID, fb);
+ if (!fb.GetMetadata().Empty()) {
+ uint64_t offset = m_MetadataWriter->Pos();
+ m_MetadataIndex.push_back(make_pair(ftID, static_cast<uint32_t>(offset)));
+ fb.GetMetadata().SerializeToMWM(*m_MetadataWriter);
+ }
uint64_t const osmID = fb.GetWayIDForRouting();
if (osmID != 0)
m_osm2ft.Add(make_pair(osmID, ftID));
}
}
-
- void ProcessFeatureAdditionalInfo(uint32_t const ftID, FeatureBuilder2 const & f)
- {
- FeatureParams::AdditionalInfoT const & ainf = f.GetAdditionalInfo();
- if (ainf.size())
- {
- uint64_t offset = m_AdditionalInfoWriter->Pos();
- m_AdditionalInfoIndex.push_back(make_pair(ftID, static_cast<uint32_t>(offset)));
- for (auto const & e: ainf)
- {
- uint8_t last_key_mark = (&e == &(*ainf.crbegin())) << 7; /// set high bit (0x80) if it last element
- uint8_t elem[2] = {static_cast<uint8_t>(e.first | last_key_mark), numeric_limits<uint8_t>::max()};
- m_AdditionalInfoWriter->Write(elem, sizeof(elem));
- m_AdditionalInfoWriter->Write(e.second.data(), elem[1]);
- }
- }
- }
-
};
/// Simplify geometry for the upper scale.
diff --git a/generator/generator_tests/metadata_test.cpp b/generator/generator_tests/metadata_test.cpp
new file mode 100644
index 0000000000..a427f2d16f
--- /dev/null
+++ b/generator/generator_tests/metadata_test.cpp
@@ -0,0 +1,153 @@
+#include "../../testing/testing.hpp"
+#include "../../base/logging.hpp"
+
+#include "../../indexer/classificator_loader.hpp"
+#include "../../generator/osm2meta.hpp"
+#include "../../coding/writer.hpp"
+#include "../../coding/reader.hpp"
+
+UNIT_TEST(Metadata_ValidateAndFormat_stars)
+{
+ FeatureParams params;
+ MetadataTagProcessor p(params);
+
+ // ignore incorrect values
+ p("stars","0");
+ TEST(params.GetMetadata().Empty(), ());
+ p("stars","-1");
+ TEST(params.GetMetadata().Empty(), ());
+ p("stars","aasdasdas");
+ TEST(params.GetMetadata().Empty(), ());
+ p("stars","8");
+ TEST(params.GetMetadata().Empty(), ());
+ p("stars","10");
+ TEST(params.GetMetadata().Empty(), ());
+ p("stars","910");
+ TEST(params.GetMetadata().Empty(), ());
+ p("stars","100");
+ TEST(params.GetMetadata().Empty(), ());
+
+ // check correct values
+ p("stars","1");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "1", ())
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_STARS);
+
+ p("stars","2");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "2", ())
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_STARS);
+
+ p("stars","3");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "3", ())
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_STARS);
+
+ p("stars","4");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "4", ())
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_STARS);
+
+ p("stars","5");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "5", ())
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_STARS);
+
+ p("stars","6");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "6", ())
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_STARS);
+
+ p("stars","7");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "7", ())
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_STARS);
+
+ // check almost correct values
+ p("stars","4+");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "4", ())
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_STARS);
+
+ p("stars","5s");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "5", ())
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_STARS);
+
+}
+
+UNIT_TEST(Metadata_ValidateAndFormat_operator)
+{
+ classificator::Load();
+ Classificator const & c = classif();
+ uint32_t const type_atm = c.GetTypeByPath({ "amenity", "atm" });
+ uint32_t const type_fuel = c.GetTypeByPath({ "amenity", "fuel" });
+
+ FeatureParams params;
+ MetadataTagProcessor p(params);
+
+ // ignore tag 'operator' if feature have inappropriate type
+ p("operator","Some");
+ TEST(params.GetMetadata().Empty(), ());
+
+ params.SetType(type_atm);
+ p("operator","Some");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_OPERATOR), "Some", ());
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_OPERATOR);
+
+ params.SetType(type_fuel);
+ p("operator","Some");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_OPERATOR), "Some", ());
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_OPERATOR);
+
+ params.SetType(type_atm);
+ params.AddType(type_fuel);
+ p("operator","Some");
+ TEST_EQUAL(params.GetMetadata().Get(feature::FeatureMetadata::FMD_OPERATOR), "Some", ());
+ params.GetMetadata().Drop(feature::FeatureMetadata::FMD_OPERATOR);
+}
+
+UNIT_TEST(Metadata_ReadWrite_Intermediate)
+{
+ FeatureParams params;
+ FeatureParams params_test;
+ MetadataTagProcessor p(params);
+
+ vector<char> buffer;
+ MemWriter<vector<char> > writer(buffer);
+
+ p("stars","3");
+ p("phone","+123456789");
+ p("opening_hours","24/7");
+ p("cuisine","regional");
+ p("operator","Unused");
+ params.GetMetadata().Serialize(writer);
+
+ MemReader reader(buffer.data(), buffer.size());
+ ReaderSource<MemReader> src(reader);
+ params_test.GetMetadata().Deserialize(src);
+
+ TEST_EQUAL(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "3", ())
+ TEST_EQUAL(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_PHONE_NUMBER), "+123456789", ())
+ TEST_EQUAL(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_OPEN_HOURS), "24/7", ())
+ TEST_EQUAL(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_CUISINE), "regional", ())
+ TEST(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_OPERATOR).empty(), ())
+}
+
+UNIT_TEST(Metadata_ReadWrite_MWM)
+{
+ FeatureParams params;
+ FeatureParams params_test;
+ MetadataTagProcessor p(params);
+
+ vector<char> buffer;
+ MemWriter<vector<char> > writer(buffer);
+
+ p("stars","3");
+ p("phone","+123456789");
+ p("opening_hours","24/7");
+ p("cuisine","regional");
+ p("operator","Unused");
+ params.GetMetadata().SerializeToMWM(writer);
+
+ MemReader reader(buffer.data(), buffer.size());
+ ReaderSource<MemReader> src(reader);
+ params_test.GetMetadata().DeserializeFromMWM(src);
+
+ TEST_EQUAL(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_STARS), "3", ())
+ TEST_EQUAL(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_PHONE_NUMBER), "+123456789", ())
+ TEST_EQUAL(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_OPEN_HOURS), "24/7", ())
+ TEST_EQUAL(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_CUISINE), "regional", ())
+ TEST(params_test.GetMetadata().Get(feature::FeatureMetadata::FMD_OPERATOR).empty(), ())
+}
diff --git a/generator/osm2meta.cpp b/generator/osm2meta.cpp
new file mode 100644
index 0000000000..dc1bd346e1
--- /dev/null
+++ b/generator/osm2meta.cpp
@@ -0,0 +1 @@
+#include "osm2meta.hpp"
diff --git a/generator/osm2meta.hpp b/generator/osm2meta.hpp
new file mode 100644
index 0000000000..5249ded5aa
--- /dev/null
+++ b/generator/osm2meta.hpp
@@ -0,0 +1,111 @@
+#pragma once
+
+#include "../indexer/feature_data.hpp"
+#include "../indexer/classificator.hpp"
+
+#include "../std/string.hpp"
+
+class MetadataTagProcessor
+{
+ FeatureParams & m_params;
+
+public:
+ typedef bool result_type;
+
+ MetadataTagProcessor(FeatureParams &params)
+ : m_params(params)
+ {
+ }
+
+ bool operator() (string const & k, string const & v)
+ {
+
+ if (v.empty())
+ return false;
+
+ if (k == "cuisine")
+ {
+ string const & value = ValidateAndFormat_cuisine(v);
+ if (!value.empty())
+ m_params.GetMetadata().Add(feature::FeatureMetadata::FMD_CUISINE, value);
+ }
+ else if (k == "phone")
+ {
+ string const & value = ValidateAndFormat_phone(v);
+ if (!value.empty())
+ m_params.GetMetadata().Add(feature::FeatureMetadata::FMD_PHONE_NUMBER, value);
+ }
+ else if (k == "stars")
+ {
+ string const & value = ValidateAndFormat_stars(v);
+ if (!value.empty())
+ m_params.GetMetadata().Add(feature::FeatureMetadata::FMD_STARS, value);
+ }
+ else if (k == "url")
+ {
+ string const & value = ValidateAndFormat_url(v);
+ if (!value.empty())
+ m_params.GetMetadata().Add(feature::FeatureMetadata::FMD_URL, value);
+ }
+ else if (k == "operator")
+ {
+ string const & value = ValidateAndFormat_operator(v);
+ if (!value.empty())
+ m_params.GetMetadata().Add(feature::FeatureMetadata::FMD_OPERATOR, value);
+ }
+ else if (k == "opening_hours")
+ {
+ string const & value = ValidateAndFormat_opening_hours(v);
+ if (!value.empty())
+ m_params.GetMetadata().Add(feature::FeatureMetadata::FMD_OPEN_HOURS, value);
+ }
+ return false;
+ }
+protected:
+ /// Validation and formatting functions
+
+ string ValidateAndFormat_stars(string const & v) const
+ {
+ if (v.empty())
+ return string();
+
+ // we accepting stars from 1 to 7
+ if (v[0] <= '0' || v[0] > '7')
+ return string();
+
+ // ignore numbers large then 9
+ if (v.size() > 1 && (v[1] >= '0' && v[1] <= '9'))
+ return string();
+
+ return string(1, v[0]);
+ }
+
+ string ValidateAndFormat_cuisine(string const & v) const
+ {
+ return v;
+ }
+ string ValidateAndFormat_operator(string const & v) const
+ {
+ Classificator const & c = classif();
+ uint32_t const type_atm = c.GetTypeByPath({ "amenity", "atm" });
+ uint32_t const type_fuel = c.GetTypeByPath({ "amenity", "fuel" });
+
+ if (!(m_params.IsTypeExist(type_atm) || m_params.IsTypeExist(type_fuel)))
+ return string();
+
+ return v;
+ }
+ string ValidateAndFormat_url(string const & v) const
+ {
+ return v;
+ }
+ string ValidateAndFormat_phone(string const & v) const
+ {
+ return v;
+ }
+ string ValidateAndFormat_opening_hours(string const & v) const
+ {
+ return v;
+ }
+
+};
diff --git a/generator/osm2type.cpp b/generator/osm2type.cpp
index 70358c21fc..a31b56c766 100644
--- a/generator/osm2type.cpp
+++ b/generator/osm2type.cpp
@@ -1,4 +1,5 @@
#include "osm2type.hpp"
+#include "osm2meta.hpp"
#include "xml_element.hpp"
#include "../indexer/classificator.hpp"
@@ -101,44 +102,6 @@ namespace ftype
}
};
- class do_find_additional_info
- {
- size_t & m_count;
- FeatureParams & m_params;
-
- public:
- typedef bool result_type;
-
- do_find_additional_info(size_t &count, FeatureParams &params)
- : m_count(count), m_params(params)
- {
- m_count = 0;
- }
-
- bool operator() (string const & k, string const & v)
- {
- ++m_count;
-
- if (v.empty())
- return false;
-
- if (k == "cuisine")
- {
- m_params.AddAdditionalInfo(FeatureParams::AIT_CUISINE, v);
- }
- else if (k == "phone")
- {
- m_params.AddAdditionalInfo(FeatureParams::AIT_PHONE_NUMBER, v);
- }
- else if (k == "opening_hours")
- {
- m_params.AddAdditionalInfo(FeatureParams::AIT_OPEN_HOURS, v);
- }
- return false;
- }
-
- };
-
class do_find_name
{
set<string> m_savedNames;
@@ -397,7 +360,6 @@ namespace ftype
{
size_t count;
for_each_tag(p, do_find_name(count, params));
- for_each_tag(p, do_find_additional_info(count, params));
return count;
}
@@ -574,6 +536,8 @@ namespace ftype
}
params.FinishAddingTypes();
+ /// Collect addidtional information about feature such as start for hotels, opening hours and etc.
+ for_each_tag(p, MetadataTagProcessor(params));
}
uint32_t GetBoundaryType2()
diff --git a/generator/xml_element.cpp b/generator/xml_element.cpp
index b37bf9e199..72af0c9a21 100644
--- a/generator/xml_element.cpp
+++ b/generator/xml_element.cpp
@@ -78,35 +78,36 @@ void BaseOSMParser::Pop(string const &)
}
}
-
-struct StdinReader
+namespace
{
- uint64_t Read(char * buffer, uint64_t bufferSize)
+ struct StdinReader
{
- return fread(buffer, sizeof(char), bufferSize, stdin);
- }
-};
-
-struct FileReader
-{
- FILE * m_file;
-
- FileReader(string const & filename)
- {
- m_file = fopen(filename.c_str(), "rb");
- }
+ uint64_t Read(char * buffer, uint64_t bufferSize)
+ {
+ return fread(buffer, sizeof(char), bufferSize, stdin);
+ }
+ };
- ~FileReader()
+ struct FileReader
{
- fclose(m_file);
- }
-
- uint64_t Read(char * buffer, uint64_t bufferSize)
- {
- return fread(buffer, sizeof(char), bufferSize, m_file);
- }
-};
-
+ FILE * m_file;
+
+ FileReader(string const & filename)
+ {
+ m_file = fopen(filename.c_str(), "rb");
+ }
+
+ ~FileReader()
+ {
+ fclose(m_file);
+ }
+
+ uint64_t Read(char * buffer, uint64_t bufferSize)
+ {
+ return fread(buffer, sizeof(char), bufferSize, m_file);
+ }
+ };
+}
void ParseXMLFromStdIn(BaseOSMParser & parser)
{
diff --git a/indexer/feature.cpp b/indexer/feature.cpp
index 4d2827d98f..6877d86525 100644
--- a/indexer/feature.cpp
+++ b/indexer/feature.cpp
@@ -82,7 +82,7 @@ void FeatureType::Deserialize(feature::LoaderBase * pLoader, BufferT buffer)
m_pLoader->InitFeature(this);
- m_bHeader2Parsed = m_bPointsParsed = m_bTrianglesParsed = m_bAdditionalInfoParsed = false;
+ m_bHeader2Parsed = m_bPointsParsed = m_bTrianglesParsed = m_bMetadataParsed = false;
m_innerStats.MakeZero();
}
@@ -137,12 +137,12 @@ uint32_t FeatureType::ParseTriangles(int scale) const
return sz;
}
-void FeatureType::ParseAdditionalInfo() const
+void FeatureType::ParseMetadata() const
{
- if (m_bAdditionalInfoParsed) return;
+ if (m_bMetadataParsed) return;
- m_pLoader->ParseAdditionalInfo();
- m_bAdditionalInfoParsed = true;
+ m_pLoader->ParseMetadata();
+ m_bMetadataParsed = true;
}
diff --git a/indexer/feature.hpp b/indexer/feature.hpp
index 8db0e00856..dc7ee5650e 100644
--- a/indexer/feature.hpp
+++ b/indexer/feature.hpp
@@ -164,7 +164,7 @@ public:
uint32_t ParseGeometry(int scale) const;
uint32_t ParseTriangles(int scale) const;
- void ParseAdditionalInfo() const;
+ void ParseMetadata() const;
//@}
/// @name Geometry.
@@ -261,7 +261,8 @@ public:
uint8_t GetRank() const;
uint32_t GetPopulation() const;
string GetRoadNumber() const;
- inline FeatureParams::AdditionalInfoT const & GetAdditionalInfo() const { return m_additional_info; }
+ inline feature::FeatureMetadata const & GetMetadata() const { return m_metadata; }
+ inline feature::FeatureMetadata & GetMetadata() { return m_metadata; }
double GetDistance(m2::PointD const & pt, int scale) const;
@@ -311,9 +312,9 @@ private:
typedef buffer_vector<m2::PointD, static_buffer> points_t;
mutable points_t m_points, m_triangles;
- mutable FeatureParams::AdditionalInfoT m_additional_info;
+ mutable feature::FeatureMetadata m_metadata;
- mutable bool m_bHeader2Parsed, m_bPointsParsed, m_bTrianglesParsed, m_bAdditionalInfoParsed;
+ mutable bool m_bHeader2Parsed, m_bPointsParsed, m_bTrianglesParsed, m_bMetadataParsed;
mutable inner_geom_stat_t m_innerStats;
diff --git a/indexer/feature_data.cpp b/indexer/feature_data.cpp
index 33843dcb97..2488338e8a 100644
--- a/indexer/feature_data.cpp
+++ b/indexer/feature_data.cpp
@@ -168,19 +168,6 @@ bool FeatureParams::AddHouseName(string const & s)
return false;
}
-bool FeatureParams::AddAdditionalInfo(additional_info_types type, string const & s)
-{
- if (m_additional_info[type].empty())
- {
- m_additional_info[type] = s;
- }
- else
- {
- m_additional_info[type] = m_additional_info[type] + ", " + s;
- }
- return true;
-}
-
bool FeatureParams::AddHouseNumber(string const & ss)
{
diff --git a/indexer/feature_data.hpp b/indexer/feature_data.hpp
index 216ee08936..a638a61e02 100644
--- a/indexer/feature_data.hpp
+++ b/indexer/feature_data.hpp
@@ -11,6 +11,7 @@
#include "../std/vector.hpp"
#include "../std/algorithm.hpp"
+#include "feature_meta.hpp"
class FeatureBase;
@@ -205,17 +206,10 @@ class FeatureParams : public FeatureParamsBase
/// We use it now only for search unit tests
string m_street;
-public:
+ feature::FeatureMetadata m_metadata;
- enum additional_info_types {
- AIT_CUISINE = 1,
- AIT_OPEN_HOURS,
- AIT_PHONE_NUMBER,
- AIT_FAX_NUMBER
- };
+public:
- typedef map<uint8_t, string> AdditionalInfoT;
- AdditionalInfoT m_additional_info;
typedef vector<uint32_t> types_t;
types_t m_Types;
@@ -228,8 +222,6 @@ public:
bool AddHouseName(string const & s);
bool AddHouseNumber(string const & s);
- bool AddAdditionalInfo(additional_info_types type, string const & s);
-
/// @name Used in storing full street address only.
//@{
void AddStreetAddress(string const & s);
@@ -244,7 +236,7 @@ public:
m_Types = rhs.m_Types;
m_street = rhs.m_street;
- m_additional_info = rhs.m_additional_info;
+ m_metadata = rhs.m_metadata;
}
inline bool IsValid() const { return !m_Types.empty(); }
@@ -270,7 +262,10 @@ public:
uint8_t GetHeader() const;
- template <class SinkT> void Write(SinkT & sink, bool needStoreAdditionalInfo = true) const
+ feature::FeatureMetadata const & GetMetadata() const { return m_metadata; }
+ feature::FeatureMetadata & GetMetadata() { return m_metadata; }
+
+ template <class SinkT> void Write(SinkT & sink, bool needStoreMetadata = true) const
{
uint8_t const header = GetHeader();
@@ -279,24 +274,13 @@ public:
for (size_t i = 0; i < m_Types.size(); ++i)
WriteVarUint(sink, GetIndexForType(m_Types[i]));
- if (needStoreAdditionalInfo)
- {
- uint8_t const ait_size = m_additional_info.size();
- WriteToSink(sink, ait_size);
- if (ait_size)
- {
- for(auto & it: m_additional_info)
- {
- WriteToSink(sink, uint8_t(it.first));
- utils::WriteString(sink, it.second);
- }
- }
- }
+ if (needStoreMetadata)
+ m_metadata.Serialize(sink);
BaseT::Write(sink, header);
}
- template <class SrcT> void Read(SrcT & src, bool needReadAdditionalInfo = true)
+ template <class SrcT> void Read(SrcT & src, bool needReadMetadata = true)
{
using namespace feature;
@@ -307,17 +291,8 @@ public:
for (size_t i = 0; i < count; ++i)
m_Types.push_back(GetTypeForIndex(ReadVarUint<uint32_t>(src)));
- if (needReadAdditionalInfo)
- {
- uint8_t const ait_size = ReadPrimitiveFromSource<uint8_t>(src);
- for (size_t i=0; i < ait_size; ++i)
- {
- uint8_t const key = ReadPrimitiveFromSource<uint8_t>(src);
- string value;
- utils::ReadString(src, value);
- m_additional_info.insert(make_pair(key, value));
- }
- }
+ if (needReadMetadata)
+ m_metadata.Deserialize(src);
BaseT::Read(src, header);
}
diff --git a/indexer/feature_loader.cpp b/indexer/feature_loader.cpp
index b88c63f80a..55664f903a 100644
--- a/indexer/feature_loader.cpp
+++ b/indexer/feature_loader.cpp
@@ -252,12 +252,12 @@ uint32_t LoaderCurrent::ParseTriangles(int scale)
return sz;
}
-void LoaderCurrent::ParseAdditionalInfo()
+void LoaderCurrent::ParseMetadata()
{
try
{
typedef pair<uint32_t, uint32_t> IdxElementT;
- DDVector<IdxElementT, FilesContainerR::ReaderT> idx(m_Info.GetAdditionalInfoIndexReader());
+ DDVector<IdxElementT, FilesContainerR::ReaderT> idx(m_Info.GetMetadataIndexReader());
auto it = lower_bound(idx.begin(), idx.end()
, make_pair(uint32_t(m_pF->m_id.m_offset), uint32_t(0))
@@ -266,16 +266,9 @@ void LoaderCurrent::ParseAdditionalInfo()
if (it != idx.end() && m_pF->m_id.m_offset == it->first)
{
- uint8_t header[2] = {0};
- char buffer[numeric_limits<uint8_t>::max()] = {0};
- ReaderSource<FilesContainerR::ReaderT> reader(m_Info.GetAdditionalInfoReader());
+ ReaderSource<FilesContainerR::ReaderT> reader(m_Info.GetMetadataReader());
reader.Skip(it->second);
- do
- {
- reader.Read(header, sizeof(header));
- reader.Read(buffer, header[1]);
- m_pF->m_additional_info[uint8_t(header[0] & 0x7F)].assign(buffer, header[1]);
- } while (!(header[0] & 0x80));
+ m_pF->GetMetadata().DeserializeFromMWM(reader);
}
}
catch(Reader::OpenException & e)
diff --git a/indexer/feature_loader.hpp b/indexer/feature_loader.hpp
index d4165a1a02..b2b00deca2 100644
--- a/indexer/feature_loader.hpp
+++ b/indexer/feature_loader.hpp
@@ -28,6 +28,6 @@ namespace feature
virtual void ParseHeader2();
virtual uint32_t ParseGeometry(int scale);
virtual uint32_t ParseTriangles(int scale);
- virtual void ParseAdditionalInfo();
+ virtual void ParseMetadata();
};
}
diff --git a/indexer/feature_loader_base.cpp b/indexer/feature_loader_base.cpp
index eb127876be..6b6f72e90d 100644
--- a/indexer/feature_loader_base.cpp
+++ b/indexer/feature_loader_base.cpp
@@ -34,14 +34,14 @@ SharedLoadInfo::ReaderT SharedLoadInfo::GetDataReader() const
return m_cont.GetReader(DATA_FILE_TAG);
}
-SharedLoadInfo::ReaderT SharedLoadInfo::GetAdditionalInfoReader() const
+SharedLoadInfo::ReaderT SharedLoadInfo::GetMetadataReader() const
{
- return m_cont.GetReader(ADDITIONAL_INFO_FILE_TAG);
+ return m_cont.GetReader(METADATA_FILE_TAG);
}
-SharedLoadInfo::ReaderT SharedLoadInfo::GetAdditionalInfoIndexReader() const
+SharedLoadInfo::ReaderT SharedLoadInfo::GetMetadataIndexReader() const
{
- return m_cont.GetReader(ADDITIONAL_INFO_INDEX_FILE_TAG);
+ return m_cont.GetReader(METADATA_INDEX_FILE_TAG);
}
SharedLoadInfo::ReaderT SharedLoadInfo::GetGeometryReader(int ind) const
diff --git a/indexer/feature_loader_base.hpp b/indexer/feature_loader_base.hpp
index eab6dca536..409d3e0e27 100644
--- a/indexer/feature_loader_base.hpp
+++ b/indexer/feature_loader_base.hpp
@@ -30,8 +30,8 @@ namespace feature
~SharedLoadInfo();
ReaderT GetDataReader() const;
- ReaderT GetAdditionalInfoReader() const;
- ReaderT GetAdditionalInfoIndexReader() const;
+ ReaderT GetMetadataReader() const;
+ ReaderT GetMetadataIndexReader() const;
ReaderT GetGeometryReader(int ind) const;
ReaderT GetTrianglesReader(int ind) const;
@@ -75,7 +75,7 @@ namespace feature
virtual void ParseHeader2() = 0;
virtual uint32_t ParseGeometry(int scale) = 0;
virtual uint32_t ParseTriangles(int scale) = 0;
- virtual void ParseAdditionalInfo() = 0;
+ virtual void ParseMetadata() = 0;
inline uint32_t GetTypesSize() const { return m_CommonOffset - m_TypesOffset; }
diff --git a/indexer/feature_meta.cpp b/indexer/feature_meta.cpp
new file mode 100644
index 0000000000..5897638c50
--- /dev/null
+++ b/indexer/feature_meta.cpp
@@ -0,0 +1 @@
+#include "feature_meta.hpp"
diff --git a/indexer/feature_meta.hpp b/indexer/feature_meta.hpp
new file mode 100644
index 0000000000..f1e4d8ff08
--- /dev/null
+++ b/indexer/feature_meta.hpp
@@ -0,0 +1,108 @@
+#pragma once
+
+#include "../coding/reader.hpp"
+#include "../coding/multilang_utf8_string.hpp"
+
+#include "../std/map.hpp"
+#include "../std/string.hpp"
+#include "../std/limits.hpp"
+#include "../std/algorithm.hpp"
+
+namespace feature
+{
+ class FeatureMetadata
+ {
+ typedef map<uint8_t, string> MetadataT;
+ MetadataT m_metadata;
+
+ public:
+ enum EMetadataType {
+ FMD_CUISINE = 1,
+ FMD_OPEN_HOURS,
+ FMD_PHONE_NUMBER,
+ FMD_FAX_NUMBER,
+ FMD_STARS,
+ FMD_OPERATOR,
+ FMD_URL,
+ FMD_INTERNET
+ };
+
+ bool Add(EMetadataType type, string const & s)
+ {
+ if (m_metadata[type].empty())
+ {
+ m_metadata[type] = s;
+ }
+ else
+ {
+ m_metadata[type] = m_metadata[type] + ", " + s;
+ }
+ return true;
+ }
+
+ string Get(EMetadataType type)
+ {
+ auto it = m_metadata.find(type);
+ return (it == m_metadata.end()) ? string() : it->second;
+ }
+
+ void Drop(EMetadataType type)
+ {
+ m_metadata.erase(type);
+ }
+
+ inline bool Empty() const { return m_metadata.empty(); }
+ inline size_t Size() const { return m_metadata.size(); }
+
+ template <class ArchiveT> void SerializeToMWM(ArchiveT & ar) const
+ {
+ for (auto const & e: m_metadata)
+ {
+ uint8_t last_key_mark = (&e == &(*m_metadata.crbegin())) << 7; /// set high bit (0x80) if it last element
+ uint8_t elem[2] = {static_cast<uint8_t>(e.first | last_key_mark), static_cast<uint8_t>(min(e.second.size(), (size_t)numeric_limits<uint8_t>::max()))};
+ ar.Write(elem, sizeof(elem));
+ ar.Write(e.second.data(), elem[1]);
+ }
+ }
+ template <class ArchiveT> void DeserializeFromMWM(ArchiveT & ar)
+ {
+ uint8_t header[2] = {0};
+ char buffer[numeric_limits<uint8_t>::max()] = {0};
+ do
+ {
+ ar.Read(header, sizeof(header));
+ ar.Read(buffer, header[1]);
+ m_metadata[static_cast<uint8_t>(header[0] & 0x7F)].assign(buffer, header[1]);
+ } while (!(header[0] & 0x80));
+ }
+
+ template <class ArchiveT> void Serialize(ArchiveT & ar) const
+ {
+ uint8_t const metadata_size = m_metadata.size();
+ WriteToSink(ar, metadata_size);
+ if (metadata_size)
+ {
+ for(auto & it: m_metadata)
+ {
+ WriteToSink(ar, static_cast<uint8_t>(it.first));
+ utils::WriteString(ar, it.second);
+ }
+ }
+ }
+
+ template <class ArchiveT> void Deserialize(ArchiveT & ar)
+ {
+ uint8_t const metadata_size = ReadPrimitiveFromSource<uint8_t>(ar);
+ for (size_t i=0; i < metadata_size; ++i)
+ {
+ uint8_t const key = ReadPrimitiveFromSource<uint8_t>(ar);
+ string value;
+ utils::ReadString(ar, value);
+ m_metadata.insert(make_pair(key, value));
+ }
+
+ }
+
+
+ };
+}
diff --git a/indexer/old/feature_loader_101.hpp b/indexer/old/feature_loader_101.hpp
index a576373df1..e18dfb32b5 100644
--- a/indexer/old/feature_loader_101.hpp
+++ b/indexer/old/feature_loader_101.hpp
@@ -36,7 +36,7 @@ namespace old_101 { namespace feature
virtual void ParseHeader2();
virtual uint32_t ParseGeometry(int scale);
virtual uint32_t ParseTriangles(int scale);
- virtual void ParseAdditionalInfo() {} /// not supported in this version
+ virtual void ParseMetadata() {} /// not supported in this version
};
}