- Writing and Reading of proto drawing rules.

- New rules file: drules_proto.txt
This commit is contained in:
vng 2011-11-14 22:44:13 +03:00 committed by Alex Zolotarev
parent 6f31774ce4
commit 6d4e795f01
8 changed files with 55771 additions and 52 deletions

55452
data/drules_proto.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -80,7 +80,10 @@ void ClassifObject::LoadPolicy::Serialize(string const & s)
// load drawing rule
drule::Key key;
key.fromString(s);
#ifndef USE_PROTO_STYLES
p->m_drawRule.push_back(key);
#endif
// mark as visible in rule's scale
p->m_visibility[key.m_scale] = true;

View file

@ -1,6 +1,7 @@
#include "classificator_loader.hpp"
#include "classificator.hpp"
#include "drawing_rules.hpp"
#include "drules_struct.pb.h"
#include "../../platform/platform.hpp"
@ -12,33 +13,26 @@
namespace classificator
{
void Read(ReaderType const & rules,
ReaderType const & classificator,
ReaderType const & visibility,
ReaderType const & types)
void ReadCommon(ReaderType const & classificator,
ReaderType const & visibility,
ReaderType const & types)
{
// LOG(LINFO, ("Reading drawing rules"));
ReaderPtrStream rulesS(rules);
drule::ReadRules(rulesS);
string buffer;
Classificator & c = classif();
c.Clear();
// LOG(LINFO, ("Reading classificator"));
//LOG(LINFO, ("Reading classificator"));
classificator.ReadAsString(buffer);
c.ReadClassificator(buffer);
// LOG(LINFO, ("Reading visibility"));
//LOG(LINFO, ("Reading visibility"));
visibility.ReadAsString(buffer);
c.ReadVisibility(buffer);
// LOG(LINFO, ("Reading types mapping"));
//LOG(LINFO, ("Reading types mapping"));
types.ReadAsString(buffer);
c.ReadTypesMapping(buffer);
// LOG(LINFO, ("Reading of classificator done"));
}
void ReadVisibility(string const & fPath)
@ -50,11 +44,25 @@ namespace classificator
void Load()
{
LOG(LINFO, ("Reading of classificator started"));
Platform & p = GetPlatform();
Read(p.GetReader("drawing_rules.bin"),
p.GetReader("classificator.txt"),
p.GetReader("visibility.txt"),
p.GetReader("types.txt"));
ReadCommon(p.GetReader("classificator.txt"),
p.GetReader("visibility.txt"),
p.GetReader("types.txt"));
//LOG(LINFO, ("Reading of drawing rules"));
#ifdef USE_PROTO_STYLES
// Load from protobuffer text file.
string buffer;
ReaderType(p.GetReader("drules_proto.txt")).ReadAsString(buffer);
drule::rules().LoadFromProto(buffer);
#else
ReaderPtrStream rulesS(p.GetReader("drawing_rules.bin"));
drule::ReadRules(rulesS);
#endif
LOG(LINFO, ("Reading of classificator done"));
}
}

View file

@ -9,10 +9,6 @@ namespace classificator
{
typedef ReaderPtr<Reader> ReaderType;
void Read(ReaderType const & rules,
ReaderType const & classificator,
ReaderType const & visibility,
ReaderType const & types);
void ReadVisibility(string const & fPath);
void Load();

View file

@ -45,13 +45,16 @@ namespace drule
{
bool operator() (drule::Key const & r1, drule::Key const & r2) const
{
if (r1.m_type == r2.m_type)
if (r1.m_scale == r2.m_scale)
{
// assume that unique algo leaves the first element (with max priority), others - go away
return (r1.m_priority > r2.m_priority);
if (r1.m_type == r2.m_type)
{
// assume that unique algo leaves the first element (with max priority), others - go away
return (r1.m_priority > r2.m_priority);
}
else return (r1.m_type < r2.m_type);
}
else
return (r1.m_type < r2.m_type);
else return (r1.m_scale < r2.m_scale);
}
};
@ -59,12 +62,16 @@ namespace drule
{
bool operator() (drule::Key const & r1, drule::Key const & r2) const
{
// many line and area rules - is ok, other rules - one is enough
// By VNG: Why many area styles ??? Did I miss something ???
if (r1.m_type == drule::line /*|| r1.m_type == drule::area*/)
return (r1 == r2);
else
return (r1.m_type == r2.m_type);
if (r1.m_scale == r2.m_scale)
{
// many line and area rules - is ok, other rules - one is enough
// By VNG: Why many area styles ??? Did I miss something ???
if (r1.m_type == drule::line /*|| r1.m_type == drule::area*/)
return (r1 == r2);
else
return (r1.m_type == r2.m_type);
}
else return false;
}
};

View file

@ -4,6 +4,8 @@
#include "../std/vector.hpp"
#define USE_PROTO_STYLES 1
namespace drule
{
class Key

View file

@ -1089,7 +1089,7 @@ namespace
static int32_t GetStoringAlpha(BaseRule const * pSrc)
{
// 255 is default value for BaseRule - completely visible
// when storing alpha, 0 - is default value
// when storing alpha, 0 - is default value for visible
int32_t r = 255 - pSrc->GetAlpha();
r = r << 24;
return r;
@ -1104,7 +1104,7 @@ namespace
return (pSrc->GetFillColor() | GetStoringAlpha(pSrc));
}
static void Convert(BaseRule const * pSrc, LineRuleProto * pDest)
static void ConvertImpl(BaseRule const * pSrc, LineRuleProto * pDest)
{
pDest->set_width(pSrc->GetWidth());
pDest->set_color(GetColor(pSrc));
@ -1119,21 +1119,21 @@ namespace
}
}
static void Convert(BaseRule const * pSrc, AreaRuleProto * pDest)
static void ConvertImpl(BaseRule const * pSrc, AreaRuleProto * pDest)
{
pDest->set_color(GetFillColor(pSrc));
if (pSrc->GetColor() != -1)
Convert(pSrc, pDest->mutable_border());
ConvertImpl(pSrc, pDest->mutable_border());
}
static void Convert(BaseRule const * pSrc, SymbolRuleProto * pDest)
static void ConvertImpl(BaseRule const * pSrc, SymbolRuleProto * pDest)
{
string s;
pSrc->GetSymbol(s);
pDest->set_name(s);
}
static void Convert(BaseRule const * pSrc, CaptionRuleProto * pDest)
static void ConvertImpl(BaseRule const * pSrc, CaptionRuleProto * pDest)
{
pDest->set_height(pSrc->GetTextHeight());
@ -1143,12 +1143,19 @@ namespace
pDest->set_stroke_color(GetColor(pSrc));
}
static void Convert(BaseRule const * pSrc, CircleRuleProto * pDest)
static void ConvertImpl(BaseRule const * pSrc, CircleRuleProto * pDest)
{
pDest->set_radius(pSrc->GetRadius());
pDest->set_color(GetFillColor(pSrc));
}
template <class T>
static void Convert(BaseRule const * pSrc, int priority, T * pDest)
{
pDest->set_priority(priority);
ConvertImpl(pSrc, pDest);
}
vector<string> m_parents;
string GetFullName(ClassifObject const & o) const
@ -1179,32 +1186,38 @@ namespace
ClassifElementProto * pCE = m_cont.add_cont();
pCE->set_name(GetFullName(o));
DrawElementProto * pDE = 0;
for (size_t i = 0; i < keys.size(); ++i)
{
// skip unnecessary trash
if (keys[i].m_type > circle)
continue;
DrawElementProto * pDE = pCE->add_element();
pDE->set_scale(keys[i].m_scale);
if (pDE == 0 || pDE->scale() != keys[i].m_scale)
{
pDE = pCE->add_element();
pDE->set_scale(keys[i].m_scale);
}
BaseRule const * pRule = m_rules.Find(keys[i]);
if (pRule->GetAlpha() == 0) continue;
switch (keys[i].m_type)
{
case line:
Convert(pRule, pDE->add_lines());
Convert(pRule, keys[i].m_priority, pDE->add_lines());
break;
case area:
Convert(pRule, pDE->mutable_area());
Convert(pRule, keys[i].m_priority, pDE->mutable_area());
break;
case symbol:
Convert(pRule, pDE->mutable_symbol());
Convert(pRule, keys[i].m_priority, pDE->mutable_symbol());
break;
case caption:
Convert(pRule, pDE->mutable_caption());
Convert(pRule, keys[i].m_priority, pDE->mutable_caption());
break;
case circle:
Convert(pRule, pDE->mutable_circle());
Convert(pRule, keys[i].m_priority, pDE->mutable_circle());
break;
}
}
@ -1226,4 +1239,232 @@ void ConvertToProtocolBuffers(string & res)
google::protobuf::TextFormat::PrintToString(cont, &res);
}
namespace
{
namespace proto_rules
{
unsigned char AlphaFromColor(int c)
{
c = c >> 24;
return (255 - c);
}
void GetPattern(LineRuleProto const & ln, vector<double> & v, double & offset)
{
offset = 0.0;
if (ln.has_dashdot())
{
DashDotProto const & dd = ln.dashdot();
int const count = dd.dd_size();
v.reserve(count);
for (int i = 0; i < count; ++i)
v.push_back(dd.dd(i));
}
}
class MyBase : public BaseRule
{
public:
virtual bool IsEqual(BaseRule const *) const { return false; }
virtual void Read(ReaderPtrStream &) {}
virtual void Write(FileWriterStream &) const {}
};
class Line : public MyBase
{
LineRuleProto m_line;
public:
Line(LineRuleProto const & r) : m_line(r) {}
virtual int GetColor() const
{
return m_line.color();
}
virtual unsigned char GetAlpha() const
{
return AlphaFromColor(GetColor());
}
virtual double GetWidth() const
{
return m_line.width();
}
virtual void GetPattern(vector<double> & v, double & offset) const
{
proto_rules::GetPattern(m_line, v, offset);
}
};
class Area : public MyBase
{
AreaRuleProto m_area;
public:
Area(AreaRuleProto const & r) : m_area(r) {}
virtual int GetColor() const
{
if (m_area.has_border())
return m_area.border().color();
return -1;
}
virtual int GetFillColor() const
{
return m_area.color();
}
virtual unsigned char GetAlpha () const
{
return AlphaFromColor(GetFillColor());
}
virtual double GetWidth() const
{
if (m_area.has_border())
return m_area.border().width();
return -1;
}
virtual void GetPattern(vector<double> & v, double & offset) const
{
if (m_area.has_border())
proto_rules::GetPattern(m_area.border(), v, offset);
}
};
class Symbol : public MyBase
{
SymbolRuleProto m_symbol;
public:
Symbol(SymbolRuleProto const & r) : m_symbol(r) {}
virtual void GetSymbol(string & name) const
{
name = m_symbol.name();
}
};
class Caption : public MyBase
{
CaptionRuleProto m_caption;
public:
Caption(CaptionRuleProto const & r) : m_caption(r) {}
virtual int GetColor() const
{
if (m_caption.has_stroke_color())
return m_caption.stroke_color();
return -1;
}
virtual int GetFillColor() const
{
return m_caption.color();
}
virtual double GetTextHeight() const
{
return m_caption.height();
}
virtual unsigned char GetAlpha () const
{
return AlphaFromColor(GetFillColor());
}
};
class Circle : public MyBase
{
CircleRuleProto m_circle;
public:
Circle(CircleRuleProto const & r) : m_circle(r) {}
virtual int GetFillColor() const
{
return m_circle.color();
}
virtual double GetRadius() const
{
return m_circle.radius();
}
};
}
class DoSetIndex
{
public:
ContainerProto m_cont;
private:
vector<string> m_names;
int FindIndex() const
{
string name = m_names[0];
for (size_t i = 1; i < m_names.size(); ++i)
name = name + "-" + m_names[i];
/// @todo Make binary search (need iterator on ProtobufRepeatedPtrField).
for (int i = 0; i < m_cont.cont_size(); ++i)
if (m_cont.cont(i).name() == name)
return i;
return -1;
}
RulesHolder & m_holder;
template <class TRule, class TProtoRule>
void AddRule(ClassifObject * p, int scale, rule_type_t type, TProtoRule const & rule)
{
size_t const i = m_holder.AddRule(scale, type, new TRule(rule));
Key k(scale, type, i);
k.SetPriority(rule.priority());
p->AddDrawRule(k);
}
public:
DoSetIndex(RulesHolder & holder)
: m_holder(holder) {}
void operator() (ClassifObject * p)
{
m_names.push_back(p->GetName());
int const i = FindIndex();
if (i != -1)
{
ClassifElementProto const & ce = m_cont.cont(i);
for (int j = 0; j < ce.element_size(); ++j)
{
DrawElementProto const & de = ce.element(j);
using namespace proto_rules;
for (size_t k = 0; k < de.lines_size(); ++k)
AddRule<Line>(p, de.scale(), line, de.lines(k));
if (de.has_area())
AddRule<Area>(p, de.scale(), area, de.area());
if (de.has_symbol())
AddRule<Symbol>(p, de.scale(), symbol, de.symbol());
if (de.has_caption())
AddRule<Caption>(p, de.scale(), caption, de.caption());
if (de.has_circle())
AddRule<Circle>(p, de.scale(), circle, de.circle());
}
}
p->ForEachObject(bind<void>(ref(*this), _1));
m_names.pop_back();
}
};
}
void RulesHolder::LoadFromProto(string const & buffer)
{
Clean();
DoSetIndex doSet(*this);
google::protobuf::TextFormat::ParseFromString(buffer, &doSet.m_cont);
classif().GetMutableRoot()->ForEachObject(bind<void>(ref(doSet), _1));
}
}

View file

@ -2,12 +2,13 @@
#include "drawing_rule_def.hpp"
#include "../base/base.hpp"
#include "../base/buffer_vector.hpp"
#include "../std/map.hpp"
#include "../std/vector.hpp"
#include "../std/array.hpp"
#include "../std/string.hpp"
#include "../base/buffer_vector.hpp"
class ReaderPtrStream;
class FileWriterStream;
@ -18,9 +19,10 @@ namespace drule
class BaseRule
{
string m_class;
string m_class; // for debug use only, can be removed
mutable buffer_vector<uint32_t, 8> m_id1, m_id2;
char m_type;
char m_type; // obsolete for new styles, can be removed
public:
static uint32_t const empty_id = 0xFFFFFFFF;
@ -78,8 +80,15 @@ namespace drule
void SetClassName(string const & cl) { m_class = cl; }
void SetType(char type) { m_type = type; }
char GetType() const { return m_type; }
inline char GetType() const
{
#ifdef USE_PROTO_STYLES
// Assume that they all are acceptable.
return (node | way);
#else
return m_type;
#endif
}
bool IsEqualBase(BaseRule const * p) const { return (m_type == p->m_type); }
void ReadBase(ReaderPtrStream & ar);
@ -92,7 +101,7 @@ namespace drule
/// @name This functions can tell us about the type of rule.
//@{
virtual int GetColor() const { return -1; } ///< path "line" color
virtual int GetFillColor()const { return -1; } ///< fill "area" color
virtual int GetFillColor() const { return -1; } ///< fill "area" color
virtual double GetTextHeight() const { return -1.0; } ///< text height of "caption"
//@}
@ -148,6 +157,7 @@ namespace drule
void Read(ReaderPtrStream & s);
void Write(FileWriterStream & s);
void LoadFromProto(string const & buffer);
template <class ToDo> void ForEachRule(ToDo toDo)
{