Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
385ca5b5b5
87 changed files with 1982 additions and 1730 deletions
|
@ -40,15 +40,15 @@
|
|||
using namespace mapnik;
|
||||
|
||||
/* Notes:
|
||||
Overriding functions in inherited classes:
|
||||
boost.python documentation doesn't really tell you how to do it.
|
||||
But this helps:
|
||||
http://www.gamedev.net/topic/446225-inheritance-in-boostpython/
|
||||
Overriding functions in inherited classes:
|
||||
boost.python documentation doesn't really tell you how to do it.
|
||||
But this helps:
|
||||
http://www.gamedev.net/topic/446225-inheritance-in-boostpython/
|
||||
|
||||
register_ptr_to_python is required for wrapped classes, but not for unwrapped.
|
||||
register_ptr_to_python is required for wrapped classes, but not for unwrapped.
|
||||
|
||||
Functions don't have to be members of the class, but can also be
|
||||
normal functions taking a ref to the class as first parameter.
|
||||
Functions don't have to be members of the class, but can also be
|
||||
normal functions taking a ref to the class as first parameter.
|
||||
*/
|
||||
|
||||
namespace {
|
||||
|
@ -261,7 +261,7 @@ struct TextPlacementsWrap: text_placements, wrapper<text_placements>
|
|||
struct TextPlacementInfoWrap: text_placement_info, wrapper<text_placement_info>
|
||||
{
|
||||
TextPlacementInfoWrap(text_placements const* parent,
|
||||
double scale_factor_)
|
||||
double scale_factor_)
|
||||
: text_placement_info(parent, scale_factor_)
|
||||
{
|
||||
|
||||
|
@ -339,7 +339,7 @@ void export_text_placement()
|
|||
;
|
||||
|
||||
class_<text_symbolizer>("TextSymbolizer",
|
||||
init<>())
|
||||
init<>())
|
||||
.def(init<expression_ptr, std::string const&, unsigned, color const&>())
|
||||
.add_property("placements",
|
||||
&text_symbolizer::get_placement_options,
|
||||
|
@ -357,7 +357,7 @@ void export_text_placement()
|
|||
|
||||
|
||||
class_with_converter<text_symbolizer_properties>
|
||||
("TextSymbolizerProperties")
|
||||
("TextSymbolizerProperties")
|
||||
.def_readwrite_convert("label_placement", &text_symbolizer_properties::label_placement)
|
||||
.def_readwrite_convert("horizontal_alignment", &text_symbolizer_properties::halign)
|
||||
.def_readwrite_convert("justify_alignment", &text_symbolizer_properties::jalign)
|
||||
|
@ -381,15 +381,15 @@ void export_text_placement()
|
|||
.add_property ("format_tree",
|
||||
&text_symbolizer_properties::format_tree,
|
||||
&text_symbolizer_properties::set_format_tree);
|
||||
/* from_xml, to_xml operate on mapnik's internal XML tree and don't make sense in python.
|
||||
add_expressions isn't useful in python either. The result is only needed by
|
||||
attribute_collector (which isn't exposed in python) and
|
||||
it just calls add_expressions of the associated formatting tree.
|
||||
set_old_style expression is just a compatibility wrapper and doesn't need to be exposed in python. */
|
||||
;
|
||||
/* from_xml, to_xml operate on mapnik's internal XML tree and don't make sense in python.
|
||||
add_expressions isn't useful in python either. The result is only needed by
|
||||
attribute_collector (which isn't exposed in python) and
|
||||
it just calls add_expressions of the associated formatting tree.
|
||||
set_old_style expression is just a compatibility wrapper and doesn't need to be exposed in python. */
|
||||
;
|
||||
|
||||
class_<char_properties>
|
||||
("CharProperties")
|
||||
("CharProperties")
|
||||
.def(init<char_properties const&>()) //Copy constructor
|
||||
.def_readwrite("face_name", &char_properties::face_name)
|
||||
.def_readwrite("fontset", &char_properties::fontset)
|
||||
|
@ -407,9 +407,9 @@ void export_text_placement()
|
|||
;
|
||||
|
||||
class_<TextPlacementsWrap,
|
||||
boost::shared_ptr<TextPlacementsWrap>,
|
||||
boost::noncopyable>
|
||||
("TextPlacements")
|
||||
boost::shared_ptr<TextPlacementsWrap>,
|
||||
boost::noncopyable>
|
||||
("TextPlacements")
|
||||
.def_readwrite("defaults", &text_placements::defaults)
|
||||
.def("get_placement_info", pure_virtual(&text_placements::get_placement_info))
|
||||
/* TODO: add_expressions() */
|
||||
|
@ -417,10 +417,10 @@ void export_text_placement()
|
|||
register_ptr_to_python<boost::shared_ptr<text_placements> >();
|
||||
|
||||
class_<TextPlacementInfoWrap,
|
||||
boost::shared_ptr<TextPlacementInfoWrap>,
|
||||
boost::noncopyable>
|
||||
("TextPlacementInfo",
|
||||
init<text_placements const*, double>())
|
||||
boost::shared_ptr<TextPlacementInfoWrap>,
|
||||
boost::noncopyable>
|
||||
("TextPlacementInfo",
|
||||
init<text_placements const*, double>())
|
||||
.def("next", pure_virtual(&text_placement_info::next))
|
||||
.def("get_actual_label_spacing", &text_placement_info::get_actual_label_spacing)
|
||||
.def("get_actual_minimum_distance", &text_placement_info::get_actual_minimum_distance)
|
||||
|
@ -432,27 +432,27 @@ void export_text_placement()
|
|||
|
||||
|
||||
class_<processed_text,
|
||||
boost::shared_ptr<processed_text>,
|
||||
boost::noncopyable>
|
||||
("ProcessedText", no_init)
|
||||
boost::shared_ptr<processed_text>,
|
||||
boost::noncopyable>
|
||||
("ProcessedText", no_init)
|
||||
.def("push_back", &processed_text::push_back)
|
||||
.def("clear", &processed_text::clear)
|
||||
;
|
||||
|
||||
|
||||
class_<expression_set,
|
||||
boost::shared_ptr<expression_set>,
|
||||
boost::noncopyable>
|
||||
("ExpressionSet")
|
||||
boost::shared_ptr<expression_set>,
|
||||
boost::noncopyable>
|
||||
("ExpressionSet")
|
||||
.def("insert", &insert_expression);
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
//TODO: Python namespace
|
||||
class_<NodeWrap,
|
||||
boost::shared_ptr<NodeWrap>,
|
||||
boost::noncopyable>
|
||||
("FormattingNode")
|
||||
boost::shared_ptr<NodeWrap>,
|
||||
boost::noncopyable>
|
||||
("FormattingNode")
|
||||
.def("apply", pure_virtual(&formatting::node::apply))
|
||||
.def("add_expressions",
|
||||
&formatting::node::add_expressions,
|
||||
|
@ -462,10 +462,10 @@ void export_text_placement()
|
|||
|
||||
|
||||
class_<TextNodeWrap,
|
||||
boost::shared_ptr<TextNodeWrap>,
|
||||
bases<formatting::node>,
|
||||
boost::noncopyable>
|
||||
("FormattingText", init<expression_ptr>())
|
||||
boost::shared_ptr<TextNodeWrap>,
|
||||
bases<formatting::node>,
|
||||
boost::noncopyable>
|
||||
("FormattingText", init<expression_ptr>())
|
||||
.def(init<std::string>())
|
||||
.def("apply", &formatting::text_node::apply, &TextNodeWrap::default_apply)
|
||||
.add_property("text",
|
||||
|
@ -476,10 +476,10 @@ void export_text_placement()
|
|||
|
||||
|
||||
class_with_converter<FormatNodeWrap,
|
||||
boost::shared_ptr<FormatNodeWrap>,
|
||||
bases<formatting::node>,
|
||||
boost::noncopyable>
|
||||
("FormattingFormat")
|
||||
boost::shared_ptr<FormatNodeWrap>,
|
||||
bases<formatting::node>,
|
||||
boost::noncopyable>
|
||||
("FormattingFormat")
|
||||
.def_readwrite_convert("text_size", &formatting::format_node::text_size)
|
||||
.def_readwrite_convert("face_name", &formatting::format_node::face_name)
|
||||
.def_readwrite_convert("character_spacing", &formatting::format_node::character_spacing)
|
||||
|
@ -499,10 +499,10 @@ void export_text_placement()
|
|||
register_ptr_to_python<boost::shared_ptr<formatting::format_node> >();
|
||||
|
||||
class_<ListNodeWrap,
|
||||
boost::shared_ptr<ListNodeWrap>,
|
||||
bases<formatting::node>,
|
||||
boost::noncopyable>
|
||||
("FormattingList", init<>())
|
||||
boost::shared_ptr<ListNodeWrap>,
|
||||
bases<formatting::node>,
|
||||
boost::noncopyable>
|
||||
("FormattingList", init<>())
|
||||
.def(init<list>())
|
||||
.def("append", &formatting::list_node::push_back)
|
||||
.def("apply", &formatting::list_node::apply, &ListNodeWrap::default_apply)
|
||||
|
@ -510,15 +510,15 @@ void export_text_placement()
|
|||
.def("__getitem__", &ListNodeWrap::get_item)
|
||||
.def("__setitem__", &ListNodeWrap::set_item)
|
||||
.def("append", &ListNodeWrap::append)
|
||||
;
|
||||
;
|
||||
|
||||
register_ptr_to_python<boost::shared_ptr<formatting::list_node> >();
|
||||
|
||||
class_<ExprFormatWrap,
|
||||
boost::shared_ptr<ExprFormatWrap>,
|
||||
bases<formatting::node>,
|
||||
boost::noncopyable>
|
||||
("FormattingExpressionFormat")
|
||||
boost::shared_ptr<ExprFormatWrap>,
|
||||
bases<formatting::node>,
|
||||
boost::noncopyable>
|
||||
("FormattingExpressionFormat")
|
||||
.def_readwrite("text_size", &formatting::expression_format::text_size)
|
||||
.def_readwrite("face_name", &formatting::expression_format::face_name)
|
||||
.def_readwrite("character_spacing", &formatting::expression_format::character_spacing)
|
||||
|
|
|
@ -29,8 +29,8 @@ namespace mapnik {
|
|||
class python_thread
|
||||
{
|
||||
/* Docs:
|
||||
http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock
|
||||
*/
|
||||
http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock
|
||||
*/
|
||||
public:
|
||||
static void unblock()
|
||||
{
|
||||
|
@ -38,8 +38,8 @@ public:
|
|||
if (state.get())
|
||||
{
|
||||
std::cerr << "ERROR: Python threads are already unblocked. "
|
||||
"Unblocking again will loose the current state and "
|
||||
"might crash later. Aborting!\n";
|
||||
"Unblocking again will loose the current state and "
|
||||
"might crash later. Aborting!\n";
|
||||
abort(); //This is a serious error and can't be handled in any other sane way
|
||||
}
|
||||
#endif
|
||||
|
@ -59,9 +59,9 @@ public:
|
|||
if (thread_support && !state.get())
|
||||
{
|
||||
std::cerr << "ERROR: Trying to restore python thread state, "
|
||||
"but no state is saved. Can't continue and also "
|
||||
"can't raise an exception because the python "
|
||||
"interpreter might be non-function. Aborting!\n";
|
||||
"but no state is saved. Can't continue and also "
|
||||
"can't raise an exception because the python "
|
||||
"interpreter might be non-function. Aborting!\n";
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -102,8 +102,8 @@ struct python_optional : public boost::noncopyable
|
|||
|
||||
/** This class works around a bug in boost python.
|
||||
|
||||
See http://osdir.com/ml/python.c++/2003-11/msg00158.html
|
||||
*/
|
||||
See http://osdir.com/ml/python.c++/2003-11/msg00158.html
|
||||
*/
|
||||
template <typename T, typename X1 = boost::python::detail::not_specified, typename X2 = boost::python::detail::not_specified, typename X3 = boost::python::detail::not_specified>
|
||||
class class_with_converter : public boost::python::class_<T, X1, X2, X3>
|
||||
{
|
||||
|
@ -131,8 +131,8 @@ public:
|
|||
self& def_readwrite_convert(char const* name, D const& d, char const* doc=0)
|
||||
{
|
||||
this->add_property(name,
|
||||
boost::python::make_getter(d, boost::python::return_value_policy<boost::python::return_by_value>()),
|
||||
boost::python::make_setter(d, boost::python::default_call_policies()));
|
||||
boost::python::make_getter(d, boost::python::return_value_policy<boost::python::return_by_value>()),
|
||||
boost::python::make_setter(d, boost::python::default_call_policies()));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
|
90
include/mapnik/boolean.hpp
Normal file
90
include/mapnik/boolean.hpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef MAPNIK_BOOLEAN_HPP
|
||||
#define MAPNIK_BOOLEAN_HPP
|
||||
#include <istream>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
/** Helper for class bool */
|
||||
class boolean {
|
||||
public:
|
||||
boolean(): b_(false) {}
|
||||
boolean(bool b) : b_(b) {}
|
||||
boolean(boolean const& b) : b_(b.b_) {}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
boolean & operator = (boolean const& other)
|
||||
{
|
||||
b_ = other.b_;
|
||||
return * this;
|
||||
}
|
||||
boolean & operator = (bool other)
|
||||
{
|
||||
b_ = other;
|
||||
return * this;
|
||||
}
|
||||
private:
|
||||
bool b_;
|
||||
};
|
||||
|
||||
/** Special stream input operator for boolean values */
|
||||
template <typename charT, typename traits>
|
||||
std::basic_istream<charT, traits> &
|
||||
operator >> ( std::basic_istream<charT, traits> & s, boolean & b )
|
||||
{
|
||||
std::string word;
|
||||
s >> word;
|
||||
if ( s )
|
||||
{
|
||||
if ( word == "true" || word == "yes" || word == "on" ||
|
||||
word == "1")
|
||||
{
|
||||
b = true;
|
||||
}
|
||||
else if ( word == "false" || word == "no" || word == "off" ||
|
||||
word == "0")
|
||||
{
|
||||
b = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setstate( std::ios::failbit );
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename charT, typename traits>
|
||||
std::basic_ostream<charT, traits> &
|
||||
operator << ( std::basic_ostream<charT, traits> & s, boolean const& b )
|
||||
{
|
||||
s << ( b ? "true" : "false" );
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_BOOLEAN_HPP
|
|
@ -137,6 +137,14 @@ public:
|
|||
std::string to_hex_string() const;
|
||||
};
|
||||
|
||||
template <typename charT, typename traits>
|
||||
std::basic_ostream<charT, traits> &
|
||||
operator << ( std::basic_ostream<charT, traits> & s, mapnik::color const& c )
|
||||
{
|
||||
std::string hex_string( c.to_string() );
|
||||
s << hex_string;
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -25,134 +25,26 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// boost 1.41 -> 1.44 compatibility, to be removed in mapnik 2.1 (dane)
|
||||
#if BOOST_VERSION >= 104500
|
||||
#include <mapnik/css_color_grammar.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
class color;
|
||||
|
||||
template <typename Iterator> struct css_color_grammar;
|
||||
class MAPNIK_DECL color_factory : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
static void init_from_string(color & c, std::string const& css_color)
|
||||
{
|
||||
typedef std::string::const_iterator iterator_type;
|
||||
typedef mapnik::css_color_grammar<iterator_type> css_color_grammar;
|
||||
|
||||
css_color_grammar g;
|
||||
iterator_type first = css_color.begin();
|
||||
iterator_type last = css_color.end();
|
||||
bool result =
|
||||
boost::spirit::qi::phrase_parse(first,
|
||||
last,
|
||||
g,
|
||||
boost::spirit::ascii::space,
|
||||
c);
|
||||
if (!result)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse color value: ") +
|
||||
"Expected a CSS color, but got '" + css_color + "'");
|
||||
}
|
||||
}
|
||||
static void init_from_string(color & c, std::string const& css_color);
|
||||
|
||||
static bool parse_from_string(color & c, std::string const& css_color,
|
||||
mapnik::css_color_grammar<std::string::const_iterator> const& g)
|
||||
{
|
||||
std::string::const_iterator first = css_color.begin();
|
||||
std::string::const_iterator last = css_color.end();
|
||||
bool result =
|
||||
boost::spirit::qi::phrase_parse(first,
|
||||
last,
|
||||
g,
|
||||
boost::spirit::ascii::space,
|
||||
c);
|
||||
return result && (first == last);
|
||||
}
|
||||
mapnik::css_color_grammar<std::string::const_iterator> const& g);
|
||||
|
||||
static color from_string(std::string const& css_color)
|
||||
{
|
||||
color c;
|
||||
init_from_string(c,css_color);
|
||||
return c;
|
||||
}
|
||||
static color from_string(std::string const& css_color);
|
||||
};
|
||||
}
|
||||
|
||||
#else
|
||||
#include <mapnik/css_color_grammar_deprecated.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
class MAPNIK_DECL color_factory : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
static bool parse_from_string(color & c, std::string const& css_color,
|
||||
mapnik::css_color_grammar<std::string::const_iterator> const& g)
|
||||
{
|
||||
std::string::const_iterator first = css_color.begin();
|
||||
std::string::const_iterator last = css_color.end();
|
||||
mapnik::css css_;
|
||||
bool result =
|
||||
boost::spirit::qi::phrase_parse(first,
|
||||
last,
|
||||
g,
|
||||
boost::spirit::ascii::space,
|
||||
css_);
|
||||
if (result && (first == last))
|
||||
{
|
||||
c.set_red(css_.r);
|
||||
c.set_green(css_.g);
|
||||
c.set_blue(css_.b);
|
||||
c.set_alpha(css_.a);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void init_from_string(color & c, std::string const& css_color)
|
||||
{
|
||||
typedef std::string::const_iterator iterator_type;
|
||||
typedef mapnik::css_color_grammar<iterator_type> css_color_grammar;
|
||||
|
||||
css_color_grammar g;
|
||||
iterator_type first = css_color.begin();
|
||||
iterator_type last = css_color.end();
|
||||
mapnik::css css_;
|
||||
bool result =
|
||||
boost::spirit::qi::phrase_parse(first,
|
||||
last,
|
||||
g,
|
||||
boost::spirit::ascii::space,
|
||||
css_);
|
||||
if (!result)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse color value: ") +
|
||||
"Expected a CSS color, but got '" + css_color + "'");
|
||||
}
|
||||
c.set_red(css_.r);
|
||||
c.set_green(css_.g);
|
||||
c.set_blue(css_.b);
|
||||
c.set_alpha(css_.a);
|
||||
}
|
||||
|
||||
static color from_string(std::string const& css_color)
|
||||
{
|
||||
color c;
|
||||
init_from_string(c,css_color);
|
||||
return c;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MAPNIK_COLOR_FACTORY_HPP
|
||||
|
|
|
@ -28,31 +28,28 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
class xml_node;
|
||||
class config_error : public std::exception
|
||||
{
|
||||
public:
|
||||
config_error():
|
||||
what_() {}
|
||||
|
||||
config_error( std::string const& what ) :
|
||||
what_( what )
|
||||
{
|
||||
}
|
||||
config_error(std::string const& what);
|
||||
config_error(std::string const& what, xml_node const& node);
|
||||
config_error(std::string const& what, unsigned line_number, std::string const& filename);
|
||||
virtual ~config_error() throw() {}
|
||||
|
||||
virtual const char * what() const throw()
|
||||
{
|
||||
return what_.c_str();
|
||||
}
|
||||
|
||||
void append_context(std::string const& ctx) const
|
||||
{
|
||||
what_ += " " + ctx;
|
||||
}
|
||||
virtual const char * what() const throw();
|
||||
|
||||
void append_context(const std::string & ctx) const;
|
||||
void append_context(const std::string & ctx, xml_node const& node) const;
|
||||
void append_context(xml_node const& node) const;
|
||||
protected:
|
||||
mutable std::string what_;
|
||||
mutable unsigned line_number_;
|
||||
mutable std::string file_;
|
||||
mutable std::string node_name_;
|
||||
mutable std::string msg_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_CONFIG_ERROR_HPP
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/expression_node.hpp>
|
||||
#include <mapnik/expression_grammar.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
|
@ -35,6 +34,7 @@ namespace mapnik
|
|||
{
|
||||
|
||||
typedef boost::shared_ptr<expr_node> expression_ptr;
|
||||
template <typename Iterator> struct expression_grammar;
|
||||
|
||||
class expression_factory
|
||||
{
|
||||
|
|
|
@ -99,11 +99,11 @@ public:
|
|||
|
||||
feature_impl(context_ptr const& ctx, int id)
|
||||
: id_(id),
|
||||
ctx_(ctx),
|
||||
data_(ctx_->mapping_.size()),
|
||||
geom_cont_(),
|
||||
raster_()
|
||||
{}
|
||||
ctx_(ctx),
|
||||
data_(ctx_->mapping_.size()),
|
||||
geom_cont_(),
|
||||
raster_()
|
||||
{}
|
||||
|
||||
inline int id() const { return id_;}
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ class MAPNIK_DECL font_face_set : private boost::noncopyable
|
|||
public:
|
||||
font_face_set(void)
|
||||
: faces_(),
|
||||
dimension_cache_() {}
|
||||
dimension_cache_() {}
|
||||
|
||||
void add(face_ptr face)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace mapnik {
|
|||
|
||||
typedef std::set<expression_ptr> expression_set;
|
||||
class processed_text;
|
||||
class xml_node;
|
||||
struct char_properties;
|
||||
|
||||
namespace formatting {
|
||||
|
@ -48,7 +49,7 @@ class node
|
|||
public:
|
||||
virtual ~node() {}
|
||||
virtual void to_xml(boost::property_tree::ptree &xml) const;
|
||||
static node_ptr from_xml(boost::property_tree::ptree const& xml);
|
||||
static node_ptr from_xml(xml_node const& xml);
|
||||
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const = 0;
|
||||
virtual void add_expressions(expression_set &output) const;
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace formatting {
|
|||
class expression_format: public node {
|
||||
public:
|
||||
void to_xml(boost::property_tree::ptree &xml) const;
|
||||
static node_ptr from_xml(boost::property_tree::ptree const& xml);
|
||||
static node_ptr from_xml(xml_node const& xml);
|
||||
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const;
|
||||
virtual void add_expressions(expression_set &output) const;
|
||||
|
||||
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
private:
|
||||
node_ptr child_;
|
||||
static expression_ptr get_expression(boost::property_tree::ptree const& xml, std::string name);
|
||||
static expression_ptr get_expression(xml_node const& xml, std::string name);
|
||||
};
|
||||
} //ns formatting
|
||||
} //ns mapnik
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace formatting {
|
|||
class format_node: public node {
|
||||
public:
|
||||
void to_xml(boost::property_tree::ptree &xml) const;
|
||||
static node_ptr from_xml(boost::property_tree::ptree const& xml);
|
||||
static node_ptr from_xml(xml_node const& xml);
|
||||
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const;
|
||||
virtual void add_expressions(expression_set &output) const;
|
||||
|
||||
|
|
|
@ -38,16 +38,16 @@ namespace mapnik
|
|||
namespace formatting
|
||||
{
|
||||
|
||||
typedef node_ptr (*from_xml_function_ptr)(boost::property_tree::ptree const& xml);
|
||||
typedef node_ptr (*from_xml_function_ptr)(xml_node const& xml);
|
||||
|
||||
class registry : public singleton<registry, CreateStatic>,
|
||||
private boost::noncopyable
|
||||
private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
registry();
|
||||
~registry() {}
|
||||
void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false);
|
||||
node_ptr from_xml(std::string name, boost::property_tree::ptree const& xml);
|
||||
node_ptr from_xml(xml_node const& xml);
|
||||
private:
|
||||
std::map<std::string, from_xml_function_ptr> map_;
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
text_node(expression_ptr text): node(), text_(text) {}
|
||||
text_node(std::string text): node(), text_(parse_expression(text)) {}
|
||||
void to_xml(boost::property_tree::ptree &xml) const;
|
||||
static node_ptr from_xml(boost::property_tree::ptree const& xml);
|
||||
static node_ptr from_xml(xml_node const& xml);
|
||||
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const;
|
||||
virtual void add_expressions(expression_set &output) const;
|
||||
|
||||
|
|
|
@ -1,26 +1,34 @@
|
|||
#ifndef DUMP_XML_HPP
|
||||
#define DUMP_XML_HPP
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
|
||||
/* Debug dump ptree XML representation.
|
||||
*/
|
||||
void dump_xml(boost::property_tree::ptree const& xml, unsigned level=0)
|
||||
*/
|
||||
void dump_xml(xml_node const& xml, unsigned level=0)
|
||||
{
|
||||
std::string indent;
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i=0; i<level; i++)
|
||||
{
|
||||
indent += " ";
|
||||
}
|
||||
if (xml.data().length()) std::cout << indent << "data: '" << xml.data() << "'\n";
|
||||
boost::property_tree::ptree::const_iterator itr = xml.begin();
|
||||
boost::property_tree::ptree::const_iterator end = xml.end();
|
||||
xml_node::attribute_map const& attr = xml.get_attributes();
|
||||
std::cerr << indent <<"[" << xml.name();
|
||||
xml_node::attribute_map::const_iterator aitr = attr.begin();
|
||||
xml_node::attribute_map::const_iterator aend = attr.end();
|
||||
for (;aitr!=aend; aitr++)
|
||||
{
|
||||
std::cerr << " (" << aitr->first << ", " << aitr->second.value << ", " << aitr->second.processed << ")";
|
||||
}
|
||||
std::cerr << "]" << "\n";
|
||||
if (xml.is_text()) std::cerr << indent << "text: '" << xml.text() << "'\n";
|
||||
xml_node::const_iterator itr = xml.begin();
|
||||
xml_node::const_iterator end = xml.end();
|
||||
for (; itr!=end; itr++)
|
||||
{
|
||||
std::cout << indent <<"[" << itr->first << "]" << "\n";
|
||||
dump_xml(itr->second, level+1);
|
||||
std::cout << indent << "[/" << itr->first << "]" << "\n";
|
||||
dump_xml(*itr, level+1);
|
||||
}
|
||||
std::cerr << indent << "[/" << xml.name() << "]" << "\n";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
class xml_node;
|
||||
|
||||
/**
|
||||
* Creates a metawriter with the properties specified in the property
|
||||
|
@ -37,7 +38,7 @@ namespace mapnik {
|
|||
* metawriters, but should provide an easy point to make them a
|
||||
* proper factory method if this is wanted in the future.
|
||||
*/
|
||||
metawriter_ptr metawriter_create(const boost::property_tree::ptree &pt);
|
||||
metawriter_ptr metawriter_create(xml_node const& pt);
|
||||
|
||||
/**
|
||||
* Writes properties into the given property tree representing the
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
|
|
|
@ -124,16 +124,16 @@ private:
|
|||
text_symbolizer_properties const& p;
|
||||
text_placement_info const& pi;
|
||||
/** Length of the longest line after linebreaks.
|
||||
* Before find_line_breaks() this is the total length of the string.
|
||||
*/
|
||||
* Before find_line_breaks() this is the total length of the string.
|
||||
*/
|
||||
double string_width_;
|
||||
/** Height of the string after linebreaks.
|
||||
* Before find_line_breaks() this is the total length of the string.
|
||||
*/
|
||||
* Before find_line_breaks() this is the total length of the string.
|
||||
*/
|
||||
double string_height_;
|
||||
/** Height of the tallest font in the first line not including line spacing.
|
||||
* Used to determine the correct offset for the first line.
|
||||
*/
|
||||
* Used to determine the correct offset for the first line.
|
||||
*/
|
||||
double first_line_space_;
|
||||
vertical_alignment_e valign_;
|
||||
horizontal_alignment_e halign_;
|
||||
|
|
|
@ -23,450 +23,17 @@
|
|||
#ifndef MAPNIK_PTREE_HELPERS_HPP
|
||||
#define MAPNIK_PTREE_HELPERS_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/color_factory.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
// boost
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
// stl
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
template <typename T>
|
||||
inline boost::optional<T> fast_cast(std::string const& value);
|
||||
|
||||
template <typename T>
|
||||
T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute,
|
||||
T const& default_value);
|
||||
template <typename T>
|
||||
T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute);
|
||||
template <typename T>
|
||||
T get_value(boost::property_tree::ptree const& node, std::string const& name);
|
||||
template <typename T>
|
||||
boost::optional<T> get_optional(boost::property_tree::ptree const& node, std::string const& name,
|
||||
bool is_attribute);
|
||||
|
||||
template <typename T>
|
||||
boost::optional<T> get_opt_attr( boost::property_tree::ptree const& node,
|
||||
std::string const& name)
|
||||
{
|
||||
return get_optional<T>( node, name, true);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
boost::optional<T> get_opt_child( boost::property_tree::ptree const& node,
|
||||
std::string const& name)
|
||||
{
|
||||
return get_optional<T>( node, name, false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_attr( boost::property_tree::ptree const& node, std::string const& name,
|
||||
T const& default_value )
|
||||
{
|
||||
return get<T>( node, name, true, default_value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_attr( boost::property_tree::ptree const& node, std::string const& name )
|
||||
{
|
||||
return get<T>( node, name, true );
|
||||
}
|
||||
|
||||
|
||||
template <typename charT, typename traits>
|
||||
std::basic_ostream<charT, traits> &
|
||||
operator << ( std::basic_ostream<charT, traits> & s, mapnik::color const& c )
|
||||
{
|
||||
std::string hex_string( c.to_string() );
|
||||
s << hex_string;
|
||||
return s;
|
||||
}
|
||||
|
||||
/** Helper for class bool */
|
||||
class boolean {
|
||||
public:
|
||||
boolean() : b_(false) {}
|
||||
boolean(bool b) : b_(b) {}
|
||||
boolean(boolean const& b) : b_(b.b_) {}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
boolean & operator = (boolean const& other)
|
||||
{
|
||||
b_ = other.b_;
|
||||
return * this;
|
||||
}
|
||||
boolean & operator = (bool other)
|
||||
{
|
||||
b_ = other;
|
||||
return * this;
|
||||
}
|
||||
private:
|
||||
bool b_;
|
||||
};
|
||||
|
||||
/** Special stream input operator for boolean values */
|
||||
template <typename charT, typename traits>
|
||||
std::basic_istream<charT, traits> &
|
||||
operator >> ( std::basic_istream<charT, traits> & s, boolean & b )
|
||||
{
|
||||
std::string word;
|
||||
s >> word;
|
||||
if ( s )
|
||||
{
|
||||
if ( word == "true" || word == "yes" || word == "on" ||
|
||||
word == "1")
|
||||
{
|
||||
b = true;
|
||||
}
|
||||
else if ( word == "false" || word == "no" || word == "off" ||
|
||||
word == "0")
|
||||
{
|
||||
b = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setstate( std::ios::failbit );
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename charT, typename traits>
|
||||
std::basic_ostream<charT, traits> &
|
||||
operator << ( std::basic_ostream<charT, traits> & s, boolean const& b )
|
||||
{
|
||||
s << ( b ? "true" : "false" );
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_attr(boost::property_tree::ptree & pt, std::string const& name, T const& v)
|
||||
{
|
||||
pt.put("<xmlattr>." + name, v);
|
||||
}
|
||||
|
||||
|
||||
class boolean;
|
||||
|
||||
template <typename T>
|
||||
struct name_trait
|
||||
{
|
||||
static std::string name()
|
||||
{
|
||||
return "<unknown>";
|
||||
}
|
||||
// missing name_trait for type ...
|
||||
// if you get here you are probably using a new type
|
||||
// in the XML file. Just add a name trait for the new
|
||||
// type below.
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == 0 );
|
||||
};
|
||||
|
||||
#define DEFINE_NAME_TRAIT( type, type_name ) \
|
||||
template <> \
|
||||
struct name_trait<type> \
|
||||
{ \
|
||||
static std::string name() { return std::string("type ") + type_name; } \
|
||||
};
|
||||
|
||||
|
||||
DEFINE_NAME_TRAIT( double, "double")
|
||||
DEFINE_NAME_TRAIT( float, "float")
|
||||
DEFINE_NAME_TRAIT( unsigned, "unsigned")
|
||||
DEFINE_NAME_TRAIT( boolean, "boolean")
|
||||
DEFINE_NAME_TRAIT( int, "integer" )
|
||||
DEFINE_NAME_TRAIT( std::string, "string" )
|
||||
DEFINE_NAME_TRAIT( color, "color" )
|
||||
|
||||
template <typename ENUM, int MAX>
|
||||
struct name_trait< mapnik::enumeration<ENUM, MAX> >
|
||||
{
|
||||
typedef enumeration<ENUM, MAX> Enum;
|
||||
|
||||
static std::string name()
|
||||
{
|
||||
std::string value_list("one of [");
|
||||
for (unsigned i = 0; i < Enum::MAX; ++i)
|
||||
{
|
||||
value_list += Enum::get_string( i );
|
||||
if ( i + 1 < Enum::MAX ) value_list += ", ";
|
||||
}
|
||||
value_list += "]";
|
||||
|
||||
return value_list;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline boost::optional<T> fast_cast(std::string const& value)
|
||||
{
|
||||
try
|
||||
{
|
||||
return boost::lexical_cast<T>( value );
|
||||
}
|
||||
catch (boost::bad_lexical_cast const& ex)
|
||||
{
|
||||
return boost::optional<T>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<int> fast_cast(std::string const& value)
|
||||
{
|
||||
int result;
|
||||
if (mapnik::conversions::string2int(value,result))
|
||||
return boost::optional<int>(result);
|
||||
return boost::optional<int>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<double> fast_cast(std::string const& value)
|
||||
{
|
||||
double result;
|
||||
if (mapnik::conversions::string2double(value,result))
|
||||
return boost::optional<double>(result);
|
||||
return boost::optional<double>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<float> fast_cast(std::string const& value)
|
||||
{
|
||||
float result;
|
||||
if (mapnik::conversions::string2float(value,result))
|
||||
return boost::optional<float>(result);
|
||||
return boost::optional<float>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get(boost::property_tree::ptree const& node,
|
||||
std::string const& name,
|
||||
bool is_attribute,
|
||||
T const& default_value)
|
||||
{
|
||||
boost::optional<std::string> str;
|
||||
if (is_attribute)
|
||||
{
|
||||
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name );
|
||||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name + ".<xmltext>");
|
||||
}
|
||||
|
||||
if ( str )
|
||||
{
|
||||
boost::optional<T> result = fast_cast<T>(*str);
|
||||
if (result)
|
||||
{
|
||||
return *result;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw config_error(std::string("Failed to parse ") +
|
||||
(is_attribute ? "attribute" : "child node") + " '" +
|
||||
name + "'. Expected " + name_trait<T>::name() +
|
||||
" but got '" + *str + "'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return default_value;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline color get(boost::property_tree::ptree const& node,
|
||||
std::string const& name,
|
||||
bool is_attribute,
|
||||
color const& default_value)
|
||||
{
|
||||
boost::optional<std::string> str;
|
||||
if (is_attribute)
|
||||
{
|
||||
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name );
|
||||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name + ".<xmltext>");
|
||||
}
|
||||
|
||||
if ( str )
|
||||
{
|
||||
try
|
||||
{
|
||||
return mapnik::color_factory::from_string((*str).c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse ") +
|
||||
(is_attribute ? "attribute" : "child node") + " '" +
|
||||
name + "'. Expected " + name_trait<color>::name() +
|
||||
" but got '" + *str + "'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return default_value;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute)
|
||||
{
|
||||
boost::optional<std::string> str;
|
||||
if (is_attribute)
|
||||
{
|
||||
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name);
|
||||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name + ".<xmltext>");
|
||||
}
|
||||
|
||||
if ( ! str )
|
||||
{
|
||||
throw config_error(std::string("Required ") +
|
||||
(is_attribute ? "attribute " : "child node ") +
|
||||
"'" + name + "' is missing");
|
||||
}
|
||||
boost::optional<T> result = fast_cast<T>(*str);
|
||||
if (result)
|
||||
{
|
||||
return *result;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw config_error(std::string("Failed to parse ") +
|
||||
(is_attribute ? "attribute" : "child node") + " '" +
|
||||
name + "'. Expected " + name_trait<T>::name() +
|
||||
" but got '" + *str + "'");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_value(boost::property_tree::ptree const& node, std::string const& name)
|
||||
{
|
||||
try
|
||||
{
|
||||
/* NOTE: get_child works as long as there is only one child with that name.
|
||||
If this function is used this used this condition must always be satisfied.
|
||||
*/
|
||||
return node.get_child("<xmltext>").get_value<T>();
|
||||
}
|
||||
catch (boost::property_tree::ptree_bad_path)
|
||||
{
|
||||
/* If the XML parser did not find any non-empty data element the is no
|
||||
<xmltext> node. But we don't want to fail here but simply return a
|
||||
default constructed value of the requested type.
|
||||
*/
|
||||
return T();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse ") +
|
||||
name + ". Expected " + name_trait<T>::name() +
|
||||
" but got '" + node.data() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
boost::optional<T> get_optional(boost::property_tree::ptree const& node,
|
||||
std::string const& name,
|
||||
bool is_attribute)
|
||||
{
|
||||
boost::optional<std::string> str;
|
||||
if (is_attribute)
|
||||
{
|
||||
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name);
|
||||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name + ".<xmltext>");
|
||||
}
|
||||
|
||||
boost::optional<T> result;
|
||||
if ( str )
|
||||
{
|
||||
result = fast_cast<T>(*str);
|
||||
if (!result)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse ") +
|
||||
(is_attribute ? "attribute" : "child node") + " '" +
|
||||
name + "'. Expected " + name_trait<T>::name() +
|
||||
" but got '" + *str + "'");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<std::string> get_optional(boost::property_tree::ptree const& node,
|
||||
std::string const& name,
|
||||
bool is_attribute)
|
||||
{
|
||||
if (is_attribute)
|
||||
{
|
||||
return node.get_optional<std::string>( std::string("<xmlattr>.") + name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return node.get_optional<std::string>(name + ".<xmltext>");
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<color> get_optional(boost::property_tree::ptree const& node,
|
||||
std::string const& name,
|
||||
bool is_attribute)
|
||||
{
|
||||
boost::optional<std::string> str;
|
||||
if (is_attribute)
|
||||
{
|
||||
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name);
|
||||
}
|
||||
else
|
||||
{
|
||||
str = node.get_optional<std::string>(name + ".<xmltext>");
|
||||
}
|
||||
|
||||
boost::optional<color> result;
|
||||
if ( str )
|
||||
{
|
||||
try
|
||||
{
|
||||
result = mapnik::color_factory::from_string((*str).c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse ") +
|
||||
(is_attribute ? "attribute" : "child node") + " '" +
|
||||
name + "'. Expected " + name_trait<color>::name() +
|
||||
" but got '" + *str + "'");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool has_child(boost::property_tree::ptree const& node, std::string const& name)
|
||||
{
|
||||
boost::optional<std::string> str = node.get_optional<std::string>(name);
|
||||
return str;
|
||||
}
|
||||
|
||||
} // end of namespace mapnik
|
||||
|
||||
#endif // MAPNIK_PTREE_HELPERS_HPP
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
|
|
|
@ -65,11 +65,11 @@ public:
|
|||
detector_(detector),
|
||||
writer_(sym.get_metawriter()),
|
||||
dims_(0, 0, width, height),
|
||||
query_extent_(query_extent),
|
||||
text_(font_manager, scale_factor),
|
||||
angle_(0.0),
|
||||
placement_valid_(false),
|
||||
points_on_line_(false),
|
||||
query_extent_(query_extent),
|
||||
finder_()
|
||||
{
|
||||
initialize_geometries();
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
text_symbolizer_properties & add();
|
||||
text_symbolizer_properties & get(unsigned i);
|
||||
unsigned size() const;
|
||||
static text_placements_ptr from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets);
|
||||
static text_placements_ptr from_xml(xml_node const &xml, fontset_map const & fontsets);
|
||||
private:
|
||||
std::vector<text_symbolizer_properties> list_;
|
||||
friend class text_placement_info_list;
|
||||
|
|
|
@ -39,17 +39,17 @@ namespace placements
|
|||
{
|
||||
|
||||
typedef text_placements_ptr (*from_xml_function_ptr)(
|
||||
boost::property_tree::ptree const& xml, fontset_map const & fontsets);
|
||||
xml_node const& xml, fontset_map const & fontsets);
|
||||
|
||||
class registry : public singleton<registry, CreateStatic>,
|
||||
private boost::noncopyable
|
||||
private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
registry();
|
||||
~registry() {}
|
||||
void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false);
|
||||
text_placements_ptr from_xml(std::string name,
|
||||
boost::property_tree::ptree const& xml,
|
||||
xml_node const& xml,
|
||||
fontset_map const & fontsets);
|
||||
private:
|
||||
std::map<std::string, from_xml_function_ptr> map_;
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
text_placement_info_ptr get_placement_info(double scale_factor) const;
|
||||
void set_positions(std::string positions);
|
||||
std::string get_positions();
|
||||
static text_placements_ptr from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets);
|
||||
static text_placements_ptr from_xml(xml_node const &xml, fontset_map const & fontsets);
|
||||
private:
|
||||
std::string positions_;
|
||||
std::vector<directions_t> direction_;
|
||||
|
|
|
@ -54,7 +54,7 @@ struct char_properties
|
|||
{
|
||||
char_properties();
|
||||
/** Construct object from XML. */
|
||||
void from_xml(boost::property_tree::ptree const &sym, fontset_map const & fontsets);
|
||||
void from_xml(xml_node const &sym, fontset_map const & fontsets);
|
||||
/** Write object to XML ptree. */
|
||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const& dfl=char_properties()) const;
|
||||
std::string face_name;
|
||||
|
@ -124,7 +124,7 @@ struct text_symbolizer_properties
|
|||
{
|
||||
text_symbolizer_properties();
|
||||
/** Load all values from XML ptree. */
|
||||
void from_xml(boost::property_tree::ptree const &sym, fontset_map const & fontsets);
|
||||
void from_xml(xml_node const &sym, fontset_map const & fontsets);
|
||||
/** Save all values to XML ptree (but does not create a new parent node!). */
|
||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, text_symbolizer_properties const &dfl=text_symbolizer_properties()) const;
|
||||
|
||||
|
|
|
@ -30,16 +30,16 @@
|
|||
|
||||
namespace mapnik { namespace conversions {
|
||||
|
||||
bool string2int(const char * value, int & result);
|
||||
bool string2int(std::string const& value, int & result);
|
||||
bool string2int(const char * value, int & result);
|
||||
bool string2int(std::string const& value, int & result);
|
||||
|
||||
bool string2double(std::string const& value, double & result);
|
||||
bool string2double(const char * value, double & result);
|
||||
bool string2double(std::string const& value, double & result);
|
||||
bool string2double(const char * value, double & result);
|
||||
|
||||
bool string2float(std::string const& value, float & result);
|
||||
bool string2float(const char * value, float & result);
|
||||
bool string2float(std::string const& value, float & result);
|
||||
bool string2float(const char * value, float & result);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MAPNIK_CONVERSIONS_UTIL_HPP
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/variant.hpp>
|
||||
|
|
|
@ -23,16 +23,14 @@
|
|||
#ifndef MAPNIK_LIBXML2_LOADER_HPP
|
||||
#define MAPNIK_LIBXML2_LOADER_HPP
|
||||
|
||||
// boost
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
void read_xml2( std::string const & filename, boost::property_tree::ptree & pt);
|
||||
void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt, std::string const & base_path="");
|
||||
class xml_node;
|
||||
void read_xml(std::string const & filename, xml_node &node);
|
||||
void read_xml_string(std::string const & str, xml_node &node, std::string const & base_path="");
|
||||
}
|
||||
|
||||
#endif // MAPNIK_LIBXML2_LOADER_HPP
|
137
include/mapnik/xml_node.hpp
Normal file
137
include/mapnik/xml_node.hpp
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_XML_NODE_H
|
||||
#define MAPNIK_XML_NODE_H
|
||||
|
||||
//mapnik
|
||||
#include <mapnik/boolean.hpp>
|
||||
|
||||
|
||||
//boost
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
//stl
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <exception>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
class xml_tree;
|
||||
|
||||
class xml_attribute
|
||||
{
|
||||
public:
|
||||
xml_attribute(std::string const& value);
|
||||
std::string value;
|
||||
mutable bool processed;
|
||||
};
|
||||
|
||||
class node_not_found: public std::exception
|
||||
{
|
||||
public:
|
||||
node_not_found(std::string node_name);
|
||||
virtual const char* what() const throw();
|
||||
~node_not_found() throw ();
|
||||
private:
|
||||
std::string node_name_;
|
||||
};
|
||||
|
||||
class attribute_not_found: public std::exception
|
||||
{
|
||||
public:
|
||||
attribute_not_found(std::string const& node_name, std::string const& attribute_name);
|
||||
virtual const char* what() const throw();
|
||||
~attribute_not_found() throw ();
|
||||
private:
|
||||
std::string node_name_;
|
||||
std::string attribute_name_;
|
||||
};
|
||||
|
||||
class more_than_one_child: public std::exception
|
||||
{
|
||||
public:
|
||||
more_than_one_child(std::string const& node_name);
|
||||
virtual const char* what() const throw();
|
||||
~more_than_one_child() throw ();
|
||||
private:
|
||||
std::string node_name_;
|
||||
};
|
||||
|
||||
class xml_node
|
||||
{
|
||||
public:
|
||||
typedef std::list<xml_node>::const_iterator const_iterator;
|
||||
typedef std::map<std::string, xml_attribute> attribute_map;
|
||||
xml_node(xml_tree &tree, std::string name, unsigned line=0, bool text_node = false);
|
||||
|
||||
std::string const& name() const;
|
||||
std::string const& text() const;
|
||||
std::string const& filename() const;
|
||||
bool is_text() const;
|
||||
bool is(std::string const& name) const;
|
||||
|
||||
xml_node &add_child(std::string const& name, unsigned line=0, bool text_node = false);
|
||||
void add_attribute(std::string const& name, std::string const& value);
|
||||
attribute_map const& get_attributes() const;
|
||||
|
||||
bool processed() const;
|
||||
void set_processed(bool processed) const;
|
||||
|
||||
unsigned line() const;
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
xml_node & get_child(std::string const& name);
|
||||
xml_node const& get_child(std::string const& name) const;
|
||||
xml_node const* get_opt_child(std::string const& name) const;
|
||||
bool has_child(std::string const& name) const;
|
||||
|
||||
template <typename T>
|
||||
boost::optional<T> get_opt_attr(std::string const& name) const;
|
||||
|
||||
template <typename T>
|
||||
T get_attr(std::string const& name, T const& default_value) const;
|
||||
template <typename T>
|
||||
T get_attr(std::string const& name) const;
|
||||
|
||||
std::string get_text() const;
|
||||
|
||||
template <typename T>
|
||||
T get_value() const;
|
||||
private:
|
||||
xml_tree &tree_;
|
||||
std::string name_;
|
||||
std::list<xml_node> children_;
|
||||
attribute_map attributes_;
|
||||
bool text_node_;
|
||||
unsigned line_;
|
||||
mutable bool processed_;
|
||||
static std::string xml_text;
|
||||
};
|
||||
|
||||
} //ns mapnik
|
||||
|
||||
#endif // MAPNIK_XML_NODE_H
|
54
include/mapnik/xml_tree.hpp
Normal file
54
include/mapnik/xml_tree.hpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_XML_TREE_H
|
||||
#define MAPNIK_XML_TREE_H
|
||||
//mapnik
|
||||
#include <mapnik/xml_node.hpp>
|
||||
#include <mapnik/expression_grammar.hpp>
|
||||
#include <mapnik/css_color_grammar.hpp>
|
||||
|
||||
//stl
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
class xml_tree
|
||||
{
|
||||
public:
|
||||
xml_tree(std::string const& encoding="utf8");
|
||||
void set_filename(std::string fn);
|
||||
std::string const& filename() const;
|
||||
xml_node &root();
|
||||
private:
|
||||
xml_node node_;
|
||||
std::string file_;
|
||||
transcoder tr_;
|
||||
public:
|
||||
mapnik::css_color_grammar<std::string::const_iterator> color_grammar;
|
||||
mapnik::expression_grammar<std::string::const_iterator> expr_grammar;
|
||||
};
|
||||
|
||||
} //ns mapnik
|
||||
|
||||
#endif // MAPNIK_XML_TREE_H
|
|
@ -6,6 +6,7 @@
|
|||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
@ -14,7 +15,7 @@
|
|||
#include <mapnik/memory_featureset.hpp>
|
||||
#include <mapnik/wkt/wkt_factory.hpp>
|
||||
#include <mapnik/util/geometry_to_ds_type.hpp>
|
||||
#include <mapnik/ptree_helpers.hpp> // mapnik::boolean
|
||||
#include <mapnik/boolean.hpp>
|
||||
|
||||
// stl
|
||||
#include <sstream>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "gdal_featureset.hpp"
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
#include <mapnik/geom_util.hpp>
|
||||
|
||||
#include <gdal_version.h>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <cstdarg>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
#include <mapnik/geom_util.hpp>
|
||||
|
||||
// boost
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <cstdio>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "occi_featureset.hpp"
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
#include <mapnik/sql_utils.hpp>
|
||||
|
||||
// boost
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <gdal_version.h>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
#include <mapnik/geom_util.hpp>
|
||||
|
||||
// boost
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
#include <mapnik/sql_utils.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
|
||||
|
@ -681,22 +681,22 @@ box2d<double> postgis_datasource::envelope() const
|
|||
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||
if (rs->next() && !rs->isNull(0))
|
||||
{
|
||||
double lox;
|
||||
double loy;
|
||||
double hix;
|
||||
double hiy;
|
||||
if (mapnik::conversions::string2double(rs->getValue(0),lox) &&
|
||||
mapnik::conversions::string2double(rs->getValue(1),loy) &&
|
||||
mapnik::conversions::string2double(rs->getValue(2),hix) &&
|
||||
mapnik::conversions::string2double(rs->getValue(3),hiy))
|
||||
{
|
||||
extent_.init(lox,loy,hix,hiy);
|
||||
extent_initialized_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::clog << boost::format("Postgis Plugin: warning: could not determine extent from query: %s\n") % s.str() << std::endl;
|
||||
}
|
||||
double lox;
|
||||
double loy;
|
||||
double hix;
|
||||
double hiy;
|
||||
if (mapnik::conversions::string2double(rs->getValue(0),lox) &&
|
||||
mapnik::conversions::string2double(rs->getValue(1),loy) &&
|
||||
mapnik::conversions::string2double(rs->getValue(2),hix) &&
|
||||
mapnik::conversions::string2double(rs->getValue(3),hiy))
|
||||
{
|
||||
extent_.init(lox,loy,hix,hiy);
|
||||
extent_initialized_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::clog << boost::format("Postgis Plugin: warning: could not determine extent from query: %s\n") % s.str() << std::endl;
|
||||
}
|
||||
}
|
||||
rs->close();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <boost/make_shared.hpp>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
#include <mapnik/geom_util.hpp>
|
||||
|
||||
using mapnik::datasource;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "sqlite_utils.hpp"
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
#include <mapnik/sql_utils.hpp>
|
||||
#include <mapnik/util/geometry_to_ds_type.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <mapnik/marker.hpp>
|
||||
#include <mapnik/marker_cache.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/font_set.hpp>
|
||||
#include <mapnik/parse_path.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
|
|
10
src/build.py
10
src/build.py
|
@ -178,6 +178,8 @@ source = Split(
|
|||
text_placements/list.cpp
|
||||
text_placements/simple.cpp
|
||||
text_properties.cpp
|
||||
xml_tree.cpp
|
||||
config_error.cpp
|
||||
"""
|
||||
)
|
||||
|
||||
|
@ -299,7 +301,7 @@ if env['XMLPARSER'] == 'libxml2' and env['HAS_LIBXML2']:
|
|||
env2 = lib_env.Clone()
|
||||
env2.Append(CXXFLAGS = '-DHAVE_LIBXML2')
|
||||
libmapnik_cxxflags.append('-DHAVE_LIBXML2')
|
||||
fixup = ['load_map.cpp','libxml2_loader.cpp']
|
||||
fixup = ['libxml2_loader.cpp']
|
||||
for cpp in fixup:
|
||||
if cpp in source:
|
||||
source.remove(cpp)
|
||||
|
@ -307,6 +309,12 @@ if env['XMLPARSER'] == 'libxml2' and env['HAS_LIBXML2']:
|
|||
source.insert(0,env2.StaticObject(cpp))
|
||||
else:
|
||||
source.insert(0,env2.SharedObject(cpp))
|
||||
else:
|
||||
source += Split(
|
||||
"""
|
||||
rapidxml_loader.cpp
|
||||
"""
|
||||
)
|
||||
|
||||
if env['CUSTOM_LDFLAGS']:
|
||||
linkflags = '%s %s' % (env['CUSTOM_LDFLAGS'], mapnik_lib_link_flag)
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/markers_placement.hpp>
|
||||
#include <mapnik/arrow.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/parse_path.hpp>
|
||||
#include <mapnik/marker.hpp>
|
||||
#include <mapnik/marker_cache.hpp>
|
||||
|
|
|
@ -25,11 +25,23 @@
|
|||
// mapnik
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/color_factory.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// stl
|
||||
#include <sstream>
|
||||
|
||||
// boost 1.41 -> 1.44 compatibility, to be removed in mapnik 2.1 (dane)
|
||||
#if BOOST_VERSION >= 104500
|
||||
#include <mapnik/css_color_grammar.hpp>
|
||||
#else
|
||||
#include <mapnik/css_color_grammar_deprecated.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
color::color( std::string const& css_string)
|
||||
|
@ -81,5 +93,89 @@ std::string color::to_hex_string() const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
void color_factory::init_from_string(color & c, std::string const& css_color)
|
||||
{
|
||||
typedef std::string::const_iterator iterator_type;
|
||||
typedef mapnik::css_color_grammar<iterator_type> css_color_grammar;
|
||||
|
||||
css_color_grammar g;
|
||||
iterator_type first = css_color.begin();
|
||||
iterator_type last = css_color.end();
|
||||
// boost 1.41 -> 1.44 compatibility, to be removed in mapnik 2.1 (dane)
|
||||
#if BOOST_VERSION >= 104500
|
||||
bool result =
|
||||
boost::spirit::qi::phrase_parse(first,
|
||||
last,
|
||||
g,
|
||||
boost::spirit::ascii::space,
|
||||
c);
|
||||
if (!result)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse color value: ") +
|
||||
"Expected a CSS color, but got '" + css_color + "'");
|
||||
}
|
||||
#else
|
||||
mapnik::css css_;
|
||||
bool result =
|
||||
boost::spirit::qi::phrase_parse(first,
|
||||
last,
|
||||
g,
|
||||
boost::spirit::ascii::space,
|
||||
css_);
|
||||
if (!result)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse color value: ") +
|
||||
"Expected a CSS color, but got '" + css_color + "'");
|
||||
}
|
||||
c.set_red(css_.r);
|
||||
c.set_green(css_.g);
|
||||
c.set_blue(css_.b);
|
||||
c.set_alpha(css_.a);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool color_factory::parse_from_string(color & c, std::string const& css_color,
|
||||
mapnik::css_color_grammar<std::string::const_iterator> const& g)
|
||||
{
|
||||
std::string::const_iterator first = css_color.begin();
|
||||
std::string::const_iterator last = css_color.end();
|
||||
// boost 1.41 -> 1.44 compatibility, to be removed in mapnik 2.1 (dane)
|
||||
#if BOOST_VERSION >= 104500
|
||||
bool result =
|
||||
boost::spirit::qi::phrase_parse(first,
|
||||
last,
|
||||
g,
|
||||
boost::spirit::ascii::space,
|
||||
c);
|
||||
return result && (first == last);
|
||||
#else
|
||||
mapnik::css css_;
|
||||
bool result =
|
||||
boost::spirit::qi::phrase_parse(first,
|
||||
last,
|
||||
g,
|
||||
boost::spirit::ascii::space,
|
||||
css_);
|
||||
if (result && (first == last))
|
||||
{
|
||||
c.set_red(css_.r);
|
||||
c.set_green(css_.g);
|
||||
c.set_blue(css_.b);
|
||||
c.set_alpha(css_.a);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
color color_factory::from_string(std::string const& css_color)
|
||||
{
|
||||
color c;
|
||||
init_from_string(c, css_color);
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
55
src/config_error.cpp
Normal file
55
src/config_error.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/xml_tree.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
config_error::config_error(std::string const& what)
|
||||
: what_(what), line_number_(0), file_(), node_name_(), msg_()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
config_error::config_error(std::string const& what, xml_node const& node)
|
||||
: what_(what), line_number_(node.line()), file_(node.filename()), node_name_(node.name()), msg_()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
config_error::config_error(std::string const& what, unsigned line_number, std::string const& filename)
|
||||
: what_(what), line_number_(line_number), file_(filename), node_name_(), msg_()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char const* config_error::what() const throw()
|
||||
{
|
||||
std::stringstream s;
|
||||
s << file_;
|
||||
if (line_number_ > 0) s << " line " << line_number_;
|
||||
if (!node_name_.empty()) s << " in node "<< node_name_;
|
||||
if (line_number_ > 0 || !file_.empty()) s << ": ";
|
||||
s << what_;
|
||||
msg_ = s.str(); //Avoid returning pointer to dead object
|
||||
return msg_.c_str();
|
||||
}
|
||||
|
||||
void config_error::append_context(std::string const& ctx) const
|
||||
{
|
||||
what_ += " " + ctx;
|
||||
}
|
||||
|
||||
void config_error::append_context(std::string const& ctx, xml_node const& node) const
|
||||
{
|
||||
append_context(ctx);
|
||||
append_context(node);
|
||||
}
|
||||
|
||||
void config_error::append_context(xml_node const& node) const
|
||||
{
|
||||
if (!line_number_) line_number_ = node.line();
|
||||
if (node_name_.empty()) node_name_ = node.name();
|
||||
if (file_.empty()) file_ = node.filename();
|
||||
}
|
||||
|
||||
}
|
|
@ -23,21 +23,21 @@
|
|||
// boost
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
|
||||
#define BOOST_SPIRIT_AUTO(domain_, name, expr) \
|
||||
typedef boost::proto::result_of:: \
|
||||
deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \
|
||||
BOOST_SPIRIT_ASSERT_MATCH( \
|
||||
boost::spirit::domain_::domain, name##_expr_type); \
|
||||
BOOST_AUTO(name, boost::proto::deep_copy(expr)); \
|
||||
#define BOOST_SPIRIT_AUTO(domain_, name, expr) \
|
||||
typedef boost::proto::result_of:: \
|
||||
deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \
|
||||
BOOST_SPIRIT_ASSERT_MATCH( \
|
||||
boost::spirit::domain_::domain, name##_expr_type); \
|
||||
BOOST_AUTO(name, boost::proto::deep_copy(expr)); \
|
||||
|
||||
|
||||
namespace mapnik { namespace conversions {
|
||||
|
||||
using namespace boost::spirit;
|
||||
|
||||
BOOST_SPIRIT_AUTO(qi, INTEGER, qi::int_);
|
||||
BOOST_SPIRIT_AUTO(qi, FLOAT, qi::float_);
|
||||
BOOST_SPIRIT_AUTO(qi, DOUBLE, qi::double_);
|
||||
BOOST_SPIRIT_AUTO(qi, INTEGER, qi::int_)
|
||||
BOOST_SPIRIT_AUTO(qi, FLOAT, qi::float_)
|
||||
BOOST_SPIRIT_AUTO(qi, DOUBLE, qi::double_)
|
||||
|
||||
bool string2int(const char * value, int & result)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <mapnik/expression.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/expression_grammar.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
@ -50,8 +51,8 @@ expression_ptr expression_factory::compile(std::string const& str,transcoder con
|
|||
}
|
||||
|
||||
bool expression_factory::parse_from_string(expression_ptr const& expr,
|
||||
std::string const& str,
|
||||
mapnik::expression_grammar<std::string::const_iterator> const& g)
|
||||
std::string const& str,
|
||||
mapnik::expression_grammar<std::string::const_iterator> const& g)
|
||||
{
|
||||
std::string::const_iterator itr = str.begin();
|
||||
std::string::const_iterator end = str.end();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <mapnik/formatting/base.hpp>
|
||||
#include <mapnik/formatting/list.hpp>
|
||||
#include <mapnik/formatting/registry.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
@ -38,18 +39,18 @@ void node::to_xml(boost::property_tree::ptree &xml) const
|
|||
#endif
|
||||
}
|
||||
|
||||
node_ptr node::from_xml(boost::property_tree::ptree const& xml)
|
||||
node_ptr node::from_xml(xml_node const& xml)
|
||||
{
|
||||
list_node *list = new list_node();
|
||||
node_ptr list_ptr(list);
|
||||
boost::property_tree::ptree::const_iterator itr = xml.begin();
|
||||
boost::property_tree::ptree::const_iterator end = xml.end();
|
||||
xml_node::const_iterator itr = xml.begin();
|
||||
xml_node::const_iterator end = xml.end();
|
||||
for (; itr != end; ++itr) {
|
||||
if (itr->first == "<xmlcomment>" || itr->first == "<xmlattr>" || itr->first == "Placement")
|
||||
if (itr->name() == "Placement")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
node_ptr n = registry::instance()->from_xml(itr->first, itr->second);
|
||||
node_ptr n = registry::instance()->from_xml(*itr);
|
||||
if (n) list->push_back(n);
|
||||
}
|
||||
if (list->get_children().size() == 1) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <mapnik/expression_evaluator.hpp>
|
||||
#include <mapnik/text_properties.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
|
||||
// boost
|
||||
|
||||
|
@ -37,7 +38,7 @@ namespace formatting
|
|||
using boost::property_tree::ptree;
|
||||
void expression_format::to_xml(boost::property_tree::ptree &xml) const
|
||||
{
|
||||
ptree &new_node = xml.push_back(ptree::value_type("Format", ptree()))->second;
|
||||
ptree &new_node = xml.push_back(ptree::value_type("ExpressionFormat", ptree()))->second;
|
||||
if (face_name) set_attr(new_node, "face-name", to_expression_string(*face_name));
|
||||
if (text_size) set_attr(new_node, "size", to_expression_string(*text_size));
|
||||
if (character_spacing) set_attr(new_node, "character-spacing", to_expression_string*character_spacing);
|
||||
|
@ -51,7 +52,7 @@ void expression_format::to_xml(boost::property_tree::ptree &xml) const
|
|||
if (child_) child_->to_xml(new_node);
|
||||
}
|
||||
|
||||
node_ptr expression_format::from_xml(ptree const& xml)
|
||||
node_ptr expression_format::from_xml(xml_node const& xml)
|
||||
{
|
||||
expression_format *n = new expression_format();
|
||||
node_ptr np(n);
|
||||
|
@ -72,9 +73,9 @@ node_ptr expression_format::from_xml(ptree const& xml)
|
|||
return np;
|
||||
}
|
||||
|
||||
expression_ptr expression_format::get_expression(ptree const& xml, std::string name)
|
||||
expression_ptr expression_format::get_expression(xml_node const& xml, std::string name)
|
||||
{
|
||||
boost::optional<std::string> tmp = get_opt_attr<std::string>(xml, name);
|
||||
boost::optional<std::string> tmp = xml.get_opt_attr<std::string>(name);
|
||||
if (tmp) return parse_expression(*tmp);
|
||||
return expression_ptr();
|
||||
}
|
||||
|
@ -84,25 +85,25 @@ void expression_format::apply(char_properties const& p, const Feature &feature,
|
|||
{
|
||||
char_properties new_properties = p;
|
||||
if (face_name) new_properties.face_name =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *face_name).to_string();
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *face_name).to_string();
|
||||
if (text_size) new_properties.text_size =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_size).to_double();
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_size).to_double();
|
||||
if (character_spacing) new_properties.character_spacing =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_double();
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_double();
|
||||
if (line_spacing) new_properties.line_spacing =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *line_spacing).to_double();
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *line_spacing).to_double();
|
||||
if (text_opacity) new_properties.text_opacity =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_opacity).to_double();
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_opacity).to_double();
|
||||
if (wrap_before) new_properties.wrap_before =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *wrap_before).to_bool();
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *wrap_before).to_bool();
|
||||
if (wrap_char) new_properties.wrap_char =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_unicode()[0];
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_unicode()[0];
|
||||
// if (fill) new_properties.fill =
|
||||
// boost::apply_visitor(evaluate<Feature,value_type>(feature), *fill).to_color();
|
||||
// if (halo_fill) new_properties.halo_fill =
|
||||
// boost::apply_visitor(evaluate<Feature,value_type>(feature), *halo_fill).to_color();
|
||||
if (halo_radius) new_properties.halo_radius =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *halo_radius).to_double();
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *halo_radius).to_double();
|
||||
|
||||
if (child_) {
|
||||
child_->apply(new_properties, feature, output);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
#include <mapnik/formatting/format.hpp>
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
using boost::property_tree::ptree;
|
||||
|
@ -44,7 +45,7 @@ void format_node::to_xml(ptree &xml) const
|
|||
}
|
||||
|
||||
|
||||
node_ptr format_node::from_xml(ptree const& xml)
|
||||
node_ptr format_node::from_xml(xml_node const& xml)
|
||||
{
|
||||
format_node *n = new format_node();
|
||||
node_ptr np(n);
|
||||
|
@ -52,19 +53,19 @@ node_ptr format_node::from_xml(ptree const& xml)
|
|||
node_ptr child = node::from_xml(xml);
|
||||
n->set_child(child);
|
||||
|
||||
n->face_name = get_opt_attr<std::string>(xml, "face-name");
|
||||
n->face_name = xml.get_opt_attr<std::string>("face-name");
|
||||
/*TODO: Fontset is problematic. We don't have the fontsets pointer here... */
|
||||
n->text_size = get_opt_attr<unsigned>(xml, "size");
|
||||
n->character_spacing = get_opt_attr<unsigned>(xml, "character-spacing");
|
||||
n->line_spacing = get_opt_attr<unsigned>(xml, "line-spacing");
|
||||
n->text_opacity = get_opt_attr<double>(xml, "opactity");
|
||||
boost::optional<boolean> wrap = get_opt_attr<boolean>(xml, "wrap-before");
|
||||
n->text_size = xml.get_opt_attr<unsigned>("size");
|
||||
n->character_spacing = xml.get_opt_attr<unsigned>("character-spacing");
|
||||
n->line_spacing = xml.get_opt_attr<unsigned>("line-spacing");
|
||||
n->text_opacity = xml.get_opt_attr<double>("opactity");
|
||||
boost::optional<boolean> wrap = xml.get_opt_attr<boolean>("wrap-before");
|
||||
if (wrap) n->wrap_before = *wrap;
|
||||
n->wrap_char = get_opt_attr<unsigned>(xml, "wrap-character");
|
||||
n->text_transform = get_opt_attr<text_transform_e>(xml, "text-transform");
|
||||
n->fill = get_opt_attr<color>(xml, "fill");
|
||||
n->halo_fill = get_opt_attr<color>(xml, "halo-fill");
|
||||
n->halo_radius = get_opt_attr<double>(xml, "halo-radius");
|
||||
n->wrap_char = xml.get_opt_attr<unsigned>("wrap-character");
|
||||
n->text_transform = xml.get_opt_attr<text_transform_e>("text-transform");
|
||||
n->fill = xml.get_opt_attr<color>("fill");
|
||||
n->halo_fill = xml.get_opt_attr<color>("halo-fill");
|
||||
n->halo_radius = xml.get_opt_attr<double>("halo-radius");
|
||||
return np;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <mapnik/formatting/text.hpp>
|
||||
#include <mapnik/formatting/format.hpp>
|
||||
#include <mapnik/formatting/expression.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
@ -46,10 +48,11 @@ void registry::register_name(std::string name, from_xml_function_ptr ptr, bool o
|
|||
}
|
||||
}
|
||||
|
||||
node_ptr registry::from_xml(std::string name, const boost::property_tree::ptree &xml)
|
||||
node_ptr registry::from_xml(xml_node const& xml)
|
||||
{
|
||||
std::map<std::string, from_xml_function_ptr>::const_iterator itr = map_.find(name);
|
||||
if (itr == map_.end()) throw config_error("Unknown element '" + name + "'");
|
||||
std::map<std::string, from_xml_function_ptr>::const_iterator itr = map_.find(xml.name());
|
||||
if (itr == map_.end()) throw config_error("Unknown element '" + xml.name() + "'", xml);
|
||||
xml.set_processed(true);
|
||||
return itr->second(xml);
|
||||
}
|
||||
} //ns formatting
|
||||
|
|
|
@ -26,10 +26,7 @@
|
|||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/text_properties.hpp>
|
||||
#include <mapnik/processed_text.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
@ -46,10 +43,9 @@ void text_node::to_xml(ptree &xml) const
|
|||
}
|
||||
|
||||
|
||||
node_ptr text_node::from_xml(boost::property_tree::ptree const& xml)
|
||||
node_ptr text_node::from_xml(xml_node const& xml)
|
||||
{
|
||||
std::string data = xml.data();
|
||||
boost::trim(data);
|
||||
std::string data = xml.text();
|
||||
if (data.empty()) return node_ptr(); //No text
|
||||
return boost::make_shared<text_node>(parse_expression(data, "utf8"));
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include <mapnik/marker.hpp>
|
||||
#include <mapnik/marker_cache.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/font_set.hpp>
|
||||
#include <mapnik/parse_path.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
|
|
|
@ -33,29 +33,29 @@ namespace mapnik { namespace json {
|
|||
|
||||
#if BOOST_VERSION >= 104700
|
||||
|
||||
template <typename Iterator>
|
||||
feature_collection_parser<Iterator>::feature_collection_parser(mapnik::context_ptr const& ctx, mapnik::transcoder const& tr)
|
||||
: grammar_(new feature_collection_grammar<iterator_type,feature_type>(ctx,tr)) {}
|
||||
template <typename Iterator>
|
||||
feature_collection_parser<Iterator>::feature_collection_parser(mapnik::context_ptr const& ctx, mapnik::transcoder const& tr)
|
||||
: grammar_(new feature_collection_grammar<iterator_type,feature_type>(ctx,tr)) {}
|
||||
|
||||
template <typename Iterator>
|
||||
feature_collection_parser<Iterator>::~feature_collection_parser() {}
|
||||
template <typename Iterator>
|
||||
feature_collection_parser<Iterator>::~feature_collection_parser() {}
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
bool feature_collection_parser<Iterator>::parse(iterator_type first, iterator_type last, std::vector<mapnik::feature_ptr> & features)
|
||||
{
|
||||
template <typename Iterator>
|
||||
bool feature_collection_parser<Iterator>::parse(iterator_type first, iterator_type last, std::vector<mapnik::feature_ptr> & features)
|
||||
{
|
||||
#if BOOST_VERSION >= 104700
|
||||
using namespace boost::spirit;
|
||||
return qi::phrase_parse(first, last, *grammar_, standard_wide::space, features);
|
||||
using namespace boost::spirit;
|
||||
return qi::phrase_parse(first, last, *grammar_, standard_wide::space, features);
|
||||
#else
|
||||
std::ostringstream s;
|
||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||
throw std::runtime_error("mapnik::feature_collection_parser::parse() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
||||
return false;
|
||||
std::ostringstream s;
|
||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||
throw std::runtime_error("mapnik::feature_collection_parser::parse() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template class feature_collection_parser<std::string::const_iterator> ;
|
||||
template class feature_collection_parser<boost::spirit::multi_pass<std::istreambuf_iterator<char> > >;
|
||||
}}
|
||||
template class feature_collection_parser<std::string::const_iterator> ;
|
||||
template class feature_collection_parser<boost::spirit::multi_pass<std::istreambuf_iterator<char> > >;
|
||||
}}
|
||||
|
||||
|
|
|
@ -32,30 +32,30 @@
|
|||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
feature_generator::feature_generator()
|
||||
: grammar_(new feature_generator_grammar<sink_type>()) {}
|
||||
feature_generator::feature_generator()
|
||||
: grammar_(new feature_generator_grammar<sink_type>()) {}
|
||||
|
||||
feature_generator::~feature_generator() {}
|
||||
feature_generator::~feature_generator() {}
|
||||
|
||||
bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
|
||||
{
|
||||
sink_type sink(geojson);
|
||||
return karma::generate(sink, *grammar_,f);
|
||||
}
|
||||
bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
|
||||
{
|
||||
sink_type sink(geojson);
|
||||
return karma::generate(sink, *grammar_,f);
|
||||
}
|
||||
|
||||
|
||||
geometry_generator::geometry_generator()
|
||||
: grammar_(new multi_geometry_generator_grammar<sink_type>()) {}
|
||||
geometry_generator::geometry_generator()
|
||||
: grammar_(new multi_geometry_generator_grammar<sink_type>()) {}
|
||||
|
||||
geometry_generator::~geometry_generator() {}
|
||||
geometry_generator::~geometry_generator() {}
|
||||
|
||||
bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
|
||||
{
|
||||
sink_type sink(geojson);
|
||||
return karma::generate(sink, *grammar_,g);
|
||||
}
|
||||
bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
|
||||
{
|
||||
sink_type sink(geojson);
|
||||
return karma::generate(sink, *grammar_,g);
|
||||
}
|
||||
|
||||
}}
|
||||
}}
|
||||
|
||||
#else
|
||||
|
||||
|
@ -65,22 +65,22 @@ bool geometry_generator::generate(std::string & geojson, mapnik::geometry_contai
|
|||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||
throw std::runtime_error("feature_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
||||
return false;
|
||||
}
|
||||
bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||
throw std::runtime_error("feature_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||
throw std::runtime_error("geometry_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
||||
return false;
|
||||
}
|
||||
bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||
throw std::runtime_error("geometry_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
}}
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,26 +22,27 @@
|
|||
|
||||
#ifdef HAVE_LIBXML2
|
||||
|
||||
#include <mapnik/libxml2_loader.hpp>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/xml_loader.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
|
||||
// libxml
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/parserInternals.h>
|
||||
#include <libxml/xinclude.h>
|
||||
|
||||
// stl
|
||||
#include <iostream>
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
using namespace std;
|
||||
|
||||
//#define DEFAULT_OPTIONS (XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA)
|
||||
#define DEFAULT_OPTIONS (XML_PARSE_NOERROR | XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA)
|
||||
|
||||
namespace mapnik
|
||||
|
@ -50,14 +51,14 @@ class libxml2_loader : boost::noncopyable
|
|||
{
|
||||
public:
|
||||
libxml2_loader(const char *encoding = NULL, int options = DEFAULT_OPTIONS, const char *url = NULL) :
|
||||
ctx_( 0 ),
|
||||
encoding_( encoding ),
|
||||
options_( options ),
|
||||
url_( url )
|
||||
ctx_(0),
|
||||
encoding_(encoding),
|
||||
options_(options),
|
||||
url_(url)
|
||||
{
|
||||
LIBXML_TEST_VERSION;
|
||||
ctx_ = xmlNewParserCtxt();
|
||||
if ( ! ctx_ )
|
||||
if (!ctx_)
|
||||
{
|
||||
throw std::runtime_error("Failed to create parser context.");
|
||||
}
|
||||
|
@ -71,19 +72,19 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void load( std::string const& filename, ptree & pt )
|
||||
void load(std::string const& filename, xml_node &node)
|
||||
{
|
||||
boost::filesystem::path path(filename);
|
||||
if ( !boost::filesystem::exists( path ) ) {
|
||||
throw config_error(string("Could not load map file '") +
|
||||
filename + "': File does not exist");
|
||||
if (!boost::filesystem::exists(path))
|
||||
{
|
||||
throw config_error(string("Could not load map file: File does not exist"), 0, filename);
|
||||
}
|
||||
|
||||
xmlDocPtr doc = xmlCtxtReadFile(ctx_, filename.c_str(), encoding_, options_);
|
||||
|
||||
if ( !doc )
|
||||
if (!doc)
|
||||
{
|
||||
xmlError * error = xmlCtxtGetLastError( ctx_ );
|
||||
xmlError * error = xmlCtxtGetLastError(ctx_);
|
||||
if (error)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
@ -91,15 +92,7 @@ public:
|
|||
os << ": " << std::endl << error->message;
|
||||
// remove CR
|
||||
std::string msg = os.str().substr(0, os.str().size() - 1);
|
||||
config_error ex( msg );
|
||||
|
||||
os.str("");
|
||||
os << "(encountered in file '" << error->file << "' at line "
|
||||
<< error->line << ")";
|
||||
|
||||
ex.append_context( os.str() );
|
||||
|
||||
throw ex;
|
||||
throw config_error(msg, error->line, error->file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,21 +103,21 @@ public:
|
|||
<< std::endl;
|
||||
}
|
||||
*/
|
||||
load(doc, pt);
|
||||
load(doc, node);
|
||||
}
|
||||
|
||||
void load( const int fd, ptree & pt )
|
||||
void load(const int fd, xml_node &node)
|
||||
{
|
||||
xmlDocPtr doc = xmlCtxtReadFd(ctx_, fd, url_, encoding_, options_);
|
||||
load(doc, pt);
|
||||
load(doc, node);
|
||||
}
|
||||
|
||||
void load_string( std::string const& buffer, ptree & pt, std::string const & base_path )
|
||||
void load_string(std::string const& buffer, xml_node &node, std::string const & base_path)
|
||||
{
|
||||
if (!base_path.empty())
|
||||
{
|
||||
boost::filesystem::path path(base_path);
|
||||
if ( ! boost::filesystem::exists( path ) ) {
|
||||
if (!boost::filesystem::exists(path)) {
|
||||
throw config_error(string("Could not locate base_path '") +
|
||||
base_path + "': file or directory does not exist");
|
||||
}
|
||||
|
@ -132,12 +125,12 @@ public:
|
|||
|
||||
xmlDocPtr doc = xmlCtxtReadMemory(ctx_, buffer.data(), buffer.length(), base_path.c_str(), encoding_, options_);
|
||||
|
||||
load(doc, pt);
|
||||
load(doc, node);
|
||||
}
|
||||
|
||||
void load( const xmlDocPtr doc, ptree & pt )
|
||||
void load(const xmlDocPtr doc, xml_node &node)
|
||||
{
|
||||
if ( !doc )
|
||||
if (!doc)
|
||||
{
|
||||
xmlError * error = xmlCtxtGetLastError( ctx_ );
|
||||
std::ostringstream os;
|
||||
|
@ -146,10 +139,10 @@ public:
|
|||
{
|
||||
os << ": " << std::endl << error->message;
|
||||
}
|
||||
throw config_error(os.str());
|
||||
throw config_error(os.str(), error->line, error->file);
|
||||
}
|
||||
|
||||
int iXIncludeReturn = xmlXIncludeProcessFlags( doc, options_ );
|
||||
int iXIncludeReturn = xmlXIncludeProcessFlags(doc, options_);
|
||||
|
||||
if (iXIncludeReturn < 0)
|
||||
{
|
||||
|
@ -157,64 +150,48 @@ public:
|
|||
throw config_error("XML XInclude error. One or more files failed to load.");
|
||||
}
|
||||
|
||||
xmlNode * root = xmlDocGetRootElement( doc );
|
||||
if ( ! root ) {
|
||||
xmlNode * root = xmlDocGetRootElement(doc);
|
||||
if (!root) {
|
||||
xmlFreeDoc(doc);
|
||||
throw config_error("XML document is empty.");
|
||||
}
|
||||
|
||||
populate_tree( root, pt );
|
||||
populate_tree(root, node);
|
||||
xmlFreeDoc(doc);
|
||||
}
|
||||
|
||||
private:
|
||||
void append_attributes( xmlAttr * attributes, ptree & pt)
|
||||
void append_attributes(xmlAttr *attributes, xml_node &node)
|
||||
{
|
||||
if (attributes)
|
||||
for (; attributes; attributes = attributes->next )
|
||||
{
|
||||
ptree::iterator it = pt.push_back( ptree::value_type( "<xmlattr>", ptree() ));
|
||||
ptree & attr_list = it->second;
|
||||
xmlAttr * cur_attr = attributes;
|
||||
for (; cur_attr; cur_attr = cur_attr->next )
|
||||
{
|
||||
ptree::iterator it = attr_list.push_back(
|
||||
ptree::value_type( (char*)cur_attr->name, ptree() ));
|
||||
it->second.put_value( (char*) cur_attr->children->content );
|
||||
}
|
||||
node.add_attribute((char *)attributes->name, (char *)attributes->children->content);
|
||||
}
|
||||
}
|
||||
|
||||
void populate_tree( xmlNode * node, ptree & pt )
|
||||
void populate_tree(xmlNode *cur_node, xml_node &node)
|
||||
{
|
||||
xmlNode * cur_node = node;
|
||||
|
||||
for (; cur_node; cur_node = cur_node->next )
|
||||
{
|
||||
switch (cur_node->type)
|
||||
{
|
||||
case XML_ELEMENT_NODE:
|
||||
{
|
||||
ptree::iterator it = pt.push_back( ptree::value_type(
|
||||
(char*)cur_node->name, ptree() ));
|
||||
append_attributes( cur_node->properties, it->second);
|
||||
populate_tree( cur_node->children, it->second );
|
||||
|
||||
xml_node &new_node = node.add_child((char *)cur_node->name, cur_node->line, false);
|
||||
append_attributes(cur_node->properties, new_node);
|
||||
populate_tree(cur_node->children, new_node);
|
||||
}
|
||||
break;
|
||||
case XML_TEXT_NODE:
|
||||
{
|
||||
std::string trimmed = boost::algorithm::trim_copy(std::string((char*)cur_node->content));
|
||||
if (trimmed.empty()) break;
|
||||
ptree::iterator it = pt.push_back(ptree::value_type("<xmltext>", ptree()));
|
||||
it->second.put_value(trimmed);
|
||||
if (trimmed.empty()) break; //Don't add empty text nodes
|
||||
node.add_child(trimmed, cur_node->line, true);
|
||||
}
|
||||
break;
|
||||
case XML_COMMENT_NODE:
|
||||
{
|
||||
ptree::iterator it = pt.push_back(
|
||||
ptree::value_type( "<xmlcomment>", ptree() ));
|
||||
it->second.put_value( (char*) cur_node->content );
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
|
@ -228,15 +205,15 @@ private:
|
|||
const char *url_;
|
||||
};
|
||||
|
||||
void read_xml2( std::string const & filename, boost::property_tree::ptree & pt)
|
||||
void read_xml(std::string const & filename, xml_node &node)
|
||||
{
|
||||
libxml2_loader loader;
|
||||
loader.load( filename, pt );
|
||||
loader.load(filename, node);
|
||||
}
|
||||
void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt, std::string const & base_path)
|
||||
void read_xml_string(std::string const & str, xml_node &node, std::string const & base_path)
|
||||
{
|
||||
libxml2_loader loader;
|
||||
loader.load_string( str, pt, base_path );
|
||||
loader.load_string(str, node, base_path);
|
||||
}
|
||||
|
||||
} // end of namespace mapnik
|
||||
|
|
1105
src/load_map.cpp
1105
src/load_map.cpp
File diff suppressed because it is too large
Load diff
|
@ -588,7 +588,7 @@ featureset_ptr Map::query_point(unsigned index, double x, double y) const
|
|||
featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y));
|
||||
if (fs)
|
||||
return boost::make_shared<filter_featureset<hit_test_filter> >(fs,
|
||||
hit_test_filter(x,y,tol));
|
||||
hit_test_filter(x,y,tol));
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
|
@ -634,7 +634,7 @@ featureset_ptr Map::query_map_point(unsigned index, double x, double y) const
|
|||
featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y));
|
||||
if (fs)
|
||||
return boost::make_shared<filter_featureset<hit_test_filter> >(fs,
|
||||
hit_test_filter(x,y,tol));
|
||||
hit_test_filter(x,y,tol));
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
|
|
|
@ -22,15 +22,15 @@
|
|||
//$Id$
|
||||
|
||||
#include <mapnik/metawriter_factory.hpp>
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
|
||||
#include <mapnik/metawriter_json.hpp>
|
||||
#include <mapnik/metawriter_inmem.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
using boost::optional;
|
||||
using std::string;
|
||||
|
||||
|
@ -38,20 +38,21 @@ namespace mapnik
|
|||
{
|
||||
|
||||
metawriter_ptr
|
||||
metawriter_create(const boost::property_tree::ptree &pt) {
|
||||
metawriter_create(xml_node const& pt)
|
||||
{
|
||||
metawriter_ptr writer;
|
||||
string type = get_attr<string>(pt, "type");
|
||||
string type = pt.get_attr<string>("type");
|
||||
|
||||
optional<string> properties = get_opt_attr<string>(pt, "default-output");
|
||||
optional<string> properties = pt.get_opt_attr<string>("default-output");
|
||||
if (type == "json") {
|
||||
string file = get_attr<string>(pt, "file");
|
||||
string file = pt.get_attr<string>("file");
|
||||
metawriter_json_ptr json = boost::make_shared<metawriter_json>(properties, parse_path(file));
|
||||
optional<boolean> output_empty = get_opt_attr<boolean>(pt, "output-empty");
|
||||
optional<boolean> output_empty = pt.get_opt_attr<boolean>("output-empty");
|
||||
if (output_empty) {
|
||||
json->set_output_empty(*output_empty);
|
||||
}
|
||||
|
||||
optional<boolean> pixel_coordinates = get_opt_attr<boolean>(pt, "pixel-coordinates");
|
||||
optional<boolean> pixel_coordinates = pt.get_opt_attr<boolean>("pixel-coordinates");
|
||||
if (pixel_coordinates) {
|
||||
json->set_pixel_coordinates(*pixel_coordinates);
|
||||
}
|
||||
|
@ -61,14 +62,16 @@ metawriter_create(const boost::property_tree::ptree &pt) {
|
|||
metawriter_inmem_ptr inmem = boost::make_shared<metawriter_inmem>(properties);
|
||||
writer = inmem;
|
||||
} else {
|
||||
throw config_error(string("Unknown type '") + type + "'");
|
||||
throw config_error(string("Unknown type '") + type + "'", pt);
|
||||
}
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
void
|
||||
metawriter_save(const metawriter_ptr &metawriter, ptree &metawriter_node, bool explicit_defaults) {
|
||||
metawriter_save(const metawriter_ptr &metawriter,
|
||||
boost::property_tree::ptree &metawriter_node, bool explicit_defaults)
|
||||
{
|
||||
|
||||
metawriter_json *json = dynamic_cast<metawriter_json *>(metawriter.get());
|
||||
if (json) {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/palette.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
|
|
@ -269,9 +269,9 @@ void placement_finder<DetectorT>::find_line_breaks()
|
|||
// wrap text at first wrap_char after (default) the wrap width or immediately before the current word
|
||||
if ((c == '\n') ||
|
||||
(line_width > 0 &&
|
||||
((line_width > wrap_at && !ci.format->wrap_before) ||
|
||||
((line_width > wrap_at && !ci.format->wrap_before) ||
|
||||
((line_width + last_wrap_char_width + word_width) > wrap_at && ci.format->wrap_before)) )
|
||||
)
|
||||
)
|
||||
{
|
||||
add_line(line_width, line_height, first_line);
|
||||
line_breaks_.push_back(last_wrap_char_pos);
|
||||
|
@ -675,10 +675,10 @@ void placement_finder<DetectorT>::find_line_placements(PathT & shape_path)
|
|||
|
||||
template <typename DetectorT>
|
||||
std::auto_ptr<text_path> placement_finder<DetectorT>::get_placement_offset(std::vector<vertex2d> const& path_positions,
|
||||
std::vector<double> const& path_distances,
|
||||
int & orientation,
|
||||
unsigned index,
|
||||
double distance)
|
||||
std::vector<double> const& path_distances,
|
||||
int & orientation,
|
||||
unsigned index,
|
||||
double distance)
|
||||
{
|
||||
//Check that the given distance is on the given index and find the correct index and distance if not
|
||||
while (distance < 0 && index > 1)
|
||||
|
@ -718,10 +718,10 @@ std::auto_ptr<text_path> placement_finder<DetectorT>::get_placement_offset(std::
|
|||
}
|
||||
|
||||
std::auto_ptr<text_path> current_placement(
|
||||
new text_path((old_x + dx*distance/segment_length),
|
||||
(old_y + dy*distance/segment_length)
|
||||
)
|
||||
);
|
||||
new text_path((old_x + dx*distance/segment_length),
|
||||
(old_y + dy*distance/segment_length)
|
||||
)
|
||||
);
|
||||
|
||||
double angle = atan2(-dy, dx);
|
||||
|
||||
|
@ -830,7 +830,7 @@ std::auto_ptr<text_path> placement_finder<DetectorT>::get_placement_offset(std::
|
|||
render_angle += M_PI;
|
||||
}
|
||||
current_placement->add_node(&ci,
|
||||
render_x - current_placement->center.x,
|
||||
render_x - current_placement->center.x,
|
||||
-render_y + current_placement->center.y,
|
||||
render_angle);
|
||||
|
||||
|
@ -870,7 +870,7 @@ std::auto_ptr<text_path> placement_finder<DetectorT>::get_placement_offset(std::
|
|||
|
||||
template <typename DetectorT>
|
||||
bool placement_finder<DetectorT>::test_placement(std::auto_ptr<text_path> const& current_placement,
|
||||
int orientation)
|
||||
int orientation)
|
||||
{
|
||||
//Create and test envelopes
|
||||
bool status = true;
|
||||
|
@ -909,8 +909,8 @@ bool placement_finder<DetectorT>::test_placement(std::auto_ptr<text_path> const&
|
|||
if (!detector_.extent().intersects(e) ||
|
||||
(!p.allow_overlap &&
|
||||
!detector_.has_placement(e, info_.get_string(), pi.get_actual_minimum_distance())
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
//std::clog << "No Intersects:" << !dimensions_.intersects(e) << ": " << e << " @ " << dimensions_ << std::endl;
|
||||
//std::clog << "No Placements:" << !detector_.has_placement(e, info.get_string(), p.minimum_distance) << std::endl;
|
||||
|
|
|
@ -1,4 +1,28 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/processed_text.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
|
@ -43,7 +67,7 @@ string_info &processed_text::get_string_info()
|
|||
{
|
||||
if (!p.fontset.get_name().empty())
|
||||
{
|
||||
throw config_error("Unable to find specified font set '" + p.face_name + "'");
|
||||
throw config_error("Unable to find specified font set '" + p.fontset.get_name() + "'");
|
||||
} else if (!p.face_name.empty()) {
|
||||
throw config_error("Unable to find specified font face '" + p.face_name + "'");
|
||||
} else {
|
||||
|
|
171
src/rapidxml_loader.cpp
Normal file
171
src/rapidxml_loader.cpp
Normal file
|
@ -0,0 +1,171 @@
|
|||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_LIBXML2
|
||||
#error HAVE_LIBXML2 defined but compiling rapidxml_loader.cpp!
|
||||
#endif
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/xml_loader.hpp>
|
||||
#include <boost/property_tree/detail/xml_parser_read_rapidxml.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
|
||||
// stl
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
namespace rapidxml = boost::property_tree::detail::rapidxml;
|
||||
namespace mapnik
|
||||
{
|
||||
class rapidxml_loader : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
rapidxml_loader(const char *encoding = NULL) :
|
||||
filename_()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~rapidxml_loader()
|
||||
{
|
||||
}
|
||||
|
||||
void load(const std::string & filename, xml_node &node)
|
||||
{
|
||||
filename_ = filename;
|
||||
std::basic_ifstream<char> stream(filename.c_str());
|
||||
if (!stream)
|
||||
{
|
||||
throw config_error("Could not load map file", 0, filename);
|
||||
}
|
||||
// TODO: stream.imbue(loc);
|
||||
load(stream, node);
|
||||
}
|
||||
|
||||
void load(std::basic_istream<char> &stream, xml_node &node)
|
||||
{
|
||||
stream.unsetf(std::ios::skipws);
|
||||
std::vector<char> v(std::istreambuf_iterator<char>(stream.rdbuf()),
|
||||
std::istreambuf_iterator<char>());
|
||||
if (!stream.good())
|
||||
{
|
||||
throw config_error("Could not load map file", 0, filename_);
|
||||
}
|
||||
v.push_back(0); // zero-terminate
|
||||
try
|
||||
{
|
||||
// Parse using appropriate flags
|
||||
const int f_tws = rapidxml::parse_normalize_whitespace
|
||||
| rapidxml::parse_trim_whitespace;
|
||||
rapidxml::xml_document<> doc;
|
||||
doc.parse<f_tws>(&v.front());
|
||||
|
||||
for (rapidxml::xml_node<char> *child = doc.first_node();
|
||||
child; child = child->next_sibling())
|
||||
{
|
||||
populate_tree(child, node);
|
||||
}
|
||||
}
|
||||
catch (rapidxml::parse_error &e)
|
||||
{
|
||||
long line = static_cast<long>(
|
||||
std::count(&v.front(), e.where<char>(), '\n') + 1);
|
||||
throw config_error(e.what(), line, filename_);
|
||||
}
|
||||
}
|
||||
|
||||
void load_string(const std::string & buffer, xml_node &node, std::string const & base_path )
|
||||
{
|
||||
|
||||
// if (!base_path.empty())
|
||||
// {
|
||||
// boost::filesystem::path path(base_path);
|
||||
// if (!boost::filesystem::exists(path)) {
|
||||
// throw config_error(string("Could not locate base_path '") +
|
||||
// base_path + "': file or directory does not exist");
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
load(buffer, node);
|
||||
}
|
||||
private:
|
||||
void populate_tree(rapidxml::xml_node<char> *cur_node, xml_node &node)
|
||||
{
|
||||
switch (cur_node->type())
|
||||
{
|
||||
case rapidxml::node_element:
|
||||
{
|
||||
xml_node &new_node = node.add_child((char *)cur_node->name(), 0, false);
|
||||
// Copy attributes
|
||||
for (rapidxml::xml_attribute<char> *attr = cur_node->first_attribute();
|
||||
attr; attr = attr->next_attribute())
|
||||
{
|
||||
new_node.add_attribute(attr->name(), attr->value());
|
||||
}
|
||||
|
||||
// Copy children
|
||||
for (rapidxml::xml_node<char> *child = cur_node->first_node();
|
||||
child; child = child->next_sibling())
|
||||
{
|
||||
populate_tree(child, new_node);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Data nodes
|
||||
case rapidxml::node_data:
|
||||
case rapidxml::node_cdata:
|
||||
{
|
||||
std::string trimmed = boost::algorithm::trim_copy(std::string(cur_node->value()));
|
||||
if (trimmed.empty()) break; //Don't add empty text nodes
|
||||
node.add_child(trimmed, 0, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::string filename_;
|
||||
};
|
||||
|
||||
void read_xml(std::string const & filename, xml_node &node)
|
||||
{
|
||||
rapidxml_loader loader;
|
||||
loader.load(filename, node);
|
||||
}
|
||||
void read_xml_string(std::string const & str, xml_node &node, std::string const & base_path)
|
||||
{
|
||||
rapidxml_loader loader;
|
||||
loader.load_string(str, node, base_path);
|
||||
}
|
||||
|
||||
} // end of namespace mapnik
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <mapnik/svg/svg_parser.hpp>
|
||||
#include <mapnik/svg/svg_path_parser.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
#include "agg_ellipse.h"
|
||||
#include "agg_rounded_rect.h"
|
||||
|
|
|
@ -20,9 +20,14 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//mapnik
|
||||
#include <mapnik/text_placements/list.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
|
||||
//boost
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
|
@ -58,8 +63,7 @@ text_symbolizer_properties & text_placements_list::get(unsigned i)
|
|||
|
||||
text_placement_info_ptr text_placements_list::get_placement_info(double scale_factor) const
|
||||
{
|
||||
return text_placement_info_ptr(
|
||||
boost::make_shared<text_placement_info_list>(this, scale_factor));
|
||||
return boost::make_shared<text_placement_info_list>(this, scale_factor);
|
||||
}
|
||||
|
||||
text_placements_list::text_placements_list() : text_placements(), list_(0)
|
||||
|
@ -83,20 +87,19 @@ unsigned text_placements_list::size() const
|
|||
return list_.size();
|
||||
}
|
||||
|
||||
text_placements_ptr text_placements_list::from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets)
|
||||
text_placements_ptr text_placements_list::from_xml(xml_node const &xml, fontset_map const & fontsets)
|
||||
{
|
||||
using boost::property_tree::ptree;
|
||||
text_placements_list *list = new text_placements_list;
|
||||
text_placements_ptr ptr = text_placements_ptr(list);
|
||||
list->defaults.from_xml(xml, fontsets);
|
||||
ptree::const_iterator itr = xml.begin();
|
||||
ptree::const_iterator end = xml.end();
|
||||
xml_node::const_iterator itr = xml.begin();
|
||||
xml_node::const_iterator end = xml.end();
|
||||
for( ;itr != end; ++itr)
|
||||
{
|
||||
if ((itr->first.find('<') != std::string::npos) || (itr->first != "Placement")) continue;
|
||||
//TODO: ensure_attrs(symIter->second, "TextSymbolizer/Placement", s_common.str());
|
||||
if (itr->is_text() || !itr->is("Placement")) continue;
|
||||
text_symbolizer_properties &p = list->add();
|
||||
p.from_xml(itr->second, fontsets);
|
||||
p.from_xml(*itr, fontsets);
|
||||
//TODO: if (strict_ &&
|
||||
// !p.format.fontset.size())
|
||||
// ensure_font_face(p.format.face_name);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <mapnik/text_placements/simple.hpp>
|
||||
#include <mapnik/text_placements/list.hpp>
|
||||
#include <mapnik/text_placements/dummy.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
@ -46,10 +47,10 @@ void registry::register_name(std::string name, from_xml_function_ptr ptr, bool o
|
|||
}
|
||||
}
|
||||
|
||||
text_placements_ptr registry::from_xml(std::string name, const boost::property_tree::ptree &xml, fontset_map const& fontsets)
|
||||
text_placements_ptr registry::from_xml(std::string name, xml_node const& xml, fontset_map const& fontsets)
|
||||
{
|
||||
std::map<std::string, from_xml_function_ptr>::const_iterator itr = map_.find(name);
|
||||
if (itr == map_.end()) throw config_error("Unknown placement-type '" + name + "'");
|
||||
if (itr == map_.end()) throw config_error("Unknown placement-type '" + name + "'", xml);
|
||||
return itr->second(xml, fontsets);
|
||||
}
|
||||
} //ns formatting
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/text_placements/simple.hpp>
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
|
@ -102,8 +103,7 @@ bool text_placement_info_simple::next_position_only()
|
|||
text_placement_info_ptr text_placements_simple::get_placement_info(
|
||||
double scale_factor) const
|
||||
{
|
||||
return text_placement_info_ptr(
|
||||
boost::make_shared<text_placement_info_simple>(this, scale_factor));
|
||||
return boost::make_shared<text_placement_info_simple>(this, scale_factor);
|
||||
}
|
||||
|
||||
/** Position string: [POS][SIZE]
|
||||
|
@ -144,10 +144,12 @@ void text_placements_simple::set_positions(std::string positions)
|
|||
(direction_name[push_back(phoenix::ref(direction_), _1)] % ',') >> *(',' >> qi::float_[push_back(phoenix::ref(text_sizes_), _1)]),
|
||||
space
|
||||
);
|
||||
if (first != last) {
|
||||
if (first != last)
|
||||
{
|
||||
std::cerr << "WARNING: Could not parse text_placement_simple placement string ('" << positions << "').\n";
|
||||
}
|
||||
if (direction_.size() == 0) {
|
||||
if (direction_.size() == 0)
|
||||
{
|
||||
std::cerr << "WARNING: text_placements_simple with no valid placements! ('"<< positions<<"')\n";
|
||||
}
|
||||
}
|
||||
|
@ -167,10 +169,10 @@ std::string text_placements_simple::get_positions()
|
|||
return positions_; //TODO: Build string from data in direction_ and text_sizes_
|
||||
}
|
||||
|
||||
text_placements_ptr text_placements_simple::from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets)
|
||||
text_placements_ptr text_placements_simple::from_xml(xml_node const &xml, fontset_map const & fontsets)
|
||||
{
|
||||
text_placements_ptr ptr = boost::make_shared<text_placements_simple>(
|
||||
get_attr<std::string>(xml, "placements", "X"));
|
||||
xml.get_attr<std::string>("placements", "X"));
|
||||
ptr->defaults.from_xml(xml, fontsets);
|
||||
return ptr;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/expression_string.hpp>
|
||||
#include <mapnik/formatting/text.hpp>
|
||||
#include <mapnik/xml_node.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/make_shared.hpp>
|
||||
|
@ -79,45 +81,45 @@ formatting::node_ptr text_symbolizer_properties::format_tree() const
|
|||
return tree_;
|
||||
}
|
||||
|
||||
void text_symbolizer_properties::from_xml(boost::property_tree::ptree const &sym, fontset_map const & fontsets)
|
||||
void text_symbolizer_properties::from_xml(xml_node const &sym, fontset_map const & fontsets)
|
||||
{
|
||||
optional<label_placement_e> placement_ = get_opt_attr<label_placement_e>(sym, "placement");
|
||||
optional<label_placement_e> placement_ = sym.get_opt_attr<label_placement_e>("placement");
|
||||
if (placement_) label_placement = *placement_;
|
||||
optional<vertical_alignment_e> valign_ = get_opt_attr<vertical_alignment_e>(sym, "vertical-alignment");
|
||||
optional<vertical_alignment_e> valign_ = sym.get_opt_attr<vertical_alignment_e>("vertical-alignment");
|
||||
if (valign_) valign = *valign_;
|
||||
optional<unsigned> text_ratio_ = get_opt_attr<unsigned>(sym, "text-ratio");
|
||||
optional<unsigned> text_ratio_ = sym.get_opt_attr<unsigned>("text-ratio");
|
||||
if (text_ratio_) text_ratio = *text_ratio_;
|
||||
optional<unsigned> wrap_width_ = get_opt_attr<unsigned>(sym, "wrap-width");
|
||||
optional<unsigned> wrap_width_ = sym.get_opt_attr<unsigned>("wrap-width");
|
||||
if (wrap_width_) wrap_width = *wrap_width_;
|
||||
optional<unsigned> label_position_tolerance_ = get_opt_attr<unsigned>(sym, "label-position-tolerance");
|
||||
optional<unsigned> label_position_tolerance_ = sym.get_opt_attr<unsigned>("label-position-tolerance");
|
||||
if (label_position_tolerance_) label_position_tolerance = *label_position_tolerance_;
|
||||
optional<unsigned> spacing_ = get_opt_attr<unsigned>(sym, "spacing");
|
||||
optional<unsigned> spacing_ = sym.get_opt_attr<unsigned>("spacing");
|
||||
if (spacing_) label_spacing = *spacing_;
|
||||
optional<unsigned> minimum_distance_ = get_opt_attr<unsigned>(sym, "minimum-distance");
|
||||
optional<unsigned> minimum_distance_ = sym.get_opt_attr<unsigned>("minimum-distance");
|
||||
if (minimum_distance_) minimum_distance = *minimum_distance_;
|
||||
optional<unsigned> min_padding_ = get_opt_attr<unsigned>(sym, "minimum-padding");
|
||||
optional<unsigned> min_padding_ = sym.get_opt_attr<unsigned>("minimum-padding");
|
||||
if (min_padding_) minimum_padding = *min_padding_;
|
||||
optional<unsigned> min_path_length_ = get_opt_attr<unsigned>(sym, "minimum-path-length");
|
||||
optional<unsigned> min_path_length_ = sym.get_opt_attr<unsigned>("minimum-path-length");
|
||||
if (min_path_length_) minimum_path_length = *min_path_length_;
|
||||
optional<boolean> avoid_edges_ = get_opt_attr<boolean>(sym, "avoid-edges");
|
||||
optional<boolean> avoid_edges_ = sym.get_opt_attr<boolean>("avoid-edges");
|
||||
if (avoid_edges_) avoid_edges = *avoid_edges_;
|
||||
optional<boolean> allow_overlap_ = get_opt_attr<boolean>(sym, "allow-overlap");
|
||||
optional<boolean> allow_overlap_ = sym.get_opt_attr<boolean>("allow-overlap");
|
||||
if (allow_overlap_) allow_overlap = *allow_overlap_;
|
||||
optional<horizontal_alignment_e> halign_ = get_opt_attr<horizontal_alignment_e>(sym, "horizontal-alignment");
|
||||
optional<horizontal_alignment_e> halign_ = sym.get_opt_attr<horizontal_alignment_e>("horizontal-alignment");
|
||||
if (halign_) halign = *halign_;
|
||||
optional<justify_alignment_e> jalign_ = get_opt_attr<justify_alignment_e>(sym, "justify-alignment");
|
||||
optional<justify_alignment_e> jalign_ = sym.get_opt_attr<justify_alignment_e>("justify-alignment");
|
||||
if (jalign_) jalign = *jalign_;
|
||||
/* Attributes needing special care */
|
||||
optional<std::string> orientation_ = get_opt_attr<std::string>(sym, "orientation");
|
||||
optional<std::string> orientation_ = sym.get_opt_attr<std::string>("orientation");
|
||||
if (orientation_) orientation = parse_expression(*orientation_, "utf8");
|
||||
optional<double> dx = get_opt_attr<double>(sym, "dx");
|
||||
optional<double> dx = sym.get_opt_attr<double>("dx");
|
||||
if (dx) displacement.first = *dx;
|
||||
optional<double> dy = get_opt_attr<double>(sym, "dy");
|
||||
optional<double> dy = sym.get_opt_attr<double>("dy");
|
||||
if (dy) displacement.second = *dy;
|
||||
optional<double> max_char_angle_delta_ = get_opt_attr<double>(sym, "max-char-angle-delta");
|
||||
optional<double> max_char_angle_delta_ = sym.get_opt_attr<double>("max-char-angle-delta");
|
||||
if (max_char_angle_delta_) max_char_angle_delta=(*max_char_angle_delta_)*(M_PI/180);
|
||||
|
||||
optional<std::string> name_ = get_opt_attr<std::string>(sym, "name");
|
||||
optional<std::string> name_ = sym.get_opt_attr<std::string>("name");
|
||||
if (name_) {
|
||||
std::clog << "### WARNING: Using 'name' in TextSymbolizer/ShieldSymbolizer is deprecated!\n";
|
||||
set_old_style_expression(parse_expression(*name_, "utf8"));
|
||||
|
@ -241,34 +243,34 @@ char_properties::char_properties() :
|
|||
|
||||
}
|
||||
|
||||
void char_properties::from_xml(boost::property_tree::ptree const &sym, fontset_map const & fontsets)
|
||||
void char_properties::from_xml(xml_node const& sym, fontset_map const& fontsets)
|
||||
{
|
||||
optional<double> text_size_ = get_opt_attr<double>(sym, "size");
|
||||
optional<double> text_size_ = sym.get_opt_attr<double>("size");
|
||||
if (text_size_) text_size = *text_size_;
|
||||
optional<double> character_spacing_ = get_opt_attr<double>(sym, "character-spacing");
|
||||
optional<double> character_spacing_ = sym.get_opt_attr<double>("character-spacing");
|
||||
if (character_spacing_) character_spacing = *character_spacing_;
|
||||
optional<color> fill_ = get_opt_attr<color>(sym, "fill");
|
||||
optional<color> fill_ = sym.get_opt_attr<color>("fill");
|
||||
if (fill_) fill = *fill_;
|
||||
optional<color> halo_fill_ = get_opt_attr<color>(sym, "halo-fill");
|
||||
optional<color> halo_fill_ = sym.get_opt_attr<color>("halo-fill");
|
||||
if (halo_fill_) halo_fill = *halo_fill_;
|
||||
optional<double> halo_radius_ = get_opt_attr<double>(sym, "halo-radius");
|
||||
optional<double> halo_radius_ = sym.get_opt_attr<double>("halo-radius");
|
||||
if (halo_radius_) halo_radius = *halo_radius_;
|
||||
optional<boolean> wrap_before_ = get_opt_attr<boolean>(sym, "wrap-before");
|
||||
optional<boolean> wrap_before_ = sym.get_opt_attr<boolean>("wrap-before");
|
||||
if (wrap_before_) wrap_before = *wrap_before_;
|
||||
optional<text_transform_e> tconvert_ = get_opt_attr<text_transform_e>(sym, "text-transform");
|
||||
optional<text_transform_e> tconvert_ = sym.get_opt_attr<text_transform_e>("text-transform");
|
||||
if (tconvert_) text_transform = *tconvert_;
|
||||
optional<double> line_spacing_ = get_opt_attr<double>(sym, "line-spacing");
|
||||
optional<double> line_spacing_ = sym.get_opt_attr<double>("line-spacing");
|
||||
if (line_spacing_) line_spacing = *line_spacing_;
|
||||
optional<double> opacity_ = get_opt_attr<double>(sym, "opacity");
|
||||
optional<double> opacity_ = sym.get_opt_attr<double>("opacity");
|
||||
if (opacity_) text_opacity = *opacity_;
|
||||
optional<std::string> wrap_char_ = get_opt_attr<std::string>(sym, "wrap-character");
|
||||
optional<std::string> wrap_char_ = sym.get_opt_attr<std::string>("wrap-character");
|
||||
if (wrap_char_ && (*wrap_char_).size() > 0) wrap_char = ((*wrap_char_)[0]);
|
||||
optional<std::string> face_name_ = get_opt_attr<std::string>(sym, "face-name");
|
||||
optional<std::string> face_name_ = sym.get_opt_attr<std::string>("face-name");
|
||||
if (face_name_)
|
||||
{
|
||||
face_name = *face_name_;
|
||||
}
|
||||
optional<std::string> fontset_name_ = get_opt_attr<std::string>(sym, "fontset-name");
|
||||
optional<std::string> fontset_name_ = sym.get_opt_attr<std::string>("fontset-name");
|
||||
if (fontset_name_) {
|
||||
std::map<std::string,font_set>::const_iterator itr = fontsets.find(*fontset_name_);
|
||||
if (itr != fontsets.end())
|
||||
|
@ -277,16 +279,16 @@ void char_properties::from_xml(boost::property_tree::ptree const &sym, fontset_m
|
|||
}
|
||||
else
|
||||
{
|
||||
throw config_error("Unable to find any fontset named '" + *fontset_name_ + "'");
|
||||
throw config_error("Unable to find any fontset named '" + *fontset_name_ + "'", sym);
|
||||
}
|
||||
}
|
||||
if (!face_name.empty() && !fontset.get_name().empty())
|
||||
{
|
||||
throw config_error(std::string("Can't have both face-name and fontset-name"));
|
||||
throw config_error("Can't have both face-name and fontset-name", sym);
|
||||
}
|
||||
if (face_name.empty() && fontset.get_name().empty())
|
||||
{
|
||||
throw config_error(std::string("Must have face-name or fontset-name"));
|
||||
throw config_error("Must have face-name or fontset-name", sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
483
src/xml_tree.cpp
Normal file
483
src/xml_tree.cpp
Normal file
|
@ -0,0 +1,483 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//mapnik
|
||||
#include <mapnik/xml_tree.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/color_factory.hpp>
|
||||
#include <mapnik/gamma_method.hpp>
|
||||
#include <mapnik/line_symbolizer.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/text_properties.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
//boost
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
inline boost::optional<T> fast_cast(xml_tree const& tree, std::string const& value)
|
||||
{
|
||||
try
|
||||
{
|
||||
return boost::lexical_cast<T>(value);
|
||||
}
|
||||
catch (boost::bad_lexical_cast const& ex)
|
||||
{
|
||||
return boost::optional<T>();
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<int> fast_cast(xml_tree const& tree, std::string const& value)
|
||||
{
|
||||
int result;
|
||||
if (mapnik::conversions::string2int(value, result))
|
||||
return boost::optional<int>(result);
|
||||
return boost::optional<int>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<double> fast_cast(xml_tree const& tree, std::string const& value)
|
||||
{
|
||||
double result;
|
||||
if (mapnik::conversions::string2double(value, result))
|
||||
return boost::optional<double>(result);
|
||||
return boost::optional<double>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<float> fast_cast(xml_tree const& tree, std::string const& value)
|
||||
{
|
||||
float result;
|
||||
if (mapnik::conversions::string2float(value, result))
|
||||
return boost::optional<float>(result);
|
||||
return boost::optional<float>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<std::string> fast_cast(xml_tree const& tree, std::string const& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<color> fast_cast(xml_tree const& tree, std::string const& value)
|
||||
{
|
||||
mapnik::color c;
|
||||
if (mapnik::color_factory::parse_from_string(c, value, tree.color_grammar))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw config_error("Failed to parse color '"+value+"'");
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline boost::optional<expression_ptr> fast_cast(xml_tree const& tree, std::string const& value)
|
||||
{
|
||||
expression_ptr expr(boost::make_shared<expr_node>(true));
|
||||
if (expression_factory::parse_from_string(expr, value, tree.expr_grammar))
|
||||
{
|
||||
return expr;
|
||||
} else
|
||||
{
|
||||
throw mapnik::config_error("Failed to parse expression '" + value + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
class boolean;
|
||||
template <typename T>
|
||||
struct name_trait
|
||||
{
|
||||
static std::string name()
|
||||
{
|
||||
return "<unknown>";
|
||||
}
|
||||
// missing name_trait for type ...
|
||||
// if you get here you are probably using a new type
|
||||
// in the XML file. Just add a name trait for the new
|
||||
// type below.
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == 0 );
|
||||
};
|
||||
|
||||
#define DEFINE_NAME_TRAIT( type, type_name ) \
|
||||
template <> \
|
||||
struct name_trait<type> \
|
||||
{ \
|
||||
static std::string name() { return std::string("type ") + type_name; } \
|
||||
};
|
||||
|
||||
|
||||
DEFINE_NAME_TRAIT( double, "double")
|
||||
DEFINE_NAME_TRAIT( float, "float")
|
||||
DEFINE_NAME_TRAIT( unsigned, "unsigned")
|
||||
DEFINE_NAME_TRAIT( boolean, "boolean")
|
||||
DEFINE_NAME_TRAIT( int, "integer" )
|
||||
DEFINE_NAME_TRAIT( std::string, "string" )
|
||||
DEFINE_NAME_TRAIT( color, "color" )
|
||||
DEFINE_NAME_TRAIT(expression_ptr, "expression_ptr" )
|
||||
|
||||
template <typename ENUM, int MAX>
|
||||
struct name_trait< mapnik::enumeration<ENUM, MAX> >
|
||||
{
|
||||
typedef enumeration<ENUM, MAX> Enum;
|
||||
|
||||
static std::string name()
|
||||
{
|
||||
std::string value_list("one of [");
|
||||
for (unsigned i = 0; i < Enum::MAX; ++i)
|
||||
{
|
||||
value_list += Enum::get_string( i );
|
||||
if ( i + 1 < Enum::MAX ) value_list += ", ";
|
||||
}
|
||||
value_list += "]";
|
||||
|
||||
return value_list;
|
||||
}
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
xml_tree::xml_tree(std::string const& encoding)
|
||||
: node_(*this, "<root>"),
|
||||
file_(),
|
||||
tr_(encoding),
|
||||
color_grammar(),
|
||||
expr_grammar(tr_)
|
||||
{
|
||||
node_.set_processed(true); //root node is always processed
|
||||
}
|
||||
|
||||
void xml_tree::set_filename(std::string fn)
|
||||
{
|
||||
file_ = fn;
|
||||
}
|
||||
|
||||
std::string const& xml_tree::filename() const
|
||||
{
|
||||
return file_;
|
||||
}
|
||||
|
||||
xml_node &xml_tree::root()
|
||||
{
|
||||
return node_;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
xml_attribute::xml_attribute(std::string const& value_)
|
||||
: value(value_), processed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
node_not_found::node_not_found(std::string node_name)
|
||||
: node_name_(node_name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* node_not_found::what() const throw()
|
||||
{
|
||||
return ("Node "+node_name_+ "not found").c_str();
|
||||
}
|
||||
|
||||
node_not_found::~node_not_found() throw()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
attribute_not_found::attribute_not_found(
|
||||
std::string const& node_name,
|
||||
std::string const& attribute_name)
|
||||
:
|
||||
node_name_(node_name),
|
||||
attribute_name_(attribute_name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* attribute_not_found::what() const throw()
|
||||
{
|
||||
return ("Attribute '" + attribute_name_ +"' not found in node '"+node_name_+ "'").c_str();
|
||||
}
|
||||
|
||||
attribute_not_found::~attribute_not_found() throw()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
more_than_one_child::more_than_one_child(std::string const& node_name)
|
||||
: node_name_(node_name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* more_than_one_child::what() const throw()
|
||||
{
|
||||
return ("More than one child node in node '" + node_name_ +"'").c_str();
|
||||
}
|
||||
|
||||
more_than_one_child::~more_than_one_child() throw()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
xml_node::xml_node(xml_tree &tree, std::string name, unsigned line, bool text_node)
|
||||
: tree_(tree),
|
||||
name_(name),
|
||||
text_node_(text_node),
|
||||
line_(line),
|
||||
processed_(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string xml_node::xml_text = "<xmltext>";
|
||||
|
||||
std::string const& xml_node::name() const
|
||||
{
|
||||
if (!text_node_)
|
||||
return name_;
|
||||
else
|
||||
return xml_text;
|
||||
}
|
||||
|
||||
std::string const& xml_node::text() const
|
||||
{
|
||||
if (text_node_)
|
||||
{
|
||||
processed_ = true;
|
||||
return name_;
|
||||
} else
|
||||
{
|
||||
throw config_error("text() called on non-text node", *this);
|
||||
}
|
||||
}
|
||||
|
||||
std::string const& xml_node::filename() const
|
||||
{
|
||||
return tree_.filename();
|
||||
}
|
||||
|
||||
bool xml_node::is_text() const
|
||||
{
|
||||
return text_node_;
|
||||
}
|
||||
|
||||
bool xml_node::is(std::string const& name) const
|
||||
{
|
||||
if (name_ == name)
|
||||
{
|
||||
processed_ = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
xml_node &xml_node::add_child(std::string const& name, unsigned line, bool text_node)
|
||||
{
|
||||
children_.push_back(xml_node(tree_, name, line, text_node));
|
||||
return children_.back();
|
||||
}
|
||||
|
||||
void xml_node::add_attribute(std::string const& name, std::string const& value)
|
||||
{
|
||||
attributes_.insert(std::make_pair(name,xml_attribute(value)));
|
||||
}
|
||||
|
||||
xml_node::attribute_map const& xml_node::get_attributes() const
|
||||
{
|
||||
return attributes_;
|
||||
}
|
||||
|
||||
void xml_node::set_processed(bool processed) const
|
||||
{
|
||||
processed_ = processed;
|
||||
}
|
||||
|
||||
bool xml_node::processed() const
|
||||
{
|
||||
return processed_;
|
||||
}
|
||||
|
||||
xml_node::const_iterator xml_node::begin() const
|
||||
{
|
||||
return children_.begin();
|
||||
}
|
||||
|
||||
xml_node::const_iterator xml_node::end() const
|
||||
{
|
||||
return children_.end();
|
||||
}
|
||||
|
||||
xml_node & xml_node::get_child(std::string const& name)
|
||||
{
|
||||
std::list<xml_node>::iterator itr = children_.begin();
|
||||
std::list<xml_node>::iterator end = children_.end();
|
||||
for (; itr != end; itr++)
|
||||
{
|
||||
if (!(itr->text_node_) && itr->name_ == name)
|
||||
{
|
||||
itr->set_processed(true);
|
||||
return *itr;
|
||||
}
|
||||
}
|
||||
throw node_not_found(name);
|
||||
}
|
||||
|
||||
xml_node const& xml_node::get_child(std::string const& name) const
|
||||
{
|
||||
xml_node const* node = get_opt_child(name);
|
||||
if (!node) throw node_not_found(name);
|
||||
return *node;
|
||||
}
|
||||
|
||||
xml_node const* xml_node::get_opt_child(std::string const& name) const
|
||||
{
|
||||
const_iterator itr = children_.begin();
|
||||
const_iterator end = children_.end();
|
||||
for (; itr != end; itr++)
|
||||
{
|
||||
if (!(itr->text_node_) && itr->name_ == name)
|
||||
{
|
||||
itr->set_processed(true);
|
||||
return &(*itr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool xml_node::has_child(std::string const& name) const
|
||||
{
|
||||
return get_opt_child(name) != 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
boost::optional<T> xml_node::get_opt_attr(std::string const& name) const
|
||||
{
|
||||
std::map<std::string, xml_attribute>::const_iterator itr = attributes_.find(name);
|
||||
if (itr == attributes_.end()) return boost::optional<T>();
|
||||
itr->second.processed = true;
|
||||
boost::optional<T> result = fast_cast<T>(tree_, itr->second.value);
|
||||
if (!result)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse attribute '") +
|
||||
name + "'. Expected " + name_trait<T>::name() +
|
||||
" but got '" + itr->second.value + "'", *this);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T xml_node::get_attr(std::string const& name, T const& default_value) const
|
||||
{
|
||||
boost::optional<T> value = get_opt_attr<T>(name);
|
||||
if (value) return *value;
|
||||
return default_value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T xml_node::get_attr(std::string const& name) const
|
||||
{
|
||||
boost::optional<T> value = get_opt_attr<T>(name);
|
||||
if (value) return *value;
|
||||
throw attribute_not_found(name_, name);
|
||||
}
|
||||
|
||||
std::string xml_node::get_text() const
|
||||
{
|
||||
if (children_.size() == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
if (children_.size() == 1)
|
||||
{
|
||||
return children_.front().text();
|
||||
}
|
||||
throw more_than_one_child(name_);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T xml_node::get_value() const
|
||||
{
|
||||
boost::optional<T> result = fast_cast<T>(tree_, get_text());
|
||||
if (!result)
|
||||
{
|
||||
throw config_error(std::string("Failed to parse value. Expected ")
|
||||
+ name_trait<T>::name() +
|
||||
" but got '" + get_text() + "'", *this);
|
||||
}
|
||||
return *result;
|
||||
}
|
||||
|
||||
unsigned xml_node::line() const
|
||||
{
|
||||
return line_;
|
||||
}
|
||||
|
||||
#define compile_get_opt_attr(T) template boost::optional<T> xml_node::get_opt_attr<T>(std::string const&) const
|
||||
#define compile_get_attr(T) template T xml_node::get_attr<T>(std::string const&) const; template T xml_node::get_attr<T>(std::string const&, T const&) const
|
||||
#define compile_get_value(T) template T xml_node::get_value<T>() const
|
||||
|
||||
compile_get_opt_attr(boolean);
|
||||
compile_get_opt_attr(std::string);
|
||||
compile_get_opt_attr(unsigned);
|
||||
compile_get_opt_attr(float);
|
||||
compile_get_opt_attr(double);
|
||||
compile_get_opt_attr(color);
|
||||
compile_get_opt_attr(gamma_method_e);
|
||||
compile_get_opt_attr(line_rasterizer_e);
|
||||
compile_get_opt_attr(line_join_e);
|
||||
compile_get_opt_attr(line_cap_e);
|
||||
compile_get_opt_attr(text_transform_e);
|
||||
compile_get_opt_attr(label_placement_e);
|
||||
compile_get_opt_attr(vertical_alignment_e);
|
||||
compile_get_opt_attr(horizontal_alignment_e);
|
||||
compile_get_opt_attr(justify_alignment_e);
|
||||
compile_get_opt_attr(expression_ptr);
|
||||
compile_get_attr(std::string);
|
||||
compile_get_attr(filter_mode_e);
|
||||
compile_get_attr(point_placement_e);
|
||||
compile_get_attr(marker_placement_e);
|
||||
compile_get_attr(marker_type_e);
|
||||
compile_get_attr(pattern_alignment_e);
|
||||
compile_get_attr(line_rasterizer_e);
|
||||
compile_get_attr(colorizer_mode);
|
||||
compile_get_attr(double);
|
||||
compile_get_value(int);
|
||||
compile_get_value(double);
|
||||
compile_get_value(expression_ptr);
|
||||
} //ns mapnik
|
|
@ -230,13 +230,8 @@ def test_map_init_from_string():
|
|||
map_string = '''<Map background-color="steelblue" base="./" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
||||
<Style name="My Style">
|
||||
<Rule>
|
||||
<PolygonSymbolizer>
|
||||
<CssParameter name="fill">#f2eff9</CssParameter>
|
||||
</PolygonSymbolizer>
|
||||
<LineSymbolizer>
|
||||
<CssParameter name="stroke">rgb(50%,50%,50%)</CssParameter>
|
||||
<CssParameter name="stroke-width">0.1</CssParameter>
|
||||
</LineSymbolizer>
|
||||
<PolygonSymbolizer fill="#f2eff9"/>
|
||||
<LineSymbolizer stroke="rgb(50%,50%,50%)" stroke-width="0.1"/>
|
||||
</Rule>
|
||||
</Style>
|
||||
<Layer name="boundaries">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import math, operator
|
||||
#import math, operator
|
||||
import Image
|
||||
import sys
|
||||
|
||||
|
@ -27,6 +27,10 @@ def compare(fn1, fn2):
|
|||
return -1
|
||||
diff = 0
|
||||
pixels = im1.size[0] * im1.size[1]
|
||||
delta_pixels = im2.size[0] * im2.size[1] - pixels
|
||||
if delta_pixels != 0:
|
||||
errors.append((fn1, delta_pixels))
|
||||
return delta_pixels
|
||||
im1 = im1.getdata()
|
||||
im2 = im2.getdata()
|
||||
for i in range(3, pixels - 1, 3):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map>
|
||||
<Map background-color="green" srs="+proj=latlong +datum=WGS84">
|
||||
<Map background-color="green" srs="+proj=latlong +datum=WGS84" minimum-version="2.0.0">
|
||||
|
||||
<Layer name="layer" srs="+proj=latlong +datum=WGS84">
|
||||
<StyleName>My Style</StyleName>
|
||||
|
|
|
@ -50,7 +50,7 @@ def render(filename, width, height=100):
|
|||
return m
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
files = [(sys.argv[1], 500)]
|
||||
files = [(sys.argv[1], (500, 500))]
|
||||
elif len(sys.argv) > 2:
|
||||
files = [sys.argv[1:]]
|
||||
|
||||
|
|
Loading…
Reference in a new issue