[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:
vng 2014-09-09 02:29:51 +03:00 committed by Alex Zolotarev
parent cf856a71bf
commit bd06c5762a
5 changed files with 263 additions and 56 deletions

View file

@ -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, ());
}
}

View file

@ -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()

View file

@ -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), ());
}

View file

@ -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);

View file

@ -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()));
}
}