From 481271cb76a4a297bebbf6e4ceb81b5236155fb2 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Mon, 5 Mar 2012 16:49:54 +0100 Subject: [PATCH 001/138] Add new XML data structure and modify XML parser to work with this structure. --- include/mapnik/xml_tree.hpp | 78 ++++++++++++++++++++++++++++ src/build.py | 1 + src/libxml2_loader.cpp | 100 ++++++++++++++++-------------------- src/xml_tree.cpp | 87 +++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+), 57 deletions(-) create mode 100644 include/mapnik/xml_tree.hpp create mode 100644 src/xml_tree.cpp diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp new file mode 100644 index 000000000..b34bb9376 --- /dev/null +++ b/include/mapnik/xml_tree.hpp @@ -0,0 +1,78 @@ +/***************************************************************************** + * + * 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 + +#include +#include +#include + +namespace mapnik +{ +class xml_tree; + +class xml_attribute +{ +public: + std::string value; + bool processed; +}; + +class xml_node +{ +public: + xml_node(xml_tree &tree, std::string name, unsigned line=0, bool text_node = false); + + std::string name() const; + std::string text() const; + + xml_node &add_child(std::string name, unsigned line=0, bool text_node = false); + void add_attribute(std::string name, std::string value); + void set_processed(bool processed); +private: + xml_tree &tree_; + std::string name_; + std::list children_; + std::map attributes_; + bool text_node_; + unsigned line_; + bool processed_; + +}; + +class xml_tree +{ +public: + xml_tree(); + void set_filename(std::string fn); + std::string filename() const; + xml_node &node(); +private: + xml_node node_; + std::string file_; + //TODO: Grammars +}; + +} //ns mapnik + +#endif // MAPNIK_XML_TREE_H diff --git a/src/build.py b/src/build.py index c25bc2fb5..b19789d3e 100644 --- a/src/build.py +++ b/src/build.py @@ -178,6 +178,7 @@ source = Split( text_placements/list.cpp text_placements/simple.cpp text_properties.cpp + xml_tree.cpp """ ) diff --git a/src/libxml2_loader.cpp b/src/libxml2_loader.cpp index c4111696f..f67f0e0db 100644 --- a/src/libxml2_loader.cpp +++ b/src/libxml2_loader.cpp @@ -22,26 +22,27 @@ #ifdef HAVE_LIBXML2 +// mapnik #include - +#include #include +// boost #include -#include #include #include +// libxml #include #include #include #include +// stl #include -using boost::property_tree::ptree; using namespace std; -//#define DEFAULT_OPTIONS (XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA) #define DEFAULT_OPTIONS (XML_PARSE_NOERROR | XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA) namespace mapnik @@ -50,14 +51,14 @@ class libxml2_loader : boost::noncopyable { public: libxml2_loader(const char *encoding = NULL, int options = DEFAULT_OPTIONS, const char *url = NULL) : - ctx_( 0 ), - encoding_( encoding ), - options_( options ), - url_( url ) + ctx_(0), + encoding_(encoding), + options_(options), + url_(url) { LIBXML_TEST_VERSION; ctx_ = xmlNewParserCtxt(); - if ( ! ctx_ ) + if (!ctx_) { throw std::runtime_error("Failed to create parser context."); } @@ -71,19 +72,20 @@ public: } } - void load( const std::string & filename, ptree & pt ) + void load(const std::string & filename, xml_node &node) { 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"); } xmlDocPtr doc = xmlCtxtReadFile(ctx_, filename.c_str(), encoding_, options_); - if ( !doc ) + if (!doc) { - xmlError * error = xmlCtxtGetLastError( ctx_ ); + xmlError * error = xmlCtxtGetLastError(ctx_); if (error) { std::ostringstream os; @@ -91,13 +93,13 @@ public: os << ": " << std::endl << error->message; // remove CR std::string msg = os.str().substr(0, os.str().size() - 1); - config_error ex( msg ); + config_error ex(msg); os.str(""); os << "(encountered in file '" << error->file << "' at line " << error->line << ")"; - ex.append_context( os.str() ); + ex.append_context(os.str()); throw ex; } @@ -110,21 +112,21 @@ public: << std::endl; } */ - load(doc, pt); + load(doc, node); } - void load( const int fd, ptree & pt ) + void load(const int fd, xml_node &node) { xmlDocPtr doc = xmlCtxtReadFd(ctx_, fd, url_, encoding_, options_); - load(doc, pt); + load(doc, node); } - void load_string( const std::string & buffer, ptree & pt, std::string const & base_path ) + 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 ) ) { + if (!boost::filesystem::exists(path)) { throw config_error(string("Could not locate base_path '") + base_path + "': file or directory does not exist"); } @@ -132,12 +134,12 @@ public: xmlDocPtr doc = xmlCtxtReadMemory(ctx_, buffer.data(), buffer.length(), base_path.c_str(), encoding_, options_); - load(doc, pt); + load(doc, node); } - void load( const xmlDocPtr doc, ptree & pt ) + void load(const xmlDocPtr doc, xml_node &node) { - if ( !doc ) + if (!doc) { xmlError * error = xmlCtxtGetLastError( ctx_ ); std::ostringstream os; @@ -149,7 +151,7 @@ public: throw config_error(os.str()); } - int iXIncludeReturn = xmlXIncludeProcessFlags( doc, options_ ); + int iXIncludeReturn = xmlXIncludeProcessFlags(doc, options_); if (iXIncludeReturn < 0) { @@ -157,63 +159,47 @@ public: throw config_error("XML XInclude error. One or more files failed to load."); } - xmlNode * root = xmlDocGetRootElement( doc ); - if ( ! root ) { + xmlNode * root = xmlDocGetRootElement(doc); + if (!root) { xmlFreeDoc(doc); throw config_error("XML document is empty."); } - populate_tree( root, pt ); + populate_tree(root, node); xmlFreeDoc(doc); } private: - void append_attributes( xmlAttr * attributes, ptree & pt) + void append_attributes(xmlAttr *attributes, xml_node &node) { - if (attributes) + for (; attributes; attributes = attributes->next ) { - ptree::iterator it = pt.push_back( ptree::value_type( "", ptree() )); - ptree & attr_list = it->second; - xmlAttr * cur_attr = attributes; - for (; cur_attr; cur_attr = cur_attr->next ) - { - ptree::iterator it = attr_list.push_back( - ptree::value_type( (char*)cur_attr->name, ptree() )); - it->second.put_value( (char*) cur_attr->children->content ); - } + node.add_attribute((char *)attributes->name, (char *)attributes->children->content); } } - void populate_tree( xmlNode * node, ptree & pt ) + void populate_tree(xmlNode *cur_node, xml_node &node) { - xmlNode * cur_node = node; - for (; cur_node; cur_node = cur_node->next ) { switch (cur_node->type) { case XML_ELEMENT_NODE: { - ptree::iterator it = pt.push_back( ptree::value_type( - (char*)cur_node->name, ptree() )); - append_attributes( cur_node->properties, it->second); - populate_tree( cur_node->children, it->second ); + + xml_node &new_node = node.add_child((char *)cur_node->name, cur_node->line, false); + append_attributes(cur_node->properties, new_node); + populate_tree(cur_node->children, new_node); } break; case XML_TEXT_NODE: { std::string trimmed = boost::algorithm::trim_copy(std::string((char*)cur_node->content)); - if (trimmed.empty()) break; - ptree::iterator it = pt.push_back(ptree::value_type("", ptree())); - it->second.put_value(trimmed); + if (trimmed.empty()) break; //Don't add empty text nodes + node.add_child(trimmed, cur_node->line, true); } break; case XML_COMMENT_NODE: - { - ptree::iterator it = pt.push_back( - ptree::value_type( "", ptree() )); - it->second.put_value( (char*) cur_node->content ); - } break; default: break; @@ -228,15 +214,15 @@ private: const char *url_; }; -void read_xml2( std::string const & filename, boost::property_tree::ptree & pt) +void read_xml2(std::string const & filename, xml_node &node) { libxml2_loader loader; - loader.load( filename, pt ); + loader.load(filename, node); } -void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt, std::string const & base_path) +void read_xml2_string(std::string const & str, xml_node &node, std::string const & base_path) { libxml2_loader loader; - loader.load_string( str, pt, base_path ); + loader.load_string(str, node, base_path); } } // end of namespace mapnik diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp new file mode 100644 index 000000000..3a05a82ac --- /dev/null +++ b/src/xml_tree.cpp @@ -0,0 +1,87 @@ +/***************************************************************************** + * + * 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 + +namespace mapnik +{ + +xml_tree::xml_tree() + : node_(*this, "") +{ +} + +void xml_tree::set_filename(std::string fn) +{ + file_ = fn; +} + +std::string xml_tree::filename() const +{ + return file_; +} + +xml_node &xml_tree::node() +{ + return node_; +} + +/****************************************************************************/ + +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::name() const +{ + if (!text_node_) + return name_; + else + return ""; +} + +std::string xml_node::text() const +{ + if (text_node_) + return name_; + else + return "NOT A TEXT NODE"; +} + +void xml_node::set_processed(bool processed) +{ + processed_ = processed; +} + +xml_node &xml_node::add_child(std::string name, unsigned line, bool text_node) +{ + children_.push_back(xml_node(tree_, name, line, text_node)); + return children_.back(); +} + + +} //ns mapnik From 3c594efec8b0aca80cce356f397ee48b92c5ae2b Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 5 Mar 2012 17:59:07 -0800 Subject: [PATCH 002/138] fix spelling --- include/mapnik/label_collision_detector.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mapnik/label_collision_detector.hpp b/include/mapnik/label_collision_detector.hpp index fa23b7ca0..b913ac0dc 100644 --- a/include/mapnik/label_collision_detector.hpp +++ b/include/mapnik/label_collision_detector.hpp @@ -39,7 +39,7 @@ struct label_collision_detector { typedef std::vector > label_placements; - bool has_plasement(box2d const& box) + bool has_placement(box2d const& box) { label_placements::const_iterator itr=labels_.begin(); for( ; itr !=labels_.end();++itr) @@ -134,7 +134,7 @@ public: }; -//quad tree based label collission detector so labels dont appear within a given distance +//quad tree based label collision detector so labels dont appear within a given distance class label_collision_detector4 : boost::noncopyable { public: From df54f710bc0e7406fe722b798cb23791f212e5b2 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 5 Mar 2012 18:00:15 -0800 Subject: [PATCH 003/138] minor formatting --- src/placement_finder.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index c9c2c6e1d..b055a9308 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -439,7 +439,9 @@ void placement_finder::find_point_placement(double label_x, // if there is an overlap with existing envelopes, then exit - no placement if (!detector_.extent().intersects(e) || - (!p.allow_overlap && !detector_.has_point_placement(e, pi.get_actual_minimum_distance())) + (!p.allow_overlap && + !detector_.has_point_placement(e, pi.get_actual_minimum_distance()) + ) ) { return; @@ -907,7 +909,10 @@ bool placement_finder::test_placement(std::auto_ptr const& y - (cwidth*sina + ci.height()*cosa)); if (!detector_.extent().intersects(e) || - !detector_.has_placement(e, info_.get_string(), pi.get_actual_minimum_distance())) + (!p.allow_overlap && + !detector_.has_placement(e, info_.get_string(), pi.get_actual_minimum_distance()) + ) + ) { //std::clog << "No Intersects:" << !dimensions_.intersects(e) << ": " << e << " @ " << dimensions_ << std::endl; //std::clog << "No Placements:" << !detector_.has_placement(e, info.get_string(), p.minimum_distance) << std::endl; From 1c6da3893e570bf6623008eda4505976005c2e38 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 5 Mar 2012 18:00:45 -0800 Subject: [PATCH 004/138] minor formatting --- src/symbolizer_helpers.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/symbolizer_helpers.cpp b/src/symbolizer_helpers.cpp index 9672e95dc..4a9a38a12 100644 --- a/src/symbolizer_helpers.cpp +++ b/src/symbolizer_helpers.cpp @@ -136,9 +136,7 @@ void text_symbolizer_helper::initialize_geometries() largest_box_only = true; if (sym_.get_minimum_path_length() > 0) { - // TODO - find less costly method than fetching full envelope box2d gbox = t_.forward(geom.envelope(), prj_trans_); - if (gbox.width() < sym_.get_minimum_path_length()) { continue; @@ -162,10 +160,13 @@ template void text_symbolizer_helper::initialize_points() { label_placement_enum how_placed = placement_->properties.label_placement; - if (how_placed == LINE_PLACEMENT) { + if (how_placed == LINE_PLACEMENT) + { point_placement_ = false; return; - } else { + } + else + { point_placement_ = true; } @@ -188,14 +189,19 @@ void text_symbolizer_helper::initialize_points() t_.forward(&label_x, &label_y); points_.push_back(std::make_pair(label_x, label_y)); } - } else { + } + else + { if (how_placed == POINT_PLACEMENT) { geom.label_position(&label_x, &label_y); - } else if (how_placed == INTERIOR_PLACEMENT) + } + else if (how_placed == INTERIOR_PLACEMENT) { geom.label_interior_position(&label_x, &label_y); - } else { + } + else + { #ifdef MAPNIK_DEBUG std::cerr << "ERROR: Unknown placement type in initialize_points();\n"; #endif From 191d0f907a94c1690e461394990ecd0ef905d3d2 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 6 Mar 2012 15:18:11 +0100 Subject: [PATCH 005/138] Convert first function to new XML structure. --- include/mapnik/libxml2_loader.hpp | 8 +- include/mapnik/xml_tree.hpp | 30 ++++++- src/load_map.cpp | 85 ++++++++---------- src/xml_tree.cpp | 137 +++++++++++++++++++++++++++++- 4 files changed, 203 insertions(+), 57 deletions(-) diff --git a/include/mapnik/libxml2_loader.hpp b/include/mapnik/libxml2_loader.hpp index 105a5f8b2..5acad070e 100644 --- a/include/mapnik/libxml2_loader.hpp +++ b/include/mapnik/libxml2_loader.hpp @@ -23,16 +23,14 @@ #ifndef MAPNIK_LIBXML2_LOADER_HPP #define MAPNIK_LIBXML2_LOADER_HPP -// boost -#include - // stl #include namespace mapnik { -void read_xml2( std::string const & filename, boost::property_tree::ptree & pt); -void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt, std::string const & base_path=""); +class xml_node; +void read_xml2( std::string const & filename, xml_node &node); +void read_xml2_string( std::string const & str, xml_node &node, std::string const & base_path=""); } #endif // MAPNIK_LIBXML2_LOADER_HPP diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index b34bb9376..fc17ae7cb 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -23,13 +23,19 @@ #ifndef MAPNIK_XML_TREE_H #define MAPNIK_XML_TREE_H +//boost +#include + +//stl #include #include #include +#include namespace mapnik { class xml_tree; +class color; class xml_attribute { @@ -38,6 +44,19 @@ public: bool processed; }; +class node_not_found: public std::exception +{ +public: + node_not_found(std::string node_name) : node_name_(node_name) {} + virtual const char* what() const throw() + { + return ("Node "+node_name_+ "not found").c_str(); + } + ~node_not_found() throw (); +private: + std::string node_name_; +}; + class xml_node { public: @@ -49,6 +68,15 @@ public: xml_node &add_child(std::string name, unsigned line=0, bool text_node = false); void add_attribute(std::string name, std::string value); void set_processed(bool processed); + + xml_node & get_child(std::string name); + xml_node const& get_child(std::string name) const; + + template + boost::optional get_opt_attr(std::string const& name) const; + + template + T get_attr(std::string const& name, T const& default_value) const; private: xml_tree &tree_; std::string name_; @@ -66,7 +94,7 @@ public: xml_tree(); void set_filename(std::string fn); std::string filename() const; - xml_node &node(); + xml_node &root(); private: xml_node node_; std::string file_; diff --git a/src/load_map.cpp b/src/load_map.cpp index ddb076e80..2fc7d6a5b 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -22,6 +22,7 @@ // mapnik #include +#include #include #include #include @@ -94,7 +95,7 @@ public: expr_grammar_(tr_) {} - void parse_map(Map & map, ptree const & sty, std::string const& base_path=""); + void parse_map(Map & map, xml_node const& sty, std::string const& base_path=""); private: void parse_map_include( Map & map, ptree const & include); void parse_style(Map & map, ptree const & sty); @@ -166,9 +167,10 @@ void remove_empty_text_nodes(ptree &pt) //#include void load_map(Map & map, std::string const& filename, bool strict) { - ptree pt; + xml_tree tree; + tree.set_filename(filename); #ifdef HAVE_LIBXML2 - read_xml2(filename, pt); + read_xml2(filename, tree.root()); #else try { @@ -180,18 +182,18 @@ void load_map(Map & map, std::string const& filename, bool strict) throw config_error( ex.what() ); } #endif - map_parser parser( strict, filename); - parser.parse_map(map, pt); + map_parser parser(strict, filename); +// parser.parse_map(map, pt); } void load_map_string(Map & map, std::string const& str, bool strict, std::string const& base_path) { - ptree pt; + xml_tree tree; #ifdef HAVE_LIBXML2 if (!base_path.empty()) - read_xml2_string(str, pt, base_path); // accept base_path passed into function + read_xml2_string(str, tree.root(), base_path); // accept base_path passed into function else - read_xml2_string(str, pt, map.base_path()); // default to map base_path + read_xml2_string(str, tree.root(), map.base_path()); // default to map base_path #else try { @@ -206,8 +208,8 @@ void load_map_string(Map & map, std::string const& str, bool strict, std::string } #endif - map_parser parser( strict, base_path); - parser.parse_map(map, pt, base_path); + map_parser parser(strict, base_path); +// parser.parse_map(map, tree.root(), base_path); } expression_ptr map_parser::parse_expr(std::string const& str) @@ -244,44 +246,31 @@ boost::optional map_parser::get_opt_color_attr(boost::property_tree::ptre return result; } -void map_parser::parse_map( Map & map, ptree const & pt, std::string const& base_path ) +void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& base_path) { try { - ptree const & map_node = pt.get_child("Map"); - - std::ostringstream s(""); - s << "background-color," - << "background-image," - << "srs," - << "buffer-size," - << "paths-from-xml," - << "minimum-version," - << "font-directory," - << "maximum-extent," - << "base"; - ensure_attrs(map_node, "Map", s.str()); - + xml_node const& map_node = pt.get_child("Map"); try { parameters extra_attr; // Check if relative paths should be interpreted as relative to/from XML location // Default is true, and map_parser::ensure_relative_to_xml will be called to modify path - optional paths_from_xml = get_opt_attr(map_node, "paths-from-xml"); + optional paths_from_xml = map_node.get_opt_attr("paths-from-xml"); if (paths_from_xml) { relative_to_xml_ = *paths_from_xml; } - optional base_path_from_xml = get_opt_attr(map_node, "base"); + optional base_path_from_xml = map_node.get_opt_attr("base"); if (!base_path.empty()) { - map.set_base_path( base_path ); + map.set_base_path(base_path); } else if (base_path_from_xml) { - map.set_base_path( *base_path_from_xml ); + map.set_base_path(*base_path_from_xml); } else { @@ -293,30 +282,30 @@ void map_parser::parse_map( Map & map, ptree const & pt, std::string const& base std::string base = xml_path.branch_path().string(); #endif - map.set_base_path( base ); + map.set_base_path(base); } - optional bgcolor = get_opt_color_attr(map_node, "background-color"); + optional bgcolor = map_node.get_opt_attr("background-color"); if (bgcolor) { - map.set_background( * bgcolor ); + map.set_background(*bgcolor); } - optional image_filename = get_opt_attr(map_node, "background-image"); + optional image_filename = map_node.get_opt_attr("background-image"); if (image_filename) { map.set_background_image(ensure_relative_to_xml(image_filename)); } - map.set_srs( get_attr(map_node, "srs", map.srs() )); + map.set_srs(map_node.get_attr("srs", map.srs())); - optional buffer_size = get_opt_attr(map_node,"buffer-size"); + optional buffer_size = map_node.get_opt_attr("buffer-size"); if (buffer_size) { map.set_buffer_size(*buffer_size); } - optional maximum_extent = get_opt_attr(map_node,"maximum-extent"); + optional maximum_extent = map_node.get_opt_attr("maximum-extent"); if (maximum_extent) { box2d box; @@ -327,33 +316,33 @@ void map_parser::parse_map( Map & map, ptree const & pt, std::string const& base else { std::ostringstream s_err; - s << "failed to parse 'maximum-extent'"; - if ( strict_ ) + s_err << "failed to parse 'maximum-extent'"; + if (strict_) throw config_error(s_err.str()); else - std::clog << "### WARNING: " << s.str() << std::endl; + std::clog << "### WARNING: " << s_err.str() << std::endl; } } - optional font_directory = get_opt_attr(map_node,"font-directory"); + optional font_directory = map_node.get_opt_attr("font-directory"); if (font_directory) { extra_attr["font-directory"] = *font_directory; - freetype_engine::register_fonts( ensure_relative_to_xml(font_directory), false); + freetype_engine::register_fonts(ensure_relative_to_xml(font_directory), false); } - optional min_version_string = get_opt_attr(map_node, "minimum-version"); + optional min_version_string = map_node.get_opt_attr("minimum-version"); if (min_version_string) { extra_attr["minimum-version"] = *min_version_string; boost::char_separator sep("."); - boost::tokenizer > tokens(*min_version_string,sep); + boost::tokenizer > tokens(*min_version_string, sep); unsigned i = 0; bool success = false; int n[3]; - for (boost::tokenizer >::iterator beg=tokens.begin(); - beg!=tokens.end();++beg) + for (boost::tokenizer >::iterator beg = tokens.begin(); + beg != tokens.end(); ++beg) { try { @@ -391,15 +380,15 @@ void map_parser::parse_map( Map & map, ptree const & pt, std::string const& base throw; } - parse_map_include( map, map_node ); +// parse_map_include( map, map_node ); } - catch (const boost::property_tree::ptree_bad_path &) + catch (node_not_found const&) { throw config_error("Not a map file. Node 'Map' not found."); } } -void map_parser::parse_map_include( Map & map, ptree const & include ) +void map_parser::parse_map_include(Map & map, xml_node const& include ) { ptree::const_iterator itr = include.begin(); ptree::const_iterator end = include.end(); diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 3a05a82ac..a004748a6 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -19,11 +19,112 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ + +//mapnik #include +#include +#include + +//boost +#include namespace mapnik { +template +inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) +{ + return boost::lexical_cast(value); +} + +template <> +inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) +{ + int result; + if (mapnik::conversions::string2int(value, result)) + return boost::optional(result); + return boost::optional(); +} + +template <> +inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) +{ + double result; + if (mapnik::conversions::string2double(value, result)) + return boost::optional(result); + return boost::optional(); +} + +template <> +inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) +{ + float result; + if (mapnik::conversions::string2float(value, result)) + return boost::optional(result); + return boost::optional(); +} + +template <> +inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) +{ + return value; +} + + +/****************************************************************************/ + +class boolean; +template +struct name_trait +{ + static std::string name() + { + return ""; + } + // 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 \ + { \ + 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 +struct name_trait< mapnik::enumeration > +{ + typedef enumeration 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() : node_(*this, "") { @@ -39,7 +140,7 @@ std::string xml_tree::filename() const return file_; } -xml_node &xml_tree::node() +xml_node &xml_tree::root() { return node_; } @@ -61,7 +162,7 @@ std::string xml_node::name() const if (!text_node_) return name_; else - return ""; + return ""; //TODO: throw } std::string xml_node::text() const @@ -69,7 +170,7 @@ std::string xml_node::text() const if (text_node_) return name_; else - return "NOT A TEXT NODE"; + return "NOT A TEXT NODE"; //TODO: throw } void xml_node::set_processed(bool processed) @@ -83,5 +184,35 @@ xml_node &xml_node::add_child(std::string name, unsigned line, bool text_node) return children_.back(); } +xml_node & xml_node::get_child(std::string name) +{ + std::list::iterator itr = children_.begin(); + std::list::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); +} + +template +boost::optional xml_node::get_opt_attr(std::string const& name) const +{ + std::map::const_iterator itr = attributes_.find(name); + if (itr == attributes_.end()) return boost::optional(); + boost::optional result = fast_cast(itr->second); + if (!result) + { + throw config_error(std::string("Failed to parse attribute '") + + name + "'. Expected " + name_trait::name() + + " but got '" + itr->second + "'"); + } + return result; +} + } //ns mapnik From ac50834d92926ffdcd913a6ce6ddcaa6dadaaf44 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 6 Mar 2012 15:47:08 +0100 Subject: [PATCH 006/138] Convert parse_map_include to xml_node. --- include/mapnik/xml_tree.hpp | 12 +++++ src/load_map.cpp | 101 +++++++++++++----------------------- src/xml_tree.cpp | 7 +++ 3 files changed, 55 insertions(+), 65 deletions(-) diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index fc17ae7cb..bbb12589f 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -60,15 +60,20 @@ private: class xml_node { public: + typedef std::list::const_iterator const_iterator; xml_node(xml_tree &tree, std::string name, unsigned line=0, bool text_node = false); std::string name() const; std::string text() const; + bool is_text() const; xml_node &add_child(std::string name, unsigned line=0, bool text_node = false); void add_attribute(std::string name, std::string value); void set_processed(bool processed); + const_iterator begin() const; + const_iterator end() const; + xml_node & get_child(std::string name); xml_node const& get_child(std::string name) const; @@ -77,6 +82,13 @@ public: template T get_attr(std::string const& name, T const& default_value) const; + template + T get_attr(std::string const& name) const; + + std::string get_text() const; + + template + T get_value(std::string const& name) const; private: xml_tree &tree_; std::string name_; diff --git a/src/load_map.cpp b/src/load_map.cpp index 2fc7d6a5b..f549468a5 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -97,7 +97,7 @@ public: void parse_map(Map & map, xml_node const& sty, std::string const& base_path=""); private: - void parse_map_include( Map & map, ptree const & include); + void parse_map_include( Map & map, xml_node const& include); void parse_style(Map & map, ptree const & sty); void parse_layer(Map & map, ptree const & lay); void parse_metawriter(Map & map, ptree const & lay); @@ -380,7 +380,7 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas throw; } -// parse_map_include( map, map_node ); + parse_map_include(map, map_node); } catch (node_not_found const&) { @@ -388,124 +388,95 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas } } -void map_parser::parse_map_include(Map & map, xml_node const& include ) +void map_parser::parse_map_include(Map & map, xml_node const& include) { - ptree::const_iterator itr = include.begin(); - ptree::const_iterator end = include.end(); + xml_node::const_iterator itr = include.begin(); + xml_node::const_iterator end = include.end(); for (; itr != end; ++itr) { - ptree::value_type const& v = *itr; - - if (v.first == "Include") + if (itr->is_text()) continue; + if (itr->name() == "Include") { - parse_map_include( map, v.second ); + parse_map_include(map, *itr); } - else if (v.first == "Style") + else if (itr->name() == "Style") { - parse_style( map, v.second ); +// parse_style(map, *itr); } - else if (v.first == "Layer") + else if (itr->name() == "Layer") { - parse_layer(map, v.second ); +// parse_layer(map, *itr); } - else if (v.first == "FontSet") + else if (itr->name() == "FontSet") { - parse_fontset(map, v.second); +// parse_fontset(map, *itr); } - else if (v.first == "MetaWriter") + else if (itr->name() == "MetaWriter") { - parse_metawriter(map, v.second); +// parse_metawriter(map, *itr); } - else if (v.first == "FileSource") + else if (itr->name() == "FileSource") { - std::string name = get_attr( v.second, "name"); - std::string value = get_value( v.second, ""); + std::string name = itr->get_attr("name"); + std::string value = itr->get_text(); file_sources_[name] = value; } - else if (v.first == "Datasource") + else if (itr->name() == "Datasource") { - std::string name = get_attr(v.second, "name", std::string("Unnamed")); + std::string name = itr->get_attr("name", std::string("Unnamed")); parameters params; - ptree::const_iterator paramIter = v.second.begin(); - ptree::const_iterator endParam = v.second.end(); + xml_node::const_iterator paramIter = itr->begin(); + xml_node::const_iterator endParam = itr->end(); for (; paramIter != endParam; ++paramIter) { - ptree const& param = paramIter->second; - - if (paramIter->first == "Parameter") + if (paramIter->name() == "Parameter") { - std::string name = get_attr(param, "name"); - std::string value = get_value( param, - "datasource parameter"); + std::string name = paramIter->get_attr("name"); + std::string value = paramIter->get_text(); params[name] = value; } - else if( paramIter->first != "" && - paramIter->first != "") - { - throw config_error(std::string("Unknown child node in ") + - "'Datasource'. Expected 'Parameter' but got '" + - paramIter->first + "'"); - } } datasource_templates_[name] = params; } - else if (v.first == "Parameters") + else if (itr->name() == "Parameters") { - std::string name = get_attr(v.second, "name", std::string("Unnamed")); + std::string name = itr->get_attr("name", std::string("Unnamed")); parameters & params = map.get_extra_parameters(); - ptree::const_iterator paramIter = v.second.begin(); - ptree::const_iterator endParam = v.second.end(); + xml_node::const_iterator paramIter = itr->begin(); + xml_node::const_iterator endParam = itr->end(); for (; paramIter != endParam; ++paramIter) { - ptree const& param = paramIter->second; - - if (paramIter->first == "Parameter") + if (paramIter->name() == "Parameter") { - std::string name = get_attr(param, "name"); + std::string name = paramIter->get_attr("name"); bool is_string = true; - boost::optional type = get_opt_attr(param, "type"); + boost::optional type = paramIter->get_opt_attr("type"); if (type) { if (*type == "int") { is_string = false; - int value = get_value( param,"parameter"); + int value = paramIter->get_value("parameter"); params[name] = value; } else if (*type == "float") { is_string = false; - double value = get_value( param,"parameter"); + double value = paramIter->get_value("parameter"); params[name] = value; } } if (is_string) { - std::string value = get_value( param, - "parameter"); + std::string value = paramIter->get_text(); params[name] = value; } } - else if( paramIter->first != "" && - paramIter->first != "" ) - { - throw config_error(std::string("Unknown child node in ") + - "'Parameters'. Expected 'Parameter' but got '" + - paramIter->first + "'"); - } } } - else if (v.first != "" && - v.first != "") - { - throw config_error(std::string("Unknown child node in 'Map': '") + - v.first + "'"); - } } - - map.init_metawriters(); } diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index a004748a6..494fc14d7 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -24,6 +24,7 @@ #include #include #include +#include //boost #include @@ -70,6 +71,12 @@ inline boost::optional fast_cast(xml_tree const& tree, std::string return value; } +template <> +inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) +{ + return mapnik::color_factory::from_string(value); +} + /****************************************************************************/ From 7a052f81f7e7e36614d6c82de9e8a8ef4f3a71c9 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 6 Mar 2012 17:29:33 +0100 Subject: [PATCH 007/138] Update more functions. --- include/mapnik/xml_tree.hpp | 9 +- src/load_map.cpp | 181 ++++++++++++------------------------ 2 files changed, 64 insertions(+), 126 deletions(-) diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index bbb12589f..a9e48a260 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -41,7 +41,7 @@ class xml_attribute { public: std::string value; - bool processed; + mutable bool processed; }; class node_not_found: public std::exception @@ -66,9 +66,10 @@ public: std::string name() const; std::string text() const; bool is_text() const; + bool is(std::string const& name) const; - xml_node &add_child(std::string name, unsigned line=0, bool text_node = false); - void add_attribute(std::string name, std::string value); + 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); void set_processed(bool processed); const_iterator begin() const; @@ -96,7 +97,7 @@ private: std::map attributes_; bool text_node_; unsigned line_; - bool processed_; + mutable bool processed_; }; diff --git a/src/load_map.cpp b/src/load_map.cpp index f549468a5..db80bd62f 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -98,13 +98,13 @@ public: void parse_map(Map & map, xml_node const& sty, std::string const& base_path=""); private: void parse_map_include( Map & map, xml_node const& include); - void parse_style(Map & map, ptree const & sty); - void parse_layer(Map & map, ptree const & lay); - void parse_metawriter(Map & map, ptree const & lay); + void parse_style(Map & map, xml_node const& sty); + void parse_layer(Map & map, xml_node const& lay); + void parse_metawriter(Map & map, xml_node const& lay); void parse_metawriter_in_symbolizer(symbolizer_base &sym, ptree const &pt); - void parse_fontset(Map & map, ptree const & fset); - void parse_font(font_set & fset, ptree const & f); + void parse_fontset(Map & map, xml_node const & fset); + void parse_font(font_set & fset, xml_node const& f); void parse_rule(feature_type_style & style, ptree const & r); @@ -390,6 +390,8 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas void map_parser::parse_map_include(Map & map, xml_node const& include) { + try + { xml_node::const_iterator itr = include.begin(); xml_node::const_iterator end = include.end(); @@ -402,7 +404,7 @@ void map_parser::parse_map_include(Map & map, xml_node const& include) } else if (itr->name() == "Style") { -// parse_style(map, *itr); + parse_style(map, *itr); } else if (itr->name() == "Layer") { @@ -477,99 +479,73 @@ void map_parser::parse_map_include(Map & map, xml_node const& include) } } } + } catch (const config_error & ex) { + ex.append_context(std::string("in map '") + filename_ + "'"); + throw; + } + map.init_metawriters(); } -void map_parser::parse_style( Map & map, ptree const & sty ) +void map_parser::parse_style(Map & map, xml_node const& sty) { - std::ostringstream s(""); - s << "name," - << "filter-mode"; - ensure_attrs(sty, "Style", s.str()); - std::string name(""); try { - name = get_attr(sty, "name"); + name = sty.get_attr("name"); feature_type_style style; - filter_mode_e filter_mode = get_attr(sty, "filter-mode", FILTER_ALL); + filter_mode_e filter_mode = sty.get_attr("filter-mode", FILTER_ALL); style.set_filter_mode(filter_mode); - ptree::const_iterator ruleIter = sty.begin(); - ptree::const_iterator endRule = sty.end(); + xml_node::const_iterator ruleIter = sty.begin(); + xml_node::const_iterator endRule = sty.end(); for (; ruleIter!=endRule; ++ruleIter) { - ptree::value_type const& rule_tag = *ruleIter; - if (rule_tag.first == "Rule") + if (ruleIter->is("Rule")) { - parse_rule( style, rule_tag.second ); - } - else if (rule_tag.first != "" && - rule_tag.first != "" ) - { - throw config_error(std::string("Unknown child node in 'Style'. ") + - "Expected 'Rule' but got '" + rule_tag.first + "'"); +// parse_rule(style, rule_tag.second); } } map.insert_style(name, style); - } catch (const config_error & ex) { - if ( ! name.empty() ) { - ex.append_context(std::string("in style '") + name + "'"); - } - ex.append_context(std::string("in map '") + filename_ + "'"); + ex.append_context(std::string("in style '") + name + "'"); throw; } } -void map_parser::parse_metawriter(Map & map, ptree const & pt) +void map_parser::parse_metawriter(Map & map, xml_node const& pt) { - ensure_attrs(pt, "MetaWriter", "name,type,file,default-output,output-empty,pixel-coordinates"); std::string name(""); metawriter_ptr writer; try { - name = get_attr(pt, "name"); - writer = metawriter_create(pt); + name = pt.get_attr("name"); +// writer = metawriter_create(pt); map.insert_metawriter(name, writer); - } catch (const config_error & ex) { - if (!name.empty()) { - ex.append_context(std::string("in meta writer '") + name + "'"); - } - ex.append_context(std::string("in map '") + filename_ + "'"); - throw; + ex.append_context(std::string("in meta writer '") + name + "'"); } } -void map_parser::parse_fontset( Map & map, ptree const & fset ) +void map_parser::parse_fontset(Map & map, xml_node const& fset) { - ensure_attrs(fset, "FontSet", "name,Font"); std::string name(""); try { - name = get_attr(fset, "name"); + name = fset.get_attr("name"); font_set fontset(name); - ptree::const_iterator itr = fset.begin(); - ptree::const_iterator end = fset.end(); + xml_node::const_iterator itr = fset.begin(); + xml_node::const_iterator end = fset.end(); for (; itr != end; ++itr) { - ptree::value_type const& font_tag = *itr; - - if (font_tag.first == "Font") + if (itr->is("Font")) { - parse_font(fontset, font_tag.second); - } - else if (font_tag.first != "" && - font_tag.first != "" ) - { - throw config_error(std::string("Unknown child node in 'FontSet'. ") + - "Expected 'Font' but got '" + font_tag.first + "'"); + parse_font(fontset, *itr); } } @@ -579,19 +555,14 @@ void map_parser::parse_fontset( Map & map, ptree const & fset ) // when it's parsed fontsets_.insert(pair(name, fontset)); } catch (const config_error & ex) { - if ( ! name.empty() ) { - ex.append_context(std::string("in FontSet '") + name + "'"); - } - ex.append_context(std::string("in map '") + filename_ + "'"); + ex.append_context(std::string("in FontSet '") + name + "'"); throw; } } -void map_parser::parse_font(font_set & fset, ptree const & f) +void map_parser::parse_font(font_set &fset, xml_node const& f) { - ensure_attrs(f, "Font", "face-name"); - - optional face_name = get_opt_attr(f, "face-name"); + optional face_name = f.get_opt_attr("face-name"); if (face_name) { if ( strict_ ) @@ -606,85 +577,72 @@ void map_parser::parse_font(font_set & fset, ptree const & f) } } -void map_parser::parse_layer( Map & map, ptree const & lay ) +void map_parser::parse_layer(Map & map, xml_node const& lay) { std::string name; - std::ostringstream s(""); - s << "name," - << "srs," - << "status," - << "minzoom," - << "maxzoom," - << "queryable," - << "clear-label-cache," - << "cache-features," - << "group-by"; - ensure_attrs(lay, "Layer", s.str()); try { - name = get_attr(lay, "name", std::string("Unnamed")); + name = lay.get_attr("name", std::string("Unnamed")); // XXX if no projection is given inherit from map? [DS] - std::string srs = get_attr(lay, "srs", map.srs()); + std::string srs = lay.get_attr("srs", map.srs()); layer lyr(name, srs); - optional status = get_opt_attr(lay, "status"); + optional status = lay.get_opt_attr("status"); if (status) { - lyr.setActive( * status ); + lyr.setActive(*status); } - optional minZoom = get_opt_attr(lay, "minzoom"); + optional minZoom = lay.get_opt_attr("minzoom"); if (minZoom) { lyr.setMinZoom( * minZoom ); } - optional maxZoom = get_opt_attr(lay, "maxzoom"); + optional maxZoom = lay.get_opt_attr("maxzoom"); if (maxZoom) { lyr.setMaxZoom( * maxZoom ); } - optional queryable = get_opt_attr(lay, "queryable"); + optional queryable = lay.get_opt_attr("queryable"); if (queryable) { lyr.setQueryable( * queryable ); } optional clear_cache = - get_opt_attr(lay, "clear-label-cache"); + lay.get_opt_attr("clear-label-cache"); if (clear_cache) { lyr.set_clear_label_cache( * clear_cache ); } optional cache_features = - get_opt_attr(lay, "cache-features"); + lay.get_opt_attr("cache-features"); if (cache_features) { lyr.set_cache_features( * cache_features ); } optional group_by = - get_opt_attr(lay, "group-by"); + lay.get_opt_attr("group-by"); if (group_by) { lyr.set_group_by( * group_by ); } - ptree::const_iterator itr2 = lay.begin(); - ptree::const_iterator end2 = lay.end(); + xml_node::const_iterator child = lay.begin(); + xml_node::const_iterator end = lay.end(); - for(; itr2 != end2; ++itr2) + for(; child != end; ++child) { - ptree::value_type const& child = *itr2; - if (child.first == "StyleName") + if (child->is("StyleName")) { - ensure_attrs(child.second, "StyleName", "none"); - std::string style_name = get_value(child.second, "style name"); + std::string style_name = child->get_value("style name"); //TODO: get_text if (style_name.empty()) { std::ostringstream ss; @@ -699,11 +657,10 @@ void map_parser::parse_layer( Map & map, ptree const & lay ) lyr.add_style(style_name); } } - else if (child.first == "Datasource") + else if (child->is("Datasource")) { - ensure_attrs(child.second, "Datasource", "base"); parameters params; - optional base = get_opt_attr( child.second, "base" ); + optional base = child->get_opt_attr("base"); if( base ) { std::map::const_iterator base_itr = datasource_templates_.find(*base); @@ -711,27 +668,16 @@ void map_parser::parse_layer( Map & map, ptree const & lay ) params = base_itr->second; } - ptree::const_iterator paramIter = child.second.begin(); - ptree::const_iterator endParam = child.second.end(); + xml_node::const_iterator paramIter = child->begin(); + xml_node::const_iterator endParam = child->end(); for (; paramIter != endParam; ++paramIter) { - ptree const& param = paramIter->second; - - if (paramIter->first == "Parameter") + if (paramIter->is("Parameter")) { - ensure_attrs(param, "Parameter", "name"); - std::string name = get_attr(param, "name"); - std::string value = get_value( param, - "datasource parameter"); + std::string name = paramIter->get_attr("name"); + std::string value = paramIter->get_text(); params[name] = value; } - else if( paramIter->first != "" && - paramIter->first != "" ) - { - throw config_error(std::string("Unknown child node in ") + - "'Datasource'. Expected 'Parameter' but got '" + - paramIter->first + "'"); - } } boost::optional base_param = params.get("base"); @@ -763,23 +709,14 @@ void map_parser::parse_layer( Map & map, ptree const & lay ) throw config_error("Unknown exception occured attempting to create datasoure for layer '" + lyr.name() + "'"); } } - else if (child.first != "" && - child.first != "") - { - throw config_error(std::string("Unknown child node in 'Layer'. ") + - "Expected 'StyleName' or 'Datasource' but got '" + - child.first + "'"); - } } - map.addLayer(lyr); - } catch (const config_error & ex) { - if ( ! name.empty() ) + if (!name.empty()) { - ex.append_context(std::string("(encountered during parsing of layer '") + name + "' in map '" + filename_ + "')"); + ex.append_context(std::string(" encountered during parsing of layer '") + name + "'"); } throw; } From 7d3fd0755d668c7c6c51534ae97c5007b2e420d6 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Wed, 7 Mar 2012 01:35:37 +0100 Subject: [PATCH 008/138] Complete XML changes in load_map.cpp --- include/mapnik/formatting/base.hpp | 3 +- include/mapnik/formatting/expression.hpp | 2 +- include/mapnik/formatting/format.hpp | 2 +- include/mapnik/formatting/registry.hpp | 4 +- include/mapnik/formatting/text.hpp | 2 +- include/mapnik/text_placements/list.hpp | 2 +- include/mapnik/text_placements/registry.hpp | 2 +- include/mapnik/text_placements/simple.hpp | 2 +- include/mapnik/text_properties.hpp | 4 +- include/mapnik/xml_tree.hpp | 8 +- src/load_map.cpp | 525 +++++++------------- src/xml_tree.cpp | 2 +- tests/visual_tests/test.py | 2 +- 13 files changed, 186 insertions(+), 374 deletions(-) diff --git a/include/mapnik/formatting/base.hpp b/include/mapnik/formatting/base.hpp index 47efe70de..7c4f0a144 100644 --- a/include/mapnik/formatting/base.hpp +++ b/include/mapnik/formatting/base.hpp @@ -36,6 +36,7 @@ namespace mapnik { typedef std::set expression_set; class processed_text; +class xml_node; struct char_properties; namespace formatting { @@ -48,7 +49,7 @@ class node public: virtual ~node() {} virtual void to_xml(boost::property_tree::ptree &xml) const; - static node_ptr from_xml(boost::property_tree::ptree const& xml); + static node_ptr from_xml(xml_node const& xml); virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const = 0; virtual void add_expressions(expression_set &output) const; }; diff --git a/include/mapnik/formatting/expression.hpp b/include/mapnik/formatting/expression.hpp index e85b7d973..bd903a4d9 100644 --- a/include/mapnik/formatting/expression.hpp +++ b/include/mapnik/formatting/expression.hpp @@ -31,7 +31,7 @@ namespace formatting { class expression_format: public node { public: void to_xml(boost::property_tree::ptree &xml) const; - static node_ptr from_xml(boost::property_tree::ptree const& xml); + static node_ptr from_xml(xml_node const& xml); virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const; virtual void add_expressions(expression_set &output) const; diff --git a/include/mapnik/formatting/format.hpp b/include/mapnik/formatting/format.hpp index 53e09a47f..22bef2d8e 100644 --- a/include/mapnik/formatting/format.hpp +++ b/include/mapnik/formatting/format.hpp @@ -31,7 +31,7 @@ namespace formatting { class format_node: public node { public: void to_xml(boost::property_tree::ptree &xml) const; - static node_ptr from_xml(boost::property_tree::ptree const& xml); + static node_ptr from_xml(xml_node const& xml); virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const; virtual void add_expressions(expression_set &output) const; diff --git a/include/mapnik/formatting/registry.hpp b/include/mapnik/formatting/registry.hpp index 9c2c9df22..2362e86ba 100644 --- a/include/mapnik/formatting/registry.hpp +++ b/include/mapnik/formatting/registry.hpp @@ -38,7 +38,7 @@ namespace mapnik namespace formatting { -typedef node_ptr (*from_xml_function_ptr)(boost::property_tree::ptree const& xml); +typedef node_ptr (*from_xml_function_ptr)(xml_node const& xml); class registry : public singleton, private boost::noncopyable @@ -47,7 +47,7 @@ public: registry(); ~registry() {} void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false); - node_ptr from_xml(std::string name, boost::property_tree::ptree const& xml); + node_ptr from_xml(std::string name, xml_node const& xml); private: std::map map_; }; diff --git a/include/mapnik/formatting/text.hpp b/include/mapnik/formatting/text.hpp index c216b4fc2..8fd1551d8 100644 --- a/include/mapnik/formatting/text.hpp +++ b/include/mapnik/formatting/text.hpp @@ -31,7 +31,7 @@ public: text_node(expression_ptr text): node(), text_(text) {} text_node(std::string text): node(), text_(parse_expression(text)) {} void to_xml(boost::property_tree::ptree &xml) const; - static node_ptr from_xml(boost::property_tree::ptree const& xml); + static node_ptr from_xml(xml_node const& xml); virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const; virtual void add_expressions(expression_set &output) const; diff --git a/include/mapnik/text_placements/list.hpp b/include/mapnik/text_placements/list.hpp index e6e0adaea..923df0c9d 100644 --- a/include/mapnik/text_placements/list.hpp +++ b/include/mapnik/text_placements/list.hpp @@ -38,7 +38,7 @@ public: text_symbolizer_properties & add(); text_symbolizer_properties & get(unsigned i); unsigned size() const; - static text_placements_ptr from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets); + static text_placements_ptr from_xml(xml_node const &xml, fontset_map const & fontsets); private: std::vector list_; friend class text_placement_info_list; diff --git a/include/mapnik/text_placements/registry.hpp b/include/mapnik/text_placements/registry.hpp index c171a5089..d8fd8b48f 100644 --- a/include/mapnik/text_placements/registry.hpp +++ b/include/mapnik/text_placements/registry.hpp @@ -49,7 +49,7 @@ public: ~registry() {} void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false); text_placements_ptr from_xml(std::string name, - boost::property_tree::ptree const& xml, + xml_node const& xml, fontset_map const & fontsets); private: std::map map_; diff --git a/include/mapnik/text_placements/simple.hpp b/include/mapnik/text_placements/simple.hpp index 4173ab87a..59c57d87e 100644 --- a/include/mapnik/text_placements/simple.hpp +++ b/include/mapnik/text_placements/simple.hpp @@ -52,7 +52,7 @@ public: text_placement_info_ptr get_placement_info(double scale_factor) const; void set_positions(std::string positions); std::string get_positions(); - static text_placements_ptr from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets); + static text_placements_ptr from_xml(xml_node const &xml, fontset_map const & fontsets); private: std::string positions_; std::vector direction_; diff --git a/include/mapnik/text_properties.hpp b/include/mapnik/text_properties.hpp index 4362a632f..5168ebaa1 100644 --- a/include/mapnik/text_properties.hpp +++ b/include/mapnik/text_properties.hpp @@ -54,7 +54,7 @@ struct char_properties { char_properties(); /** Construct object from XML. */ - void from_xml(boost::property_tree::ptree const &sym, fontset_map const & fontsets); + void from_xml(xml_node const &sym, fontset_map const & fontsets); /** Write object to XML ptree. */ void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const &dfl=char_properties()) const; std::string face_name; @@ -124,7 +124,7 @@ struct text_symbolizer_properties { text_symbolizer_properties(); /** Load all values from XML ptree. */ - void from_xml(boost::property_tree::ptree const &sym, fontset_map const & fontsets); + void from_xml(xml_node const &sym, fontset_map const & fontsets); /** Save all values to XML ptree (but does not create a new parent node!). */ void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, text_symbolizer_properties const &dfl=text_symbolizer_properties()) const; diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index a9e48a260..137fa83ab 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -75,8 +75,10 @@ public: const_iterator begin() const; const_iterator end() const; - xml_node & get_child(std::string name); - xml_node const& get_child(std::string name) const; + xml_node & get_child(std::string const& name); + xml_node const& get_child(std::string const& name) const; + xml_node *get_opt_child(std::string const& name) const; + bool has_child(std::string const& name) const; template boost::optional get_opt_attr(std::string const& name) const; @@ -89,7 +91,7 @@ public: std::string get_text() const; template - T get_value(std::string const& name) const; + T get_value() const; private: xml_tree &tree_; std::string name_; diff --git a/src/load_map.cpp b/src/load_map.cpp index db80bd62f..1fbeff3d5 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -73,7 +73,6 @@ using boost::lexical_cast; using boost::bad_lexical_cast; using boost::tokenizer; -using boost::property_tree::ptree; using std::cerr; using std::endl; @@ -101,32 +100,31 @@ private: void parse_style(Map & map, xml_node const& sty); void parse_layer(Map & map, xml_node const& lay); void parse_metawriter(Map & map, xml_node const& lay); - void parse_metawriter_in_symbolizer(symbolizer_base &sym, ptree const &pt); + void parse_metawriter_in_symbolizer(symbolizer_base &sym, xml_node const& pt); void parse_fontset(Map & map, xml_node const & fset); void parse_font(font_set & fset, xml_node const& f); - void parse_rule(feature_type_style & style, ptree const & r); + void parse_rule(feature_type_style & style, xml_node const & r); - void parse_point_symbolizer(rule & rule, ptree const & sym); - void parse_line_pattern_symbolizer(rule & rule, ptree const & sym); - void parse_polygon_pattern_symbolizer(rule & rule, ptree const & sym); - void parse_text_symbolizer(rule & rule, ptree const & sym); - void parse_shield_symbolizer(rule & rule, ptree const & sym); - void parse_line_symbolizer(rule & rule, ptree const & sym); - void parse_polygon_symbolizer(rule & rule, ptree const & sym); - void parse_building_symbolizer(rule & rule, ptree const & sym ); - void parse_raster_symbolizer(rule & rule, ptree const & sym ); - void parse_markers_symbolizer(rule & rule, ptree const & sym ); + void parse_point_symbolizer(rule & rule, xml_node const& sym); + void parse_line_pattern_symbolizer(rule & rule, xml_node const& sym); + void parse_polygon_pattern_symbolizer(rule & rule, xml_node const& sym); + void parse_text_symbolizer(rule & rule, xml_node const& sym); + void parse_shield_symbolizer(rule & rule, xml_node const& sym); + void parse_line_symbolizer(rule & rule, xml_node const& sym); + void parse_polygon_symbolizer(rule & rule, xml_node const& sym); + void parse_building_symbolizer(rule & rule, xml_node const& sym ); + void parse_raster_symbolizer(rule & rule, xml_node const& sym ); + void parse_markers_symbolizer(rule & rule, xml_node const& sym ); - void parse_raster_colorizer(raster_colorizer_ptr const& rc, ptree const& node ); - void parse_stroke(stroke & strk, ptree const & sym); + void parse_raster_colorizer(raster_colorizer_ptr const& rc, xml_node const& node ); + void parse_stroke(stroke & strk, xml_node const & sym); expression_ptr parse_expr(std::string const& expr); void ensure_font_face( const std::string & face_name ); std::string ensure_relative_to_xml( boost::optional opt_path ); - void ensure_attrs( ptree const& sym, std::string name, std::string attrs); boost::optional get_opt_color_attr(boost::property_tree::ptree const& node, std::string const& name); @@ -144,27 +142,7 @@ private: }; -void remove_empty_text_nodes(ptree &pt) -{ - ptree::iterator itr = pt.begin(); - ptree::iterator end = pt.end(); - while (itr!=end) - { - if (itr->first == "") { - std::string trimmed = boost::algorithm::trim_copy(itr->second.data()); - if (trimmed.empty()) { - itr = pt.erase(itr); - } else { - itr++; - } - } else { - remove_empty_text_nodes(itr->second); - itr++; - } - } -} -//#include void load_map(Map & map, std::string const& filename, bool strict) { xml_tree tree; @@ -183,7 +161,7 @@ void load_map(Map & map, std::string const& filename, bool strict) } #endif map_parser parser(strict, filename); -// parser.parse_map(map, pt); + parser.parse_map(map, tree.root()); } void load_map_string(Map & map, std::string const& str, bool strict, std::string const& base_path) @@ -209,7 +187,7 @@ void load_map_string(Map & map, std::string const& str, bool strict, std::string #endif map_parser parser(strict, base_path); -// parser.parse_map(map, tree.root(), base_path); + parser.parse_map(map, tree.root(), base_path); } expression_ptr map_parser::parse_expr(std::string const& str) @@ -408,15 +386,15 @@ void map_parser::parse_map_include(Map & map, xml_node const& include) } else if (itr->name() == "Layer") { -// parse_layer(map, *itr); + parse_layer(map, *itr); } else if (itr->name() == "FontSet") { -// parse_fontset(map, *itr); + parse_fontset(map, *itr); } else if (itr->name() == "MetaWriter") { -// parse_metawriter(map, *itr); + parse_metawriter(map, *itr); } else if (itr->name() == "FileSource") { @@ -459,13 +437,13 @@ void map_parser::parse_map_include(Map & map, xml_node const& include) if (*type == "int") { is_string = false; - int value = paramIter->get_value("parameter"); + int value = paramIter->get_value(); params[name] = value; } else if (*type == "float") { is_string = false; - double value = paramIter->get_value("parameter"); + double value = paramIter->get_value(); params[name] = value; } } @@ -505,7 +483,7 @@ void map_parser::parse_style(Map & map, xml_node const& sty) { if (ruleIter->is("Rule")) { -// parse_rule(style, rule_tag.second); + parse_rule(style, *ruleIter); } } @@ -523,7 +501,7 @@ void map_parser::parse_metawriter(Map & map, xml_node const& pt) try { name = pt.get_attr("name"); -// writer = metawriter_create(pt); + //TODO: writer = metawriter_create(pt); map.insert_metawriter(name, writer); } catch (const config_error & ex) { ex.append_context(std::string("in meta writer '") + name + "'"); @@ -642,7 +620,7 @@ void map_parser::parse_layer(Map & map, xml_node const& lay) if (child->is("StyleName")) { - std::string style_name = child->get_value("style name"); //TODO: get_text + std::string style_name = child->get_value(); //TODO: get_text if (style_name.empty()) { std::ostringstream ss; @@ -722,149 +700,140 @@ void map_parser::parse_layer(Map & map, xml_node const& lay) } } -void map_parser::parse_rule( feature_type_style & style, ptree const & r ) +void map_parser::parse_rule(feature_type_style & style, xml_node const& r) { - ensure_attrs(r, "Rule", "name"); std::string name; try { - name = get_attr( r, "name", std::string()); + name = r.get_attr("name", std::string()); rule rule(name); - optional filter_expr = - get_opt_child( r, "Filter"); - if (filter_expr) + xml_node *child = r.get_opt_child("Filter"); + if (child) { - rule.set_filter(parse_expr(*filter_expr)); + rule.set_filter(child->get_value()); } - if (has_child(r, "ElseFilter")) + if (r.has_child("ElseFilter")) { rule.set_else(true); } - if (has_child(r, "AlsoFilter")) + if (r.has_child("AlsoFilter")) { rule.set_also(true); } - optional min_scale = - get_opt_child(r, "MinScaleDenominator"); - if (min_scale) + child = r.get_opt_child("MinScaleDenominator"); + if (child) { - rule.set_min_scale(*min_scale); + rule.set_min_scale(child->get_value()); } - optional max_scale = - get_opt_child(r, "MaxScaleDenominator"); - if (max_scale) + child = r.get_opt_child("MaxScaleDenominator"); + if (child) { - rule.set_max_scale(*max_scale); + rule.set_max_scale(child->get_value()); } - ptree::const_iterator symIter = r.begin(); - ptree::const_iterator endSym = r.end(); + xml_node::const_iterator symIter = r.begin(); + xml_node::const_iterator endSym = r.end(); for( ;symIter != endSym; ++symIter) { - ptree::value_type const& sym = *symIter; - if ( sym.first == "PointSymbolizer") + if ( symIter->is("PointSymbolizer")) { - parse_point_symbolizer( rule, sym.second ); + parse_point_symbolizer(rule, *symIter); } - else if ( sym.first == "LinePatternSymbolizer") + else if (symIter->is("LinePatternSymbolizer")) { - parse_line_pattern_symbolizer( rule, sym.second ); + parse_line_pattern_symbolizer(rule, *symIter); } - else if ( sym.first == "PolygonPatternSymbolizer") + else if (symIter->is("PolygonPatternSymbolizer")) { - parse_polygon_pattern_symbolizer( rule, sym.second ); + parse_polygon_pattern_symbolizer(rule, *symIter); } - else if ( sym.first == "TextSymbolizer") + else if (symIter->is("TextSymbolizer")) { - parse_text_symbolizer( rule, sym.second ); + parse_text_symbolizer(rule, *symIter); } - else if ( sym.first == "ShieldSymbolizer") + else if (symIter->is("ShieldSymbolizer")) { - parse_shield_symbolizer( rule, sym.second ); + parse_shield_symbolizer(rule, *symIter); } - else if ( sym.first == "LineSymbolizer") + else if (symIter->is("LineSymbolizer")) { - parse_line_symbolizer( rule, sym.second ); + parse_line_symbolizer(rule, *symIter); } - else if ( sym.first == "PolygonSymbolizer") + else if (symIter->is("PolygonSymbolizer")) { - parse_polygon_symbolizer( rule, sym.second ); + parse_polygon_symbolizer(rule, *symIter); } - else if ( sym.first == "BuildingSymbolizer") + else if (symIter->is("BuildingSymbolizer")) { - parse_building_symbolizer( rule, sym.second ); + parse_building_symbolizer(rule, *symIter); } - else if ( sym.first == "RasterSymbolizer") + else if (symIter->is("RasterSymbolizer")) { - parse_raster_symbolizer( rule, sym.second ); + parse_raster_symbolizer( rule, *symIter); } - else if ( sym.first == "MarkersSymbolizer") + else if (symIter->is("MarkersSymbolizer")) { - parse_markers_symbolizer(rule, sym.second); - } - - else if ( sym.first != "MinScaleDenominator" && - sym.first != "MaxScaleDenominator" && - sym.first != "Filter" && - sym.first != "ElseFilter" && - sym.first != "AlsoFilter" && - sym.first != "" && - sym.first != "" ) - { - throw config_error(std::string("Unknown symbolizer '") + - sym.first + "'"); + parse_markers_symbolizer(rule, *symIter); } } - style.add_rule(rule); } catch (const config_error & ex) { - if ( ! name.empty() ) + if (!name.empty() ) { - ex.append_context(std::string("in rule '") + name + "' in map '" + filename_ + "')"); + ex.append_context(std::string("in rule '") + name + "'"); } throw; } } -void map_parser::parse_metawriter_in_symbolizer(symbolizer_base &sym, ptree const &pt) +void map_parser::parse_metawriter_in_symbolizer(symbolizer_base &sym, xml_node const &pt) { - optional writer = get_opt_attr(pt, "meta-writer"); + optional writer = pt.get_opt_attr("meta-writer"); if (!writer) return; - optional output = get_opt_attr(pt, "meta-output"); + optional output = pt.get_opt_attr("meta-output"); sym.add_metawriter(*writer, output); } -void map_parser::parse_point_symbolizer( rule & rule, ptree const & sym ) +void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym) { try { - std::stringstream s; - s << "file,base,allow-overlap,ignore-placement,opacity,placement,transform,meta-writer,meta-output"; + optional file = sym.get_opt_attr("file"); + optional base = sym.get_opt_attr("base"); + optional allow_overlap = sym.get_opt_attr("allow-overlap"); + optional ignore_placement = sym.get_opt_attr("ignore-placement"); + optional opacity = sym.get_opt_attr("opacity"); + optional transform_wkt = sym.get_opt_attr("transform"); - optional file = get_opt_attr(sym, "file"); - optional base = get_opt_attr(sym, "base"); - optional allow_overlap = - get_opt_attr(sym, "allow-overlap"); - optional ignore_placement = - get_opt_attr(sym, "ignore-placement"); - optional opacity = - get_opt_attr(sym, "opacity"); - - optional transform_wkt = get_opt_attr(sym, "transform"); + point_symbolizer symbol; + if (allow_overlap) + { + symbol.set_allow_overlap( * allow_overlap ); + } + if (opacity) + { + symbol.set_opacity( * opacity ); + } + if (ignore_placement) + { + symbol.set_ignore_placement( * ignore_placement ); + } + point_placement_e placement = + sym.get_attr("placement", CENTROID_POINT_PLACEMENT); + symbol.set_point_placement( placement ); if (file) { - ensure_attrs(sym, "PointSymbolizer", s.str()); try { if( base ) @@ -878,23 +847,7 @@ void map_parser::parse_point_symbolizer( rule & rule, ptree const & sym ) *file = ensure_relative_to_xml(file); - point_symbolizer symbol(parse_path(*file)); - - if (allow_overlap) - { - symbol.set_allow_overlap( * allow_overlap ); - } - if (opacity) - { - symbol.set_opacity( * opacity ); - } - if (ignore_placement) - { - symbol.set_ignore_placement( * ignore_placement ); - } - point_placement_e placement = - get_attr(sym, "placement", CENTROID_POINT_PLACEMENT); - symbol.set_point_placement( placement ); + symbol.set_filename(parse_path(*file)); if (transform_wkt) { @@ -930,32 +883,9 @@ void map_parser::parse_point_symbolizer( rule & rule, ptree const & sym ) std::clog << "### WARNING: " << msg << endl; } } - - } - else - { - ensure_attrs(sym, "PointSymbolizer", s.str()); - point_symbolizer symbol; - - if (allow_overlap) - { - symbol.set_allow_overlap( * allow_overlap ); - } - if (opacity) - { - symbol.set_opacity( * opacity ); - } - if (ignore_placement) - { - symbol.set_ignore_placement( * ignore_placement ); - } - point_placement_e placement = - get_attr(sym, "placement", CENTROID_POINT_PLACEMENT); - symbol.set_point_placement( placement ); - - parse_metawriter_in_symbolizer(symbol, sym); - rule.append(symbol); } + parse_metawriter_in_symbolizer(symbol, sym); + rule.append(symbol); } catch (const config_error & ex) { @@ -965,30 +895,17 @@ void map_parser::parse_point_symbolizer( rule & rule, ptree const & sym ) } -void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym ) +void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) { try { std::string filename(""); - optional file = get_opt_attr(sym, "file"); - optional base = get_opt_attr(sym, "base"); - optional transform_wkt = get_opt_attr(sym, "transform"); - - std::stringstream s; - //s << "file,opacity,spacing,max-error,allow-overlap,placement,"; - s << "file,base,transform,fill,opacity," - << "spacing,max-error,allow-overlap," - << "width,height,placement,marker-type," - << "stroke,stroke-width,stroke-opacity,stroke-linejoin," - << "stroke-linecap,stroke-dashoffset,stroke-dasharray," - // note: stroke-gamma intentionally left off here as markers do not support them - << "meta-writer,meta-output"; - ensure_attrs(sym, "MarkersSymbolizer", s.str()); + optional file = sym.get_opt_attr("file"); + optional base = sym.get_opt_attr("base"); + optional transform_wkt = sym.get_opt_attr("transform"); if (file) { - //s << "base,transform"; - //ensure_attrs(sym, "MarkersSymbolizer", s.str()); try { if (base) @@ -1015,14 +932,9 @@ void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym ) } } } - /*else - { - //s << "fill,marker-type,width,height"; - //ensure_attrs(sym, "MarkersSymbolizer", s.str()); - }*/ markers_symbolizer symbol(parse_path(filename)); - optional opacity = get_opt_attr(sym, "opacity"); + optional opacity = sym.get_opt_attr("opacity"); if (opacity) symbol.set_opacity( *opacity ); if (transform_wkt) @@ -1043,17 +955,17 @@ void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym ) symbol.set_transform(matrix); } - optional c = get_opt_color_attr(sym, "fill"); + optional c = sym.get_opt_attr("fill"); if (c) symbol.set_fill(*c); - optional spacing = get_opt_attr(sym, "spacing"); + optional spacing = sym.get_opt_attr("spacing"); if (spacing) symbol.set_spacing(*spacing); - optional max_error = get_opt_attr(sym, "max-error"); + optional max_error = sym.get_opt_attr("max-error"); if (max_error) symbol.set_max_error(*max_error); - optional allow_overlap = get_opt_attr(sym, "allow-overlap"); + optional allow_overlap = sym.get_opt_attr("allow-overlap"); if (allow_overlap) symbol.set_allow_overlap(*allow_overlap); - optional w = get_opt_attr(sym, "width"); - optional h = get_opt_attr(sym, "height"); + optional w = sym.get_opt_attr("width"); + optional h = sym.get_opt_attr("height"); if (w && h) { symbol.set_width(*w); @@ -1075,7 +987,7 @@ void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym ) parse_stroke(strk,sym); symbol.set_stroke(strk); - marker_placement_e placement = get_attr(sym, "placement", MARKER_LINE_PLACEMENT); + marker_placement_e placement = sym.get_attr("placement", MARKER_LINE_PLACEMENT); symbol.set_marker_placement( placement ); marker_type_e dfl_marker_type = ARROW; @@ -1083,7 +995,7 @@ void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym ) if (placement == MARKER_POINT_PLACEMENT) dfl_marker_type = ELLIPSE; - marker_type_e marker_type = get_attr(sym, "marker-type", dfl_marker_type); + marker_type_e marker_type = sym.get_attr("marker-type", dfl_marker_type); symbol.set_marker_type( marker_type ); parse_metawriter_in_symbolizer(symbol, sym); @@ -1096,13 +1008,12 @@ void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym ) } } -void map_parser::parse_line_pattern_symbolizer( rule & rule, ptree const & sym ) +void map_parser::parse_line_pattern_symbolizer( rule & rule, xml_node const & sym ) { - ensure_attrs(sym, "LinePatternSymbolizer", "file,base,meta-writer,meta-output"); try { - std::string file = get_attr(sym, "file"); - optional base = get_opt_attr(sym, "base"); + std::string file = sym.get_attr("file"); + optional base = sym.get_opt_attr("base"); try { @@ -1144,13 +1055,12 @@ void map_parser::parse_line_pattern_symbolizer( rule & rule, ptree const & sym ) } void map_parser::parse_polygon_pattern_symbolizer( rule & rule, - ptree const & sym ) + xml_node const & sym ) { - ensure_attrs(sym, "PolygonPatternSymbolizer", "file,base,alignment,gamma,meta-writer,meta-output"); try { - std::string file = get_attr(sym, "file"); - optional base = get_opt_attr(sym, "base"); + std::string file = sym.get_attr("file"); + optional base = sym.get_opt_attr("base"); try { @@ -1168,15 +1078,15 @@ void map_parser::parse_polygon_pattern_symbolizer( rule & rule, polygon_pattern_symbolizer symbol(parse_path(file)); // pattern alignment - pattern_alignment_e p_alignment = get_attr(sym, "alignment",LOCAL_ALIGNMENT); + pattern_alignment_e p_alignment = sym.get_attr("alignment",LOCAL_ALIGNMENT); symbol.set_alignment(p_alignment); // gamma - optional gamma = get_opt_attr(sym, "gamma"); + optional gamma = sym.get_opt_attr("gamma"); if (gamma) symbol.set_gamma(*gamma); // gamma method - optional gamma_method = get_opt_attr(sym, "gamma-method"); + optional gamma_method = sym.get_opt_attr("gamma-method"); if (gamma_method) symbol.set_gamma_method(*gamma_method); parse_metawriter_in_symbolizer(symbol, sym); @@ -1203,27 +1113,12 @@ void map_parser::parse_polygon_pattern_symbolizer( rule & rule, } } -void map_parser::parse_text_symbolizer( rule & rule, ptree const & sym ) +void map_parser::parse_text_symbolizer( rule & rule, xml_node const& sym ) { - std::stringstream s_common; - s_common << "name,face-name,fontset-name,size,fill,orientation," - << "dx,dy,placement,vertical-alignment,halo-fill," - << "halo-radius,text-ratio,wrap-width,wrap-before," - << "wrap-character,text-transform,line-spacing," - << "label-position-tolerance,character-spacing," - << "spacing,minimum-distance,minimum-padding,minimum-path-length," - << "avoid-edges,allow-overlap,opacity,max-char-angle-delta," - << "horizontal-alignment,justify-alignment"; - - std::stringstream s_symbolizer; - s_symbolizer << s_common.str() << ",placements,placement-type," - << "meta-writer,meta-output"; - - ensure_attrs(sym, "TextSymbolizer", s_symbolizer.str()); try { text_placements_ptr placement_finder; - optional placement_type = get_opt_attr(sym, "placement-type"); + optional placement_type = sym.get_opt_attr("placement-type"); if (placement_type) { placement_finder = placements::registry::instance()->from_xml(*placement_type, sym, fontsets_); } else { @@ -1245,28 +1140,12 @@ void map_parser::parse_text_symbolizer( rule & rule, ptree const & sym ) } } -void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym ) +void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym ) { - std::string s_common( - "name,face-name,fontset-name,size,fill,orientation," - "dx,dy,placement,vertical-alignment,halo-fill," - "halo-radius,text-ratio,wrap-width,wrap-before," - "wrap-character,text-transform,line-spacing," - "label-position-tolerance,character-spacing," - "spacing,minimum-distance,minimum-padding,minimum-path-length," - "avoid-edges,allow-overlap,opacity,max-char-angle-delta," - "horizontal-alignment,justify-alignment"); - - std::string s_symbolizer(s_common + ",file,base," - "transform,shield-dx,shield-dy,text-opacity," - "unlock-image" - "placements,placement-type,meta-writer,meta-output"); - - ensure_attrs(sym, "ShieldSymbolizer", s_symbolizer); try { text_placements_ptr placement_finder; - optional placement_type = get_opt_attr(sym, "placement-type"); + optional placement_type = sym.get_opt_attr("placement-type"); if (placement_type) { placement_finder = placements::registry::instance()->from_xml(*placement_type, sym, fontsets_); } else { @@ -1279,7 +1158,7 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym ) shield_symbolizer shield_symbol = shield_symbolizer(placement_finder); /* Symbolizer specific attributes. */ - optional transform_wkt = get_opt_attr(sym, "transform"); + optional transform_wkt = sym.get_opt_attr("transform"); if (transform_wkt) { agg::trans_affine tr; @@ -1297,12 +1176,12 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym ) shield_symbol.set_transform(matrix); } // shield displacement - double shield_dx = get_attr(sym, "shield-dx", 0.0); - double shield_dy = get_attr(sym, "shield-dy", 0.0); + double shield_dx = sym.get_attr("shield-dx", 0.0); + double shield_dy = sym.get_attr("shield-dy", 0.0); shield_symbol.set_shield_displacement(shield_dx,shield_dy); // opacity - optional opacity = get_opt_attr(sym, "opacity"); + optional opacity = sym.get_opt_attr("opacity"); if (opacity) { shield_symbol.set_opacity(*opacity); @@ -1311,7 +1190,7 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym ) // text-opacity // TODO: Could be problematic because it is named opacity in TextSymbolizer but opacity has a diffrent meaning here. optional text_opacity = - get_opt_attr(sym, "text-opacity"); + sym.get_opt_attr("text-opacity"); if (text_opacity) { shield_symbol.set_text_opacity( * text_opacity ); @@ -1319,7 +1198,7 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym ) // unlock_image optional unlock_image = - get_opt_attr(sym, "unlock-image"); + sym.get_opt_attr("unlock-image"); if (unlock_image) { shield_symbol.set_unlock_image( * unlock_image ); @@ -1327,8 +1206,8 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym ) parse_metawriter_in_symbolizer(shield_symbol, sym); - std::string image_file = get_attr(sym, "file"); - optional base = get_opt_attr(sym, "base"); + std::string image_file = sym.get_attr("file"); + optional base = sym.get_opt_attr("base"); try { @@ -1366,42 +1245,42 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym ) } } -void map_parser::parse_stroke(stroke & strk, ptree const & sym) +void map_parser::parse_stroke(stroke & strk, xml_node const & sym) { // stroke color - optional c = get_opt_color_attr(sym, "stroke"); + optional c = sym.get_opt_attr("stroke"); if (c) strk.set_color(*c); // stroke-width - optional width = get_opt_attr(sym, "stroke-width"); + optional width = sym.get_opt_attr("stroke-width"); if (width) strk.set_width(*width); // stroke-opacity - optional opacity = get_opt_attr(sym, "stroke-opacity"); + optional opacity = sym.get_opt_attr("stroke-opacity"); if (opacity) strk.set_opacity(*opacity); // stroke-linejoin - optional line_join = get_opt_attr(sym, "stroke-linejoin"); + optional line_join = sym.get_opt_attr("stroke-linejoin"); if (line_join) strk.set_line_join(*line_join); // stroke-linecap - optional line_cap = get_opt_attr(sym, "stroke-linecap"); + optional line_cap = sym.get_opt_attr("stroke-linecap"); if (line_cap) strk.set_line_cap(*line_cap); // stroke-gamma - optional gamma = get_opt_attr(sym, "stroke-gamma"); + optional gamma = sym.get_opt_attr("stroke-gamma"); if (gamma) strk.set_gamma(*gamma); // stroke-gamma-method - optional gamma_method = get_opt_attr(sym, "stroke-gamma-method"); + optional gamma_method = sym.get_opt_attr("stroke-gamma-method"); if (gamma_method) strk.set_gamma_method(*gamma_method); // stroke-dashoffset - optional dash_offset = get_opt_attr(sym, "stroke-dashoffset"); + optional dash_offset = sym.get_opt_attr("stroke-dashoffset"); if (dash_offset) strk.set_dash_offset(*dash_offset); // stroke-dasharray - optional str = get_opt_attr(sym,"stroke-dasharray"); + optional str = sym.get_opt_attr("stroke-dasharray"); if (str) { tokenizer<> tok (*str); @@ -1441,15 +1320,8 @@ void map_parser::parse_stroke(stroke & strk, ptree const & sym) } } -void map_parser::parse_line_symbolizer( rule & rule, ptree const & sym ) +void map_parser::parse_line_symbolizer( rule & rule, xml_node const & sym ) { - std::stringstream s; - s << "stroke,stroke-width,stroke-opacity,stroke-linejoin," - << "stroke-linecap,stroke-gamma,stroke-dash-offset,stroke-dasharray," - << "rasterizer," - << "meta-writer,meta-output"; - - ensure_attrs(sym, "LineSymbolizer", s.str()); try { stroke strk; @@ -1457,8 +1329,8 @@ void map_parser::parse_line_symbolizer( rule & rule, ptree const & sym ) line_symbolizer symbol = line_symbolizer(strk); // rasterizer method - line_rasterizer_e rasterizer = get_attr(sym, "rasterizer", RASTERIZER_FULL); - //optional rasterizer_method = get_opt_attr(sym, "full"); + line_rasterizer_e rasterizer = sym.get_attr("rasterizer", RASTERIZER_FULL); + //optional rasterizer_method = sym.get_opt_attr("full"); symbol.set_rasterizer(rasterizer); parse_metawriter_in_symbolizer(symbol, sym); @@ -1472,23 +1344,22 @@ void map_parser::parse_line_symbolizer( rule & rule, ptree const & sym ) } -void map_parser::parse_polygon_symbolizer( rule & rule, ptree const & sym ) +void map_parser::parse_polygon_symbolizer( rule & rule, xml_node const & sym ) { - ensure_attrs(sym, "PolygonSymbolizer", "fill,fill-opacity,gamma,gamma-method,meta-writer,meta-output"); try { polygon_symbolizer poly_sym; // fill - optional fill = get_opt_color_attr(sym, "fill"); + optional fill = sym.get_opt_attr("fill"); if (fill) poly_sym.set_fill(*fill); // fill-opacity - optional opacity = get_opt_attr(sym, "fill-opacity"); + optional opacity = sym.get_opt_attr("fill-opacity"); if (opacity) poly_sym.set_opacity(*opacity); // gamma - optional gamma = get_opt_attr(sym, "gamma"); + optional gamma = sym.get_opt_attr("gamma"); if (gamma) poly_sym.set_gamma(*gamma); // gamma method - optional gamma_method = get_opt_attr(sym, "gamma-method"); + optional gamma_method = sym.get_opt_attr("gamma-method"); if (gamma_method) poly_sym.set_gamma_method(*gamma_method); parse_metawriter_in_symbolizer(poly_sym, sym); @@ -1502,21 +1373,20 @@ void map_parser::parse_polygon_symbolizer( rule & rule, ptree const & sym ) } -void map_parser::parse_building_symbolizer( rule & rule, ptree const & sym ) +void map_parser::parse_building_symbolizer( rule & rule, xml_node const & sym ) { - ensure_attrs(sym, "PolygonSymbolizer", "fill,fill-opacity,height,meta-writer,meta-output"); try { building_symbolizer building_sym; // fill - optional fill = get_opt_color_attr(sym, "fill"); + optional fill = sym.get_opt_attr("fill"); if (fill) building_sym.set_fill(*fill); // fill-opacity - optional opacity = get_opt_attr(sym, "fill-opacity"); + optional opacity = sym.get_opt_attr("fill-opacity"); if (opacity) building_sym.set_opacity(*opacity); // height - optional height = get_opt_attr(sym, "height"); + optional height = sym.get_opt_attr("height"); if (height) building_sym.set_height(parse_expr(*height)); parse_metawriter_in_symbolizer(building_sym, sym); @@ -1529,53 +1399,43 @@ void map_parser::parse_building_symbolizer( rule & rule, ptree const & sym ) } } -void map_parser::parse_raster_symbolizer( rule & rule, ptree const & sym ) +void map_parser::parse_raster_symbolizer( rule & rule, xml_node const & sym ) { - // no support for meta-writer,meta-output - ensure_attrs(sym, "RasterSymbolizer", "mode,scaling,opacity,filter-factor,mesh-size"); try { raster_symbolizer raster_sym; // mode - optional mode = get_opt_attr(sym, "mode"); + optional mode = sym.get_opt_attr("mode"); if (mode) raster_sym.set_mode(*mode); // scaling - optional scaling = get_opt_attr(sym, "scaling"); + optional scaling = sym.get_opt_attr("scaling"); if (scaling) raster_sym.set_scaling(*scaling); // opacity - optional opacity = get_opt_attr(sym, "opacity"); + optional opacity = sym.get_opt_attr("opacity"); if (opacity) raster_sym.set_opacity(*opacity); // filter factor - optional filter_factor = get_opt_attr(sym, "filter-factor"); + optional filter_factor = sym.get_opt_attr("filter-factor"); if (filter_factor) raster_sym.set_filter_factor(*filter_factor); // mesh-size - optional mesh_size = get_opt_attr(sym, "mesh-size"); + optional mesh_size = sym.get_opt_attr("mesh-size"); if (mesh_size) raster_sym.set_mesh_size(*mesh_size); - ptree::const_iterator cssIter = sym.begin(); - ptree::const_iterator endCss = sym.end(); + xml_node::const_iterator cssIter = sym.begin(); + xml_node::const_iterator endCss = sym.end(); for(; cssIter != endCss; ++cssIter) { - ptree::value_type const& css_tag = *cssIter; - - if (css_tag.first == "RasterColorizer") + if (cssIter->is("RasterColorizer")) { raster_colorizer_ptr colorizer(new raster_colorizer()); raster_sym.set_colorizer(colorizer); - parse_raster_colorizer(colorizer, css_tag.second); - } - else if (css_tag.first != "" && - css_tag.first != "" ) - { - throw config_error(std::string("Unknown child node. ") + - "Expected 'RasterColorizer' but got '" + css_tag.first + "'"); + parse_raster_colorizer(colorizer, *cssIter); } } //Note: raster_symbolizer doesn't support metawriters @@ -1589,14 +1449,13 @@ void map_parser::parse_raster_symbolizer( rule & rule, ptree const & sym ) } void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, - ptree const& node ) + xml_node const& node ) { try { - ensure_attrs(node, "RasterColorizer", "default-mode,default-color,epsilon"); // mode colorizer_mode default_mode = - get_attr(node, "default-mode", COLORIZER_LINEAR); + node.get_attr("default-mode", COLORIZER_LINEAR); if(default_mode == COLORIZER_INHERIT) { throw config_error("RasterColorizer mode must not be INHERIT. "); @@ -1604,7 +1463,7 @@ void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, rc->set_default_mode( default_mode ); // default colour - optional default_color = get_opt_color_attr(node, "default-color"); + optional default_color = node.get_opt_attr("default-color"); if (default_color) { rc->set_default_color( *default_color ); @@ -1612,7 +1471,7 @@ void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, // epsilon - optional eps = get_opt_attr(node, "epsilon"); + optional eps = node.get_opt_attr("epsilon"); if (eps) { if(*eps < 0) { @@ -1622,31 +1481,27 @@ void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, } - ptree::const_iterator stopIter = node.begin(); - ptree::const_iterator endStop = node.end(); + xml_node::const_iterator stopIter = node.begin(); + xml_node::const_iterator endStop = node.end(); float maximumValue = -std::numeric_limits::max(); for(; stopIter != endStop; ++stopIter) { - ptree::value_type const& stop_tag = *stopIter; - ptree const & stop = stopIter->second; - - if (stop_tag.first == "stop") + if (stopIter->is("stop")) { - ensure_attrs(stop_tag.second, "stop", "color,mode,value,label"); // colour is optional. - optional stopcolor = get_opt_color_attr(stop, "color"); + optional stopcolor = stopIter->get_opt_attr("color"); if (!stopcolor) { *stopcolor = *default_color; } // mode default to INHERIT colorizer_mode mode = - get_attr(stop, "mode", COLORIZER_INHERIT); + stopIter->get_attr("mode", COLORIZER_INHERIT); // value is required, and it must be bigger than the previous optional value = - get_opt_attr(stop, "value"); + stopIter->get_opt_attr("value"); if(!value) { throw config_error("stop tag missing value"); @@ -1658,7 +1513,7 @@ void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, maximumValue = *value; optional label = - get_opt_attr(stop, "label"); + stopIter->get_opt_attr("label"); //append the stop colorizer_stop tmpStop; @@ -1670,12 +1525,6 @@ void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, rc->add_stop(tmpStop); } - else if (stop_tag.first != "" && - stop_tag.first != "" ) - { - throw config_error(std::string("Unknown child node. ") + - "Expected 'stop' but got '" + stop_tag.first + "'"); - } } } catch (const config_error & ex) @@ -1720,44 +1569,4 @@ std::string map_parser::ensure_relative_to_xml( boost::optional opt return *opt_path; } -void map_parser::ensure_attrs(ptree const& sym, std::string name, std::string attrs) -{ - typedef ptree::key_type::value_type Ch; - optional attribs = sym.get_child_optional( boost::property_tree::xml_parser::xmlattr() ); - if (attribs) - { - std::set attr_set; - boost::split(attr_set, attrs, boost::is_any_of(",")); - std::ostringstream s(""); - s << "### " << name << " properties warning: "; - int missing = 0; - for (ptree::const_iterator it = attribs.get().begin(); it != attribs.get().end(); ++it) - { - std::string name = it->first; - bool found = (attr_set.find(name) != attr_set.end()); - if (!found) - { - if (missing) - { - s << ","; - } - s << "'" << name << "'"; - ++missing; - } - } - if (missing) { - if (missing > 1) - { - s << " are"; - } - else - { - s << " is"; - } - s << " invalid, acceptable values are:\n'" << attrs << "'\n"; - std::clog << s.str(); - } - } -} - } // end of namespace mapnik diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 494fc14d7..2b98e2dc0 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -185,7 +185,7 @@ void xml_node::set_processed(bool processed) processed_ = processed; } -xml_node &xml_node::add_child(std::string name, unsigned line, bool text_node) +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(); diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index b7509fd73..a7ded9ce5 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -51,7 +51,7 @@ def render(filename, width, height=100): return m if len(sys.argv) == 2: - files = [(sys.argv[1], 500)] + files = [(sys.argv[1], (500, 500))] elif len(sys.argv) > 2: files = [sys.argv[1:]] From f214675c69cedf59438729478b496d66dbc49ab8 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Wed, 7 Mar 2012 02:23:16 +0100 Subject: [PATCH 009/138] Modify all other files for new XML structure. --- include/mapnik/formatting/expression.hpp | 2 +- include/mapnik/formatting/registry.hpp | 2 +- include/mapnik/text_placements/registry.hpp | 2 +- src/formatting/base.cpp | 11 ++-- src/formatting/expression.cpp | 7 ++- src/formatting/format.cpp | 25 ++++---- src/formatting/registry.cpp | 7 ++- src/formatting/text.cpp | 9 +-- src/text_placements/list.cpp | 16 +++-- src/text_placements/registry.cpp | 2 +- src/text_placements/simple.cpp | 5 +- src/text_properties.cpp | 65 +++++++++++---------- src/xml_tree.cpp | 2 +- 13 files changed, 81 insertions(+), 74 deletions(-) diff --git a/include/mapnik/formatting/expression.hpp b/include/mapnik/formatting/expression.hpp index bd903a4d9..d3db09691 100644 --- a/include/mapnik/formatting/expression.hpp +++ b/include/mapnik/formatting/expression.hpp @@ -51,7 +51,7 @@ public: private: node_ptr child_; - static expression_ptr get_expression(boost::property_tree::ptree const& xml, std::string name); + static expression_ptr get_expression(xml_node const& xml, std::string name); }; } //ns formatting } //ns mapnik diff --git a/include/mapnik/formatting/registry.hpp b/include/mapnik/formatting/registry.hpp index 2362e86ba..7c4faa4d7 100644 --- a/include/mapnik/formatting/registry.hpp +++ b/include/mapnik/formatting/registry.hpp @@ -47,7 +47,7 @@ public: registry(); ~registry() {} void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false); - node_ptr from_xml(std::string name, xml_node const& xml); + node_ptr from_xml(xml_node const& xml); private: std::map map_; }; diff --git a/include/mapnik/text_placements/registry.hpp b/include/mapnik/text_placements/registry.hpp index d8fd8b48f..35fd59f46 100644 --- a/include/mapnik/text_placements/registry.hpp +++ b/include/mapnik/text_placements/registry.hpp @@ -39,7 +39,7 @@ namespace placements { typedef text_placements_ptr (*from_xml_function_ptr)( - boost::property_tree::ptree const& xml, fontset_map const & fontsets); + xml_node const& xml, fontset_map const & fontsets); class registry : public singleton, private boost::noncopyable diff --git a/src/formatting/base.cpp b/src/formatting/base.cpp index e9c1ff3e7..307935809 100644 --- a/src/formatting/base.cpp +++ b/src/formatting/base.cpp @@ -23,6 +23,7 @@ #include #include #include +#include // boost #include @@ -38,18 +39,18 @@ void node::to_xml(boost::property_tree::ptree &xml) const #endif } -node_ptr node::from_xml(boost::property_tree::ptree const& xml) +node_ptr node::from_xml(xml_node const& xml) { list_node *list = new list_node(); node_ptr list_ptr(list); - boost::property_tree::ptree::const_iterator itr = xml.begin(); - boost::property_tree::ptree::const_iterator end = xml.end(); + xml_node::const_iterator itr = xml.begin(); + xml_node::const_iterator end = xml.end(); for (; itr != end; ++itr) { - if (itr->first == "" || itr->first == "" || itr->first == "Placement") + if (itr->name() == "Placement") { continue; } - node_ptr n = registry::instance()->from_xml(itr->first, itr->second); + node_ptr n = registry::instance()->from_xml(*itr); if (n) list->push_back(n); } if (list->get_children().size() == 1) { diff --git a/src/formatting/expression.cpp b/src/formatting/expression.cpp index 0ee7598bd..40bc1f466 100644 --- a/src/formatting/expression.cpp +++ b/src/formatting/expression.cpp @@ -27,6 +27,7 @@ #include #include #include +#include // boost @@ -51,7 +52,7 @@ void expression_format::to_xml(boost::property_tree::ptree &xml) const if (child_) child_->to_xml(new_node); } -node_ptr expression_format::from_xml(ptree const& xml) +node_ptr expression_format::from_xml(xml_node const& xml) { expression_format *n = new expression_format(); node_ptr np(n); @@ -72,9 +73,9 @@ node_ptr expression_format::from_xml(ptree const& xml) return np; } -expression_ptr expression_format::get_expression(ptree const& xml, std::string name) +expression_ptr expression_format::get_expression(xml_node const& xml, std::string name) { - boost::optional tmp = get_opt_attr(xml, name); + boost::optional tmp = xml.get_opt_attr(name); if (tmp) return parse_expression(*tmp); return expression_ptr(); } diff --git a/src/formatting/format.cpp b/src/formatting/format.cpp index 860896dce..564902617 100644 --- a/src/formatting/format.cpp +++ b/src/formatting/format.cpp @@ -21,6 +21,7 @@ *****************************************************************************/ #include #include +#include namespace mapnik { using boost::property_tree::ptree; @@ -44,7 +45,7 @@ void format_node::to_xml(ptree &xml) const } -node_ptr format_node::from_xml(ptree const& xml) +node_ptr format_node::from_xml(xml_node const& xml) { format_node *n = new format_node(); node_ptr np(n); @@ -52,19 +53,19 @@ node_ptr format_node::from_xml(ptree const& xml) node_ptr child = node::from_xml(xml); n->set_child(child); - n->face_name = get_opt_attr(xml, "face-name"); + n->face_name = xml.get_opt_attr("face-name"); /*TODO: Fontset is problematic. We don't have the fontsets pointer here... */ - n->text_size = get_opt_attr(xml, "size"); - n->character_spacing = get_opt_attr(xml, "character-spacing"); - n->line_spacing = get_opt_attr(xml, "line-spacing"); - n->text_opacity = get_opt_attr(xml, "opactity"); - boost::optional wrap = get_opt_attr(xml, "wrap-before"); + n->text_size = xml.get_opt_attr("size"); + n->character_spacing = xml.get_opt_attr("character-spacing"); + n->line_spacing = xml.get_opt_attr("line-spacing"); + n->text_opacity = xml.get_opt_attr("opactity"); + boost::optional wrap = xml.get_opt_attr("wrap-before"); if (wrap) n->wrap_before = *wrap; - n->wrap_char = get_opt_attr(xml, "wrap-character"); - n->text_transform = get_opt_attr(xml, "text-transform"); - n->fill = get_opt_attr(xml, "fill"); - n->halo_fill = get_opt_attr(xml, "halo-fill"); - n->halo_radius = get_opt_attr(xml, "halo-radius"); + n->wrap_char = xml.get_opt_attr("wrap-character"); + n->text_transform = xml.get_opt_attr("text-transform"); + n->fill = xml.get_opt_attr("fill"); + n->halo_fill = xml.get_opt_attr("halo-fill"); + n->halo_radius = xml.get_opt_attr("halo-radius"); return np; } diff --git a/src/formatting/registry.cpp b/src/formatting/registry.cpp index 2c3a29a4a..8cfb0c6a4 100644 --- a/src/formatting/registry.cpp +++ b/src/formatting/registry.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace mapnik { @@ -46,10 +47,10 @@ 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::const_iterator itr = map_.find(name); - if (itr == map_.end()) throw config_error("Unknown element '" + name + "'"); + std::map::const_iterator itr = map_.find(xml.name()); + if (itr == map_.end()) throw config_error("Unknown element '" + xml.name() + "'"); return itr->second(xml); } } //ns formatting diff --git a/src/formatting/text.cpp b/src/formatting/text.cpp index bfe3e80b2..0be312501 100644 --- a/src/formatting/text.cpp +++ b/src/formatting/text.cpp @@ -26,9 +26,7 @@ #include #include #include - -// boost -#include +#include namespace mapnik { @@ -45,10 +43,9 @@ void text_node::to_xml(ptree &xml) const } -node_ptr text_node::from_xml(boost::property_tree::ptree const& xml) +node_ptr text_node::from_xml(xml_node const& xml) { - std::string data = xml.data(); - boost::trim(data); + std::string data = xml.get_text(); if (data.empty()) return node_ptr(); //No text return node_ptr(new text_node(parse_expression(data, "utf8"))); } diff --git a/src/text_placements/list.cpp b/src/text_placements/list.cpp index a9bc7aa83..d2ce9cad0 100644 --- a/src/text_placements/list.cpp +++ b/src/text_placements/list.cpp @@ -20,9 +20,14 @@ * *****************************************************************************/ +//mapnik #include +#include + +//boost #include + namespace mapnik { @@ -83,20 +88,19 @@ unsigned text_placements_list::size() const return list_.size(); } -text_placements_ptr text_placements_list::from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets) +text_placements_ptr text_placements_list::from_xml(xml_node const &xml, fontset_map const & fontsets) { using boost::property_tree::ptree; text_placements_list *list = new text_placements_list; text_placements_ptr ptr = text_placements_ptr(list); list->defaults.from_xml(xml, fontsets); - ptree::const_iterator itr = xml.begin(); - ptree::const_iterator end = xml.end(); + xml_node::const_iterator itr = xml.begin(); + xml_node::const_iterator end = xml.end(); for( ;itr != end; ++itr) { - if ((itr->first.find('<') != std::string::npos) || (itr->first != "Placement")) continue; -//TODO: ensure_attrs(symIter->second, "TextSymbolizer/Placement", s_common.str()); + if (itr->is_text() || itr->name() != "Placement") continue; text_symbolizer_properties &p = list->add(); - p.from_xml(itr->second, fontsets); + p.from_xml(*itr, fontsets); //TODO: if (strict_ && // !p.format.fontset.size()) // ensure_font_face(p.format.face_name); diff --git a/src/text_placements/registry.cpp b/src/text_placements/registry.cpp index 30668b78f..23950a751 100644 --- a/src/text_placements/registry.cpp +++ b/src/text_placements/registry.cpp @@ -44,7 +44,7 @@ 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::const_iterator itr = map_.find(name); if (itr == map_.end()) throw config_error("Unknown placement-type '" + name + "'"); diff --git a/src/text_placements/simple.cpp b/src/text_placements/simple.cpp index 598082e55..ebaba1fc8 100644 --- a/src/text_placements/simple.cpp +++ b/src/text_placements/simple.cpp @@ -23,6 +23,7 @@ // mapnik #include #include +#include // boost #include @@ -167,10 +168,10 @@ std::string text_placements_simple::get_positions() return positions_; //TODO: Build string from data in direction_ and text_sizes_ } -text_placements_ptr text_placements_simple::from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets) +text_placements_ptr text_placements_simple::from_xml(xml_node const &xml, fontset_map const & fontsets) { text_placements_ptr ptr = text_placements_ptr(boost::make_shared( - get_attr(xml, "placements", "X"))); + xml.get_attr("placements", "X"))); ptr->defaults.from_xml(xml, fontsets); return ptr; } diff --git a/src/text_properties.cpp b/src/text_properties.cpp index 864cdd4ec..09f3a85be 100644 --- a/src/text_properties.cpp +++ b/src/text_properties.cpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace mapnik { @@ -72,45 +73,45 @@ formatting::node_ptr text_symbolizer_properties::format_tree() const return tree_; } -void text_symbolizer_properties::from_xml(boost::property_tree::ptree const &sym, fontset_map const & fontsets) +void text_symbolizer_properties::from_xml(xml_node const &sym, fontset_map const & fontsets) { - optional placement_ = get_opt_attr(sym, "placement"); + optional placement_ = sym.get_opt_attr("placement"); if (placement_) label_placement = *placement_; - optional valign_ = get_opt_attr(sym, "vertical-alignment"); + optional valign_ = sym.get_opt_attr("vertical-alignment"); if (valign_) valign = *valign_; - optional text_ratio_ = get_opt_attr(sym, "text-ratio"); + optional text_ratio_ = sym.get_opt_attr("text-ratio"); if (text_ratio_) text_ratio = *text_ratio_; - optional wrap_width_ = get_opt_attr(sym, "wrap-width"); + optional wrap_width_ = sym.get_opt_attr("wrap-width"); if (wrap_width_) wrap_width = *wrap_width_; - optional label_position_tolerance_ = get_opt_attr(sym, "label-position-tolerance"); + optional label_position_tolerance_ = sym.get_opt_attr("label-position-tolerance"); if (label_position_tolerance_) label_position_tolerance = *label_position_tolerance_; - optional spacing_ = get_opt_attr(sym, "spacing"); + optional spacing_ = sym.get_opt_attr("spacing"); if (spacing_) label_spacing = *spacing_; - optional minimum_distance_ = get_opt_attr(sym, "minimum-distance"); + optional minimum_distance_ = sym.get_opt_attr("minimum-distance"); if (minimum_distance_) minimum_distance = *minimum_distance_; - optional min_padding_ = get_opt_attr(sym, "minimum-padding"); + optional min_padding_ = sym.get_opt_attr("minimum-padding"); if (min_padding_) minimum_padding = *min_padding_; - optional min_path_length_ = get_opt_attr(sym, "minimum-path-length"); + optional min_path_length_ = sym.get_opt_attr("minimum-path-length"); if (min_path_length_) minimum_path_length = *min_path_length_; - optional avoid_edges_ = get_opt_attr(sym, "avoid-edges"); + optional avoid_edges_ = sym.get_opt_attr("avoid-edges"); if (avoid_edges_) avoid_edges = *avoid_edges_; - optional allow_overlap_ = get_opt_attr(sym, "allow-overlap"); + optional allow_overlap_ = sym.get_opt_attr("allow-overlap"); if (allow_overlap_) allow_overlap = *allow_overlap_; - optional halign_ = get_opt_attr(sym, "horizontal-alignment"); + optional halign_ = sym.get_opt_attr("horizontal-alignment"); if (halign_) halign = *halign_; - optional jalign_ = get_opt_attr(sym, "justify-alignment"); + optional jalign_ = sym.get_opt_attr("justify-alignment"); if (jalign_) jalign = *jalign_; /* Attributes needing special care */ - optional orientation_ = get_opt_attr(sym, "orientation"); + optional orientation_ = sym.get_opt_attr("orientation"); if (orientation_) orientation = parse_expression(*orientation_, "utf8"); - optional dx = get_opt_attr(sym, "dx"); + optional dx = sym.get_opt_attr("dx"); if (dx) displacement.first = *dx; - optional dy = get_opt_attr(sym, "dy"); + optional dy = sym.get_opt_attr("dy"); if (dy) displacement.second = *dy; - optional max_char_angle_delta_ = get_opt_attr(sym, "max-char-angle-delta"); + optional max_char_angle_delta_ = sym.get_opt_attr("max-char-angle-delta"); if (max_char_angle_delta_) max_char_angle_delta=(*max_char_angle_delta_)*(M_PI/180); - optional name_ = get_opt_attr(sym, "name"); + optional name_ = sym.get_opt_attr("name"); if (name_) { std::clog << "### WARNING: Using 'name' in TextSymbolizer/ShieldSymbolizer is deprecated!\n"; set_old_style_expression(parse_expression(*name_, "utf8")); @@ -230,34 +231,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 text_size_ = get_opt_attr(sym, "size"); + optional text_size_ = sym.get_opt_attr("size"); if (text_size_) text_size = *text_size_; - optional character_spacing_ = get_opt_attr(sym, "character-spacing"); + optional character_spacing_ = sym.get_opt_attr("character-spacing"); if (character_spacing_) character_spacing = *character_spacing_; - optional fill_ = get_opt_attr(sym, "fill"); + optional fill_ = sym.get_opt_attr("fill"); if (fill_) fill = *fill_; - optional halo_fill_ = get_opt_attr(sym, "halo-fill"); + optional halo_fill_ = sym.get_opt_attr("halo-fill"); if (halo_fill_) halo_fill = *halo_fill_; - optional halo_radius_ = get_opt_attr(sym, "halo-radius"); + optional halo_radius_ = sym.get_opt_attr("halo-radius"); if (halo_radius_) halo_radius = *halo_radius_; - optional wrap_before_ = get_opt_attr(sym, "wrap-before"); + optional wrap_before_ = sym.get_opt_attr("wrap-before"); if (wrap_before_) wrap_before = *wrap_before_; - optional tconvert_ = get_opt_attr(sym, "text-transform"); + optional tconvert_ = sym.get_opt_attr("text-transform"); if (tconvert_) text_transform = *tconvert_; - optional line_spacing_ = get_opt_attr(sym, "line-spacing"); + optional line_spacing_ = sym.get_opt_attr("line-spacing"); if (line_spacing_) line_spacing = *line_spacing_; - optional opacity_ = get_opt_attr(sym, "opacity"); + optional opacity_ = sym.get_opt_attr("opacity"); if (opacity_) text_opacity = *opacity_; - optional wrap_char_ = get_opt_attr(sym, "wrap-character"); + optional wrap_char_ = sym.get_opt_attr("wrap-character"); if (wrap_char_ && (*wrap_char_).size() > 0) wrap_char = ((*wrap_char_)[0]); - optional face_name_ = get_opt_attr(sym, "face-name"); + optional face_name_ = sym.get_opt_attr("face-name"); if (face_name_) { face_name = *face_name_; } - optional fontset_name_ = get_opt_attr(sym, "fontset-name"); + optional fontset_name_ = sym.get_opt_attr("fontset-name"); if (fontset_name_) { std::map::const_iterator itr = fontsets.find(*fontset_name_); if (itr != fontsets.end()) diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 2b98e2dc0..5ed24c351 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -191,7 +191,7 @@ xml_node &xml_node::add_child(std::string const& name, unsigned line, bool text_ return children_.back(); } -xml_node & xml_node::get_child(std::string name) +xml_node & xml_node::get_child(std::string const& name) { std::list::iterator itr = children_.begin(); std::list::iterator end = children_.end(); From 9a05dc18280cd3e30ae55118b5e9afc155ceba97 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Wed, 7 Mar 2012 03:57:31 +0100 Subject: [PATCH 010/138] Add XML functions. --- include/mapnik/xml_tree.hpp | 34 +++++-- src/load_map.cpp | 2 +- src/xml_tree.cpp | 184 +++++++++++++++++++++++++++++++++++- 3 files changed, 207 insertions(+), 13 deletions(-) diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index 137fa83ab..534228e79 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -40,6 +40,7 @@ class color; class xml_attribute { public: + xml_attribute(std::string const& value); std::string value; mutable bool processed; }; @@ -47,16 +48,34 @@ public: class node_not_found: public std::exception { public: - node_not_found(std::string node_name) : node_name_(node_name) {} - virtual const char* what() const throw() - { - return ("Node "+node_name_+ "not found").c_str(); - } + 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: @@ -70,14 +89,15 @@ public: 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); - void set_processed(bool processed); + + void set_processed(bool processed) 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 *get_opt_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 diff --git a/src/load_map.cpp b/src/load_map.cpp index 1fbeff3d5..1d03075d4 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -708,7 +708,7 @@ void map_parser::parse_rule(feature_type_style & style, xml_node const& r) name = r.get_attr("name", std::string()); rule rule(name); - xml_node *child = r.get_opt_child("Filter"); + xml_node const* child = r.get_opt_child("Filter"); if (child) { rule.set_filter(child->get_value()); diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 5ed24c351..415107da8 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -25,6 +25,8 @@ #include #include #include +#include +#include //boost #include @@ -152,6 +154,68 @@ 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) @@ -169,7 +233,7 @@ std::string xml_node::name() const if (!text_node_) return name_; else - return ""; //TODO: throw + return ""; } std::string xml_node::text() const @@ -180,9 +244,19 @@ std::string xml_node::text() const return "NOT A TEXT NODE"; //TODO: throw } -void xml_node::set_processed(bool processed) +bool xml_node::is_text() const { - processed_ = processed; + 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) @@ -191,6 +265,26 @@ xml_node &xml_node::add_child(std::string const& name, unsigned line, bool text_ 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))); +} + +void xml_node::set_processed(bool processed) const +{ + processed_ = 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::iterator itr = children_.begin(); @@ -206,20 +300,100 @@ xml_node & xml_node::get_child(std::string const& name) 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 boost::optional xml_node::get_opt_attr(std::string const& name) const { std::map::const_iterator itr = attributes_.find(name); if (itr == attributes_.end()) return boost::optional(); - boost::optional result = fast_cast(itr->second); + itr->second.processed = true; + boost::optional result = fast_cast(tree_, itr->second.value); if (!result) { throw config_error(std::string("Failed to parse attribute '") + name + "'. Expected " + name_trait::name() + - " but got '" + itr->second + "'"); + " but got '" + itr->second.value + "'"); } return result; } +template +T xml_node::get_attr(std::string const& name, T const& default_value) const +{ + boost::optional value = get_opt_attr(name); + if (value) return *value; + return default_value; +} +template +T xml_node::get_attr(std::string const& name) const +{ + boost::optional value = get_opt_attr(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 +T xml_node::get_value() const +{ + boost::optional result = fast_cast(get_text()); + if (!result) + { + throw config_error(std::string("Failed to parse value in node '") + + name_ + "'. Expected " + name_trait::name() + + " but got '" + get_text() + "'"); + } + return result; +} + +#define compile_get_opt_attr(T) template boost::optional xml_node::get_opt_attr(std::string const&) 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); } //ns mapnik From daf30ca0d17d01c5ebc59415eb752ddb61ed3024 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Wed, 7 Mar 2012 15:26:13 +0100 Subject: [PATCH 011/138] Update metawriter_factory.hpp --- include/mapnik/metawriter_factory.hpp | 3 ++- src/load_map.cpp | 5 ++--- src/metawriter_factory.cpp | 22 ++++++++++++---------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/include/mapnik/metawriter_factory.hpp b/include/mapnik/metawriter_factory.hpp index d5b8911fd..1af7ff5d7 100644 --- a/include/mapnik/metawriter_factory.hpp +++ b/include/mapnik/metawriter_factory.hpp @@ -30,6 +30,7 @@ #include namespace mapnik { +class xml_node; /** * Creates a metawriter with the properties specified in the property @@ -37,7 +38,7 @@ namespace mapnik { * metawriters, but should provide an easy point to make them a * proper factory method if this is wanted in the future. */ -metawriter_ptr metawriter_create(const boost::property_tree::ptree &pt); +metawriter_ptr metawriter_create(xml_node const& pt); /** * Writes properties into the given property tree representing the diff --git a/src/load_map.cpp b/src/load_map.cpp index 1d03075d4..6120d22c7 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -35,7 +35,6 @@ #include #include -#include #ifdef HAVE_LIBXML2 #include #endif @@ -501,7 +500,7 @@ void map_parser::parse_metawriter(Map & map, xml_node const& pt) try { name = pt.get_attr("name"); - //TODO: writer = metawriter_create(pt); + writer = metawriter_create(pt); map.insert_metawriter(name, writer); } catch (const config_error & ex) { ex.append_context(std::string("in meta writer '") + name + "'"); @@ -620,7 +619,7 @@ void map_parser::parse_layer(Map & map, xml_node const& lay) if (child->is("StyleName")) { - std::string style_name = child->get_value(); //TODO: get_text + std::string style_name = child->get_text(); if (style_name.empty()) { std::ostringstream ss; diff --git a/src/metawriter_factory.cpp b/src/metawriter_factory.cpp index d79201838..2d05a70aa 100644 --- a/src/metawriter_factory.cpp +++ b/src/metawriter_factory.cpp @@ -22,14 +22,13 @@ //$Id$ #include -#include - #include #include +#include +#include #include -using boost::property_tree::ptree; using boost::optional; using std::string; @@ -37,20 +36,21 @@ namespace mapnik { metawriter_ptr -metawriter_create(const boost::property_tree::ptree &pt) { +metawriter_create(xml_node const& pt) +{ metawriter_ptr writer; - string type = get_attr(pt, "type"); + string type = pt.get_attr("type"); - optional properties = get_opt_attr(pt, "default-output"); + optional properties = pt.get_opt_attr("default-output"); if (type == "json") { - string file = get_attr(pt, "file"); + string file = pt.get_attr("file"); metawriter_json_ptr json = metawriter_json_ptr(new metawriter_json(properties, parse_path(file))); - optional output_empty = get_opt_attr(pt, "output-empty"); + optional output_empty = pt.get_opt_attr("output-empty"); if (output_empty) { json->set_output_empty(*output_empty); } - optional pixel_coordinates = get_opt_attr(pt, "pixel-coordinates"); + optional pixel_coordinates = pt.get_opt_attr("pixel-coordinates"); if (pixel_coordinates) { json->set_pixel_coordinates(*pixel_coordinates); } @@ -67,7 +67,9 @@ metawriter_create(const boost::property_tree::ptree &pt) { } 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.get()); if (json) { From adfa73f64ac14ad9a832fb6616acee53661df827 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 7 Mar 2012 08:54:04 -0800 Subject: [PATCH 012/138] avoid combining default arg with const& --- src/load_map.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/load_map.cpp b/src/load_map.cpp index eea4353a8..3cfd51fb0 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -94,7 +94,7 @@ public: expr_grammar_(tr_) {} - void parse_map(Map & map, ptree const & sty, std::string const& base_path=""); + void parse_map(Map & map, ptree const & sty, std::string const& base_path); private: void parse_map_include( Map & map, ptree const & include); void parse_style(Map & map, ptree const & sty); @@ -181,7 +181,8 @@ void load_map(Map & map, std::string const& filename, bool strict) } #endif map_parser parser( strict, filename); - parser.parse_map(map, pt); + std::string base_path(""); + parser.parse_map(map, pt, base_path); } void load_map_string(Map & map, std::string const& str, bool strict, std::string base_path) From c3cd50ff57b58d21b3c4a7dda6e123f4c6b89ef9 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Wed, 7 Mar 2012 19:16:41 +0100 Subject: [PATCH 013/138] Complete new XML structure. --- include/mapnik/boolean.hpp | 90 ++++ include/mapnik/color.hpp | 8 + include/mapnik/ptree_helpers.hpp | 425 ------------------ include/mapnik/xml_tree.hpp | 4 + plugins/input/csv/csv_datasource.cpp | 3 +- plugins/input/gdal/gdal_datasource.cpp | 2 +- plugins/input/geos/geos_datasource.cpp | 2 +- plugins/input/kismet/kismet_datasource.cpp | 2 +- plugins/input/occi/occi_datasource.cpp | 2 +- plugins/input/ogr/ogr_datasource.cpp | 2 +- plugins/input/postgis/postgis_datasource.cpp | 2 +- .../rasterlite/rasterlite_datasource.cpp | 2 +- plugins/input/sqlite/sqlite_datasource.cpp | 2 +- src/formatting/text.cpp | 2 +- src/xml_tree.cpp | 35 +- 15 files changed, 145 insertions(+), 438 deletions(-) create mode 100644 include/mapnik/boolean.hpp diff --git a/include/mapnik/boolean.hpp b/include/mapnik/boolean.hpp new file mode 100644 index 000000000..dc74d3d8b --- /dev/null +++ b/include/mapnik/boolean.hpp @@ -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 + +namespace mapnik +{ +/** Helper for class bool */ +class boolean { +public: + boolean() {} + 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 +std::basic_istream & +operator >> ( std::basic_istream & 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 +std::basic_ostream & +operator << ( std::basic_ostream & s, boolean const& b ) +{ + s << ( b ? "true" : "false" ); + return s; +} + +} + +#endif // MAPNIK_BOOLEAN_HPP diff --git a/include/mapnik/color.hpp b/include/mapnik/color.hpp index c7f2de610..ad9806276 100644 --- a/include/mapnik/color.hpp +++ b/include/mapnik/color.hpp @@ -137,6 +137,14 @@ public: std::string to_hex_string() const; }; +template +std::basic_ostream & +operator << ( std::basic_ostream & s, mapnik::color const& c ) +{ + std::string hex_string( c.to_string() ); + s << hex_string; + return s; +} } diff --git a/include/mapnik/ptree_helpers.hpp b/include/mapnik/ptree_helpers.hpp index 811317312..64167b590 100644 --- a/include/mapnik/ptree_helpers.hpp +++ b/include/mapnik/ptree_helpers.hpp @@ -23,442 +23,17 @@ #ifndef MAPNIK_PTREE_HELPERS_HPP #define MAPNIK_PTREE_HELPERS_HPP -// mapnik -#include -#include -#include -#include // boost #include -#include -#include - -// stl -#include -#include namespace mapnik { -template -inline boost::optional fast_cast(std::string const& value); - -template -T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute, - T const& default_value); -template -T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute); -template -T get_value(boost::property_tree::ptree const& node, std::string const& name); -template -boost::optional get_optional(boost::property_tree::ptree const& node, std::string const& name, - bool is_attribute); - -template -boost::optional get_opt_attr( boost::property_tree::ptree const& node, - std::string const& name) -{ - return get_optional( node, name, true); -} - -template -boost::optional get_opt_child( boost::property_tree::ptree const& node, - std::string const& name) -{ - return get_optional( node, name, false); -} - -template -T get_attr( boost::property_tree::ptree const& node, std::string const& name, - T const& default_value ) -{ - return get( node, name, true, default_value); -} - -template -T get_attr( boost::property_tree::ptree const& node, std::string const& name ) -{ - return get( node, name, true ); -} - - -template -std::basic_ostream & -operator << ( std::basic_ostream & 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() {} - 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 -std::basic_istream & -operator >> ( std::basic_istream & 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 -std::basic_ostream & -operator << ( std::basic_ostream & s, boolean const& b ) -{ - s << ( b ? "true" : "false" ); - return s; -} - template void set_attr(boost::property_tree::ptree & pt, std::string const& name, T const& v) { pt.put("." + name, v); } - -class boolean; - -template -struct name_trait -{ - static std::string name() - { - return ""; - } - // 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 \ - { \ - 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 -struct name_trait< mapnik::enumeration > -{ - typedef enumeration 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 -inline boost::optional fast_cast(std::string const& value) -{ - return boost::lexical_cast( value ); -} - -template <> -inline boost::optional fast_cast(std::string const& value) -{ - int result; - if (mapnik::conversions::string2int(value,result)) - return boost::optional(result); - return boost::optional(); -} - -template <> -inline boost::optional fast_cast(std::string const& value) -{ - double result; - if (mapnik::conversions::string2double(value,result)) - return boost::optional(result); - return boost::optional(); -} - -template <> -inline boost::optional fast_cast(std::string const& value) -{ - float result; - if (mapnik::conversions::string2float(value,result)) - return boost::optional(result); - return boost::optional(); -} - -template -T get(boost::property_tree::ptree const& node, - std::string const& name, - bool is_attribute, - T const& default_value) -{ - boost::optional str; - if (is_attribute) - { - str = node.get_optional( std::string(".") + name ); - } - else - { - str = node.get_optional(name + "."); - } - - if ( str ) - { - boost::optional result = fast_cast(*str); - if (result) - { - return *result; - } - else - { - throw config_error(std::string("Failed to parse ") + - (is_attribute ? "attribute" : "child node") + " '" + - name + "'. Expected " + name_trait::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 str; - if (is_attribute) - { - str = node.get_optional( std::string(".") + name ); - } - else - { - str = node.get_optional(name + "."); - } - - 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::name() + - " but got '" + *str + "'"); - } - } - else - { - return default_value; - } -} - -template -T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute) -{ - boost::optional str; - if (is_attribute) - { - str = node.get_optional( std::string(".") + name); - } - else - { - str = node.get_optional(name + "."); - } - - if ( ! str ) - { - throw config_error(std::string("Required ") + - (is_attribute ? "attribute " : "child node ") + - "'" + name + "' is missing"); - } - boost::optional result = fast_cast(*str); - if (result) - { - return *result; - } - else - { - throw config_error(std::string("Failed to parse ") + - (is_attribute ? "attribute" : "child node") + " '" + - name + "'. Expected " + name_trait::name() + - " but got '" + *str + "'"); - } -} - -template -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("").get_value(); - } - catch (boost::property_tree::ptree_bad_path) - { - /* If the XML parser did not find any non-empty data element the is no - 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::name() + - " but got '" + node.data() + "'"); - } -} - -template -boost::optional get_optional(boost::property_tree::ptree const& node, - std::string const& name, - bool is_attribute) -{ - boost::optional str; - if (is_attribute) - { - str = node.get_optional( std::string(".") + name); - } - else - { - str = node.get_optional(name + "."); - } - - boost::optional result; - if ( str ) - { - result = fast_cast(*str); - if (!result) - { - throw config_error(std::string("Failed to parse ") + - (is_attribute ? "attribute" : "child node") + " '" + - name + "'. Expected " + name_trait::name() + - " but got '" + *str + "'"); - } - } - - return result; -} - -template <> -inline boost::optional get_optional(boost::property_tree::ptree const& node, - std::string const& name, - bool is_attribute) -{ - if (is_attribute) - { - return node.get_optional( std::string(".") + name); - } - else - { - return node.get_optional(name + "."); - } -} - -template <> -inline boost::optional get_optional(boost::property_tree::ptree const& node, - std::string const& name, - bool is_attribute) -{ - boost::optional str; - if (is_attribute) - { - str = node.get_optional( std::string(".") + name); - } - else - { - str = node.get_optional(name + "."); - } - - boost::optional 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::name() + - " but got '" + *str + "'"); - } - } - - return result; -} - -static inline bool has_child(boost::property_tree::ptree const& node, std::string const& name) -{ - boost::optional str = node.get_optional(name); - return str; -} - } // end of namespace mapnik #endif // MAPNIK_PTREE_HELPERS_HPP diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index 534228e79..40406382c 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -23,6 +23,10 @@ #ifndef MAPNIK_XML_TREE_H #define MAPNIK_XML_TREE_H +//mapnik +#include + + //boost #include diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index b2848509f..8aa04b667 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -14,7 +14,8 @@ #include #include #include -#include // mapnik::boolean +#include +#include // stl #include diff --git a/plugins/input/gdal/gdal_datasource.cpp b/plugins/input/gdal/gdal_datasource.cpp index a19842413..1bdf85ce1 100644 --- a/plugins/input/gdal/gdal_datasource.cpp +++ b/plugins/input/gdal/gdal_datasource.cpp @@ -25,7 +25,7 @@ #include "gdal_featureset.hpp" // mapnik -#include +#include #include #include diff --git a/plugins/input/geos/geos_datasource.cpp b/plugins/input/geos/geos_datasource.cpp index 9fcc8c4ab..ddf649ede 100644 --- a/plugins/input/geos/geos_datasource.cpp +++ b/plugins/input/geos/geos_datasource.cpp @@ -30,7 +30,7 @@ #include // mapnik -#include +#include #include // boost diff --git a/plugins/input/kismet/kismet_datasource.cpp b/plugins/input/kismet/kismet_datasource.cpp index 7780b078d..00f604789 100644 --- a/plugins/input/kismet/kismet_datasource.cpp +++ b/plugins/input/kismet/kismet_datasource.cpp @@ -33,7 +33,7 @@ #include // mapnik -#include +#include // boost #include diff --git a/plugins/input/occi/occi_datasource.cpp b/plugins/input/occi/occi_datasource.cpp index b99698d22..e4d3fa4a3 100644 --- a/plugins/input/occi/occi_datasource.cpp +++ b/plugins/input/occi/occi_datasource.cpp @@ -25,7 +25,7 @@ #include "occi_featureset.hpp" // mapnik -#include +#include #include // boost diff --git a/plugins/input/ogr/ogr_datasource.cpp b/plugins/input/ogr/ogr_datasource.cpp index 0e6035a3c..da404cbb9 100644 --- a/plugins/input/ogr/ogr_datasource.cpp +++ b/plugins/input/ogr/ogr_datasource.cpp @@ -33,7 +33,7 @@ #include // mapnik -#include +#include #include // boost diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp index 0c5f083e8..26c2b9074 100644 --- a/plugins/input/postgis/postgis_datasource.cpp +++ b/plugins/input/postgis/postgis_datasource.cpp @@ -26,7 +26,7 @@ // mapnik #include -#include +#include #include #include diff --git a/plugins/input/rasterlite/rasterlite_datasource.cpp b/plugins/input/rasterlite/rasterlite_datasource.cpp index e9cd0bf69..ac609f357 100644 --- a/plugins/input/rasterlite/rasterlite_datasource.cpp +++ b/plugins/input/rasterlite/rasterlite_datasource.cpp @@ -29,7 +29,7 @@ #include // mapnik -#include +#include #include using mapnik::datasource; diff --git a/plugins/input/sqlite/sqlite_datasource.cpp b/plugins/input/sqlite/sqlite_datasource.cpp index 02e184d3a..77015ef82 100644 --- a/plugins/input/sqlite/sqlite_datasource.cpp +++ b/plugins/input/sqlite/sqlite_datasource.cpp @@ -26,7 +26,7 @@ #include "sqlite_utils.hpp" // mapnik -#include +#include #include #include #include diff --git a/src/formatting/text.cpp b/src/formatting/text.cpp index 0be312501..a65285200 100644 --- a/src/formatting/text.cpp +++ b/src/formatting/text.cpp @@ -45,7 +45,7 @@ void text_node::to_xml(ptree &xml) const node_ptr text_node::from_xml(xml_node const& xml) { - std::string data = xml.get_text(); + std::string data = xml.text(); if (data.empty()) return node_ptr(); //No text return node_ptr(new text_node(parse_expression(data, "utf8"))); } diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 415107da8..2ba5ff709 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include //boost #include @@ -79,6 +81,11 @@ inline boost::optional fast_cast(xml_tree const& tree, std::string const& return mapnik::color_factory::from_string(value); } +template <> +inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) +{ + return parse_expression(value); +} /****************************************************************************/ @@ -112,6 +119,7 @@ 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 struct name_trait< mapnik::enumeration > @@ -376,19 +384,21 @@ std::string xml_node::get_text() const template T xml_node::get_value() const { - boost::optional result = fast_cast(get_text()); + boost::optional result = fast_cast(tree_, get_text()); if (!result) { throw config_error(std::string("Failed to parse value in node '") + name_ + "'. Expected " + name_trait::name() + " but got '" + get_text() + "'"); } - return result; + return *result; } #define compile_get_opt_attr(T) template boost::optional xml_node::get_opt_attr(std::string const&) const +#define compile_get_attr(T) template T xml_node::get_attr(std::string const&) const; template T xml_node::get_attr(std::string const&, T const&) const +#define compile_get_value(T) template T xml_node::get_value() const -//compile_get_opt_attr(boolean); +compile_get_opt_attr(boolean); compile_get_opt_attr(std::string); compile_get_opt_attr(unsigned); compile_get_opt_attr(float); @@ -396,4 +406,23 @@ 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_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 From c47dae692aa7f0e3a6dbff7c3eeeedaab32dde27 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 7 Mar 2012 15:34:59 -0800 Subject: [PATCH 014/138] add no-omit-frame-pointer to debug flags to ensure without question it is not enabled --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 28d3cb94f..b860bb58e 100644 --- a/SConstruct +++ b/SConstruct @@ -1411,7 +1411,7 @@ if not preconfigured: pthread = '-pthread' # Common debugging flags. - debug_flags = '-g -DDEBUG -DMAPNIK_DEBUG' + debug_flags = '-g -fno-omit-frame-pointer -DDEBUG -DMAPNIK_DEBUG' ndebug_flags = '-DNDEBUG' From 2a7709a0cf4bada065ca1dd76ef1ec16ce3119d0 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Thu, 8 Mar 2012 01:29:19 +0100 Subject: [PATCH 015/138] Dump xml tree. --- include/mapnik/internal/dump_xml.hpp | 24 ++++++++++++++++-------- include/mapnik/xml_tree.hpp | 4 +++- src/load_map.cpp | 3 ++- src/xml_tree.cpp | 5 +++++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/include/mapnik/internal/dump_xml.hpp b/include/mapnik/internal/dump_xml.hpp index 022591f7a..944be73ba 100644 --- a/include/mapnik/internal/dump_xml.hpp +++ b/include/mapnik/internal/dump_xml.hpp @@ -1,10 +1,10 @@ #ifndef DUMP_XML_HPP #define DUMP_XML_HPP -#include +#include /* Debug dump ptree XML representation. */ -void dump_xml(boost::property_tree::ptree const& xml, unsigned level=0) +void dump_xml(xml_node const& xml, unsigned level=0) { std::string indent; int i; @@ -12,15 +12,23 @@ void dump_xml(boost::property_tree::ptree const& xml, unsigned level=0) { indent += " "; } - if (xml.data().length()) std::cout << indent << "data: '" << xml.data() << "'\n"; - boost::property_tree::ptree::const_iterator itr = xml.begin(); - boost::property_tree::ptree::const_iterator end = xml.end(); + xml_node::attribute_map const& attr = xml.get_attributes(); + std::cout << indent <<"[" << xml.name(); + xml_node::attribute_map::const_iterator aitr = attr.begin(); + xml_node::attribute_map::const_iterator aend = attr.end(); + for (;aitr!=aend; aitr++) + { + std::cout << " (" << aitr->first << ", " << aitr->second.value << ", " << aitr->second.processed << ")"; + } + std::cout << "]" << "\n"; + if (xml.is_text()) std::cout << indent << "text: '" << xml.text() << "'\n"; + xml_node::const_iterator itr = xml.begin(); + xml_node::const_iterator end = xml.end(); for (; itr!=end; itr++) { - std::cout << indent <<"[" << itr->first << "]" << "\n"; - dump_xml(itr->second, level+1); - std::cout << indent << "[/" << itr->first << "]" << "\n"; + dump_xml(*itr, level+1); } + std::cout << indent << "[/" << xml.name() << "]" << "\n"; } diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index 40406382c..b1b750b97 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -84,6 +84,7 @@ class xml_node { public: typedef std::list::const_iterator const_iterator; + typedef std::map attribute_map; xml_node(xml_tree &tree, std::string name, unsigned line=0, bool text_node = false); std::string name() const; @@ -93,6 +94,7 @@ public: 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; void set_processed(bool processed) const; @@ -120,7 +122,7 @@ private: xml_tree &tree_; std::string name_; std::list children_; - std::map attributes_; + attribute_map attributes_; bool text_node_; unsigned line_; mutable bool processed_; diff --git a/src/load_map.cpp b/src/load_map.cpp index 6120d22c7..6c6edc281 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -141,7 +141,7 @@ private: }; - +#include void load_map(Map & map, std::string const& filename, bool strict) { xml_tree tree; @@ -161,6 +161,7 @@ void load_map(Map & map, std::string const& filename, bool strict) #endif map_parser parser(strict, filename); parser.parse_map(map, tree.root()); + dump_xml(tree.root()); } void load_map_string(Map & map, std::string const& str, bool strict, std::string const& base_path) diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 2ba5ff709..a7714e057 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -278,6 +278,11 @@ 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; From adc8f9df1b9a566ff06eac04934e5b20d31d01fa Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Thu, 8 Mar 2012 13:00:08 +0100 Subject: [PATCH 016/138] Fix PointSymbolizer problem. --- src/load_map.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/load_map.cpp b/src/load_map.cpp index 6c6edc281..131a4d6c0 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -866,9 +866,6 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym) tr.store_to(&matrix[0]); symbol.set_transform(matrix); } - - parse_metawriter_in_symbolizer(symbol, sym); - rule.append(symbol); } catch (image_reader_exception const & ex ) { From f1aee039124ce301789d588a1448f45a66b49da1 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 8 Mar 2012 08:37:58 -0800 Subject: [PATCH 017/138] forward declare marker so marker_cache api access is cleaner --- include/mapnik/agg_renderer.hpp | 4 ---- include/mapnik/marker_cache.hpp | 9 +-------- src/agg/agg_renderer.cpp | 3 ++- src/agg/process_line_pattern_symbolizer.cpp | 1 + src/agg/process_markers_symbolizer.cpp | 1 + src/agg/process_point_symbolizer.cpp | 1 + src/agg/process_polygon_pattern_symbolizer.cpp | 1 + src/cairo_renderer.cpp | 3 ++- src/grid/grid_renderer.cpp | 3 ++- src/grid/process_markers_symbolizer.cpp | 1 + src/grid/process_point_symbolizer.cpp | 2 +- src/image_util.cpp | 1 - src/marker_cache.cpp | 13 ++++++++----- 13 files changed, 21 insertions(+), 22 deletions(-) diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index 4522e3aeb..11550fc88 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.hpp @@ -29,10 +29,6 @@ #include #include #include -//#include - -// agg -//#include "agg_trans_affine.h" // boost #include diff --git a/include/mapnik/marker_cache.hpp b/include/mapnik/marker_cache.hpp index 5b56770b0..8f5fb8a0d 100644 --- a/include/mapnik/marker_cache.hpp +++ b/include/mapnik/marker_cache.hpp @@ -25,14 +25,7 @@ // mapnik #include -#include #include -#include -#include -#include - -// agg -#include "agg_path_storage.h" // boost #include @@ -43,7 +36,7 @@ namespace mapnik { -using namespace mapnik::svg; +class marker; typedef boost::shared_ptr marker_ptr; diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index ac618ee56..079274cd3 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -24,6 +24,7 @@ // mapnik #include #include +#include #include #include #include @@ -246,7 +247,7 @@ void agg_renderer::render_marker(pixel_position const& pos, marker const& mar mtx *= agg::trans_affine_scaling(scale_factor_); // render the marker at the center of the marker box mtx.translate(pos.x+0.5 * marker.width(), pos.y+0.5 * marker.height()); - + using namespace mapnik::svg; vertex_stl_adapter stl_storage((*marker.get_vector_data())->source()); svg_path_adapter svg_path(stl_storage); svg_renderer #include #include +#include #include #include diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index c1e75c3f5..6248f004f 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/src/agg/process_point_symbolizer.cpp b/src/agg/process_point_symbolizer.cpp index 967ebd082..d29f6d15c 100644 --- a/src/agg/process_point_symbolizer.cpp +++ b/src/agg/process_point_symbolizer.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp index 5867b3fae..0f14c4dd0 100644 --- a/src/agg/process_polygon_pattern_symbolizer.cpp +++ b/src/agg/process_polygon_pattern_symbolizer.cpp @@ -24,6 +24,7 @@ // mapnik #include #include +#include #include #include diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index 85cc7592d..d0564d587 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -903,7 +904,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) typedef coord_transform2 path_type; mapnik::path_ptr vmarker = *marker.get_vector_data(); - + using namespace mapnik::svg; agg::pod_bvector const & attributes_ = vmarker->attributes(); for(unsigned i = 0; i < attributes_.size(); ++i) { diff --git a/src/grid/grid_renderer.cpp b/src/grid/grid_renderer.cpp index 754356a46..1552a6fd1 100644 --- a/src/grid/grid_renderer.cpp +++ b/src/grid/grid_renderer.cpp @@ -29,6 +29,7 @@ #include +#include #include #include #include @@ -144,7 +145,7 @@ void grid_renderer::render_marker(mapnik::feature_ptr const& feature, unsigne mtx *= agg::trans_affine_scaling(scale_factor_*(1.0/step)); // render the marker at the center of the marker box mtx.translate(pos.x+0.5 * marker.width(), pos.y+0.5 * marker.height()); - + using namespace mapnik::svg; vertex_stl_adapter stl_storage((*marker.get_vector_data())->source()); svg_path_adapter svg_path(stl_storage); svg_renderer #include #include +#include #include #include diff --git a/src/grid/process_point_symbolizer.cpp b/src/grid/process_point_symbolizer.cpp index 2db4dd5c2..2c3e2b634 100644 --- a/src/grid/process_point_symbolizer.cpp +++ b/src/grid/process_point_symbolizer.cpp @@ -29,7 +29,7 @@ #include #include #include - +#include #include // stl diff --git a/src/image_util.cpp b/src/image_util.cpp index c3cee7610..5b3b46454 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -57,7 +57,6 @@ extern "C" #include // agg -//#include "agg_conv_transform.h" #include "agg_image_accessors.h" #include "agg_pixfmt_rgba.h" #include "agg_rasterizer_scanline_aa.h" diff --git a/src/marker_cache.cpp b/src/marker_cache.cpp index f5139699a..41117bba6 100644 --- a/src/marker_cache.cpp +++ b/src/marker_cache.cpp @@ -23,11 +23,13 @@ //$Id$ // mapnik +#include #include #include #include -#include #include +#include +#include #include #include @@ -35,6 +37,7 @@ #include #include #include +#include namespace mapnik { @@ -72,7 +75,7 @@ boost::optional marker_cache::find(std::string const& uri, bool upda using namespace mapnik::svg; try { - path_ptr marker_path(new svg_storage_type); + path_ptr marker_path(boost::make_shared()); vertex_stl_adapter stl_storage(marker_path->source()); svg_path_adapter svg_path(stl_storage); svg_converter_type svg(svg_path, marker_path->attributes()); @@ -84,7 +87,7 @@ boost::optional marker_cache::find(std::string const& uri, bool upda svg.bounding_rect(&lox, &loy, &hix, &hiy); marker_path->set_bounding_box(lox,loy,hix,hiy); - marker_ptr mark(new marker(marker_path)); + marker_ptr mark(boost::make_shared(marker_path)); result.reset(mark); if (update_cache) { @@ -107,9 +110,9 @@ boost::optional marker_cache::find(std::string const& uri, bool upda unsigned width = reader->width(); unsigned height = reader->height(); BOOST_ASSERT(width > 0 && height > 0); - mapnik::image_ptr image(new mapnik::image_data_32(width,height)); + mapnik::image_ptr image(boost::make_shared(width,height)); reader->read(0,0,*image); - marker_ptr mark(new marker(image)); + marker_ptr mark(boost::make_shared(image)); result.reset(mark); if (update_cache) { From 3add1f984c9646bf08e42cb0e20323ac9b1a5994 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 8 Mar 2012 08:40:12 -0800 Subject: [PATCH 018/138] add Geos plugin to exported module scope --- bindings/python/mapnik/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py index 9fa035211..7d7a93d2c 100644 --- a/bindings/python/mapnik/__init__.py +++ b/bindings/python/mapnik/__init__.py @@ -682,6 +682,7 @@ __all__ = [ 'SQLite', 'Osm', 'Kismet', + 'Geos', # version and environment 'mapnik_version_string', 'mapnik_version', From 8b0b9ed5fe1f4f5fed31226563a2b15553f728c6 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Thu, 8 Mar 2012 18:29:46 +0100 Subject: [PATCH 019/138] Handle different image sizes correctly. --- tests/visual_tests/compare.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/visual_tests/compare.py b/tests/visual_tests/compare.py index 21a627d99..414f49979 100644 --- a/tests/visual_tests/compare.py +++ b/tests/visual_tests/compare.py @@ -1,4 +1,4 @@ -import math, operator +#import math, operator import Image import sys @@ -27,6 +27,10 @@ def compare(fn1, fn2): return -1 diff = 0 pixels = im1.size[0] * im1.size[1] + delta_pixels = im2.size[0] * im2.size[1] - pixels + if delta_pixels != 0: + errors.append((fn1, delta_pixels)) + return delta_pixels im1 = im1.getdata() im2 = im2.getdata() for i in range(3, pixels - 1, 3): From cd8cfc65273f4622f9150e4ced8bd0a61eae2946 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Thu, 8 Mar 2012 18:51:23 +0100 Subject: [PATCH 020/138] Improve error messages. --- include/mapnik/config_error.hpp | 20 +++++------ include/mapnik/raster_colorizer.hpp | 1 - include/mapnik/value.hpp | 1 - include/mapnik/xml_tree.hpp | 3 ++ src/agg/agg_renderer.cpp | 1 - src/build.py | 1 + src/cairo_renderer.cpp | 1 - src/config_error.cpp | 44 +++++++++++++++++++++++ src/formatting/registry.cpp | 3 +- src/grid/grid_renderer.cpp | 1 - src/libxml2_loader.cpp | 15 ++------ src/load_map.cpp | 14 ++++---- src/metawriter_factory.cpp | 3 +- src/processed_text.cpp | 26 +++++++++++++- src/text_placements/registry.cpp | 3 +- src/text_properties.cpp | 7 ++-- src/xml_tree.cpp | 10 ++++++ tests/visual_tests/shieldsymbolizer-1.xml | 5 ++- 18 files changed, 115 insertions(+), 44 deletions(-) create mode 100644 src/config_error.cpp diff --git a/include/mapnik/config_error.hpp b/include/mapnik/config_error.hpp index b25ae07f1..00ec3be8a 100644 --- a/include/mapnik/config_error.hpp +++ b/include/mapnik/config_error.hpp @@ -28,29 +28,25 @@ namespace mapnik { +class xml_node; class config_error : public std::exception { public: config_error() {} - config_error( const std::string & what ) : - what_( what ) - { - } + config_error(std::string const& what, xml_node const* node = 0, std::string const& filename=""); + config_error(unsigned line_number, std::string const& filename, std::string const& what); virtual ~config_error() throw() {} - virtual const char * what() const throw() - { - return what_.c_str(); - } + virtual const char * what() const throw(); - void append_context(const std::string & ctx) const - { - what_ += " " + ctx; - } + void append_context(const std::string & ctx, xml_node const* node = 0, std::string const& filename="") const; protected: mutable std::string what_; + mutable unsigned line_number_; + mutable std::string file_; + mutable std::string node_name_; }; } diff --git a/include/mapnik/raster_colorizer.hpp b/include/mapnik/raster_colorizer.hpp index 74fcf4853..8903d60f2 100644 --- a/include/mapnik/raster_colorizer.hpp +++ b/include/mapnik/raster_colorizer.hpp @@ -39,7 +39,6 @@ // mapnik #include -#include #include #include #include diff --git a/include/mapnik/value.hpp b/include/mapnik/value.hpp index d657d974c..a3cef23b4 100644 --- a/include/mapnik/value.hpp +++ b/include/mapnik/value.hpp @@ -26,7 +26,6 @@ // mapnik #include #include -#include // boost #include diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index b1b750b97..bb01c24da 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -96,8 +96,11 @@ public: 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; diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index ac618ee56..f355b3c84 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/src/build.py b/src/build.py index b19789d3e..9034a6de2 100644 --- a/src/build.py +++ b/src/build.py @@ -179,6 +179,7 @@ source = Split( text_placements/simple.cpp text_properties.cpp xml_tree.cpp + config_error.cpp """ ) diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index 85cc7592d..19909bf34 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/src/config_error.cpp b/src/config_error.cpp new file mode 100644 index 000000000..6837f3cbd --- /dev/null +++ b/src/config_error.cpp @@ -0,0 +1,44 @@ +#include +#include + +namespace mapnik +{ +config_error::config_error(std::string const& what, xml_node const* node, std::string const& filename) + : what_( what ), file_(filename) +{ + if (node) + { + node_name_ = node->name(); + line_number_ = node->line(); + } +} + + +config_error::config_error(unsigned line_number, std::string const& filename, std::string const& what) + : what_( what ), line_number_(line_number), file_(filename) +{ + +} + + 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_; + return s.str().c_str(); +} + +void config_error::append_context(const std::string & ctx, xml_node const* node, std::string const& filename) const +{ + what_ += " " + ctx; + if (node) + { + if (!line_number_) line_number_ = node->line(); + if (node_name_.empty()) node_name_ = node->name(); + if (file_.empty()) file_ = filename; + } +} +} diff --git a/src/formatting/registry.cpp b/src/formatting/registry.cpp index 8cfb0c6a4..00b031317 100644 --- a/src/formatting/registry.cpp +++ b/src/formatting/registry.cpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace mapnik { @@ -50,7 +51,7 @@ void registry::register_name(std::string name, from_xml_function_ptr ptr, bool o node_ptr registry::from_xml(xml_node const& xml) { std::map::const_iterator itr = map_.find(xml.name()); - if (itr == map_.end()) throw config_error("Unknown element '" + xml.name() + "'"); + if (itr == map_.end()) throw config_error("Unknown element '" + xml.name() + "'", &xml); return itr->second(xml); } } //ns formatting diff --git a/src/grid/grid_renderer.cpp b/src/grid/grid_renderer.cpp index 754356a46..9cd39dd50 100644 --- a/src/grid/grid_renderer.cpp +++ b/src/grid/grid_renderer.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #include #include diff --git a/src/libxml2_loader.cpp b/src/libxml2_loader.cpp index f67f0e0db..ac5ac6499 100644 --- a/src/libxml2_loader.cpp +++ b/src/libxml2_loader.cpp @@ -77,8 +77,7 @@ public: boost::filesystem::path path(filename); 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_); @@ -93,15 +92,7 @@ public: os << ": " << std::endl << error->message; // remove CR std::string msg = os.str().substr(0, os.str().size() - 1); - config_error ex(msg); - - os.str(""); - os << "(encountered in file '" << error->file << "' at line " - << error->line << ")"; - - ex.append_context(os.str()); - - throw ex; + throw config_error(error->line, error->file, msg); } } @@ -148,7 +139,7 @@ public: { os << ": " << std::endl << error->message; } - throw config_error(os.str()); + throw config_error(error->line, error->file, os.str()); } int iXIncludeReturn = xmlXIncludeProcessFlags(doc, options_); diff --git a/src/load_map.cpp b/src/load_map.cpp index 131a4d6c0..731ee6bde 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -195,7 +195,7 @@ expression_ptr map_parser::parse_expr(std::string const& str) expression_ptr expr(boost::make_shared(true)); if (!expression_factory::parse_from_string(expr,str,expr_grammar_)) { - throw mapnik::config_error( "Failed to parse expression: '" + str + "'" ); + throw mapnik::config_error( "Failed to parse expression '" + str + "'" ); } return expr; @@ -354,7 +354,7 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas } catch (const config_error & ex) { - ex.append_context("(in node Map)"); + ex.append_context("", &map_node, filename_); throw; } @@ -458,7 +458,7 @@ void map_parser::parse_map_include(Map & map, xml_node const& include) } } } catch (const config_error & ex) { - ex.append_context(std::string("in map '") + filename_ + "'"); + ex.append_context("", &include, filename_); throw; } @@ -489,7 +489,7 @@ void map_parser::parse_style(Map & map, xml_node const& sty) map.insert_style(name, style); } catch (const config_error & ex) { - ex.append_context(std::string("in style '") + name + "'"); + ex.append_context(std::string("in style '") + name + "'", &sty, filename_); throw; } } @@ -504,7 +504,7 @@ void map_parser::parse_metawriter(Map & map, xml_node const& pt) writer = metawriter_create(pt); map.insert_metawriter(name, writer); } catch (const config_error & ex) { - ex.append_context(std::string("in meta writer '") + name + "'"); + ex.append_context(std::string("in meta writer '") + name + "'", &pt, filename_); } } @@ -533,7 +533,7 @@ void map_parser::parse_fontset(Map & map, xml_node const& fset) // when it's parsed fontsets_.insert(pair(name, fontset)); } catch (const config_error & ex) { - ex.append_context(std::string("in FontSet '") + name + "'"); + ex.append_context(std::string("in FontSet '") + name + "'", &fset, filename_); throw; } } @@ -551,7 +551,7 @@ void map_parser::parse_font(font_set &fset, xml_node const& f) } else { - throw config_error(std::string("Must have 'face-name' set")); + throw config_error("Must have 'face-name' set", &f, filename_); } } diff --git a/src/metawriter_factory.cpp b/src/metawriter_factory.cpp index 2d05a70aa..e0b5b721b 100644 --- a/src/metawriter_factory.cpp +++ b/src/metawriter_factory.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -60,7 +61,7 @@ metawriter_create(xml_node const& pt) metawriter_inmem_ptr inmem = metawriter_inmem_ptr(new metawriter_inmem(properties)); writer = inmem; } else { - throw config_error(string("Unknown type '") + type + "'"); + throw config_error(string("Unknown type '") + type + "'", &pt); } return writer; diff --git a/src/processed_text.cpp b/src/processed_text.cpp index 3a6949487..921e528c6 100644 --- a/src/processed_text.cpp +++ b/src/processed_text.cpp @@ -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 +#include + namespace mapnik { @@ -43,7 +67,7 @@ string_info &processed_text::get_string_info() { if (!p.fontset.get_name().empty()) { - throw config_error("Unable to find specified font set '" + p.face_name + "'"); + throw config_error("Unable to find specified font set '" + p.fontset.get_name() + "'"); } else if (!p.face_name.empty()) { throw config_error("Unable to find specified font face '" + p.face_name + "'"); } else { diff --git a/src/text_placements/registry.cpp b/src/text_placements/registry.cpp index 23950a751..af6751665 100644 --- a/src/text_placements/registry.cpp +++ b/src/text_placements/registry.cpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace mapnik { @@ -47,7 +48,7 @@ void registry::register_name(std::string name, from_xml_function_ptr ptr, bool o text_placements_ptr registry::from_xml(std::string name, xml_node const& xml, fontset_map const& fontsets) { std::map::const_iterator itr = map_.find(name); - if (itr == map_.end()) throw config_error("Unknown placement-type '" + name + "'"); + if (itr == map_.end()) throw config_error("Unknown placement-type '" + name + "'", &xml); return itr->second(xml, fontsets); } } //ns formatting diff --git a/src/text_properties.cpp b/src/text_properties.cpp index 09f3a85be..0eb106ec0 100644 --- a/src/text_properties.cpp +++ b/src/text_properties.cpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace mapnik { @@ -266,16 +267,16 @@ void char_properties::from_xml(xml_node const& sym, fontset_map const& fontsets) fontset = itr->second; } else { - throw config_error("Unable to find any fontset named '" + *fontset_name_ + "'"); + throw config_error("Unable to find any fontset named '" + *fontset_name_ + "'", &sym); } } if (!face_name.empty() && !fontset.get_name().empty()) { - throw config_error(std::string("Can't have both face-name and fontset-name")); + throw config_error("Can't have both face-name and fontset-name", &sym); } if (face_name.empty() && fontset.get_name().empty()) { - throw config_error(std::string("Must have face-name or fontset-name")); + throw config_error("Must have face-name or fontset-name", &sym); } } diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index a7714e057..ce61a8e12 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -288,6 +288,11 @@ 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(); @@ -399,6 +404,11 @@ T xml_node::get_value() const return *result; } +unsigned xml_node::line() const +{ + return line_; +} + #define compile_get_opt_attr(T) template boost::optional xml_node::get_opt_attr(std::string const&) const #define compile_get_attr(T) template T xml_node::get_attr(std::string const&) const; template T xml_node::get_attr(std::string const&, T const&) const #define compile_get_value(T) template T xml_node::get_value() const diff --git a/tests/visual_tests/shieldsymbolizer-1.xml b/tests/visual_tests/shieldsymbolizer-1.xml index 6f780d888..010d93171 100644 --- a/tests/visual_tests/shieldsymbolizer-1.xml +++ b/tests/visual_tests/shieldsymbolizer-1.xml @@ -1,6 +1,6 @@ - + My Style @@ -9,6 +9,9 @@ points.shp + From 2f10469c8d68ffb8a2c16634d0c7ef14136e83f1 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 13 Mar 2012 07:54:32 -0700 Subject: [PATCH 059/138] apply mapnik_format.el formatting --- include/mapnik/agg_renderer.hpp | 2 +- include/mapnik/color_factory.hpp | 2 +- include/mapnik/expression_grammar.hpp | 4 ++-- include/mapnik/feature.hpp | 24 ++++++++++----------- include/mapnik/font_engine_freetype.hpp | 2 +- include/mapnik/formatting/registry.hpp | 2 +- include/mapnik/geometry.hpp | 2 +- include/mapnik/hextree.hpp | 4 ++-- include/mapnik/internal/dump_xml.hpp | 2 +- include/mapnik/placement_finder.hpp | 12 +++++------ include/mapnik/text_placements/registry.hpp | 2 +- include/mapnik/util/conversions.hpp | 18 ++++++++-------- include/mapnik/vertex_vector.hpp | 8 +++---- 13 files changed, 42 insertions(+), 42 deletions(-) diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index 592105ef1..d7e09049a 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.hpp @@ -66,7 +66,7 @@ public: void start_layer_processing(layer const& lay, box2d const& query_extent); void end_layer_processing(layer const& lay); void render_marker(pixel_position const& pos, marker const& marker, agg::trans_affine const& tr, double opacity); - + void process(point_symbolizer const& sym, mapnik::feature_ptr const& feature, proj_transform const& prj_trans); diff --git a/include/mapnik/color_factory.hpp b/include/mapnik/color_factory.hpp index 93f368a48..418c244a0 100644 --- a/include/mapnik/color_factory.hpp +++ b/include/mapnik/color_factory.hpp @@ -41,7 +41,7 @@ public: static void init_from_string(color & c, std::string const& css_color); static bool parse_from_string(color & c, std::string const& css_color, - mapnik::css_color_grammar const& g); + mapnik::css_color_grammar const& g); static color from_string(std::string const& css_color); }; diff --git a/include/mapnik/expression_grammar.hpp b/include/mapnik/expression_grammar.hpp index b5d478c5e..702e18a9b 100644 --- a/include/mapnik/expression_grammar.hpp +++ b/include/mapnik/expression_grammar.hpp @@ -229,7 +229,7 @@ struct expression_grammar : qi::grammar ("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\') ("\\\'", '\'')("\\\"", '\"') ; - + #if BOOST_VERSION > 104500 quote_char %= char_('\'') | char_('"'); ustring %= omit[quote_char[_a = _1]] @@ -237,7 +237,7 @@ struct expression_grammar : qi::grammar >> lit(_a); attr %= '[' >> no_skip[+~char_(']')] >> ']'; #else - ustring %= lit('\'') + ustring %= lit('\'') >> *(unesc_char | "\\x" >> hex | (char_ - lit('\''))) >> lit('\''); attr %= '[' >> lexeme[+(char_ - ']')] >> ']'; diff --git a/include/mapnik/feature.hpp b/include/mapnik/feature.hpp index 9b636824d..8a8d75bd5 100644 --- a/include/mapnik/feature.hpp +++ b/include/mapnik/feature.hpp @@ -99,11 +99,11 @@ public: feature_impl(context_ptr const& ctx, int id) : id_(id), - ctx_(ctx), - data_(ctx_->mapping_.size()), - geom_cont_(), - raster_() - {} + ctx_(ctx), + data_(ctx_->mapping_.size()), + geom_cont_(), + raster_() + {} inline int id() const { return id_;} @@ -163,25 +163,25 @@ public: { context_type::map_type::const_iterator itr = ctx_->mapping_.find(key); if (itr != ctx_->mapping_.end()) - return get(itr->second); - else - throw std::out_of_range(std::string("Key does not exist: '") + key + "'"); + return get(itr->second); + else + throw std::out_of_range(std::string("Key does not exist: '") + key + "'"); } - + value_type const& get(std::size_t index) const { if (index < data_.size()) return data_[index]; throw std::out_of_range("Index out of range"); } - + boost::optional get_optional(std::size_t index) const { if (index < data_.size()) return boost::optional(data_[index]); return boost::optional(); } - + std::size_t size() const { return data_.size(); @@ -273,7 +273,7 @@ public: if (index < data_.size()) { ss << " " << itr->first << ":" << data_[itr->second] << std::endl; - } + } } ss << ")" << std::endl; return ss.str(); diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index ab8cad809..ffb0950e5 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -153,7 +153,7 @@ class MAPNIK_DECL font_face_set : private boost::noncopyable public: font_face_set(void) : faces_(), - dimension_cache_() {} + dimension_cache_() {} void add(face_ptr face) { diff --git a/include/mapnik/formatting/registry.hpp b/include/mapnik/formatting/registry.hpp index 7c4faa4d7..1c44e68dd 100644 --- a/include/mapnik/formatting/registry.hpp +++ b/include/mapnik/formatting/registry.hpp @@ -41,7 +41,7 @@ namespace formatting typedef node_ptr (*from_xml_function_ptr)(xml_node const& xml); class registry : public singleton, - private boost::noncopyable + private boost::noncopyable { public: registry(); diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 16eb3c0cc..691bf5404 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -390,7 +390,7 @@ public: } return false; } - + }; typedef geometry geometry_type; diff --git a/include/mapnik/hextree.hpp b/include/mapnik/hextree.hpp index 36ab40857..50102a812 100644 --- a/include/mapnik/hextree.hpp +++ b/include/mapnik/hextree.hpp @@ -160,7 +160,7 @@ public: ~hextree() {} - + void setMaxColors(unsigned max_colors) { max_colors_ = max_colors; @@ -335,7 +335,7 @@ public: sorted_pal_.reserve(colors_); create_palette_rek(sorted_pal_, root_.get()); - + // sort palette for binary searching in quantization #if BOOST_VERSION >= 104600 boost::sort(sorted_pal_, rgba::mean_sort_cmp()); diff --git a/include/mapnik/internal/dump_xml.hpp b/include/mapnik/internal/dump_xml.hpp index 391b89d15..7bdf78f66 100644 --- a/include/mapnik/internal/dump_xml.hpp +++ b/include/mapnik/internal/dump_xml.hpp @@ -3,7 +3,7 @@ #include /* Debug dump ptree XML representation. -*/ + */ void dump_xml(xml_node const& xml, unsigned level=0) { std::string indent; diff --git a/include/mapnik/placement_finder.hpp b/include/mapnik/placement_finder.hpp index 662078238..1ee636349 100644 --- a/include/mapnik/placement_finder.hpp +++ b/include/mapnik/placement_finder.hpp @@ -124,16 +124,16 @@ private: text_symbolizer_properties const& p; text_placement_info const& pi; /** Length of the longest line after linebreaks. - * Before find_line_breaks() this is the total length of the string. - */ + * Before find_line_breaks() this is the total length of the string. + */ double string_width_; /** Height of the string after linebreaks. - * Before find_line_breaks() this is the total length of the string. - */ + * Before find_line_breaks() this is the total length of the string. + */ double string_height_; /** Height of the tallest font in the first line not including line spacing. - * Used to determine the correct offset for the first line. - */ + * Used to determine the correct offset for the first line. + */ double first_line_space_; vertical_alignment_e valign_; horizontal_alignment_e halign_; diff --git a/include/mapnik/text_placements/registry.hpp b/include/mapnik/text_placements/registry.hpp index 35fd59f46..f3bd123bf 100644 --- a/include/mapnik/text_placements/registry.hpp +++ b/include/mapnik/text_placements/registry.hpp @@ -42,7 +42,7 @@ typedef text_placements_ptr (*from_xml_function_ptr)( xml_node const& xml, fontset_map const & fontsets); class registry : public singleton, - private boost::noncopyable + private boost::noncopyable { public: registry(); diff --git a/include/mapnik/util/conversions.hpp b/include/mapnik/util/conversions.hpp index 1b38dee3d..c4d4a321b 100644 --- a/include/mapnik/util/conversions.hpp +++ b/include/mapnik/util/conversions.hpp @@ -30,16 +30,16 @@ namespace mapnik { namespace conversions { -bool string2int(const char * value, int & result); -bool string2int(std::string const& value, int & result); - -bool string2double(std::string const& value, double & result); -bool string2double(const char * value, double & result); - -bool string2float(std::string const& value, float & result); -bool string2float(const char * value, float & result); + bool string2int(const char * value, int & result); + bool string2int(std::string const& value, int & result); -} + bool string2double(std::string const& value, double & result); + bool string2double(const char * value, double & result); + + bool string2float(std::string const& value, float & result); + bool string2float(const char * value, float & result); + + } } #endif // MAPNIK_CONVERSIONS_UTIL_HPP diff --git a/include/mapnik/vertex_vector.hpp b/include/mapnik/vertex_vector.hpp index e326aa284..85bcd8857 100644 --- a/include/mapnik/vertex_vector.hpp +++ b/include/mapnik/vertex_vector.hpp @@ -55,16 +55,16 @@ public: // required for iterators support typedef boost::tuple value_type; typedef std::size_t size_type; - + private: unsigned num_blocks_; unsigned max_blocks_; coord_type** vertices_; unsigned char** commands_; size_type pos_; - + public: - + vertex_vector() : num_blocks_(0), max_blocks_(0), @@ -114,7 +114,7 @@ public: *y = (*vertex); return commands_[block] [pos & block_mask]; } - + private: void allocate_block(unsigned block) { From 93995d7c4b3330c35f13099b8a1a190e103a1248 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 13 Mar 2012 07:56:11 -0700 Subject: [PATCH 060/138] apply mapnik_format.el formatting --- src/agg/process_line_symbolizer.cpp | 4 +- src/agg/process_markers_symbolizer.cpp | 2 +- .../process_polygon_pattern_symbolizer.cpp | 2 +- src/agg/process_polygon_symbolizer.cpp | 2 +- src/cairo_renderer.cpp | 24 +-- src/color.cpp | 2 +- src/config_error.cpp | 10 +- src/conversions.cpp | 16 +- src/expression.cpp | 4 +- src/feature_style_processor.cpp | 4 +- src/formatting/expression.cpp | 16 +- src/json/feature_collection_parser.cpp | 36 ++-- src/json/geojson_generator.cpp | 66 +++---- src/libxml2_loader.cpp | 2 +- src/load_map.cpp | 162 +++++++++--------- src/map.cpp | 4 +- src/placement_finder.cpp | 30 ++-- src/rapidxml_loader.cpp | 4 +- src/symbolizer_helpers.cpp | 2 +- src/text_placements/list.cpp | 2 +- src/text_placements/simple.cpp | 4 +- src/xml_tree.cpp | 6 +- 22 files changed, 202 insertions(+), 202 deletions(-) diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index e45226bf3..193e53f43 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -63,7 +63,7 @@ void agg_renderer::process(line_symbolizer const& sym, agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4); agg::pixfmt_rgba32_plain pixf(buf); - + box2d ext = query_extent_ * 1.1; if (sym.get_rasterizer() == RASTERIZER_FAST) { @@ -132,7 +132,7 @@ void agg_renderer::process(line_symbolizer const& sym, clipped_geometry_type clipped(geom); clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); path_type path(t_,clipped,prj_trans); - + if (stroke_.has_dash()) { agg::conv_dash dash(path); diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index 1637f9450..57a01448e 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -253,7 +253,7 @@ void agg_renderer::process(markers_symbolizer const& sym, if (marker_type == ARROW) marker.concat_path(arrow_); - + clipped_geometry_type clipped(geom); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp index 7e0f92c94..670fea9b6 100644 --- a/src/agg/process_polygon_pattern_symbolizer.cpp +++ b/src/agg/process_polygon_pattern_symbolizer.cpp @@ -134,7 +134,7 @@ void agg_renderer::process(polygon_pattern_symbolizer const& sym, if (align == LOCAL_ALIGNMENT) { double x0=0,y0=0; - if (num_geometries>0) // FIXME: hmm...? + if (num_geometries>0) // FIXME: hmm...? { clipped_geometry_type clipped(feature->get_geometry(0)); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); diff --git a/src/agg/process_polygon_symbolizer.cpp b/src/agg/process_polygon_symbolizer.cpp index 4b1f64bb8..a7187a444 100644 --- a/src/agg/process_polygon_symbolizer.cpp +++ b/src/agg/process_polygon_symbolizer.cpp @@ -63,7 +63,7 @@ void agg_renderer::process(polygon_symbolizer const& sym, unsigned a=fill_.alpha(); //renb.clip_box(0,0,width_,height_); renderer ren(renb); - + ras_ptr->reset(); switch (sym.get_gamma_method()) { diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index 76eb9b009..c900491a6 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -256,7 +256,7 @@ cairo_face_ptr cairo_face_manager::get_face(face_ptr face) entry = boost::make_shared(font_engine_, face); cache_.insert(std::make_pair(face, entry)); } - + return entry; } @@ -712,7 +712,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) } query_extent_ = query_extent; } - + void cairo_renderer_base::end_layer_processing(layer const&) { #ifdef MAPNIK_DEBUG @@ -739,13 +739,13 @@ void cairo_renderer_base::start_map_processing(Map const& map) { clipped_geometry_type clipped(geom); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); - path_type path(t_,clipped,prj_trans); + path_type path(t_,clipped,prj_trans); context.add_path(path); context.fill(); } } } - + void cairo_renderer_base::process(building_symbolizer const& sym, mapnik::feature_ptr const& feature, proj_transform const& prj_trans) @@ -862,7 +862,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) { typedef agg::conv_clip_polyline clipped_geometry_type; typedef coord_transform2 path_type; - + cairo_context context(context_); mapnik::stroke const& stroke_ = sym.get_stroke(); @@ -1065,7 +1065,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) 1.0 /*scale_factor*/, t_, font_manager_, detector_, query_extent_); cairo_context context(context_); - + while (helper.next()) { placements_type &placements = helper.placements(); for (unsigned int ii = 0; ii < placements.size(); ++ii) @@ -1085,7 +1085,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) { typedef agg::conv_clip_polyline clipped_geometry_type; typedef coord_transform2 path_type; - + std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); boost::optional marker = mapnik::marker_cache::instance()->find(filename,true); if (!marker && !(*marker)->is_bitmap()) return; @@ -1109,7 +1109,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) clipped_geometry_type clipped(geom); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); - + double length(0); double x0(0), y0(0); double x, y; @@ -1158,7 +1158,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) { typedef agg::conv_clip_polygon clipped_geometry_type; typedef coord_transform2 path_type; - + cairo_context context(context_); std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); boost::optional marker = mapnik::marker_cache::instance()->find(filename,true); @@ -1178,7 +1178,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) { clipped_geometry_type clipped(geom); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); - path_type path(t_,clipped,prj_trans); + path_type path(t_,clipped,prj_trans); context.add_path(path); context.fill(); } @@ -1247,9 +1247,9 @@ void cairo_renderer_base::start_map_processing(Map const& map) if (geom.num_points() > 1) { - + path_type path(t_, geom, prj_trans); - + markers_placement placement(path, arrow_.extent(), detector_, sym.get_spacing(), sym.get_max_error(), sym.get_allow_overlap()); double x, y, angle; diff --git a/src/color.cpp b/src/color.cpp index 3a98976f7..480b6b9d2 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -137,7 +137,7 @@ void color_factory::init_from_string(color & c, std::string const& css_color) } bool color_factory::parse_from_string(color & c, std::string const& css_color, - mapnik::css_color_grammar const& g) + mapnik::css_color_grammar const& g) { std::string::const_iterator first = css_color.begin(); std::string::const_iterator last = css_color.end(); diff --git a/src/config_error.cpp b/src/config_error.cpp index 21ab1ac63..714f5a5e2 100644 --- a/src/config_error.cpp +++ b/src/config_error.cpp @@ -22,7 +22,7 @@ config_error::config_error(std::string const& what, unsigned line_number, std::s } - char const* config_error::what() const throw() +char const* config_error::what() const throw() { std::stringstream s; s << file_; @@ -34,10 +34,10 @@ config_error::config_error(std::string const& what, unsigned line_number, std::s 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) const +{ + what_ += " " + ctx; +} void config_error::append_context(std::string const& ctx, xml_node const& node) const { diff --git a/src/conversions.cpp b/src/conversions.cpp index 7debd7a6c..822b63263 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -23,14 +23,14 @@ // boost #include -#define BOOST_SPIRIT_AUTO(domain_, name, expr) \ - typedef boost::proto::result_of:: \ - deep_copy::type name##_expr_type; \ - BOOST_SPIRIT_ASSERT_MATCH( \ - boost::spirit::domain_::domain, name##_expr_type); \ - BOOST_AUTO(name, boost::proto::deep_copy(expr)); \ - - +#define BOOST_SPIRIT_AUTO(domain_, name, expr) \ + typedef boost::proto::result_of:: \ + deep_copy::type name##_expr_type; \ + BOOST_SPIRIT_ASSERT_MATCH( \ + boost::spirit::domain_::domain, name##_expr_type); \ + BOOST_AUTO(name, boost::proto::deep_copy(expr)); \ + \ + \ namespace mapnik { namespace conversions { using namespace boost::spirit; diff --git a/src/expression.cpp b/src/expression.cpp index a99fc9fcc..84cd6b0ec 100644 --- a/src/expression.cpp +++ b/src/expression.cpp @@ -51,8 +51,8 @@ expression_ptr expression_factory::compile(std::string const& str,transcoder con } bool expression_factory::parse_from_string(expression_ptr const& expr, - std::string const& str, - mapnik::expression_grammar const& g) + std::string const& str, + mapnik::expression_grammar const& g) { std::string::const_iterator itr = str.begin(); std::string::const_iterator end = str.end(); diff --git a/src/feature_style_processor.cpp b/src/feature_style_processor.cpp index 9b8c9de12..4b78ab0a3 100644 --- a/src/feature_style_processor.cpp +++ b/src/feature_style_processor.cpp @@ -203,7 +203,7 @@ void feature_style_processor::apply_to_layer(layer const& lay, Proces return; } - + #if defined(RENDERING_STATS) progress_timer layer_timer(std::clog, "rendering total for layer: '" + lay.name() + "'"); @@ -270,7 +270,7 @@ void feature_style_processor::apply_to_layer(layer const& lay, Proces m_.height()/qh); query q(layer_ext,res,scale_denom,unbuffered_extent); - p.start_layer_processing(lay, query_ext); + p.start_layer_processing(lay, query_ext); std::vector active_styles; attribute_collector collector(names); double filt_factor = 1; diff --git a/src/formatting/expression.cpp b/src/formatting/expression.cpp index 1bd199a33..5dfff9972 100644 --- a/src/formatting/expression.cpp +++ b/src/formatting/expression.cpp @@ -85,25 +85,25 @@ void expression_format::apply(char_properties const& p, const Feature &feature, { char_properties new_properties = p; if (face_name) new_properties.face_name = - boost::apply_visitor(evaluate(feature), *face_name).to_string(); + boost::apply_visitor(evaluate(feature), *face_name).to_string(); if (text_size) new_properties.text_size = - boost::apply_visitor(evaluate(feature), *text_size).to_double(); + boost::apply_visitor(evaluate(feature), *text_size).to_double(); if (character_spacing) new_properties.character_spacing = - boost::apply_visitor(evaluate(feature), *character_spacing).to_double(); + boost::apply_visitor(evaluate(feature), *character_spacing).to_double(); if (line_spacing) new_properties.line_spacing = - boost::apply_visitor(evaluate(feature), *line_spacing).to_double(); + boost::apply_visitor(evaluate(feature), *line_spacing).to_double(); if (text_opacity) new_properties.text_opacity = - boost::apply_visitor(evaluate(feature), *text_opacity).to_double(); + boost::apply_visitor(evaluate(feature), *text_opacity).to_double(); if (wrap_before) new_properties.wrap_before = - boost::apply_visitor(evaluate(feature), *wrap_before).to_bool(); + boost::apply_visitor(evaluate(feature), *wrap_before).to_bool(); if (wrap_char) new_properties.wrap_char = - boost::apply_visitor(evaluate(feature), *character_spacing).to_unicode()[0]; + boost::apply_visitor(evaluate(feature), *character_spacing).to_unicode()[0]; // if (fill) new_properties.fill = // boost::apply_visitor(evaluate(feature), *fill).to_color(); // if (halo_fill) new_properties.halo_fill = // boost::apply_visitor(evaluate(feature), *halo_fill).to_color(); if (halo_radius) new_properties.halo_radius = - boost::apply_visitor(evaluate(feature), *halo_radius).to_double(); + boost::apply_visitor(evaluate(feature), *halo_radius).to_double(); if (child_) { child_->apply(new_properties, feature, output); diff --git a/src/json/feature_collection_parser.cpp b/src/json/feature_collection_parser.cpp index fbf9c2b19..a7f2a418a 100644 --- a/src/json/feature_collection_parser.cpp +++ b/src/json/feature_collection_parser.cpp @@ -33,29 +33,29 @@ namespace mapnik { namespace json { #if BOOST_VERSION >= 104700 -template -feature_collection_parser::feature_collection_parser(mapnik::context_ptr const& ctx, mapnik::transcoder const& tr) - : grammar_(new feature_collection_grammar(ctx,tr)) {} + template + feature_collection_parser::feature_collection_parser(mapnik::context_ptr const& ctx, mapnik::transcoder const& tr) + : grammar_(new feature_collection_grammar(ctx,tr)) {} -template -feature_collection_parser::~feature_collection_parser() {} + template + feature_collection_parser::~feature_collection_parser() {} #endif -template -bool feature_collection_parser::parse(iterator_type first, iterator_type last, std::vector & features) -{ + template + bool feature_collection_parser::parse(iterator_type first, iterator_type last, std::vector & features) + { #if BOOST_VERSION >= 104700 - using namespace boost::spirit; - return qi::phrase_parse(first, last, *grammar_, standard_wide::space, features); + using namespace boost::spirit; + return qi::phrase_parse(first, last, *grammar_, standard_wide::space, features); #else - std::ostringstream s; - s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100; - throw std::runtime_error("mapnik::feature_collection_parser::parse() requires at least boost 1.47 while your build was compiled against boost " + s.str()); - return false; + std::ostringstream s; + s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100; + throw std::runtime_error("mapnik::feature_collection_parser::parse() requires at least boost 1.47 while your build was compiled against boost " + s.str()); + return false; #endif -} + } -template class feature_collection_parser ; -template class feature_collection_parser > >; -}} + template class feature_collection_parser ; + template class feature_collection_parser > >; + }} diff --git a/src/json/geojson_generator.cpp b/src/json/geojson_generator.cpp index c25440ded..750489690 100644 --- a/src/json/geojson_generator.cpp +++ b/src/json/geojson_generator.cpp @@ -32,30 +32,30 @@ namespace mapnik { namespace json { -feature_generator::feature_generator() - : grammar_(new feature_generator_grammar()) {} - -feature_generator::~feature_generator() {} + feature_generator::feature_generator() + : grammar_(new feature_generator_grammar()) {} -bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f) -{ - sink_type sink(geojson); - return karma::generate(sink, *grammar_,f); -} + feature_generator::~feature_generator() {} + + bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f) + { + sink_type sink(geojson); + return karma::generate(sink, *grammar_,f); + } -geometry_generator::geometry_generator() - : grammar_(new multi_geometry_generator_grammar()) {} + geometry_generator::geometry_generator() + : grammar_(new multi_geometry_generator_grammar()) {} -geometry_generator::~geometry_generator() {} + geometry_generator::~geometry_generator() {} -bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g) -{ - sink_type sink(geojson); - return karma::generate(sink, *grammar_,g); -} + bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g) + { + sink_type sink(geojson); + return karma::generate(sink, *grammar_,g); + } -}} + }} #else @@ -65,22 +65,22 @@ bool geometry_generator::generate(std::string & geojson, mapnik::geometry_contai namespace mapnik { namespace json { -bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f) -{ - std::ostringstream s; - s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100; - throw std::runtime_error("feature_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str()); - return false; -} + bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f) + { + std::ostringstream s; + s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100; + throw std::runtime_error("feature_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str()); + return false; + } -bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g) -{ - std::ostringstream s; - s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100; - throw std::runtime_error("geometry_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str()); - return false; -} + bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g) + { + std::ostringstream s; + s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100; + throw std::runtime_error("geometry_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str()); + return false; + } -}} + }} #endif diff --git a/src/libxml2_loader.cpp b/src/libxml2_loader.cpp index 964545a00..d95e145ca 100644 --- a/src/libxml2_loader.cpp +++ b/src/libxml2_loader.cpp @@ -191,7 +191,7 @@ private: } break; case XML_COMMENT_NODE: - break; + break; default: break; diff --git a/src/load_map.cpp b/src/load_map.cpp index 5e4680fd4..0b71ba838 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -85,7 +85,7 @@ public: filename_( filename ), relative_to_xml_(true), font_manager_(font_engine_) - {} + {} void parse_map(Map & map, xml_node const& sty, std::string const& base_path); private: @@ -121,7 +121,7 @@ private: std::string ensure_relative_to_xml(boost::optional opt_path); boost::optional get_opt_color_attr(boost::property_tree::ptree const& node, - std::string const& name); + std::string const& name); bool strict_; std::string filename_; @@ -306,93 +306,93 @@ void map_parser::parse_map_include(Map & map, xml_node const& include) { try { - xml_node::const_iterator itr = include.begin(); - xml_node::const_iterator end = include.end(); + xml_node::const_iterator itr = include.begin(); + xml_node::const_iterator end = include.end(); - for (; itr != end; ++itr) - { - if (itr->is_text()) continue; - if (itr->is("Include")) + for (; itr != end; ++itr) { - parse_map_include(map, *itr); - } - else if (itr->is("Style")) - { - parse_style(map, *itr); - } - else if (itr->is("Layer")) - { - parse_layer(map, *itr); - } - else if (itr->is("FontSet")) - { - parse_fontset(map, *itr); - } - else if (itr->is("MetaWriter")) - { - parse_metawriter(map, *itr); - } - else if (itr->is("FileSource")) - { - std::string name = itr->get_attr("name"); - std::string value = itr->get_text(); - file_sources_[name] = value; - } - else if (itr->is("Datasource")) - { - std::string name = itr->get_attr("name", std::string("Unnamed")); - parameters params; - xml_node::const_iterator paramIter = itr->begin(); - xml_node::const_iterator endParam = itr->end(); - for (; paramIter != endParam; ++paramIter) + if (itr->is_text()) continue; + if (itr->is("Include")) { - if (paramIter->is("Parameter")) - { - std::string name = paramIter->get_attr("name"); - std::string value = paramIter->get_text(); - params[name] = value; - } + parse_map_include(map, *itr); } - datasource_templates_[name] = params; - } - else if (itr->is("Parameters")) - { - std::string name = itr->get_attr("name", std::string("Unnamed")); - parameters & params = map.get_extra_parameters(); - xml_node::const_iterator paramIter = itr->begin(); - xml_node::const_iterator endParam = itr->end(); - for (; paramIter != endParam; ++paramIter) + else if (itr->is("Style")) { - if (paramIter->is("Parameter")) + parse_style(map, *itr); + } + else if (itr->is("Layer")) + { + parse_layer(map, *itr); + } + else if (itr->is("FontSet")) + { + parse_fontset(map, *itr); + } + else if (itr->is("MetaWriter")) + { + parse_metawriter(map, *itr); + } + else if (itr->is("FileSource")) + { + std::string name = itr->get_attr("name"); + std::string value = itr->get_text(); + file_sources_[name] = value; + } + else if (itr->is("Datasource")) + { + std::string name = itr->get_attr("name", std::string("Unnamed")); + parameters params; + xml_node::const_iterator paramIter = itr->begin(); + xml_node::const_iterator endParam = itr->end(); + for (; paramIter != endParam; ++paramIter) { - std::string name = paramIter->get_attr("name"); - bool is_string = true; - boost::optional type = paramIter->get_opt_attr("type"); - if (type) - { - if (*type == "int") - { - is_string = false; - int value = paramIter->get_value(); - params[name] = value; - } - else if (*type == "float") - { - is_string = false; - double value = paramIter->get_value(); - params[name] = value; - } - } - - if (is_string) + if (paramIter->is("Parameter")) { + std::string name = paramIter->get_attr("name"); std::string value = paramIter->get_text(); params[name] = value; } } + datasource_templates_[name] = params; + } + else if (itr->is("Parameters")) + { + std::string name = itr->get_attr("name", std::string("Unnamed")); + parameters & params = map.get_extra_parameters(); + xml_node::const_iterator paramIter = itr->begin(); + xml_node::const_iterator endParam = itr->end(); + for (; paramIter != endParam; ++paramIter) + { + if (paramIter->is("Parameter")) + { + std::string name = paramIter->get_attr("name"); + bool is_string = true; + boost::optional type = paramIter->get_opt_attr("type"); + if (type) + { + if (*type == "int") + { + is_string = false; + int value = paramIter->get_value(); + params[name] = value; + } + else if (*type == "float") + { + is_string = false; + double value = paramIter->get_value(); + params[name] = value; + } + } + + if (is_string) + { + std::string value = paramIter->get_text(); + params[name] = value; + } + } + } } } - } } catch (const config_error & ex) { ex.append_context(include); throw; @@ -1060,7 +1060,7 @@ void map_parser::parse_text_symbolizer( rule & rule, xml_node const& sym ) placement_finder->defaults.from_xml(sym, fontsets_); } if (strict_ && - !placement_finder->defaults.format.fontset.size()) + !placement_finder->defaults.format.fontset.size()) ensure_font_face(placement_finder->defaults.format.face_name); text_symbolizer text_symbol = text_symbolizer(placement_finder); @@ -1087,7 +1087,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym ) } placement_finder->defaults.from_xml(sym, fontsets_); if (strict_ && - !placement_finder->defaults.format.fontset.size()) + !placement_finder->defaults.format.fontset.size()) ensure_font_face(placement_finder->defaults.format.face_name); shield_symbolizer shield_symbol = shield_symbolizer(placement_finder); @@ -1447,7 +1447,7 @@ void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, maximumValue = *value; optional label = - stopIter->get_opt_attr("label"); + stopIter->get_opt_attr("label"); //append the stop colorizer_stop tmpStop; @@ -1532,8 +1532,8 @@ void map_parser::find_unused_nodes_recursive(xml_node const& node, std::stringst if (!aitr->second.processed) { error_message << "\n* attribute '" << aitr->first << - "' with value '" << aitr->second.value << - "' in line " << node.line(); + "' with value '" << aitr->second.value << + "' in line " << node.line(); } } xml_node::const_iterator itr = node.begin(); diff --git a/src/map.cpp b/src/map.cpp index 5af404a62..661c5c819 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -588,7 +588,7 @@ featureset_ptr Map::query_point(unsigned index, double x, double y) const featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y)); if (fs) return boost::make_shared >(fs, - hit_test_filter(x,y,tol)); + hit_test_filter(x,y,tol)); } } catch (...) @@ -634,7 +634,7 @@ featureset_ptr Map::query_map_point(unsigned index, double x, double y) const featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y)); if (fs) return boost::make_shared >(fs, - hit_test_filter(x,y,tol)); + hit_test_filter(x,y,tol)); } } catch (...) diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index f68597edb..387323323 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -269,9 +269,9 @@ void placement_finder::find_line_breaks() // wrap text at first wrap_char after (default) the wrap width or immediately before the current word if ((c == '\n') || (line_width > 0 && - ((line_width > wrap_at && !ci.format->wrap_before) || + ((line_width > wrap_at && !ci.format->wrap_before) || ((line_width + last_wrap_char_width + word_width) > wrap_at && ci.format->wrap_before)) ) - ) + ) { add_line(line_width, line_height, first_line); line_breaks_.push_back(last_wrap_char_pos); @@ -440,8 +440,8 @@ void placement_finder::find_point_placement(double label_x, if (!detector_.extent().intersects(e) || (!p.allow_overlap && - !detector_.has_point_placement(e, pi.get_actual_minimum_distance()))) - { + !detector_.has_point_placement(e, pi.get_actual_minimum_distance()))) + { return; } @@ -675,10 +675,10 @@ void placement_finder::find_line_placements(PathT & shape_path) template std::auto_ptr placement_finder::get_placement_offset(std::vector const& path_positions, - std::vector const& path_distances, - int & orientation, - unsigned index, - double distance) + std::vector const& path_distances, + int & orientation, + unsigned index, + double distance) { //Check that the given distance is on the given index and find the correct index and distance if not while (distance < 0 && index > 1) @@ -718,10 +718,10 @@ std::auto_ptr placement_finder::get_placement_offset(std:: } std::auto_ptr current_placement( - new text_path((old_x + dx*distance/segment_length), - (old_y + dy*distance/segment_length) - ) - ); + new text_path((old_x + dx*distance/segment_length), + (old_y + dy*distance/segment_length) + ) + ); double angle = atan2(-dy, dx); @@ -830,7 +830,7 @@ std::auto_ptr placement_finder::get_placement_offset(std:: render_angle += M_PI; } current_placement->add_node(&ci, - render_x - current_placement->center.x, + render_x - current_placement->center.x, -render_y + current_placement->center.y, render_angle); @@ -870,7 +870,7 @@ std::auto_ptr placement_finder::get_placement_offset(std:: template bool placement_finder::test_placement(std::auto_ptr const& current_placement, - int orientation) + int orientation) { //Create and test envelopes bool status = true; @@ -909,8 +909,8 @@ bool placement_finder::test_placement(std::auto_ptr const& if (!detector_.extent().intersects(e) || (!p.allow_overlap && !detector_.has_placement(e, info_.get_string(), pi.get_actual_minimum_distance()) + ) ) - ) { //std::clog << "No Intersects:" << !dimensions_.intersects(e) << ": " << e << " @ " << dimensions_ << std::endl; //std::clog << "No Placements:" << !detector_.has_placement(e, info.get_string(), p.minimum_distance) << std::endl; diff --git a/src/rapidxml_loader.cpp b/src/rapidxml_loader.cpp index c7be38b5b..4a9293f54 100644 --- a/src/rapidxml_loader.cpp +++ b/src/rapidxml_loader.cpp @@ -73,7 +73,7 @@ public: { stream.unsetf(std::ios::skipws); std::vector v(std::istreambuf_iterator(stream.rdbuf()), - std::istreambuf_iterator()); + std::istreambuf_iterator()); if (!stream.good()) { throw config_error("Could not load map file", 0, filename_); @@ -83,7 +83,7 @@ public: { // Parse using appropriate flags const int f_tws = rapidxml::parse_normalize_whitespace - | rapidxml::parse_trim_whitespace; + | rapidxml::parse_trim_whitespace; rapidxml::xml_document<> doc; doc.parse(&v.front()); diff --git a/src/symbolizer_helpers.cpp b/src/symbolizer_helpers.cpp index 8c59ff272..cfcc83902 100644 --- a/src/symbolizer_helpers.cpp +++ b/src/symbolizer_helpers.cpp @@ -51,7 +51,7 @@ bool text_symbolizer_helper::next_line_placement() geo_itr_ = geometries_to_process_.begin(); continue; //Reexecute size check } - + typedef agg::conv_clip_polyline clipped_geometry_type; typedef coord_transform2 path_type; clipped_geometry_type clipped(**geo_itr_); diff --git a/src/text_placements/list.cpp b/src/text_placements/list.cpp index 6a43e8716..ce2ea33d4 100644 --- a/src/text_placements/list.cpp +++ b/src/text_placements/list.cpp @@ -64,7 +64,7 @@ text_symbolizer_properties & text_placements_list::get(unsigned i) text_placement_info_ptr text_placements_list::get_placement_info(double scale_factor) const { return text_placement_info_ptr( - boost::make_shared(this, scale_factor)); + boost::make_shared(this, scale_factor)); } text_placements_list::text_placements_list() : text_placements(), list_(0) diff --git a/src/text_placements/simple.cpp b/src/text_placements/simple.cpp index f23e79e67..c35f1e7f3 100644 --- a/src/text_placements/simple.cpp +++ b/src/text_placements/simple.cpp @@ -104,7 +104,7 @@ text_placement_info_ptr text_placements_simple::get_placement_info( double scale_factor) const { return text_placement_info_ptr( - boost::make_shared(this, scale_factor)); + boost::make_shared(this, scale_factor)); } /** Position string: [POS][SIZE] @@ -171,7 +171,7 @@ std::string text_placements_simple::get_positions() text_placements_ptr text_placements_simple::from_xml(xml_node const &xml, fontset_map const & fontsets) { text_placements_ptr ptr = boost::make_shared( - xml.get_attr("placements", "X")); + xml.get_attr("placements", "X")); ptr->defaults.from_xml(xml, fontsets); return ptr; } diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index a1b80b786..ef61e9258 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -127,7 +127,7 @@ struct name_trait BOOST_STATIC_ASSERT( sizeof(T) == 0 ); }; -#define DEFINE_NAME_TRAIT( type, type_name ) \ +#define DEFINE_NAME_TRAIT( type, type_name ) \ template <> \ struct name_trait \ { \ @@ -220,8 +220,8 @@ attribute_not_found::attribute_not_found( std::string const& node_name, std::string const& attribute_name) : - node_name_(node_name), - attribute_name_(attribute_name) + node_name_(node_name), + attribute_name_(attribute_name) { } From 76e108ff9d49e96e6e622600669b2d5ee5c1c863 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 13 Mar 2012 07:58:38 -0700 Subject: [PATCH 061/138] remove uneeded shared_ptr copy --- src/text_placements/list.cpp | 3 +-- src/text_placements/simple.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/text_placements/list.cpp b/src/text_placements/list.cpp index ce2ea33d4..7aea6812d 100644 --- a/src/text_placements/list.cpp +++ b/src/text_placements/list.cpp @@ -63,8 +63,7 @@ text_symbolizer_properties & text_placements_list::get(unsigned i) text_placement_info_ptr text_placements_list::get_placement_info(double scale_factor) const { - return text_placement_info_ptr( - boost::make_shared(this, scale_factor)); + return boost::make_shared(this, scale_factor); } text_placements_list::text_placements_list() : text_placements(), list_(0) diff --git a/src/text_placements/simple.cpp b/src/text_placements/simple.cpp index c35f1e7f3..cefa199fa 100644 --- a/src/text_placements/simple.cpp +++ b/src/text_placements/simple.cpp @@ -103,8 +103,7 @@ bool text_placement_info_simple::next_position_only() text_placement_info_ptr text_placements_simple::get_placement_info( double scale_factor) const { - return text_placement_info_ptr( - boost::make_shared(this, scale_factor)); + return boost::make_shared(this, scale_factor); } /** Position string: [POS][SIZE] @@ -145,10 +144,12 @@ void text_placements_simple::set_positions(std::string positions) (direction_name[push_back(phoenix::ref(direction_), _1)] % ',') >> *(',' >> qi::float_[push_back(phoenix::ref(text_sizes_), _1)]), space ); - if (first != last) { + if (first != last) + { std::cerr << "WARNING: Could not parse text_placement_simple placement string ('" << positions << "').\n"; } - if (direction_.size() == 0) { + if (direction_.size() == 0) + { std::cerr << "WARNING: text_placements_simple with no valid placements! ('"<< positions<<"')\n"; } } From b36739fd88b41a7348c75f34503f37ce85726d17 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 13 Mar 2012 07:59:22 -0700 Subject: [PATCH 062/138] apply mapnik_format.el formatting --- bindings/python/mapnik_image.cpp | 2 +- bindings/python/mapnik_text_placement.cpp | 102 +++++++++---------- bindings/python/mapnik_threads.hpp | 14 +-- bindings/python/python_optional.hpp | 8 +- plugins/input/occi/occi_featureset.cpp | 2 +- plugins/input/postgis/postgis_datasource.cpp | 32 +++--- plugins/input/shape/shape_io.cpp | 10 +- 7 files changed, 85 insertions(+), 85 deletions(-) diff --git a/bindings/python/mapnik_image.cpp b/bindings/python/mapnik_image.cpp index 858c53437..5ade76573 100644 --- a/bindings/python/mapnik_image.cpp +++ b/bindings/python/mapnik_image.cpp @@ -125,7 +125,7 @@ bool painted(mapnik::image_32 const& im) void set_pixel(mapnik::image_32 & im, unsigned x, unsigned y, mapnik::color const& c) { im.setPixel(x, y, c.rgba()); -} +} boost::shared_ptr open_from_file(std::string const& filename) { diff --git a/bindings/python/mapnik_text_placement.cpp b/bindings/python/mapnik_text_placement.cpp index 12c8dfa55..c9f1ac4e5 100644 --- a/bindings/python/mapnik_text_placement.cpp +++ b/bindings/python/mapnik_text_placement.cpp @@ -40,15 +40,15 @@ using namespace mapnik; /* Notes: -Overriding functions in inherited classes: -boost.python documentation doesn't really tell you how to do it. -But this helps: -http://www.gamedev.net/topic/446225-inheritance-in-boostpython/ + Overriding functions in inherited classes: + boost.python documentation doesn't really tell you how to do it. + But this helps: + http://www.gamedev.net/topic/446225-inheritance-in-boostpython/ -register_ptr_to_python is required for wrapped classes, but not for unwrapped. + register_ptr_to_python is required for wrapped classes, but not for unwrapped. -Functions don't have to be members of the class, but can also be -normal functions taking a ref to the class as first parameter. + Functions don't have to be members of the class, but can also be + normal functions taking a ref to the class as first parameter. */ namespace { @@ -261,7 +261,7 @@ struct TextPlacementsWrap: text_placements, wrapper struct TextPlacementInfoWrap: text_placement_info, wrapper { TextPlacementInfoWrap(text_placements const* parent, - double scale_factor_) + double scale_factor_) : text_placement_info(parent, scale_factor_) { @@ -339,7 +339,7 @@ void export_text_placement() ; class_("TextSymbolizer", - init<>()) + init<>()) .def(init()) .add_property("placements", &text_symbolizer::get_placement_options, @@ -357,7 +357,7 @@ void export_text_placement() class_with_converter - ("TextSymbolizerProperties") + ("TextSymbolizerProperties") .def_readwrite_convert("label_placement", &text_symbolizer_properties::label_placement) .def_readwrite_convert("horizontal_alignment", &text_symbolizer_properties::halign) .def_readwrite_convert("justify_alignment", &text_symbolizer_properties::jalign) @@ -381,15 +381,15 @@ void export_text_placement() .add_property ("format_tree", &text_symbolizer_properties::format_tree, &text_symbolizer_properties::set_format_tree); - /* from_xml, to_xml operate on mapnik's internal XML tree and don't make sense in python. - add_expressions isn't useful in python either. The result is only needed by - attribute_collector (which isn't exposed in python) and - it just calls add_expressions of the associated formatting tree. - set_old_style expression is just a compatibility wrapper and doesn't need to be exposed in python. */ - ; + /* from_xml, to_xml operate on mapnik's internal XML tree and don't make sense in python. + add_expressions isn't useful in python either. The result is only needed by + attribute_collector (which isn't exposed in python) and + it just calls add_expressions of the associated formatting tree. + set_old_style expression is just a compatibility wrapper and doesn't need to be exposed in python. */ + ; class_ - ("CharProperties") + ("CharProperties") .def(init()) //Copy constructor .def_readwrite("face_name", &char_properties::face_name) .def_readwrite("fontset", &char_properties::fontset) @@ -407,9 +407,9 @@ void export_text_placement() ; class_, - boost::noncopyable> - ("TextPlacements") + boost::shared_ptr, + boost::noncopyable> + ("TextPlacements") .def_readwrite("defaults", &text_placements::defaults) .def("get_placement_info", pure_virtual(&text_placements::get_placement_info)) /* TODO: add_expressions() */ @@ -417,10 +417,10 @@ void export_text_placement() register_ptr_to_python >(); class_, - boost::noncopyable> - ("TextPlacementInfo", - init()) + boost::shared_ptr, + boost::noncopyable> + ("TextPlacementInfo", + init()) .def("next", pure_virtual(&text_placement_info::next)) .def("get_actual_label_spacing", &text_placement_info::get_actual_label_spacing) .def("get_actual_minimum_distance", &text_placement_info::get_actual_minimum_distance) @@ -432,27 +432,27 @@ void export_text_placement() class_, - boost::noncopyable> - ("ProcessedText", no_init) + boost::shared_ptr, + boost::noncopyable> + ("ProcessedText", no_init) .def("push_back", &processed_text::push_back) .def("clear", &processed_text::clear) ; class_, - boost::noncopyable> - ("ExpressionSet") + boost::shared_ptr, + boost::noncopyable> + ("ExpressionSet") .def("insert", &insert_expression); - ; + ; //TODO: Python namespace class_, - boost::noncopyable> - ("FormattingNode") + boost::shared_ptr, + boost::noncopyable> + ("FormattingNode") .def("apply", pure_virtual(&formatting::node::apply)) .def("add_expressions", &formatting::node::add_expressions, @@ -462,10 +462,10 @@ void export_text_placement() class_, - bases, - boost::noncopyable> - ("FormattingText", init()) + boost::shared_ptr, + bases, + boost::noncopyable> + ("FormattingText", init()) .def(init()) .def("apply", &formatting::text_node::apply, &TextNodeWrap::default_apply) .add_property("text", @@ -476,10 +476,10 @@ void export_text_placement() class_with_converter, - bases, - boost::noncopyable> - ("FormattingFormat") + boost::shared_ptr, + bases, + boost::noncopyable> + ("FormattingFormat") .def_readwrite_convert("text_size", &formatting::format_node::text_size) .def_readwrite_convert("face_name", &formatting::format_node::face_name) .def_readwrite_convert("character_spacing", &formatting::format_node::character_spacing) @@ -499,10 +499,10 @@ void export_text_placement() register_ptr_to_python >(); class_, - bases, - boost::noncopyable> - ("FormattingList", init<>()) + boost::shared_ptr, + bases, + boost::noncopyable> + ("FormattingList", init<>()) .def(init()) .def("append", &formatting::list_node::push_back) .def("apply", &formatting::list_node::apply, &ListNodeWrap::default_apply) @@ -510,15 +510,15 @@ void export_text_placement() .def("__getitem__", &ListNodeWrap::get_item) .def("__setitem__", &ListNodeWrap::set_item) .def("append", &ListNodeWrap::append) - ; + ; register_ptr_to_python >(); class_, - bases, - boost::noncopyable> - ("FormattingExpressionFormat") + boost::shared_ptr, + bases, + boost::noncopyable> + ("FormattingExpressionFormat") .def_readwrite("text_size", &formatting::expression_format::text_size) .def_readwrite("face_name", &formatting::expression_format::face_name) .def_readwrite("character_spacing", &formatting::expression_format::character_spacing) diff --git a/bindings/python/mapnik_threads.hpp b/bindings/python/mapnik_threads.hpp index b1ac3f4e6..85789ff61 100644 --- a/bindings/python/mapnik_threads.hpp +++ b/bindings/python/mapnik_threads.hpp @@ -29,8 +29,8 @@ namespace mapnik { class python_thread { /* Docs: - http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock - */ + http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock + */ public: static void unblock() { @@ -38,8 +38,8 @@ public: if (state.get()) { std::cerr << "ERROR: Python threads are already unblocked. " - "Unblocking again will loose the current state and " - "might crash later. Aborting!\n"; + "Unblocking again will loose the current state and " + "might crash later. Aborting!\n"; abort(); //This is a serious error and can't be handled in any other sane way } #endif @@ -59,9 +59,9 @@ public: if (thread_support && !state.get()) { std::cerr << "ERROR: Trying to restore python thread state, " - "but no state is saved. Can't continue and also " - "can't raise an exception because the python " - "interpreter might be non-function. Aborting!\n"; + "but no state is saved. Can't continue and also " + "can't raise an exception because the python " + "interpreter might be non-function. Aborting!\n"; abort(); } #endif diff --git a/bindings/python/python_optional.hpp b/bindings/python/python_optional.hpp index da3279f2f..7707f0053 100644 --- a/bindings/python/python_optional.hpp +++ b/bindings/python/python_optional.hpp @@ -102,8 +102,8 @@ struct python_optional : public boost::noncopyable /** This class works around a bug in boost python. - See http://osdir.com/ml/python.c++/2003-11/msg00158.html - */ + See http://osdir.com/ml/python.c++/2003-11/msg00158.html +*/ template class class_with_converter : public boost::python::class_ { @@ -131,8 +131,8 @@ public: self& def_readwrite_convert(char const* name, D const& d, char const* doc=0) { this->add_property(name, - boost::python::make_getter(d, boost::python::return_value_policy()), - boost::python::make_setter(d, boost::python::default_call_policies())); + boost::python::make_getter(d, boost::python::return_value_policy()), + boost::python::make_setter(d, boost::python::default_call_policies())); return *this; } }; diff --git a/plugins/input/occi/occi_featureset.cpp b/plugins/input/occi/occi_featureset.cpp index 1cf17a3aa..3a09200f3 100644 --- a/plugins/input/occi/occi_featureset.cpp +++ b/plugins/input/occi/occi_featureset.cpp @@ -373,7 +373,7 @@ void occi_featureset::convert_ordinates(mapnik::feature_ptr feature, if (! is_single_geom && elem_size > SDO_ELEM_INFO_SIZE) { geometry_type* geom = new geometry_type(geom_type); - + for (int i = SDO_ELEM_INFO_SIZE; i < elem_size; i+=3) { int next_offset = elem_info[i]; diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp index f9c1af707..05c397892 100644 --- a/plugins/input/postgis/postgis_datasource.cpp +++ b/plugins/input/postgis/postgis_datasource.cpp @@ -681,22 +681,22 @@ box2d postgis_datasource::envelope() const shared_ptr rs = conn->executeQuery(s.str()); if (rs->next() && !rs->isNull(0)) { - double lox; - double loy; - double hix; - double hiy; - if (mapnik::conversions::string2double(rs->getValue(0),lox) && - mapnik::conversions::string2double(rs->getValue(1),loy) && - mapnik::conversions::string2double(rs->getValue(2),hix) && - mapnik::conversions::string2double(rs->getValue(3),hiy)) - { - extent_.init(lox,loy,hix,hiy); - extent_initialized_ = true; - } - else - { - std::clog << boost::format("Postgis Plugin: warning: could not determine extent from query: %s\n") % s.str() << std::endl; - } + double lox; + double loy; + double hix; + double hiy; + if (mapnik::conversions::string2double(rs->getValue(0),lox) && + mapnik::conversions::string2double(rs->getValue(1),loy) && + mapnik::conversions::string2double(rs->getValue(2),hix) && + mapnik::conversions::string2double(rs->getValue(3),hiy)) + { + extent_.init(lox,loy,hix,hiy); + extent_initialized_ = true; + } + else + { + std::clog << boost::format("Postgis Plugin: warning: could not determine extent from query: %s\n") % s.str() << std::endl; + } } rs->close(); } diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index 4ace58937..81677677b 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -103,12 +103,12 @@ void shape_io::read_polyline(mapnik::geometry_container & geom) { shape_file::record_type record(reclength_ * 2 - 36); shp_.read_record(record); - + int num_parts = record.read_ndr_integer(); int num_points = record.read_ndr_integer(); if (num_parts == 1) { - geometry_type* line = new geometry_type(mapnik::LineString); + geometry_type* line = new geometry_type(mapnik::LineString); record.skip(4); double x = record.read_double(); double y = record.read_double(); @@ -132,7 +132,7 @@ void shape_io::read_polyline(mapnik::geometry_container & geom) int start, end; for (int k = 0; k < num_parts; ++k) { - geometry_type* line = new geometry_type(mapnik::LineString); + geometry_type* line = new geometry_type(mapnik::LineString); start = parts[k]; if (k == num_parts - 1) { @@ -179,11 +179,11 @@ void shape_io::read_polygon(mapnik::geometry_container & geom) { shape_file::record_type record(reclength_ * 2 - 36); shp_.read_record(record); - + int num_parts = record.read_ndr_integer(); int num_points = record.read_ndr_integer(); std::vector parts(num_parts); - + for (int i = 0; i < num_parts; ++i) { parts[i] = record.read_ndr_integer(); From 5601731a89dee31c43b9bcfa9a447abffa66e833 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 13 Mar 2012 08:05:26 -0700 Subject: [PATCH 063/138] fix macro in conversions.cpp --- src/conversions.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/conversions.cpp b/src/conversions.cpp index 822b63263..d19272162 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -29,15 +29,15 @@ BOOST_SPIRIT_ASSERT_MATCH( \ boost::spirit::domain_::domain, name##_expr_type); \ BOOST_AUTO(name, boost::proto::deep_copy(expr)); \ - \ - \ + + namespace mapnik { namespace conversions { using namespace boost::spirit; -BOOST_SPIRIT_AUTO(qi, INTEGER, qi::int_); -BOOST_SPIRIT_AUTO(qi, FLOAT, qi::float_); -BOOST_SPIRIT_AUTO(qi, DOUBLE, qi::double_); +BOOST_SPIRIT_AUTO(qi, INTEGER, qi::int_) +BOOST_SPIRIT_AUTO(qi, FLOAT, qi::float_) +BOOST_SPIRIT_AUTO(qi, DOUBLE, qi::double_) bool string2int(const char * value, int & result) { From 9cbef6059593bfc23a72988c3aaa72bfd00d3b08 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 13 Mar 2012 08:22:34 -0700 Subject: [PATCH 064/138] pep8 formatting --- bindings/python/mapnik/__init__.py | 16 +-- bindings/python/mapnik/printing.py | 206 ++++++++++++++--------------- 2 files changed, 111 insertions(+), 111 deletions(-) diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py index 7d7a93d2c..5bd751629 100644 --- a/bindings/python/mapnik/__init__.py +++ b/bindings/python/mapnik/__init__.py @@ -120,7 +120,7 @@ class _Coord(Coord,_injector): Returns the easting (x) and northing (y) as a coordinate pair. - + Example: Project the geographic coordinates of the city center of Stuttgart into the local map projection (GK Zone 3/DHDN, EPSG 31467) @@ -136,7 +136,7 @@ class _Coord(Coord,_injector): into the geographic space. The x component is considered to be the easting, the y component to be the northing. - + Returns the longitude (x) and latitude (y) as a coordinate pair. @@ -153,8 +153,8 @@ class _Coord(Coord,_injector): class _Box2d(Box2d,_injector): """ Represents a spatial envelope (i.e. bounding box). - - + + Following operators are defined for Box2d: Addition: @@ -285,12 +285,12 @@ def Datasource(**keywords): Create a Mapnik Datasource using a dictionary of parameters. Keywords must include: - + type='plugin_name' # e.g. type='gdal' - + See the convenience factory methods of each input plugin for details on additional required keyword arguments. - + """ return CreateDatasource(keywords) @@ -322,7 +322,7 @@ def PostGIS(**keywords): Required keyword arguments: dbname -- database name to connect to table -- table name or subselect query - + *Note: if using subselects for the 'table' value consider also passing the 'geometry_field' and 'srid' and 'extent_from_subquery' options and/or specifying the 'geometry_table' option. diff --git a/bindings/python/mapnik/printing.py b/bindings/python/mapnik/printing.py index 5e6456bd9..8c15d8a8c 100644 --- a/bindings/python/mapnik/printing.py +++ b/bindings/python/mapnik/printing.py @@ -43,7 +43,7 @@ except ImportError: class centering: """Style of centering to use with the map, the default is constrained - + none: map will be placed flush with the margin/box in the top left corner constrained: map will be centered on the most constrained axis (for a portrait page and a square map this will be horizontally) @@ -167,7 +167,7 @@ def sequence_scale(scale,scale_sequence): """Default scale helper, this rounds scale to a 'sensible' value""" factor = math.floor(math.log10(scale)) norm = scale/(10**factor) - + for s in scale_sequence: if norm <= s: return s*10**factor @@ -199,7 +199,7 @@ def deg_min_sec_scale(scale): return x else: return x - + def format_deg_min_sec(value): deg = math.floor(value) min = math.floor((value-deg)/(1.0/60)) @@ -219,12 +219,12 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse opens the given multipage PDF and converts each page to be a layer in a single page PDF layer_names should be a sequence of the user visible names of the layers, if not given or if shorter than num pages generic names will be given to the unnamed layers - + if output_name is not provided a temporary file will be used for the conversion which will then be copied back over the source file. - + requires pyPdf >= 1.13 to be available""" - + if not HAS_PYPDF: raise Exception("pyPdf Not available") @@ -235,13 +235,13 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse else: (outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename)) outfile = os.fdopen(outfd,'wb') - + i = pyPdf.PdfFileReader(infile) o = pyPdf.PdfFileWriter() - + template_page_size = i.pages[0].mediaBox op = o.addBlankPage(width=template_page_size.getWidth(),height=template_page_size.getHeight()) - + contentkey = pyPdf.generic.NameObject('/Contents') resourcekey = pyPdf.generic.NameObject('/Resources') propertieskey = pyPdf.generic.NameObject('/Properties') @@ -249,7 +249,7 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse op[resourcekey] = pyPdf.generic.DictionaryObject() properties = pyPdf.generic.DictionaryObject() ocgs = pyPdf.generic.ArrayObject() - + for (i, p) in enumerate(i.pages): # first start an OCG for the layer ocgname = pyPdf.generic.NameObject('/oc%d' % i) @@ -262,9 +262,9 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse p[pyPdf.generic.NameObject('/Contents')].append(ocgend) else: p[pyPdf.generic.NameObject('/Contents')] = pyPdf.generic.ArrayObject((ocgstart,p['/Contents'],ocgend)) - + op.mergePage(p) - + ocg = pyPdf.generic.DictionaryObject() ocg[pyPdf.generic.NameObject('/Type')] = pyPdf.generic.NameObject('/OCG') if len(layer_names) > i: @@ -274,9 +274,9 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse indirect_ocg = o._addObject(ocg) properties[ocgname] = indirect_ocg ocgs.append(indirect_ocg) - + op[resourcekey][propertieskey] = o._addObject(properties) - + ocproperties = pyPdf.generic.DictionaryObject() ocproperties[pyPdf.generic.NameObject('/OCGs')] = ocgs defaultview = pyPdf.generic.DictionaryObject() @@ -289,16 +289,16 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse else: defaultview[pyPdf.generic.NameObject('/Order')] = pyPdf.generic.ArrayObject(reversed(ocgs)) defaultview[pyPdf.generic.NameObject('/OFF')] = pyPdf.generic.ArrayObject() - + ocproperties[pyPdf.generic.NameObject('/D')] = o._addObject(defaultview) - + o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = o._addObject(ocproperties) - + o.write(outfile) - + outfile.close() infile.close() - + if not output_name: os.rename(outfilename, filename) @@ -318,7 +318,7 @@ class PDFPrinter: is_latlon=False, use_ocg_layers=False): """Creates a cairo surface and context to render a PDF with. - + pagesize: tuple of page size in meters, see predefined sizes in pagessizes dict (default a4) margin: page margin in meters (default 0.01) box: box within the page to render the map into (will not render over margin). This should be @@ -348,54 +348,54 @@ class PDFPrinter: self._centering = centering self._is_latlon = is_latlon self._use_ocg_layers = use_ocg_layers - + self._s = None self._layer_names = [] self._filename = None - + self.map_box = None self.scale = None - + # don't both to round the scale if they are not preserving the aspect ratio if not preserve_aspect: self._scale = any_scale - + if percent_box: self._box = Box2d(percent_box[0]*pagesize[0],percent_box[1]*pagesize[1], percent_box[2]*pagesize[0],percent_box[3]*pagesize[1]) if not HAS_PYCAIRO_MODULE: raise Exception("PDF rendering only available when pycairo is available") - + self.font_name = "DejaVu Sans" - + def finish(self): if self._s: self._s.finish() self._s = None - + if self._use_ocg_layers: convert_pdf_pages_to_layers(self._filename,layer_names=self._layer_names + ["Legend and Information"],reverse_all_but_last=True) - + def add_geospatial_pdf_header(self,m,filename,epsg=None,wkt=None): """ Postprocessing step to add geospatial PDF information to PDF file as per PDF standard 1.7 extension level 3 (also in draft PDF v2 standard at time of writing) - + one of either the epsg code or wkt text for the projection must be provided - + Should be called *after* the page has had .finish() called""" if HAS_PYPDF and (epsg or wkt): infile=file(filename,'rb') (outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename)) outfile = os.fdopen(outfd,'wb') - + i=pyPdf.PdfFileReader(infile) o=pyPdf.PdfFileWriter() - + # preserve OCProperties at document root if we have one if i.trailer['/Root'].has_key(pyPdf.generic.NameObject('/OCProperties')): o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = i.trailer['/Root'].getObject()[pyPdf.generic.NameObject('/OCProperties')] - + for p in i.pages: gcs = pyPdf.generic.DictionaryObject() gcs[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/PROJCS') @@ -403,7 +403,7 @@ class PDFPrinter: gcs[pyPdf.generic.NameObject('/EPSG')]=pyPdf.generic.NumberObject(int(epsg)) if wkt: gcs[pyPdf.generic.NameObject('/WKT')]=pyPdf.generic.TextStringObject(wkt) - + measure = pyPdf.generic.DictionaryObject() measure[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Measure') measure[pyPdf.generic.NameObject('/Subtype')]=pyPdf.generic.NameObject('/GEO') @@ -414,7 +414,7 @@ class PDFPrinter: measure[pyPdf.generic.NameObject('/Bounds')]=bounds measure[pyPdf.generic.NameObject('/LPTS')]=bounds gpts=pyPdf.generic.ArrayObject() - + proj=Projection(m.srs) env=m.envelope() for x in ((env.minx, env.miny), (env.minx, env.maxy), (env.maxx, env.maxy), (env.maxx, env.miny)): @@ -423,31 +423,31 @@ class PDFPrinter: gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.y))) gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.x))) measure[pyPdf.generic.NameObject('/GPTS')]=gpts - + vp=pyPdf.generic.DictionaryObject() vp[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Viewport') bbox=pyPdf.generic.ArrayObject() - + for x in self.map_box: bbox.append(pyPdf.generic.FloatObject(str(x))) vp[pyPdf.generic.NameObject('/BBox')]=bbox vp[pyPdf.generic.NameObject('/Measure')]=measure - + vpa = pyPdf.generic.ArrayObject() vpa.append(vp) p[pyPdf.generic.NameObject('/VP')]=vpa o.addPage(p) - + o.write(outfile) infile=None outfile.close() os.rename(outfilename,filename) - - + + def get_context(self): """allow access so that extra 'bits' can be rendered to the page directly""" return cairo.Context(self._s) - + def get_width(self): return self._pagesize[0] @@ -456,7 +456,7 @@ class PDFPrinter: def get_margin(self): return self._margin - + def write_text(self,ctx,text,box_width=None,size=10, fill_color=(0.0, 0.0, 0.0), alignment=None): if HAS_PANGOCAIRO_MODULE: (attr,t,accel) = pango.parse_markup(text) @@ -474,7 +474,7 @@ class PDFPrinter: pctx.set_source_rgb(*fill_color) pctx.show_layout(l) return l.get_pixel_extents()[0] - + else: ctx.rel_move_to(0,size) ctx.select_font_face(self.font_name, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) @@ -489,18 +489,18 @@ class PDFPrinter: elif HAS_PYCAIRO_MODULE: return cairo.Context(self._s) return None - + def _get_render_area(self): """return a bounding box with the area of the page we are allowed to render out map to in page coordinates (i.e. meters) """ # take off our page margins render_area = Box2d(self._margin,self._margin,self._pagesize[0]-self._margin,self._pagesize[1]-self._margin) - + #then if user specified a box to render get intersection with that if self._box: return render_area.intersect(self._box) - + return render_area def _get_render_area_size(self): @@ -513,7 +513,7 @@ class PDFPrinter: available_area = self._get_render_area_size() map_aspect = m.envelope().width()/m.envelope().height() page_aspect = available_area[0]/available_area[1] - + return map_aspect > page_aspect def _get_meta_info_corner(self,render_size,m): @@ -526,7 +526,7 @@ class PDFPrinter: else: x += render_size[0]+0.005 y = self._margin - + return (x,y) def _get_render_corner(self,render_size,m): @@ -535,9 +535,9 @@ class PDFPrinter: x=available_area[0] y=available_area[1] - + h_is_contrained = self._is_h_contrained(m) - + if (self._centering == centering.both or self._centering == centering.horizontal or (self._centering == centering.constrained and h_is_contrained) or @@ -550,26 +550,26 @@ class PDFPrinter: (self._centering == centering.unconstrained and h_is_contrained)): y+=(available_area.height()-render_size[1])/2 return (x,y) - + def _get_map_pixel_size(self, width_page_m, height_page_m): """for a given map size in paper coordinates return a tuple of the map 'pixel' size we should create at the defined resolution""" return (int(m2px(width_page_m,self._resolution)), int(m2px(height_page_m,self._resolution))) - + def render_map(self,m, filename): """Render the given map to filename""" - + # store this for later so we can post process the PDF self._filename = filename - + # work out the best scale to render out map at given the available space (eff_width,eff_height) = self._get_render_area_size() map_aspect = m.envelope().width()/m.envelope().height() page_aspect = eff_width/eff_height - + scalex=m.envelope().width()/eff_width scaley=m.envelope().height()/eff_height - + scale=max(scalex,scaley) rounded_mapscale=self._scale(scale) @@ -581,26 +581,26 @@ class PDFPrinter: maph=mapw*(1/map_aspect) else: mapw=maph*map_aspect - + # set the map size so that raster elements render at the correct resolution m.resize(*self._get_map_pixel_size(mapw,maph)) # calculate the translation for the map starting point (tx,ty) = self._get_render_corner((mapw,maph),m) - + # create our cairo surface and context and then render the map into it self._s = cairo.PDFSurface(filename, m2pt(self._pagesize[0]),m2pt(self._pagesize[1])) ctx=cairo.Context(self._s) - + for l in m.layers: # extract the layer names for naming layers if we use OCG self._layer_names.append(l.name) - + layer_map = Map(m.width,m.height,m.srs) layer_map.layers.append(l) for s in l.styles: layer_map.append_style(s,m.find_style(s)) layer_map.zoom_to_box(m.envelope()) - + def render_map(): ctx.save() ctx.translate(m2pt(tx),m2pt(ty)) @@ -608,7 +608,7 @@ class PDFPrinter: ctx.scale(72.0/self._resolution,72.0/self._resolution) render(layer_map, ctx) ctx.restore() - + # antimeridian render_map() if self._is_latlon and (m.envelope().minx < -180 or m.envelope().maxx > 180): @@ -621,10 +621,10 @@ class PDFPrinter: render_map() # restore the original env m.zoom_to_box(old_env) - + if self._use_ocg_layers: self._s.show_page() - + self.scale = rounded_mapscale self.map_box = Box2d(tx,ty,tx+mapw,ty+maph) @@ -640,7 +640,7 @@ class PDFPrinter: if p2.inverse(m.envelope().center()).y > latlon_bounds.maxy: latlon_bounds = Box2d(latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.maxx,latlon_bounds.miny+360) - + latlon_mapwidth = latlon_bounds.width() # render an extra 20% so we generally won't miss the ends of lines latlon_buffer = 0.2*latlon_mapwidth @@ -649,7 +649,7 @@ class PDFPrinter: else: latlon_divsize = deg_min_sec_scale(latlon_mapwidth/7.0) latlon_interpsize = latlon_mapwidth/m.width - + self._render_lat_lon_axis(m,p2,latlon_bounds.minx,latlon_bounds.maxx,latlon_bounds.miny,latlon_bounds.maxy,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,True) self._render_lat_lon_axis(m,p2,latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.minx,latlon_bounds.maxx,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,False) @@ -658,21 +658,21 @@ class PDFPrinter: ctx.set_source_rgb(1,0,0) ctx.set_line_width(1) latlon_labelsize = 6 - + ctx.translate(m2pt(self.map_box.minx),m2pt(self.map_box.miny)) ctx.rectangle(0,0,m2pt(self.map_box.width()),m2pt(self.map_box.height())) ctx.clip() - + ctx.select_font_face("DejaVu", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) ctx.set_font_size(latlon_labelsize) - + box_top = self.map_box.height() if not is_x_axis: ctx.translate(m2pt(self.map_box.width()/2),m2pt(self.map_box.height()/2)) ctx.rotate(-math.pi/2) ctx.translate(-m2pt(self.map_box.height()/2),-m2pt(self.map_box.width()/2)) box_top = self.map_box.width() - + for xvalue in round_grid_generator(x1 - latlon_buffer,x2 + latlon_buffer,latlon_divsize): yvalue = y1 - latlon_buffer start_cross = None @@ -693,12 +693,12 @@ class PDFPrinter: ctx.move_to(start.x,start.y) ctx.line_to(end.x,end.y) ctx.stroke() - + if cmp(start.y, 0) != cmp(end.y,0): start_cross = end.x if cmp(start.y,m2pt(self.map_box.height())) != cmp(end.y, m2pt(self.map_box.height())): end_cross = end.x - + if dec_degrees: line_text = "%g" % (xvalue) else: @@ -712,19 +712,19 @@ class PDFPrinter: def render_on_map_scale(self,m): (div_size,page_div_size) = self._get_sensible_scalebar_size(m) - + first_value_x = (math.floor(m.envelope().minx / div_size) + 1) * div_size first_value_x_percent = (first_value_x-m.envelope().minx)/m.envelope().width() self._render_scale_axis(first_value_x,first_value_x_percent,self.map_box.minx,self.map_box.maxx,page_div_size,div_size,self.map_box.miny,self.map_box.maxy,True) - + first_value_y = (math.floor(m.envelope().miny / div_size) + 1) * div_size first_value_y_percent = (first_value_y-m.envelope().miny)/m.envelope().height() self._render_scale_axis(first_value_y,first_value_y_percent,self.map_box.miny,self.map_box.maxy,page_div_size,div_size,self.map_box.minx,self.map_box.maxx,False) - + if self._use_ocg_layers: self._s.show_page() self._layer_names.append("Coordinate Grid Overlay") - + def _get_sensible_scalebar_size(self,m,width=-1): # aim for about 8 divisions across the map # also make sure we can fit the bar with in page area width if specified @@ -744,7 +744,7 @@ class PDFPrinter: ctx.set_source_rgb(*stroke_color) ctx.rectangle(x,y,w,h) ctx.stroke() - + if text: ctx.move_to(x+1,y) self.write_text(ctx,text,fill_color=[1-z for z in fill_color],size=h-2) @@ -758,14 +758,14 @@ class PDFPrinter: label_value = first-div_size if self._is_latlon and label_value < -180: label_value += 360 - + ctx=cairo.Context(self._s) - + if not is_x_axis: ctx.translate(m2pt(self.map_box.center().x),m2pt(self.map_box.center().y)) ctx.rotate(-math.pi/2) ctx.translate(-m2pt(self.map_box.center().y),-m2pt(self.map_box.center().x)) - + while value < end: ctx.move_to(m2pt(value),m2pt(boundary_start)) ctx.line_to(m2pt(value),m2pt(boundary_end)) @@ -775,7 +775,7 @@ class PDFPrinter: for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)): self._render_box(ctx,m2pt(prev),bar,m2pt(value-prev),border_size,text,fill_color=fill) - + prev = value value+=page_div_size fill = [1-z for z in fill] @@ -787,18 +787,18 @@ class PDFPrinter: for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)): self._render_box(ctx,m2pt(prev),bar,m2pt(end-prev),border_size,fill_color=fill) - + def render_scale(self,m,ctx=None,width=0.05): """ m: map to render scale for ctx: A cairo context to render the scale to. If this is None (the default) then automatically create a context and choose the best location for the scale bar. width: Width of area available to render scale bar in (in m) - + will return the size of the rendered scale block in pts """ - + (w,h) = (0,0) - + # don't render scale if we are lat lon # dont report scale if we have warped the aspect ratio if self._preserve_aspect and not self._is_latlon: @@ -808,15 +808,15 @@ class PDFPrinter: ctx=cairo.Context(self._s) (tx,ty) = self._get_meta_info_corner((self.map_box.width(),self.map_box.height()),m) ctx.translate(tx,ty) - + (div_size,page_div_size) = self._get_sensible_scalebar_size(m, width/box_count) - + div_unit = "m" if div_size > 1000: div_size /= 1000 div_unit = "km" - + text = "0%s" % div_unit ctx.save() if width > 0: @@ -846,7 +846,7 @@ class PDFPrinter: text_ext=self.write_text(ctx,"Scale 1:%d" % self.scale,box_width=box_width,size=font_size, alignment=alignment) h+=text_ext[3]+2 - + return (w,h) def render_legend(self,m, page_break=False, ctx=None, collumns=1,width=None, height=None, item_per_rule=False, attribution={}, legend_item_box_size=(0.015,0.0075)): @@ -858,7 +858,7 @@ class PDFPrinter: collumns: number of collumns available in legend box attribution: additional text that will be rendered in gray under the layer name. keyed by layer name legend_item_box_size: two tuple with width and height of legend item box size in meters - + will return the size of the rendered block in pts """ @@ -879,7 +879,7 @@ class PDFPrinter: else: cwidth = None current_collumn = 0 - + processed_layers = [] for l in reversed(m.layers): have_layer_header = False @@ -888,7 +888,7 @@ class PDFPrinter: if layer_title in processed_layers: continue processed_layers.append(layer_title) - + # check through the features to find which combinations of styles are active # for each unique combination add a legend entry for f in l.datasource.all_features(): @@ -913,20 +913,20 @@ class PDFPrinter: active_rules = tuple(active_rules) if added_styles.has_key(active_rules): continue - + added_styles[active_rules] = (f,rule_text) if not item_per_rule: break else: added_styles[l] = (None,None) - + legend_items = added_styles.keys() legend_items.sort() for li in legend_items: if True: (f,rule_text) = added_styles[li] - - + + legend_map_size = (int(m2pt(legend_item_box_size[0])),int(m2pt(legend_item_box_size[1]))) lemap=Map(legend_map_size[0],legend_map_size[1],srs=m.srs) if m.background: @@ -967,11 +967,11 @@ class PDFPrinter: for s in l.styles: lelayer.styles.append(s) lemap.layers.append(lelayer) - + if f is None or f.envelope().width() != 0: lemap.zoom_all() lemap.zoom(1.1) - + item_size = legend_map_size[1] if not have_layer_header: item_size += 8 @@ -998,7 +998,7 @@ class PDFPrinter: ctx.save() render(lemap, ctx) ctx.restore() - + ctx.rectangle(0,0,*legend_map_size) ctx.set_source_rgb(0.5,0.5,0.5) ctx.set_line_width(1) @@ -1017,12 +1017,12 @@ class PDFPrinter: if attribution.has_key(layer_title): e=self.write_text(ctx, attribution[layer_title], m2pt(cwidth-legend_item_box_size[0]-0.005), 6, fill_color=(0.5,0.5,0.5)) legend_text_size += e[3] - + if legend_text_size > legend_entry_size: legend_entry_size=legend_text_size - + y+=legend_entry_size +2 if y > h: h = y return (w,h) - + From 0c537ed9eef6d8e59172248c6c37549dc55a3f04 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 14 Mar 2012 14:55:14 +0000 Subject: [PATCH 065/138] + add: #include mapnik/config_error.hpp --- demo/viewer/mapwidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/demo/viewer/mapwidget.cpp b/demo/viewer/mapwidget.cpp index dadaba84c..103b4d9cd 100644 --- a/demo/viewer/mapwidget.cpp +++ b/demo/viewer/mapwidget.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include "mapwidget.hpp" #include "info_dialog.hpp" @@ -487,7 +488,7 @@ void MapWidget::updateMap() } catch (mapnik::config_error & ex) { - std::cerr << ex.what() << std::endl; + std::cerr << ex.what() << std::endl; } catch (...) { From 87b22c29b208a1414fffef83fa7a2cb0901cd27e Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 14 Mar 2012 15:01:31 +0000 Subject: [PATCH 066/138] + add optional polygon smoothing ( 0.0 < smooth < 1.0 ) using agg_conv_poly1_curve --- include/mapnik/polygon_symbolizer.hpp | 6 ++++-- src/agg/process_polygon_symbolizer.cpp | 29 ++++++++++++++++++++------ src/load_map.cpp | 5 ++++- src/polygon_symbolizer.cpp | 16 ++++++++++++-- src/save_map.cpp | 4 ++++ 5 files changed, 49 insertions(+), 11 deletions(-) diff --git a/include/mapnik/polygon_symbolizer.hpp b/include/mapnik/polygon_symbolizer.hpp index a4f8706d5..e7a2a85c7 100644 --- a/include/mapnik/polygon_symbolizer.hpp +++ b/include/mapnik/polygon_symbolizer.hpp @@ -35,7 +35,7 @@ namespace mapnik struct MAPNIK_DECL polygon_symbolizer : public symbolizer_base { polygon_symbolizer(); - polygon_symbolizer(color const& fill); + explicit polygon_symbolizer(color const& fill); color const& get_fill() const; void set_fill(color const& fill); void set_opacity(double opacity); @@ -44,12 +44,14 @@ struct MAPNIK_DECL polygon_symbolizer : public symbolizer_base double get_gamma() const; void set_gamma_method(gamma_method_e gamma_method); gamma_method_e get_gamma_method() const; - + void set_smooth(double smooth); + double smooth() const; private: color fill_; double opacity_; double gamma_; gamma_method_e gamma_method_; + double smooth_; }; } diff --git a/src/agg/process_polygon_symbolizer.cpp b/src/agg/process_polygon_symbolizer.cpp index a7187a444..bcd1a7431 100644 --- a/src/agg/process_polygon_symbolizer.cpp +++ b/src/agg/process_polygon_symbolizer.cpp @@ -35,6 +35,7 @@ // for polygon_symbolizer #include "agg_renderer_scanline.h" #include "agg_conv_clip_polygon.h" +#include "agg_conv_smooth_poly1.h" // stl #include @@ -45,11 +46,10 @@ void agg_renderer::process(polygon_symbolizer const& sym, mapnik::feature_ptr const& feature, proj_transform const& prj_trans) { - typedef agg::conv_clip_polygon clipped_geometry_type; - typedef coord_transform2 path_type; typedef agg::renderer_base ren_base; typedef agg::renderer_scanline_aa_solid renderer; + box2d query_extent = query_extent_ * 1.0; color const& fill_ = sym.get_fill(); agg::scanline_u8 sl; @@ -92,10 +92,27 @@ void agg_renderer::process(polygon_symbolizer const& sym, geometry_type & geom=feature->get_geometry(i); if (geom.num_points() > 2) { - clipped_geometry_type clipped(geom); - clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); - path_type path(t_,clipped,prj_trans); - ras_ptr->add_path(path); + if (sym.smooth() > 0.0) + { + typedef agg::conv_smooth_poly1_curve smooth_type; + typedef agg::conv_clip_polygon clipped_geometry_type; + typedef coord_transform2 path_type; + smooth_type smooth(geom); + smooth.smooth_value(sym.smooth()); + clipped_geometry_type clipped(smooth); + clipped.clip_box(query_extent.minx(),query_extent.miny(),query_extent.maxx(),query_extent.maxy()); + path_type path(t_,clipped,prj_trans); + ras_ptr->add_path(path); + } + else + { + typedef agg::conv_clip_polygon clipped_geometry_type; + typedef coord_transform2 path_type; + clipped_geometry_type clipped(geom); + clipped.clip_box(query_extent.minx(),query_extent.miny(),query_extent.maxx(),query_extent.maxy()); + path_type path(t_,clipped,prj_trans); + ras_ptr->add_path(path); + } //if (writer.first) writer.first->add_polygon(path, *feature, t_, writer.second); } } diff --git a/src/load_map.cpp b/src/load_map.cpp index 0b71ba838..92787c83e 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -1295,7 +1295,10 @@ void map_parser::parse_polygon_symbolizer( rule & rule, xml_node const & sym ) // gamma method optional gamma_method = sym.get_opt_attr("gamma-method"); if (gamma_method) poly_sym.set_gamma_method(*gamma_method); - + // smooth value + optional smooth = sym.get_opt_attr("smooth"); + if (smooth) poly_sym.set_smooth(*smooth); + parse_metawriter_in_symbolizer(poly_sym, sym); rule.append(poly_sym); } diff --git a/src/polygon_symbolizer.cpp b/src/polygon_symbolizer.cpp index 7009e586c..7c783a12d 100644 --- a/src/polygon_symbolizer.cpp +++ b/src/polygon_symbolizer.cpp @@ -32,14 +32,16 @@ polygon_symbolizer::polygon_symbolizer() fill_(color(128,128,128)), opacity_(1.0), gamma_(1.0), - gamma_method_(GAMMA_POWER) {} + gamma_method_(GAMMA_POWER), + smooth_(0.0) {} polygon_symbolizer::polygon_symbolizer(color const& fill) : symbolizer_base(), fill_(fill), opacity_(1.0), gamma_(1.0), - gamma_method_(GAMMA_POWER) {} + gamma_method_(GAMMA_POWER), + smooth_(0.0) {} color const& polygon_symbolizer::get_fill() const { @@ -81,4 +83,14 @@ gamma_method_e polygon_symbolizer::get_gamma_method() const return gamma_method_; } +void polygon_symbolizer::set_smooth(double smooth) +{ + smooth_ = smooth; +} + +double polygon_symbolizer::smooth() const +{ + return smooth_; +} + } diff --git a/src/save_map.cpp b/src/save_map.cpp index cec1faa75..d81508ad3 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -125,6 +125,10 @@ public: { set_attr( sym_node, "gamma-method", sym.get_gamma_method() ); } + if ( sym.smooth() != dfl.smooth() || explicit_defaults_ ) + { + set_attr( sym_node, "smooth", sym.smooth() ); + } add_metawriter_attributes(sym_node, sym); } From 108b99725cc9af484d0695e02be94895e7dbb4b2 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 14 Mar 2012 15:42:22 +0000 Subject: [PATCH 067/138] + refactor gamma setting logic to avoid code duplication ( agg_helpers.hpp ) --- include/mapnik/agg_helpers.hpp | 57 +++++++++++++++++++ src/agg/process_line_symbolizer.cpp | 37 +++++------- .../process_polygon_pattern_symbolizer.cpp | 24 +------- src/agg/process_polygon_symbolizer.cpp | 23 +------- 4 files changed, 76 insertions(+), 65 deletions(-) create mode 100644 include/mapnik/agg_helpers.hpp diff --git a/include/mapnik/agg_helpers.hpp b/include/mapnik/agg_helpers.hpp new file mode 100644 index 000000000..5b221c9aa --- /dev/null +++ b/include/mapnik/agg_helpers.hpp @@ -0,0 +1,57 @@ +/***************************************************************************** + * + * 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_AGG_HELPERS_HPP +#define MAPNIK_AGG_HELPERS_HPP + +#include "agg_gamma_functions.h" + +namespace mapnik { + +template +void set_gamma_method(T0 const& obj, T1 & ras_ptr) +{ + switch (obj.get_gamma_method()) + { + case GAMMA_POWER: + ras_ptr->gamma(agg::gamma_power(obj.get_gamma())); + break; + case GAMMA_LINEAR: + ras_ptr->gamma(agg::gamma_linear(0.0, obj.get_gamma())); + break; + case GAMMA_NONE: + ras_ptr->gamma(agg::gamma_none()); + break; + case GAMMA_THRESHOLD: + ras_ptr->gamma(agg::gamma_threshold(obj.get_gamma())); + break; + case GAMMA_MULTIPLY: + ras_ptr->gamma(agg::gamma_multiply(obj.get_gamma())); + break; + default: + ras_ptr->gamma(agg::gamma_power(obj.get_gamma())); + } +} + +} + +#endif //MAPNIK_AGG_HELPERS_HPP diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index 193e53f43..b4f37be67 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -23,6 +23,7 @@ // mapnik #include +#include #include #include @@ -71,7 +72,6 @@ void agg_renderer::process(line_symbolizer const& sym, typedef agg::rasterizer_outline_aa rasterizer_type; agg::line_profile_aa profile; - //agg::line_profile_aa profile(stroke_.get_width() * scale_factor_, agg::gamma_none()); profile.width(stroke_.get_width() * scale_factor_); ren_base base_ren(pixf); renderer_type ren(base_ren, profile); @@ -102,26 +102,10 @@ void agg_renderer::process(line_symbolizer const& sym, ren_base renb(pixf); renderer ren(renb); ras_ptr->reset(); - switch (stroke_.get_gamma_method()) - { - case GAMMA_POWER: - ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma())); - break; - case GAMMA_LINEAR: - ras_ptr->gamma(agg::gamma_linear(0.0, stroke_.get_gamma())); - break; - case GAMMA_NONE: - ras_ptr->gamma(agg::gamma_none()); - break; - case GAMMA_THRESHOLD: - ras_ptr->gamma(agg::gamma_threshold(stroke_.get_gamma())); - break; - case GAMMA_MULTIPLY: - ras_ptr->gamma(agg::gamma_multiply(stroke_.get_gamma())); - break; - default: - ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma())); - } + + set_gamma_method(stroke_, ras_ptr); + + //metawriter_with_properties writer = sym.get_metawriter(); for (unsigned i=0;inum_geometries();++i) @@ -129,12 +113,13 @@ void agg_renderer::process(line_symbolizer const& sym, geometry_type & geom = feature->get_geometry(i); if (geom.num_points() > 1) { - clipped_geometry_type clipped(geom); - clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); - path_type path(t_,clipped,prj_trans); if (stroke_.has_dash()) { + clipped_geometry_type clipped(geom); + clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); + path_type path(t_,clipped,prj_trans); + agg::conv_dash dash(path); dash_array const& d = stroke_.get_dash_array(); dash_array::const_iterator itr = d.begin(); @@ -172,6 +157,10 @@ void agg_renderer::process(line_symbolizer const& sym, } else { + clipped_geometry_type clipped(geom); + clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); + path_type path(t_,clipped,prj_trans); + agg::conv_stroke stroke(path); line_join_e join=stroke_.get_line_join(); if ( join == MITER_JOIN) diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp index 670fea9b6..1d6fbde1f 100644 --- a/src/agg/process_polygon_pattern_symbolizer.cpp +++ b/src/agg/process_polygon_pattern_symbolizer.cpp @@ -23,6 +23,7 @@ // mapnik #include +#include #include #include #include @@ -72,27 +73,8 @@ void agg_renderer::process(polygon_pattern_symbolizer const& sym, agg::scanline_u8 sl; ras_ptr->reset(); - switch (sym.get_gamma_method()) - { - case GAMMA_POWER: - ras_ptr->gamma(agg::gamma_power(sym.get_gamma())); - break; - case GAMMA_LINEAR: - ras_ptr->gamma(agg::gamma_linear(0.0, sym.get_gamma())); - break; - case GAMMA_NONE: - ras_ptr->gamma(agg::gamma_none()); - break; - case GAMMA_THRESHOLD: - ras_ptr->gamma(agg::gamma_threshold(sym.get_gamma())); - break; - case GAMMA_MULTIPLY: - ras_ptr->gamma(agg::gamma_multiply(sym.get_gamma())); - break; - default: - ras_ptr->gamma(agg::gamma_power(sym.get_gamma())); - } - + set_gamma_method(sym,ras_ptr); + std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); boost::optional marker; if ( !filename.empty() ) diff --git a/src/agg/process_polygon_symbolizer.cpp b/src/agg/process_polygon_symbolizer.cpp index bcd1a7431..5baa68642 100644 --- a/src/agg/process_polygon_symbolizer.cpp +++ b/src/agg/process_polygon_symbolizer.cpp @@ -23,6 +23,7 @@ // mapnik #include +#include #include #include @@ -65,27 +66,9 @@ void agg_renderer::process(polygon_symbolizer const& sym, renderer ren(renb); ras_ptr->reset(); - switch (sym.get_gamma_method()) - { - case GAMMA_POWER: - ras_ptr->gamma(agg::gamma_power(sym.get_gamma())); - break; - case GAMMA_LINEAR: - ras_ptr->gamma(agg::gamma_linear(0.0, sym.get_gamma())); - break; - case GAMMA_NONE: - ras_ptr->gamma(agg::gamma_none()); - break; - case GAMMA_THRESHOLD: - ras_ptr->gamma(agg::gamma_threshold(sym.get_gamma())); - break; - case GAMMA_MULTIPLY: - ras_ptr->gamma(agg::gamma_multiply(sym.get_gamma())); - break; - default: - ras_ptr->gamma(agg::gamma_power(sym.get_gamma())); - } + set_gamma_method(sym,ras_ptr); + //metawriter_with_properties writer = sym.get_metawriter(); for (unsigned i=0;inum_geometries();++i) { From 07d4e45521ab17ec6cbba21ca0ce065de3187b9c Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 14 Mar 2012 08:56:07 -0700 Subject: [PATCH 068/138] fix compile with boost 1.42-1.44 after 2b68cea0a10 --- include/mapnik/xml_tree.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index a27a7e78a..27893d262 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -25,7 +25,15 @@ //mapnik #include #include + +// boost +#include + +#if BOOST_VERSION >= 104500 #include +#else +#include +#endif //stl #include From 81ab02cc723069533f306ef63b6d747b8d6cadbc Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 14 Mar 2012 08:56:59 -0700 Subject: [PATCH 069/138] fix failing test 'bgcolor_broken.xml' when compiled against boost 1.42 --- src/color.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/color.cpp b/src/color.cpp index 480b6b9d2..80464ccbb 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -166,6 +166,7 @@ bool color_factory::parse_from_string(color & c, std::string const& css_color, c.set_alpha(css_.a); return true; } + return false; #endif } From 8e0ed96756cfbed152ca271296c5de7770d91b73 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 14 Mar 2012 09:12:26 -0700 Subject: [PATCH 070/138] fix whitespace --- include/mapnik/agg_helpers.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mapnik/agg_helpers.hpp b/include/mapnik/agg_helpers.hpp index 5b221c9aa..2113db113 100644 --- a/include/mapnik/agg_helpers.hpp +++ b/include/mapnik/agg_helpers.hpp @@ -50,8 +50,8 @@ void set_gamma_method(T0 const& obj, T1 & ras_ptr) default: ras_ptr->gamma(agg::gamma_power(obj.get_gamma())); } -} +} } -#endif //MAPNIK_AGG_HELPERS_HPP +#endif //MAPNIK_AGG_HELPERS_HPP From f1a088762851f9fbd95a736e90c980b3f6680c21 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 14 Mar 2012 16:12:36 +0000 Subject: [PATCH 071/138] + apply smooth converter after clipping and transformations + inflate query_extent --- src/agg/process_polygon_symbolizer.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/agg/process_polygon_symbolizer.cpp b/src/agg/process_polygon_symbolizer.cpp index 5baa68642..2b532fb9f 100644 --- a/src/agg/process_polygon_symbolizer.cpp +++ b/src/agg/process_polygon_symbolizer.cpp @@ -50,7 +50,6 @@ void agg_renderer::process(polygon_symbolizer const& sym, typedef agg::renderer_base ren_base; typedef agg::renderer_scanline_aa_solid renderer; - box2d query_extent = query_extent_ * 1.0; color const& fill_ = sym.get_fill(); agg::scanline_u8 sl; @@ -70,6 +69,7 @@ void agg_renderer::process(polygon_symbolizer const& sym, set_gamma_method(sym,ras_ptr); //metawriter_with_properties writer = sym.get_metawriter(); + box2d inflated_extent = query_extent_ * 1.1; for (unsigned i=0;inum_geometries();++i) { geometry_type & geom=feature->get_geometry(i); @@ -77,22 +77,22 @@ void agg_renderer::process(polygon_symbolizer const& sym, { if (sym.smooth() > 0.0) { - typedef agg::conv_smooth_poly1_curve smooth_type; - typedef agg::conv_clip_polygon clipped_geometry_type; + typedef agg::conv_clip_polygon clipped_geometry_type; typedef coord_transform2 path_type; - smooth_type smooth(geom); - smooth.smooth_value(sym.smooth()); - clipped_geometry_type clipped(smooth); - clipped.clip_box(query_extent.minx(),query_extent.miny(),query_extent.maxx(),query_extent.maxy()); + typedef agg::conv_smooth_poly1_curve smooth_type; + clipped_geometry_type clipped(geom); + clipped.clip_box(inflated_extent.minx(),inflated_extent.miny(),inflated_extent.maxx(),inflated_extent.maxy()); path_type path(t_,clipped,prj_trans); - ras_ptr->add_path(path); + smooth_type smooth(path); + smooth.smooth_value(sym.smooth()); + ras_ptr->add_path(smooth); } else { typedef agg::conv_clip_polygon clipped_geometry_type; typedef coord_transform2 path_type; clipped_geometry_type clipped(geom); - clipped.clip_box(query_extent.minx(),query_extent.miny(),query_extent.maxx(),query_extent.maxy()); + clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); ras_ptr->add_path(path); } From 72baf5924729d7425ac7fb06e05d767aeef386e4 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 14 Mar 2012 16:51:07 +0000 Subject: [PATCH 072/138] + add smooth property + update help strings --- bindings/python/mapnik_polygon_symbolizer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bindings/python/mapnik_polygon_symbolizer.cpp b/bindings/python/mapnik_polygon_symbolizer.cpp index 4b4fb1b1a..dd809ac5d 100644 --- a/bindings/python/mapnik_polygon_symbolizer.cpp +++ b/bindings/python/mapnik_polygon_symbolizer.cpp @@ -84,7 +84,11 @@ void export_polygon_symbolizer() .add_property("gamma_method", &polygon_symbolizer::get_gamma_method, &polygon_symbolizer::set_gamma_method, - "Set/get the gamma correction method of the polygon") + "gamma correction method") + .add_property("smooth", + &polygon_symbolizer::smooth, + &polygon_symbolizer::set_smooth, + "smooth value (0..1.0)") ; } From d85556840027aea37df9facd9cd0ba564d6b011f Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 14 Mar 2012 17:06:23 +0000 Subject: [PATCH 073/138] + use smooth=1.0 for water polygons --- demo/python/rundemo.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/demo/python/rundemo.py b/demo/python/rundemo.py index 0fda7526d..bd9639a4b 100644 --- a/demo/python/rundemo.py +++ b/demo/python/rundemo.py @@ -138,7 +138,9 @@ qcdrain_lyr.datasource = mapnik.Shapefile(file='../data/qcdrainage') qcdrain_style = mapnik.Style() qcdrain_rule = mapnik.Rule() qcdrain_rule.filter = mapnik.Expression('[HYC] = 8') -qcdrain_rule.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(153, 204, 255))) +sym = mapnik.PolygonSymbolizer(mapnik.Color(153, 204, 255)) +sym.smooth = 1.0 # very smooth +qcdrain_rule.symbols.append(sym) qcdrain_style.rules.append(qcdrain_rule) m.append_style('drainage', qcdrain_style) From 3e4733c51a5a621686e386d0fa85fc8f7fc57828 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 14 Mar 2012 17:21:04 +0000 Subject: [PATCH 074/138] + refactor join/cap settings (agg_helper.hpp) --- include/mapnik/agg_helpers.hpp | 34 ++++++++++++++++++++++ src/agg/process_line_symbolizer.cpp | 44 ++--------------------------- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/include/mapnik/agg_helpers.hpp b/include/mapnik/agg_helpers.hpp index 2113db113..aa13729d4 100644 --- a/include/mapnik/agg_helpers.hpp +++ b/include/mapnik/agg_helpers.hpp @@ -24,6 +24,7 @@ #define MAPNIK_AGG_HELPERS_HPP #include "agg_gamma_functions.h" +#include "agg_math_stroke.h" namespace mapnik { @@ -52,6 +53,39 @@ void set_gamma_method(T0 const& obj, T1 & ras_ptr) } } +template +void set_join_caps(Stroke const& stroke_, PathType & stroke) +{ + line_join_e join=stroke_.get_line_join(); + switch (join) + { + case MITER_JOIN: + stroke.generator().line_join(agg::miter_join); + break; + case MITER_REVERT_JOIN: + stroke.generator().line_join(agg::miter_join); + break; + case ROUND_JOIN: + stroke.generator().line_join(agg::round_join); + break; + default: + stroke.generator().line_join(agg::bevel_join); + } + + line_cap_e cap=stroke_.get_line_cap(); + switch (cap) + { + case BUTT_CAP: + stroke.generator().line_cap(agg::butt_cap); + break; + case SQUARE_CAP: + stroke.generator().line_cap(agg::square_cap); + break; + default: + stroke.generator().line_cap(agg::round_cap); + } +} + } #endif //MAPNIK_AGG_HELPERS_HPP diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index b4f37be67..cc00d2f2e 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -113,7 +113,6 @@ void agg_renderer::process(line_symbolizer const& sym, geometry_type & geom = feature->get_geometry(i); if (geom.num_points() > 1) { - if (stroke_.has_dash()) { clipped_geometry_type clipped(geom); @@ -129,27 +128,8 @@ void agg_renderer::process(line_symbolizer const& sym, dash.add_dash(itr->first * scale_factor_, itr->second * scale_factor_); } - agg::conv_stroke > stroke(dash); - - line_join_e join=stroke_.get_line_join(); - if ( join == MITER_JOIN) - stroke.generator().line_join(agg::miter_join); - else if( join == MITER_REVERT_JOIN) - stroke.generator().line_join(agg::miter_join); - else if( join == ROUND_JOIN) - stroke.generator().line_join(agg::round_join); - else - stroke.generator().line_join(agg::bevel_join); - - line_cap_e cap=stroke_.get_line_cap(); - if (cap == BUTT_CAP) - stroke.generator().line_cap(agg::butt_cap); - else if (cap == SQUARE_CAP) - stroke.generator().line_cap(agg::square_cap); - else - stroke.generator().line_cap(agg::round_cap); - + set_join_caps(stroke_,stroke); stroke.generator().miter_limit(4.0); stroke.generator().width(stroke_.get_width() * scale_factor_); ras_ptr->add_path(stroke); @@ -160,26 +140,8 @@ void agg_renderer::process(line_symbolizer const& sym, clipped_geometry_type clipped(geom); clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); path_type path(t_,clipped,prj_trans); - - agg::conv_stroke stroke(path); - line_join_e join=stroke_.get_line_join(); - if ( join == MITER_JOIN) - stroke.generator().line_join(agg::miter_join); - else if( join == MITER_REVERT_JOIN) - stroke.generator().line_join(agg::miter_join); - else if( join == ROUND_JOIN) - stroke.generator().line_join(agg::round_join); - else - stroke.generator().line_join(agg::bevel_join); - - line_cap_e cap=stroke_.get_line_cap(); - if (cap == BUTT_CAP) - stroke.generator().line_cap(agg::butt_cap); - else if (cap == SQUARE_CAP) - stroke.generator().line_cap(agg::square_cap); - else - stroke.generator().line_cap(agg::round_cap); - + agg::conv_stroke stroke(path); + set_join_caps(stroke_,stroke); stroke.generator().miter_limit(4.0); stroke.generator().width(stroke_.get_width() * scale_factor_); ras_ptr->add_path(stroke); From f0bc1064c6c0ba6da1e9f5f4495126ad59fed4fa Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 14 Mar 2012 17:38:27 +0000 Subject: [PATCH 075/138] + supprt polygon smoothing in cairo backend --- src/cairo_renderer.cpp | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index c900491a6..7f10d8cba 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -53,6 +53,7 @@ // agg #include "agg_conv_clip_polyline.h" #include "agg_conv_clip_polygon.h" +#include "agg_conv_smooth_poly1.h" // stl #ifdef MAPNIK_DEBUG @@ -725,23 +726,37 @@ void cairo_renderer_base::start_map_processing(Map const& map) proj_transform const& prj_trans) { - typedef agg::conv_clip_polygon clipped_geometry_type; - typedef coord_transform2 path_type; - cairo_context context(context_); - context.set_color(sym.get_fill(), sym.get_opacity()); - + box2d inflated_extent = query_extent_ * 1.1; for (unsigned i = 0; i < feature->num_geometries(); ++i) { geometry_type & geom = feature->get_geometry(i); if (geom.num_points() > 2) { - clipped_geometry_type clipped(geom); - clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); - path_type path(t_,clipped,prj_trans); - context.add_path(path); - context.fill(); + if (sym.smooth() > 0.0) + { + typedef agg::conv_clip_polygon clipped_geometry_type; + typedef coord_transform2 path_type; + typedef agg::conv_smooth_poly1_curve smooth_type; + clipped_geometry_type clipped(geom); + clipped.clip_box(inflated_extent.minx(),inflated_extent.miny(),inflated_extent.maxx(),inflated_extent.maxy()); + path_type path(t_,clipped,prj_trans); + smooth_type smooth(path); + smooth.smooth_value(sym.smooth()); + context.add_agg_path(smooth); + context.fill(); + } + else + { + typedef agg::conv_clip_polygon clipped_geometry_type; + typedef coord_transform2 path_type; + clipped_geometry_type clipped(geom); + clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); + path_type path(t_,clipped,prj_trans); + context.add_path(path); + context.fill(); + } } } } From 78b53b4afea38b14f227372196f82d7411ee6a70 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 14 Mar 2012 15:33:55 -0700 Subject: [PATCH 076/138] rename dtd --- utils/xml/{mapnik2.dtd => mapnik.dtd} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename utils/xml/{mapnik2.dtd => mapnik.dtd} (100%) diff --git a/utils/xml/mapnik2.dtd b/utils/xml/mapnik.dtd similarity index 100% rename from utils/xml/mapnik2.dtd rename to utils/xml/mapnik.dtd From 74452f8ed78fec54831e11065432dfdb19d0ca5f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 14 Mar 2012 15:35:16 -0700 Subject: [PATCH 077/138] remove explicit exports in python using __all__ - way more trouble than it is worth --- bindings/python/mapnik/__init__.py | 110 ----------------------------- 1 file changed, 110 deletions(-) diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py index 5bd751629..11129f80a 100644 --- a/bindings/python/mapnik/__init__.py +++ b/bindings/python/mapnik/__init__.py @@ -598,113 +598,3 @@ def register_fonts(path=fontscollectionpath,valid_extensions=['.ttf','.otf','.tt # auto-register known plugins and fonts register_plugins() register_fonts() - -# Explicitly export API members to avoid namespace pollution -# and ensure correct documentation processing -__all__ = [ - # classes - 'CharProperties', - 'Color', - 'Coord', - 'Palette', - #'ColorBand', - 'CompositeOp', - 'DatasourceCache', - 'MemoryDatasource', - 'Box2d', - 'Feature', - 'Featureset', - 'FontEngine', - 'FontSet', - 'FormattingNode', - 'FormattingText', - 'FormattingFormat', - 'FormattingList', - 'FormattingExpressionFormat', - 'Geometry2d', - 'Image', - 'ImageView', - 'Grid', - 'GridView', - 'Layer', - 'Layers', - 'LinePatternSymbolizer', - 'LineSymbolizer', - 'Map', - 'MarkersSymbolizer', - 'Names', - 'Path', - 'Parameter', - 'Parameters', - 'PointSymbolizer', - 'PolygonPatternSymbolizer', - 'PolygonSymbolizer', - 'ProcessedText', - 'ProjTransform', - 'Projection', - 'Query', - 'RasterSymbolizer', - 'RasterColorizer', - 'Rule', 'Rules', - 'ShieldSymbolizer', - 'Singleton', - 'Stroke', - 'Style', - 'Symbolizer', - 'Symbolizers', - 'TextPlacements', - 'TextPlacementInfo', - 'TextSymbolizer', - 'TextSymbolizerProperties', - 'ViewTransform', - # enums - 'aspect_fix_mode', - 'point_placement', - 'label_placement', - 'line_cap', - 'line_join', - 'text_transform', - 'vertical_alignment', - 'horizontal_alignment', - 'justify_alignment', - 'pattern_alignment', - 'filter_mode', - # functions - # datasources - 'Datasource', - 'CreateDatasource', - 'Shapefile', - 'PostGIS', - 'Raster', - 'Gdal', - 'Occi', - 'Ogr', - 'SQLite', - 'Osm', - 'Kismet', - 'Geos', - # version and environment - 'mapnik_version_string', - 'mapnik_version', - 'has_cairo', - 'has_pycairo', - # factory methods - 'Expression', - 'PathExpression', - # load/save/render - 'load_map', - 'load_map_from_string', - 'save_map', - 'save_map_to_string', - 'render', - 'render_grid', - 'render_tile_to_file', - 'render_to_file', - # other - 'register_plugins', - 'register_fonts', - 'scale_denominator', - # deprecated - 'Filter', - 'Envelope', - ] From 2abe02bd96104988ea76869d1203aa270cf9a68c Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 14 Mar 2012 17:26:50 -0700 Subject: [PATCH 078/138] make available MAPNIK_VERSION_STRING in c++ header (not just in python) and add MAPNIK_VERSION_IS_RELEASE define that indicates if the code is released --- SConstruct | 17 ++++++----------- bindings/python/mapnik/__init__.py | 7 ------- bindings/python/mapnik_python.cpp | 6 ++++++ include/mapnik/version.hpp | 24 +++++++++++++++++++++++- src/build.py | 4 ++-- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/SConstruct b/SConstruct index 5b10da417..71f04991d 100644 --- a/SConstruct +++ b/SConstruct @@ -768,7 +768,7 @@ def GetMapnikLibVersion(context): int main() { - std::cout << MAPNIK_VERSION << std::endl; + std::cout << MAPNIK_VERSION_STRING << std::endl; return 0; } @@ -778,11 +778,7 @@ int main() context.Result(ret[0]) if not ret[1]: return [] - version = int(ret[1].strip()) - patch_level = version % 100 - minor_version = version / 100 % 1000 - major_version = version / 100000 - return [major_version,minor_version,patch_level] + return ret[1].strip() def icu_at_least_four_two(context): ret = context.TryRun(""" @@ -1382,14 +1378,13 @@ if not preconfigured: # fetch the mapnik version header in order to set the # ABI version used to build libmapnik.so on linux in src/build.py abi = conf.GetMapnikLibVersion() - abi_fallback = [2,0,0] + abi_fallback = "2.0.1-pre" if not abi: color_print(1,'Problem encountered parsing mapnik version, falling back to %s' % abi_fallback) - env['ABI_VERSION'] = abi_fallback - else: - env['ABI_VERSION'] = abi - env['MAPNIK_VERSION_STRING'] = '.'.join(['%d' % i for i in env['ABI_VERSION']]) + abi = abi_fallback + env['ABI_VERSION'] = abi.replace('-pre','').split('.') + env['MAPNIK_VERSION_STRING'] = abi # Common C++ flags. if env['THREADING'] == 'multi': diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py index 11129f80a..8cf54f1d9 100644 --- a/bindings/python/mapnik/__init__.py +++ b/bindings/python/mapnik/__init__.py @@ -572,13 +572,6 @@ def Geos(**keywords): keywords['type'] = 'geos' return CreateDatasource(keywords) -def mapnik_version_string(version=mapnik_version()): - """Return the Mapnik version as a string.""" - patch_level = version % 100 - minor_version = version / 100 % 1000 - major_version = version / 100000 - return '%s.%s.%s' % ( major_version, minor_version,patch_level) - def mapnik_version_from_string(version_string): """Return the Mapnik version from a string.""" n = version_string.split('.') diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp index e0591977a..4a4f5c4c9 100644 --- a/bindings/python/mapnik_python.cpp +++ b/bindings/python/mapnik_python.cpp @@ -279,6 +279,11 @@ unsigned mapnik_version() return MAPNIK_VERSION; } +std::string mapnik_version_string() +{ + return MAPNIK_VERSION_STRING; +} + // indicator for jpeg read/write support within libmapnik bool has_jpeg() { @@ -573,6 +578,7 @@ BOOST_PYTHON_MODULE(_mapnik) def("save_map_to_string", &save_map_to_string, save_map_to_string_overloads()); def("mapnik_version", &mapnik_version,"Get the Mapnik version number"); + def("mapnik_version_string", &mapnik_version_string,"Get the Mapnik version string"); def("has_jpeg", &has_jpeg, "Get jpeg read/write support status"); def("has_cairo", &has_cairo, "Get cairo library status"); def("has_pycairo", &has_pycairo, "Get pycairo module status"); diff --git a/include/mapnik/version.hpp b/include/mapnik/version.hpp index b79c0f666..b5a96d8ea 100644 --- a/include/mapnik/version.hpp +++ b/include/mapnik/version.hpp @@ -23,6 +23,28 @@ #ifndef MAPNIK_VERSION_HPP #define MAPNIK_VERSION_HPP -#define MAPNIK_VERSION 200000 +#define MAPNIK_VERSION_IS_RELEASE 0 + +#define MAPNIK_MAJOR_VERSION 2 +#define MAPNIK_MINOR_VERSION 1 +#define MAPNIK_PATCH_VERSION 0 + +#define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION) + +#ifndef MAPNIK_STRINGIFY +#define MAPNIK_STRINGIFY(n) MAPNIK_STRINGIFY_HELPER(n) +#define MAPNIK_STRINGIFY_HELPER(n) #n +#endif + +#if MAPNIK_VERSION_IS_RELEASE +# define MAPNIK_VERSION_STRING MAPNIK_STRINGIFY(MAPNIK_MAJOR_VERSION) "." \ + MAPNIK_STRINGIFY(MAPNIK_MINOR_VERSION) "." \ + MAPNIK_STRINGIFY(MAPNIK_PATCH_VERSION) + +#else +# define MAPNIK_VERSION_STRING MAPNIK_STRINGIFY(MAPNIK_MAJOR_VERSION) "." \ + MAPNIK_STRINGIFY(MAPNIK_MINOR_VERSION) "." \ + MAPNIK_STRINGIFY(MAPNIK_PATCH_VERSION) "-pre" +#endif #endif // MAPNIK_VERSION_HPP diff --git a/src/build.py b/src/build.py index 78df41b46..956b5d550 100644 --- a/src/build.py +++ b/src/build.py @@ -83,7 +83,7 @@ else: if env['PLATFORM'] == 'Darwin': mapnik_libname = 'libmapnik.dylib' else: - mapnik_libname = 'libmapnik.so.' + ("%d.%d" % (ABI_VERSION[0],ABI_VERSION[1])) + mapnik_libname = 'libmapnik.so.' + ("%d.%d" % (int(ABI_VERSION[0]),int(ABI_VERSION[1]))) if env['PLATFORM'] == 'Darwin': if env['FULL_LIB_PATH']: @@ -91,7 +91,7 @@ if env['PLATFORM'] == 'Darwin': else: lib_path = mapnik_libname mapnik_lib_link_flag += ' -Wl,-install_name,%s' % lib_path - _d = {'version':env['MAPNIK_VERSION_STRING']} + _d = {'version':env['MAPNIK_VERSION_STRING'].replace('-pre','')} mapnik_lib_link_flag += ' -current_version %(version)s -compatibility_version %(version)s' % _d elif env['PLATFORM'] == 'SunOS': if env['CXX'].startswith('CC'): From 926404d9aead018bb50c2fa4710cfd9d69ea214e Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 15 Mar 2012 02:03:33 +0000 Subject: [PATCH 079/138] properly format abi versions in a few more placesa --- src/build.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/build.py b/src/build.py index 956b5d550..25a63496c 100644 --- a/src/build.py +++ b/src/build.py @@ -342,7 +342,7 @@ if env['PLATFORM'] != 'Darwin': major, minor, micro = ABI_VERSION - soFile = "%s.%d.%d.%d" % (os.path.basename(str(mapnik[0])), major, minor, micro) + soFile = "%s.%d.%d.%d" % (os.path.basename(str(mapnik[0])), int(major), int(minor), int(micro)) target = os.path.join(env['MAPNIK_LIB_BASE_DEST'], soFile) if 'uninstall' not in COMMAND_LINE_TARGETS: @@ -353,7 +353,7 @@ if env['PLATFORM'] != 'Darwin': # Install symlinks - target1 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], "%s.%d.%d" % (os.path.basename(str(mapnik[0])),major, minor)) + target1 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], "%s.%d.%d" % (os.path.basename(str(mapnik[0])),int(major), int(minor))) target2 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], os.path.basename(str(mapnik[0]))) if 'uninstall' not in COMMAND_LINE_TARGETS: if 'install' in COMMAND_LINE_TARGETS: From 70512dc03b0d38dd324e19667ba56437069307ea Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Thu, 15 Mar 2012 10:26:53 +0000 Subject: [PATCH 080/138] + add optional smothing to line_symbolizer ( TODO: conv_dash ) --- bindings/python/mapnik_line_symbolizer.cpp | 4 +++ include/mapnik/line_symbolizer.hpp | 20 +++++++++-- src/agg/process_line_symbolizer.cpp | 41 ++++++++++++++++------ src/load_map.cpp | 5 ++- src/save_map.cpp | 6 +++- 5 files changed, 60 insertions(+), 16 deletions(-) diff --git a/bindings/python/mapnik_line_symbolizer.cpp b/bindings/python/mapnik_line_symbolizer.cpp index 062d52618..9c7053b90 100644 --- a/bindings/python/mapnik_line_symbolizer.cpp +++ b/bindings/python/mapnik_line_symbolizer.cpp @@ -62,5 +62,9 @@ void export_line_symbolizer() (&line_symbolizer::get_stroke, return_value_policy()), &line_symbolizer::set_stroke) + .add_property("smooth", + &line_symbolizer::smooth, + &line_symbolizer::set_smooth, + "smooth value (0..1.0)") ; } diff --git a/include/mapnik/line_symbolizer.hpp b/include/mapnik/line_symbolizer.hpp index 84c845098..bcb3ab971 100644 --- a/include/mapnik/line_symbolizer.hpp +++ b/include/mapnik/line_symbolizer.hpp @@ -44,17 +44,20 @@ struct MAPNIK_DECL line_symbolizer : public symbolizer_base explicit line_symbolizer() : symbolizer_base(), stroke_(), - rasterizer_p_(RASTERIZER_FULL) {} + rasterizer_p_(RASTERIZER_FULL), + smooth_(0.0) {} line_symbolizer(stroke const& stroke) : symbolizer_base(), stroke_(stroke), - rasterizer_p_(RASTERIZER_FULL) {} + rasterizer_p_(RASTERIZER_FULL), + smooth_(0.0) {} line_symbolizer(color const& pen,float width=1.0) : symbolizer_base(), stroke_(pen,width), - rasterizer_p_(RASTERIZER_FULL) {} + rasterizer_p_(RASTERIZER_FULL), + smooth_(0.0) {} stroke const& get_stroke() const { @@ -76,9 +79,20 @@ struct MAPNIK_DECL line_symbolizer : public symbolizer_base return rasterizer_p_; } + void set_smooth(double smooth) + { + smooth_ = smooth; + } + + double smooth() const + { + return smooth_; + } + private: stroke stroke_; line_rasterizer_e rasterizer_p_; + double smooth_; }; } diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index cc00d2f2e..d07f47a28 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -40,7 +40,7 @@ #include "agg_renderer_outline_aa.h" #include "agg_rasterizer_outline_aa.h" #include "agg_conv_clip_polyline.h" - +#include "agg_conv_smooth_poly1.h" // stl #include @@ -105,8 +105,6 @@ void agg_renderer::process(line_symbolizer const& sym, set_gamma_method(stroke_, ras_ptr); - - //metawriter_with_properties writer = sym.get_metawriter(); for (unsigned i=0;inum_geometries();++i) { @@ -137,14 +135,35 @@ void agg_renderer::process(line_symbolizer const& sym, } else { - clipped_geometry_type clipped(geom); - clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); - path_type path(t_,clipped,prj_trans); - agg::conv_stroke stroke(path); - set_join_caps(stroke_,stroke); - stroke.generator().miter_limit(4.0); - stroke.generator().width(stroke_.get_width() * scale_factor_); - ras_ptr->add_path(stroke); + if (sym.smooth() > 0.0) + { + typedef agg::conv_clip_polyline clipped_geometry_type; + typedef coord_transform2 path_type; + typedef agg::conv_smooth_poly1_curve smooth_type; + clipped_geometry_type clipped(geom); + clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); + path_type path(t_,clipped,prj_trans); + smooth_type smooth(path); + smooth.smooth_value(sym.smooth()); + agg::conv_stroke stroke(smooth); + set_join_caps(stroke_,stroke); + stroke.generator().miter_limit(4.0); + stroke.generator().width(stroke_.get_width() * scale_factor_); + ras_ptr->add_path(stroke); + } + else + { + typedef agg::conv_clip_polyline clipped_geometry_type; + typedef coord_transform2 path_type; + clipped_geometry_type clipped(geom); + clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); + path_type path(t_,clipped,prj_trans); + agg::conv_stroke stroke(path); + set_join_caps(stroke_,stroke); + stroke.generator().miter_limit(4.0); + stroke.generator().width(stroke_.get_width() * scale_factor_); + ras_ptr->add_path(stroke); + } //if (writer.first) writer.first->add_line(path, *feature, t_, writer.second); } } diff --git a/src/load_map.cpp b/src/load_map.cpp index 92787c83e..354817a36 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -1266,7 +1266,10 @@ void map_parser::parse_line_symbolizer( rule & rule, xml_node const & sym ) line_rasterizer_e rasterizer = sym.get_attr("rasterizer", RASTERIZER_FULL); //optional rasterizer_method = sym.get_opt_attr("full"); symbol.set_rasterizer(rasterizer); - + // smooth value + optional smooth = sym.get_opt_attr("smooth"); + if (smooth) symbol.set_smooth(*smooth); + // meta-writer parse_metawriter_in_symbolizer(symbol, sym); rule.append(symbol); } diff --git a/src/save_map.cpp b/src/save_map.cpp index d81508ad3..a890973ce 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -91,8 +91,12 @@ public: { set_attr( sym_node, "rasterizer", sym.get_rasterizer() ); } + if ( sym.smooth() != dfl.smooth() || explicit_defaults_ ) + { + set_attr( sym_node, "smooth", sym.smooth() ); + } } - + void operator () ( line_pattern_symbolizer const& sym ) { ptree & sym_node = rule_.push_back( From 66beaaa05b54d7128efba85b3988a2bd271082c2 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Thu, 15 Mar 2012 10:42:30 +0000 Subject: [PATCH 081/138] + support smoothing in conv_dash --- src/agg/process_line_symbolizer.cpp | 69 ++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index d07f47a28..8763b882f 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -52,9 +52,7 @@ void agg_renderer::process(line_symbolizer const& sym, proj_transform const& prj_trans) { typedef agg::renderer_base ren_base; - typedef agg::conv_clip_polyline clipped_geometry_type; - typedef coord_transform2 path_type; - + stroke const& stroke_ = sym.get_stroke(); color const& col = stroke_.get_color(); unsigned r=col.red(); @@ -70,6 +68,8 @@ void agg_renderer::process(line_symbolizer const& sym, { typedef agg::renderer_outline_aa renderer_type; typedef agg::rasterizer_outline_aa rasterizer_type; + typedef agg::conv_clip_polyline clipped_geometry_type; + typedef coord_transform2 path_type; agg::line_profile_aa profile; profile.width(stroke_.get_width() * scale_factor_); @@ -113,25 +113,54 @@ void agg_renderer::process(line_symbolizer const& sym, { if (stroke_.has_dash()) { - clipped_geometry_type clipped(geom); - clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); - path_type path(t_,clipped,prj_trans); - - agg::conv_dash dash(path); - dash_array const& d = stroke_.get_dash_array(); - dash_array::const_iterator itr = d.begin(); - dash_array::const_iterator end = d.end(); - for (;itr != end;++itr) + if (sym.smooth() > 0.0) { - dash.add_dash(itr->first * scale_factor_, - itr->second * scale_factor_); + typedef agg::conv_clip_polyline clipped_geometry_type; + typedef coord_transform2 path_type; + typedef agg::conv_smooth_poly1_curve smooth_type; + clipped_geometry_type clipped(geom); + clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); + path_type path(t_,clipped,prj_trans); + smooth_type smooth(path); + smooth.smooth_value(sym.smooth()); + agg::conv_dash dash(smooth); + dash_array const& d = stroke_.get_dash_array(); + dash_array::const_iterator itr = d.begin(); + dash_array::const_iterator end = d.end(); + for (;itr != end;++itr) + { + dash.add_dash(itr->first * scale_factor_, + itr->second * scale_factor_); + } + agg::conv_stroke > stroke(dash); + set_join_caps(stroke_,stroke); + stroke.generator().miter_limit(4.0); + stroke.generator().width(stroke_.get_width() * scale_factor_); + ras_ptr->add_path(stroke); + } + else + { + typedef agg::conv_clip_polyline clipped_geometry_type; + typedef coord_transform2 path_type; + clipped_geometry_type clipped(geom); + clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); + path_type path(t_,clipped,prj_trans); + + agg::conv_dash dash(path); + dash_array const& d = stroke_.get_dash_array(); + dash_array::const_iterator itr = d.begin(); + dash_array::const_iterator end = d.end(); + for (;itr != end;++itr) + { + dash.add_dash(itr->first * scale_factor_, + itr->second * scale_factor_); + } + agg::conv_stroke > stroke(dash); + set_join_caps(stroke_,stroke); + stroke.generator().miter_limit(4.0); + stroke.generator().width(stroke_.get_width() * scale_factor_); + ras_ptr->add_path(stroke); } - agg::conv_stroke > stroke(dash); - set_join_caps(stroke_,stroke); - stroke.generator().miter_limit(4.0); - stroke.generator().width(stroke_.get_width() * scale_factor_); - ras_ptr->add_path(stroke); - } else { From c95959c549880c2474c9d9dd47ecead08a47b29f Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Thu, 15 Mar 2012 11:29:57 +0000 Subject: [PATCH 082/138] + re-use cairo_context --- src/cairo_renderer.cpp | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index 7f10d8cba..dff4ce123 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -745,7 +745,6 @@ void cairo_renderer_base::start_map_processing(Map const& map) smooth_type smooth(path); smooth.smooth_value(sym.smooth()); context.add_agg_path(smooth); - context.fill(); } else { @@ -755,10 +754,11 @@ void cairo_renderer_base::start_map_processing(Map const& map) clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); context.add_path(path); - context.fill(); - } + } } } + // fill polygon + context.fill(); } void cairo_renderer_base::process(building_symbolizer const& sym, @@ -877,35 +877,34 @@ void cairo_renderer_base::start_map_processing(Map const& map) { typedef agg::conv_clip_polyline clipped_geometry_type; typedef coord_transform2 path_type; - - cairo_context context(context_); + mapnik::stroke const& stroke_ = sym.get_stroke(); - + cairo_context context(context_); context.set_color(stroke_.get_color(), stroke_.get_opacity()); - + context.set_line_join(stroke_.get_line_join()); + context.set_line_cap(stroke_.get_line_cap()); + context.set_miter_limit(4.0); + context.set_line_width(stroke_.get_width()); + if (stroke_.has_dash()) + { + context.set_dash(stroke_.get_dash_array()); + } + for (unsigned i = 0; i < feature->num_geometries(); ++i) { geometry_type & geom = feature->get_geometry(i); if (geom.num_points() > 1) { - cairo_context context(context_); + //cairo_context context(context_); clipped_geometry_type clipped(geom); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); - if (stroke_.has_dash()) - { - context.set_dash(stroke_.get_dash_array()); - } - - context.set_line_join(stroke_.get_line_join()); - context.set_line_cap(stroke_.get_line_cap()); - context.set_miter_limit(4.0); - context.set_line_width(stroke_.get_width()); + context.add_path(path); - context.stroke(); } } + context.stroke(); } void cairo_renderer_base::render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity) From f9b2e5fb56e8b2099d47f872638464f065df5240 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Fri, 16 Mar 2012 00:38:03 +0100 Subject: [PATCH 083/138] Add test for RTL text. --- tests/visual_tests/rtl-point.xml | 25 +++++++++++++++++++++++++ tests/visual_tests/test.py | 4 +++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/visual_tests/rtl-point.xml diff --git a/tests/visual_tests/rtl-point.xml b/tests/visual_tests/rtl-point.xml new file mode 100644 index 000000000..c29a41797 --- /dev/null +++ b/tests/visual_tests/rtl-point.xml @@ -0,0 +1,25 @@ + + + + + + My Style + + + shape + points.shp + + + + + + diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index f899da1ea..804137c0b 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -27,7 +27,9 @@ files = [ ("formating-3", 500), ("formating-4", 500), ("shieldsymbolizer-1", 490, 495, 497, 498, 499, 500, 501, 502, 505, 510), - ("expressionformat", 500)] + ("expressionformat", 500), + ("rtl-point", (200, 200)) + ] def render(filename, width, height=100): print "-"*80 From 1b85f42a883b6df8f0176607c25a62c8d8f9504d Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Fri, 16 Mar 2012 01:01:12 +0100 Subject: [PATCH 084/138] Reapply RTL patch. Fixes #189. --- src/placement_finder.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index 387323323..719b56dee 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -384,6 +384,9 @@ void placement_finder::find_point_placement(double label_x, // set for upper left corner of text envelope for the first line, bottom left of first character y = string_height_ / 2.0 - line_height; + // RTL text is converted to a mirrored representation in get_string_info() + // so we have to fix line break order here + if (info_.get_rtl()) y = -y; // adjust for desired justification if (p.jalign == J_LEFT) @@ -408,7 +411,13 @@ void placement_finder::find_point_placement(double label_x, line_width = line_sizes_[line_number].first; line_height= line_sizes_[line_number].second; - y -= line_height; // move position down to line start + if (info_.get_rtl()) + { + y += line_height; + } else + { + y -= line_height; // move position down to line start + } // reset to begining of line position if (p.jalign == J_LEFT) From 725248628d807480ca2c32231559fab3a6c97ded Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Fri, 16 Mar 2012 01:50:55 +0100 Subject: [PATCH 085/138] C++ style. --- src/load_map.cpp | 114 +++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/load_map.cpp b/src/load_map.cpp index 354817a36..2f77db471 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -80,16 +80,16 @@ using boost::optional; class map_parser : boost::noncopyable { public: - map_parser( bool strict, std::string const& filename = "" ) : - strict_( strict ), - filename_( filename ), + map_parser(bool strict, std::string const& filename = "") : + strict_(strict), + filename_(filename), relative_to_xml_(true), font_manager_(font_engine_) {} void parse_map(Map & map, xml_node const& sty, std::string const& base_path); private: - void parse_map_include( Map & map, xml_node const& include); + void parse_map_include(Map & map, xml_node const& include); void parse_style(Map & map, xml_node const& sty); void parse_layer(Map & map, xml_node const& lay); void parse_metawriter(Map & map, xml_node const& lay); @@ -107,9 +107,9 @@ private: void parse_shield_symbolizer(rule & rule, xml_node const& sym); void parse_line_symbolizer(rule & rule, xml_node const& sym); void parse_polygon_symbolizer(rule & rule, xml_node const& sym); - void parse_building_symbolizer(rule & rule, xml_node const& sym ); - void parse_raster_symbolizer(rule & rule, xml_node const& sym ); - void parse_markers_symbolizer(rule & rule, xml_node const& sym ); + void parse_building_symbolizer(rule & rule, xml_node const& sym); + void parse_raster_symbolizer(rule & rule, xml_node const& sym); + void parse_markers_symbolizer(rule & rule, xml_node const& sym); void parse_raster_colorizer(raster_colorizer_ptr const& rc, xml_node const& node); void parse_stroke(stroke & strk, xml_node const & sym); @@ -479,7 +479,7 @@ void map_parser::parse_font(font_set &fset, xml_node const& f) optional face_name = f.get_opt_attr("face-name"); if (face_name) { - if ( strict_ ) + if (strict_) { ensure_font_face(*face_name); } @@ -506,47 +506,47 @@ void map_parser::parse_layer(Map & map, xml_node const& lay) optional status = lay.get_opt_attr("status"); if (status) { - lyr.set_active(* status ); + lyr.set_active(* status); } optional min_zoom = lay.get_opt_attr("minzoom"); if (min_zoom) { - lyr.set_min_zoom( * min_zoom ); + lyr.set_min_zoom(* min_zoom); } optional max_zoom = lay.get_opt_attr("maxzoom"); if (max_zoom) { - lyr.set_max_zoom( * max_zoom ); + lyr.set_max_zoom(* max_zoom); } optional queryable = lay.get_opt_attr("queryable"); if (queryable) { - lyr.set_queryable( * queryable ); + lyr.set_queryable(* queryable); } optional clear_cache = lay.get_opt_attr("clear-label-cache"); if (clear_cache) { - lyr.set_clear_label_cache( * clear_cache ); + lyr.set_clear_label_cache(* clear_cache); } optional cache_features = lay.get_opt_attr("cache-features"); if (cache_features) { - lyr.set_cache_features( * cache_features ); + lyr.set_cache_features(* cache_features); } optional group_by = lay.get_opt_attr("group-by"); if (group_by) { - lyr.set_group_by( * group_by ); + lyr.set_group_by(* group_by); } xml_node::const_iterator child = lay.begin(); @@ -576,7 +576,7 @@ void map_parser::parse_layer(Map & map, xml_node const& lay) { parameters params; optional base = child->get_opt_attr("base"); - if( base ) + if(base) { std::map::const_iterator base_itr = datasource_templates_.find(*base); if (base_itr!=datasource_templates_.end()) @@ -614,9 +614,9 @@ void map_parser::parse_layer(Map & map, xml_node const& lay) lyr.set_datasource(ds); } - catch (const std::exception & ex ) + catch (const std::exception & ex) { - throw config_error( ex.what() ); + throw config_error(ex.what()); } catch (...) @@ -676,10 +676,10 @@ void map_parser::parse_rule(feature_type_style & style, xml_node const& r) xml_node::const_iterator symIter = r.begin(); xml_node::const_iterator endSym = r.end(); - for( ;symIter != endSym; ++symIter) + for(;symIter != endSym; ++symIter) { - if ( symIter->is("PointSymbolizer")) + if (symIter->is("PointSymbolizer")) { parse_point_symbolizer(rule, *symIter); } @@ -713,7 +713,7 @@ void map_parser::parse_rule(feature_type_style & style, xml_node const& r) } else if (symIter->is("RasterSymbolizer")) { - parse_raster_symbolizer( rule, *symIter); + parse_raster_symbolizer(rule, *symIter); } else if (symIter->is("MarkersSymbolizer")) { @@ -725,7 +725,7 @@ void map_parser::parse_rule(feature_type_style & style, xml_node const& r) } catch (const config_error & ex) { - if (!name.empty() ) + if (!name.empty()) { ex.append_context(std::string("in rule '") + name + "'", r); } @@ -755,25 +755,25 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym) point_symbolizer symbol; if (allow_overlap) { - symbol.set_allow_overlap( * allow_overlap ); + symbol.set_allow_overlap(* allow_overlap); } if (opacity) { - symbol.set_opacity( * opacity ); + symbol.set_opacity(* opacity); } if (ignore_placement) { - symbol.set_ignore_placement( * ignore_placement ); + symbol.set_ignore_placement(* ignore_placement); } point_placement_e placement = sym.get_attr("placement", CENTROID_POINT_PLACEMENT); - symbol.set_point_placement( placement ); + symbol.set_point_placement(placement); if (file) { try { - if( base ) + if(base) { std::map::const_iterator itr = file_sources_.find(*base); if (itr!=file_sources_.end()) @@ -804,7 +804,7 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym) symbol.set_transform(matrix); } } - catch (image_reader_exception const & ex ) + catch (image_reader_exception const & ex) { std::string msg("Failed to load image file '" + * file + "': " + ex.what()); @@ -869,7 +869,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) markers_symbolizer symbol(parse_path(filename)); optional opacity = sym.get_opt_attr("opacity"); - if (opacity) symbol.set_opacity( *opacity ); + if (opacity) symbol.set_opacity(*opacity); if (transform_wkt) { @@ -922,7 +922,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) symbol.set_stroke(strk); marker_placement_e placement = sym.get_attr("placement", MARKER_LINE_PLACEMENT); - symbol.set_marker_placement( placement ); + symbol.set_marker_placement(placement); marker_type_e dfl_marker_type = ARROW; @@ -930,7 +930,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) dfl_marker_type = ELLIPSE; marker_type_e marker_type = sym.get_attr("marker-type", dfl_marker_type); - symbol.set_marker_type( marker_type ); + symbol.set_marker_type(marker_type); parse_metawriter_in_symbolizer(symbol, sym); rule.append(symbol); @@ -942,7 +942,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) } } -void map_parser::parse_line_pattern_symbolizer( rule & rule, xml_node const & sym ) +void map_parser::parse_line_pattern_symbolizer(rule & rule, xml_node const & sym) { try { @@ -951,7 +951,7 @@ void map_parser::parse_line_pattern_symbolizer( rule & rule, xml_node const & sy try { - if( base ) + if(base) { std::map::const_iterator itr = file_sources_.find(*base); if (itr!=file_sources_.end()) @@ -967,7 +967,7 @@ void map_parser::parse_line_pattern_symbolizer( rule & rule, xml_node const & sy parse_metawriter_in_symbolizer(symbol, sym); rule.append(symbol); } - catch (image_reader_exception const & ex ) + catch (image_reader_exception const & ex) { std::string msg("Failed to load image file '" + file + "': " + ex.what()); @@ -988,8 +988,8 @@ void map_parser::parse_line_pattern_symbolizer( rule & rule, xml_node const & sy } } -void map_parser::parse_polygon_pattern_symbolizer( rule & rule, - xml_node const & sym ) +void map_parser::parse_polygon_pattern_symbolizer(rule & rule, + xml_node const & sym) { try { @@ -998,7 +998,7 @@ void map_parser::parse_polygon_pattern_symbolizer( rule & rule, try { - if( base ) + if(base) { std::map::iterator itr = file_sources_.find(*base); if (itr!=file_sources_.end()) @@ -1026,7 +1026,7 @@ void map_parser::parse_polygon_pattern_symbolizer( rule & rule, parse_metawriter_in_symbolizer(symbol, sym); rule.append(symbol); } - catch (image_reader_exception const & ex ) + catch (image_reader_exception const & ex) { std::string msg("Failed to load image file '" + file + "': " + ex.what()); @@ -1047,7 +1047,7 @@ void map_parser::parse_polygon_pattern_symbolizer( rule & rule, } } -void map_parser::parse_text_symbolizer( rule & rule, xml_node const& sym ) +void map_parser::parse_text_symbolizer(rule & rule, xml_node const& sym) { try { @@ -1074,7 +1074,7 @@ void map_parser::parse_text_symbolizer( rule & rule, xml_node const& sym ) } } -void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym ) +void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym) { try { @@ -1127,7 +1127,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym ) sym.get_opt_attr("text-opacity"); if (text_opacity) { - shield_symbol.set_text_opacity( * text_opacity ); + shield_symbol.set_text_opacity(* text_opacity); } // unlock_image @@ -1135,7 +1135,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym ) sym.get_opt_attr("unlock-image"); if (unlock_image) { - shield_symbol.set_unlock_image( * unlock_image ); + shield_symbol.set_unlock_image(* unlock_image); } parse_metawriter_in_symbolizer(shield_symbol, sym); @@ -1145,7 +1145,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym ) try { - if( base ) + if(base) { std::map::const_iterator itr = file_sources_.find(*base); if (itr!=file_sources_.end()) @@ -1157,7 +1157,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym ) image_file = ensure_relative_to_xml(image_file); shield_symbol.set_filename(parse_path(image_file)); } - catch (image_reader_exception const & ex ) + catch (image_reader_exception const & ex) { std::string msg("Failed to load image file '" + image_file + "': " + ex.what()); @@ -1227,7 +1227,7 @@ void map_parser::parse_stroke(stroke & strk, xml_node const & sym) double f = boost::lexical_cast(*itr); dash_array.push_back(f); } - catch ( boost::bad_lexical_cast &) + catch (boost::bad_lexical_cast &) { throw config_error(std::string("Failed to parse dasharray ") + "'. Expected a " + @@ -1237,7 +1237,7 @@ void map_parser::parse_stroke(stroke & strk, xml_node const & sym) if (dash_array.size()) { size_t size = dash_array.size(); - if ( size % 2) + if (size % 2) { for (size_t i=0; i < size ;++i) { @@ -1254,7 +1254,7 @@ void map_parser::parse_stroke(stroke & strk, xml_node const & sym) } } -void map_parser::parse_line_symbolizer( rule & rule, xml_node const & sym ) +void map_parser::parse_line_symbolizer(rule & rule, xml_node const & sym) { try { @@ -1281,7 +1281,7 @@ void map_parser::parse_line_symbolizer( rule & rule, xml_node const & sym ) } -void map_parser::parse_polygon_symbolizer( rule & rule, xml_node const & sym ) +void map_parser::parse_polygon_symbolizer(rule & rule, xml_node const & sym) { try { @@ -1313,7 +1313,7 @@ void map_parser::parse_polygon_symbolizer( rule & rule, xml_node const & sym ) } -void map_parser::parse_building_symbolizer( rule & rule, xml_node const & sym ) +void map_parser::parse_building_symbolizer(rule & rule, xml_node const & sym) { try { @@ -1339,7 +1339,7 @@ void map_parser::parse_building_symbolizer( rule & rule, xml_node const & sym ) } } -void map_parser::parse_raster_symbolizer( rule & rule, xml_node const & sym ) +void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & sym) { try { @@ -1400,13 +1400,13 @@ void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, if(default_mode == COLORIZER_INHERIT) { throw config_error("RasterColorizer mode must not be INHERIT. "); } - rc->set_default_mode( default_mode ); + rc->set_default_mode(default_mode); // default colour optional default_color = node.get_opt_attr("default-color"); if (default_color) { - rc->set_default_color( *default_color ); + rc->set_default_color(*default_color); } @@ -1417,7 +1417,7 @@ void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, if(*eps < 0) { throw config_error("RasterColorizer epsilon must be > 0. "); } - rc->set_epsilon( *eps ); + rc->set_epsilon(*eps); } @@ -1474,22 +1474,22 @@ void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, } } -void map_parser::ensure_font_face( std::string const& face_name ) +void map_parser::ensure_font_face(std::string const& face_name) { - if ( ! font_manager_.get_face( face_name ) ) + if (! font_manager_.get_face(face_name)) { throw config_error("Failed to find font face '" + face_name + "'"); } } -std::string map_parser::ensure_relative_to_xml( boost::optional opt_path ) +std::string map_parser::ensure_relative_to_xml(boost::optional opt_path) { if (relative_to_xml_) { boost::filesystem::path xml_path = filename_; boost::filesystem::path rel_path = *opt_path; - if ( !rel_path.has_root_path() ) + if (!rel_path.has_root_path()) { #if (BOOST_FILESYSTEM_VERSION == 3) // TODO - normalize is now deprecated, use make_preferred? From ff78217276fd68201bb7f78239306e0b3f3d0c2a Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Fri, 16 Mar 2012 01:51:19 +0100 Subject: [PATCH 086/138] Add reference image for RTL test. --- tests/visual_tests/rtl-point-200-reference.png | Bin 0 -> 2175 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/visual_tests/rtl-point-200-reference.png diff --git a/tests/visual_tests/rtl-point-200-reference.png b/tests/visual_tests/rtl-point-200-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..0d8979ed05c14de327b61d6da46bc124eedeb0d8 GIT binary patch literal 2175 zcmeHJc{JPk7SHj}Fw`<_(X>fQv`=d&Izg9+J*Jk{7CBO(sLBY!R0*NlF{!1sOp8vH zGs<)Zu~bPHl1^>4rDK^8A;cD=mXN4KBHpia-oNkt`~G?7-0$~$&iCAVzxUqHy`S^V zzU1w$t$A1z1OjP$U|f8G^Zn-qRtI)^P<=TF1a|Xqar93vTb)X|>$L~#Apy z*G9#Ir0AZ_L;FHlO?D;)qup`lKg3QmkD`*+`J~kCH806BTpf&1-+#m|l-EjXUga@( z9C|Qmto}-C^vEwR4TrAYLSGFPFAlaQ3cZ6Fu}`#(tUHhUln+4X_f#`G-xiv<*Ch(s zg7BeAS0r)tpZ#pMw}f~M@aeW6hKkXFp*$r-csCf~7|U;qCa}`IB*YnlF6Oq>j|tT% zf@CUOaX4IS)Q9qTcEU%_SMrTH_e!kB-fgt9(&EbNdCE}ZHxExDum1t(HHFitI})>@ zT3VVeMo%{KYVffwUaCf5RTbee1 zThr^OGfg=MPfbYv8X>JszT&i}Zi{Xh85wjKEldBhvypEVqyDve|zb*w%k*%O)tgUUz_{>u|BwRBu_H=jv`>?-r27c_1%xo}ac0D91P zuU*Lw-AnZ@Ki}*3PQwYFHA8cL>Yi`0IVRgv7+B!J6;#X2QD=D8rAc(b&gVGOLiuee z*&*5p(0?2b#9fwiG7uLsanZ9o1!1M)0f&W+19gU+4nCh=PDF(avc56qCsq8WVu zf&qpvV5kEcAsvB{YUQO5T-q&~z9^HrKw-^iStmsxJ#q&-LW%^h*^% z|F%=Kg>TGuv8L9AC(`Ysrr)3P|21@XXR8?ii*{;qhpObpZLjidS4e5sV<{9$eH0Un zNYTYu$zIV2;x;>D=lDVe@VvFP^*iW{bYo72QqFees<4pOss_FJ=$u}iYJkiQuYI-Q zjBtqlFfgD6VX>|+jRm?dn-n Date: Fri, 16 Mar 2012 13:43:48 -0700 Subject: [PATCH 087/138] create context in init list --- plugins/input/csv/csv_datasource.cpp | 4 ++-- plugins/input/raster/raster_featureset.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index c65b47373..dc0b27c5e 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -46,7 +46,8 @@ csv_datasource::csv_datasource(parameters const& params, bool bind) manual_headers_(boost::trim_copy(*params_.get("headers", ""))), strict_(*params_.get("strict", false)), quiet_(*params_.get("quiet", false)), - filesize_max_(*params_.get("filesize_max", 20.0)) // MB + filesize_max_(*params_.get("filesize_max", 20.0)), // MB + ctx_(boost::make_shared()) { /* TODO: general: @@ -392,7 +393,6 @@ void csv_datasource::parse_csv(T& stream, bool extent_initialized = false; std::size_t num_headers = headers_.size(); - ctx_ = boost::make_shared(); for (std::size_t i = 0; i < headers_.size(); ++i) { ctx_->push(headers_[i]); diff --git a/plugins/input/raster/raster_featureset.cpp b/plugins/input/raster/raster_featureset.cpp index 3abc6d72e..2d08d117b 100644 --- a/plugins/input/raster/raster_featureset.cpp +++ b/plugins/input/raster/raster_featureset.cpp @@ -48,9 +48,9 @@ raster_featureset::raster_featureset(LookupPolicy const& policy, extent_(extent), bbox_(q.get_bbox()), curIter_(policy_.begin()), - endIter_(policy_.end()) + endIter_(policy_.end()), + ctx_(boost::make_shared()) { - ctx_ = boost::make_shared(); } template From cdc63767192a101903a24420605dee3d29f6b280 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 16 Mar 2012 14:49:56 -0700 Subject: [PATCH 088/138] be explicit about zero-division protection --- include/mapnik/ctrans.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mapnik/ctrans.hpp b/include/mapnik/ctrans.hpp index 014073906..31c62f391 100644 --- a/include/mapnik/ctrans.hpp +++ b/include/mapnik/ctrans.hpp @@ -397,9 +397,9 @@ public: sx_(1.0), sy_(1.0) { - if (extent_.width()) + if (extent_.width() > 0) sx_ = static_cast(width_) / extent_.width(); - if (extent_.height()) + if (extent_.height() > 0) sy_ = static_cast(height_) / extent_.height(); } From 1542e3e5137daf370a687901287d9d4108f3a118 Mon Sep 17 00:00:00 2001 From: ldp Date: Sun, 18 Mar 2012 22:35:02 +0100 Subject: [PATCH 089/138] add ignore-placement to MarkersSymbolizer --- include/mapnik/markers_symbolizer.hpp | 3 +++ src/agg/process_markers_symbolizer.cpp | 3 ++- src/load_map.cpp | 2 ++ src/markers_symbolizer.cpp | 13 +++++++++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/mapnik/markers_symbolizer.hpp b/include/mapnik/markers_symbolizer.hpp index b6e78a8c2..ccd249da9 100644 --- a/include/mapnik/markers_symbolizer.hpp +++ b/include/mapnik/markers_symbolizer.hpp @@ -56,6 +56,8 @@ public: explicit markers_symbolizer(); markers_symbolizer(path_expression_ptr filename); markers_symbolizer(markers_symbolizer const& rhs); + void set_ignore_placement(bool ignore_placement); + bool get_ignore_placement() const; void set_allow_overlap(bool overlap); bool get_allow_overlap() const; void set_spacing(double spacing); @@ -76,6 +78,7 @@ public: marker_type_e get_marker_type() const; private: + bool ignore_placement_; bool allow_overlap_; color fill_; double spacing_; diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index 57a01448e..ae7725bf1 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -244,7 +244,8 @@ void agg_renderer::process(markers_symbolizer const& sym, ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity()))); agg::render_scanlines(*ras_ptr, sl_line, ren); } - detector_->insert(label_ext); + if (!sym.get_ignore_placement()) + detector_->insert(label_ext); if (writer.first) writer.first->add_box(label_ext, *feature, t_, writer.second); } } diff --git a/src/load_map.cpp b/src/load_map.cpp index 2f77db471..38bcfbff7 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -896,7 +896,9 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) optional max_error = sym.get_opt_attr("max-error"); if (max_error) symbol.set_max_error(*max_error); optional allow_overlap = sym.get_opt_attr("allow-overlap"); + optional ignore_placement = sym.get_opt_attr("ignore-placement"); if (allow_overlap) symbol.set_allow_overlap(*allow_overlap); + if (ignore_placement) symbol.set_ignore_placement(*ignore_placement); optional w = sym.get_opt_attr("width"); optional h = sym.get_opt_attr("height"); diff --git a/src/markers_symbolizer.cpp b/src/markers_symbolizer.cpp index 02afffdd4..a2ccd70ab 100644 --- a/src/markers_symbolizer.cpp +++ b/src/markers_symbolizer.cpp @@ -47,6 +47,7 @@ markers_symbolizer::markers_symbolizer() : symbolizer_with_image(path_expression_ptr(new path_expression)), symbolizer_base(), allow_overlap_(false), + ignore_placement_(false), fill_(color(0,0,255)), spacing_(100.0), max_error_(0.2), @@ -60,6 +61,7 @@ markers_symbolizer::markers_symbolizer(path_expression_ptr filename) : symbolizer_with_image(filename), symbolizer_base(), allow_overlap_(false), + ignore_placement_(false), fill_(color(0,0,255)), spacing_(100.0), max_error_(0.2), @@ -73,6 +75,7 @@ markers_symbolizer::markers_symbolizer(markers_symbolizer const& rhs) : symbolizer_with_image(rhs), symbolizer_base(rhs), allow_overlap_(rhs.allow_overlap_), + ignore_placement_(rhs.ignore_placement_), fill_(rhs.fill_), spacing_(rhs.spacing_), max_error_(rhs.max_error_), @@ -82,6 +85,16 @@ markers_symbolizer::markers_symbolizer(markers_symbolizer const& rhs) marker_p_(rhs.marker_p_), marker_type_(rhs.marker_type_) {} +void markers_symbolizer::set_ignore_placement(bool ignore_placement) +{ + ignore_placement_ = ignore_placement; +} + +bool markers_symbolizer::get_ignore_placement() const +{ + return ignore_placement_; +} + void markers_symbolizer::set_allow_overlap(bool overlap) { allow_overlap_ = overlap; From 0ecd5bae45c79f02d72d8f59b54158d9fa72713c Mon Sep 17 00:00:00 2001 From: novldp Date: Sun, 18 Mar 2012 23:30:37 +0100 Subject: [PATCH 090/138] +add MarkersSymbolizer ignore-placement to save_map and python bindings --- bindings/python/mapnik_markers_symbolizer.cpp | 9 +++++++-- src/save_map.cpp | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bindings/python/mapnik_markers_symbolizer.cpp b/bindings/python/mapnik_markers_symbolizer.cpp index df0ae4606..999bb40e6 100644 --- a/bindings/python/mapnik_markers_symbolizer.cpp +++ b/bindings/python/mapnik_markers_symbolizer.cpp @@ -60,7 +60,8 @@ struct markers_symbolizer_pickle_suite : boost::python::pickle_suite static boost::python::tuple getstate(markers_symbolizer const& p) { - return boost::python::make_tuple(p.get_allow_overlap());//,p.get_opacity()); + return boost::python::make_tuple(p.get_allow_overlap(), + p.get_ignore_placement());//,p.get_opacity()); } static void @@ -77,7 +78,8 @@ struct markers_symbolizer_pickle_suite : boost::python::pickle_suite } p.set_allow_overlap(extract(state[0])); - //p.set_opacity(extract(state[1])); + p.set_ignore_placement(extract(state[1])); + //p.set_opacity(extract(state[2])); } @@ -108,6 +110,9 @@ void export_markers_symbolizer() &markers_symbolizer::get_opacity, &markers_symbolizer::set_opacity, "Set/get the text opacity") + .add_property("ignore_placement", + &markers_symbolizer::get_ignore_placement, + &markers_symbolizer::set_ignore_placement) .add_property("transform", &mapnik::get_svg_transform, &mapnik::set_svg_transform) diff --git a/src/save_map.cpp b/src/save_map.cpp index a890973ce..6aa9fe5d5 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -273,6 +273,10 @@ public: { set_attr( sym_node, "allow-overlap", sym.get_allow_overlap() ); } + if (sym.get_ignore_placement() != dfl.get_ignore_placement() || explicit_defaults_) + { + set_attr( sym_node, "ignore-placement", sym.get_ignore_placement() ); + } if (sym.get_spacing() != dfl.get_spacing() || explicit_defaults_) { set_attr( sym_node, "spacing", sym.get_spacing() ); From aef214292ecd67af8915b8f57d8291299a43808b Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Mon, 19 Mar 2012 10:11:55 +0000 Subject: [PATCH 091/138] don't rely on compiler for-loop optimisation --- include/mapnik/font_engine_freetype.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index ffb0950e5..54baaa04d 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -168,13 +168,14 @@ public: glyph_ptr get_glyph(unsigned c) const { - for (std::vector::const_iterator face = faces_.begin(); face != faces_.end(); ++face) + std::vector::const_iterator face = faces_.begin(); + std::vector::const_iterator end = faces_.end(); + for (; face != end; ++face) { FT_UInt g = (*face)->get_char(c); - if (g) return boost::make_shared(*face, g); } - + // Final fallback to empty square if nothing better in any font return boost::make_shared(*faces_.begin(), 0); } From e06c4567895732e2c7d8f3a91f02b3b16b43b88e Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Mon, 19 Mar 2012 10:46:44 +0000 Subject: [PATCH 092/138] even better, use BOOST_FOREACH --- include/mapnik/font_engine_freetype.hpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index 54baaa04d..5b4b87b40 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -46,6 +46,7 @@ extern "C" #include #include #include +#include #ifdef MAPNIK_THREADSAFE #include #endif @@ -168,12 +169,10 @@ public: glyph_ptr get_glyph(unsigned c) const { - std::vector::const_iterator face = faces_.begin(); - std::vector::const_iterator end = faces_.end(); - for (; face != end; ++face) + BOOST_FOREACH ( face_ptr const& face, faces_) { - FT_UInt g = (*face)->get_char(c); - if (g) return boost::make_shared(*face, g); + FT_UInt g = face->get_char(c); + if (g) return boost::make_shared(face, g); } // Final fallback to empty square if nothing better in any font @@ -186,17 +185,17 @@ public: void set_pixel_sizes(unsigned size) { - for (std::vector::iterator face = faces_.begin(); face != faces_.end(); ++face) + BOOST_FOREACH ( face_ptr const& face, faces_) { - (*face)->set_pixel_sizes(size); + face->set_pixel_sizes(size); } } void set_character_sizes(float size) { - for (std::vector::iterator face = faces_.begin(); face != faces_.end(); ++face) + BOOST_FOREACH ( face_ptr const& face, faces_) { - (*face)->set_character_sizes(size); + face->set_character_sizes(size); } } private: From 9b62a19cf42b3daab1da50f2e89352edeb031644 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Mon, 19 Mar 2012 17:12:53 +0100 Subject: [PATCH 093/138] Implement justify-alignment=auto. Closes #1125. --- bindings/python/mapnik_text_placement.cpp | 1 + include/mapnik/placement_finder.hpp | 1 + include/mapnik/text_properties.hpp | 1 + src/placement_finder.cpp | 44 ++++++++++++++---- src/text_properties.cpp | 2 +- src/text_symbolizer.cpp | 1 + .../jalign-auto-200-reference.png | Bin 0 -> 2316 bytes tests/visual_tests/jalign-auto.xml | 30 ++++++++++++ tests/visual_tests/test.py | 3 +- 9 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 tests/visual_tests/jalign-auto-200-reference.png create mode 100644 tests/visual_tests/jalign-auto.xml diff --git a/bindings/python/mapnik_text_placement.cpp b/bindings/python/mapnik_text_placement.cpp index c9f1ac4e5..13de8478b 100644 --- a/bindings/python/mapnik_text_placement.cpp +++ b/bindings/python/mapnik_text_placement.cpp @@ -329,6 +329,7 @@ void export_text_placement() .value("LEFT",J_LEFT) .value("MIDDLE",J_MIDDLE) .value("RIGHT",J_RIGHT) + .value("AUTO", J_AUTO) ; enumeration_("text_transform") diff --git a/include/mapnik/placement_finder.hpp b/include/mapnik/placement_finder.hpp index 1ee636349..57d6ee2ab 100644 --- a/include/mapnik/placement_finder.hpp +++ b/include/mapnik/placement_finder.hpp @@ -137,6 +137,7 @@ private: double first_line_space_; vertical_alignment_e valign_; horizontal_alignment_e halign_; + justify_alignment_e jalign_; std::vector line_breaks_; std::vector > line_sizes_; std::queue< box2d > envelopes_; diff --git a/include/mapnik/text_properties.hpp b/include/mapnik/text_properties.hpp index 9f12b3663..7b6ab953a 100644 --- a/include/mapnik/text_properties.hpp +++ b/include/mapnik/text_properties.hpp @@ -110,6 +110,7 @@ enum justify_alignment J_LEFT = 0, J_MIDDLE, J_RIGHT, + J_AUTO, justify_alignment_MAX }; diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index 719b56dee..5419cb8b6 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -305,23 +305,47 @@ template void placement_finder::init_alignment() { valign_ = p.valign; - if (valign_ == V_AUTO) { + if (valign_ == V_AUTO) + { if (p.displacement.second > 0.0) + { valign_ = V_BOTTOM; - else if (p.displacement.second < 0.0) + } else if (p.displacement.second < 0.0) + { valign_ = V_TOP; - else + } else + { valign_ = V_MIDDLE; + } } halign_ = p.halign; - if (halign_ == H_AUTO) { + if (halign_ == H_AUTO) + { if (p.displacement.first > 0.0) + { halign_ = H_RIGHT; - else if (p.displacement.first < 0.0) + } else if (p.displacement.first < 0.0) + { halign_ = H_LEFT; - else + } else + { halign_ = H_MIDDLE; + } + } + + jalign_ = p.jalign; + if (jalign_ == J_AUTO) + { + if (p.displacement.first > 0.0) + { + jalign_ = J_LEFT; + } else if (p.displacement.first < 0.0) + { + jalign_ = J_RIGHT; + } else { + jalign_ = J_MIDDLE; + } } } @@ -389,9 +413,9 @@ void placement_finder::find_point_placement(double label_x, if (info_.get_rtl()) y = -y; // adjust for desired justification - if (p.jalign == J_LEFT) + if (jalign_ == J_LEFT) x = -(string_width_ / 2.0); - else if (p.jalign == J_RIGHT) + else if (jalign_ == J_RIGHT) x = (string_width_ / 2.0) - line_width; else /* J_MIDDLE */ x = -(line_width / 2.0); @@ -420,9 +444,9 @@ void placement_finder::find_point_placement(double label_x, } // reset to begining of line position - if (p.jalign == J_LEFT) + if (jalign_ == J_LEFT) x = -(string_width_ / 2.0); - else if (p.jalign == J_RIGHT) + else if (jalign_ == J_RIGHT) x = (string_width_ / 2.0) - line_width; else x = -(line_width / 2.0); diff --git a/src/text_properties.cpp b/src/text_properties.cpp index 4587cb5e4..89e4ee6cd 100644 --- a/src/text_properties.cpp +++ b/src/text_properties.cpp @@ -40,7 +40,7 @@ text_symbolizer_properties::text_symbolizer_properties() : displacement(0,0), label_placement(POINT_PLACEMENT), halign(H_AUTO), - jalign(J_MIDDLE), + jalign(J_AUTO), valign(V_AUTO), label_spacing(0), label_position_tolerance(0), diff --git a/src/text_symbolizer.cpp b/src/text_symbolizer.cpp index c060e43d1..75e76849b 100644 --- a/src/text_symbolizer.cpp +++ b/src/text_symbolizer.cpp @@ -69,6 +69,7 @@ static const char * justify_alignment_strings[] = { "left", "center", "right", + "auto", "" }; diff --git a/tests/visual_tests/jalign-auto-200-reference.png b/tests/visual_tests/jalign-auto-200-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..6acf39cdcda902403d7997b85918ab1092898dfa GIT binary patch literal 2316 zcmd5;Yc$(w9u7*CYHeGlrD+*dl^Rv0?xE5!BwA7FP)w=1Z;qPQR4T%Z7S%;f-APdq zRI+Yy>1b-)gLEng73{VWl1Mn@LNx5(?0lF#XV2Nw`LrM2%kR9u_dL(<^1SEGxPpLb zsOhMIKp+hdcQ+qk9o!wND!|-uom372sWLp=TztPT70kljeFKjV#3jVO|61L|B)y5K zYDr7a^m~|6|Nh92N6gO{W?H+rKv!}|Pv59krq1<7>ECoyhU&bAv|7XdB)I2a1G_i^(f1^fJs_hZ;9fR^39d4M_Evg2Mhidn`0H-#{QB zrT;JEQjo%?m|wtZk2BzZWYl=yZ`fFTi#OPoY_5k-x1ob&wkCn}ANC$x5YE2hY%MY8 z)5gh-KcOJlPaFF73BvEPuhshvRYD(+?Z_p9nbLxF&Zuq?aF9-=Chr8@9xXNse*GY~ z3YN`bw7kqW4?I(kBGWrbUZP=be`>!^cg=NU@AB``=px~)z3si_!sWTH8SuVwfC+nz zJWYPD@KA7z^)YkBZ#<0`$>)}ReNpAWXbH(2di zFmg9+{nO_9&uR$j2Og^NzIr;=fsS_$HowuXckrasPkoQS7zX$(Y)My|ZVeqmwUpSP zX_;E4EZCBW%V2NIx7L=Yn?;sB%HEDttla;UcexoxDtrcvpnSpZI&FeuAPIdK@0(LvfrdAaR9o5hsqr>V>?dF)NBgL zIhNIa^)|iKB<~db4%9h8cwDX%4urj8qb43)U1NK0N(3b<&}Q?=3!L`614mU=ztz*j z=@W4qCuY_ch7Q|eBrk7t-03^ZFz)hXO-ww)B3#LbxbTkrd~GhDzdruUPMlm;oSCa z$f_skt6Azf^-Gq*XkK>LS0)<*=H3^pxx-+Obg}Q|=7c0EKS`X) zW+ZWZG^YN*D6y_?ZIWIXrBkV=^dUYbdrazGW;dZxv1+81GajFm)aC2v*9pG7V!K4I z5;2}rD1LVK_SLnu9#K(IBWxaq$K(CndY(}H@bm`G5Ij?L$p}DS{M)iqn0oq&A|#DQ zV>QpMjxql38!$XP40AmD4(v1F97#>es0CO%>3IOGO}Yv2lFKX?iGBdYKOlfXu2HP) z=@mzmO;1)-RQzR_FBIOJcb08!by0ppqTv=SDKMLb{IdbKwj=^*WHbqA!8@G!<|i&Z zf#6wYX6DUHL%$(pTI%u8p%@{n!@$VMNJxBHV=Ma=Uo3kX4N*~1VXc^2ot6;C^Sww z9*Qvc@<%3&oNDoNb;!o)Ztr@LdML=sA8{Gg`0?# zTYyvdUcf1@f-vN^>qG}%fS;n_P6Im)U`NC)nD#e1R#XvspkU4CQ~&Pi&x`i=JNL)Z zu&D^M9C!VOQ)$0D)#e$+pALh2&ZQ`OwP;uCGGtlCYT zVq;^+7>vA#ZxYkoXNU!UcO`^Bis#%2x9sx;bEv0ut`_&AoX_W1H#Ln3EE38^?P^wb%N{Wa3kwr|gZ`cydA+WI z&1P4X=Pw*vM8c!=S)sciukp-C5t#m|8UCPh=_>Zwa! + + + + + My Style + + shape + points.shp + + + + + + diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index 804137c0b..8d9d3166f 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -28,7 +28,8 @@ files = [ ("formating-4", 500), ("shieldsymbolizer-1", 490, 495, 497, 498, 499, 500, 501, 502, 505, 510), ("expressionformat", 500), - ("rtl-point", (200, 200)) + ("rtl-point", (200, 200)), + ("jalign-auto", (200, 200)) ] def render(filename, width, height=100): From ad5bcb70df903f49ff824d46841d0c08faa3a3e0 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Mon, 19 Mar 2012 17:37:21 +0100 Subject: [PATCH 094/138] Update changelog. --- CHANGELOG | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 8dfa52f59..de227fb68 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -26,7 +26,9 @@ Mapnik 2.1.0 - Added parameter in OGR plugin to select a layer by SQL query (besides name or index): see http://www.gdal.org/ogr/ogr_sql.html for specifications (kunitoki) (#472) -- Added suppport for output maps as tiff files (addresses #967 partially) +- Added support for output maps as tiff files (addresses #967 partially) + +- Added support for justify-alignment=auto. This is the new default. (#1125) Mapnik 2.0.0 From a84fcdb1331ee27caa806bdc20705f0175abe127 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Mon, 19 Mar 2012 17:40:51 +0100 Subject: [PATCH 095/138] Update tests. Refs #1125. --- tests/python_tests/object_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/python_tests/object_test.py b/tests/python_tests/object_test.py index 9c9787f4b..cf0920d55 100644 --- a/tests/python_tests/object_test.py +++ b/tests/python_tests/object_test.py @@ -54,7 +54,7 @@ def test_shieldsymbolizer_init(): # r1341 eq_(s.wrap_before, False) eq_(s.horizontal_alignment, mapnik.horizontal_alignment.AUTO) - eq_(s.justify_alignment, mapnik.justify_alignment.MIDDLE) + eq_(s.justify_alignment, mapnik.justify_alignment.AUTO) eq_(s.opacity, 1.0) # r2300 From b2ca10f3a0996fdf6b954f59d687f22fd63824fe Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Mon, 19 Mar 2012 21:19:52 +0000 Subject: [PATCH 096/138] + always premultiply destination buffer for correct ops (ensure no color component exceeds alpha channel) --- include/mapnik/image_compositing.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/mapnik/image_compositing.hpp b/include/mapnik/image_compositing.hpp index c6a334ac0..9dff58045 100644 --- a/include/mapnik/image_compositing.hpp +++ b/include/mapnik/image_compositing.hpp @@ -84,6 +84,7 @@ void composite(T1 & im, T2 & im2, composite_mode_e mode) agg::rendering_buffer mask(im2.getBytes(),im2.width(),im2.height(),im2.width() * 4); agg::pixfmt_custom_blend_rgba pixf(source); + pixf.premultiply(); agg::pixfmt_custom_blend_rgba pixf_mask(mask); switch(mode) From 4843572e1b59ac430da7631405e7747f6de2e342 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 19 Mar 2012 15:42:30 -0700 Subject: [PATCH 097/138] move image_compositing to cpp file --- include/mapnik/image_compositing.hpp | 117 +-------------------------- src/build.py | 1 + 2 files changed, 2 insertions(+), 116 deletions(-) diff --git a/include/mapnik/image_compositing.hpp b/include/mapnik/image_compositing.hpp index 9dff58045..92320c4f8 100644 --- a/include/mapnik/image_compositing.hpp +++ b/include/mapnik/image_compositing.hpp @@ -24,11 +24,6 @@ #define MAPNIK_IMAGE_COMPOSITING_HPP // agg -#include "agg_rendering_buffer.h" -#include "agg_rasterizer_scanline_aa.h" -#include "agg_scanline_u.h" -#include "agg_renderer_scanline.h" -#include "agg_pixfmt_rgba.h" namespace mapnik { @@ -69,117 +64,7 @@ enum composite_mode_e }; template -void composite(T1 & im, T2 & im2, composite_mode_e mode) -{ - typedef agg::rgba8 color; - typedef agg::order_bgra order; - typedef agg::pixel32_type pixel_type; - typedef agg::comp_op_adaptor_rgba blender_type; - typedef agg::pixfmt_custom_blend_rgba pixfmt_type; - typedef agg::renderer_base renderer_type; - typedef agg::comp_op_adaptor_rgba blender_type; - typedef agg::renderer_base renderer_type; - - agg::rendering_buffer source(im.getBytes(),im.width(),im.height(),im.width() * 4); - agg::rendering_buffer mask(im2.getBytes(),im2.width(),im2.height(),im2.width() * 4); - - agg::pixfmt_custom_blend_rgba pixf(source); - pixf.premultiply(); - agg::pixfmt_custom_blend_rgba pixf_mask(mask); - - switch(mode) - { - case clear : - pixf.comp_op(agg::comp_op_clear); - break; - case src: - pixf.comp_op(agg::comp_op_src); - break; - case dst: - pixf.comp_op(agg::comp_op_dst); - break; - case src_over: - pixf.comp_op(agg::comp_op_src_over); - break; - case dst_over: - pixf.comp_op(agg::comp_op_dst_over); - break; - case src_in: - pixf.comp_op(agg::comp_op_src_in); - break; - case dst_in: - pixf.comp_op(agg::comp_op_dst_in); - break; - case src_out: - pixf.comp_op(agg::comp_op_src_out); - break; - case dst_out: - pixf.comp_op(agg::comp_op_dst_out); - break; - case src_atop: - pixf.comp_op(agg::comp_op_src_atop); - break; - case dst_atop: - pixf.comp_op(agg::comp_op_dst_atop); - break; - case _xor: - pixf.comp_op(agg::comp_op_xor); - break; - case plus: - pixf.comp_op(agg::comp_op_plus); - break; - case minus: - pixf.comp_op(agg::comp_op_minus); - break; - case multiply: - pixf.comp_op(agg::comp_op_multiply); - break; - case screen: - pixf.comp_op(agg::comp_op_screen); - break; - case overlay: - pixf.comp_op(agg::comp_op_overlay); - break; - case darken: - pixf.comp_op(agg::comp_op_darken); - break; - case lighten: - pixf.comp_op(agg::comp_op_lighten); - break; - case color_dodge: - pixf.comp_op(agg::comp_op_color_dodge); - break; - case color_burn: - pixf.comp_op(agg::comp_op_color_burn); - break; - case hard_light: - pixf.comp_op(agg::comp_op_hard_light); - break; - case soft_light: - pixf.comp_op(agg::comp_op_soft_light); - break; - case difference: - pixf.comp_op(agg::comp_op_difference); - break; - case exclusion: - pixf.comp_op(agg::comp_op_exclusion); - break; - case contrast: - pixf.comp_op(agg::comp_op_contrast); - break; - case invert: - pixf.comp_op(agg::comp_op_invert); - break; - case invert_rgb: - pixf.comp_op(agg::comp_op_invert_rgb); - break; - } - renderer_type ren(pixf); - agg::renderer_base rb(pixf); - rb.blend_from(pixf_mask,0,0,0,255); +void composite(T1 & im, T2 & im2, composite_mode_e mode); } - -} - #endif // MAPNIK_IMAGE_COMPOSITING_HPP diff --git a/src/build.py b/src/build.py index 25a63496c..59bf949ca 100644 --- a/src/build.py +++ b/src/build.py @@ -105,6 +105,7 @@ source = Split( """ color.cpp conversions.cpp + image_compositing.cpp box2d.cpp building_symbolizer.cpp datasource_cache.cpp From 89877edc670e5421754dacb7c008ea6fdac6bb51 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 19 Mar 2012 15:42:44 -0700 Subject: [PATCH 098/138] move image_compositing to cpp file --- src/image_compositing.cpp | 153 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/image_compositing.cpp diff --git a/src/image_compositing.cpp b/src/image_compositing.cpp new file mode 100644 index 000000000..e4dde9f6f --- /dev/null +++ b/src/image_compositing.cpp @@ -0,0 +1,153 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +// mapnik +#include +#include + +// agg +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_scanline_u.h" +#include "agg_renderer_scanline.h" +#include "agg_pixfmt_rgba.h" + + +namespace mapnik +{ + + +template +void composite(T1 & im, T2 & im2, composite_mode_e mode) +{ + typedef agg::rgba8 color; + typedef agg::order_bgra order; + typedef agg::pixel32_type pixel_type; + typedef agg::comp_op_adaptor_rgba blender_type; + typedef agg::pixfmt_custom_blend_rgba pixfmt_type; + typedef agg::renderer_base renderer_type; + typedef agg::comp_op_adaptor_rgba blender_type; + typedef agg::renderer_base renderer_type; + + agg::rendering_buffer source(im.getBytes(),im.width(),im.height(),im.width() * 4); + agg::rendering_buffer mask(im2.getBytes(),im2.width(),im2.height(),im2.width() * 4); + + agg::pixfmt_custom_blend_rgba pixf(source); + pixf.premultiply(); + agg::pixfmt_custom_blend_rgba pixf_mask(mask); + + switch(mode) + { + case clear : + pixf.comp_op(agg::comp_op_clear); + break; + case src: + pixf.comp_op(agg::comp_op_src); + break; + case dst: + pixf.comp_op(agg::comp_op_dst); + break; + case src_over: + pixf.comp_op(agg::comp_op_src_over); + break; + case dst_over: + pixf.comp_op(agg::comp_op_dst_over); + break; + case src_in: + pixf.comp_op(agg::comp_op_src_in); + break; + case dst_in: + pixf.comp_op(agg::comp_op_dst_in); + break; + case src_out: + pixf.comp_op(agg::comp_op_src_out); + break; + case dst_out: + pixf.comp_op(agg::comp_op_dst_out); + break; + case src_atop: + pixf.comp_op(agg::comp_op_src_atop); + break; + case dst_atop: + pixf.comp_op(agg::comp_op_dst_atop); + break; + case _xor: + pixf.comp_op(agg::comp_op_xor); + break; + case plus: + pixf.comp_op(agg::comp_op_plus); + break; + case minus: + pixf.comp_op(agg::comp_op_minus); + break; + case multiply: + pixf.comp_op(agg::comp_op_multiply); + break; + case screen: + pixf.comp_op(agg::comp_op_screen); + break; + case overlay: + pixf.comp_op(agg::comp_op_overlay); + break; + case darken: + pixf.comp_op(agg::comp_op_darken); + break; + case lighten: + pixf.comp_op(agg::comp_op_lighten); + break; + case color_dodge: + pixf.comp_op(agg::comp_op_color_dodge); + break; + case color_burn: + pixf.comp_op(agg::comp_op_color_burn); + break; + case hard_light: + pixf.comp_op(agg::comp_op_hard_light); + break; + case soft_light: + pixf.comp_op(agg::comp_op_soft_light); + break; + case difference: + pixf.comp_op(agg::comp_op_difference); + break; + case exclusion: + pixf.comp_op(agg::comp_op_exclusion); + break; + case contrast: + pixf.comp_op(agg::comp_op_contrast); + break; + case invert: + pixf.comp_op(agg::comp_op_invert); + break; + case invert_rgb: + pixf.comp_op(agg::comp_op_invert_rgb); + break; + } + renderer_type ren(pixf); + agg::renderer_base rb(pixf); + rb.blend_from(pixf_mask,0,0,0,255); +} + + +template void composite(mapnik::image_data_32 & im, mapnik::image_data_32 & im2, composite_mode_e mode); + +} From f7a387f8af3a58646a89225eeec6f1d481105ff7 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 20 Mar 2012 21:28:21 +0100 Subject: [PATCH 099/138] Change visual tests directory structure. --- tests/visual_tests/clean.sh | 4 +-- tests/visual_tests/{ => data}/lines.osm | 0 tests/visual_tests/{ => data}/points.dbf | Bin tests/visual_tests/{ => data}/points.osm | 0 tests/visual_tests/{ => data}/points.shp | Bin .../expressionformat-500-reference.png | Bin .../formating-1-500-reference.png | Bin .../formating-2-500-reference.png | Bin .../formating-3-500-reference.png | Bin .../formating-4-500-reference.png | Bin .../{ => images}/formating-500-reference.png | Bin .../jalign-auto-200-reference.png | Bin .../{ => images}/lines-1-200-reference.png | Bin .../{ => images}/lines-1-400-reference.png | Bin .../{ => images}/lines-1-600-reference.png | Bin .../{ => images}/lines-1-800-reference.png | Bin .../{ => images}/lines-2-200-reference.png | Bin .../{ => images}/lines-2-400-reference.png | Bin .../{ => images}/lines-2-600-reference.png | Bin .../{ => images}/lines-2-800-reference.png | Bin .../{ => images}/lines-3-200-reference.png | Bin .../{ => images}/lines-3-400-reference.png | Bin .../{ => images}/lines-3-600-reference.png | Bin .../{ => images}/lines-3-800-reference.png | Bin .../lines-shield-200-reference.png | Bin .../lines-shield-400-reference.png | Bin .../lines-shield-600-reference.png | Bin .../lines-shield-800-reference.png | Bin .../{ => images}/list-100-reference.png | Bin .../{ => images}/list-150-reference.png | Bin .../{ => images}/list-200-reference.png | Bin .../{ => images}/list-250-reference.png | Bin .../{ => images}/list-300-reference.png | Bin .../{ => images}/list-400-reference.png | Bin .../{ => images}/list-600-reference.png | Bin .../{ => images}/list-800-reference.png | Bin .../{ => images}/python-IfElse-reference.png | Bin .../{ => images}/python-MyText-reference.png | Bin .../python-TextNode-reference.png | Bin .../{ => images}/rtl-point-200-reference.png | Bin .../shieldsymbolizer-1-490-reference.png | Bin .../shieldsymbolizer-1-495-reference.png | Bin .../shieldsymbolizer-1-497-reference.png | Bin .../shieldsymbolizer-1-498-reference.png | Bin .../shieldsymbolizer-1-499-reference.png | Bin .../shieldsymbolizer-1-500-reference.png | Bin .../shieldsymbolizer-1-501-reference.png | Bin .../shieldsymbolizer-1-502-reference.png | Bin .../shieldsymbolizer-1-505-reference.png | Bin .../shieldsymbolizer-1-510-reference.png | Bin .../{ => images}/simple-100-reference.png | Bin .../{ => images}/simple-150-reference.png | Bin .../{ => images}/simple-200-reference.png | Bin .../{ => images}/simple-250-reference.png | Bin .../{ => images}/simple-300-reference.png | Bin .../{ => images}/simple-400-reference.png | Bin .../{ => images}/simple-600-reference.png | Bin .../{ => images}/simple-800-reference.png | Bin .../{ => images}/simple-E-500-reference.png | Bin .../{ => images}/simple-N-500-reference.png | Bin .../{ => images}/simple-NE-500-reference.png | Bin .../{ => images}/simple-NW-500-reference.png | Bin .../{ => images}/simple-S-500-reference.png | Bin .../{ => images}/simple-SE-500-reference.png | Bin .../{ => images}/simple-SW-500-reference.png | Bin .../{ => images}/simple-W-500-reference.png | Bin .../{ => styles}/expressionformat.xml | 2 +- .../visual_tests/{ => styles}/formating-1.xml | 2 +- .../visual_tests/{ => styles}/formating-2.xml | 2 +- .../visual_tests/{ => styles}/formating-3.xml | 2 +- .../visual_tests/{ => styles}/formating-4.xml | 2 +- tests/visual_tests/{ => styles}/formating.xml | 2 +- .../visual_tests/{ => styles}/jalign-auto.xml | 2 +- tests/visual_tests/{ => styles}/lines-1.xml | 2 +- tests/visual_tests/{ => styles}/lines-2.xml | 2 +- tests/visual_tests/{ => styles}/lines-3.xml | 2 +- .../{ => styles}/lines-shield.xml | 4 +-- tests/visual_tests/{ => styles}/list.xml | 4 +-- tests/visual_tests/{ => styles}/rtl-point.xml | 2 +- .../{ => styles}/shieldsymbolizer-1.xml | 24 +++++++++--------- tests/visual_tests/{ => styles}/simple-E.xml | 2 +- tests/visual_tests/{ => styles}/simple-N.xml | 2 +- tests/visual_tests/{ => styles}/simple-NE.xml | 2 +- tests/visual_tests/{ => styles}/simple-NW.xml | 2 +- tests/visual_tests/{ => styles}/simple-S.xml | 2 +- tests/visual_tests/{ => styles}/simple-SE.xml | 2 +- tests/visual_tests/{ => styles}/simple-SW.xml | 2 +- tests/visual_tests/{ => styles}/simple-W.xml | 2 +- tests/visual_tests/{ => styles}/simple.xml | 6 +---- tests/visual_tests/test.py | 6 ++--- tests/visual_tests/test_python.py | 6 +++-- 91 files changed, 45 insertions(+), 47 deletions(-) rename tests/visual_tests/{ => data}/lines.osm (100%) rename tests/visual_tests/{ => data}/points.dbf (100%) rename tests/visual_tests/{ => data}/points.osm (100%) rename tests/visual_tests/{ => data}/points.shp (100%) rename tests/visual_tests/{ => images}/expressionformat-500-reference.png (100%) rename tests/visual_tests/{ => images}/formating-1-500-reference.png (100%) rename tests/visual_tests/{ => images}/formating-2-500-reference.png (100%) rename tests/visual_tests/{ => images}/formating-3-500-reference.png (100%) rename tests/visual_tests/{ => images}/formating-4-500-reference.png (100%) rename tests/visual_tests/{ => images}/formating-500-reference.png (100%) rename tests/visual_tests/{ => images}/jalign-auto-200-reference.png (100%) rename tests/visual_tests/{ => images}/lines-1-200-reference.png (100%) rename tests/visual_tests/{ => images}/lines-1-400-reference.png (100%) rename tests/visual_tests/{ => images}/lines-1-600-reference.png (100%) rename tests/visual_tests/{ => images}/lines-1-800-reference.png (100%) rename tests/visual_tests/{ => images}/lines-2-200-reference.png (100%) rename tests/visual_tests/{ => images}/lines-2-400-reference.png (100%) rename tests/visual_tests/{ => images}/lines-2-600-reference.png (100%) rename tests/visual_tests/{ => images}/lines-2-800-reference.png (100%) rename tests/visual_tests/{ => images}/lines-3-200-reference.png (100%) rename tests/visual_tests/{ => images}/lines-3-400-reference.png (100%) rename tests/visual_tests/{ => images}/lines-3-600-reference.png (100%) rename tests/visual_tests/{ => images}/lines-3-800-reference.png (100%) rename tests/visual_tests/{ => images}/lines-shield-200-reference.png (100%) rename tests/visual_tests/{ => images}/lines-shield-400-reference.png (100%) rename tests/visual_tests/{ => images}/lines-shield-600-reference.png (100%) rename tests/visual_tests/{ => images}/lines-shield-800-reference.png (100%) rename tests/visual_tests/{ => images}/list-100-reference.png (100%) rename tests/visual_tests/{ => images}/list-150-reference.png (100%) rename tests/visual_tests/{ => images}/list-200-reference.png (100%) rename tests/visual_tests/{ => images}/list-250-reference.png (100%) rename tests/visual_tests/{ => images}/list-300-reference.png (100%) rename tests/visual_tests/{ => images}/list-400-reference.png (100%) rename tests/visual_tests/{ => images}/list-600-reference.png (100%) rename tests/visual_tests/{ => images}/list-800-reference.png (100%) rename tests/visual_tests/{ => images}/python-IfElse-reference.png (100%) rename tests/visual_tests/{ => images}/python-MyText-reference.png (100%) rename tests/visual_tests/{ => images}/python-TextNode-reference.png (100%) rename tests/visual_tests/{ => images}/rtl-point-200-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-490-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-495-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-497-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-498-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-499-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-500-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-501-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-502-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-505-reference.png (100%) rename tests/visual_tests/{ => images}/shieldsymbolizer-1-510-reference.png (100%) rename tests/visual_tests/{ => images}/simple-100-reference.png (100%) rename tests/visual_tests/{ => images}/simple-150-reference.png (100%) rename tests/visual_tests/{ => images}/simple-200-reference.png (100%) rename tests/visual_tests/{ => images}/simple-250-reference.png (100%) rename tests/visual_tests/{ => images}/simple-300-reference.png (100%) rename tests/visual_tests/{ => images}/simple-400-reference.png (100%) rename tests/visual_tests/{ => images}/simple-600-reference.png (100%) rename tests/visual_tests/{ => images}/simple-800-reference.png (100%) rename tests/visual_tests/{ => images}/simple-E-500-reference.png (100%) rename tests/visual_tests/{ => images}/simple-N-500-reference.png (100%) rename tests/visual_tests/{ => images}/simple-NE-500-reference.png (100%) rename tests/visual_tests/{ => images}/simple-NW-500-reference.png (100%) rename tests/visual_tests/{ => images}/simple-S-500-reference.png (100%) rename tests/visual_tests/{ => images}/simple-SE-500-reference.png (100%) rename tests/visual_tests/{ => images}/simple-SW-500-reference.png (100%) rename tests/visual_tests/{ => images}/simple-W-500-reference.png (100%) rename tests/visual_tests/{ => styles}/expressionformat.xml (90%) rename tests/visual_tests/{ => styles}/formating-1.xml (91%) rename tests/visual_tests/{ => styles}/formating-2.xml (91%) rename tests/visual_tests/{ => styles}/formating-3.xml (91%) rename tests/visual_tests/{ => styles}/formating-4.xml (89%) rename tests/visual_tests/{ => styles}/formating.xml (91%) rename tests/visual_tests/{ => styles}/jalign-auto.xml (96%) rename tests/visual_tests/{ => styles}/lines-1.xml (89%) rename tests/visual_tests/{ => styles}/lines-2.xml (90%) rename tests/visual_tests/{ => styles}/lines-3.xml (90%) rename tests/visual_tests/{ => styles}/lines-shield.xml (76%) rename tests/visual_tests/{ => styles}/list.xml (85%) rename tests/visual_tests/{ => styles}/rtl-point.xml (92%) rename tests/visual_tests/{ => styles}/shieldsymbolizer-1.xml (58%) rename tests/visual_tests/{ => styles}/simple-E.xml (90%) rename tests/visual_tests/{ => styles}/simple-N.xml (90%) rename tests/visual_tests/{ => styles}/simple-NE.xml (90%) rename tests/visual_tests/{ => styles}/simple-NW.xml (90%) rename tests/visual_tests/{ => styles}/simple-S.xml (90%) rename tests/visual_tests/{ => styles}/simple-SE.xml (90%) rename tests/visual_tests/{ => styles}/simple-SW.xml (90%) rename tests/visual_tests/{ => styles}/simple-W.xml (90%) rename tests/visual_tests/{ => styles}/simple.xml (77%) diff --git a/tests/visual_tests/clean.sh b/tests/visual_tests/clean.sh index ba31ecae5..1278159f4 100755 --- a/tests/visual_tests/clean.sh +++ b/tests/visual_tests/clean.sh @@ -1,3 +1,3 @@ -rm -f *-agg.png -rm -f *-out.xml +rm -f images/*-agg.png +rm -f xml_output/*-out.xml diff --git a/tests/visual_tests/lines.osm b/tests/visual_tests/data/lines.osm similarity index 100% rename from tests/visual_tests/lines.osm rename to tests/visual_tests/data/lines.osm diff --git a/tests/visual_tests/points.dbf b/tests/visual_tests/data/points.dbf similarity index 100% rename from tests/visual_tests/points.dbf rename to tests/visual_tests/data/points.dbf diff --git a/tests/visual_tests/points.osm b/tests/visual_tests/data/points.osm similarity index 100% rename from tests/visual_tests/points.osm rename to tests/visual_tests/data/points.osm diff --git a/tests/visual_tests/points.shp b/tests/visual_tests/data/points.shp similarity index 100% rename from tests/visual_tests/points.shp rename to tests/visual_tests/data/points.shp diff --git a/tests/visual_tests/expressionformat-500-reference.png b/tests/visual_tests/images/expressionformat-500-reference.png similarity index 100% rename from tests/visual_tests/expressionformat-500-reference.png rename to tests/visual_tests/images/expressionformat-500-reference.png diff --git a/tests/visual_tests/formating-1-500-reference.png b/tests/visual_tests/images/formating-1-500-reference.png similarity index 100% rename from tests/visual_tests/formating-1-500-reference.png rename to tests/visual_tests/images/formating-1-500-reference.png diff --git a/tests/visual_tests/formating-2-500-reference.png b/tests/visual_tests/images/formating-2-500-reference.png similarity index 100% rename from tests/visual_tests/formating-2-500-reference.png rename to tests/visual_tests/images/formating-2-500-reference.png diff --git a/tests/visual_tests/formating-3-500-reference.png b/tests/visual_tests/images/formating-3-500-reference.png similarity index 100% rename from tests/visual_tests/formating-3-500-reference.png rename to tests/visual_tests/images/formating-3-500-reference.png diff --git a/tests/visual_tests/formating-4-500-reference.png b/tests/visual_tests/images/formating-4-500-reference.png similarity index 100% rename from tests/visual_tests/formating-4-500-reference.png rename to tests/visual_tests/images/formating-4-500-reference.png diff --git a/tests/visual_tests/formating-500-reference.png b/tests/visual_tests/images/formating-500-reference.png similarity index 100% rename from tests/visual_tests/formating-500-reference.png rename to tests/visual_tests/images/formating-500-reference.png diff --git a/tests/visual_tests/jalign-auto-200-reference.png b/tests/visual_tests/images/jalign-auto-200-reference.png similarity index 100% rename from tests/visual_tests/jalign-auto-200-reference.png rename to tests/visual_tests/images/jalign-auto-200-reference.png diff --git a/tests/visual_tests/lines-1-200-reference.png b/tests/visual_tests/images/lines-1-200-reference.png similarity index 100% rename from tests/visual_tests/lines-1-200-reference.png rename to tests/visual_tests/images/lines-1-200-reference.png diff --git a/tests/visual_tests/lines-1-400-reference.png b/tests/visual_tests/images/lines-1-400-reference.png similarity index 100% rename from tests/visual_tests/lines-1-400-reference.png rename to tests/visual_tests/images/lines-1-400-reference.png diff --git a/tests/visual_tests/lines-1-600-reference.png b/tests/visual_tests/images/lines-1-600-reference.png similarity index 100% rename from tests/visual_tests/lines-1-600-reference.png rename to tests/visual_tests/images/lines-1-600-reference.png diff --git a/tests/visual_tests/lines-1-800-reference.png b/tests/visual_tests/images/lines-1-800-reference.png similarity index 100% rename from tests/visual_tests/lines-1-800-reference.png rename to tests/visual_tests/images/lines-1-800-reference.png diff --git a/tests/visual_tests/lines-2-200-reference.png b/tests/visual_tests/images/lines-2-200-reference.png similarity index 100% rename from tests/visual_tests/lines-2-200-reference.png rename to tests/visual_tests/images/lines-2-200-reference.png diff --git a/tests/visual_tests/lines-2-400-reference.png b/tests/visual_tests/images/lines-2-400-reference.png similarity index 100% rename from tests/visual_tests/lines-2-400-reference.png rename to tests/visual_tests/images/lines-2-400-reference.png diff --git a/tests/visual_tests/lines-2-600-reference.png b/tests/visual_tests/images/lines-2-600-reference.png similarity index 100% rename from tests/visual_tests/lines-2-600-reference.png rename to tests/visual_tests/images/lines-2-600-reference.png diff --git a/tests/visual_tests/lines-2-800-reference.png b/tests/visual_tests/images/lines-2-800-reference.png similarity index 100% rename from tests/visual_tests/lines-2-800-reference.png rename to tests/visual_tests/images/lines-2-800-reference.png diff --git a/tests/visual_tests/lines-3-200-reference.png b/tests/visual_tests/images/lines-3-200-reference.png similarity index 100% rename from tests/visual_tests/lines-3-200-reference.png rename to tests/visual_tests/images/lines-3-200-reference.png diff --git a/tests/visual_tests/lines-3-400-reference.png b/tests/visual_tests/images/lines-3-400-reference.png similarity index 100% rename from tests/visual_tests/lines-3-400-reference.png rename to tests/visual_tests/images/lines-3-400-reference.png diff --git a/tests/visual_tests/lines-3-600-reference.png b/tests/visual_tests/images/lines-3-600-reference.png similarity index 100% rename from tests/visual_tests/lines-3-600-reference.png rename to tests/visual_tests/images/lines-3-600-reference.png diff --git a/tests/visual_tests/lines-3-800-reference.png b/tests/visual_tests/images/lines-3-800-reference.png similarity index 100% rename from tests/visual_tests/lines-3-800-reference.png rename to tests/visual_tests/images/lines-3-800-reference.png diff --git a/tests/visual_tests/lines-shield-200-reference.png b/tests/visual_tests/images/lines-shield-200-reference.png similarity index 100% rename from tests/visual_tests/lines-shield-200-reference.png rename to tests/visual_tests/images/lines-shield-200-reference.png diff --git a/tests/visual_tests/lines-shield-400-reference.png b/tests/visual_tests/images/lines-shield-400-reference.png similarity index 100% rename from tests/visual_tests/lines-shield-400-reference.png rename to tests/visual_tests/images/lines-shield-400-reference.png diff --git a/tests/visual_tests/lines-shield-600-reference.png b/tests/visual_tests/images/lines-shield-600-reference.png similarity index 100% rename from tests/visual_tests/lines-shield-600-reference.png rename to tests/visual_tests/images/lines-shield-600-reference.png diff --git a/tests/visual_tests/lines-shield-800-reference.png b/tests/visual_tests/images/lines-shield-800-reference.png similarity index 100% rename from tests/visual_tests/lines-shield-800-reference.png rename to tests/visual_tests/images/lines-shield-800-reference.png diff --git a/tests/visual_tests/list-100-reference.png b/tests/visual_tests/images/list-100-reference.png similarity index 100% rename from tests/visual_tests/list-100-reference.png rename to tests/visual_tests/images/list-100-reference.png diff --git a/tests/visual_tests/list-150-reference.png b/tests/visual_tests/images/list-150-reference.png similarity index 100% rename from tests/visual_tests/list-150-reference.png rename to tests/visual_tests/images/list-150-reference.png diff --git a/tests/visual_tests/list-200-reference.png b/tests/visual_tests/images/list-200-reference.png similarity index 100% rename from tests/visual_tests/list-200-reference.png rename to tests/visual_tests/images/list-200-reference.png diff --git a/tests/visual_tests/list-250-reference.png b/tests/visual_tests/images/list-250-reference.png similarity index 100% rename from tests/visual_tests/list-250-reference.png rename to tests/visual_tests/images/list-250-reference.png diff --git a/tests/visual_tests/list-300-reference.png b/tests/visual_tests/images/list-300-reference.png similarity index 100% rename from tests/visual_tests/list-300-reference.png rename to tests/visual_tests/images/list-300-reference.png diff --git a/tests/visual_tests/list-400-reference.png b/tests/visual_tests/images/list-400-reference.png similarity index 100% rename from tests/visual_tests/list-400-reference.png rename to tests/visual_tests/images/list-400-reference.png diff --git a/tests/visual_tests/list-600-reference.png b/tests/visual_tests/images/list-600-reference.png similarity index 100% rename from tests/visual_tests/list-600-reference.png rename to tests/visual_tests/images/list-600-reference.png diff --git a/tests/visual_tests/list-800-reference.png b/tests/visual_tests/images/list-800-reference.png similarity index 100% rename from tests/visual_tests/list-800-reference.png rename to tests/visual_tests/images/list-800-reference.png diff --git a/tests/visual_tests/python-IfElse-reference.png b/tests/visual_tests/images/python-IfElse-reference.png similarity index 100% rename from tests/visual_tests/python-IfElse-reference.png rename to tests/visual_tests/images/python-IfElse-reference.png diff --git a/tests/visual_tests/python-MyText-reference.png b/tests/visual_tests/images/python-MyText-reference.png similarity index 100% rename from tests/visual_tests/python-MyText-reference.png rename to tests/visual_tests/images/python-MyText-reference.png diff --git a/tests/visual_tests/python-TextNode-reference.png b/tests/visual_tests/images/python-TextNode-reference.png similarity index 100% rename from tests/visual_tests/python-TextNode-reference.png rename to tests/visual_tests/images/python-TextNode-reference.png diff --git a/tests/visual_tests/rtl-point-200-reference.png b/tests/visual_tests/images/rtl-point-200-reference.png similarity index 100% rename from tests/visual_tests/rtl-point-200-reference.png rename to tests/visual_tests/images/rtl-point-200-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-490-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-490-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-490-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-490-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-495-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-495-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-495-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-495-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-497-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-497-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-497-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-497-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-498-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-498-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-498-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-498-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-499-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-499-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-499-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-499-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-500-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-500-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-500-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-500-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-501-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-501-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-501-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-501-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-502-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-502-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-502-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-502-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-505-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-505-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-505-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-505-reference.png diff --git a/tests/visual_tests/shieldsymbolizer-1-510-reference.png b/tests/visual_tests/images/shieldsymbolizer-1-510-reference.png similarity index 100% rename from tests/visual_tests/shieldsymbolizer-1-510-reference.png rename to tests/visual_tests/images/shieldsymbolizer-1-510-reference.png diff --git a/tests/visual_tests/simple-100-reference.png b/tests/visual_tests/images/simple-100-reference.png similarity index 100% rename from tests/visual_tests/simple-100-reference.png rename to tests/visual_tests/images/simple-100-reference.png diff --git a/tests/visual_tests/simple-150-reference.png b/tests/visual_tests/images/simple-150-reference.png similarity index 100% rename from tests/visual_tests/simple-150-reference.png rename to tests/visual_tests/images/simple-150-reference.png diff --git a/tests/visual_tests/simple-200-reference.png b/tests/visual_tests/images/simple-200-reference.png similarity index 100% rename from tests/visual_tests/simple-200-reference.png rename to tests/visual_tests/images/simple-200-reference.png diff --git a/tests/visual_tests/simple-250-reference.png b/tests/visual_tests/images/simple-250-reference.png similarity index 100% rename from tests/visual_tests/simple-250-reference.png rename to tests/visual_tests/images/simple-250-reference.png diff --git a/tests/visual_tests/simple-300-reference.png b/tests/visual_tests/images/simple-300-reference.png similarity index 100% rename from tests/visual_tests/simple-300-reference.png rename to tests/visual_tests/images/simple-300-reference.png diff --git a/tests/visual_tests/simple-400-reference.png b/tests/visual_tests/images/simple-400-reference.png similarity index 100% rename from tests/visual_tests/simple-400-reference.png rename to tests/visual_tests/images/simple-400-reference.png diff --git a/tests/visual_tests/simple-600-reference.png b/tests/visual_tests/images/simple-600-reference.png similarity index 100% rename from tests/visual_tests/simple-600-reference.png rename to tests/visual_tests/images/simple-600-reference.png diff --git a/tests/visual_tests/simple-800-reference.png b/tests/visual_tests/images/simple-800-reference.png similarity index 100% rename from tests/visual_tests/simple-800-reference.png rename to tests/visual_tests/images/simple-800-reference.png diff --git a/tests/visual_tests/simple-E-500-reference.png b/tests/visual_tests/images/simple-E-500-reference.png similarity index 100% rename from tests/visual_tests/simple-E-500-reference.png rename to tests/visual_tests/images/simple-E-500-reference.png diff --git a/tests/visual_tests/simple-N-500-reference.png b/tests/visual_tests/images/simple-N-500-reference.png similarity index 100% rename from tests/visual_tests/simple-N-500-reference.png rename to tests/visual_tests/images/simple-N-500-reference.png diff --git a/tests/visual_tests/simple-NE-500-reference.png b/tests/visual_tests/images/simple-NE-500-reference.png similarity index 100% rename from tests/visual_tests/simple-NE-500-reference.png rename to tests/visual_tests/images/simple-NE-500-reference.png diff --git a/tests/visual_tests/simple-NW-500-reference.png b/tests/visual_tests/images/simple-NW-500-reference.png similarity index 100% rename from tests/visual_tests/simple-NW-500-reference.png rename to tests/visual_tests/images/simple-NW-500-reference.png diff --git a/tests/visual_tests/simple-S-500-reference.png b/tests/visual_tests/images/simple-S-500-reference.png similarity index 100% rename from tests/visual_tests/simple-S-500-reference.png rename to tests/visual_tests/images/simple-S-500-reference.png diff --git a/tests/visual_tests/simple-SE-500-reference.png b/tests/visual_tests/images/simple-SE-500-reference.png similarity index 100% rename from tests/visual_tests/simple-SE-500-reference.png rename to tests/visual_tests/images/simple-SE-500-reference.png diff --git a/tests/visual_tests/simple-SW-500-reference.png b/tests/visual_tests/images/simple-SW-500-reference.png similarity index 100% rename from tests/visual_tests/simple-SW-500-reference.png rename to tests/visual_tests/images/simple-SW-500-reference.png diff --git a/tests/visual_tests/simple-W-500-reference.png b/tests/visual_tests/images/simple-W-500-reference.png similarity index 100% rename from tests/visual_tests/simple-W-500-reference.png rename to tests/visual_tests/images/simple-W-500-reference.png diff --git a/tests/visual_tests/expressionformat.xml b/tests/visual_tests/styles/expressionformat.xml similarity index 90% rename from tests/visual_tests/expressionformat.xml rename to tests/visual_tests/styles/expressionformat.xml index 3c7b74b03..5c66ab54c 100644 --- a/tests/visual_tests/expressionformat.xml +++ b/tests/visual_tests/styles/expressionformat.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/formating-1.xml b/tests/visual_tests/styles/formating-1.xml similarity index 91% rename from tests/visual_tests/formating-1.xml rename to tests/visual_tests/styles/formating-1.xml index 75158e8b5..a044f662c 100644 --- a/tests/visual_tests/formating-1.xml +++ b/tests/visual_tests/styles/formating-1.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/formating-2.xml b/tests/visual_tests/styles/formating-2.xml similarity index 91% rename from tests/visual_tests/formating-2.xml rename to tests/visual_tests/styles/formating-2.xml index 4fda094db..285646515 100644 --- a/tests/visual_tests/formating-2.xml +++ b/tests/visual_tests/styles/formating-2.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/formating-3.xml b/tests/visual_tests/styles/formating-3.xml similarity index 91% rename from tests/visual_tests/formating-3.xml rename to tests/visual_tests/styles/formating-3.xml index 1e1bbd048..159ef880c 100644 --- a/tests/visual_tests/formating-3.xml +++ b/tests/visual_tests/styles/formating-3.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/formating-4.xml b/tests/visual_tests/styles/formating-4.xml similarity index 89% rename from tests/visual_tests/formating-4.xml rename to tests/visual_tests/styles/formating-4.xml index 746f38d02..551cd09d5 100644 --- a/tests/visual_tests/formating-4.xml +++ b/tests/visual_tests/styles/formating-4.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/formating.xml b/tests/visual_tests/styles/formating.xml similarity index 91% rename from tests/visual_tests/formating.xml rename to tests/visual_tests/styles/formating.xml index d59c7b8da..acef45dd7 100644 --- a/tests/visual_tests/formating.xml +++ b/tests/visual_tests/styles/formating.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/jalign-auto.xml b/tests/visual_tests/styles/jalign-auto.xml similarity index 96% rename from tests/visual_tests/jalign-auto.xml rename to tests/visual_tests/styles/jalign-auto.xml index d3c8631f0..8956751e5 100644 --- a/tests/visual_tests/jalign-auto.xml +++ b/tests/visual_tests/styles/jalign-auto.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/lines-1.xml b/tests/visual_tests/styles/lines-1.xml similarity index 89% rename from tests/visual_tests/lines-1.xml rename to tests/visual_tests/styles/lines-1.xml index 7df2294c7..5b8fe6a58 100644 --- a/tests/visual_tests/lines-1.xml +++ b/tests/visual_tests/styles/lines-1.xml @@ -6,7 +6,7 @@ My Style osm - lines.osm + ../data/lines.osm diff --git a/tests/visual_tests/lines-2.xml b/tests/visual_tests/styles/lines-2.xml similarity index 90% rename from tests/visual_tests/lines-2.xml rename to tests/visual_tests/styles/lines-2.xml index 1c77a3115..9b32abb73 100644 --- a/tests/visual_tests/lines-2.xml +++ b/tests/visual_tests/styles/lines-2.xml @@ -6,7 +6,7 @@ My Style osm - lines.osm + ../data/lines.osm diff --git a/tests/visual_tests/lines-3.xml b/tests/visual_tests/styles/lines-3.xml similarity index 90% rename from tests/visual_tests/lines-3.xml rename to tests/visual_tests/styles/lines-3.xml index ef37dc51c..13f5cc332 100644 --- a/tests/visual_tests/lines-3.xml +++ b/tests/visual_tests/styles/lines-3.xml @@ -6,7 +6,7 @@ My Style osm - lines.osm + ../data/lines.osm diff --git a/tests/visual_tests/lines-shield.xml b/tests/visual_tests/styles/lines-shield.xml similarity index 76% rename from tests/visual_tests/lines-shield.xml rename to tests/visual_tests/styles/lines-shield.xml index 05a0f4fd2..4402411a7 100644 --- a/tests/visual_tests/lines-shield.xml +++ b/tests/visual_tests/styles/lines-shield.xml @@ -6,14 +6,14 @@ My Style osm - lines.osm + ../data/lines.osm diff --git a/tests/visual_tests/list.xml b/tests/visual_tests/styles/list.xml similarity index 85% rename from tests/visual_tests/list.xml rename to tests/visual_tests/styles/list.xml index 93ef3726d..e146ded22 100644 --- a/tests/visual_tests/list.xml +++ b/tests/visual_tests/styles/list.xml @@ -7,9 +7,9 @@ + ../data/points.osm--> shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/rtl-point.xml b/tests/visual_tests/styles/rtl-point.xml similarity index 92% rename from tests/visual_tests/rtl-point.xml rename to tests/visual_tests/styles/rtl-point.xml index c29a41797..54edac854 100644 --- a/tests/visual_tests/rtl-point.xml +++ b/tests/visual_tests/styles/rtl-point.xml @@ -10,7 +10,7 @@ points.osm --> shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/shieldsymbolizer-1.xml b/tests/visual_tests/styles/shieldsymbolizer-1.xml similarity index 58% rename from tests/visual_tests/shieldsymbolizer-1.xml rename to tests/visual_tests/styles/shieldsymbolizer-1.xml index 69ec6f2f5..90b456890 100644 --- a/tests/visual_tests/shieldsymbolizer-1.xml +++ b/tests/visual_tests/styles/shieldsymbolizer-1.xml @@ -6,53 +6,53 @@ My Style shape - points.shp + ../../data/points.shp diff --git a/tests/visual_tests/simple-E.xml b/tests/visual_tests/styles/simple-E.xml similarity index 90% rename from tests/visual_tests/simple-E.xml rename to tests/visual_tests/styles/simple-E.xml index 31e11acaa..9a0668bd0 100644 --- a/tests/visual_tests/simple-E.xml +++ b/tests/visual_tests/styles/simple-E.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/simple-N.xml b/tests/visual_tests/styles/simple-N.xml similarity index 90% rename from tests/visual_tests/simple-N.xml rename to tests/visual_tests/styles/simple-N.xml index 919e0d2b6..74265ec5a 100644 --- a/tests/visual_tests/simple-N.xml +++ b/tests/visual_tests/styles/simple-N.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/simple-NE.xml b/tests/visual_tests/styles/simple-NE.xml similarity index 90% rename from tests/visual_tests/simple-NE.xml rename to tests/visual_tests/styles/simple-NE.xml index 74c6a5d09..df1095195 100644 --- a/tests/visual_tests/simple-NE.xml +++ b/tests/visual_tests/styles/simple-NE.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/simple-NW.xml b/tests/visual_tests/styles/simple-NW.xml similarity index 90% rename from tests/visual_tests/simple-NW.xml rename to tests/visual_tests/styles/simple-NW.xml index 5e80dc607..120e26fcb 100644 --- a/tests/visual_tests/simple-NW.xml +++ b/tests/visual_tests/styles/simple-NW.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/simple-S.xml b/tests/visual_tests/styles/simple-S.xml similarity index 90% rename from tests/visual_tests/simple-S.xml rename to tests/visual_tests/styles/simple-S.xml index 1ada1baca..e738ab8b4 100644 --- a/tests/visual_tests/simple-S.xml +++ b/tests/visual_tests/styles/simple-S.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/simple-SE.xml b/tests/visual_tests/styles/simple-SE.xml similarity index 90% rename from tests/visual_tests/simple-SE.xml rename to tests/visual_tests/styles/simple-SE.xml index c8ee4f6d5..ae43761b0 100644 --- a/tests/visual_tests/simple-SE.xml +++ b/tests/visual_tests/styles/simple-SE.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/simple-SW.xml b/tests/visual_tests/styles/simple-SW.xml similarity index 90% rename from tests/visual_tests/simple-SW.xml rename to tests/visual_tests/styles/simple-SW.xml index 641452d4b..7b206417c 100644 --- a/tests/visual_tests/simple-SW.xml +++ b/tests/visual_tests/styles/simple-SW.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/simple-W.xml b/tests/visual_tests/styles/simple-W.xml similarity index 90% rename from tests/visual_tests/simple-W.xml rename to tests/visual_tests/styles/simple-W.xml index 012dc4375..cd0708a7a 100644 --- a/tests/visual_tests/simple-W.xml +++ b/tests/visual_tests/styles/simple-W.xml @@ -6,7 +6,7 @@ My Style shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/simple.xml b/tests/visual_tests/styles/simple.xml similarity index 77% rename from tests/visual_tests/simple.xml rename to tests/visual_tests/styles/simple.xml index cc008f598..61bb07748 100644 --- a/tests/visual_tests/simple.xml +++ b/tests/visual_tests/styles/simple.xml @@ -5,12 +5,8 @@ My Style - shape - points.shp + ../data/points.shp diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index 8d9d3166f..cbc36bcad 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -39,10 +39,10 @@ def render(filename, width, height=100): width = int(width) height = int(height) m = mapnik.Map(width, height) - mapnik.load_map(m, os.path.join(dirname, "%s.xml" % filename), False) + mapnik.load_map(m, os.path.join(dirname, "styles", "%s.xml" % filename), False) bbox = mapnik.Box2d(-0.05, -0.01, 0.95, 0.01) m.zoom_to_box(bbox) - basefn = os.path.join(dirname,'%s-%d' % (filename, width)) + basefn = os.path.join(dirname, "images", '%s-%d' % (filename, width)) mapnik.render_to_file(m, basefn+'-agg.png') diff = compare(basefn + '-agg.png', basefn + '-reference.png') if diff > 0: @@ -63,6 +63,6 @@ for f in files: m = render(f[0], width[0], width[1]) else: m = render(f[0], width) - mapnik.save_map(m, os.path.join(dirname,"%s-out.xml" % f[0])) + mapnik.save_map(m, os.path.join(dirname, 'xml_output', "%s-out.xml" % f[0])) summary() diff --git a/tests/visual_tests/test_python.py b/tests/visual_tests/test_python.py index e45ab6e55..db6117c4c 100755 --- a/tests/visual_tests/test_python.py +++ b/tests/visual_tests/test_python.py @@ -1,6 +1,8 @@ #!/usr/bin/env python import mapnik import sys +import os.path +import compare class MyText(mapnik.FormattingNode): def __init__(self): @@ -67,7 +69,7 @@ m.append_style('Style', style) layer = mapnik.Layer('Layer') -layer.datasource = mapnik.Shapefile(file="points.shp") +layer.datasource = mapnik.Shapefile(file="data/points.shp") layer.styles.append('Style') m.layers.append(layer) @@ -95,4 +97,4 @@ format_trees = [ for format_tree in format_trees: text.placements.defaults.format_tree = format_tree[1] - mapnik.render_to_file(m, 'python-%s.png' % format_tree[0], 'png') + mapnik.render_to_file(m, os.path.join("images", 'python-%s.png' % format_tree[0]), 'png') From fe2879ac42dc43a382317c01749de1db50aed13b Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 20 Mar 2012 21:34:16 +0100 Subject: [PATCH 100/138] Update python tests. --- .../images/python-Format-reference.png | Bin 0 -> 2958 bytes .../images/python-List-reference.png | Bin 0 -> 4599 bytes tests/visual_tests/test_python.py | 7 ++++++- 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 tests/visual_tests/images/python-Format-reference.png create mode 100644 tests/visual_tests/images/python-List-reference.png diff --git a/tests/visual_tests/images/python-Format-reference.png b/tests/visual_tests/images/python-Format-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..1e0426a233f4a00b8fa84046a701ae0041f49ee6 GIT binary patch literal 2958 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 literal 0 HcmV?d00001 diff --git a/tests/visual_tests/images/python-List-reference.png b/tests/visual_tests/images/python-List-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..21f6e4f58211a895320794b7b9505f22b4125f50 GIT binary patch literal 4599 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 literal 0 HcmV?d00001 diff --git a/tests/visual_tests/test_python.py b/tests/visual_tests/test_python.py index db6117c4c..0cba25907 100755 --- a/tests/visual_tests/test_python.py +++ b/tests/visual_tests/test_python.py @@ -2,7 +2,7 @@ import mapnik import sys import os.path -import compare +from compare import compare, summary class MyText(mapnik.FormattingNode): def __init__(self): @@ -98,3 +98,8 @@ format_trees = [ for format_tree in format_trees: text.placements.defaults.format_tree = format_tree[1] mapnik.render_to_file(m, os.path.join("images", 'python-%s.png' % format_tree[0]), 'png') + compare(os.path.join("images", 'python-%s.png' % format_tree[0]), + os.path.join("images", 'python-%s-reference.png' % format_tree[0]) + ) + +summary() From eb911deca5cd52109ac112cff08cf2a3c8a7dcee Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 20 Mar 2012 22:06:22 +0100 Subject: [PATCH 101/138] Change visual tests config format. --- ...nce.png => formatting-1-500-reference.png} | Bin ...nce.png => formatting-2-500-reference.png} | Bin ...nce.png => formatting-3-500-reference.png} | Bin ...nce.png => formatting-4-500-reference.png} | Bin .../{formating-1.xml => formatting-1.xml} | 0 .../{formating-2.xml => formatting-2.xml} | 0 .../{formating-3.xml => formatting-3.xml} | 0 .../{formating-4.xml => formatting-4.xml} | 0 .../styles/shieldsymbolizer-1.xml | 2 +- tests/visual_tests/test.py | 72 ++++++++++-------- tests/visual_tests/xml_output/.gitignore | 1 + 11 files changed, 42 insertions(+), 33 deletions(-) rename tests/visual_tests/images/{formating-1-500-reference.png => formatting-1-500-reference.png} (100%) rename tests/visual_tests/images/{formating-2-500-reference.png => formatting-2-500-reference.png} (100%) rename tests/visual_tests/images/{formating-3-500-reference.png => formatting-3-500-reference.png} (100%) rename tests/visual_tests/images/{formating-4-500-reference.png => formatting-4-500-reference.png} (100%) rename tests/visual_tests/styles/{formating-1.xml => formatting-1.xml} (100%) rename tests/visual_tests/styles/{formating-2.xml => formatting-2.xml} (100%) rename tests/visual_tests/styles/{formating-3.xml => formatting-3.xml} (100%) rename tests/visual_tests/styles/{formating-4.xml => formatting-4.xml} (100%) create mode 100644 tests/visual_tests/xml_output/.gitignore diff --git a/tests/visual_tests/images/formating-1-500-reference.png b/tests/visual_tests/images/formatting-1-500-reference.png similarity index 100% rename from tests/visual_tests/images/formating-1-500-reference.png rename to tests/visual_tests/images/formatting-1-500-reference.png diff --git a/tests/visual_tests/images/formating-2-500-reference.png b/tests/visual_tests/images/formatting-2-500-reference.png similarity index 100% rename from tests/visual_tests/images/formating-2-500-reference.png rename to tests/visual_tests/images/formatting-2-500-reference.png diff --git a/tests/visual_tests/images/formating-3-500-reference.png b/tests/visual_tests/images/formatting-3-500-reference.png similarity index 100% rename from tests/visual_tests/images/formating-3-500-reference.png rename to tests/visual_tests/images/formatting-3-500-reference.png diff --git a/tests/visual_tests/images/formating-4-500-reference.png b/tests/visual_tests/images/formatting-4-500-reference.png similarity index 100% rename from tests/visual_tests/images/formating-4-500-reference.png rename to tests/visual_tests/images/formatting-4-500-reference.png diff --git a/tests/visual_tests/styles/formating-1.xml b/tests/visual_tests/styles/formatting-1.xml similarity index 100% rename from tests/visual_tests/styles/formating-1.xml rename to tests/visual_tests/styles/formatting-1.xml diff --git a/tests/visual_tests/styles/formating-2.xml b/tests/visual_tests/styles/formatting-2.xml similarity index 100% rename from tests/visual_tests/styles/formating-2.xml rename to tests/visual_tests/styles/formatting-2.xml diff --git a/tests/visual_tests/styles/formating-3.xml b/tests/visual_tests/styles/formatting-3.xml similarity index 100% rename from tests/visual_tests/styles/formating-3.xml rename to tests/visual_tests/styles/formatting-3.xml diff --git a/tests/visual_tests/styles/formating-4.xml b/tests/visual_tests/styles/formatting-4.xml similarity index 100% rename from tests/visual_tests/styles/formating-4.xml rename to tests/visual_tests/styles/formatting-4.xml diff --git a/tests/visual_tests/styles/shieldsymbolizer-1.xml b/tests/visual_tests/styles/shieldsymbolizer-1.xml index 90b456890..329343461 100644 --- a/tests/visual_tests/styles/shieldsymbolizer-1.xml +++ b/tests/visual_tests/styles/shieldsymbolizer-1.xml @@ -6,7 +6,7 @@ My Style shape - ../../data/points.shp + ../data/points.shp diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index cbc36bcad..442aad86d 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -6,41 +6,50 @@ import sys import os.path from compare import compare, summary +defaults = { + 'sizes': [(500, 100)], + 'bbox': mapnik.Box2d(-0.05, -0.01, 0.95, 0.01) +} + +sizes_many_in_big_range = [(800, 100), (600, 100), (400, 100), + (300, 100), (250, 100), (150, 100), (100, 100)] + +sizes_few_square = [(800, 800), (600, 600), (400, 400), (200, 200)] +sizes_many_in_small_range = [(490, 100), (495, 100), (497, 100), (498, 100), + (499, 100), (500, 100), (501, 100), (502, 100), (505, 100), (510, 100)] + dirname = os.path.dirname(__file__) files = [ - ("list", 800, 600, 400, 300, 250, 200, 150, 100), - ("simple", 800, 600, 400, 300, 250, 200, 150, 100), - ("lines-1", (800, 800), (600, 600), (400, 400), (200, 200)), - ("lines-2", (800, 800), (600, 600), (400, 400), (200, 200)), - ("lines-3", (800, 800), (600, 600), (400, 400), (200, 200)), - ("lines-shield", (800, 800), (600, 600), (400, 400), (200, 200)), - ("simple-E", 500), - ("simple-NE", 500), - ("simple-NW", 500), - ("simple-N", 500), - ("simple-SE", 500), - ("simple-SW", 500), - ("simple-S", 500), - ("simple-W", 500), - ("formating-1", 500), - ("formating-2", 500), - ("formating-3", 500), - ("formating-4", 500), - ("shieldsymbolizer-1", 490, 495, 497, 498, 499, 500, 501, 502, 505, 510), - ("expressionformat", 500), - ("rtl-point", (200, 200)), - ("jalign-auto", (200, 200)) + {'name': "list", 'sizes': sizes_many_in_big_range}, + {'name': "simple", 'sizes': sizes_many_in_big_range}, + {'name': "lines-1", 'sizes': sizes_few_square}, + {'name': "lines-2", 'sizes': sizes_few_square}, + {'name': "lines-3", 'sizes': sizes_few_square}, + {'name': "lines-shield", 'sizes': sizes_few_square}, + {'name': "simple-E"}, + {'name': "simple-NE"}, + {'name': "simple-NW"}, + {'name': "simple-N"}, + {'name': "simple-SE"}, + {'name': "simple-SW"}, + {'name': "simple-S"}, + {'name': "simple-W"}, + {'name': "formatting-1"}, + {'name': "formatting-2"}, + {'name': "formatting-3"}, + {'name': "formatting-4"}, + {'name': "expressionformat"}, + {'name': "shieldsymbolizer-1", 'sizes': sizes_many_in_small_range}, + {'name': "rtl-point", 'sizes': [(200, 200)]}, + {'name': "jalign-auto", 'sizes': [(200, 200)]} ] -def render(filename, width, height=100): +def render(filename, width, height, bbox): print "-"*80 print "Rendering style \"%s\" with size %dx%d ... " % (filename, width, height) print "-"*80 - width = int(width) - height = int(height) m = mapnik.Map(width, height) mapnik.load_map(m, os.path.join(dirname, "styles", "%s.xml" % filename), False) - bbox = mapnik.Box2d(-0.05, -0.01, 0.95, 0.01) m.zoom_to_box(bbox) basefn = os.path.join(dirname, "images", '%s-%d' % (filename, width)) mapnik.render_to_file(m, basefn+'-agg.png') @@ -58,11 +67,10 @@ elif len(sys.argv) > 2: files = [sys.argv[1:]] for f in files: - for width in f[1:]: - if isinstance(width, tuple): - m = render(f[0], width[0], width[1]) - else: - m = render(f[0], width) - mapnik.save_map(m, os.path.join(dirname, 'xml_output', "%s-out.xml" % f[0])) + config = dict(defaults) + config.update(f) + for size in config['sizes']: + m = render(config['name'], size[0], size[1], config['bbox']) + mapnik.save_map(m, os.path.join(dirname, 'xml_output', "%s-out.xml" % config['name'])) summary() diff --git a/tests/visual_tests/xml_output/.gitignore b/tests/visual_tests/xml_output/.gitignore new file mode 100644 index 000000000..6722cd96e --- /dev/null +++ b/tests/visual_tests/xml_output/.gitignore @@ -0,0 +1 @@ +*.xml From bd9fe739e5d47b13a83c9acb2d0b63c66d547f04 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 20 Mar 2012 23:02:19 +0100 Subject: [PATCH 102/138] Throw in OSM datasource if not all parameters are specified but bind is requested. --- plugins/input/osm/osm_datasource.cpp | 60 +++++++++++++--------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/plugins/input/osm/osm_datasource.cpp b/plugins/input/osm/osm_datasource.cpp index 7c4db20c2..90cebc0fe 100644 --- a/plugins/input/osm/osm_datasource.cpp +++ b/plugins/input/osm/osm_datasource.cpp @@ -52,6 +52,7 @@ DATASOURCE_PLUGIN(osm_datasource) osm_datasource::osm_datasource(const parameters& params, bool bind) : datasource (params), + extent_(), type_(datasource::Vector), desc_(*params_.get("type"), *params_.get("encoding", "utf-8")) { @@ -71,13 +72,11 @@ void osm_datasource::bind() const std::string url = *params_.get("url", ""); std::string bbox = *params_.get("bbox", ""); - bool do_process = false; // load the data - // if we supplied a filename, load from file if (url != "" && bbox != "") { - // otherwise if we supplied a url and a bounding box, load from the url + // if we supplied a url and a bounding box, load from the url #ifdef MAPNIK_DEBUG std::clog << "Osm Plugin: loading_from_url: url=" << url << " bbox=" << bbox << std::endl; #endif @@ -85,44 +84,40 @@ void osm_datasource::bind() const { throw datasource_exception("Error loading from URL"); } - - do_process = true; } else if (osm_filename != "") { - if ((osm_data_= dataset_deliverer::load_from_file(osm_filename, parser)) == NULL) + // if we supplied a filename, load from file + if ((osm_data_ = dataset_deliverer::load_from_file(osm_filename, parser)) == NULL) { std::ostringstream s; s << "OSM Plugin: Error loading from file '" << osm_filename << "'"; throw datasource_exception(s.str()); } - - do_process = true; + } else { + throw datasource_exception("OSM Plugin: Neither 'file' nor 'url' and 'bbox' specified"); } - if (do_process == true) + + osm_tag_types tagtypes; + tagtypes.add_type("maxspeed", mapnik::Integer); + tagtypes.add_type("z_order", mapnik::Integer); + + osm_data_->rewind(); + + // Need code to get the attributes of all the data + std::set keys = osm_data_->get_keys(); + + // Add the attributes to the datasource descriptor - assume they are + // all of type String + for (std::set::iterator i = keys.begin(); i != keys.end(); i++) { - osm_tag_types tagtypes; - tagtypes.add_type("maxspeed", mapnik::Integer); - tagtypes.add_type("z_order", mapnik::Integer); - - osm_data_->rewind(); - - // Need code to get the attributes of all the data - std::set keys = osm_data_->get_keys(); - - // Add the attributes to the datasource descriptor - assume they are - // all of type String - for (std::set::iterator i = keys.begin(); i != keys.end(); i++) - { - desc_.add_descriptor(attribute_descriptor(*i, tagtypes.get_type(*i))); - } - - // Get the bounds of the data and set extent_ accordingly - bounds b = osm_data_->get_bounds(); - extent_ = box2d(b.w, b.s, b.e, b.n); + desc_.add_descriptor(attribute_descriptor(*i, tagtypes.get_type(*i))); } + // Get the bounds of the data and set extent_ accordingly + bounds b = osm_data_->get_bounds(); + extent_ = box2d(b.w, b.s, b.e, b.n); is_bound_ = true; } @@ -149,7 +144,7 @@ layer_descriptor osm_datasource::get_descriptor() const featureset_ptr osm_datasource::features(const query& q) const { - if (! is_bound_) bind(); + if (!is_bound_) bind(); filter_in_box filter(q.get_bbox()); // so we need to filter osm features by bbox here... @@ -162,7 +157,7 @@ featureset_ptr osm_datasource::features(const query& q) const featureset_ptr osm_datasource::features_at_point(coord2d const& pt) const { - if (! is_bound_) bind(); + if (!is_bound_) bind(); filter_at_point filter(pt); // collect all attribute names @@ -185,8 +180,7 @@ featureset_ptr osm_datasource::features_at_point(coord2d const& pt) const box2d osm_datasource::envelope() const { - if (! is_bound_) bind(); - + if (!is_bound_) bind(); return extent_; } @@ -194,4 +188,4 @@ boost::optional osm_datasource::get_geometry_typ { if (! is_bound_) bind(); return boost::optional(mapnik::datasource::Collection); -} \ No newline at end of file +} From 94634d469118e85f945cfad652a1c63e3bb3d0ae Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 20 Mar 2012 23:03:01 +0100 Subject: [PATCH 103/138] Correctly parse empty elements in OSM datasource. --- plugins/input/osm/osmparser.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/input/osm/osmparser.cpp b/plugins/input/osm/osmparser.cpp index fcc7b5d53..9b83d2b79 100644 --- a/plugins/input/osm/osmparser.cpp +++ b/plugins/input/osm/osmparser.cpp @@ -103,6 +103,11 @@ void osmparser::startElement(xmlTextReaderPtr reader, const xmlChar *name) xmlFree(xk); xmlFree(xv); } + if (xmlTextReaderIsEmptyElement(reader)) + { + // Fake endElement for empty nodes + endElement(name); + } } void osmparser::endElement(const xmlChar* name) From eac133952ce87aad32187aec9fe0ef83f5415209 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 20 Mar 2012 23:12:39 +0100 Subject: [PATCH 104/138] Add line-offset test. --- tests/visual_tests/data/line-offset.osm | 435 ++++++++++++++++++++++ tests/visual_tests/styles/line-offset.xml | 29 ++ tests/visual_tests/test.py | 9 +- 3 files changed, 471 insertions(+), 2 deletions(-) create mode 100644 tests/visual_tests/data/line-offset.osm create mode 100644 tests/visual_tests/styles/line-offset.xml diff --git a/tests/visual_tests/data/line-offset.osm b/tests/visual_tests/data/line-offset.osm new file mode 100644 index 000000000..9a568dc30 --- /dev/null +++ b/tests/visual_tests/data/line-offset.osm @@ -0,0 +1,435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/visual_tests/styles/line-offset.xml b/tests/visual_tests/styles/line-offset.xml new file mode 100644 index 000000000..ed738555d --- /dev/null +++ b/tests/visual_tests/styles/line-offset.xml @@ -0,0 +1,29 @@ + + + + + My Style + + osm + ../data/line-offset.osm + + + + + \ No newline at end of file diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index 442aad86d..554c1c5c5 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -41,7 +41,9 @@ files = [ {'name': "expressionformat"}, {'name': "shieldsymbolizer-1", 'sizes': sizes_many_in_small_range}, {'name': "rtl-point", 'sizes': [(200, 200)]}, - {'name': "jalign-auto", 'sizes': [(200, 200)]} + {'name': "jalign-auto", 'sizes': [(200, 200)]}, + {'name': "line-offset", 'sizes':[(900, 250)], + 'bbox': mapnik.Box2d(-5.192, 50.189, -5.174, 50.195)} ] def render(filename, width, height, bbox): @@ -50,7 +52,10 @@ def render(filename, width, height, bbox): print "-"*80 m = mapnik.Map(width, height) mapnik.load_map(m, os.path.join(dirname, "styles", "%s.xml" % filename), False) - m.zoom_to_box(bbox) + if bbox is not None: + m.zoom_to_box(bbox) + else: + m.zoom_all() basefn = os.path.join(dirname, "images", '%s-%d' % (filename, width)) mapnik.render_to_file(m, basefn+'-agg.png') diff = compare(basefn + '-agg.png', basefn + '-reference.png') From 8b5e5fbb64016083c132e333403a0bb341ea24dd Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 20 Mar 2012 23:50:20 +0100 Subject: [PATCH 105/138] Always place text at the same side of a line. Fixes #608. --- src/placement_finder.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index 5419cb8b6..a1892708b 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -660,15 +660,24 @@ void placement_finder::find_line_placements(PathT & shape_path) double anglesum = 0; for (unsigned i = 0; i < current_placement->nodes_.size(); i++) { - anglesum += current_placement->nodes_[i].angle; + double angle = current_placement->nodes_[i].angle; + //Normalize angle in range -PI ... PI + while (angle > M_PI) { + angle -= 2*M_PI; + } + anglesum += angle; } anglesum /= current_placement->nodes_.size(); //Now it is angle average + double cosa = orientation * cos(anglesum); + double sina = orientation * sin(anglesum); //Offset all the characters by this angle for (unsigned i = 0; i < current_placement->nodes_.size(); i++) { - current_placement->nodes_[i].pos.x += pi.get_scale_factor() * displacement*cos(anglesum+M_PI/2); - current_placement->nodes_[i].pos.y += pi.get_scale_factor() * displacement*sin(anglesum+M_PI/2); + current_placement->nodes_[i].pos.x -= + pi.get_scale_factor() * displacement * sina; + current_placement->nodes_[i].pos.y += + pi.get_scale_factor() * displacement * cosa; } } From 620f3f943e2a6e165d008fa3f84aa97a0abdecda Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Tue, 20 Mar 2012 23:52:13 +0100 Subject: [PATCH 106/138] Add reference image. --- .../images/line-offset-900-reference.png | Bin 0 -> 32175 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/visual_tests/images/line-offset-900-reference.png diff --git a/tests/visual_tests/images/line-offset-900-reference.png b/tests/visual_tests/images/line-offset-900-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..37f3c4b6e1d525cf94b1258864cc6bbbfd31ab0f GIT binary patch literal 32175 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%0AV%Z`Mf~7Mf(~qv>_bX@OJ5 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 R9>k8IEUzwCFJlq Date: Tue, 20 Mar 2012 23:56:35 +0100 Subject: [PATCH 107/138] Remove old comment. --- src/placement_finder.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index a1892708b..0132ed656 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -656,7 +656,6 @@ void placement_finder::find_line_placements(PathT & shape_path) if (displacement != 0) { //Average the angle of all characters and then offset them all by that angle - //NOTE: This probably calculates a bad angle due to going around the circle, test this! double anglesum = 0; for (unsigned i = 0; i < current_placement->nodes_.size(); i++) { From 3f067474070cbcecc29836acf35605b009b15a84 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 20 Mar 2012 16:40:07 -0700 Subject: [PATCH 108/138] braces for readibility --- src/load_map.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/load_map.cpp b/src/load_map.cpp index 38bcfbff7..ef5c58f7e 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -1063,7 +1063,9 @@ void map_parser::parse_text_symbolizer(rule & rule, xml_node const& sym) } if (strict_ && !placement_finder->defaults.format.fontset.size()) + { ensure_font_face(placement_finder->defaults.format.face_name); + } text_symbolizer text_symbol = text_symbolizer(placement_finder); parse_metawriter_in_symbolizer(text_symbol, sym); @@ -1090,7 +1092,9 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym) placement_finder->defaults.from_xml(sym, fontsets_); if (strict_ && !placement_finder->defaults.format.fontset.size()) + { ensure_font_face(placement_finder->defaults.format.face_name); + } shield_symbolizer shield_symbol = shield_symbolizer(placement_finder); /* Symbolizer specific attributes. */ From d55ad5a4d21c4ae0541aa056151df2aca69946fc Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 21 Mar 2012 15:34:01 -0700 Subject: [PATCH 109/138] check which cairo surfaces are supported --- src/build.py | 1 + src/image_util.cpp | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/build.py b/src/build.py index 59bf949ca..34ba537d1 100644 --- a/src/build.py +++ b/src/build.py @@ -73,6 +73,7 @@ if env['THREADING'] == 'multi': if env['RUNTIME_LINK'] == 'static': if 'icuuc' in env['ICU_LIB_NAME']: lib_env['LIBS'].append('icudata') + lib_env['LIBS'].append('icui18n') else: if env['INTERNAL_LIBAGG']: lib_env['LIBS'].insert(0, 'agg') diff --git a/src/image_util.cpp b/src/image_util.cpp index 5b3b46454..35ccb4ba1 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -45,6 +45,7 @@ extern "C" #ifdef HAVE_CAIRO #include +#include #endif #include @@ -371,17 +372,39 @@ void save_to_cairo_file(mapnik::Map const& map, unsigned width = map.width(); unsigned height = map.height(); if (type == "pdf") + { +#if defined(CAIRO_HAS_PDF_SURFACE) surface = Cairo::PdfSurface::create(filename,width,height); + throw ImageWriterException("PDFSurface not supported in the cairo backend"); +#endif + } +#if defined(CAIRO_HAS_SVG_SURFACE) else if (type == "svg") + { surface = Cairo::SvgSurface::create(filename,width,height); + } +#endif +#if defined(CAIRO_HAS_PS_SURFACE) else if (type == "ps") + { surface = Cairo::PsSurface::create(filename,width,height); + } +#endif +#if defined(CAIRO_HAS_IMAGE_SURFACE) else if (type == "ARGB32") + { surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32,width,height); + } else if (type == "RGB24") + { surface = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24,width,height); + } +#endif else + { throw ImageWriterException("unknown file type: " + type); + } + Cairo::RefPtr context = Cairo::Context::create(surface); // TODO - expose as user option From 0beca49b2aa410363b4cb1c9b4ef0ad86d4eae8c Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 21 Mar 2012 15:38:32 -0700 Subject: [PATCH 110/138] scons: when parsing xml2-config only pull --cflags to avoid uneeded pollution of other libs on osx (namely libicucore) --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 71f04991d..60352732c 100644 --- a/SConstruct +++ b/SConstruct @@ -1068,7 +1068,7 @@ if not preconfigured: # libxml2 should be optional but is currently not # https://github.com/mapnik/mapnik/issues/913 - if conf.parse_config('XML2_CONFIG'): + if conf.parse_config('XML2_CONFIG',checks='--cflags'): env['HAS_LIBXML2'] = True LIBSHEADERS = [ From 40b0ab8d6c0e1aa49a60fc2c1c1d37c825fda64c Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 21 Mar 2012 17:45:19 -0700 Subject: [PATCH 111/138] add missing #else --- src/image_util.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/image_util.cpp b/src/image_util.cpp index 35ccb4ba1..dfc1c54c6 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -375,6 +375,7 @@ void save_to_cairo_file(mapnik::Map const& map, { #if defined(CAIRO_HAS_PDF_SURFACE) surface = Cairo::PdfSurface::create(filename,width,height); +#else throw ImageWriterException("PDFSurface not supported in the cairo backend"); #endif } From 2e2bce312619510a6ed7b9a5b813816b561efa1b Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 22 Mar 2012 16:31:57 -0700 Subject: [PATCH 112/138] formatting --- include/mapnik/agg_helpers.hpp | 4 ++-- include/mapnik/font_engine_freetype.hpp | 8 ++++---- include/mapnik/line_symbolizer.hpp | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/mapnik/agg_helpers.hpp b/include/mapnik/agg_helpers.hpp index aa13729d4..e605194fe 100644 --- a/include/mapnik/agg_helpers.hpp +++ b/include/mapnik/agg_helpers.hpp @@ -71,7 +71,7 @@ void set_join_caps(Stroke const& stroke_, PathType & stroke) default: stroke.generator().line_join(agg::bevel_join); } - + line_cap_e cap=stroke_.get_line_cap(); switch (cap) { @@ -85,7 +85,7 @@ void set_join_caps(Stroke const& stroke_, PathType & stroke) stroke.generator().line_cap(agg::round_cap); } } - + } #endif //MAPNIK_AGG_HELPERS_HPP diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index 5b4b87b40..a08a6454d 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -169,12 +169,12 @@ public: glyph_ptr get_glyph(unsigned c) const { - BOOST_FOREACH ( face_ptr const& face, faces_) + BOOST_FOREACH ( face_ptr const& face, faces_) { FT_UInt g = face->get_char(c); if (g) return boost::make_shared(face, g); } - + // Final fallback to empty square if nothing better in any font return boost::make_shared(*faces_.begin(), 0); } @@ -185,7 +185,7 @@ public: void set_pixel_sizes(unsigned size) { - BOOST_FOREACH ( face_ptr const& face, faces_) + BOOST_FOREACH ( face_ptr const& face, faces_) { face->set_pixel_sizes(size); } @@ -193,7 +193,7 @@ public: void set_character_sizes(float size) { - BOOST_FOREACH ( face_ptr const& face, faces_) + BOOST_FOREACH ( face_ptr const& face, faces_) { face->set_character_sizes(size); } diff --git a/include/mapnik/line_symbolizer.hpp b/include/mapnik/line_symbolizer.hpp index bcb3ab971..29634db1a 100644 --- a/include/mapnik/line_symbolizer.hpp +++ b/include/mapnik/line_symbolizer.hpp @@ -83,12 +83,12 @@ struct MAPNIK_DECL line_symbolizer : public symbolizer_base { smooth_ = smooth; } - + double smooth() const { return smooth_; } - + private: stroke stroke_; line_rasterizer_e rasterizer_p_; From 61c38d0ec7e8c745a84c17b34da81262aa6a444e Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 22 Mar 2012 16:35:33 -0700 Subject: [PATCH 113/138] avoid copying unbuffered bbox --- src/feature_style_processor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/feature_style_processor.cpp b/src/feature_style_processor.cpp index 4b78ab0a3..7cb02042b 100644 --- a/src/feature_style_processor.cpp +++ b/src/feature_style_processor.cpp @@ -248,9 +248,11 @@ void feature_style_processor::apply_to_layer(layer const& lay, Proces layer_ext.clip(map_ext); // forward project layer extent back into native projection if (!prj_trans.forward(layer_ext, PROJ_ENVELOPE_POINTS)) + { std::clog << "WARNING: layer " << lay.name() << " extent " << layer_ext << " in map projection " << " did not reproject properly back to layer projection\n"; + } } else { @@ -262,14 +264,13 @@ void feature_style_processor::apply_to_layer(layer const& lay, Proces } box2d query_ext = m_.get_current_extent(); - box2d unbuffered_extent = m_.get_current_extent(); prj_trans.forward(query_ext, PROJ_ENVELOPE_POINTS); double qw = query_ext.width()>0 ? query_ext.width() : 1; double qh = query_ext.height()>0 ? query_ext.height() : 1; query::resolution_type res(m_.width()/qw, m_.height()/qh); - query q(layer_ext,res,scale_denom,unbuffered_extent); + query q(layer_ext,res,scale_denom,m_.get_current_extent()); p.start_layer_processing(lay, query_ext); std::vector active_styles; attribute_collector collector(names); From d23a4b63b9dfb4e5d82c080c873e256dc0767b2d Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 22 Mar 2012 16:36:25 -0700 Subject: [PATCH 114/138] expose both a clipped and unclipped labeling path type --- include/mapnik/placement_finder.hpp | 17 +++++++++++++++-- src/placement_finder.cpp | 14 +++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/include/mapnik/placement_finder.hpp b/include/mapnik/placement_finder.hpp index 57d6ee2ab..bf8844808 100644 --- a/include/mapnik/placement_finder.hpp +++ b/include/mapnik/placement_finder.hpp @@ -23,13 +23,20 @@ #ifndef MAPNIK_PLACEMENT_FINDER_HPP #define MAPNIK_PLACEMENT_FINDER_HPP -//mapnik +// mapnik #include #include #include #include +#include +#include -//stl + +// agg +#include "agg_conv_clip_polyline.h" + + +// stl #include namespace mapnik @@ -39,6 +46,12 @@ class text_placement_info; class string_info; class text_path; +typedef agg::conv_clip_polyline clipped_geometry_type; +typedef coord_transform2 ClippedPathType; +typedef coord_transform2 PathType; + +typedef label_collision_detector4 DetectorType; + template class placement_finder : boost::noncopyable diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index 0132ed656..b7e797203 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -26,14 +26,12 @@ #include #include #include -#include #include #include -#include // agg #include "agg_path_length.h" -#include "agg_conv_clip_polyline.h" + // boost #include #include @@ -674,9 +672,9 @@ void placement_finder::find_line_placements(PathT & shape_path) for (unsigned i = 0; i < current_placement->nodes_.size(); i++) { current_placement->nodes_[i].pos.x -= - pi.get_scale_factor() * displacement * sina; + pi.get_scale_factor() * displacement * sina; current_placement->nodes_[i].pos.y += - pi.get_scale_factor() * displacement * cosa; + pi.get_scale_factor() * displacement * cosa; } } @@ -1058,11 +1056,9 @@ void placement_finder::clear_placements() while (!envelopes_.empty()) envelopes_.pop(); } -typedef agg::conv_clip_polyline clipped_geometry_type; -typedef coord_transform2 PathType; -typedef label_collision_detector4 DetectorType; - template class placement_finder; +template void placement_finder::find_point_placements(ClippedPathType &); +template void placement_finder::find_line_placements(ClippedPathType &); template void placement_finder::find_point_placements(PathType &); template void placement_finder::find_line_placements(PathType &); } // namespace From d991427737fc3bb2e3cd23e5c472a4642a5bccab Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 22 Mar 2012 16:37:24 -0700 Subject: [PATCH 115/138] formatting --- src/agg/process_line_symbolizer.cpp | 8 ++++---- src/agg/process_polygon_pattern_symbolizer.cpp | 2 +- src/agg/process_polygon_symbolizer.cpp | 2 +- src/cairo_renderer.cpp | 8 ++++---- src/load_map.cpp | 4 ++-- src/save_map.cpp | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index 8763b882f..6046e116e 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -52,7 +52,7 @@ void agg_renderer::process(line_symbolizer const& sym, proj_transform const& prj_trans) { typedef agg::renderer_base ren_base; - + stroke const& stroke_ = sym.get_stroke(); color const& col = stroke_.get_color(); unsigned r=col.red(); @@ -104,7 +104,7 @@ void agg_renderer::process(line_symbolizer const& sym, ras_ptr->reset(); set_gamma_method(stroke_, ras_ptr); - + //metawriter_with_properties writer = sym.get_metawriter(); for (unsigned i=0;inum_geometries();++i) { @@ -145,7 +145,7 @@ void agg_renderer::process(line_symbolizer const& sym, clipped_geometry_type clipped(geom); clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); path_type path(t_,clipped,prj_trans); - + agg::conv_dash dash(path); dash_array const& d = stroke_.get_dash_array(); dash_array::const_iterator itr = d.begin(); @@ -191,7 +191,7 @@ void agg_renderer::process(line_symbolizer const& sym, set_join_caps(stroke_,stroke); stroke.generator().miter_limit(4.0); stroke.generator().width(stroke_.get_width() * scale_factor_); - ras_ptr->add_path(stroke); + ras_ptr->add_path(stroke); } //if (writer.first) writer.first->add_line(path, *feature, t_, writer.second); } diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp index 1d6fbde1f..56e1293ef 100644 --- a/src/agg/process_polygon_pattern_symbolizer.cpp +++ b/src/agg/process_polygon_pattern_symbolizer.cpp @@ -74,7 +74,7 @@ void agg_renderer::process(polygon_pattern_symbolizer const& sym, agg::scanline_u8 sl; ras_ptr->reset(); set_gamma_method(sym,ras_ptr); - + std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); boost::optional marker; if ( !filename.empty() ) diff --git a/src/agg/process_polygon_symbolizer.cpp b/src/agg/process_polygon_symbolizer.cpp index 2b532fb9f..0cc902b04 100644 --- a/src/agg/process_polygon_symbolizer.cpp +++ b/src/agg/process_polygon_symbolizer.cpp @@ -67,7 +67,7 @@ void agg_renderer::process(polygon_symbolizer const& sym, ras_ptr->reset(); set_gamma_method(sym,ras_ptr); - + //metawriter_with_properties writer = sym.get_metawriter(); box2d inflated_extent = query_extent_ * 1.1; for (unsigned i=0;inum_geometries();++i) diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index dff4ce123..589247e0f 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -754,7 +754,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); context.add_path(path); - } + } } } // fill polygon @@ -877,7 +877,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) { typedef agg::conv_clip_polyline clipped_geometry_type; typedef coord_transform2 path_type; - + mapnik::stroke const& stroke_ = sym.get_stroke(); cairo_context context(context_); context.set_color(stroke_.get_color(), stroke_.get_opacity()); @@ -889,7 +889,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) { context.set_dash(stroke_.get_dash_array()); } - + for (unsigned i = 0; i < feature->num_geometries(); ++i) { geometry_type & geom = feature->get_geometry(i); @@ -900,7 +900,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) clipped_geometry_type clipped(geom); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); - + context.add_path(path); } } diff --git a/src/load_map.cpp b/src/load_map.cpp index ef5c58f7e..a1344448b 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -991,7 +991,7 @@ void map_parser::parse_line_pattern_symbolizer(rule & rule, xml_node const & sym } void map_parser::parse_polygon_pattern_symbolizer(rule & rule, - xml_node const & sym) + xml_node const & sym) { try { @@ -1307,7 +1307,7 @@ void map_parser::parse_polygon_symbolizer(rule & rule, xml_node const & sym) // smooth value optional smooth = sym.get_opt_attr("smooth"); if (smooth) poly_sym.set_smooth(*smooth); - + parse_metawriter_in_symbolizer(poly_sym, sym); rule.append(poly_sym); } diff --git a/src/save_map.cpp b/src/save_map.cpp index 6aa9fe5d5..8b25e2aff 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -96,7 +96,7 @@ public: set_attr( sym_node, "smooth", sym.smooth() ); } } - + void operator () ( line_pattern_symbolizer const& sym ) { ptree & sym_node = rule_.push_back( From caaa8b5392efadbe687aa4d33fedb0f6e58e641a Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 22 Mar 2012 16:41:44 -0700 Subject: [PATCH 116/138] disable stderr from svg parsing unless in debug mode --- src/svg_parser.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/svg_parser.cpp b/src/svg_parser.cpp index 4d4d30a98..e62f45deb 100644 --- a/src/svg_parser.cpp +++ b/src/svg_parser.cpp @@ -226,10 +226,12 @@ void svg_parser::start_element(xmlTextReaderPtr reader) { parse_gradient_stop(reader); } +#ifdef MAPNIK_DEBUG else if (!xmlStrEqual(name, BAD_CAST "svg")) { std::clog << "notice: unhandled svg element: " << name << "\n"; } +#endif } void svg_parser::end_element(xmlTextReaderPtr reader) From e9940c6add9310515dabff025b07779eba953952 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 22 Mar 2012 16:44:27 -0700 Subject: [PATCH 117/138] update osm test now that extent is not hardcoded --- tests/python_tests/osm_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/python_tests/osm_test.py b/tests/python_tests/osm_test.py index ae063e6f3..91ad2a1ed 100644 --- a/tests/python_tests/osm_test.py +++ b/tests/python_tests/osm_test.py @@ -20,10 +20,10 @@ if 'osm' in mapnik.DatasourceCache.instance().plugin_names(): e = ds.envelope() # these are hardcoded in the plugin… ugh - assert_almost_equal(e.minx, -180.0) - assert_almost_equal(e.miny, -90.0) - assert_almost_equal(e.maxx, 180.0) - assert_almost_equal(e.maxy, 90) + eq_(e.minx >= -180.0,True) + eq_(e.miny >= -90.0,True) + eq_(e.maxx <= 180.0,True) + eq_(e.maxy <= 90,True) @raises(RuntimeError) def test_that_nonexistant_query_field_throws(**kwargs): From 242385f16d156ad2f5aa5c3d1cb4a0d451cdbe45 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Fri, 23 Mar 2012 11:01:18 +0000 Subject: [PATCH 118/138] use mapnik::util namespace for conversions --- include/mapnik/util/conversions.hpp | 11 +++++------ plugins/input/postgis/postgis_datasource.cpp | 12 ++++++------ plugins/input/postgis/postgis_featureset.cpp | 2 +- src/conversions.cpp | 2 +- src/image_util.cpp | 10 +++++----- src/xml_tree.cpp | 6 +++--- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/include/mapnik/util/conversions.hpp b/include/mapnik/util/conversions.hpp index c4d4a321b..b57f55ff9 100644 --- a/include/mapnik/util/conversions.hpp +++ b/include/mapnik/util/conversions.hpp @@ -20,15 +20,15 @@ * *****************************************************************************/ -#ifndef MAPNIK_CONVERSIONS_UTIL_HPP -#define MAPNIK_CONVERSIONS_UTIL_HPP +#ifndef MAPNIK_UTIL_CONVERSIONS_HPP +#define MAPNIK_UTIL_CONVERSIONS_HPP // mapnik // stl #include -namespace mapnik { namespace conversions { +namespace mapnik { namespace util { bool string2int(const char * value, int & result); bool string2int(std::string const& value, int & result); @@ -39,7 +39,6 @@ namespace mapnik { namespace conversions { bool string2float(std::string const& value, float & result); bool string2float(const char * value, float & result); - } -} +}} -#endif // MAPNIK_CONVERSIONS_UTIL_HPP +#endif // MAPNIK_UTIL_CONVERSIONS_HPP diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp index 05c397892..316ee02c1 100644 --- a/plugins/input/postgis/postgis_datasource.cpp +++ b/plugins/input/postgis/postgis_datasource.cpp @@ -175,7 +175,7 @@ void postgis_datasource::bind() const if (srid_c != NULL) { int result; - if (mapnik::conversions::string2int(srid_c,result)) + if (mapnik::util::string2int(srid_c,result)) srid_ = result; } } @@ -205,7 +205,7 @@ void postgis_datasource::bind() const if (srid_c != NULL) { int result; - if (mapnik::conversions::string2int(srid_c,result)) + if (mapnik::util::string2int(srid_c,result)) srid_ = result; } } @@ -685,10 +685,10 @@ box2d postgis_datasource::envelope() const double loy; double hix; double hiy; - if (mapnik::conversions::string2double(rs->getValue(0),lox) && - mapnik::conversions::string2double(rs->getValue(1),loy) && - mapnik::conversions::string2double(rs->getValue(2),hix) && - mapnik::conversions::string2double(rs->getValue(3),hiy)) + if (mapnik::util::string2double(rs->getValue(0),lox) && + mapnik::util::string2double(rs->getValue(1),loy) && + mapnik::util::string2double(rs->getValue(2),hix) && + mapnik::util::string2double(rs->getValue(3),hiy)) { extent_.init(lox,loy,hix,hiy); extent_initialized_ = true; diff --git a/plugins/input/postgis/postgis_featureset.cpp b/plugins/input/postgis/postgis_featureset.cpp index f4bbfe4b2..177413fee 100644 --- a/plugins/input/postgis/postgis_featureset.cpp +++ b/plugins/input/postgis/postgis_featureset.cpp @@ -162,7 +162,7 @@ feature_ptr postgis_featureset::next() { std::string str = mapnik::sql_utils::numeric2string(buf); double val; - if (mapnik::conversions::string2double(str,val)) + if (mapnik::util::string2double(str,val)) feature->put(name,val); } else diff --git a/src/conversions.cpp b/src/conversions.cpp index d19272162..76e9d0531 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -31,7 +31,7 @@ BOOST_AUTO(name, boost::proto::deep_copy(expr)); \ -namespace mapnik { namespace conversions { +namespace mapnik { namespace util { using namespace boost::spirit; diff --git a/src/image_util.cpp b/src/image_util.cpp index dfc1c54c6..cde2ba9e2 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -158,7 +158,7 @@ void handle_png_options(std::string const& type, if (*colors < 0) throw ImageWriterException("invalid color parameter: unavailable for true color images"); - if (!mapnik::conversions::string2int(t.substr(2),*colors) || *colors < 0 || *colors > 256) + if (!mapnik::util::string2int(t.substr(2),*colors) || *colors < 0 || *colors > 256) throw ImageWriterException("invalid color parameter: " + t.substr(2)); } else if (boost::algorithm::starts_with(t, "t=")) @@ -166,14 +166,14 @@ void handle_png_options(std::string const& type, if (*colors < 0) throw ImageWriterException("invalid trans_mode parameter: unavailable for true color images"); - if (!mapnik::conversions::string2int(t.substr(2),*trans_mode) || *trans_mode < 0 || *trans_mode > 2) + if (!mapnik::util::string2int(t.substr(2),*trans_mode) || *trans_mode < 0 || *trans_mode > 2) throw ImageWriterException("invalid trans_mode parameter: " + t.substr(2)); } else if (boost::algorithm::starts_with(t, "g=")) { if (*colors < 0) throw ImageWriterException("invalid gamma parameter: unavailable for true color images"); - if (!mapnik::conversions::string2double(t.substr(2),*gamma) || *gamma < 0) + if (!mapnik::util::string2double(t.substr(2),*gamma) || *gamma < 0) { throw ImageWriterException("invalid gamma parameter: " + t.substr(2)); } @@ -186,7 +186,7 @@ void handle_png_options(std::string const& type, #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) */ - if (!mapnik::conversions::string2int(t.substr(2),*compression) + if (!mapnik::util::string2int(t.substr(2),*compression) || *compression < Z_DEFAULT_COMPRESSION || *compression > Z_BEST_COMPRESSION) { @@ -317,7 +317,7 @@ void save_to_stream(T const& image, std::string const& val = t.substr(4); if (!val.empty()) { - if (!mapnik::conversions::string2int(val,quality) || quality < 0 || quality > 100) + if (!mapnik::util::string2int(val,quality) || quality < 0 || quality > 100) { throw ImageWriterException("invalid jpeg quality: '" + val + "'"); } diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index ef61e9258..36995166f 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -54,7 +54,7 @@ template <> inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) { int result; - if (mapnik::conversions::string2int(value, result)) + if (mapnik::util::string2int(value, result)) return boost::optional(result); return boost::optional(); } @@ -63,7 +63,7 @@ template <> inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) { double result; - if (mapnik::conversions::string2double(value, result)) + if (mapnik::util::string2double(value, result)) return boost::optional(result); return boost::optional(); } @@ -72,7 +72,7 @@ template <> inline boost::optional fast_cast(xml_tree const& tree, std::string const& value) { float result; - if (mapnik::conversions::string2float(value, result)) + if (mapnik::util::string2float(value, result)) return boost::optional(result); return boost::optional(); } From b4e96c35b558a0b0a4e999f5e7f2bba0e08fb569 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Fri, 23 Mar 2012 11:56:23 +0000 Subject: [PATCH 119/138] + impl dasharray parser (supports 'none') + skip 0,0 dashes in load_map --- include/mapnik/util/dasharray_parser.hpp | 62 ++++++++++++++++++++++++ src/load_map.cpp | 47 ++++++++---------- 2 files changed, 81 insertions(+), 28 deletions(-) create mode 100644 include/mapnik/util/dasharray_parser.hpp diff --git a/include/mapnik/util/dasharray_parser.hpp b/include/mapnik/util/dasharray_parser.hpp new file mode 100644 index 000000000..e9a3753f2 --- /dev/null +++ b/include/mapnik/util/dasharray_parser.hpp @@ -0,0 +1,62 @@ +/***************************************************************************** + * + * 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_UTIL_DASHARRAY_PARSER_HPP +#define MAPNIK_UTIL_DASHARRAY_PARSER_HPP + +#include +#include +#include +#include + +namespace mapnik { namespace util { + +template +bool parse_dasharray(Iterator first, Iterator last, std::vector& dasharray) +{ + using qi::double_; + using qi::phrase_parse; + using qi::_1; + using qi::lit; + using ascii::space; + using phoenix::push_back; + // SVG + // dasharray ::= (length | percentage) (comma-wsp dasharray)? + // no support for 'percentage' as viewport is unknown at load_map + // + bool r = phrase_parse(first, last, + ( + lit("none") | (double_[push_back(phoenix::ref(dasharray), _1)] + >> *(',' >> double_[push_back(phoenix::ref(dasharray), _1)])) + ) + , + space); + + if (first != last) + return false; + + return r; +} + +}} + +#endif // MAPNIK_UTIL_DASHARRAY_PARSER_HPP diff --git a/src/load_map.cpp b/src/load_map.cpp index a1344448b..ee4313d91 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -49,6 +49,7 @@ #include #include #include +#include // boost #include @@ -1223,39 +1224,29 @@ void map_parser::parse_stroke(stroke & strk, xml_node const & sym) optional str = sym.get_opt_attr("stroke-dasharray"); if (str) { - tokenizer<> tok (*str); std::vector dash_array; - tokenizer<>::iterator itr = tok.begin(); - for (; itr != tok.end(); ++itr) + if (util::parse_dasharray((*str).begin(),(*str).end(),dash_array)) { - try + if (!dash_array.empty()) { - double f = boost::lexical_cast(*itr); - dash_array.push_back(f); - } - catch (boost::bad_lexical_cast &) - { - throw config_error(std::string("Failed to parse dasharray ") + - "'. Expected a " + - "list of floats but got '" + (*str) + "'"); - } - } - if (dash_array.size()) - { - size_t size = dash_array.size(); - if (size % 2) - { - for (size_t i=0; i < size ;++i) + size_t size = dash_array.size(); + if (size % 2 == 1) + dash_array.insert(dash_array.end(),dash_array.begin(),dash_array.end()); + + std::vector::const_iterator pos = dash_array.begin(); + while (pos != dash_array.end()) { - dash_array.push_back(dash_array[i]); + if (*pos > 0.0 || *(pos+1) > 0.0) // avoid both dash and gap eq 0.0 + strk.add_dash(*pos,*(pos + 1)); + pos +=2; } - } - std::vector::const_iterator pos = dash_array.begin(); - while (pos != dash_array.end()) - { - strk.add_dash(*pos,*(pos + 1)); - pos +=2; - } + } + } + else + { + throw config_error(std::string("Failed to parse dasharray ") + + "'. Expected a " + + "list of floats or 'none' but got '" + (*str) + "'"); } } } From 97a9abc8f3428ac59c89e937e369f5e5b6abaee0 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Fri, 23 Mar 2012 12:56:26 +0000 Subject: [PATCH 120/138] + add 'wsp' delimiter support + re-arrange grammar a bit --- include/mapnik/util/dasharray_parser.hpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/include/mapnik/util/dasharray_parser.hpp b/include/mapnik/util/dasharray_parser.hpp index e9a3753f2..32d405bed 100644 --- a/include/mapnik/util/dasharray_parser.hpp +++ b/include/mapnik/util/dasharray_parser.hpp @@ -37,20 +37,17 @@ bool parse_dasharray(Iterator first, Iterator last, std::vector& dasharr using qi::phrase_parse; using qi::_1; using qi::lit; - using ascii::space; + using qi::char_; + using qi::no_skip; using phoenix::push_back; // SVG // dasharray ::= (length | percentage) (comma-wsp dasharray)? // no support for 'percentage' as viewport is unknown at load_map // bool r = phrase_parse(first, last, - ( - lit("none") | (double_[push_back(phoenix::ref(dasharray), _1)] - >> *(',' >> double_[push_back(phoenix::ref(dasharray), _1)])) - ) - , - space); - + (double_[push_back(phoenix::ref(dasharray), _1)] % no_skip[char_(", ")] | lit("none")), + qi::ascii::space); + if (first != last) return false; From 30f59aac0cc09660744a5afb925a21169634fdaf Mon Sep 17 00:00:00 2001 From: Datendelphin Date: Fri, 23 Mar 2012 17:33:35 +0100 Subject: [PATCH 121/138] fix invalid memory access in font engine acess of member face->num_faces after free() fixed by making local copy num_faces before FT_Done_Face(face) --- src/font_engine_freetype.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp index f30c41480..8e0746f29 100644 --- a/src/font_engine_freetype.cpp +++ b/src/font_engine_freetype.cpp @@ -83,10 +83,11 @@ bool freetype_engine::register_font(std::string const& file_name) } FT_Face face = 0; + int num_faces = 0; // some font files have multiple fonts in a file // the count is in the 'root' face library[0] // see the FT_FaceRec in freetype.h - for ( int i = 0; face == 0 || i < face->num_faces; i++ ) { + for ( int i = 0; face == 0 || i < num_faces; i++ ) { // if face is null then this is the first face error = FT_New_Face (library,file_name.c_str(),i,&face); if (error) @@ -94,6 +95,9 @@ bool freetype_engine::register_font(std::string const& file_name) FT_Done_FreeType(library); return false; } + // store num_faces locally, after FT_Done_Face it can not be accessed any more + if (!num_faces) + num_faces = face->num_faces; // some fonts can lack names, skip them // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec if (face->family_name && face->style_name) { From 2ff8c3344e8cc9981c871410dd856331de98207f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 23 Mar 2012 11:22:00 -0700 Subject: [PATCH 122/138] avoid copy --- include/mapnik/feature.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mapnik/feature.hpp b/include/mapnik/feature.hpp index 8a8d75bd5..fa517101c 100644 --- a/include/mapnik/feature.hpp +++ b/include/mapnik/feature.hpp @@ -224,13 +224,14 @@ public: box2d envelope() const { + // TODO - cache this box2d result; for (unsigned i=0;i box = geom.envelope(); + box2d const& box = geom.envelope(); result.init(box.minx(),box.miny(),box.maxx(),box.maxy()); } else From e570ea3a9890cc1c9588b5149cbb393b859416db Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 23 Mar 2012 12:42:11 -0700 Subject: [PATCH 123/138] hook up visual tests to the 'make test' target --- Makefile | 1 + tests/visual_tests/compare.py | 8 ++++++-- tests/visual_tests/test.py | 1 + tests/visual_tests/test_python.py | 10 ++++++---- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 51a2abbab..e8957a80d 100755 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ uninstall: test: @python tests/run_tests.py -q + @python tests/visual_tests/test.py pep8: # https://gist.github.com/1903033 diff --git a/tests/visual_tests/compare.py b/tests/visual_tests/compare.py index 414f49979..46bba923e 100644 --- a/tests/visual_tests/compare.py +++ b/tests/visual_tests/compare.py @@ -42,9 +42,9 @@ def compare(fn1, fn2): def summary(): global errors + print "-"*80 + print "Summary:" if len(errors) != 0: - print "-"*80 - print "Summary:" for error in errors: if (error[1] is None): print "Could not verify %s: No reference image found!" % error[0] @@ -52,3 +52,7 @@ def summary(): print "%s failed: %d different pixels" % error print "-"*80 sys.exit(1) + else: + print 'No errors detected!' + print "-"*80 + sys.exit(0) diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index 554c1c5c5..29716e6bd 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -19,6 +19,7 @@ sizes_many_in_small_range = [(490, 100), (495, 100), (497, 100), (498, 100), (499, 100), (500, 100), (501, 100), (502, 100), (505, 100), (510, 100)] dirname = os.path.dirname(__file__) + files = [ {'name': "list", 'sizes': sizes_many_in_big_range}, {'name': "simple", 'sizes': sizes_many_in_big_range}, diff --git a/tests/visual_tests/test_python.py b/tests/visual_tests/test_python.py index 0cba25907..9648a8626 100755 --- a/tests/visual_tests/test_python.py +++ b/tests/visual_tests/test_python.py @@ -4,6 +4,8 @@ import sys import os.path from compare import compare, summary +dirname = os.path.dirname(__file__) + class MyText(mapnik.FormattingNode): def __init__(self): mapnik.FormattingNode.__init__(self) @@ -69,7 +71,7 @@ m.append_style('Style', style) layer = mapnik.Layer('Layer') -layer.datasource = mapnik.Shapefile(file="data/points.shp") +layer.datasource = mapnik.Shapefile(file=os.path.join(dirname,"data/points.shp")) layer.styles.append('Style') m.layers.append(layer) @@ -97,9 +99,9 @@ format_trees = [ for format_tree in format_trees: text.placements.defaults.format_tree = format_tree[1] - mapnik.render_to_file(m, os.path.join("images", 'python-%s.png' % format_tree[0]), 'png') - compare(os.path.join("images", 'python-%s.png' % format_tree[0]), - os.path.join("images", 'python-%s-reference.png' % format_tree[0]) + mapnik.render_to_file(m, os.path.join(dirname,"images", 'python-%s.png' % format_tree[0]), 'png') + compare(os.path.join(dirname,"images", 'python-%s.png' % format_tree[0]), + os.path.join(dirname,"images", 'python-%s-reference.png' % format_tree[0]) ) summary() From 5e6632f6ebe76153763d3cb9a9a5866a8916b8b3 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 23 Mar 2012 14:22:47 -0700 Subject: [PATCH 124/138] declare register_fonts as static --- bindings/python/mapnik_font_engine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/python/mapnik_font_engine.cpp b/bindings/python/mapnik_font_engine.cpp index 3992b1287..1b2596e3c 100644 --- a/bindings/python/mapnik_font_engine.cpp +++ b/bindings/python/mapnik_font_engine.cpp @@ -42,6 +42,7 @@ void export_font_engine() .def("register_fonts",&freetype_engine::register_fonts) .def("face_names",&freetype_engine::face_names) .staticmethod("register_font") + .staticmethod("register_fonts") .staticmethod("face_names") ; } From 3b498efbd99b68bc46995c97dd34bcc3d0896a5f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 23 Mar 2012 15:07:28 -0700 Subject: [PATCH 125/138] fixup font registration code ensuring invalid fonts will warn but not throw and register_fonts will only return success if > one font is registered and none have failed --- Makefile | 3 ++ SConstruct | 2 +- src/font_engine_freetype.cpp | 60 +++++++++++---------- src/load_map.cpp | 8 ++- tests/cpp_tests/build.py | 2 + tests/cpp_tests/font_registration_test.cpp | 27 ++++++---- tests/data/fonts/fake.ttf | 0 tests/data/fonts/intentionally-broken.ttf | Bin 0 -> 49420 bytes tests/data/good_maps/rtl_text_map.xml | 4 +- 9 files changed, 65 insertions(+), 41 deletions(-) create mode 100644 tests/data/fonts/fake.ttf create mode 100644 tests/data/fonts/intentionally-broken.ttf diff --git a/Makefile b/Makefile index e8957a80d..33de62e87 100755 --- a/Makefile +++ b/Makefile @@ -27,4 +27,7 @@ pep8: @pep8 -r --select=W293 -q --filename=*.py `pwd`/tests/ | xargs gsed -i 's/^[ \r\t]*$//' @pep8 -r --select=W391 -q --filename=*.py `pwd`/tests/ | xargs gsed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}' +grind: + @valgrind --leak-check=full tests/cpp_tests/font_registration_test + .PHONY: clean reset uninstall test install diff --git a/SConstruct b/SConstruct index 60352732c..c014b9bb5 100644 --- a/SConstruct +++ b/SConstruct @@ -1716,7 +1716,7 @@ if not HELP_REQUESTED: # build C++ tests # not ready for release - #SConscript('tests/cpp_tests/build.py') + SConscript('tests/cpp_tests/build.py') # not ready for release #if env['SVG_RENDERER']: diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp index 8e0746f29..cef4551d8 100644 --- a/src/font_engine_freetype.cpp +++ b/src/font_engine_freetype.cpp @@ -71,11 +71,10 @@ bool freetype_engine::is_font_file(std::string const& file_name) bool freetype_engine::register_font(std::string const& file_name) { - if (!boost::filesystem::is_regular_file(file_name) || !is_font_file(file_name)) return false; #ifdef MAPNIK_THREADSAFE mutex::scoped_lock lock(mutex_); #endif - FT_Library library; + FT_Library library = 0; FT_Error error = FT_Init_FreeType(&library); if (error) { @@ -84,6 +83,7 @@ bool freetype_engine::register_font(std::string const& file_name) FT_Face face = 0; int num_faces = 0; + bool success = false; // some font files have multiple fonts in a file // the count is in the 'root' face library[0] // see the FT_FaceRec in freetype.h @@ -92,31 +92,37 @@ bool freetype_engine::register_font(std::string const& file_name) error = FT_New_Face (library,file_name.c_str(),i,&face); if (error) { - FT_Done_FreeType(library); - return false; + break; } // store num_faces locally, after FT_Done_Face it can not be accessed any more if (!num_faces) num_faces = face->num_faces; // some fonts can lack names, skip them // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec - if (face->family_name && face->style_name) { + if (face->family_name && face->style_name) + { + success = true; std::string name = std::string(face->family_name) + " " + std::string(face->style_name); name2file_.insert(std::make_pair(name, std::make_pair(i,file_name))); - FT_Done_Face(face); - //FT_Done_FreeType(library); - //return true; - } else { - FT_Done_Face(face); - FT_Done_FreeType(library); + } + else + { std::ostringstream s; - s << "Error: unable to load invalid font file which lacks identifiable family and style name: '" - << file_name << "'"; - throw std::runtime_error(s.str()); + s << "Warning: unable to load font file '" << file_name << "' "; + if (!face->family_name && !face->style_name) + s << "which lacks both a family name and style name"; + else if (face->family_name) + s << "which reports a family name of '" << std::string(face->family_name) << "' and lacks a style name"; + else if (face->style_name) + s << "which reports a style name of '" << std::string(face->style_name) << "' and lacks a family name"; + std::clog << s.str() << std::endl; } } - FT_Done_FreeType(library); - return true; + if (face) + FT_Done_Face(face); + if (library) + FT_Done_FreeType(library); + return success; } bool freetype_engine::register_fonts(std::string const& dir, bool recurse) @@ -130,26 +136,24 @@ bool freetype_engine::register_fonts(std::string const& dir, bool recurse) return mapnik::freetype_engine::register_font(dir); boost::filesystem::directory_iterator end_itr; + bool success = false; for (boost::filesystem::directory_iterator itr(dir); itr != end_itr; ++itr) { +#if (BOOST_FILESYSTEM_VERSION == 3) + std::string const& file_name = itr->path().string(); +#else // v2 + std::string const& file_name = itr->string(); +#endif if (boost::filesystem::is_directory(*itr) && recurse) { -#if (BOOST_FILESYSTEM_VERSION == 3) - if (!register_fonts(itr->path().string(), true)) return false; -#else // v2 - if (!register_fonts(itr->string(), true)) return false; -#endif + success = register_fonts(file_name, true); } - else + else if (boost::filesystem::is_regular_file(file_name) && is_font_file(file_name)) { -#if (BOOST_FILESYSTEM_VERSION == 3) - mapnik::freetype_engine::register_font(itr->path().string()); -#else // v2 - mapnik::freetype_engine::register_font(itr->string()); -#endif + success = mapnik::freetype_engine::register_font(file_name); } } - return true; + return success; } diff --git a/src/load_map.cpp b/src/load_map.cpp index ee4313d91..2682015fd 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -242,7 +242,13 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas if (font_directory) { extra_attr["font-directory"] = *font_directory; - freetype_engine::register_fonts(ensure_relative_to_xml(font_directory), false); + if (!freetype_engine::register_fonts(ensure_relative_to_xml(font_directory), false)) + { + if (strict_) + { + throw config_error(std::string("Failed to load fonts from: ") << *font_directory); + } + } } optional min_version_string = map_node.get_opt_attr("minimum-version"); diff --git a/tests/cpp_tests/build.py b/tests/cpp_tests/build.py index 11cd33f45..bcc31bc94 100644 --- a/tests/cpp_tests/build.py +++ b/tests/cpp_tests/build.py @@ -11,6 +11,8 @@ headers = env['CPPPATH'] libraries = copy(env['LIBMAPNIK_LIBS']) libraries.append('mapnik') +test_env.Append(CXXFLAGS='-g') + for cpp_test in glob.glob('*_test.cpp'): test_program = test_env.Program(cpp_test.replace('.cpp',''), [cpp_test], CPPPATH=headers, LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS']) Depends(test_program, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME'])) diff --git a/tests/cpp_tests/font_registration_test.cpp b/tests/cpp_tests/font_registration_test.cpp index 1906d896b..55715b9b1 100644 --- a/tests/cpp_tests/font_registration_test.cpp +++ b/tests/cpp_tests/font_registration_test.cpp @@ -6,8 +6,6 @@ using fs::path; namespace sys = boost::system; #include -//#include -//#include #include #include @@ -39,14 +37,23 @@ int main( int, char*[] ) // directories without fonts std::string src("src"); - // a legitimate directory will return true even it is does not - // successfully register a font... - BOOST_TEST( mapnik::freetype_engine::register_fonts(src , true ) ); - face_names = mapnik::freetype_engine::face_names(); - BOOST_TEST( face_names.size() == 0 ); - std::clog << "number of registered fonts: " << face_names.size() << std::endl; + // an empty directory will not return true + // we need to register at least one font and not fail on any + // to return true + BOOST_TEST( mapnik::freetype_engine::register_font(src) == false ); + BOOST_TEST( mapnik::freetype_engine::register_fonts(src, true) == false ); + BOOST_TEST( mapnik::freetype_engine::face_names().size() == 0 ); - // register unifont + // bogus, emtpy file that looks like font + BOOST_TEST( mapnik::freetype_engine::register_font("tests/data/fonts/fake.ttf") == false ); + BOOST_TEST( mapnik::freetype_engine::register_fonts("tests/data/fonts/fake.ttf") == false ); + BOOST_TEST( mapnik::freetype_engine::face_names().size() == 0 ); + + BOOST_TEST( mapnik::freetype_engine::register_font("tests/data/fonts/intentionally-broken.ttf") == false ); + BOOST_TEST( mapnik::freetype_engine::register_fonts("tests/data/fonts/intentionally-broken.ttf") == false ); + BOOST_TEST( mapnik::freetype_engine::face_names().size() == 0 ); + + // register unifont, since we know it sits in the root fonts/ dir BOOST_TEST( mapnik::freetype_engine::register_fonts(fontdir) ); face_names = mapnik::freetype_engine::face_names(); std::clog << "number of registered fonts: " << face_names.size() << std::endl; @@ -71,7 +78,7 @@ int main( int, char*[] ) BOOST_TEST( mapnik::freetype_engine::register_fonts(fontdir, true) ); face_names = mapnik::freetype_engine::face_names(); std::clog << "number of registered fonts: " << face_names.size() << std::endl; - BOOST_TEST( face_names.size() == 21 ); + BOOST_TEST( face_names.size() == 22 ); return ::boost::report_errors(); } diff --git a/tests/data/fonts/fake.ttf b/tests/data/fonts/fake.ttf new file mode 100644 index 000000000..e69de29bb diff --git a/tests/data/fonts/intentionally-broken.ttf b/tests/data/fonts/intentionally-broken.ttf new file mode 100644 index 0000000000000000000000000000000000000000..887230d766e322b73024f482f859abecf6818fb2 GIT binary patch literal 49420 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 literal 0 HcmV?d00001 diff --git a/tests/data/good_maps/rtl_text_map.xml b/tests/data/good_maps/rtl_text_map.xml index 3892c69af..38f46aca1 100644 --- a/tests/data/good_maps/rtl_text_map.xml +++ b/tests/data/good_maps/rtl_text_map.xml @@ -1,5 +1,7 @@ - + + +