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;
|
using namespace mapnik;
|
||||||
|
|
||||||
/* Notes:
|
/* Notes:
|
||||||
Overriding functions in inherited classes:
|
Overriding functions in inherited classes:
|
||||||
boost.python documentation doesn't really tell you how to do it.
|
boost.python documentation doesn't really tell you how to do it.
|
||||||
But this helps:
|
But this helps:
|
||||||
http://www.gamedev.net/topic/446225-inheritance-in-boostpython/
|
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
|
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.
|
normal functions taking a ref to the class as first parameter.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -103,7 +103,7 @@ struct python_optional : public boost::noncopyable
|
||||||
/** This class works around a bug in boost python.
|
/** 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>
|
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>
|
class class_with_converter : public boost::python::class_<T, X1, X2, X3>
|
||||||
{
|
{
|
||||||
|
|
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;
|
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
|
// mapnik
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/color.hpp>
|
|
||||||
#include <mapnik/config_error.hpp>
|
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/utility.hpp>
|
#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 {
|
namespace mapnik {
|
||||||
|
|
||||||
|
class color;
|
||||||
|
|
||||||
|
template <typename Iterator> struct css_color_grammar;
|
||||||
class MAPNIK_DECL color_factory : boost::noncopyable
|
class MAPNIK_DECL color_factory : boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void init_from_string(color & c, std::string const& css_color)
|
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 bool parse_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)
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static color from_string(std::string const& css_color)
|
static color from_string(std::string const& css_color);
|
||||||
{
|
|
||||||
color c;
|
|
||||||
init_from_string(c,css_color);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#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
|
#endif // MAPNIK_COLOR_FACTORY_HPP
|
||||||
|
|
|
@ -28,31 +28,28 @@
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
|
class xml_node;
|
||||||
class config_error : public std::exception
|
class config_error : public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
config_error():
|
config_error(std::string const& what);
|
||||||
what_() {}
|
config_error(std::string const& what, xml_node const& node);
|
||||||
|
config_error(std::string const& what, unsigned line_number, std::string const& filename);
|
||||||
config_error( std::string const& what ) :
|
|
||||||
what_( what )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
virtual ~config_error() throw() {}
|
virtual ~config_error() throw() {}
|
||||||
|
|
||||||
virtual const char * what() const throw()
|
virtual const char * what() const throw();
|
||||||
{
|
|
||||||
return what_.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_context(std::string const& ctx) const
|
|
||||||
{
|
|
||||||
what_ += " " + ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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:
|
protected:
|
||||||
mutable std::string what_;
|
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
|
#endif // MAPNIK_CONFIG_ERROR_HPP
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/expression_node.hpp>
|
#include <mapnik/expression_node.hpp>
|
||||||
#include <mapnik/expression_grammar.hpp>
|
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -35,6 +34,7 @@ namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef boost::shared_ptr<expr_node> expression_ptr;
|
typedef boost::shared_ptr<expr_node> expression_ptr;
|
||||||
|
template <typename Iterator> struct expression_grammar;
|
||||||
|
|
||||||
class expression_factory
|
class expression_factory
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace mapnik {
|
||||||
|
|
||||||
typedef std::set<expression_ptr> expression_set;
|
typedef std::set<expression_ptr> expression_set;
|
||||||
class processed_text;
|
class processed_text;
|
||||||
|
class xml_node;
|
||||||
struct char_properties;
|
struct char_properties;
|
||||||
|
|
||||||
namespace formatting {
|
namespace formatting {
|
||||||
|
@ -48,7 +49,7 @@ class node
|
||||||
public:
|
public:
|
||||||
virtual ~node() {}
|
virtual ~node() {}
|
||||||
virtual void to_xml(boost::property_tree::ptree &xml) const;
|
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 apply(char_properties const& p, Feature const& feature, processed_text &output) const = 0;
|
||||||
virtual void add_expressions(expression_set &output) const;
|
virtual void add_expressions(expression_set &output) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace formatting {
|
||||||
class expression_format: public node {
|
class expression_format: public node {
|
||||||
public:
|
public:
|
||||||
void to_xml(boost::property_tree::ptree &xml) const;
|
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 apply(char_properties const& p, Feature const& feature, processed_text &output) const;
|
||||||
virtual void add_expressions(expression_set &output) const;
|
virtual void add_expressions(expression_set &output) const;
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
node_ptr child_;
|
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 formatting
|
||||||
} //ns mapnik
|
} //ns mapnik
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace formatting {
|
||||||
class format_node: public node {
|
class format_node: public node {
|
||||||
public:
|
public:
|
||||||
void to_xml(boost::property_tree::ptree &xml) const;
|
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 apply(char_properties const& p, Feature const& feature, processed_text &output) const;
|
||||||
virtual void add_expressions(expression_set &output) const;
|
virtual void add_expressions(expression_set &output) const;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace mapnik
|
||||||
namespace formatting
|
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>,
|
class registry : public singleton<registry, CreateStatic>,
|
||||||
private boost::noncopyable
|
private boost::noncopyable
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
registry();
|
registry();
|
||||||
~registry() {}
|
~registry() {}
|
||||||
void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false);
|
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:
|
private:
|
||||||
std::map<std::string, from_xml_function_ptr> map_;
|
std::map<std::string, from_xml_function_ptr> map_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
text_node(expression_ptr text): node(), text_(text) {}
|
text_node(expression_ptr text): node(), text_(text) {}
|
||||||
text_node(std::string text): node(), text_(parse_expression(text)) {}
|
text_node(std::string text): node(), text_(parse_expression(text)) {}
|
||||||
void to_xml(boost::property_tree::ptree &xml) const;
|
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 apply(char_properties const& p, Feature const& feature, processed_text &output) const;
|
||||||
virtual void add_expressions(expression_set &output) const;
|
virtual void add_expressions(expression_set &output) const;
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,34 @@
|
||||||
#ifndef DUMP_XML_HPP
|
#ifndef DUMP_XML_HPP
|
||||||
#define DUMP_XML_HPP
|
#define DUMP_XML_HPP
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <mapnik/xml_node.hpp>
|
||||||
|
|
||||||
/* Debug dump ptree XML representation.
|
/* 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;
|
std::string indent;
|
||||||
int i;
|
unsigned i;
|
||||||
for (i=0; i<level; i++)
|
for (i=0; i<level; i++)
|
||||||
{
|
{
|
||||||
indent += " ";
|
indent += " ";
|
||||||
}
|
}
|
||||||
if (xml.data().length()) std::cout << indent << "data: '" << xml.data() << "'\n";
|
xml_node::attribute_map const& attr = xml.get_attributes();
|
||||||
boost::property_tree::ptree::const_iterator itr = xml.begin();
|
std::cerr << indent <<"[" << xml.name();
|
||||||
boost::property_tree::ptree::const_iterator end = xml.end();
|
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++)
|
for (; itr!=end; itr++)
|
||||||
{
|
{
|
||||||
std::cout << indent <<"[" << itr->first << "]" << "\n";
|
dump_xml(*itr, level+1);
|
||||||
dump_xml(itr->second, level+1);
|
|
||||||
std::cout << indent << "[/" << itr->first << "]" << "\n";
|
|
||||||
}
|
}
|
||||||
|
std::cerr << indent << "[/" << xml.name() << "]" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
class xml_node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a metawriter with the properties specified in the property
|
* 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
|
* metawriters, but should provide an easy point to make them a
|
||||||
* proper factory method if this is wanted in the future.
|
* 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
|
* Writes properties into the given property tree representing the
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
|
@ -23,450 +23,17 @@
|
||||||
#ifndef MAPNIK_PTREE_HELPERS_HPP
|
#ifndef MAPNIK_PTREE_HELPERS_HPP
|
||||||
#define 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
|
// boost
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
|
||||||
|
|
||||||
// stl
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace mapnik {
|
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>
|
template <typename T>
|
||||||
void set_attr(boost::property_tree::ptree & pt, std::string const& name, T const& v)
|
void set_attr(boost::property_tree::ptree & pt, std::string const& name, T const& v)
|
||||||
{
|
{
|
||||||
pt.put("<xmlattr>." + name, 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
|
} // end of namespace mapnik
|
||||||
|
|
||||||
#endif // MAPNIK_PTREE_HELPERS_HPP
|
#endif // MAPNIK_PTREE_HELPERS_HPP
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
|
||||||
#include <mapnik/color.hpp>
|
#include <mapnik/color.hpp>
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
#include <mapnik/enumeration.hpp>
|
#include <mapnik/enumeration.hpp>
|
||||||
|
|
|
@ -65,11 +65,11 @@ public:
|
||||||
detector_(detector),
|
detector_(detector),
|
||||||
writer_(sym.get_metawriter()),
|
writer_(sym.get_metawriter()),
|
||||||
dims_(0, 0, width, height),
|
dims_(0, 0, width, height),
|
||||||
|
query_extent_(query_extent),
|
||||||
text_(font_manager, scale_factor),
|
text_(font_manager, scale_factor),
|
||||||
angle_(0.0),
|
angle_(0.0),
|
||||||
placement_valid_(false),
|
placement_valid_(false),
|
||||||
points_on_line_(false),
|
points_on_line_(false),
|
||||||
query_extent_(query_extent),
|
|
||||||
finder_()
|
finder_()
|
||||||
{
|
{
|
||||||
initialize_geometries();
|
initialize_geometries();
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
text_symbolizer_properties & add();
|
text_symbolizer_properties & add();
|
||||||
text_symbolizer_properties & get(unsigned i);
|
text_symbolizer_properties & get(unsigned i);
|
||||||
unsigned size() const;
|
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:
|
private:
|
||||||
std::vector<text_symbolizer_properties> list_;
|
std::vector<text_symbolizer_properties> list_;
|
||||||
friend class text_placement_info_list;
|
friend class text_placement_info_list;
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace placements
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef text_placements_ptr (*from_xml_function_ptr)(
|
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>,
|
class registry : public singleton<registry, CreateStatic>,
|
||||||
private boost::noncopyable
|
private boost::noncopyable
|
||||||
|
@ -49,7 +49,7 @@ public:
|
||||||
~registry() {}
|
~registry() {}
|
||||||
void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false);
|
void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false);
|
||||||
text_placements_ptr from_xml(std::string name,
|
text_placements_ptr from_xml(std::string name,
|
||||||
boost::property_tree::ptree const& xml,
|
xml_node const& xml,
|
||||||
fontset_map const & fontsets);
|
fontset_map const & fontsets);
|
||||||
private:
|
private:
|
||||||
std::map<std::string, from_xml_function_ptr> map_;
|
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;
|
text_placement_info_ptr get_placement_info(double scale_factor) const;
|
||||||
void set_positions(std::string positions);
|
void set_positions(std::string positions);
|
||||||
std::string get_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:
|
private:
|
||||||
std::string positions_;
|
std::string positions_;
|
||||||
std::vector<directions_t> direction_;
|
std::vector<directions_t> direction_;
|
||||||
|
|
|
@ -54,7 +54,7 @@ struct char_properties
|
||||||
{
|
{
|
||||||
char_properties();
|
char_properties();
|
||||||
/** Construct object from XML. */
|
/** 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. */
|
/** Write object to XML ptree. */
|
||||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const& dfl=char_properties()) const;
|
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const& dfl=char_properties()) const;
|
||||||
std::string face_name;
|
std::string face_name;
|
||||||
|
@ -124,7 +124,7 @@ struct text_symbolizer_properties
|
||||||
{
|
{
|
||||||
text_symbolizer_properties();
|
text_symbolizer_properties();
|
||||||
/** Load all values from XML ptree. */
|
/** 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!). */
|
/** 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;
|
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 {
|
namespace mapnik { namespace conversions {
|
||||||
|
|
||||||
bool string2int(const char * value, int & result);
|
bool string2int(const char * value, int & result);
|
||||||
bool string2int(std::string const& value, int & result);
|
bool string2int(std::string const& value, int & result);
|
||||||
|
|
||||||
bool string2double(std::string const& value, double & result);
|
bool string2double(std::string const& value, double & result);
|
||||||
bool string2double(const char * value, double & result);
|
bool string2double(const char * value, double & result);
|
||||||
|
|
||||||
bool string2float(std::string const& value, float & result);
|
bool string2float(std::string const& value, float & result);
|
||||||
bool string2float(const char * value, float & result);
|
bool string2float(const char * value, float & result);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MAPNIK_CONVERSIONS_UTIL_HPP
|
#endif // MAPNIK_CONVERSIONS_UTIL_HPP
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
#include <mapnik/unicode.hpp>
|
#include <mapnik/unicode.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
|
|
|
@ -23,16 +23,14 @@
|
||||||
#ifndef MAPNIK_LIBXML2_LOADER_HPP
|
#ifndef MAPNIK_LIBXML2_LOADER_HPP
|
||||||
#define MAPNIK_LIBXML2_LOADER_HPP
|
#define MAPNIK_LIBXML2_LOADER_HPP
|
||||||
|
|
||||||
// boost
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
void read_xml2( std::string const & filename, boost::property_tree::ptree & pt);
|
class xml_node;
|
||||||
void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt, std::string const & base_path="");
|
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
|
#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/lexical_cast.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/include/qi.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/feature_layer_desc.hpp>
|
#include <mapnik/feature_layer_desc.hpp>
|
||||||
|
@ -14,7 +15,7 @@
|
||||||
#include <mapnik/memory_featureset.hpp>
|
#include <mapnik/memory_featureset.hpp>
|
||||||
#include <mapnik/wkt/wkt_factory.hpp>
|
#include <mapnik/wkt/wkt_factory.hpp>
|
||||||
#include <mapnik/util/geometry_to_ds_type.hpp>
|
#include <mapnik/util/geometry_to_ds_type.hpp>
|
||||||
#include <mapnik/ptree_helpers.hpp> // mapnik::boolean
|
#include <mapnik/boolean.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "gdal_featureset.hpp"
|
#include "gdal_featureset.hpp"
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/boolean.hpp>
|
||||||
#include <mapnik/geom_util.hpp>
|
#include <mapnik/geom_util.hpp>
|
||||||
|
|
||||||
#include <gdal_version.h>
|
#include <gdal_version.h>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/boolean.hpp>
|
||||||
#include <mapnik/geom_util.hpp>
|
#include <mapnik/geom_util.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/boolean.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "occi_featureset.hpp"
|
#include "occi_featureset.hpp"
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/boolean.hpp>
|
||||||
#include <mapnik/sql_utils.hpp>
|
#include <mapnik/sql_utils.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include <gdal_version.h>
|
#include <gdal_version.h>
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/boolean.hpp>
|
||||||
#include <mapnik/geom_util.hpp>
|
#include <mapnik/geom_util.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/boolean.hpp>
|
||||||
#include <mapnik/sql_utils.hpp>
|
#include <mapnik/sql_utils.hpp>
|
||||||
#include <mapnik/util/conversions.hpp>
|
#include <mapnik/util/conversions.hpp>
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/boolean.hpp>
|
||||||
#include <mapnik/geom_util.hpp>
|
#include <mapnik/geom_util.hpp>
|
||||||
|
|
||||||
using mapnik::datasource;
|
using mapnik::datasource;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "sqlite_utils.hpp"
|
#include "sqlite_utils.hpp"
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/boolean.hpp>
|
||||||
#include <mapnik/sql_utils.hpp>
|
#include <mapnik/sql_utils.hpp>
|
||||||
#include <mapnik/util/geometry_to_ds_type.hpp>
|
#include <mapnik/util/geometry_to_ds_type.hpp>
|
||||||
#include <mapnik/wkb.hpp>
|
#include <mapnik/wkb.hpp>
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <mapnik/marker.hpp>
|
#include <mapnik/marker.hpp>
|
||||||
#include <mapnik/marker_cache.hpp>
|
#include <mapnik/marker_cache.hpp>
|
||||||
#include <mapnik/unicode.hpp>
|
#include <mapnik/unicode.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
|
||||||
#include <mapnik/font_set.hpp>
|
#include <mapnik/font_set.hpp>
|
||||||
#include <mapnik/parse_path.hpp>
|
#include <mapnik/parse_path.hpp>
|
||||||
#include <mapnik/map.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/list.cpp
|
||||||
text_placements/simple.cpp
|
text_placements/simple.cpp
|
||||||
text_properties.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 = lib_env.Clone()
|
||||||
env2.Append(CXXFLAGS = '-DHAVE_LIBXML2')
|
env2.Append(CXXFLAGS = '-DHAVE_LIBXML2')
|
||||||
libmapnik_cxxflags.append('-DHAVE_LIBXML2')
|
libmapnik_cxxflags.append('-DHAVE_LIBXML2')
|
||||||
fixup = ['load_map.cpp','libxml2_loader.cpp']
|
fixup = ['libxml2_loader.cpp']
|
||||||
for cpp in fixup:
|
for cpp in fixup:
|
||||||
if cpp in source:
|
if cpp in source:
|
||||||
source.remove(cpp)
|
source.remove(cpp)
|
||||||
|
@ -307,6 +309,12 @@ if env['XMLPARSER'] == 'libxml2' and env['HAS_LIBXML2']:
|
||||||
source.insert(0,env2.StaticObject(cpp))
|
source.insert(0,env2.StaticObject(cpp))
|
||||||
else:
|
else:
|
||||||
source.insert(0,env2.SharedObject(cpp))
|
source.insert(0,env2.SharedObject(cpp))
|
||||||
|
else:
|
||||||
|
source += Split(
|
||||||
|
"""
|
||||||
|
rapidxml_loader.cpp
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
if env['CUSTOM_LDFLAGS']:
|
if env['CUSTOM_LDFLAGS']:
|
||||||
linkflags = '%s %s' % (env['CUSTOM_LDFLAGS'], mapnik_lib_link_flag)
|
linkflags = '%s %s' % (env['CUSTOM_LDFLAGS'], mapnik_lib_link_flag)
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <mapnik/unicode.hpp>
|
#include <mapnik/unicode.hpp>
|
||||||
#include <mapnik/markers_placement.hpp>
|
#include <mapnik/markers_placement.hpp>
|
||||||
#include <mapnik/arrow.hpp>
|
#include <mapnik/arrow.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
|
||||||
#include <mapnik/parse_path.hpp>
|
#include <mapnik/parse_path.hpp>
|
||||||
#include <mapnik/marker.hpp>
|
#include <mapnik/marker.hpp>
|
||||||
#include <mapnik/marker_cache.hpp>
|
#include <mapnik/marker_cache.hpp>
|
||||||
|
|
|
@ -25,11 +25,23 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/color.hpp>
|
#include <mapnik/color.hpp>
|
||||||
#include <mapnik/color_factory.hpp>
|
#include <mapnik/color_factory.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <sstream>
|
#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 {
|
namespace mapnik {
|
||||||
|
|
||||||
color::color( std::string const& css_string)
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -35,9 +35,9 @@ namespace mapnik { namespace conversions {
|
||||||
|
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
|
|
||||||
BOOST_SPIRIT_AUTO(qi, INTEGER, qi::int_);
|
BOOST_SPIRIT_AUTO(qi, INTEGER, qi::int_)
|
||||||
BOOST_SPIRIT_AUTO(qi, FLOAT, qi::float_);
|
BOOST_SPIRIT_AUTO(qi, FLOAT, qi::float_)
|
||||||
BOOST_SPIRIT_AUTO(qi, DOUBLE, qi::double_);
|
BOOST_SPIRIT_AUTO(qi, DOUBLE, qi::double_)
|
||||||
|
|
||||||
bool string2int(const char * value, int & result)
|
bool string2int(const char * value, int & result)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <mapnik/expression.hpp>
|
#include <mapnik/expression.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
#include <mapnik/config_error.hpp>
|
||||||
#include <mapnik/unicode.hpp>
|
#include <mapnik/unicode.hpp>
|
||||||
|
#include <mapnik/expression_grammar.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <mapnik/formatting/base.hpp>
|
#include <mapnik/formatting/base.hpp>
|
||||||
#include <mapnik/formatting/list.hpp>
|
#include <mapnik/formatting/list.hpp>
|
||||||
#include <mapnik/formatting/registry.hpp>
|
#include <mapnik/formatting/registry.hpp>
|
||||||
|
#include <mapnik/xml_node.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
@ -38,18 +39,18 @@ void node::to_xml(boost::property_tree::ptree &xml) const
|
||||||
#endif
|
#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();
|
list_node *list = new list_node();
|
||||||
node_ptr list_ptr(list);
|
node_ptr list_ptr(list);
|
||||||
boost::property_tree::ptree::const_iterator itr = xml.begin();
|
xml_node::const_iterator itr = xml.begin();
|
||||||
boost::property_tree::ptree::const_iterator end = xml.end();
|
xml_node::const_iterator end = xml.end();
|
||||||
for (; itr != end; ++itr) {
|
for (; itr != end; ++itr) {
|
||||||
if (itr->first == "<xmlcomment>" || itr->first == "<xmlattr>" || itr->first == "Placement")
|
if (itr->name() == "Placement")
|
||||||
{
|
{
|
||||||
continue;
|
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 (n) list->push_back(n);
|
||||||
}
|
}
|
||||||
if (list->get_children().size() == 1) {
|
if (list->get_children().size() == 1) {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <mapnik/expression_evaluator.hpp>
|
#include <mapnik/expression_evaluator.hpp>
|
||||||
#include <mapnik/text_properties.hpp>
|
#include <mapnik/text_properties.hpp>
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/xml_node.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ namespace formatting
|
||||||
using boost::property_tree::ptree;
|
using boost::property_tree::ptree;
|
||||||
void expression_format::to_xml(boost::property_tree::ptree &xml) const
|
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 (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 (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);
|
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);
|
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();
|
expression_format *n = new expression_format();
|
||||||
node_ptr np(n);
|
node_ptr np(n);
|
||||||
|
@ -72,9 +73,9 @@ node_ptr expression_format::from_xml(ptree const& xml)
|
||||||
return np;
|
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);
|
if (tmp) return parse_expression(*tmp);
|
||||||
return expression_ptr();
|
return expression_ptr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#include <mapnik/formatting/format.hpp>
|
#include <mapnik/formatting/format.hpp>
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/ptree_helpers.hpp>
|
||||||
|
#include <mapnik/xml_node.hpp>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
using boost::property_tree::ptree;
|
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();
|
format_node *n = new format_node();
|
||||||
node_ptr np(n);
|
node_ptr np(n);
|
||||||
|
@ -52,19 +53,19 @@ node_ptr format_node::from_xml(ptree const& xml)
|
||||||
node_ptr child = node::from_xml(xml);
|
node_ptr child = node::from_xml(xml);
|
||||||
n->set_child(child);
|
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... */
|
/*TODO: Fontset is problematic. We don't have the fontsets pointer here... */
|
||||||
n->text_size = get_opt_attr<unsigned>(xml, "size");
|
n->text_size = xml.get_opt_attr<unsigned>("size");
|
||||||
n->character_spacing = get_opt_attr<unsigned>(xml, "character-spacing");
|
n->character_spacing = xml.get_opt_attr<unsigned>("character-spacing");
|
||||||
n->line_spacing = get_opt_attr<unsigned>(xml, "line-spacing");
|
n->line_spacing = xml.get_opt_attr<unsigned>("line-spacing");
|
||||||
n->text_opacity = get_opt_attr<double>(xml, "opactity");
|
n->text_opacity = xml.get_opt_attr<double>("opactity");
|
||||||
boost::optional<boolean> wrap = get_opt_attr<boolean>(xml, "wrap-before");
|
boost::optional<boolean> wrap = xml.get_opt_attr<boolean>("wrap-before");
|
||||||
if (wrap) n->wrap_before = *wrap;
|
if (wrap) n->wrap_before = *wrap;
|
||||||
n->wrap_char = get_opt_attr<unsigned>(xml, "wrap-character");
|
n->wrap_char = xml.get_opt_attr<unsigned>("wrap-character");
|
||||||
n->text_transform = get_opt_attr<text_transform_e>(xml, "text-transform");
|
n->text_transform = xml.get_opt_attr<text_transform_e>("text-transform");
|
||||||
n->fill = get_opt_attr<color>(xml, "fill");
|
n->fill = xml.get_opt_attr<color>("fill");
|
||||||
n->halo_fill = get_opt_attr<color>(xml, "halo-fill");
|
n->halo_fill = xml.get_opt_attr<color>("halo-fill");
|
||||||
n->halo_radius = get_opt_attr<double>(xml, "halo-radius");
|
n->halo_radius = xml.get_opt_attr<double>("halo-radius");
|
||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <mapnik/formatting/text.hpp>
|
#include <mapnik/formatting/text.hpp>
|
||||||
#include <mapnik/formatting/format.hpp>
|
#include <mapnik/formatting/format.hpp>
|
||||||
#include <mapnik/formatting/expression.hpp>
|
#include <mapnik/formatting/expression.hpp>
|
||||||
|
#include <mapnik/xml_node.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
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);
|
std::map<std::string, from_xml_function_ptr>::const_iterator itr = map_.find(xml.name());
|
||||||
if (itr == map_.end()) throw config_error("Unknown element '" + name + "'");
|
if (itr == map_.end()) throw config_error("Unknown element '" + xml.name() + "'", xml);
|
||||||
|
xml.set_processed(true);
|
||||||
return itr->second(xml);
|
return itr->second(xml);
|
||||||
}
|
}
|
||||||
} //ns formatting
|
} //ns formatting
|
||||||
|
|
|
@ -26,10 +26,7 @@
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
#include <mapnik/text_properties.hpp>
|
#include <mapnik/text_properties.hpp>
|
||||||
#include <mapnik/processed_text.hpp>
|
#include <mapnik/processed_text.hpp>
|
||||||
|
#include <mapnik/xml_node.hpp>
|
||||||
// boost
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
#include <boost/make_shared.hpp>
|
|
||||||
|
|
||||||
namespace mapnik
|
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();
|
std::string data = xml.text();
|
||||||
boost::trim(data);
|
|
||||||
if (data.empty()) return node_ptr(); //No text
|
if (data.empty()) return node_ptr(); //No text
|
||||||
return boost::make_shared<text_node>(parse_expression(data, "utf8"));
|
return boost::make_shared<text_node>(parse_expression(data, "utf8"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <mapnik/marker.hpp>
|
#include <mapnik/marker.hpp>
|
||||||
#include <mapnik/marker_cache.hpp>
|
#include <mapnik/marker_cache.hpp>
|
||||||
#include <mapnik/unicode.hpp>
|
#include <mapnik/unicode.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
|
||||||
#include <mapnik/font_set.hpp>
|
#include <mapnik/font_set.hpp>
|
||||||
#include <mapnik/parse_path.hpp>
|
#include <mapnik/parse_path.hpp>
|
||||||
#include <mapnik/map.hpp>
|
#include <mapnik/map.hpp>
|
||||||
|
|
|
@ -33,17 +33,17 @@ namespace mapnik { namespace json {
|
||||||
|
|
||||||
#if BOOST_VERSION >= 104700
|
#if BOOST_VERSION >= 104700
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
feature_collection_parser<Iterator>::feature_collection_parser(mapnik::context_ptr const& ctx, mapnik::transcoder const& tr)
|
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)) {}
|
: grammar_(new feature_collection_grammar<iterator_type,feature_type>(ctx,tr)) {}
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
feature_collection_parser<Iterator>::~feature_collection_parser() {}
|
feature_collection_parser<Iterator>::~feature_collection_parser() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
bool feature_collection_parser<Iterator>::parse(iterator_type first, iterator_type last, std::vector<mapnik::feature_ptr> & features)
|
bool feature_collection_parser<Iterator>::parse(iterator_type first, iterator_type last, std::vector<mapnik::feature_ptr> & features)
|
||||||
{
|
{
|
||||||
#if BOOST_VERSION >= 104700
|
#if BOOST_VERSION >= 104700
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
return qi::phrase_parse(first, last, *grammar_, standard_wide::space, features);
|
return qi::phrase_parse(first, last, *grammar_, standard_wide::space, features);
|
||||||
|
@ -53,9 +53,9 @@ bool feature_collection_parser<Iterator>::parse(iterator_type first, iterator_ty
|
||||||
throw std::runtime_error("mapnik::feature_collection_parser::parse() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
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;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template class feature_collection_parser<std::string::const_iterator> ;
|
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<boost::spirit::multi_pass<std::istreambuf_iterator<char> > >;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
|
@ -32,30 +32,30 @@
|
||||||
|
|
||||||
namespace mapnik { namespace json {
|
namespace mapnik { namespace json {
|
||||||
|
|
||||||
feature_generator::feature_generator()
|
feature_generator::feature_generator()
|
||||||
: grammar_(new feature_generator_grammar<sink_type>()) {}
|
: 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)
|
bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
|
||||||
{
|
{
|
||||||
sink_type sink(geojson);
|
sink_type sink(geojson);
|
||||||
return karma::generate(sink, *grammar_,f);
|
return karma::generate(sink, *grammar_,f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
geometry_generator::geometry_generator()
|
geometry_generator::geometry_generator()
|
||||||
: grammar_(new multi_geometry_generator_grammar<sink_type>()) {}
|
: 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)
|
bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
|
||||||
{
|
{
|
||||||
sink_type sink(geojson);
|
sink_type sink(geojson);
|
||||||
return karma::generate(sink, *grammar_,g);
|
return karma::generate(sink, *grammar_,g);
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -65,22 +65,22 @@ bool geometry_generator::generate(std::string & geojson, mapnik::geometry_contai
|
||||||
|
|
||||||
namespace mapnik { namespace json {
|
namespace mapnik { namespace json {
|
||||||
|
|
||||||
bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
|
bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
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());
|
throw std::runtime_error("feature_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
|
bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
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());
|
throw std::runtime_error("geometry_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,26 +22,27 @@
|
||||||
|
|
||||||
#ifdef HAVE_LIBXML2
|
#ifdef HAVE_LIBXML2
|
||||||
|
|
||||||
#include <mapnik/libxml2_loader.hpp>
|
// mapnik
|
||||||
|
#include <mapnik/xml_loader.hpp>
|
||||||
|
#include <mapnik/xml_node.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/filesystem/operations.hpp>
|
#include <boost/filesystem/operations.hpp>
|
||||||
#include <boost/algorithm/string/trim.hpp>
|
#include <boost/algorithm/string/trim.hpp>
|
||||||
|
|
||||||
|
// libxml
|
||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
#include <libxml/parserInternals.h>
|
#include <libxml/parserInternals.h>
|
||||||
#include <libxml/xinclude.h>
|
#include <libxml/xinclude.h>
|
||||||
|
|
||||||
|
// stl
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using boost::property_tree::ptree;
|
|
||||||
using namespace std;
|
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)
|
#define DEFAULT_OPTIONS (XML_PARSE_NOERROR | XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA)
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
|
@ -50,14 +51,14 @@ class libxml2_loader : boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
libxml2_loader(const char *encoding = NULL, int options = DEFAULT_OPTIONS, const char *url = NULL) :
|
libxml2_loader(const char *encoding = NULL, int options = DEFAULT_OPTIONS, const char *url = NULL) :
|
||||||
ctx_( 0 ),
|
ctx_(0),
|
||||||
encoding_( encoding ),
|
encoding_(encoding),
|
||||||
options_( options ),
|
options_(options),
|
||||||
url_( url )
|
url_(url)
|
||||||
{
|
{
|
||||||
LIBXML_TEST_VERSION;
|
LIBXML_TEST_VERSION;
|
||||||
ctx_ = xmlNewParserCtxt();
|
ctx_ = xmlNewParserCtxt();
|
||||||
if ( ! ctx_ )
|
if (!ctx_)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create parser context.");
|
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);
|
boost::filesystem::path path(filename);
|
||||||
if ( !boost::filesystem::exists( path ) ) {
|
if (!boost::filesystem::exists(path))
|
||||||
throw config_error(string("Could not load map file '") +
|
{
|
||||||
filename + "': File does not exist");
|
throw config_error(string("Could not load map file: File does not exist"), 0, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlDocPtr doc = xmlCtxtReadFile(ctx_, filename.c_str(), encoding_, options_);
|
xmlDocPtr doc = xmlCtxtReadFile(ctx_, filename.c_str(), encoding_, options_);
|
||||||
|
|
||||||
if ( !doc )
|
if (!doc)
|
||||||
{
|
{
|
||||||
xmlError * error = xmlCtxtGetLastError( ctx_ );
|
xmlError * error = xmlCtxtGetLastError(ctx_);
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
@ -91,15 +92,7 @@ public:
|
||||||
os << ": " << std::endl << error->message;
|
os << ": " << std::endl << error->message;
|
||||||
// remove CR
|
// remove CR
|
||||||
std::string msg = os.str().substr(0, os.str().size() - 1);
|
std::string msg = os.str().substr(0, os.str().size() - 1);
|
||||||
config_error ex( msg );
|
throw config_error(msg, error->line, error->file);
|
||||||
|
|
||||||
os.str("");
|
|
||||||
os << "(encountered in file '" << error->file << "' at line "
|
|
||||||
<< error->line << ")";
|
|
||||||
|
|
||||||
ex.append_context( os.str() );
|
|
||||||
|
|
||||||
throw ex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,21 +103,21 @@ public:
|
||||||
<< std::endl;
|
<< 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_);
|
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())
|
if (!base_path.empty())
|
||||||
{
|
{
|
||||||
boost::filesystem::path path(base_path);
|
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 '") +
|
throw config_error(string("Could not locate base_path '") +
|
||||||
base_path + "': file or directory does not exist");
|
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_);
|
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_ );
|
xmlError * error = xmlCtxtGetLastError( ctx_ );
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
@ -146,10 +139,10 @@ public:
|
||||||
{
|
{
|
||||||
os << ": " << std::endl << error->message;
|
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)
|
if (iXIncludeReturn < 0)
|
||||||
{
|
{
|
||||||
|
@ -157,63 +150,47 @@ public:
|
||||||
throw config_error("XML XInclude error. One or more files failed to load.");
|
throw config_error("XML XInclude error. One or more files failed to load.");
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlNode * root = xmlDocGetRootElement( doc );
|
xmlNode * root = xmlDocGetRootElement(doc);
|
||||||
if ( ! root ) {
|
if (!root) {
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
throw config_error("XML document is empty.");
|
throw config_error("XML document is empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
populate_tree( root, pt );
|
populate_tree(root, node);
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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() ));
|
node.add_attribute((char *)attributes->name, (char *)attributes->children->content);
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 )
|
for (; cur_node; cur_node = cur_node->next )
|
||||||
{
|
{
|
||||||
switch (cur_node->type)
|
switch (cur_node->type)
|
||||||
{
|
{
|
||||||
case XML_ELEMENT_NODE:
|
case XML_ELEMENT_NODE:
|
||||||
{
|
{
|
||||||
ptree::iterator it = pt.push_back( ptree::value_type(
|
|
||||||
(char*)cur_node->name, ptree() ));
|
xml_node &new_node = node.add_child((char *)cur_node->name, cur_node->line, false);
|
||||||
append_attributes( cur_node->properties, it->second);
|
append_attributes(cur_node->properties, new_node);
|
||||||
populate_tree( cur_node->children, it->second );
|
populate_tree(cur_node->children, new_node);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XML_TEXT_NODE:
|
case XML_TEXT_NODE:
|
||||||
{
|
{
|
||||||
std::string trimmed = boost::algorithm::trim_copy(std::string((char*)cur_node->content));
|
std::string trimmed = boost::algorithm::trim_copy(std::string((char*)cur_node->content));
|
||||||
if (trimmed.empty()) break;
|
if (trimmed.empty()) break; //Don't add empty text nodes
|
||||||
ptree::iterator it = pt.push_back(ptree::value_type("<xmltext>", ptree()));
|
node.add_child(trimmed, cur_node->line, true);
|
||||||
it->second.put_value(trimmed);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XML_COMMENT_NODE:
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -228,15 +205,15 @@ private:
|
||||||
const char *url_;
|
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;
|
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;
|
libxml2_loader loader;
|
||||||
loader.load_string( str, pt, base_path );
|
loader.load_string(str, node, base_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace mapnik
|
} // end of namespace mapnik
|
||||||
|
|
1015
src/load_map.cpp
1015
src/load_map.cpp
File diff suppressed because it is too large
Load diff
|
@ -22,15 +22,15 @@
|
||||||
//$Id$
|
//$Id$
|
||||||
|
|
||||||
#include <mapnik/metawriter_factory.hpp>
|
#include <mapnik/metawriter_factory.hpp>
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
|
||||||
|
|
||||||
#include <mapnik/metawriter_json.hpp>
|
#include <mapnik/metawriter_json.hpp>
|
||||||
#include <mapnik/metawriter_inmem.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/make_shared.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
using boost::property_tree::ptree;
|
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
|
@ -38,20 +38,21 @@ namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
metawriter_ptr
|
metawriter_ptr
|
||||||
metawriter_create(const boost::property_tree::ptree &pt) {
|
metawriter_create(xml_node const& pt)
|
||||||
|
{
|
||||||
metawriter_ptr writer;
|
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") {
|
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));
|
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) {
|
if (output_empty) {
|
||||||
json->set_output_empty(*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) {
|
if (pixel_coordinates) {
|
||||||
json->set_pixel_coordinates(*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);
|
metawriter_inmem_ptr inmem = boost::make_shared<metawriter_inmem>(properties);
|
||||||
writer = inmem;
|
writer = inmem;
|
||||||
} else {
|
} else {
|
||||||
throw config_error(string("Unknown type '") + type + "'");
|
throw config_error(string("Unknown type '") + type + "'", pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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());
|
metawriter_json *json = dynamic_cast<metawriter_json *>(metawriter.get());
|
||||||
if (json) {
|
if (json) {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <mapnik/palette.hpp>
|
#include <mapnik/palette.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
|
@ -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/processed_text.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -43,7 +67,7 @@ string_info &processed_text::get_string_info()
|
||||||
{
|
{
|
||||||
if (!p.fontset.get_name().empty())
|
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()) {
|
} else if (!p.face_name.empty()) {
|
||||||
throw config_error("Unable to find specified font face '" + p.face_name + "'");
|
throw config_error("Unable to find specified font face '" + p.face_name + "'");
|
||||||
} else {
|
} 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_parser.hpp>
|
||||||
#include <mapnik/svg/svg_path_parser.hpp>
|
#include <mapnik/svg/svg_path_parser.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
#include "agg_ellipse.h"
|
#include "agg_ellipse.h"
|
||||||
#include "agg_rounded_rect.h"
|
#include "agg_rounded_rect.h"
|
||||||
|
|
|
@ -20,9 +20,14 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
//mapnik
|
||||||
#include <mapnik/text_placements/list.hpp>
|
#include <mapnik/text_placements/list.hpp>
|
||||||
|
#include <mapnik/xml_node.hpp>
|
||||||
|
|
||||||
|
//boost
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace mapnik
|
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
|
text_placement_info_ptr text_placements_list::get_placement_info(double scale_factor) const
|
||||||
{
|
{
|
||||||
return text_placement_info_ptr(
|
return boost::make_shared<text_placement_info_list>(this, scale_factor);
|
||||||
boost::make_shared<text_placement_info_list>(this, scale_factor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
text_placements_list::text_placements_list() : text_placements(), list_(0)
|
text_placements_list::text_placements_list() : text_placements(), list_(0)
|
||||||
|
@ -83,20 +87,19 @@ unsigned text_placements_list::size() const
|
||||||
return list_.size();
|
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;
|
using boost::property_tree::ptree;
|
||||||
text_placements_list *list = new text_placements_list;
|
text_placements_list *list = new text_placements_list;
|
||||||
text_placements_ptr ptr = text_placements_ptr(list);
|
text_placements_ptr ptr = text_placements_ptr(list);
|
||||||
list->defaults.from_xml(xml, fontsets);
|
list->defaults.from_xml(xml, fontsets);
|
||||||
ptree::const_iterator itr = xml.begin();
|
xml_node::const_iterator itr = xml.begin();
|
||||||
ptree::const_iterator end = xml.end();
|
xml_node::const_iterator end = xml.end();
|
||||||
for( ;itr != end; ++itr)
|
for( ;itr != end; ++itr)
|
||||||
{
|
{
|
||||||
if ((itr->first.find('<') != std::string::npos) || (itr->first != "Placement")) continue;
|
if (itr->is_text() || !itr->is("Placement")) continue;
|
||||||
//TODO: ensure_attrs(symIter->second, "TextSymbolizer/Placement", s_common.str());
|
|
||||||
text_symbolizer_properties &p = list->add();
|
text_symbolizer_properties &p = list->add();
|
||||||
p.from_xml(itr->second, fontsets);
|
p.from_xml(*itr, fontsets);
|
||||||
//TODO: if (strict_ &&
|
//TODO: if (strict_ &&
|
||||||
// !p.format.fontset.size())
|
// !p.format.fontset.size())
|
||||||
// ensure_font_face(p.format.face_name);
|
// ensure_font_face(p.format.face_name);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <mapnik/text_placements/simple.hpp>
|
#include <mapnik/text_placements/simple.hpp>
|
||||||
#include <mapnik/text_placements/list.hpp>
|
#include <mapnik/text_placements/list.hpp>
|
||||||
#include <mapnik/text_placements/dummy.hpp>
|
#include <mapnik/text_placements/dummy.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
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);
|
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);
|
return itr->second(xml, fontsets);
|
||||||
}
|
}
|
||||||
} //ns formatting
|
} //ns formatting
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/text_placements/simple.hpp>
|
#include <mapnik/text_placements/simple.hpp>
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/ptree_helpers.hpp>
|
||||||
|
#include <mapnik/xml_node.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#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(
|
text_placement_info_ptr text_placements_simple::get_placement_info(
|
||||||
double scale_factor) const
|
double scale_factor) const
|
||||||
{
|
{
|
||||||
return text_placement_info_ptr(
|
return boost::make_shared<text_placement_info_simple>(this, scale_factor);
|
||||||
boost::make_shared<text_placement_info_simple>(this, scale_factor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Position string: [POS][SIZE]
|
/** 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)]),
|
(direction_name[push_back(phoenix::ref(direction_), _1)] % ',') >> *(',' >> qi::float_[push_back(phoenix::ref(text_sizes_), _1)]),
|
||||||
space
|
space
|
||||||
);
|
);
|
||||||
if (first != last) {
|
if (first != last)
|
||||||
|
{
|
||||||
std::cerr << "WARNING: Could not parse text_placement_simple placement string ('" << positions << "').\n";
|
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";
|
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_
|
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>(
|
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);
|
ptr->defaults.from_xml(xml, fontsets);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <mapnik/ptree_helpers.hpp>
|
#include <mapnik/ptree_helpers.hpp>
|
||||||
#include <mapnik/expression_string.hpp>
|
#include <mapnik/expression_string.hpp>
|
||||||
#include <mapnik/formatting/text.hpp>
|
#include <mapnik/formatting/text.hpp>
|
||||||
|
#include <mapnik/xml_node.hpp>
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
@ -79,45 +81,45 @@ formatting::node_ptr text_symbolizer_properties::format_tree() const
|
||||||
return tree_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
if (jalign_) jalign = *jalign_;
|
||||||
/* Attributes needing special care */
|
/* 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");
|
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;
|
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;
|
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);
|
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_) {
|
if (name_) {
|
||||||
std::clog << "### WARNING: Using 'name' in TextSymbolizer/ShieldSymbolizer is deprecated!\n";
|
std::clog << "### WARNING: Using 'name' in TextSymbolizer/ShieldSymbolizer is deprecated!\n";
|
||||||
set_old_style_expression(parse_expression(*name_, "utf8"));
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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_;
|
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]);
|
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_)
|
if (face_name_)
|
||||||
{
|
{
|
||||||
face_name = *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_) {
|
if (fontset_name_) {
|
||||||
std::map<std::string,font_set>::const_iterator itr = fontsets.find(*fontset_name_);
|
std::map<std::string,font_set>::const_iterator itr = fontsets.find(*fontset_name_);
|
||||||
if (itr != fontsets.end())
|
if (itr != fontsets.end())
|
||||||
|
@ -277,16 +279,16 @@ void char_properties::from_xml(boost::property_tree::ptree const &sym, fontset_m
|
||||||
}
|
}
|
||||||
else
|
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())
|
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())
|
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">
|
map_string = '''<Map background-color="steelblue" base="./" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
||||||
<Style name="My Style">
|
<Style name="My Style">
|
||||||
<Rule>
|
<Rule>
|
||||||
<PolygonSymbolizer>
|
<PolygonSymbolizer fill="#f2eff9"/>
|
||||||
<CssParameter name="fill">#f2eff9</CssParameter>
|
<LineSymbolizer stroke="rgb(50%,50%,50%)" stroke-width="0.1"/>
|
||||||
</PolygonSymbolizer>
|
|
||||||
<LineSymbolizer>
|
|
||||||
<CssParameter name="stroke">rgb(50%,50%,50%)</CssParameter>
|
|
||||||
<CssParameter name="stroke-width">0.1</CssParameter>
|
|
||||||
</LineSymbolizer>
|
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
<Layer name="boundaries">
|
<Layer name="boundaries">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import math, operator
|
#import math, operator
|
||||||
import Image
|
import Image
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@ def compare(fn1, fn2):
|
||||||
return -1
|
return -1
|
||||||
diff = 0
|
diff = 0
|
||||||
pixels = im1.size[0] * im1.size[1]
|
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()
|
im1 = im1.getdata()
|
||||||
im2 = im2.getdata()
|
im2 = im2.getdata()
|
||||||
for i in range(3, pixels - 1, 3):
|
for i in range(3, pixels - 1, 3):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE Map>
|
<!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">
|
<Layer name="layer" srs="+proj=latlong +datum=WGS84">
|
||||||
<StyleName>My Style</StyleName>
|
<StyleName>My Style</StyleName>
|
||||||
|
|
|
@ -50,7 +50,7 @@ def render(filename, width, height=100):
|
||||||
return m
|
return m
|
||||||
|
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) == 2:
|
||||||
files = [(sys.argv[1], 500)]
|
files = [(sys.argv[1], (500, 500))]
|
||||||
elif len(sys.argv) > 2:
|
elif len(sys.argv) > 2:
|
||||||
files = [sys.argv[1:]]
|
files = [sys.argv[1:]]
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue