forked from organicmaps/organicmaps
[generator]
- Do add “layer” attribute if absent in “bridge” or “tunnel” - Do process “restaurant” and “hotel” synonyms - Correct processing of layer=-1 (needed for “tunnel”) - Skip “ref=route” attribute
This commit is contained in:
parent
cf856a71bf
commit
bd06c5762a
5 changed files with 263 additions and 56 deletions
|
@ -16,12 +16,7 @@ namespace
|
|||
{
|
||||
p->parent = 0;
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
p->childs.push_back(XMLElement());
|
||||
p->childs.back().name = "tag";
|
||||
p->childs.back().attrs["k"] = arr[i][0];
|
||||
p->childs.back().attrs["v"] = arr[i][1];
|
||||
}
|
||||
p->AddKV(arr[i][0], arr[i][1]);
|
||||
}
|
||||
|
||||
template <size_t N> uint32_t GetType(char const * (&arr)[N])
|
||||
|
@ -48,7 +43,7 @@ UNIT_TEST(OsmType_SkipDummy)
|
|||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
TEST_EQUAL ( params.m_Types.size(), 1, () );
|
||||
TEST_EQUAL ( params.m_Types.size(), 1, (params) );
|
||||
TEST_EQUAL ( params.m_Types[0], GetType(arr[1]), () );
|
||||
}
|
||||
|
||||
|
@ -127,8 +122,9 @@ UNIT_TEST(OsmType_Combined)
|
|||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
TEST(params.IsTypeExist(GetType(arr[3])), ());
|
||||
char const * arrT[] = { "building" };
|
||||
TEST_EQUAL(params.m_Types.size(), 2, (params));
|
||||
TEST(params.IsTypeExist(GetType(arr[3])), ());
|
||||
TEST(params.IsTypeExist(GetType(arrT)), ());
|
||||
|
||||
string s;
|
||||
|
@ -157,6 +153,7 @@ UNIT_TEST(OsmType_Address)
|
|||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * arrT[] = { "building", "address" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(arrT)), ());
|
||||
|
||||
TEST_EQUAL(params.house.Get(), "223/5", ());
|
||||
|
@ -183,6 +180,7 @@ UNIT_TEST(OsmType_PlaceState)
|
|||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * arrT[] = { "place", "state", "USA" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(arrT)), ());
|
||||
|
||||
string s;
|
||||
|
@ -233,8 +231,8 @@ UNIT_TEST(OsmType_AlabamaRiver)
|
|||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * arrT[] = { "waterway", "river" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(arrT)), ());
|
||||
TEST_EQUAL(params.m_Types.size(), 1, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(OsmType_Synonyms)
|
||||
|
@ -244,7 +242,9 @@ UNIT_TEST(OsmType_Synonyms)
|
|||
char const * arr[][2] = {
|
||||
{ "building", "yes" },
|
||||
{ "shop", "yes" },
|
||||
{ "atm", "yes" }
|
||||
{ "atm", "yes" },
|
||||
{ "restaurant", "yes" },
|
||||
{ "hotel", "yes" },
|
||||
};
|
||||
|
||||
XMLElement e;
|
||||
|
@ -256,10 +256,15 @@ UNIT_TEST(OsmType_Synonyms)
|
|||
char const * arrT1[] = { "building" };
|
||||
char const * arrT2[] = { "amenity", "atm" };
|
||||
char const * arrT3[] = { "shop" };
|
||||
TEST_EQUAL(params.m_Types.size(), 3, ());
|
||||
char const * arrT4[] = { "amenity", "restaurant" };
|
||||
char const * arrT5[] = { "tourism", "hotel" };
|
||||
TEST_EQUAL(params.m_Types.size(), 5, (params));
|
||||
|
||||
TEST(params.IsTypeExist(GetType(arrT1)), ());
|
||||
TEST(params.IsTypeExist(GetType(arrT2)), ());
|
||||
TEST(params.IsTypeExist(GetType(arrT3)), ());
|
||||
TEST(params.IsTypeExist(GetType(arrT4)), ());
|
||||
TEST(params.IsTypeExist(GetType(arrT5)), ());
|
||||
}
|
||||
|
||||
// Duplicating test.
|
||||
|
@ -276,7 +281,7 @@ UNIT_TEST(OsmType_Synonyms)
|
|||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * arrT[] = { "amenity", "atm" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, ());
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(arrT)), ());
|
||||
}
|
||||
|
||||
|
@ -295,7 +300,7 @@ UNIT_TEST(OsmType_Synonyms)
|
|||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * arrT[] = { "building" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, ());
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(arrT)), ());
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +319,7 @@ UNIT_TEST(OsmType_Capital)
|
|||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
TEST_EQUAL(params.m_Types.size(), 1, ());
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
char const * type[] = { "place", "city", "capital" };
|
||||
TEST(params.IsTypeExist(GetType(type)), ());
|
||||
}
|
||||
|
@ -331,8 +336,139 @@ UNIT_TEST(OsmType_Capital)
|
|||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
TEST_EQUAL(params.m_Types.size(), 1, ());
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
char const * type[] = { "place", "city" };
|
||||
TEST(params.IsTypeExist(GetType(type)), ());
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(OsmType_Route)
|
||||
{
|
||||
{
|
||||
char const * arr[][2] = {
|
||||
{ "highway", "motorway" },
|
||||
{ "ref", "I 95" }
|
||||
};
|
||||
|
||||
XMLElement e;
|
||||
FillXmlElement(arr, ARRAY_SIZE(arr), &e);
|
||||
|
||||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(arr[0])), ());
|
||||
TEST_EQUAL(params.ref, arr[1][1], ());
|
||||
}
|
||||
|
||||
{
|
||||
char const * arr[][2] = {
|
||||
{ "highway", "path" },
|
||||
{ "ref", "route" }
|
||||
};
|
||||
|
||||
XMLElement e;
|
||||
FillXmlElement(arr, ARRAY_SIZE(arr), &e);
|
||||
|
||||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(arr[0])), ());
|
||||
TEST(params.ref.empty(), ());
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(OsmType_Layer)
|
||||
{
|
||||
{
|
||||
char const * arr[][2] = {
|
||||
{ "highway", "motorway" },
|
||||
{ "bridge", "yes" },
|
||||
{ "layer", "2" },
|
||||
};
|
||||
|
||||
XMLElement e;
|
||||
FillXmlElement(arr, ARRAY_SIZE(arr), &e);
|
||||
|
||||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * type[] = { "highway", "motorway", "bridge" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(type)), ());
|
||||
TEST_EQUAL(params.layer, 2, ());
|
||||
}
|
||||
|
||||
{
|
||||
char const * arr[][2] = {
|
||||
{ "highway", "trunk" },
|
||||
{ "tunnel", "yes" },
|
||||
{ "layer", "-1" },
|
||||
};
|
||||
|
||||
XMLElement e;
|
||||
FillXmlElement(arr, ARRAY_SIZE(arr), &e);
|
||||
|
||||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * type[] = { "highway", "trunk", "tunnel" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(type)), ());
|
||||
TEST_EQUAL(params.layer, -1, ());
|
||||
}
|
||||
|
||||
{
|
||||
char const * arr[][2] = {
|
||||
{ "highway", "secondary" },
|
||||
{ "bridge", "yes" },
|
||||
};
|
||||
|
||||
XMLElement e;
|
||||
FillXmlElement(arr, ARRAY_SIZE(arr), &e);
|
||||
|
||||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * type[] = { "highway", "secondary", "bridge" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(type)), ());
|
||||
TEST_EQUAL(params.layer, 1, ());
|
||||
}
|
||||
|
||||
{
|
||||
char const * arr[][2] = {
|
||||
{ "highway", "primary" },
|
||||
{ "tunnel", "yes" },
|
||||
};
|
||||
|
||||
XMLElement e;
|
||||
FillXmlElement(arr, ARRAY_SIZE(arr), &e);
|
||||
|
||||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * type[] = { "highway", "primary", "tunnel" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(type)), ());
|
||||
TEST_EQUAL(params.layer, -1, ());
|
||||
}
|
||||
|
||||
{
|
||||
char const * arr[][2] = {
|
||||
{ "highway", "living_street" },
|
||||
};
|
||||
|
||||
XMLElement e;
|
||||
FillXmlElement(arr, ARRAY_SIZE(arr), &e);
|
||||
|
||||
FeatureParams params;
|
||||
ftype::GetNameAndType(&e, params);
|
||||
|
||||
char const * type[] = { "highway", "living_street" };
|
||||
TEST_EQUAL(params.m_Types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType(type)), ());
|
||||
TEST_EQUAL(params.layer, 0, ());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "../base/math.hpp"
|
||||
|
||||
#include "../std/vector.hpp"
|
||||
#include "../std/bind.hpp"
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
|
@ -26,8 +27,11 @@ namespace ftype
|
|||
strings::SimpleTokenizer it(v, "|");
|
||||
while (it)
|
||||
{
|
||||
if (strings::IsInArray(aTrue, *it)) return 1;
|
||||
if (strings::IsInArray(aFalse, *it)) return -1;
|
||||
if (strings::IsInArray(aTrue, *it))
|
||||
return 1;
|
||||
if (k != "layer" && strings::IsInArray(aFalse, *it))
|
||||
return -1;
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
|
@ -169,7 +173,7 @@ namespace ftype
|
|||
}
|
||||
|
||||
// get reference (we process road numbers only)
|
||||
if (k == "ref")
|
||||
if (k == "ref" && v != "route")
|
||||
m_params.ref = v;
|
||||
|
||||
// get house number
|
||||
|
@ -251,20 +255,21 @@ namespace ftype
|
|||
|
||||
class do_find_root_obj
|
||||
{
|
||||
set<string> const & m_skipTags;
|
||||
set<int> & m_skipTags;
|
||||
path_type & m_path;
|
||||
int m_id;
|
||||
|
||||
public:
|
||||
typedef ClassifObjectPtr result_type;
|
||||
typedef bool result_type;
|
||||
|
||||
do_find_root_obj(set<string> const & skipTags, path_type & path)
|
||||
: m_skipTags(skipTags), m_path(path)
|
||||
do_find_root_obj(set<int> & skipTags, path_type & path)
|
||||
: m_skipTags(skipTags), m_path(path), m_id(0)
|
||||
{
|
||||
}
|
||||
|
||||
ClassifObjectPtr operator() (string const & k, string const & v) const
|
||||
bool operator() (string const & k, string const & v)
|
||||
{
|
||||
if (m_skipTags.find(k) == m_skipTags.end())
|
||||
if (m_skipTags.count(m_id) == 0)
|
||||
{
|
||||
// first try to match key
|
||||
ClassifObjectPtr p = do_find_obj(classif().GetRoot(), true)(k, v);
|
||||
|
@ -276,10 +281,14 @@ namespace ftype
|
|||
p = do_find_obj(p.get(), false)(k, v);
|
||||
if (p)
|
||||
m_path.push_back(p);
|
||||
|
||||
m_skipTags.insert(m_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return (!m_path.empty() ? m_path.back() : ClassifObjectPtr(0, 0));
|
||||
++m_id;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -292,14 +301,52 @@ namespace ftype
|
|||
|
||||
bool operator() (string & k, string & v) const
|
||||
{
|
||||
if (k == "atm" && v == "yes")
|
||||
if (v == "yes")
|
||||
{
|
||||
k = "amenity";
|
||||
v = "atm";
|
||||
if (k == "atm" || k == "restaurant")
|
||||
{
|
||||
k.swap(v);
|
||||
k = "amenity";
|
||||
}
|
||||
else if (k == "hotel")
|
||||
{
|
||||
k.swap(v);
|
||||
k = "tourism";
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class do_find_pairs
|
||||
{
|
||||
string const (*m_arr) [2];
|
||||
size_t m_size;
|
||||
|
||||
vector<bool> m_res;
|
||||
|
||||
public:
|
||||
template <size_t N> do_find_pairs(string const (&arr) [N][2])
|
||||
: m_arr(&arr[0]), m_size(N)
|
||||
{
|
||||
m_res.resize(m_size, false);
|
||||
}
|
||||
|
||||
bool operator() (string const & k, string const & v)
|
||||
{
|
||||
for (size_t i = 0; i < m_size; ++i)
|
||||
if ((k == "*" || k == m_arr[i][0]) &&
|
||||
(v == "*" || v == m_arr[i][1]))
|
||||
{
|
||||
m_res[i] = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsExist(size_t i) const { return m_res[i]; }
|
||||
};
|
||||
}
|
||||
|
||||
ClassifObjectPtr find_object(ClassifObject const * parent, XMLElement * p, bool isKey)
|
||||
|
@ -319,6 +366,26 @@ namespace ftype
|
|||
for_each_tag(p, do_replace_synonyms());
|
||||
}
|
||||
|
||||
void add_layers(XMLElement * p)
|
||||
{
|
||||
static string const arr[][2] = {
|
||||
{ "bridge", "yes" },
|
||||
{ "tunnel", "yes" },
|
||||
{ "layer", "*" },
|
||||
};
|
||||
|
||||
do_find_pairs doFind(arr);
|
||||
for_each_tag(p, bind<bool>(ref(doFind), _1, _2));
|
||||
|
||||
if (!doFind.IsExist(2))
|
||||
{
|
||||
if (doFind.IsExist(0))
|
||||
p->AddKV("layer", "1");
|
||||
if (doFind.IsExist(1))
|
||||
p->AddKV("layer", "-1");
|
||||
}
|
||||
}
|
||||
|
||||
//#ifdef DEBUG
|
||||
// class debug_find_string
|
||||
// {
|
||||
|
@ -362,21 +429,21 @@ namespace ftype
|
|||
// }
|
||||
//#endif
|
||||
|
||||
process_synonims(p);
|
||||
add_layers(p);
|
||||
|
||||
// maybe an empty feature
|
||||
if (process_common_params(p, params) == 0)
|
||||
return;
|
||||
|
||||
process_synonims(p);
|
||||
|
||||
set<string> skipRootKeys;
|
||||
|
||||
set<int> skipRootKeys;
|
||||
do
|
||||
{
|
||||
path_type path;
|
||||
|
||||
// find first root object by key
|
||||
do_find_root_obj doFindRoot(skipRootKeys, path);
|
||||
(void)for_each_tag(p, doFindRoot);
|
||||
for_each_tag(p, doFindRoot);
|
||||
|
||||
if (path.empty())
|
||||
break;
|
||||
|
@ -409,9 +476,6 @@ namespace ftype
|
|||
if (feature::IsDrawableAny(t))
|
||||
params.AddType(t);
|
||||
|
||||
// save this root to skip, and try again
|
||||
skipRootKeys.insert(path[0]->GetName());
|
||||
|
||||
} while (true);
|
||||
|
||||
if (!params.house.IsEmpty())
|
||||
|
@ -428,6 +492,8 @@ namespace ftype
|
|||
params.AddType(types.Address());
|
||||
}
|
||||
}
|
||||
|
||||
params.FinishAddingTypes();
|
||||
}
|
||||
|
||||
uint32_t GetBoundaryType2()
|
||||
|
|
|
@ -1,13 +1,30 @@
|
|||
#include "xml_element.hpp"
|
||||
|
||||
#include "../coding/parse_xml.hpp"
|
||||
#include "../coding/reader.hpp"
|
||||
|
||||
#include "../std/cstdio.hpp"
|
||||
#include "../std/algorithm.hpp"
|
||||
#include "../std/limits.hpp"
|
||||
|
||||
|
||||
void XMLElement::Clear()
|
||||
{
|
||||
name.clear();
|
||||
attrs.clear();
|
||||
childs.clear();
|
||||
parent = 0;
|
||||
}
|
||||
|
||||
void XMLElement::AddKV(string const & k, string const & v)
|
||||
{
|
||||
childs.push_back(XMLElement());
|
||||
XMLElement & e = childs.back();
|
||||
|
||||
e.name = "tag";
|
||||
e.attrs["k"] = k;
|
||||
e.attrs["v"] = v;
|
||||
e.parent = this;
|
||||
}
|
||||
|
||||
bool BaseOSMParser::is_our_tag(string const & name)
|
||||
{
|
||||
return (find(m_tags.begin(), m_tags.end(), name) != m_tags.end());
|
||||
|
@ -76,9 +93,3 @@ void ParseXMLFromStdIn(BaseOSMParser & parser)
|
|||
StdinReader reader;
|
||||
(void)ParseXMLSequence(reader, parser);
|
||||
}
|
||||
|
||||
void ParseXMLFromFile(FileReader const & reader, BaseOSMParser & parser)
|
||||
{
|
||||
ReaderSource<FileReader> src(reader);
|
||||
CHECK(ParseXML(src, parser), ());
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
#include "../coding/file_reader.hpp"
|
||||
#include "../std/string.hpp"
|
||||
#include "../std/vector.hpp"
|
||||
#include "../std/map.hpp"
|
||||
|
||||
|
||||
struct XMLElement
|
||||
{
|
||||
string name;
|
||||
|
@ -11,13 +11,9 @@ struct XMLElement
|
|||
vector<XMLElement> childs;
|
||||
XMLElement * parent;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
name.clear();
|
||||
attrs.clear();
|
||||
childs.clear();
|
||||
parent = 0;
|
||||
}
|
||||
void Clear();
|
||||
|
||||
void AddKV(string const & k, string const & v);
|
||||
};
|
||||
|
||||
class BaseOSMParser
|
||||
|
@ -45,5 +41,3 @@ protected:
|
|||
};
|
||||
|
||||
void ParseXMLFromStdIn(BaseOSMParser & parser);
|
||||
|
||||
void ParseXMLFromFile(FileReader const & reader, BaseOSMParser & parser);
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
}
|
||||
catch (RootException const & e)
|
||||
{
|
||||
LOG(LINFO, ("Cannot add ", v[0], " file to benchmark: ", e.what()));
|
||||
LOG(LINFO, ("Can't add", v[0], "file to benchmark:", e.Msg()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ void ForEachBenchmarkRecord(ToDo & toDo)
|
|||
}
|
||||
catch (RootException const & e)
|
||||
{
|
||||
LOG(LERROR, ("Error reading benchmarks: ", e.what()));
|
||||
LOG(LERROR, ("Error reading benchmarks:", e.Msg()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue