From 9c5dbc20c50ed6f96d301627eb25a1f6b1202064 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 20 Jul 2012 15:28:10 -0700 Subject: [PATCH 01/66] properly skip empty geometries - refs #1333 and #1305 an #1132 + remove redundant ar.size() > 0 check + use std::auto_ptr to avoid memory leaks and improve exception safety. --- src/wkb.cpp | 128 ++++++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 58 deletions(-) diff --git a/src/wkb.cpp b/src/wkb.cpp index 0551034cd..a26122a88 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -113,9 +113,6 @@ public: { int type = read_integer(); -#ifdef MAPNIK_LOG - MAPNIK_LOG_DEBUG(wkb_reader) << "wkb_reader: Read=" << wkb_geometry_type_string(type) << "," << type; -#endif switch (type) { case wkbPoint: @@ -246,9 +243,9 @@ private: void read_point(boost::ptr_vector & paths) { - geometry_type* pt = new geometry_type(Point); double x = read_double(); double y = read_double(); + std::auto_ptr pt(new geometry_type(Point)); pt->move_to(x, y); paths.push_back(pt); } @@ -265,9 +262,9 @@ private: void read_point_xyz(boost::ptr_vector & paths) { - geometry_type* pt = new geometry_type(Point); double x = read_double(); double y = read_double(); + std::auto_ptr pt(new geometry_type(Point)); pos_ += 8; // double z = read_double(); pt->move_to(x, y); paths.push_back(pt); @@ -285,16 +282,19 @@ private: void read_linestring(boost::ptr_vector & paths) { - geometry_type* line = new geometry_type(LineString); int num_points = read_integer(); - CoordinateArray ar(num_points); - read_coords(ar); - line->move_to(ar[0].x, ar[0].y); - for (int i = 1; i < num_points; ++i) + if (num_points > 0) { - line->line_to(ar[i].x, ar[i].y); + CoordinateArray ar(num_points); + read_coords(ar); + std::auto_ptr line(new geometry_type(LineString)); + line->move_to(ar[0].x, ar[0].y); + for (int i = 1; i < num_points; ++i) + { + line->line_to(ar[i].x, ar[i].y); + } + paths.push_back(line); } - paths.push_back(line); } void read_multilinestring(boost::ptr_vector & paths) @@ -309,16 +309,19 @@ private: void read_linestring_xyz(boost::ptr_vector & paths) { - geometry_type* line = new geometry_type(LineString); int num_points = read_integer(); - CoordinateArray ar(num_points); - read_coords_xyz(ar); - line->move_to(ar[0].x, ar[0].y); - for (int i = 1; i < num_points; ++i) + if (num_points > 0) { - line->line_to(ar[i].x, ar[i].y); + CoordinateArray ar(num_points); + read_coords_xyz(ar); + std::auto_ptr line(new geometry_type(LineString)); + line->move_to(ar[0].x, ar[0].y); + for (int i = 1; i < num_points; ++i) + { + line->line_to(ar[i].x, ar[i].y); + } + paths.push_back(line); } - paths.push_back(line); } void read_multilinestring_xyz(boost::ptr_vector & paths) @@ -334,22 +337,27 @@ private: void read_polygon(boost::ptr_vector & paths) { - geometry_type* poly = new geometry_type(Polygon); int num_rings = read_integer(); - unsigned capacity = 0; - for (int i = 0; i < num_rings; ++i) + if (num_rings > 0) { - int num_points = read_integer(); - capacity += num_points; - CoordinateArray ar(num_points); - read_coords(ar); - poly->move_to(ar[0].x, ar[0].y); - for (int j = 1; j < num_points; ++j) + std::auto_ptr poly(new geometry_type(Polygon)); + for (int i = 0; i < num_rings; ++i) { - poly->line_to(ar[j].x, ar[j].y); + int num_points = read_integer(); + if (num_points > 0) + { + CoordinateArray ar(num_points); + read_coords(ar); + poly->move_to(ar[0].x, ar[0].y); + for (int j = 1; j < num_points; ++j) + { + poly->line_to(ar[j].x, ar[j].y); + } + } } + if (poly->size() > 2) // ignore if polygon has less than 3 vertices + paths.push_back(poly); } - paths.push_back(poly); } void read_multipolygon(boost::ptr_vector & paths) @@ -364,22 +372,27 @@ private: void read_polygon_xyz(boost::ptr_vector & paths) { - geometry_type* poly = new geometry_type(Polygon); int num_rings = read_integer(); - unsigned capacity = 0; - for (int i = 0; i < num_rings; ++i) + if (num_rings > 0) { - int num_points = read_integer(); - capacity += num_points; - CoordinateArray ar(num_points); - read_coords_xyz(ar); - poly->move_to(ar[0].x, ar[0].y); - for (int j = 1; j < num_points; ++j) + std::auto_ptr poly(new geometry_type(Polygon)); + for (int i = 0; i < num_rings; ++i) { - poly->line_to(ar[j].x, ar[j].y); + int num_points = read_integer(); + if (num_points > 0) + { + CoordinateArray ar(num_points); + read_coords_xyz(ar); + poly->move_to(ar[0].x, ar[0].y); + for (int j = 1; j < num_points; ++j) + { + poly->line_to(ar[j].x, ar[j].y); + } + } } + if (poly->size() > 2) // ignore if polygon has less than 3 vertices + paths.push_back(poly); } - paths.push_back(poly); } void read_multipolygon_xyz(boost::ptr_vector & paths) @@ -402,33 +415,32 @@ private: } } -#ifdef MAPNIK_LOG std::string wkb_geometry_type_string(int type) { std::stringstream s; switch (type) { - case wkbPoint: s << "wkbPoint"; break; - case wkbLineString: s << "wkbLineString"; break; - case wkbPolygon: s << "wkbPolygon"; break; - case wkbMultiPoint: s << "wkbMultiPoint"; break; - case wkbMultiLineString: s << "wkbMultiLineString"; break; - case wkbMultiPolygon: s << "wkbMultiPolygon"; break; - case wkbGeometryCollection: s << "wkbGeometryCollection"; break; - case wkbPointZ: s << "wkbPointZ"; break; - case wkbLineStringZ: s << "wkbLineStringZ"; break; - case wkbPolygonZ: s << "wkbPolygonZ"; break; - case wkbMultiPointZ: s << "wkbMultiPointZ"; break; - case wkbMultiLineStringZ: s << "wkbMultiLineStringZ"; break; - case wkbMultiPolygonZ: s << "wkbMultiPolygonZ"; break; - case wkbGeometryCollectionZ: s << "wkbGeometryCollectionZ"; break; - default: s << "wkbUknown"; break; + case wkbPoint: s << "Point"; break; + case wkbLineString: s << "LineString"; break; + case wkbPolygon: s << "Polygon"; break; + case wkbMultiPoint: s << "MultiPoint"; break; + case wkbMultiLineString: s << "MultiLineString"; break; + case wkbMultiPolygon: s << "MultiPolygon"; break; + case wkbGeometryCollection: s << "GeometryCollection"; break; + case wkbPointZ: s << "PointZ"; break; + case wkbLineStringZ: s << "LineStringZ"; break; + case wkbPolygonZ: s << "PolygonZ"; break; + case wkbMultiPointZ: s << "MultiPointZ"; break; + case wkbMultiLineStringZ: s << "MultiLineStringZ"; break; + case wkbMultiPolygonZ: s << "MultiPolygonZ"; break; + case wkbGeometryCollectionZ: s << "GeometryCollectionZ"; break; + default: s << "wkbUknown(" << type << ")"; break; } return s.str(); } -#endif + }; bool geometry_utils::from_wkb(boost::ptr_vector& paths, From bbd1b052f7571ee79ba186279e0b91aaf8ceb4fd Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 11:38:59 -0700 Subject: [PATCH 02/66] fix spelling in comment --- include/mapnik/transform_expression.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/transform_expression.hpp b/include/mapnik/transform_expression.hpp index 069863470..53170f63f 100644 --- a/include/mapnik/transform_expression.hpp +++ b/include/mapnik/transform_expression.hpp @@ -115,7 +115,7 @@ namespace detail { // boost::spirit::traits::clear(T& val) [with T = boost::variant<...>] // attempts to assign to the variant's current value a default-constructed -// value ot the same type, which not only requires that each value-type is +// value of the same type, which not only requires that each value-type is // default-constructible, but also makes little sense with our variant of // transform nodes... From 450bf40d4da7a4959c248699ff9063cc866ba6a9 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 11:41:08 -0700 Subject: [PATCH 03/66] suppress strict-aliasing warnings with older gcc and newer boost - refs #1330 --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 60c68a83b..2b0f716e7 100644 --- a/SConstruct +++ b/SConstruct @@ -1526,7 +1526,7 @@ if not preconfigured: if env['DEBUG']: env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags) else: - env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags)) + env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -fno-strict-aliasing -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags)) if env['DEBUG_UNDEFINED']: env.Append(CXXFLAGS = '-fcatch-undefined-behavior -ftrapv -fwrapv') From e13e81c4d54fce5921124b12e35df32e585ed07f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 11:43:24 -0700 Subject: [PATCH 04/66] move grid utility functions to cpp file - avoids function 'defined but not used' compiler warnings - refs #1330 --- bindings/python/python_grid_utils.cpp | 505 ++++++++++++++++++++++++++ bindings/python/python_grid_utils.hpp | 449 +---------------------- 2 files changed, 521 insertions(+), 433 deletions(-) create mode 100644 bindings/python/python_grid_utils.cpp diff --git a/bindings/python/python_grid_utils.cpp b/bindings/python/python_grid_utils.cpp new file mode 100644 index 000000000..87379c9fd --- /dev/null +++ b/bindings/python/python_grid_utils.cpp @@ -0,0 +1,505 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +// boost +#include +#include +#include + +// mapnik +#include +#include +#include +#include +#include +#include +#include +#include +#include "mapnik_value_converter.hpp" +#include "python_grid_utils.hpp" + +namespace mapnik { + + +template +void grid2utf(T const& grid_type, + boost::python::list& l, + std::vector& key_order) +{ + typedef std::map< typename T::lookup_type, typename T::value_type> keys_type; + typedef typename keys_type::const_iterator keys_iterator; + + typename T::data_type const& data = grid_type.data(); + typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys(); + typename T::feature_key_type::const_iterator feature_pos; + + keys_type keys; + // start counting at utf8 codepoint 32, aka space character + boost::uint16_t codepoint = 32; + + unsigned array_size = data.width(); + for (unsigned y = 0; y < data.height(); ++y) + { + boost::uint16_t idx = 0; + boost::scoped_array line(new Py_UNICODE[array_size]); + typename T::value_type const* row = data.getRow(y); + for (unsigned x = 0; x < data.width(); ++x) + { + typename T::value_type feature_id = row[x]; + feature_pos = feature_keys.find(feature_id); + if (feature_pos != feature_keys.end()) + { + mapnik::grid::lookup_type val = feature_pos->second; + keys_iterator key_pos = keys.find(val); + if (key_pos == keys.end()) + { + // Create a new entry for this key. Skip the codepoints that + // can't be encoded directly in JSON. + if (codepoint == 34) ++codepoint; // Skip " + else if (codepoint == 92) ++codepoint; // Skip backslash + if (feature_id == mapnik::grid::base_mask) + { + keys[""] = codepoint; + key_order.push_back(""); + } + else + { + keys[val] = codepoint; + key_order.push_back(val); + } + line[idx++] = static_cast(codepoint); + ++codepoint; + } + else + { + line[idx++] = static_cast(key_pos->second); + } + } + // else, shouldn't get here... + } + l.append(boost::python::object( + boost::python::handle<>( + PyUnicode_FromUnicode(line.get(), array_size)))); + } +} + + +template +void grid2utf(T const& grid_type, + boost::python::list& l, + std::vector& key_order, + unsigned int resolution) +{ + typedef std::map< typename T::lookup_type, typename T::value_type> keys_type; + typedef typename keys_type::const_iterator keys_iterator; + + typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys(); + typename T::feature_key_type::const_iterator feature_pos; + + keys_type keys; + // start counting at utf8 codepoint 32, aka space character + boost::uint16_t codepoint = 32; + + // TODO - use double? + unsigned array_size = static_cast(grid_type.width()/resolution); + for (unsigned y = 0; y < grid_type.height(); y=y+resolution) + { + boost::uint16_t idx = 0; + boost::scoped_array line(new Py_UNICODE[array_size]); + mapnik::grid::value_type const* row = grid_type.getRow(y); + for (unsigned x = 0; x < grid_type.width(); x=x+resolution) + { + typename T::value_type feature_id = row[x]; + feature_pos = feature_keys.find(feature_id); + if (feature_pos != feature_keys.end()) + { + mapnik::grid::lookup_type val = feature_pos->second; + keys_iterator key_pos = keys.find(val); + if (key_pos == keys.end()) + { + // Create a new entry for this key. Skip the codepoints that + // can't be encoded directly in JSON. + if (codepoint == 34) ++codepoint; // Skip " + else if (codepoint == 92) ++codepoint; // Skip backslash + if (feature_id == mapnik::grid::base_mask) + { + keys[""] = codepoint; + key_order.push_back(""); + } + else + { + keys[val] = codepoint; + key_order.push_back(val); + } + line[idx++] = static_cast(codepoint); + ++codepoint; + } + else + { + line[idx++] = static_cast(key_pos->second); + } + } + // else, shouldn't get here... + } + l.append(boost::python::object( + boost::python::handle<>( + PyUnicode_FromUnicode(line.get(), array_size)))); + } +} + + +template +void grid2utf2(T const& grid_type, + boost::python::list& l, + std::vector& key_order, + unsigned int resolution) +{ + typedef std::map< typename T::lookup_type, typename T::value_type> keys_type; + typedef typename keys_type::const_iterator keys_iterator; + + typename T::data_type const& data = grid_type.data(); + typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys(); + typename T::feature_key_type::const_iterator feature_pos; + + keys_type keys; + // start counting at utf8 codepoint 32, aka space character + uint16_t codepoint = 32; + + mapnik::grid::data_type target(data.width()/resolution,data.height()/resolution); + mapnik::scale_grid(target,grid_type.data(),0.0,0.0); + + unsigned array_size = target.width(); + for (unsigned y = 0; y < target.height(); ++y) + { + uint16_t idx = 0; + boost::scoped_array line(new Py_UNICODE[array_size]); + mapnik::grid::value_type * row = target.getRow(y); + unsigned x; + for (x = 0; x < target.width(); ++x) + { + feature_pos = feature_keys.find(row[x]); + if (feature_pos != feature_keys.end()) + { + mapnik::grid::lookup_type val = feature_pos->second; + keys_iterator key_pos = keys.find(val); + if (key_pos == keys.end()) + { + // Create a new entry for this key. Skip the codepoints that + // can't be encoded directly in JSON. + if (codepoint == 34) ++codepoint; // Skip " + else if (codepoint == 92) ++codepoint; // Skip backslash + keys[val] = codepoint; + key_order.push_back(val); + line[idx++] = static_cast(codepoint); + ++codepoint; + } + else + { + line[idx++] = static_cast(key_pos->second); + } + } + // else, shouldn't get here... + } + l.append(boost::python::object( + boost::python::handle<>( + PyUnicode_FromUnicode(line.get(), array_size)))); + } +} + + +template +void write_features(T const& grid_type, + boost::python::dict& feature_data, + std::vector const& key_order) +{ + std::string const& key = grid_type.get_key(); + std::set const& attributes = grid_type.property_names(); + typename T::feature_type const& g_features = grid_type.get_grid_features(); + typename T::feature_type::const_iterator feat_itr = g_features.begin(); + typename T::feature_type::const_iterator feat_end = g_features.end(); + bool include_key = (attributes.find(key) != attributes.end()); + for (; feat_itr != feat_end; ++feat_itr) + { + mapnik::feature_ptr feature = feat_itr->second; + boost::optional join_value; + if (key == grid_type.key_name()) + { + join_value = feat_itr->first; + } + else if (feature->has_key(key)) + { + join_value = feature->get(key).to_string(); + } + + if (join_value) + { + // only serialize features visible in the grid + if(std::find(key_order.begin(), key_order.end(), *join_value) != key_order.end()) { + boost::python::dict feat; + bool found = false; + if (key == grid_type.key_name()) + { + // drop key unless requested + if (include_key) { + found = true; + //TODO - add __id__ as data key? + //feat[key] = *join_value; + } + } + + feature_kv_iterator itr = feature->begin(); + feature_kv_iterator end = feature->end(); + for ( ;itr!=end; ++itr) + { + std::string const& key_name = boost::get<0>(*itr); + if (key_name == key) { + // drop key unless requested + if (include_key) { + found = true; + feat[key_name] = boost::get<1>(*itr); + } + } + else if ( (attributes.find(key_name) != attributes.end()) ) + { + found = true; + feat[key_name] = boost::get<1>(*itr); + } + } + + if (found) + { + feature_data[feat_itr->first] = feat; + } + } + } + else + { + MAPNIK_LOG_DEBUG(bindings) << "write_features: Should not get here: key " << key << " not found in grid feature properties"; + } + } +} + +template +void grid_encode_utf(T const& grid_type, + boost::python::dict & json, + bool add_features, + unsigned int resolution) +{ + // convert buffer to utf and gather key order + boost::python::list l; + std::vector key_order; + + if (resolution != 1) { + // resample on the fly - faster, less accurate + mapnik::grid2utf(grid_type,l,key_order,resolution); + + // resample first - slower, more accurate + //mapnik::grid2utf2(grid_type,l,key_order,resolution); + } + else + { + mapnik::grid2utf(grid_type,l,key_order); + } + + // convert key order to proper python list + boost::python::list keys_a; + BOOST_FOREACH ( typename T::lookup_type const& key_id, key_order ) + { + keys_a.append(key_id); + } + + // gather feature data + boost::python::dict feature_data; + if (add_features) { + mapnik::write_features(grid_type,feature_data,key_order); + } + + json["grid"] = l; + json["keys"] = keys_a; + json["data"] = feature_data; + +} + +template +boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution) +{ + if (format == "utf") { + boost::python::dict json; + grid_encode_utf(grid,json,add_features,resolution); + return json; + } + else + { + std::stringstream s; + s << "'utf' is currently the only supported encoding format."; + throw mapnik::value_error(s.str()); + } +} + +template boost::python::dict grid_encode( mapnik::grid const& grid, std::string format, bool add_features, unsigned int resolution); +template boost::python::dict grid_encode( mapnik::grid_view const& grid, std::string format, bool add_features, unsigned int resolution); + +/* new approach: key comes from grid object + * grid size should be same as the map + * encoding, resizing handled as method on grid object + * whether features are dumped is determined by argument not 'fields' + */ +void render_layer_for_grid(const mapnik::Map& map, + mapnik::grid& grid, + unsigned layer_idx, // TODO - layer by name or index + boost::python::list const& fields) +{ + std::vector const& layers = map.layers(); + std::size_t layer_num = layers.size(); + if (layer_idx >= layer_num) { + std::ostringstream s; + s << "Zero-based layer index '" << layer_idx << "' not valid, only '" + << layer_num << "' layers are in map\n"; + throw std::runtime_error(s.str()); + } + + // convert python list to std::vector + boost::python::ssize_t num_fields = boost::python::len(fields); + for(boost::python::ssize_t i=0; i name(fields[i]); + if (name.check()) { + grid.add_property_name(name()); + } + else + { + std::stringstream s; + s << "list of field names must be strings"; + throw mapnik::value_error(s.str()); + } + } + + // copy property names + std::set attributes = grid.property_names(); + std::string const& key = grid.get_key(); + + // if key is special __id__ keyword + if (key == grid.key_name()) + { + // TODO - should feature.id() be a first class attribute? + + // if __id__ is requested to be dumped out + // remove it so that datasource queries will not break + if (attributes.find(key) != attributes.end()) + { + attributes.erase(key); + } + } + // if key is not the special __id__ keyword + else if (attributes.find(key) == attributes.end()) + { + // them make sure the datasource query includes this field + attributes.insert(key); + } + + mapnik::grid_renderer ren(map,grid,1.0,0,0); + mapnik::layer const& layer = layers[layer_idx]; + ren.apply(layer,attributes); +} + +/* old, original impl - to be removed after further testing + * grid object is created on the fly at potentially reduced size + */ +boost::python::dict render_grid(const mapnik::Map& map, + unsigned layer_idx, // layer + std::string const& key, // key_name + unsigned int step, // resolution + boost::python::list const& fields) +{ + + std::vector const& layers = map.layers(); + std::size_t layer_num = layers.size(); + if (layer_idx >= layer_num) { + std::ostringstream s; + s << "Zero-based layer index '" << layer_idx << "' not valid, only '" + << layer_num << "' layers are in map\n"; + throw std::runtime_error(s.str()); + } + + unsigned int grid_width = map.width()/step; + unsigned int grid_height = map.height()/step; + + // TODO - no need to pass step here + mapnik::grid grid(grid_width,grid_height,key,step); + + // convert python list to std::vector + boost::python::ssize_t num_fields = boost::python::len(fields); + for(boost::python::ssize_t i=0; i name(fields[i]); + if (name.check()) { + grid.add_property_name(name()); + } + else + { + std::stringstream s; + s << "list of field names must be strings"; + throw mapnik::value_error(s.str()); + } + } + + // copy property names + std::set attributes = grid.property_names(); + + // if key is special __id__ keyword + if (key == grid.key_name()) + { + // TODO - should feature.id() be a first class attribute? + + // if __id__ is requested to be dumped out + // remove it so that datasource queries will not break + if (attributes.find(key) != attributes.end()) + { + attributes.erase(key); + } + } + // if key is not the special __id__ keyword + else if (attributes.find(key) == attributes.end()) + { + // them make sure the datasource query includes this field + attributes.insert(key); + } + + try + { + mapnik::grid_renderer ren(map,grid,1.0,0,0); + mapnik::layer const& layer = layers[layer_idx]; + ren.apply(layer,attributes); + } + catch (...) + { + throw; + } + + bool add_features = false; + if (num_fields > 0) + add_features = true; + // build dictionary and return to python + boost::python::dict json; + grid_encode_utf(grid,json,add_features,1); + return json; +} + +} diff --git a/bindings/python/python_grid_utils.hpp b/bindings/python/python_grid_utils.hpp index f3d1301ca..30ed4ff43 100644 --- a/bindings/python/python_grid_utils.hpp +++ b/bindings/python/python_grid_utils.hpp @@ -24,483 +24,66 @@ // boost #include -#include -#include // mapnik -#include -#include +#include #include -#include -#include -#include -#include -#include -#include "mapnik_value_converter.hpp" - namespace mapnik { template -static void grid2utf(T const& grid_type, +void grid2utf(T const& grid_type, boost::python::list& l, - std::vector& key_order) -{ - typedef std::map< typename T::lookup_type, typename T::value_type> keys_type; - typedef typename keys_type::const_iterator keys_iterator; - - typename T::data_type const& data = grid_type.data(); - typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys(); - typename T::feature_key_type::const_iterator feature_pos; - - keys_type keys; - // start counting at utf8 codepoint 32, aka space character - boost::uint16_t codepoint = 32; - - unsigned array_size = data.width(); - for (unsigned y = 0; y < data.height(); ++y) - { - boost::uint16_t idx = 0; - boost::scoped_array line(new Py_UNICODE[array_size]); - typename T::value_type const* row = data.getRow(y); - for (unsigned x = 0; x < data.width(); ++x) - { - typename T::value_type feature_id = row[x]; - feature_pos = feature_keys.find(feature_id); - if (feature_pos != feature_keys.end()) - { - mapnik::grid::lookup_type val = feature_pos->second; - keys_iterator key_pos = keys.find(val); - if (key_pos == keys.end()) - { - // Create a new entry for this key. Skip the codepoints that - // can't be encoded directly in JSON. - if (codepoint == 34) ++codepoint; // Skip " - else if (codepoint == 92) ++codepoint; // Skip backslash - if (feature_id == mapnik::grid::base_mask) - { - keys[""] = codepoint; - key_order.push_back(""); - } - else - { - keys[val] = codepoint; - key_order.push_back(val); - } - line[idx++] = static_cast(codepoint); - ++codepoint; - } - else - { - line[idx++] = static_cast(key_pos->second); - } - } - // else, shouldn't get here... - } - l.append(boost::python::object( - boost::python::handle<>( - PyUnicode_FromUnicode(line.get(), array_size)))); - } -} + std::vector& key_order); template -static void grid2utf(T const& grid_type, +void grid2utf(T const& grid_type, boost::python::list& l, std::vector& key_order, - unsigned int resolution) -{ - typedef std::map< typename T::lookup_type, typename T::value_type> keys_type; - typedef typename keys_type::const_iterator keys_iterator; - - typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys(); - typename T::feature_key_type::const_iterator feature_pos; - - keys_type keys; - // start counting at utf8 codepoint 32, aka space character - boost::uint16_t codepoint = 32; - - // TODO - use double? - unsigned array_size = static_cast(grid_type.width()/resolution); - for (unsigned y = 0; y < grid_type.height(); y=y+resolution) - { - boost::uint16_t idx = 0; - boost::scoped_array line(new Py_UNICODE[array_size]); - mapnik::grid::value_type const* row = grid_type.getRow(y); - for (unsigned x = 0; x < grid_type.width(); x=x+resolution) - { - typename T::value_type feature_id = row[x]; - feature_pos = feature_keys.find(feature_id); - if (feature_pos != feature_keys.end()) - { - mapnik::grid::lookup_type val = feature_pos->second; - keys_iterator key_pos = keys.find(val); - if (key_pos == keys.end()) - { - // Create a new entry for this key. Skip the codepoints that - // can't be encoded directly in JSON. - if (codepoint == 34) ++codepoint; // Skip " - else if (codepoint == 92) ++codepoint; // Skip backslash - if (feature_id == mapnik::grid::base_mask) - { - keys[""] = codepoint; - key_order.push_back(""); - } - else - { - keys[val] = codepoint; - key_order.push_back(val); - } - line[idx++] = static_cast(codepoint); - ++codepoint; - } - else - { - line[idx++] = static_cast(key_pos->second); - } - } - // else, shouldn't get here... - } - l.append(boost::python::object( - boost::python::handle<>( - PyUnicode_FromUnicode(line.get(), array_size)))); - } -} + unsigned int resolution); template -static void grid2utf2(T const& grid_type, +void grid2utf2(T const& grid_type, boost::python::list& l, std::vector& key_order, - unsigned int resolution) -{ - typedef std::map< typename T::lookup_type, typename T::value_type> keys_type; - typedef typename keys_type::const_iterator keys_iterator; - - typename T::data_type const& data = grid_type.data(); - typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys(); - typename T::feature_key_type::const_iterator feature_pos; - - keys_type keys; - // start counting at utf8 codepoint 32, aka space character - uint16_t codepoint = 32; - - mapnik::grid::data_type target(data.width()/resolution,data.height()/resolution); - mapnik::scale_grid(target,grid_type.data(),0.0,0.0); - - unsigned array_size = target.width(); - for (unsigned y = 0; y < target.height(); ++y) - { - uint16_t idx = 0; - boost::scoped_array line(new Py_UNICODE[array_size]); - mapnik::grid::value_type * row = target.getRow(y); - unsigned x; - for (x = 0; x < target.width(); ++x) - { - feature_pos = feature_keys.find(row[x]); - if (feature_pos != feature_keys.end()) - { - mapnik::grid::lookup_type val = feature_pos->second; - keys_iterator key_pos = keys.find(val); - if (key_pos == keys.end()) - { - // Create a new entry for this key. Skip the codepoints that - // can't be encoded directly in JSON. - if (codepoint == 34) ++codepoint; // Skip " - else if (codepoint == 92) ++codepoint; // Skip backslash - keys[val] = codepoint; - key_order.push_back(val); - line[idx++] = static_cast(codepoint); - ++codepoint; - } - else - { - line[idx++] = static_cast(key_pos->second); - } - } - // else, shouldn't get here... - } - l.append(boost::python::object( - boost::python::handle<>( - PyUnicode_FromUnicode(line.get(), array_size)))); - } -} + unsigned int resolution); template -static void write_features(T const& grid_type, +void write_features(T const& grid_type, boost::python::dict& feature_data, - std::vector const& key_order) -{ - std::string const& key = grid_type.get_key(); - std::set const& attributes = grid_type.property_names(); - typename T::feature_type const& g_features = grid_type.get_grid_features(); - typename T::feature_type::const_iterator feat_itr = g_features.begin(); - typename T::feature_type::const_iterator feat_end = g_features.end(); - bool include_key = (attributes.find(key) != attributes.end()); - for (; feat_itr != feat_end; ++feat_itr) - { - mapnik::feature_ptr feature = feat_itr->second; - boost::optional join_value; - if (key == grid_type.key_name()) - { - join_value = feat_itr->first; - } - else if (feature->has_key(key)) - { - join_value = feature->get(key).to_string(); - } - - if (join_value) - { - // only serialize features visible in the grid - if(std::find(key_order.begin(), key_order.end(), *join_value) != key_order.end()) { - boost::python::dict feat; - bool found = false; - if (key == grid_type.key_name()) - { - // drop key unless requested - if (include_key) { - found = true; - //TODO - add __id__ as data key? - //feat[key] = *join_value; - } - } - - feature_kv_iterator itr = feature->begin(); - feature_kv_iterator end = feature->end(); - for ( ;itr!=end; ++itr) - { - std::string const& key_name = boost::get<0>(*itr); - if (key_name == key) { - // drop key unless requested - if (include_key) { - found = true; - feat[key_name] = boost::get<1>(*itr); - } - } - else if ( (attributes.find(key_name) != attributes.end()) ) - { - found = true; - feat[key_name] = boost::get<1>(*itr); - } - } - - if (found) - { - feature_data[feat_itr->first] = feat; - } - } - } - else - { - MAPNIK_LOG_DEBUG(bindings) << "write_features: Should not get here: key " << key << " not found in grid feature properties"; - } - } -} + std::vector const& key_order); template -static void grid_encode_utf(T const& grid_type, +void grid_encode_utf(T const& grid_type, boost::python::dict & json, bool add_features, - unsigned int resolution) -{ - // convert buffer to utf and gather key order - boost::python::list l; - std::vector key_order; - - if (resolution != 1) { - // resample on the fly - faster, less accurate - mapnik::grid2utf(grid_type,l,key_order,resolution); - - // resample first - slower, more accurate - //mapnik::grid2utf2(grid_type,l,key_order,resolution); - } - else - { - mapnik::grid2utf(grid_type,l,key_order); - } - - // convert key order to proper python list - boost::python::list keys_a; - BOOST_FOREACH ( typename T::lookup_type const& key_id, key_order ) - { - keys_a.append(key_id); - } - - // gather feature data - boost::python::dict feature_data; - if (add_features) { - mapnik::write_features(grid_type,feature_data,key_order); - } - - json["grid"] = l; - json["keys"] = keys_a; - json["data"] = feature_data; - -} + unsigned int resolution); template -static boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution) -{ - if (format == "utf") { - boost::python::dict json; - grid_encode_utf(grid,json,add_features,resolution); - return json; - } - else - { - std::stringstream s; - s << "'utf' is currently the only supported encoding format."; - throw mapnik::value_error(s.str()); - } -} +boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution); /* new approach: key comes from grid object * grid size should be same as the map * encoding, resizing handled as method on grid object * whether features are dumped is determined by argument not 'fields' */ -static void render_layer_for_grid(const mapnik::Map& map, +void render_layer_for_grid(const mapnik::Map& map, mapnik::grid& grid, unsigned layer_idx, // TODO - layer by name or index - boost::python::list const& fields) -{ - std::vector const& layers = map.layers(); - std::size_t layer_num = layers.size(); - if (layer_idx >= layer_num) { - std::ostringstream s; - s << "Zero-based layer index '" << layer_idx << "' not valid, only '" - << layer_num << "' layers are in map\n"; - throw std::runtime_error(s.str()); - } - - // convert python list to std::vector - boost::python::ssize_t num_fields = boost::python::len(fields); - for(boost::python::ssize_t i=0; i name(fields[i]); - if (name.check()) { - grid.add_property_name(name()); - } - else - { - std::stringstream s; - s << "list of field names must be strings"; - throw mapnik::value_error(s.str()); - } - } - - // copy property names - std::set attributes = grid.property_names(); - std::string const& key = grid.get_key(); - - // if key is special __id__ keyword - if (key == grid.key_name()) - { - // TODO - should feature.id() be a first class attribute? - - // if __id__ is requested to be dumped out - // remove it so that datasource queries will not break - if (attributes.find(key) != attributes.end()) - { - attributes.erase(key); - } - } - // if key is not the special __id__ keyword - else if (attributes.find(key) == attributes.end()) - { - // them make sure the datasource query includes this field - attributes.insert(key); - } - - mapnik::grid_renderer ren(map,grid,1.0,0,0); - mapnik::layer const& layer = layers[layer_idx]; - ren.apply(layer,attributes); -} + boost::python::list const& fields); /* old, original impl - to be removed after further testing * grid object is created on the fly at potentially reduced size */ -static boost::python::dict render_grid(const mapnik::Map& map, +boost::python::dict render_grid(const mapnik::Map& map, unsigned layer_idx, // layer std::string const& key, // key_name unsigned int step, // resolution - boost::python::list const& fields) -{ - - std::vector const& layers = map.layers(); - std::size_t layer_num = layers.size(); - if (layer_idx >= layer_num) { - std::ostringstream s; - s << "Zero-based layer index '" << layer_idx << "' not valid, only '" - << layer_num << "' layers are in map\n"; - throw std::runtime_error(s.str()); - } - - unsigned int grid_width = map.width()/step; - unsigned int grid_height = map.height()/step; - - // TODO - no need to pass step here - mapnik::grid grid(grid_width,grid_height,key,step); - - // convert python list to std::vector - boost::python::ssize_t num_fields = boost::python::len(fields); - for(boost::python::ssize_t i=0; i name(fields[i]); - if (name.check()) { - grid.add_property_name(name()); - } - else - { - std::stringstream s; - s << "list of field names must be strings"; - throw mapnik::value_error(s.str()); - } - } - - // copy property names - std::set attributes = grid.property_names(); - - // if key is special __id__ keyword - if (key == grid.key_name()) - { - // TODO - should feature.id() be a first class attribute? - - // if __id__ is requested to be dumped out - // remove it so that datasource queries will not break - if (attributes.find(key) != attributes.end()) - { - attributes.erase(key); - } - } - // if key is not the special __id__ keyword - else if (attributes.find(key) == attributes.end()) - { - // them make sure the datasource query includes this field - attributes.insert(key); - } - - try - { - mapnik::grid_renderer ren(map,grid,1.0,0,0); - mapnik::layer const& layer = layers[layer_idx]; - ren.apply(layer,attributes); - } - catch (...) - { - throw; - } - - bool add_features = false; - if (num_fields > 0) - add_features = true; - // build dictionary and return to python - boost::python::dict json; - grid_encode_utf(grid,json,add_features,1); - return json; -} - + boost::python::list const& fields); } #endif // MAPNIK_PYTHON_BINDING_GRID_UTILS_INCLUDED From 8f803b9897a57ed5a1e4e15076c424a729f04fab Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 16:15:27 -0700 Subject: [PATCH 05/66] reduce build time of xml_tree by half and memory usage by 1/3 - refs #1267 --- include/mapnik/expression_grammar.hpp | 142 +-------------------- include/mapnik/expression_node.hpp | 29 ++--- src/build.py | 2 + src/expression_grammar.cpp | 174 ++++++++++++++++++++++++++ src/expression_node.cpp | 52 ++++++++ 5 files changed, 240 insertions(+), 159 deletions(-) create mode 100644 src/expression_grammar.cpp create mode 100644 src/expression_node.cpp diff --git a/include/mapnik/expression_grammar.hpp b/include/mapnik/expression_grammar.hpp index 8f11aea55..0fe062923 100644 --- a/include/mapnik/expression_grammar.hpp +++ b/include/mapnik/expression_grammar.hpp @@ -86,14 +86,7 @@ struct regex_match_impl : tr_(tr) {} template - expr_node operator() (T0 & node, T1 const& pattern) const - { -#if defined(BOOST_REGEX_HAS_ICU) - return regex_match_node(node,tr_.transcode(pattern.c_str())); -#else - return regex_match_node(node,pattern); -#endif - } + expr_node operator() (T0 & node, T1 const& pattern) const; mapnik::transcoder const& tr_; }; @@ -110,14 +103,7 @@ struct regex_replace_impl : tr_(tr) {} template - expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const - { -#if defined(BOOST_REGEX_HAS_ICU) - return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str())); -#else - return regex_replace_node(node,pattern,format); -#endif - } + expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const; mapnik::transcoder const& tr_; }; @@ -139,134 +125,12 @@ struct expression_grammar : qi::grammar { typedef qi::rule rule_type; - explicit expression_grammar(mapnik::transcoder const& tr) - : expression_grammar::base_type(expr), - unicode_(unicode_impl(tr)), - regex_match_(regex_match_impl(tr)), - regex_replace_(regex_replace_impl(tr)) - { - using boost::phoenix::construct; - using qi::_1; - using qi::_a; - using qi::_b; - using qi::_r1; -#if BOOST_VERSION > 104200 - using qi::no_skip; -#endif - using qi::lexeme; - using qi::_val; - using qi::lit; - using qi::int_; - using qi::double_; - using qi::hex; - using qi::omit; - using standard_wide::char_; - using standard_wide::no_case; - expr = logical_expr.alias(); - - logical_expr = not_expr [_val = _1] - >> - *( ( ( lit("and") | lit("&&")) >> not_expr [_val && _1] ) - | (( lit("or") | lit("||")) >> not_expr [_val || _1]) - ) - ; - - not_expr = - cond_expr [_val = _1 ] - | ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ]) - ; - - cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1] - ; - - equality_expr = - relational_expr [_val = _1] - >> *( ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1]) - | (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1]) - ) - ; - - regex_match_expr = lit(".match") - >> lit('(') - >> ustring [_val = _1] - >> lit(')') - ; - - regex_replace_expr = - lit(".replace") - >> lit('(') - >> ustring [_a = _1] - >> lit(',') - >> ustring [_b = _1] - >> lit(')') [_val = regex_replace_(_r1,_a,_b)] - ; - - relational_expr = additive_expr[_val = _1] - >> - *( ( (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ]) - | ( (lit('<') | lit("lt") ) >> additive_expr [ _val < _1 ]) - | ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ]) - | ( (lit('>') | lit("gt") ) >> additive_expr [ _val > _1 ]) - ) - ; - - additive_expr = multiplicative_expr [_val = _1] - >> * ( '+' >> multiplicative_expr[_val += _1] - | '-' >> multiplicative_expr[_val -= _1] - ) - ; - - multiplicative_expr = unary_expr [_val = _1] - >> *( '*' >> unary_expr [_val *= _1] - | '/' >> unary_expr [_val /= _1] - | '%' >> unary_expr [_val %= _1] - | regex_match_expr[_val = regex_match_(_val, _1)] - | regex_replace_expr(_val) [_val = _1] - ) - ; - - unary_expr = primary_expr [_val = _1] - | '+' >> primary_expr [_val = _1] - | '-' >> primary_expr [_val = -_1] - ; - - primary_expr = strict_double [_val = _1] - | int_ [_val = _1] - | no_case[lit("true")] [_val = true] - | no_case[lit("false")] [_val = false] - | no_case[lit("null")] [_val = value_null() ] - | no_case[geom_type][_val = _1 ] - | ustring [_val = unicode_(_1) ] - | lit("[mapnik::geometry_type]")[_val = construct()] - | attr [_val = construct( _1 ) ] - | '(' >> expr [_val = _1 ] >> ')' - ; - - unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n') - ("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\') - ("\\\'", '\'')("\\\"", '\"') - ; - -#if BOOST_VERSION > 104500 - quote_char %= char_('\'') | char_('"'); - ustring %= omit[quote_char[_a = _1]] - >> *(unesc_char | "\\x" >> hex | (char_ - lit(_a))) - >> lit(_a); - attr %= '[' >> no_skip[+~char_(']')] >> ']'; -#else - ustring %= lit('\'') - >> *(unesc_char | "\\x" >> hex | (char_ - lit('\''))) - >> lit('\''); - attr %= '[' >> lexeme[+(char_ - ']')] >> ']'; -#endif - - } + explicit expression_grammar(mapnik::transcoder const& tr); qi::real_parser > strict_double; boost::phoenix::function unicode_; boost::phoenix::function regex_match_; boost::phoenix::function regex_replace_; - // rule_type expr; rule_type equality_expr; rule_type cond_expr; diff --git a/include/mapnik/expression_node.hpp b/include/mapnik/expression_node.hpp index da5f7e2d9..56b70a9ef 100644 --- a/include/mapnik/expression_node.hpp +++ b/include/mapnik/expression_node.hpp @@ -28,12 +28,12 @@ #include // boost -#include -#include #include #if defined(BOOST_REGEX_HAS_ICU) #include #endif +#include +#include #include namespace mapnik @@ -240,12 +240,10 @@ struct binary_node }; #if defined(BOOST_REGEX_HAS_ICU) + struct regex_match_node { - regex_match_node (expr_node const& a, UnicodeString const& ustr) - : expr(a), - pattern(boost::make_u32regex(ustr)) {} - + regex_match_node (expr_node const& a, UnicodeString const& ustr); expr_node expr; boost::u32regex pattern; }; @@ -253,22 +251,17 @@ struct regex_match_node struct regex_replace_node { - regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f) - : expr(a), - pattern(boost::make_u32regex(ustr)), - format(f) {} - + regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f); expr_node expr; boost::u32regex pattern; UnicodeString format; }; + #else + struct regex_match_node { - regex_match_node (expr_node const& a, std::string const& str) - : expr(a), - pattern(str) {} - + regex_match_node (expr_node const& a, std::string const& str); expr_node expr; boost::regex pattern; }; @@ -276,11 +269,7 @@ struct regex_match_node struct regex_replace_node { - regex_replace_node (expr_node const& a, std::string const& str, std::string const& f) - : expr(a), - pattern(str), - format(f) {} - + regex_replace_node (expr_node const& a, std::string const& str, std::string const& f); expr_node expr; boost::regex pattern; std::string format; diff --git a/src/build.py b/src/build.py index c8514b273..a89db439a 100644 --- a/src/build.py +++ b/src/build.py @@ -109,6 +109,8 @@ source = Split( datasource_cache.cpp debug.cpp deepcopy.cpp + expression_node.cpp + expression_grammar.cpp expression_string.cpp expression.cpp transform_expression.cpp diff --git a/src/expression_grammar.cpp b/src/expression_grammar.cpp new file mode 100644 index 000000000..fcc2575f8 --- /dev/null +++ b/src/expression_grammar.cpp @@ -0,0 +1,174 @@ +/***************************************************************************** + * + * 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 +{ + +template +expr_node regex_match_impl::operator() (T0 & node, T1 const& pattern) const +{ +#if defined(BOOST_REGEX_HAS_ICU) + return regex_match_node(node,tr_.transcode(pattern.c_str())); +#else + return regex_match_node(node,pattern); +#endif +} + +template +expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const& format) const +{ +#if defined(BOOST_REGEX_HAS_ICU) + return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str())); +#else + return regex_replace_node(node,pattern,format); +#endif +} + +template +expression_grammar::expression_grammar(mapnik::transcoder const& tr) + : expression_grammar::base_type(expr), + unicode_(unicode_impl(tr)), + regex_match_(regex_match_impl(tr)), + regex_replace_(regex_replace_impl(tr)) +{ + using boost::phoenix::construct; + using qi::_1; + using qi::_a; + using qi::_b; + using qi::_r1; +#if BOOST_VERSION > 104200 + using qi::no_skip; +#endif + using qi::lexeme; + using qi::_val; + using qi::lit; + using qi::int_; + using qi::double_; + using qi::hex; + using qi::omit; + using standard_wide::char_; + using standard_wide::no_case; + expr = logical_expr.alias(); + + logical_expr = not_expr [_val = _1] + >> + *( ( ( lit("and") | lit("&&")) >> not_expr [_val && _1] ) + | (( lit("or") | lit("||")) >> not_expr [_val || _1]) + ) + ; + + not_expr = + cond_expr [_val = _1 ] + | ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ]) + ; + + cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1] + ; + + equality_expr = + relational_expr [_val = _1] + >> *( ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1]) + | (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1]) + ) + ; + + regex_match_expr = lit(".match") + >> lit('(') + >> ustring [_val = _1] + >> lit(')') + ; + + regex_replace_expr = + lit(".replace") + >> lit('(') + >> ustring [_a = _1] + >> lit(',') + >> ustring [_b = _1] + >> lit(')') [_val = regex_replace_(_r1,_a,_b)] + ; + + relational_expr = additive_expr[_val = _1] + >> + *( ( (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ]) + | ( (lit('<') | lit("lt") ) >> additive_expr [ _val < _1 ]) + | ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ]) + | ( (lit('>') | lit("gt") ) >> additive_expr [ _val > _1 ]) + ) + ; + + additive_expr = multiplicative_expr [_val = _1] + >> * ( '+' >> multiplicative_expr[_val += _1] + | '-' >> multiplicative_expr[_val -= _1] + ) + ; + + multiplicative_expr = unary_expr [_val = _1] + >> *( '*' >> unary_expr [_val *= _1] + | '/' >> unary_expr [_val /= _1] + | '%' >> unary_expr [_val %= _1] + | regex_match_expr[_val = regex_match_(_val, _1)] + | regex_replace_expr(_val) [_val = _1] + ) + ; + + unary_expr = primary_expr [_val = _1] + | '+' >> primary_expr [_val = _1] + | '-' >> primary_expr [_val = -_1] + ; + + primary_expr = strict_double [_val = _1] + | int_ [_val = _1] + | no_case[lit("true")] [_val = true] + | no_case[lit("false")] [_val = false] + | no_case[lit("null")] [_val = value_null() ] + | no_case[geom_type][_val = _1 ] + | ustring [_val = unicode_(_1) ] + | lit("[mapnik::geometry_type]")[_val = construct()] + | attr [_val = construct( _1 ) ] + | '(' >> expr [_val = _1 ] >> ')' + ; + + unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n') + ("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\') + ("\\\'", '\'')("\\\"", '\"') + ; + +#if BOOST_VERSION > 104500 + quote_char %= char_('\'') | char_('"'); + ustring %= omit[quote_char[_a = _1]] + >> *(unesc_char | "\\x" >> hex | (char_ - lit(_a))) + >> lit(_a); + attr %= '[' >> no_skip[+~char_(']')] >> ']'; +#else + ustring %= lit('\'') + >> *(unesc_char | "\\x" >> hex | (char_ - lit('\''))) + >> lit('\''); + attr %= '[' >> lexeme[+(char_ - ']')] >> ']'; +#endif + +} + +template struct mapnik::expression_grammar; + +} \ No newline at end of file diff --git a/src/expression_node.cpp b/src/expression_node.cpp new file mode 100644 index 000000000..5c997044d --- /dev/null +++ b/src/expression_node.cpp @@ -0,0 +1,52 @@ +/***************************************************************************** + * + * 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 +{ + +#if defined(BOOST_REGEX_HAS_ICU) + +regex_match_node::regex_match_node (expr_node const& a, UnicodeString const& ustr) + : expr(a), + pattern(boost::make_u32regex(ustr)) {} + +regex_replace_node::regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f) + : expr(a), + pattern(boost::make_u32regex(ustr)), + format(f) {} + +#else +regex_match_node::pattern boost::regex; + +regex_match_node::regex_match_node (expr_node const& a, std::string const& str) + : expr(a), + pattern(str) {} + +regex_replace_node::regex_replace_node (expr_node const& a, std::string const& str, std::string const& f) + : expr(a), + pattern(str), + format(f) {} +#endif + +} \ No newline at end of file From 348dfff0c7cefd92ba5893583165ff6500eeb9c7 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 17:03:06 -0700 Subject: [PATCH 06/66] move feature_grammar to cpp file reducing compile time mem usage for feature_collection_parser.cpp - refs #1267 --- include/mapnik/json/feature_grammar.hpp | 192 +------------------- src/build.py | 1 + src/json/feature_grammar.cpp | 227 ++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 190 deletions(-) create mode 100644 src/json/feature_grammar.cpp diff --git a/include/mapnik/json/feature_grammar.hpp b/include/mapnik/json/feature_grammar.hpp index b756daead..b56a991b7 100644 --- a/include/mapnik/json/feature_grammar.hpp +++ b/include/mapnik/json/feature_grammar.hpp @@ -25,6 +25,7 @@ // mapnik #include +#include // spirit::qi #include @@ -135,196 +136,7 @@ struct feature_grammar : qi::grammar { - feature_grammar(mapnik::transcoder const& tr) - : feature_grammar::base_type(feature,"feature"), - put_property_(put_property(tr)) - { - using qi::lit; - using qi::int_; - using qi::double_; -#if BOOST_VERSION > 104200 - using qi::no_skip; -#else - using qi::lexeme; -#endif - using standard_wide::char_; - using qi::_val; - using qi::_1; - using qi::_2; - using qi::_3; - using qi::_4; - using qi::_a; - using qi::_b; - using qi::_r1; - using qi::_r2; - using qi::fail; - using qi::on_error; - using qi::_pass; - using qi::eps; - using qi::raw; - - using phoenix::new_; - using phoenix::push_back; - using phoenix::construct; - - // generic json types - value = object | array | string_ - | number - ; - - pairs = key_value % lit(',') - ; - - key_value = (string_ >> lit(':') >> value) - ; - - object = lit('{') - >> *pairs - >> lit('}') - ; - array = lit('[') - >> value >> *(lit(',') >> value) - >> lit(']') - ; - - number %= strict_double - | int_ - | lit("true") [_val = true] - | lit ("false") [_val = false] - | lit("null")[_val = construct()] - ; - - unesc_char.add - ("\\\"", '\"') // quotation mark - ("\\\\", '\\') // reverse solidus - ("\\/", '/') // solidus - ("\\b", '\b') // backspace - ("\\f", '\f') // formfeed - ("\\n", '\n') // newline - ("\\r", '\r') // carrige return - ("\\t", '\t') // tab - ; - - string_ %= lit('"') >> *(unesc_char | "\\u" >> hex4 | (char_ - lit('"'))) >> lit('"') - ; - - // geojson types - - feature_type = lit("\"type\"") - >> lit(':') - >> lit("\"Feature\"") - ; - - feature = lit('{') - >> (feature_type | (lit("\"geometry\"") > lit(':') > geometry(_r1)) | properties(_r1) | key_value) % lit(',') - >> lit('}') - ; - - properties = lit("\"properties\"") - >> lit(':') >> (lit('{') >> attributes(_r1) >> lit('}')) | lit("null") - ; - - attributes = (string_ [_a = _1] >> lit(':') >> attribute_value [put_property_(_r1,_a,_1)]) % lit(',') - ; - - attribute_value %= number | string_ ; - - // Nabialek trick - FIXME: how to bind argument to dispatch rule? - // geometry = lit("\"geometry\"") - // >> lit(':') >> lit('{') - // >> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1] - // >> lit(',') >> lit("\"coordinates\"") >> lit(':') - // >> qi::lazy(*_a) - // >> lit('}') - // ; - // geometry_dispatch.add - // ("\"Point\"",&point_coordinates) - // ("\"LineString\"",&linestring_coordinates) - // ("\"Polygon\"",&polygon_coordinates) - // ; - ////////////////////////////////////////////////////////////////// - - geometry = (lit('{')[_a = 0 ] - >> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1] // <---- should be Nabialek trick! - >> lit(',') - >> (lit("\"coordinates\"") > lit(':') > coordinates(_r1,_a) - | - lit("\"geometries\"") > lit(':') - >> lit('[') >> geometry_collection(_r1) >> lit(']')) - >> lit('}')) - | lit("null") - ; - - geometry_dispatch.add - ("\"Point\"",1) - ("\"LineString\"",2) - ("\"Polygon\"",3) - ("\"MultiPoint\"",4) - ("\"MultiLineString\"",5) - ("\"MultiPolygon\"",6) - ("\"GeometryCollection\"",7) - // - ; - - coordinates = (eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1))) - | (eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1))) - | (eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1))) - | (eps(_r2 == 4) > multipoint_coordinates(extract_geometry_(_r1))) - | (eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1))) - | (eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1))) - ; - - point_coordinates = eps[ _a = new_(Point) ] - > ( point(SEG_MOVETO,_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false] ) - ; - - linestring_coordinates = eps[ _a = new_(LineString)] - > -(points(_a) [push_back(_r1,_a)] - | eps[cleanup_(_a)][_pass = false]) - ; - - polygon_coordinates = eps[ _a = new_(Polygon) ] - > ((lit('[') - > -(points(_a) % lit(',')) - > lit(']')) [push_back(_r1,_a)] - | eps[cleanup_(_a)][_pass = false]) - ; - - multipoint_coordinates = lit('[') - > -(point_coordinates(_r1) % lit(',')) - > lit(']') - ; - - multilinestring_coordinates = lit('[') - > -(linestring_coordinates(_r1) % lit(',')) - > lit(']') - ; - - multipolygon_coordinates = lit('[') - > -(polygon_coordinates(_r1) % lit(',')) - > lit(']') - ; - - geometry_collection = *geometry(_r1) >> *(lit(',') >> geometry(_r1)) - ; - - // point - point = lit('[') > -((double_ > lit(',') > double_)[push_vertex_(_r1,_r2,_1,_2)]) > lit(']'); - // points - points = lit('[')[_a = SEG_MOVETO] > -(point (_a,_r1) % lit(',')[_a = SEG_LINETO]) > lit(']'); - on_error - ( - feature - , std::clog - << phoenix::val("Error! Expecting ") - << _4 // what failed? - << phoenix::val(" here: \"") - << construct(_3, _2) // iterators to error-pos, end - << phoenix::val("\"") - << std::endl - ); - - } + feature_grammar(mapnik::transcoder const& tr); // start // generic JSON diff --git a/src/build.py b/src/build.py index a89db439a..2884f6c52 100644 --- a/src/build.py +++ b/src/build.py @@ -165,6 +165,7 @@ source = Split( svg_points_parser.cpp svg_transform_parser.cpp warp.cpp + json/feature_grammar.cpp json/feature_collection_parser.cpp json/geojson_generator.cpp markers_placement.cpp diff --git a/src/json/feature_grammar.cpp b/src/json/feature_grammar.cpp new file mode 100644 index 000000000..59be9386e --- /dev/null +++ b/src/json/feature_grammar.cpp @@ -0,0 +1,227 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2012 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include + +// boost +#include + +namespace mapnik { namespace json { + +template +feature_grammar::feature_grammar(mapnik::transcoder const& tr) + : feature_grammar::base_type(feature,"feature"), + put_property_(put_property(tr)) +{ + using qi::lit; + using qi::int_; + using qi::double_; +#if BOOST_VERSION > 104200 + using qi::no_skip; +#else + using qi::lexeme; +#endif + using standard_wide::char_; + using qi::_val; + using qi::_1; + using qi::_2; + using qi::_3; + using qi::_4; + using qi::_a; + using qi::_b; + using qi::_r1; + using qi::_r2; + using qi::fail; + using qi::on_error; + using qi::_pass; + using qi::eps; + using qi::raw; + + using phoenix::new_; + using phoenix::push_back; + using phoenix::construct; + + // generic json types + value = object | array | string_ + | number + ; + + pairs = key_value % lit(',') + ; + + key_value = (string_ >> lit(':') >> value) + ; + + object = lit('{') + >> *pairs + >> lit('}') + ; + array = lit('[') + >> value >> *(lit(',') >> value) + >> lit(']') + ; + + number %= strict_double + | int_ + | lit("true") [_val = true] + | lit ("false") [_val = false] + | lit("null")[_val = construct()] + ; + + unesc_char.add + ("\\\"", '\"') // quotation mark + ("\\\\", '\\') // reverse solidus + ("\\/", '/') // solidus + ("\\b", '\b') // backspace + ("\\f", '\f') // formfeed + ("\\n", '\n') // newline + ("\\r", '\r') // carrige return + ("\\t", '\t') // tab + ; + + string_ %= lit('"') >> *(unesc_char | "\\u" >> hex4 | (char_ - lit('"'))) >> lit('"') + ; + + // geojson types + + feature_type = lit("\"type\"") + >> lit(':') + >> lit("\"Feature\"") + ; + + feature = lit('{') + >> (feature_type | (lit("\"geometry\"") > lit(':') > geometry(_r1)) | properties(_r1) | key_value) % lit(',') + >> lit('}') + ; + + properties = lit("\"properties\"") + >> lit(':') >> (lit('{') >> attributes(_r1) >> lit('}')) | lit("null") + ; + + attributes = (string_ [_a = _1] >> lit(':') >> attribute_value [put_property_(_r1,_a,_1)]) % lit(',') + ; + + attribute_value %= number | string_ ; + + // Nabialek trick - FIXME: how to bind argument to dispatch rule? + // geometry = lit("\"geometry\"") + // >> lit(':') >> lit('{') + // >> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1] + // >> lit(',') >> lit("\"coordinates\"") >> lit(':') + // >> qi::lazy(*_a) + // >> lit('}') + // ; + // geometry_dispatch.add + // ("\"Point\"",&point_coordinates) + // ("\"LineString\"",&linestring_coordinates) + // ("\"Polygon\"",&polygon_coordinates) + // ; + ////////////////////////////////////////////////////////////////// + + geometry = (lit('{')[_a = 0 ] + >> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1] // <---- should be Nabialek trick! + >> lit(',') + >> (lit("\"coordinates\"") > lit(':') > coordinates(_r1,_a) + | + lit("\"geometries\"") > lit(':') + >> lit('[') >> geometry_collection(_r1) >> lit(']')) + >> lit('}')) + | lit("null") + ; + + geometry_dispatch.add + ("\"Point\"",1) + ("\"LineString\"",2) + ("\"Polygon\"",3) + ("\"MultiPoint\"",4) + ("\"MultiLineString\"",5) + ("\"MultiPolygon\"",6) + ("\"GeometryCollection\"",7) + // + ; + + coordinates = (eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 4) > multipoint_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1))) + | (eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1))) + ; + + point_coordinates = eps[ _a = new_(Point) ] + > ( point(SEG_MOVETO,_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false] ) + ; + + linestring_coordinates = eps[ _a = new_(LineString)] + > -(points(_a) [push_back(_r1,_a)] + | eps[cleanup_(_a)][_pass = false]) + ; + + polygon_coordinates = eps[ _a = new_(Polygon) ] + > ((lit('[') + > -(points(_a) % lit(',')) + > lit(']')) [push_back(_r1,_a)] + | eps[cleanup_(_a)][_pass = false]) + ; + + multipoint_coordinates = lit('[') + > -(point_coordinates(_r1) % lit(',')) + > lit(']') + ; + + multilinestring_coordinates = lit('[') + > -(linestring_coordinates(_r1) % lit(',')) + > lit(']') + ; + + multipolygon_coordinates = lit('[') + > -(polygon_coordinates(_r1) % lit(',')) + > lit(']') + ; + + geometry_collection = *geometry(_r1) >> *(lit(',') >> geometry(_r1)) + ; + + // point + point = lit('[') > -((double_ > lit(',') > double_)[push_vertex_(_r1,_r2,_1,_2)]) > lit(']'); + // points + points = lit('[')[_a = SEG_MOVETO] > -(point (_a,_r1) % lit(',')[_a = SEG_LINETO]) > lit(']'); + on_error + ( + feature + , std::clog + << phoenix::val("Error! Expecting ") + << _4 // what failed? + << phoenix::val(" here: \"") + << construct(_3, _2) // iterators to error-pos, end + << phoenix::val("\"") + << std::endl + ); + +} + +template struct mapnik::json::feature_grammar; +template struct mapnik::json::feature_grammar >,mapnik::Feature>; + +}} \ No newline at end of file From a1d6579da2acfa20c10e597f81061f53fc2d801f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 17:21:29 -0700 Subject: [PATCH 07/66] silence a few compiler warnings --- plugins/input/osm/basiccurl.cpp | 6 ++++-- plugins/input/postgis/postgis_featureset.cpp | 2 +- plugins/input/postgis/postgis_featureset.hpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/input/osm/basiccurl.cpp b/plugins/input/osm/basiccurl.cpp index ef8c32f4e..021eacfff 100755 --- a/plugins/input/osm/basiccurl.cpp +++ b/plugins/input/osm/basiccurl.cpp @@ -39,7 +39,6 @@ CURL_LOAD_DATA* grab_http_response(const char* url) CURL_LOAD_DATA* do_grab(CURL* curl,const char* url) { - CURLcode res; CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)malloc(sizeof(CURL_LOAD_DATA)); data->data = NULL; data->nbytes = 0; @@ -48,7 +47,10 @@ CURL_LOAD_DATA* do_grab(CURL* curl,const char* url) curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, data); - res = curl_easy_perform(curl); + CURLcode res = curl_easy_perform(curl); + if (res !=0) { + std::clog << "error grabbing data\n"; + } return data; } diff --git a/plugins/input/postgis/postgis_featureset.cpp b/plugins/input/postgis/postgis_featureset.cpp index 5ac6e85f4..dd121a36d 100644 --- a/plugins/input/postgis/postgis_featureset.cpp +++ b/plugins/input/postgis/postgis_featureset.cpp @@ -112,7 +112,7 @@ feature_ptr postgis_featureset::next() totalGeomSize_ += size; - int num_attrs = ctx_->size() + 1; + unsigned num_attrs = ctx_->size() + 1; for (; pos < num_attrs; ++pos) { std::string name = rs_->getFieldName(pos); diff --git a/plugins/input/postgis/postgis_featureset.hpp b/plugins/input/postgis/postgis_featureset.hpp index 80c011c83..013a7de0f 100644 --- a/plugins/input/postgis/postgis_featureset.hpp +++ b/plugins/input/postgis/postgis_featureset.hpp @@ -55,7 +55,7 @@ private: boost::shared_ptr rs_; context_ptr ctx_; boost::scoped_ptr tr_; - int totalGeomSize_; + unsigned totalGeomSize_; int feature_id_; bool key_field_; }; From 5c20a9f72a546d3e091f020fbaf9212dda6dfb8c Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 17:29:10 -0700 Subject: [PATCH 08/66] suppress unused variable compiler warnings with gcc --- include/mapnik/geom_util.hpp | 38 ++++++++++++++++--------- include/mapnik/image_filter_types.hpp | 3 -- include/mapnik/util/geometry_to_wkb.hpp | 9 ++++-- plugins/input/osm/basiccurl.cpp | 2 ++ 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index 808b34b0f..427f36883 100644 --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.hpp @@ -39,7 +39,7 @@ namespace mapnik template bool clip_test(T p,T q,double& tmin,double& tmax) { - double r; + double r(0); bool result=true; if (p<0.0) { @@ -96,7 +96,8 @@ inline bool point_inside_path(double x,double y,Iter start,Iter end) double x0=boost::get<0>(*start); double y0=boost::get<1>(*start); - double x1,y1; + double x1(0); + double y1(0); while (++start!=end) { if ( boost::get<2>(*start) == SEG_MOVETO) @@ -173,7 +174,8 @@ inline bool point_on_path(double x,double y,Iter start,Iter end, double tol) { double x0=boost::get<0>(*start); double y0=boost::get<1>(*start); - double x1,y1; + double x1(0); + double y1(0); while (++start != end) { if ( boost::get<2>(*start) == SEG_MOVETO) @@ -222,7 +224,10 @@ struct filter_at_point template double path_length(PathType & path) { - double x0,y0,x1,y1; + double x0(0); + double y0(0); + double x1(0); + double y1(0); path.rewind(0); unsigned command = path.vertex(&x0,&y0); if (command == SEG_END) return 0; @@ -239,7 +244,10 @@ double path_length(PathType & path) template bool middle_point(PathType & path, double & x, double & y) { - double x0,y0,x1,y1; + double x0(0); + double y0(0); + double x1(0); + double y1(0); double mid_length = 0.5 * path_length(path); path.rewind(0); unsigned command = path.vertex(&x0,&y0); @@ -268,10 +276,10 @@ namespace label { template bool centroid(PathType & path, double & x, double & y) { - double x0; - double y0; - double x1; - double y1; + double x0(0); + double y0(0); + double x1(0); + double y1(0); double start_x; double start_y; @@ -318,7 +326,10 @@ template bool hit_test(PathType & path, double x, double y, double tol) { bool inside=false; - double x0, y0, x1, y1; + double x0(0); + double y0(0); + double x1(0); + double y1(0); path.rewind(0); unsigned command = path.vertex(&x0, &y0); if (command == SEG_END) return false; @@ -363,11 +374,12 @@ void interior_position(PathType & path, double & x, double & y) std::vector intersections; // only need to store the X as we know the y - double x0; - double y0; + double x0(0); + double y0(0); path.rewind(0); unsigned command = path.vertex(&x0, &y0); - double x1,y1; + double x1(0); + double y1(0); while (SEG_END != (command = path.vertex(&x1, &y1))) { if (command != SEG_MOVETO) diff --git a/include/mapnik/image_filter_types.hpp b/include/mapnik/image_filter_types.hpp index 6f00e1e28..bb19f5392 100644 --- a/include/mapnik/image_filter_types.hpp +++ b/include/mapnik/image_filter_types.hpp @@ -46,9 +46,6 @@ struct agg_stack_blur { agg_stack_blur(unsigned rx_, unsigned ry_) : rx(rx_),ry(ry_) {} - // an attempt to support older boost spirit (< 1.46) - agg_stack_blur() - : rx(1),ry(1) {} unsigned rx; unsigned ry; }; diff --git a/include/mapnik/util/geometry_to_wkb.hpp b/include/mapnik/util/geometry_to_wkb.hpp index 1252479dc..3b0159345 100644 --- a/include/mapnik/util/geometry_to_wkb.hpp +++ b/include/mapnik/util/geometry_to_wkb.hpp @@ -126,7 +126,8 @@ namespace mapnik { namespace util { ss.write(reinterpret_cast(&byte_order),1); int type = static_cast(mapnik::Point); write(ss,type,4,byte_order); - double x,y; + double x(0); + double y(0); g.vertex(0,&x,&y); write(ss,x,8,byte_order); write(ss,y,8,byte_order); @@ -145,7 +146,8 @@ namespace mapnik { namespace util { int type = static_cast(mapnik::LineString); write(ss,type,4,byte_order); write(ss,num_points,4,byte_order); - double x,y; + double x(0); + double y(0); for (unsigned i=0; i< num_points; ++i) { g.vertex(i,&x,&y); @@ -165,7 +167,8 @@ namespace mapnik { namespace util { typedef std::vector linear_ring; boost::ptr_vector rings; - double x,y; + double x(0); + double y(0); std::size_t size = 1 + 4 + 4 ; // byteOrder + wkbType + numRings for (unsigned i=0; i< num_points; ++i) { diff --git a/plugins/input/osm/basiccurl.cpp b/plugins/input/osm/basiccurl.cpp index 021eacfff..600f2f30b 100755 --- a/plugins/input/osm/basiccurl.cpp +++ b/plugins/input/osm/basiccurl.cpp @@ -22,6 +22,8 @@ #include "basiccurl.h" +#include + CURL_LOAD_DATA* grab_http_response(const char* url) { CURL_LOAD_DATA* data; From 5014694591110f14f44ee2058b5b0d9379380f93 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 17:41:52 -0700 Subject: [PATCH 09/66] allow auto-opening of rendered svg on linux --- utils/svg2png/svg2png.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/utils/svg2png/svg2png.cpp b/utils/svg2png/svg2png.cpp index 63aa5725d..c06ba187f 100644 --- a/utils/svg2png/svg2png.cpp +++ b/utils/svg2png/svg2png.cpp @@ -182,14 +182,16 @@ int main (int argc,char** argv) boost::algorithm::ireplace_last(svg_name,".svg",".png"); mapnik::save_to_file(im.data(),svg_name,"png"); -#ifdef DARWIN if (auto_open) { std::ostringstream s; +#ifdef DARWIN s << "open " << svg_name; +#else + s << "xdg-open " << svg_name; +#endif system(s.str().c_str()); } -#endif std::clog << "rendered to: " << svg_name << "\n"; } } From 1b23838c583d0e0e9c24c72beb8927ae4251cbdd Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 17:43:21 -0700 Subject: [PATCH 10/66] avoid uninitialized compiler warning --- plugins/input/csv/csv_datasource.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index 0c2d276ed..b10729d3a 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -277,9 +277,9 @@ void csv_datasource::parse_csv(T& stream, bool has_wkt_field = false; bool has_lat_field = false; bool has_lon_field = false; - unsigned wkt_idx; - unsigned lat_idx; - unsigned lon_idx; + unsigned wkt_idx(0); + unsigned lat_idx(0); + unsigned lon_idx(0); if (!manual_headers_.empty()) { From 2ba016b08b8730f5f7d6808d851db4a8956fd626 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 17:52:26 -0700 Subject: [PATCH 11/66] make the svg2png return value sensitive to auto_open results --- utils/svg2png/svg2png.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/utils/svg2png/svg2png.cpp b/utils/svg2png/svg2png.cpp index c06ba187f..228387893 100644 --- a/utils/svg2png/svg2png.cpp +++ b/utils/svg2png/svg2png.cpp @@ -55,7 +55,7 @@ int main (int argc,char** argv) bool verbose = false; bool auto_open = false; - bool error = false; + int return_value = 0; std::vector svg_files; mapnik::logger logger; logger.set_severity(mapnik::logger::error); @@ -131,14 +131,14 @@ int main (int argc,char** argv) if (!marker_ptr) { std::clog << "svg2png error: could not open: '" << svg_name << "'\n"; - error = true; + return_value = -1; continue; } mapnik::marker marker = **marker_ptr; if (!marker.is_vector()) { std::clog << "svg2png error: '" << svg_name << "' is not a valid vector!\n"; - error = true; + return_value = -1; continue; } @@ -190,7 +190,9 @@ int main (int argc,char** argv) #else s << "xdg-open " << svg_name; #endif - system(s.str().c_str()); + int ret = system(s.str().c_str()); + if (ret != 0) + return_value = ret; } std::clog << "rendered to: " << svg_name << "\n"; } @@ -206,7 +208,5 @@ int main (int argc,char** argv) // to make sure valgrind output is clean // http://xmlsoft.org/xmlmem.html xmlCleanupParser(); - if (error) - return -1; - return 0; + return return_value; } From 29deca8db89cbc9d6d86c947907f209614393ebc Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 23 Jul 2012 18:12:10 -0700 Subject: [PATCH 12/66] shave off 4 seconds from xml_node.cpp compile time (16 -> 12) by moving transform grammar to cpp - refs #1267 --- .../mapnik/transform_expression_grammar.hpp | 60 +----------- src/build.py | 1 + src/transform_expression_grammar.cpp | 91 +++++++++++++++++++ 3 files changed, 93 insertions(+), 59 deletions(-) create mode 100644 src/transform_expression_grammar.cpp diff --git a/include/mapnik/transform_expression_grammar.hpp b/include/mapnik/transform_expression_grammar.hpp index fe09f4e5c..4d4afae9f 100644 --- a/include/mapnik/transform_expression_grammar.hpp +++ b/include/mapnik/transform_expression_grammar.hpp @@ -39,65 +39,7 @@ namespace mapnik { struct transform_expression_grammar : qi::grammar { - explicit transform_expression_grammar(expression_grammar const& g) - : transform_expression_grammar::base_type(start) - { - using boost::phoenix::construct; - using qi::_a; using qi::_1; using qi::_4; - using qi::_b; using qi::_2; using qi::_5; - using qi::_c; using qi::_3; using qi::_6; - using qi::_val; - using qi::char_; - using qi::lit; - using qi::no_case; - using qi::no_skip; - - start = transform_ % no_skip[char_(", ")] ; - - transform_ = matrix | translate | scale | rotate | skewX | skewY ; - - matrix = no_case[lit("matrix")] - >> (lit('(') - >> expr >> -lit(',') - >> expr >> -lit(',') - >> expr >> -lit(',') - >> expr >> -lit(',') - >> expr >> -lit(',') - >> expr >> lit(')')) - [ _val = construct(_1,_2,_3,_4,_5,_6) ]; - - translate = no_case[lit("translate")] - >> (lit('(') - >> expr >> -lit(',') - >> -expr >> lit(')')) - [ _val = construct(_1,_2) ]; - - scale = no_case[lit("scale")] - >> (lit('(') - >> expr >> -lit(',') - >> -expr >> lit(')')) - [ _val = construct(_1,_2) ]; - - rotate = no_case[lit("rotate")] - >> lit('(') - >> expr[_a = _1] >> -lit(',') - >> -(expr [_b = _1] >> -lit(',') >> expr[_c = _1]) - >> lit(')') - [ _val = construct(_a,_b,_c) ]; - - skewX = no_case[lit("skewX")] - >> lit('(') - >> expr [ _val = construct(_1) ] - >> lit(')'); - - skewY = no_case[lit("skewY")] - >> lit('(') - >> expr [ _val = construct(_1) ] - >> lit(')'); - - expr = g.expr.alias(); - } - + explicit transform_expression_grammar(expression_grammar const& g); typedef qi::locals, boost::optional > rotate_locals; diff --git a/src/build.py b/src/build.py index 2884f6c52..1ad71687b 100644 --- a/src/build.py +++ b/src/build.py @@ -113,6 +113,7 @@ source = Split( expression_grammar.cpp expression_string.cpp expression.cpp + transform_expression_grammar.cpp transform_expression.cpp feature_kv_iterator.cpp feature_type_style.cpp diff --git a/src/transform_expression_grammar.cpp b/src/transform_expression_grammar.cpp new file mode 100644 index 000000000..026c6c13e --- /dev/null +++ b/src/transform_expression_grammar.cpp @@ -0,0 +1,91 @@ +/***************************************************************************** + * + * 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 { + +namespace qi = boost::spirit::qi; + +template +transform_expression_grammar::transform_expression_grammar(expression_grammar const& g) + : transform_expression_grammar::base_type(start) +{ + using boost::phoenix::construct; + using qi::_a; using qi::_1; using qi::_4; + using qi::_b; using qi::_2; using qi::_5; + using qi::_c; using qi::_3; using qi::_6; + using qi::_val; + using qi::char_; + using qi::lit; + using qi::no_case; + using qi::no_skip; + + start = transform_ % no_skip[char_(", ")] ; + + transform_ = matrix | translate | scale | rotate | skewX | skewY ; + + matrix = no_case[lit("matrix")] + >> (lit('(') + >> expr >> -lit(',') + >> expr >> -lit(',') + >> expr >> -lit(',') + >> expr >> -lit(',') + >> expr >> -lit(',') + >> expr >> lit(')')) + [ _val = construct(_1,_2,_3,_4,_5,_6) ]; + + translate = no_case[lit("translate")] + >> (lit('(') + >> expr >> -lit(',') + >> -expr >> lit(')')) + [ _val = construct(_1,_2) ]; + + scale = no_case[lit("scale")] + >> (lit('(') + >> expr >> -lit(',') + >> -expr >> lit(')')) + [ _val = construct(_1,_2) ]; + + rotate = no_case[lit("rotate")] + >> lit('(') + >> expr[_a = _1] >> -lit(',') + >> -(expr [_b = _1] >> -lit(',') >> expr[_c = _1]) + >> lit(')') + [ _val = construct(_a,_b,_c) ]; + + skewX = no_case[lit("skewX")] + >> lit('(') + >> expr [ _val = construct(_1) ] + >> lit(')'); + + skewY = no_case[lit("skewY")] + >> lit('(') + >> expr [ _val = construct(_1) ] + >> lit(')'); + + expr = g.expr.alias(); +} + +template struct mapnik::transform_expression_grammar; + +} \ No newline at end of file From 8de27eaf6f525fb456ca92d1a5590f2da19cb974 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 24 Jul 2012 09:43:05 +0100 Subject: [PATCH 13/66] + use assignment op to initialize built-in types. --- include/mapnik/geom_util.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index 427f36883..c891320aa 100644 --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.hpp @@ -374,12 +374,12 @@ void interior_position(PathType & path, double & x, double & y) std::vector intersections; // only need to store the X as we know the y - double x0(0); - double y0(0); + double x0 = 0; + double y0 = 0; path.rewind(0); unsigned command = path.vertex(&x0, &y0); - double x1(0); - double y1(0); + double x1 = 0; + double y1 = 0; while (SEG_END != (command = path.vertex(&x1, &y1))) { if (command != SEG_MOVETO) From 553e767169166d92df3d626d7647e85c2ba8b1f5 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 24 Jul 2012 09:44:14 +0100 Subject: [PATCH 14/66] + remove const modifiers --- src/agg/process_point_symbolizer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/agg/process_point_symbolizer.cpp b/src/agg/process_point_symbolizer.cpp index d1de3f843..aac4355a2 100644 --- a/src/agg/process_point_symbolizer.cpp +++ b/src/agg/process_point_symbolizer.cpp @@ -65,14 +65,14 @@ void agg_renderer::process(point_symbolizer const& sym, if (marker) { box2d const& bbox = (*marker)->bounding_box(); - coord2d const center = bbox.center(); + coord2d center = bbox.center(); agg::trans_affine tr; evaluate_transform(tr, feature, sym.get_image_transform()); tr = agg::trans_affine_scaling(scale_factor_) * tr; - agg::trans_affine_translation const recenter(-center.x, -center.y); - agg::trans_affine const recenter_tr = recenter * tr; + agg::trans_affine_translation recenter(-center.x, -center.y); + agg::trans_affine recenter_tr = recenter * tr; box2d label_ext = bbox * recenter_tr; for (unsigned i=0; i Date: Tue, 24 Jul 2012 14:03:52 +0100 Subject: [PATCH 15/66] + formatting.. --- include/mapnik/marker.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/mapnik/marker.hpp b/include/mapnik/marker.hpp index d8b181ad7..d26819892 100644 --- a/include/mapnik/marker.hpp +++ b/include/mapnik/marker.hpp @@ -65,19 +65,21 @@ public: (*bitmap_data_)->set(0xff000000); } - marker(const boost::optional &data) : bitmap_data_(data) + marker(const boost::optional &data) + : bitmap_data_(data) { } - marker(const boost::optional &data) : vector_data_(data) + marker(const boost::optional &data) + : vector_data_(data) { } - marker(const marker& rhs) : bitmap_data_(rhs.bitmap_data_), vector_data_(rhs.vector_data_) - { - } + marker(const marker& rhs) + : bitmap_data_(rhs.bitmap_data_), vector_data_(rhs.vector_data_) + {} box2d bounding_box() const { From 5ac4d2ec93546029cec9779e0423e597fdc08f1b Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 24 Jul 2012 14:04:25 +0100 Subject: [PATCH 16/66] + add raster markers support --- src/agg/process_markers_symbolizer.cpp | 257 ++++++++++++++++++++----- 1 file changed, 207 insertions(+), 50 deletions(-) diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index ce1fc7310..11f90def7 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -45,14 +45,18 @@ #include "agg_path_storage.h" #include "agg_conv_clip_polyline.h" #include "agg_conv_transform.h" - +#include "agg_image_filters.h" +#include "agg_trans_bilinear.h" +#include "agg_span_allocator.h" +#include "agg_image_accessors.h" +#include "agg_span_image_filter_rgba.h" // boost #include namespace mapnik { template -struct markers_rasterizer_dispatch +struct vector_markers_rasterizer_dispatch { typedef agg::rgba8 color_type; typedef agg::order_rgba order_type; @@ -62,7 +66,7 @@ struct markers_rasterizer_dispatch typedef agg::renderer_base renderer_base; typedef agg::renderer_scanline_aa_solid renderer_type; - markers_rasterizer_dispatch(BufferType & image_buffer, + vector_markers_rasterizer_dispatch(BufferType & image_buffer, SvgRenderer & svg_renderer, Rasterizer & ras, box2d const& bbox, @@ -91,7 +95,6 @@ struct markers_rasterizer_dispatch if (placement_method == MARKER_POINT_PLACEMENT) { - double x,y; path.rewind(0); label::interior_position(path, x, y); @@ -124,7 +127,6 @@ struct markers_rasterizer_dispatch } } } - private: agg::scanline_u8 sl_; agg::rendering_buffer buf_; @@ -139,11 +141,61 @@ private: double scale_factor_; }; +template +void render_raster_marker(Rasterizer & ras, RendererBuffer & renb, agg::scanline_u8 & sl, + pixel_position const& pos, image_data_32 const& src, + agg::trans_affine const& tr,double opacity, + double scale_factor) +{ -template -void agg_renderer::process(markers_symbolizer const& sym, - mapnik::feature_impl & feature, - proj_transform const& prj_trans) + double width = src.width(); + double height = src.height(); + double p[8]; + p[0] = pos.x; p[1] = pos.y; + p[2] = pos.x + width; p[3] = pos.y; + p[4] = pos.x + width; p[5] = pos.y + height; + p[6] = pos.x; p[7] = pos.y + height; + + agg::trans_affine marker_tr; + + marker_tr *= agg::trans_affine_translation(-pos.x,-pos.y); + marker_tr *= tr; + marker_tr *= agg::trans_affine_scaling(scale_factor); + marker_tr *= agg::trans_affine_translation(pos.x,pos.y); + + marker_tr.transform(&p[0], &p[1]); + marker_tr.transform(&p[2], &p[3]); + marker_tr.transform(&p[4], &p[5]); + marker_tr.transform(&p[6], &p[7]); + + ras.move_to_d(p[0],p[1]); + ras.line_to_d(p[2],p[3]); + ras.line_to_d(p[4],p[5]); + ras.line_to_d(p[6],p[7]); + + typedef agg::rgba8 color_type; + agg::span_allocator sa; + agg::image_filter_bilinear filter_kernel; + agg::image_filter_lut filter(filter_kernel, false); + + agg::rendering_buffer marker_buf((unsigned char *)src.getBytes(), + src.width(), + src.height(), + src.width()*4); + agg::pixfmt_rgba32_pre pixf(marker_buf); + + typedef agg::image_accessor_clone img_accessor_type; + typedef agg::span_interpolator_linear interpolator_type; + typedef agg::span_image_filter_rgba_2x2 span_gen_type; + img_accessor_type ia(pixf); + interpolator_type interpolator(agg::trans_affine(p, 0, 0, width, height) ); + span_gen_type sg(ia, interpolator, filter); + agg::render_scanlines_aa(ras, sl, renb, sa, sg); +} + +template +struct raster_markers_rasterizer_dispatch { typedef agg::rgba8 color_type; typedef agg::order_rgba order_type; @@ -153,6 +205,96 @@ void agg_renderer::process(markers_symbolizer const& sym, typedef agg::renderer_base renderer_base; typedef agg::renderer_scanline_aa_solid renderer_type; + raster_markers_rasterizer_dispatch(BufferType & image_buffer, + Rasterizer & ras, + image_data_32 const& src, + agg::trans_affine const& marker_trans, + markers_symbolizer const& sym, + Detector & detector, + double scale_factor) + : buf_(image_buffer.raw_data(), image_buffer.width(), image_buffer.height(), image_buffer.width() * 4), + pixf_(buf_), + renb_(pixf_), + ras_(ras), + src_(src), + marker_trans_(marker_trans), + sym_(sym), + detector_(detector), + scale_factor_(scale_factor) + { + pixf_.comp_op(static_cast(sym_.comp_op())); + } + + template + void add_path(T & path) + { + marker_placement_e placement_method = sym_.get_marker_placement(); + box2d bbox_(0,0, src_.width(),src_.height()); + + if (placement_method == MARKER_POINT_PLACEMENT) + { + double x,y; + path.rewind(0); + label::interior_position(path, x, y); + agg::trans_affine matrix = marker_trans_; + matrix.translate(x,y); + box2d transformed_bbox = bbox_ * matrix; + + if (sym_.get_allow_overlap() || + detector_.has_placement(transformed_bbox)) + { + + render_raster_marker(ras_, renb_, sl_, pixel_position(x,y), src_, + marker_trans_, sym_.get_opacity(), scale_factor_); + if (!sym_.get_ignore_placement()) + detector_.insert(transformed_bbox); + } + } + else + { + markers_placement placement(path, bbox_, marker_trans_, detector_, + sym_.get_spacing() * scale_factor_, + sym_.get_max_error(), + sym_.get_allow_overlap()); + double x, y, angle; + while (placement.get_point(x, y, angle)) + { + agg::trans_affine matrix = marker_trans_; + matrix.rotate(angle); + render_raster_marker(ras_, renb_, sl_, pixel_position(x,y), src_, + matrix, sym_.get_opacity(), scale_factor_); + } + } + } +private: + agg::scanline_u8 sl_; + agg::rendering_buffer buf_; + pixfmt_comp_type pixf_; + renderer_base renb_; + Rasterizer & ras_; + image_data_32 const& src_; + agg::trans_affine const& marker_trans_; + markers_symbolizer const& sym_; + Detector & detector_; + double scale_factor_; +}; + + +template +void agg_renderer::process(markers_symbolizer const& sym, + feature_impl & feature, + proj_transform const& prj_trans) +{ + typedef agg::rgba8 color_type; + typedef agg::order_rgba order_type; + typedef agg::pixel32_type pixel_type; + typedef agg::comp_op_adaptor_rgba_pre blender_type; // comp blender + typedef agg::pixfmt_custom_blend_rgba pixfmt_comp_type; + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_type; + typedef label_collision_detector4 detector_type; + typedef boost::mpl::vector conv_types; + std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature); if (!filename.empty()) @@ -160,61 +302,76 @@ void agg_renderer::process(markers_symbolizer const& sym, boost::optional mark = mapnik::marker_cache::instance()->find(filename, true); if (mark && *mark) { - if (!(*mark)->is_vector()) - { - MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: markers_symbolizer does not yet support non-SVG markers"; - return; - } - ras_ptr->reset(); ras_ptr->gamma(agg::gamma_power()); agg::trans_affine geom_tr; evaluate_transform(geom_tr, feature, sym.get_transform()); - boost::optional marker = (*mark)->get_vector_data(); - box2d const& bbox = (*marker)->bounding_box(); - + box2d const& bbox = (*mark)->bounding_box(); agg::trans_affine tr; setup_label_transform(tr, bbox, feature, sym); tr = agg::trans_affine_scaling(scale_factor_) * tr; - coord2d center = bbox.center(); agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine marker_trans = recenter * tr; - using namespace mapnik::svg; - vertex_stl_adapter stl_storage((*marker)->source()); - svg_path_adapter svg_path(stl_storage); - - agg::pod_bvector attributes; - bool result = push_explicit_style( (*marker)->attributes(), attributes, sym); - - typedef label_collision_detector4 detector_type; - typedef svg_renderer, - renderer_type, - agg::pixfmt_rgba32 > svg_renderer_type; - typedef markers_rasterizer_dispatch markers_rasterizer_dispatch_type; - typedef boost::mpl::vector conv_types; - - svg_renderer_type svg_renderer(svg_path, result ? attributes : (*marker)->attributes()); - - markers_rasterizer_dispatch_type rasterizer_dispatch(*current_buffer_,svg_renderer,*ras_ptr, - bbox, marker_trans, sym, *detector_, scale_factor_); - - - vertex_converter, markers_rasterizer_dispatch_type, markers_symbolizer, - CoordTransform, proj_transform, agg::trans_affine, conv_types> - converter(query_extent_* 1.1,rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_); - - if (sym.clip()) converter.template set(); //optional clip (default: true) - converter.template set(); //always transform - if (sym.smooth() > 0.0) converter.template set(); // optional smooth converter - - BOOST_FOREACH(geometry_type & geom, feature.paths()) + if ((*mark)->is_vector()) { - converter.apply(geom); + using namespace mapnik::svg; + boost::optional marker = (*mark)->get_vector_data(); + + + vertex_stl_adapter stl_storage((*marker)->source()); + svg_path_adapter svg_path(stl_storage); + + agg::pod_bvector attributes; + bool result = push_explicit_style( (*marker)->attributes(), attributes, sym); + + typedef svg_renderer, + renderer_type, + agg::pixfmt_rgba32 > svg_renderer_type; + typedef vector_markers_rasterizer_dispatch dispatch_type; + + + svg_renderer_type svg_renderer(svg_path, result ? attributes : (*marker)->attributes()); + + dispatch_type rasterizer_dispatch(*current_buffer_,svg_renderer,*ras_ptr, + bbox, marker_trans, sym, *detector_, scale_factor_); + + + vertex_converter, dispatch_type, markers_symbolizer, + CoordTransform, proj_transform, agg::trans_affine, conv_types> + converter(query_extent_* 1.1,rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_); + + if (sym.clip()) converter.template set(); //optional clip (default: true) + converter.template set(); //always transform + if (sym.smooth() > 0.0) converter.template set(); // optional smooth converter + + BOOST_FOREACH(geometry_type & geom, feature.paths()) + { + converter.apply(geom); + } + } + else // raster markers + { + boost::optional marker = (*mark)->get_bitmap_data(); + typedef raster_markers_rasterizer_dispatch dispatch_type; + dispatch_type rasterizer_dispatch(*current_buffer_,*ras_ptr, **marker, + marker_trans, sym, *detector_, scale_factor_); + vertex_converter, dispatch_type, markers_symbolizer, + CoordTransform, proj_transform, agg::trans_affine, conv_types> + converter(query_extent_* 1.1, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_); + + if (sym.clip()) converter.template set(); //optional clip (default: true) + converter.template set(); //always transform + if (sym.smooth() > 0.0) converter.template set(); // optional smooth converter + + BOOST_FOREACH(geometry_type & geom, feature.paths()) + { + converter.apply(geom); + } } } } From 139b5e710fd912766262acd4b00b0bec9ed5c22a Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 24 Jul 2012 17:34:59 +0100 Subject: [PATCH 17/66] + centroid: return first vertex if num_vertices == 1 --- include/mapnik/geom_util.hpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index c891320aa..a8a058b5e 100644 --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.hpp @@ -276,10 +276,10 @@ namespace label { template bool centroid(PathType & path, double & x, double & y) { - double x0(0); - double y0(0); - double x1(0); - double y1(0); + double x0 = 0; + double y0 = 0; + double x1 = 0; + double y1 = 0; double start_x; double start_y; @@ -293,7 +293,7 @@ bool centroid(PathType & path, double & x, double & y) double atmp = 0; double xtmp = 0; double ytmp = 0; - + unsigned count = 1; while (SEG_END != (command = path.vertex(&x1, &y1))) { double dx0 = x0 - start_x; @@ -307,6 +307,14 @@ bool centroid(PathType & path, double & x, double & y) ytmp += (dy1 + dy0) * ai; x0 = x1; y0 = y1; + ++count; + } + + if (count == 1) + { + x = start_x; + y = start_y; + return true; } if (atmp != 0) From ec12d02209dc979594edd05fef26eebfde10a554 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 14:01:46 -0700 Subject: [PATCH 18/66] iterate image_filters by const& - refs #1330 --- src/agg/agg_renderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index bff971757..46f048063 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -239,7 +239,7 @@ void agg_renderer::end_style_processing(feature_type_style const& st) { blend_from = true; mapnik::filter::filter_visitor visitor(*current_buffer_); - BOOST_FOREACH(mapnik::filter::filter_type filter_tag, st.image_filters()) + BOOST_FOREACH(mapnik::filter::filter_type const& filter_tag, st.image_filters()) { boost::apply_visitor(visitor, filter_tag); } @@ -256,7 +256,7 @@ void agg_renderer::end_style_processing(feature_type_style const& st) // apply any 'direct' image filters mapnik::filter::filter_visitor visitor(pixmap_); - BOOST_FOREACH(mapnik::filter::filter_type filter_tag, st.direct_image_filters()) + BOOST_FOREACH(mapnik::filter::filter_type const& filter_tag, st.direct_image_filters()) { boost::apply_visitor(visitor, filter_tag); } From 25a7c6bc01b1d81aaccf1adaacd379b93963d965 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 14:20:57 -0700 Subject: [PATCH 19/66] + use assignment op to initialize built-in types. --- include/mapnik/geom_util.hpp | 34 +++++++++++++++---------------- include/mapnik/geometry.hpp | 4 ++-- include/mapnik/grid/grid_util.hpp | 13 +++++++----- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index a8a058b5e..31432aa33 100644 --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.hpp @@ -39,7 +39,7 @@ namespace mapnik template bool clip_test(T p,T q,double& tmin,double& tmax) { - double r(0); + double r = 0; bool result=true; if (p<0.0) { @@ -96,8 +96,8 @@ inline bool point_inside_path(double x,double y,Iter start,Iter end) double x0=boost::get<0>(*start); double y0=boost::get<1>(*start); - double x1(0); - double y1(0); + double x1 = 0; + double y1 = 0; while (++start!=end) { if ( boost::get<2>(*start) == SEG_MOVETO) @@ -174,8 +174,8 @@ inline bool point_on_path(double x,double y,Iter start,Iter end, double tol) { double x0=boost::get<0>(*start); double y0=boost::get<1>(*start); - double x1(0); - double y1(0); + double x1 = 0; + double y1 = 0; while (++start != end) { if ( boost::get<2>(*start) == SEG_MOVETO) @@ -224,10 +224,10 @@ struct filter_at_point template double path_length(PathType & path) { - double x0(0); - double y0(0); - double x1(0); - double y1(0); + double x0 = 0; + double y0 = 0; + double x1 = 0; + double y1 = 0; path.rewind(0); unsigned command = path.vertex(&x0,&y0); if (command == SEG_END) return 0; @@ -244,10 +244,10 @@ double path_length(PathType & path) template bool middle_point(PathType & path, double & x, double & y) { - double x0(0); - double y0(0); - double x1(0); - double y1(0); + double x0 = 0; + double y0 = 0; + double x1 = 0; + double y1 = 0; double mid_length = 0.5 * path_length(path); path.rewind(0); unsigned command = path.vertex(&x0,&y0); @@ -334,10 +334,10 @@ template bool hit_test(PathType & path, double x, double y, double tol) { bool inside=false; - double x0(0); - double y0(0); - double x1(0); - double y1(0); + double x0 = 0; + double y0 = 0; + double x1 = 0; + double y1 = 0; path.rewind(0); unsigned command = path.vertex(&x0, &y0); if (command == SEG_END) return false; diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 20356dc84..31bfeb337 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -88,8 +88,8 @@ public: box2d envelope() const { box2d result; - double x(0); - double y(0); + double x = 0; + double y = 0; rewind(0); for (unsigned i=0;i Date: Tue, 24 Jul 2012 14:24:24 -0700 Subject: [PATCH 20/66] svg2png: no need to scale the svg marker down --- utils/svg2png/svg2png.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/utils/svg2png/svg2png.cpp b/utils/svg2png/svg2png.cpp index 228387893..2c9113b08 100644 --- a/utils/svg2png/svg2png.cpp +++ b/utils/svg2png/svg2png.cpp @@ -149,7 +149,6 @@ int main (int argc,char** argv) agg::scanline_u8 sl; double opacity = 1; - double scale_factor_ = .95; int w = marker.width(); int h = marker.height(); if (verbose) @@ -165,8 +164,6 @@ int main (int argc,char** argv) mapnik::coord c = bbox.center(); // center the svg marker on '0,0' agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y); - // apply symbol transformation to get to map space - mtx *= agg::trans_affine_scaling(scale_factor_); // render the marker at the center of the marker box mtx.translate(0.5 * w, 0.5 * h); From 881ff0180ae5780e3fb0ecc81f0c491049a0353d Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 14:35:19 -0700 Subject: [PATCH 21/66] suppress gcc Wunused-but-set-variable warnings --- include/mapnik/grid/grid_util.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/mapnik/grid/grid_util.hpp b/include/mapnik/grid/grid_util.hpp index f681debb7..b1b61c661 100644 --- a/include/mapnik/grid/grid_util.hpp +++ b/include/mapnik/grid/grid_util.hpp @@ -26,6 +26,9 @@ // mapnik #include +// boost +#include + namespace mapnik { /* @@ -57,6 +60,8 @@ static inline void scale_grid(mapnik::grid::data_type & target, unsigned yprt1 = 0; unsigned xprt = 0; unsigned xprt1 = 0; + boost::ignore_unused_variable_warning(yprt1); + boost::ignore_unused_variable_warning(xprt1); //no scaling or subpixel offset if (target_height == source_height && target_width == source_width && offs_x == 0 && offs_y == 0){ From 3f444302f04424292cd7e26cd1acc7dc3a0aebd6 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 15:04:39 -0700 Subject: [PATCH 22/66] move wkb_generator.cpp to cpp to reduce grammar compilation burden in the python bindings --- .../mapnik/util/geometry_wkt_generator.hpp | 236 +++++------------- src/build.py | 1 + src/wkb_generator.cpp | 141 +++++++++++ 3 files changed, 207 insertions(+), 171 deletions(-) create mode 100644 src/wkb_generator.cpp diff --git a/include/mapnik/util/geometry_wkt_generator.hpp b/include/mapnik/util/geometry_wkt_generator.hpp index 46780e5fd..969b932d6 100644 --- a/include/mapnik/util/geometry_wkt_generator.hpp +++ b/include/mapnik/util/geometry_wkt_generator.hpp @@ -26,8 +26,6 @@ // mapnik #include #include -#include -#include // boost #include @@ -55,161 +53,88 @@ struct is_container namespace mapnik { namespace util { - namespace karma = boost::spirit::karma; - namespace phoenix = boost::phoenix; - - namespace { - - struct get_type - { - template - struct result { typedef int type; }; - - int operator() (geometry_type const& geom) const - { - return static_cast(geom.type()); - } - }; - - struct get_first - { - template - struct result { typedef geometry_type::value_type const type; }; - - geometry_type::value_type const operator() (geometry_type const& geom) const - { - geometry_type::value_type coord; - boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord)); - return coord; - } - }; - - - struct multi_geometry_ - { - template - struct result { typedef bool type; }; - - bool operator() (geometry_container const& geom) const - { - return geom.size() > 1 ? true : false; - } - }; - - struct multi_geometry_type - { - template - struct result { typedef boost::tuple type; }; - - boost::tuple operator() (geometry_container const& geom) const - { - unsigned type = 0u; - bool collection = false; - - geometry_container::const_iterator itr = geom.begin(); - geometry_container::const_iterator end = geom.end(); - - for ( ; itr != end; ++itr) - { - if (type != 0 && itr->type() != type) - { - collection = true; - break; - } - type = itr->type(); - } - return boost::tuple(type, collection); - } - }; +namespace karma = boost::spirit::karma; +namespace phoenix = boost::phoenix; +namespace { +struct get_type +{ template - struct wkt_coordinate_policy : karma::real_policies - { - typedef boost::spirit::karma::real_policies base_type; - static int floatfield(T n) { return base_type::fmtflags::fixed; } - static unsigned precision(T n) { return 6 ;} - }; + struct result { typedef int type; }; + int operator() (geometry_type const& geom) const + { + return static_cast(geom.type()); } +}; - template - struct wkt_generator : - karma::grammar +struct get_first +{ + template + struct result { typedef geometry_type::value_type const type; }; + + geometry_type::value_type const operator() (geometry_type const& geom) const { + geometry_type::value_type coord; + boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord)); + return coord; + } +}; - wkt_generator(bool single = false) - : wkt_generator::base_type(wkt) - { - using boost::spirit::karma::uint_; - using boost::spirit::karma::_val; - using boost::spirit::karma::_1; - using boost::spirit::karma::lit; - using boost::spirit::karma::_a; - using boost::spirit::karma::_r1; - using boost::spirit::karma::eps; - using boost::spirit::karma::string; - wkt = point | linestring | polygon - ; +struct multi_geometry_ +{ + template + struct result { typedef bool type; }; - point = &uint_(mapnik::Point)[_1 = _type(_val)] - << string[ phoenix::if_ (single) [_1 = "Point("] - .else_[_1 = "("]] - << point_coord [_1 = _first(_val)] << lit(')') - ; + bool operator() (geometry_container const& geom) const + { + return geom.size() > 1 ? true : false; + } +}; - linestring = &uint_(mapnik::LineString)[_1 = _type(_val)] - << string[ phoenix::if_ (single) [_1 = "LineString("] - .else_[_1 = "("]] - << coords - << lit(')') - ; +struct multi_geometry_type +{ + template + struct result { typedef boost::tuple type; }; - polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)] - << string[ phoenix::if_ (single) [_1 = "Polygon("] - .else_[_1 = "("]] - << coords2 - << lit("))") - ; + boost::tuple operator() (geometry_container const& geom) const; +}; - point_coord = &uint_ << coord_type << lit(' ') << coord_type - ; - polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1] - << string[ if_ (_r1 > 1) [_1 = "),("] - .else_[_1 = "("] ] | &uint_ << ",") - << coord_type - << lit(' ') - << coord_type - ; +template +struct wkt_coordinate_policy : karma::real_policies +{ + typedef boost::spirit::karma::real_policies base_type; + static int floatfield(T n) { return base_type::fmtflags::fixed; } + static unsigned precision(T n) { return 6 ;} +}; - coords2 %= *polygon_coord(_a) - ; +} - coords = point_coord % lit(',') - ; +template +struct wkt_generator : + karma::grammar +{ + wkt_generator(bool single = false); + // rules + karma::rule wkt; + karma::rule point; + karma::rule linestring; + karma::rule polygon; - } - // rules - karma::rule wkt; - karma::rule point; - karma::rule linestring; - karma::rule polygon; - - karma::rule coords; - karma::rule, geometry_type const& ()> coords2; - karma::rule point_coord; - karma::rule polygon_coord; - - // phoenix functions - phoenix::function _type; - phoenix::function _first; - // - karma::real_generator > coord_type; - - }; + karma::rule coords; + karma::rule, geometry_type const& ()> coords2; + karma::rule point_coord; + karma::rule polygon_coord; + // phoenix functions + phoenix::function _type; + phoenix::function _first; + // + karma::real_generator > coord_type; +}; template @@ -217,38 +142,7 @@ struct wkt_multi_generator : karma::grammar >, geometry_container const& ()> { - wkt_multi_generator() - : wkt_multi_generator::base_type(wkt) - { - using boost::spirit::karma::lit; - using boost::spirit::karma::eps; - using boost::spirit::karma::_val; - using boost::spirit::karma::_1; - using boost::spirit::karma::_a; - - geometry_types.add - (mapnik::Point,"Point") - (mapnik::LineString,"LineString") - (mapnik::Polygon,"Polygon") - ; - - wkt = eps(phoenix::at_c<1>(_a))[_a = _multi_type(_val)] - << lit("GeometryCollection(") << geometry << lit(")") - | eps(is_multi(_val)) << lit("Multi") << geometry_types[_1 = phoenix::at_c<0>(_a)] - << "(" << multi_geometry << ")" - | geometry - ; - - geometry = -(single_geometry % lit(',')) - ; - - single_geometry = geometry_types[_1 = _type(_val)] << path - ; - - multi_geometry = -(path % lit(',')) - ; - - } + wkt_multi_generator(); // rules karma::rule >, geometry_container const& ()> wkt; karma::rule geometry; diff --git a/src/build.py b/src/build.py index 1ad71687b..cf75e6b20 100644 --- a/src/build.py +++ b/src/build.py @@ -144,6 +144,7 @@ source = Split( text_symbolizer.cpp tiff_reader.cpp wkb.cpp + wkb_generator.cpp projection.cpp proj_transform.cpp distance.cpp diff --git a/src/wkb_generator.cpp b/src/wkb_generator.cpp new file mode 100644 index 000000000..68decfc9e --- /dev/null +++ b/src/wkb_generator.cpp @@ -0,0 +1,141 @@ +/***************************************************************************** + * + * 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 +#include + +namespace mapnik { namespace util { + +boost::tuple multi_geometry_type::operator() (geometry_container const& geom) const +{ + unsigned type = 0u; + bool collection = false; + + geometry_container::const_iterator itr = geom.begin(); + geometry_container::const_iterator end = geom.end(); + + for ( ; itr != end; ++itr) + { + if (type != 0 && itr->type() != type) + { + collection = true; + break; + } + type = itr->type(); + } + return boost::tuple(type, collection); +} + +template +wkt_generator::wkt_generator(bool single) + : wkt_generator::base_type(wkt) +{ + using boost::spirit::karma::uint_; + using boost::spirit::karma::_val; + using boost::spirit::karma::_1; + using boost::spirit::karma::lit; + using boost::spirit::karma::_a; + using boost::spirit::karma::_r1; + using boost::spirit::karma::eps; + using boost::spirit::karma::string; + + wkt = point | linestring | polygon + ; + + point = &uint_(mapnik::Point)[_1 = _type(_val)] + << string[ phoenix::if_ (single) [_1 = "Point("] + .else_[_1 = "("]] + << point_coord [_1 = _first(_val)] << lit(')') + ; + + linestring = &uint_(mapnik::LineString)[_1 = _type(_val)] + << string[ phoenix::if_ (single) [_1 = "LineString("] + .else_[_1 = "("]] + << coords + << lit(')') + ; + + polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)] + << string[ phoenix::if_ (single) [_1 = "Polygon("] + .else_[_1 = "("]] + << coords2 + << lit("))") + ; + + point_coord = &uint_ << coord_type << lit(' ') << coord_type + ; + + polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1] + << string[ if_ (_r1 > 1) [_1 = "),("] + .else_[_1 = "("] ] | &uint_ << ",") + << coord_type + << lit(' ') + << coord_type + ; + + coords2 %= *polygon_coord(_a) + ; + + coords = point_coord % lit(',') + ; +} + +template +wkt_multi_generator::wkt_multi_generator() + : wkt_multi_generator::base_type(wkt) +{ + using boost::spirit::karma::lit; + using boost::spirit::karma::eps; + using boost::spirit::karma::_val; + using boost::spirit::karma::_1; + using boost::spirit::karma::_a; + + geometry_types.add + (mapnik::Point,"Point") + (mapnik::LineString,"LineString") + (mapnik::Polygon,"Polygon") + ; + + wkt = eps(phoenix::at_c<1>(_a))[_a = _multi_type(_val)] + << lit("GeometryCollection(") << geometry << lit(")") + | eps(is_multi(_val)) << lit("Multi") << geometry_types[_1 = phoenix::at_c<0>(_a)] + << "(" << multi_geometry << ")" + | geometry + ; + + geometry = -(single_geometry % lit(',')) + ; + + single_geometry = geometry_types[_1 = _type(_val)] << path + ; + + multi_geometry = -(path % lit(',')) + ; + +} + +template struct mapnik::util::wkt_generator >; +template struct mapnik::util::wkt_multi_generator >; + + +}} \ No newline at end of file From d35821d0587ffb86ddc463e9acd9e85579d425e4 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Wed, 25 Jul 2012 00:20:58 +0200 Subject: [PATCH 23/66] Fix deprecation warnings. Part 1 Refs #1340. --- src/save_map.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/save_map.cpp b/src/save_map.cpp index 58fa54e7a..1072d2b94 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -204,9 +204,11 @@ public: { set_attr(sym_node, "unlock-image", sym.get_unlock_image()); } - if (sym.get_text_opacity() != dfl.get_text_opacity() || explicit_defaults_) + + if (sym.get_placement_options()->defaults.format.text_opacity != + dfl.get_placement_options()->defaults.format.text_opacity || explicit_defaults_) { - set_attr(sym_node, "text-opacity", sym.get_text_opacity()); + set_attr(sym_node, "text-opacity", sym.get_placement_options()->defaults.format.text_opacity); } position displacement = sym.get_shield_displacement(); if (displacement.first != dfl.get_shield_displacement().first || explicit_defaults_) From ebf87969e43abb78599b9602e57e10d0e0b3f37b Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 15:43:32 -0700 Subject: [PATCH 24/66] move css_color and path_expression grammars to cpp --- include/mapnik/css_color_grammar.hpp | 233 +----------------- include/mapnik/path_expression_grammar.hpp | 40 +--- src/build.py | 2 + src/css_color_grammar.cpp | 262 +++++++++++++++++++++ src/path_expression_grammar.cpp | 62 +++++ 5 files changed, 331 insertions(+), 268 deletions(-) create mode 100644 src/css_color_grammar.cpp create mode 100644 src/path_expression_grammar.cpp diff --git a/include/mapnik/css_color_grammar.hpp b/include/mapnik/css_color_grammar.hpp index 870965fa9..014c51299 100644 --- a/include/mapnik/css_color_grammar.hpp +++ b/include/mapnik/css_color_grammar.hpp @@ -63,162 +63,10 @@ typedef boost::spirit::ascii::space_type ascii_space_type; struct named_colors_ : qi::symbols { - named_colors_() - { - add - ("aliceblue", color(240, 248, 255)) - ("antiquewhite", color(250, 235, 215)) - ("aqua", color(0, 255, 255)) - ("aquamarine", color(127, 255, 212)) - ("azure", color(240, 255, 255)) - ("beige", color(245, 245, 220)) - ("bisque", color(255, 228, 196)) - ("black", color(0, 0, 0)) - ("blanchedalmond", color(255,235,205)) - ("blue", color(0, 0, 255)) - ("blueviolet", color(138, 43, 226)) - ("brown", color(165, 42, 42)) - ("burlywood", color(222, 184, 135)) - ("cadetblue", color(95, 158, 160)) - ("chartreuse", color(127, 255, 0)) - ("chocolate", color(210, 105, 30)) - ("coral", color(255, 127, 80)) - ("cornflowerblue", color(100, 149, 237)) - ("cornsilk", color(255, 248, 220)) - ("crimson", color(220, 20, 60)) - ("cyan", color(0, 255, 255)) - ("darkblue", color(0, 0, 139)) - ("darkcyan", color(0, 139, 139)) - ("darkgoldenrod", color(184, 134, 11)) - ("darkgray", color(169, 169, 169)) - ("darkgreen", color(0, 100, 0)) - ("darkgrey", color(169, 169, 169)) - ("darkkhaki", color(189, 183, 107)) - ("darkmagenta", color(139, 0, 139)) - ("darkolivegreen", color(85, 107, 47)) - ("darkorange", color(255, 140, 0)) - ("darkorchid", color(153, 50, 204)) - ("darkred", color(139, 0, 0)) - ("darksalmon", color(233, 150, 122)) - ("darkseagreen", color(143, 188, 143)) - ("darkslateblue", color(72, 61, 139)) - ("darkslategrey", color(47, 79, 79)) - ("darkturquoise", color(0, 206, 209)) - ("darkviolet", color(148, 0, 211)) - ("deeppink", color(255, 20, 147)) - ("deepskyblue", color(0, 191, 255)) - ("dimgray", color(105, 105, 105)) - ("dimgrey", color(105, 105, 105)) - ("dodgerblue", color(30, 144, 255)) - ("firebrick", color(178, 34, 34)) - ("floralwhite", color(255, 250, 240)) - ("forestgreen", color(34, 139, 34)) - ("fuchsia", color(255, 0, 255)) - ("gainsboro", color(220, 220, 220)) - ("ghostwhite", color(248, 248, 255)) - ("gold", color(255, 215, 0)) - ("goldenrod", color(218, 165, 32)) - ("gray", color(128, 128, 128)) - ("grey", color(128, 128, 128)) - ("green", color(0, 128, 0)) - ("greenyellow", color(173, 255, 47)) - ("honeydew", color(240, 255, 240)) - ("hotpink", color(255, 105, 180)) - ("indianred", color(205, 92, 92)) - ("indigo", color(75, 0, 130)) - ("ivory", color(255, 255, 240)) - ("khaki", color(240, 230, 140)) - ("lavender", color(230, 230, 250)) - ("lavenderblush", color(255, 240, 245)) - ("lawngreen", color(124, 252, 0)) - ("lemonchiffon", color(255, 250, 205)) - ("lightblue", color(173, 216, 230)) - ("lightcoral", color(240, 128, 128)) - ("lightcyan", color(224, 255, 255)) - ("lightgoldenrodyellow", color(250, 250, 210)) - ("lightgray", color(211, 211, 211)) - ("lightgreen", color(144, 238, 144)) - ("lightgrey", color(211, 211, 211)) - ("lightpink", color(255, 182, 193)) - ("lightsalmon", color(255, 160, 122)) - ("lightseagreen", color(32, 178, 170)) - ("lightskyblue", color(135, 206, 250)) - ("lightslategray", color(119, 136, 153)) - ("lightslategrey", color(119, 136, 153)) - ("lightsteelblue", color(176, 196, 222)) - ("lightyellow", color(255, 255, 224)) - ("lime", color(0, 255, 0)) - ("limegreen", color(50, 205, 50)) - ("linen", color(250, 240, 230)) - ("magenta", color(255, 0, 255)) - ("maroon", color(128, 0, 0)) - ("mediumaquamarine", color(102, 205, 170)) - ("mediumblue", color(0, 0, 205)) - ("mediumorchid", color(186, 85, 211)) - ("mediumpurple", color(147, 112, 219)) - ("mediumseagreen", color(60, 179, 113)) - ("mediumslateblue", color(123, 104, 238)) - ("mediumspringgreen", color(0, 250, 154)) - ("mediumturquoise", color(72, 209, 204)) - ("mediumvioletred", color(199, 21, 133)) - ("midnightblue", color(25, 25, 112)) - ("mintcream", color(245, 255, 250)) - ("mistyrose", color(255, 228, 225)) - ("moccasin", color(255, 228, 181)) - ("navajowhite", color(255, 222, 173)) - ("navy", color(0, 0, 128)) - ("oldlace", color(253, 245, 230)) - ("olive", color(128, 128, 0)) - ("olivedrab", color(107, 142, 35)) - ("orange", color(255, 165, 0)) - ("orangered", color(255, 69, 0)) - ("orchid", color(218, 112, 214)) - ("palegoldenrod", color(238, 232, 170)) - ("palegreen", color(152, 251, 152)) - ("paleturquoise", color(175, 238, 238)) - ("palevioletred", color(219, 112, 147)) - ("papayawhip", color(255, 239, 213)) - ("peachpuff", color(255, 218, 185)) - ("peru", color(205, 133, 63)) - ("pink", color(255, 192, 203)) - ("plum", color(221, 160, 221)) - ("powderblue", color(176, 224, 230)) - ("purple", color(128, 0, 128)) - ("red", color(255, 0, 0)) - ("rosybrown", color(188, 143, 143)) - ("royalblue", color(65, 105, 225)) - ("saddlebrown", color(139, 69, 19)) - ("salmon", color(250, 128, 114)) - ("sandybrown", color(244, 164, 96)) - ("seagreen", color(46, 139, 87)) - ("seashell", color(255, 245, 238)) - ("sienna", color(160, 82, 45)) - ("silver", color(192, 192, 192)) - ("skyblue", color(135, 206, 235)) - ("slateblue", color(106, 90, 205)) - ("slategray", color(112, 128, 144)) - ("slategrey", color(112, 128, 144)) - ("snow", color(255, 250, 250)) - ("springgreen", color(0, 255, 127)) - ("steelblue", color(70, 130, 180)) - ("tan", color(210, 180, 140)) - ("teal", color(0, 128, 128)) - ("thistle", color(216, 191, 216)) - ("tomato", color(255, 99, 71)) - ("turquoise", color(64, 224, 208)) - ("violet", color(238, 130, 238)) - ("wheat", color(245, 222, 179)) - ("white", color(255, 255, 255)) - ("whitesmoke", color(245, 245, 245)) - ("yellow", color(255, 255, 0)) - ("yellowgreen", color(154, 205, 50)) - ("transparent", color(0, 0, 0, 0)) - ; - } + named_colors_(); } ; // clipper helper - template inline int clip_int(int val) { @@ -256,19 +104,7 @@ struct alpha_conv_impl }; // http://www.w3.org/TR/css3-color/#hsl-color -inline double hue_to_rgb( double m1, double m2, double h) -{ - if (h < 0.0) h = h + 1.0; - else if (h > 1) h = h - 1.0; - - if (h * 6 < 1.0) - return m1 + (m2 - m1) * h * 6.0; - if (h * 2 < 1.0) - return m2; - if (h * 3 < 2.0) - return m1 + (m2 - m1)* (2.0/3.0 - h) * 6.0; - return m1; -} +inline double hue_to_rgb( double m1, double m2, double h); struct hsl_conv_impl { @@ -307,70 +143,7 @@ struct hsl_conv_impl template struct css_color_grammar : qi::grammar { - - css_color_grammar() - : css_color_grammar::base_type(css_color) - - { - using qi::lit; - using qi::_val; - using qi::double_; - using qi::_1; - using qi::_a; - using qi::_b; - using qi::_c; - using ascii::no_case; - using phoenix::at_c; - - css_color %= rgba_color - | rgba_percent_color - | hsl_percent_color - | hex_color - | hex_color_small - | no_case[named]; - - hex_color = lit('#') - >> hex2 [ at_c<0>(_val) = _1 ] - >> hex2 [ at_c<1>(_val) = _1 ] - >> hex2 [ at_c<2>(_val) = _1 ] - >>-hex2 [ at_c<3>(_val) = _1 ] - ; - - hex_color_small = lit('#') - >> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ] - >> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ] - >> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ] - >>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ] - ; - - rgba_color = lit("rgb") >> -lit('a') - >> lit('(') - >> dec3 [at_c<0>(_val) = _1] >> ',' - >> dec3 [at_c<1>(_val) = _1] >> ',' - >> dec3 [at_c<2>(_val) = _1] - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) - >> lit(')') - ; - - rgba_percent_color = lit("rgb") >> -lit('a') - >> lit('(') - >> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ',' - >> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ',' - >> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%' - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) - >> lit(')') - ; - - hsl_percent_color = lit("hsl") >> -lit('a') - >> lit('(') - >> double_ [ _a = _1] >> ',' // hue 0..360 - >> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100% - >> double_ [ _c = _1] >> '%' // lightness 0..100% - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1 - >> lit (')') [ hsl_converter(_val,_a,_b,_c)] - ; - } - + css_color_grammar(); qi::uint_parser< unsigned, 16, 2, 2 > hex2 ; qi::uint_parser< unsigned, 16, 1, 1 > hex1 ; qi::uint_parser< unsigned, 10, 1, 3 > dec3 ; diff --git a/include/mapnik/path_expression_grammar.hpp b/include/mapnik/path_expression_grammar.hpp index 9c11e29eb..f60f33feb 100644 --- a/include/mapnik/path_expression_grammar.hpp +++ b/include/mapnik/path_expression_grammar.hpp @@ -24,29 +24,15 @@ #define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP // mapnik -#include -#include -#include +#include // boost #include -#include // spirit2 #include #include -// fusion -#include - -// phoenix -#include -#include -#include -#include -#include -#include - // stl #include #include @@ -65,29 +51,7 @@ typedef boost::variant path_component; template struct path_expression_grammar : qi::grammar(), space_type> { - path_expression_grammar() - : path_expression_grammar::base_type(expr) - { - using boost::phoenix::construct; - using standard_wide::char_; - using qi::_1; - using qi::_val; - using qi::lit; - using qi::lexeme; - using phoenix::push_back; - - expr = - * ( - str [ push_back(_val, _1)] - | - ( '[' >> attr [ push_back(_val, construct( _1 )) ] >> ']') - ) - ; - - attr %= +(char_ - ']'); - str %= lexeme[+(char_ -'[')]; - } - + path_expression_grammar(); qi::rule() , space_type> expr; qi::rule attr; qi::rule str; diff --git a/src/build.py b/src/build.py index cf75e6b20..35b612d2b 100644 --- a/src/build.py +++ b/src/build.py @@ -101,6 +101,7 @@ else: # unix, non-macos source = Split( """ color.cpp + css_color_grammar.cpp conversions.cpp image_compositing.cpp image_scaling.cpp @@ -133,6 +134,7 @@ source = Split( parse_path.cpp parse_transform.cpp palette.cpp + path_expression_grammar.cpp placement_finder.cpp plugin.cpp png_reader.cpp diff --git a/src/css_color_grammar.cpp b/src/css_color_grammar.cpp new file mode 100644 index 000000000..cf0d3f242 --- /dev/null +++ b/src/css_color_grammar.cpp @@ -0,0 +1,262 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#include + +namespace mapnik +{ + +named_colors_::named_colors_() +{ + add + ("aliceblue", color(240, 248, 255)) + ("antiquewhite", color(250, 235, 215)) + ("aqua", color(0, 255, 255)) + ("aquamarine", color(127, 255, 212)) + ("azure", color(240, 255, 255)) + ("beige", color(245, 245, 220)) + ("bisque", color(255, 228, 196)) + ("black", color(0, 0, 0)) + ("blanchedalmond", color(255,235,205)) + ("blue", color(0, 0, 255)) + ("blueviolet", color(138, 43, 226)) + ("brown", color(165, 42, 42)) + ("burlywood", color(222, 184, 135)) + ("cadetblue", color(95, 158, 160)) + ("chartreuse", color(127, 255, 0)) + ("chocolate", color(210, 105, 30)) + ("coral", color(255, 127, 80)) + ("cornflowerblue", color(100, 149, 237)) + ("cornsilk", color(255, 248, 220)) + ("crimson", color(220, 20, 60)) + ("cyan", color(0, 255, 255)) + ("darkblue", color(0, 0, 139)) + ("darkcyan", color(0, 139, 139)) + ("darkgoldenrod", color(184, 134, 11)) + ("darkgray", color(169, 169, 169)) + ("darkgreen", color(0, 100, 0)) + ("darkgrey", color(169, 169, 169)) + ("darkkhaki", color(189, 183, 107)) + ("darkmagenta", color(139, 0, 139)) + ("darkolivegreen", color(85, 107, 47)) + ("darkorange", color(255, 140, 0)) + ("darkorchid", color(153, 50, 204)) + ("darkred", color(139, 0, 0)) + ("darksalmon", color(233, 150, 122)) + ("darkseagreen", color(143, 188, 143)) + ("darkslateblue", color(72, 61, 139)) + ("darkslategrey", color(47, 79, 79)) + ("darkturquoise", color(0, 206, 209)) + ("darkviolet", color(148, 0, 211)) + ("deeppink", color(255, 20, 147)) + ("deepskyblue", color(0, 191, 255)) + ("dimgray", color(105, 105, 105)) + ("dimgrey", color(105, 105, 105)) + ("dodgerblue", color(30, 144, 255)) + ("firebrick", color(178, 34, 34)) + ("floralwhite", color(255, 250, 240)) + ("forestgreen", color(34, 139, 34)) + ("fuchsia", color(255, 0, 255)) + ("gainsboro", color(220, 220, 220)) + ("ghostwhite", color(248, 248, 255)) + ("gold", color(255, 215, 0)) + ("goldenrod", color(218, 165, 32)) + ("gray", color(128, 128, 128)) + ("grey", color(128, 128, 128)) + ("green", color(0, 128, 0)) + ("greenyellow", color(173, 255, 47)) + ("honeydew", color(240, 255, 240)) + ("hotpink", color(255, 105, 180)) + ("indianred", color(205, 92, 92)) + ("indigo", color(75, 0, 130)) + ("ivory", color(255, 255, 240)) + ("khaki", color(240, 230, 140)) + ("lavender", color(230, 230, 250)) + ("lavenderblush", color(255, 240, 245)) + ("lawngreen", color(124, 252, 0)) + ("lemonchiffon", color(255, 250, 205)) + ("lightblue", color(173, 216, 230)) + ("lightcoral", color(240, 128, 128)) + ("lightcyan", color(224, 255, 255)) + ("lightgoldenrodyellow", color(250, 250, 210)) + ("lightgray", color(211, 211, 211)) + ("lightgreen", color(144, 238, 144)) + ("lightgrey", color(211, 211, 211)) + ("lightpink", color(255, 182, 193)) + ("lightsalmon", color(255, 160, 122)) + ("lightseagreen", color(32, 178, 170)) + ("lightskyblue", color(135, 206, 250)) + ("lightslategray", color(119, 136, 153)) + ("lightslategrey", color(119, 136, 153)) + ("lightsteelblue", color(176, 196, 222)) + ("lightyellow", color(255, 255, 224)) + ("lime", color(0, 255, 0)) + ("limegreen", color(50, 205, 50)) + ("linen", color(250, 240, 230)) + ("magenta", color(255, 0, 255)) + ("maroon", color(128, 0, 0)) + ("mediumaquamarine", color(102, 205, 170)) + ("mediumblue", color(0, 0, 205)) + ("mediumorchid", color(186, 85, 211)) + ("mediumpurple", color(147, 112, 219)) + ("mediumseagreen", color(60, 179, 113)) + ("mediumslateblue", color(123, 104, 238)) + ("mediumspringgreen", color(0, 250, 154)) + ("mediumturquoise", color(72, 209, 204)) + ("mediumvioletred", color(199, 21, 133)) + ("midnightblue", color(25, 25, 112)) + ("mintcream", color(245, 255, 250)) + ("mistyrose", color(255, 228, 225)) + ("moccasin", color(255, 228, 181)) + ("navajowhite", color(255, 222, 173)) + ("navy", color(0, 0, 128)) + ("oldlace", color(253, 245, 230)) + ("olive", color(128, 128, 0)) + ("olivedrab", color(107, 142, 35)) + ("orange", color(255, 165, 0)) + ("orangered", color(255, 69, 0)) + ("orchid", color(218, 112, 214)) + ("palegoldenrod", color(238, 232, 170)) + ("palegreen", color(152, 251, 152)) + ("paleturquoise", color(175, 238, 238)) + ("palevioletred", color(219, 112, 147)) + ("papayawhip", color(255, 239, 213)) + ("peachpuff", color(255, 218, 185)) + ("peru", color(205, 133, 63)) + ("pink", color(255, 192, 203)) + ("plum", color(221, 160, 221)) + ("powderblue", color(176, 224, 230)) + ("purple", color(128, 0, 128)) + ("red", color(255, 0, 0)) + ("rosybrown", color(188, 143, 143)) + ("royalblue", color(65, 105, 225)) + ("saddlebrown", color(139, 69, 19)) + ("salmon", color(250, 128, 114)) + ("sandybrown", color(244, 164, 96)) + ("seagreen", color(46, 139, 87)) + ("seashell", color(255, 245, 238)) + ("sienna", color(160, 82, 45)) + ("silver", color(192, 192, 192)) + ("skyblue", color(135, 206, 235)) + ("slateblue", color(106, 90, 205)) + ("slategray", color(112, 128, 144)) + ("slategrey", color(112, 128, 144)) + ("snow", color(255, 250, 250)) + ("springgreen", color(0, 255, 127)) + ("steelblue", color(70, 130, 180)) + ("tan", color(210, 180, 140)) + ("teal", color(0, 128, 128)) + ("thistle", color(216, 191, 216)) + ("tomato", color(255, 99, 71)) + ("turquoise", color(64, 224, 208)) + ("violet", color(238, 130, 238)) + ("wheat", color(245, 222, 179)) + ("white", color(255, 255, 255)) + ("whitesmoke", color(245, 245, 245)) + ("yellow", color(255, 255, 0)) + ("yellowgreen", color(154, 205, 50)) + ("transparent", color(0, 0, 0, 0)) + ; +} + +double hue_to_rgb( double m1, double m2, double h) +{ + if (h < 0.0) h = h + 1.0; + else if (h > 1) h = h - 1.0; + + if (h * 6 < 1.0) + return m1 + (m2 - m1) * h * 6.0; + if (h * 2 < 1.0) + return m2; + if (h * 3 < 2.0) + return m1 + (m2 - m1)* (2.0/3.0 - h) * 6.0; + return m1; +} + +template +css_color_grammar::css_color_grammar() + : css_color_grammar::base_type(css_color) + +{ + using qi::lit; + using qi::_val; + using qi::double_; + using qi::_1; + using qi::_a; + using qi::_b; + using qi::_c; + using ascii::no_case; + using phoenix::at_c; + + css_color %= rgba_color + | rgba_percent_color + | hsl_percent_color + | hex_color + | hex_color_small + | no_case[named]; + + hex_color = lit('#') + >> hex2 [ at_c<0>(_val) = _1 ] + >> hex2 [ at_c<1>(_val) = _1 ] + >> hex2 [ at_c<2>(_val) = _1 ] + >>-hex2 [ at_c<3>(_val) = _1 ] + ; + + hex_color_small = lit('#') + >> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ] + >> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ] + >> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ] + >>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ] + ; + + rgba_color = lit("rgb") >> -lit('a') + >> lit('(') + >> dec3 [at_c<0>(_val) = _1] >> ',' + >> dec3 [at_c<1>(_val) = _1] >> ',' + >> dec3 [at_c<2>(_val) = _1] + >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) + >> lit(')') + ; + + rgba_percent_color = lit("rgb") >> -lit('a') + >> lit('(') + >> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ',' + >> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ',' + >> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%' + >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) + >> lit(')') + ; + + hsl_percent_color = lit("hsl") >> -lit('a') + >> lit('(') + >> double_ [ _a = _1] >> ',' // hue 0..360 + >> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100% + >> double_ [ _c = _1] >> '%' // lightness 0..100% + >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1 + >> lit (')') [ hsl_converter(_val,_a,_b,_c)] + ; +} + +template struct mapnik::css_color_grammar; + + +} \ No newline at end of file diff --git a/src/path_expression_grammar.cpp b/src/path_expression_grammar.cpp new file mode 100644 index 000000000..40185818b --- /dev/null +++ b/src/path_expression_grammar.cpp @@ -0,0 +1,62 @@ +/***************************************************************************** + * + * 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 + +// boost +#include +#include +#include +#include + +namespace mapnik +{ + +template +path_expression_grammar::path_expression_grammar() + : path_expression_grammar::base_type(expr) +{ + using boost::phoenix::construct; + using standard_wide::char_; + using qi::_1; + using qi::_val; + using qi::lit; + using qi::lexeme; + using phoenix::push_back; + + expr = + * ( + str [ push_back(_val, _1)] + | + ( '[' >> attr [ push_back(_val, construct( _1 )) ] >> ']') + ) + ; + + attr %= +(char_ - ']'); + str %= lexeme[+(char_ -'[')]; +} + +template struct mapnik::path_expression_grammar; + +} From 08cbf1c71c232d58456c359c7b13a2cdf7c2b207 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Wed, 25 Jul 2012 01:15:44 +0200 Subject: [PATCH 25/66] Fix deprecation warnings. Part 2 Closes #1340. --- bindings/python/mapnik_shield_symbolizer.cpp | 54 ++++---------------- include/mapnik/text_symbolizer.hpp | 2 +- 2 files changed, 12 insertions(+), 44 deletions(-) diff --git a/bindings/python/mapnik_shield_symbolizer.cpp b/bindings/python/mapnik_shield_symbolizer.cpp index 28ae7083e..8a08900bb 100644 --- a/bindings/python/mapnik_shield_symbolizer.cpp +++ b/bindings/python/mapnik_shield_symbolizer.cpp @@ -21,6 +21,13 @@ * *****************************************************************************/ +/* The functions in this file produce deprecation warnings. + * But as shield symbolizer doesn't fully support more than one + * placement from python yet these functions are actually the + * correct ones. + */ +#define NO_DEPRECATION_WARNINGS + // boost #include @@ -53,12 +60,13 @@ tuple get_shield_displacement(const shield_symbolizer& s) void set_shield_displacement(shield_symbolizer & s, boost::python::tuple arg) { - s.set_shield_displacement(extract(arg[0]),extract(arg[1])); + s.get_placement_options()->defaults.displacement.first = extract(arg[0]); + s.get_placement_options()->defaults.displacement.second = extract(arg[1]); } tuple get_text_displacement(const shield_symbolizer& t) { - position const& pos = t.get_displacement(); + position const& pos = t.get_placement_options()->defaults.displacement; return boost::python::make_tuple(pos.first, pos.second); } @@ -79,46 +87,6 @@ void set_filename(shield_symbolizer & t, std::string const& file_expr) } -struct shield_symbolizer_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const shield_symbolizer& s) - { - std::string filename = path_processor_type::to_string(*s.get_filename()); - //(name, font name, font size, font color, image file, image type, width, height) - return boost::python::make_tuple( "TODO",//s.get_name(), - s.get_face_name(),s.get_text_size(),s.get_fill(),filename,guess_type(filename)); - - } - - static boost::python::tuple - getstate(const shield_symbolizer& s) - { - return boost::python::make_tuple(s.get_halo_fill(),s.get_halo_radius()); - } - - // TODO add lots more... - static void - setstate (shield_symbolizer& s, boost::python::tuple state) - { - using namespace boost::python; - /*if (len(state) != 1) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 1-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - }*/ - - s.set_halo_fill(extract(state[0])); - s.set_halo_radius(extract(state[1])); - - } - -}; - - void export_shield_symbolizer() { using namespace boost::python; @@ -126,7 +94,7 @@ void export_shield_symbolizer() init("TODO") + path_expression_ptr>() ) //.def_pickle(shield_symbolizer_pickle_suite()) .add_property("allow_overlap", diff --git a/include/mapnik/text_symbolizer.hpp b/include/mapnik/text_symbolizer.hpp index 05a9c2a39..1824f62fe 100644 --- a/include/mapnik/text_symbolizer.hpp +++ b/include/mapnik/text_symbolizer.hpp @@ -37,7 +37,7 @@ // stl #include -#if (1 && __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#if (!defined(NO_DEPRECATION_WARNINGS) && __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #define func_deprecated __attribute__ ((deprecated)) #else #define func_deprecated From 80b0b4a8886bc57353c93c3fd372220d6ec2f82c Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 17:41:08 -0700 Subject: [PATCH 26/66] do not attempt to inline complex templated method on grid - refs #1330 --- include/mapnik/grid/grid.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/grid/grid.hpp b/include/mapnik/grid/grid.hpp index 0c89e8173..7cd9d0bbc 100644 --- a/include/mapnik/grid/grid.hpp +++ b/include/mapnik/grid/grid.hpp @@ -97,7 +97,7 @@ public: return id_name_; } - inline void add_feature(mapnik::feature_impl & feature); + void add_feature(mapnik::feature_impl & feature); inline void add_property_name(std::string const& name) { From 6c7ab1767ba766b2655a90b0c384d56e68378ff0 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 18:35:18 -0700 Subject: [PATCH 27/66] include what you use --- bindings/python/mapnik_python.cpp | 1 + bindings/python/python_grid_utils.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp index 5ec4b93ac..b86a7e33d 100644 --- a/bindings/python/mapnik_python.cpp +++ b/bindings/python/mapnik_python.cpp @@ -72,6 +72,7 @@ void export_logger(); #include #include +#include #include #include #ifdef HAVE_CAIRO diff --git a/bindings/python/python_grid_utils.cpp b/bindings/python/python_grid_utils.cpp index 87379c9fd..f0b99f714 100644 --- a/bindings/python/python_grid_utils.cpp +++ b/bindings/python/python_grid_utils.cpp @@ -26,6 +26,8 @@ #include // mapnik +#include +#include #include #include #include From b4f3d6da11dfc6d1456a6c9a5227458ea96173a1 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 18:35:41 -0700 Subject: [PATCH 28/66] include what you use --- demo/c++/rundemo.cpp | 3 +++ src/agg/agg_renderer.cpp | 2 ++ src/cairo_renderer.cpp | 3 ++- src/deepcopy.cpp | 1 + src/feature_style_processor.cpp | 6 ++++-- src/grid/grid_renderer.cpp | 2 ++ src/load_map.cpp | 6 ------ src/map.cpp | 4 +++- src/save_map.cpp | 2 ++ 9 files changed, 19 insertions(+), 10 deletions(-) diff --git a/demo/c++/rundemo.cpp b/demo/c++/rundemo.cpp index 2546bd09e..31e016ced 100644 --- a/demo/c++/rundemo.cpp +++ b/demo/c++/rundemo.cpp @@ -21,6 +21,9 @@ *****************************************************************************/ #include +#include +#include +#include #include #include #include diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index 46f048063..92cda8973 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -21,6 +21,8 @@ *****************************************************************************/ // mapnik +#include +#include #include #include #include diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index e8120444d..10b22cb1b 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -23,6 +23,8 @@ #if defined(HAVE_CAIRO) // mapnik +#include +#include #include #include #include @@ -52,7 +54,6 @@ #include // agg - #include "agg_conv_clip_polyline.h" #include "agg_conv_clip_polygon.h" #include "agg_conv_smooth_poly1.h" diff --git a/src/deepcopy.cpp b/src/deepcopy.cpp index 9c77db0ee..e14df4973 100644 --- a/src/deepcopy.cpp +++ b/src/deepcopy.cpp @@ -21,6 +21,7 @@ *****************************************************************************/ // mapnik +#include #include #include #include diff --git a/src/feature_style_processor.cpp b/src/feature_style_processor.cpp index 31f955ad5..8e198f375 100644 --- a/src/feature_style_processor.cpp +++ b/src/feature_style_processor.cpp @@ -20,8 +20,9 @@ * *****************************************************************************/ -//mapnik +// mapnik #include +#include #include #include #include @@ -36,7 +37,8 @@ // boost #include #include -//stl + +// stl #include #if defined(HAVE_CAIRO) diff --git a/src/grid/grid_renderer.cpp b/src/grid/grid_renderer.cpp index fdbe834dd..ab231e853 100644 --- a/src/grid/grid_renderer.cpp +++ b/src/grid/grid_renderer.cpp @@ -21,6 +21,8 @@ *****************************************************************************/ // mapnik +#include +#include #include #include #include diff --git a/src/load_map.cpp b/src/load_map.cpp index 9a1183a89..b8905a690 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -22,9 +22,7 @@ // mapnik #include - #include - #include #include #include @@ -39,16 +37,12 @@ #include #include #include - #include #include #include #include - #include - #include - #include #include #include diff --git a/src/map.cpp b/src/map.cpp index 1b7f14905..7a9d1f14b 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -20,7 +20,9 @@ * *****************************************************************************/ -//mapnik +// mapnik +#include +#include #include #include #include diff --git a/src/save_map.cpp b/src/save_map.cpp index 517aaafa1..232aba2a7 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -21,6 +21,8 @@ *****************************************************************************/ // mapnik +#include +#include #include #include #include From b6fa8dc0ed414ce0f755330113992296a36378ff Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 18:36:31 -0700 Subject: [PATCH 29/66] include what you use --- include/mapnik/agg_renderer.hpp | 2 ++ include/mapnik/cairo_renderer.hpp | 2 +- include/mapnik/grid/grid_renderer.hpp | 2 +- include/mapnik/rule.hpp | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index 71401b8de..c82f57239 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.hpp @@ -29,6 +29,7 @@ #include #include #include +#include // for all symbolizers // boost #include @@ -47,6 +48,7 @@ struct trans_affine; namespace mapnik { class marker; + struct rasterizer; template diff --git a/include/mapnik/cairo_renderer.hpp b/include/mapnik/cairo_renderer.hpp index 73d5e4f47..30741427c 100644 --- a/include/mapnik/cairo_renderer.hpp +++ b/include/mapnik/cairo_renderer.hpp @@ -31,7 +31,7 @@ #include #include #include -//#include +#include // for all symbolizers // cairo #include diff --git a/include/mapnik/grid/grid_renderer.hpp b/include/mapnik/grid/grid_renderer.hpp index 1fa66aedf..a5a31245f 100644 --- a/include/mapnik/grid/grid_renderer.hpp +++ b/include/mapnik/grid/grid_renderer.hpp @@ -29,7 +29,7 @@ #include #include #include -//#include +#include // for all symbolizers #include // boost diff --git a/include/mapnik/rule.hpp b/include/mapnik/rule.hpp index 6acb43cc9..104f763e7 100644 --- a/include/mapnik/rule.hpp +++ b/include/mapnik/rule.hpp @@ -23,7 +23,7 @@ #ifndef MAPNIK_RULE_HPP #define MAPNIK_RULE_HPP -// mapni +// mapnik #include #include #include From 1476280189d2d27518e94cd8e2ff799a540abd1e Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 19:08:15 -0700 Subject: [PATCH 30/66] include what you use --- bindings/python/mapnik_datasource.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bindings/python/mapnik_datasource.cpp b/bindings/python/mapnik_datasource.cpp index f89b4eb01..ced0a53ee 100644 --- a/bindings/python/mapnik_datasource.cpp +++ b/bindings/python/mapnik_datasource.cpp @@ -30,6 +30,8 @@ // mapnik #include +#include +#include #include #include #include From 074b3859994221d6745648ae466fffcdef7bbfb7 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 19:08:26 -0700 Subject: [PATCH 31/66] include what you use --- src/feature_style_processor.cpp | 1 + src/memory_datasource.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/feature_style_processor.cpp b/src/feature_style_processor.cpp index 8e198f375..a8e0fc8cd 100644 --- a/src/feature_style_processor.cpp +++ b/src/feature_style_processor.cpp @@ -22,6 +22,7 @@ // mapnik #include +#include #include #include #include diff --git a/src/memory_datasource.cpp b/src/memory_datasource.cpp index 17d32e877..8bee607ac 100644 --- a/src/memory_datasource.cpp +++ b/src/memory_datasource.cpp @@ -22,6 +22,8 @@ // mapnik #include +#include +#include #include #include #include From 241bf28da06e25cdbc47b0fb8125e39b51935e42 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 19:21:55 -0700 Subject: [PATCH 32/66] 'include what you use' in plugins to set up for future forward declarations in mapnik/feature.hpp and mapnik/datasource.hpp --- plugins/input/csv/csv_datasource.hpp | 10 ++++++++++ plugins/input/gdal/gdal_datasource.hpp | 12 +++++++++++- plugins/input/gdal/gdal_featureset.cpp | 1 + plugins/input/gdal/gdal_featureset.hpp | 2 ++ plugins/input/geojson/geojson_datasource.cpp | 1 + plugins/input/geojson/geojson_datasource.hpp | 15 +++++++++++++++ plugins/input/geos/geos_datasource.hpp | 9 +++++++++ plugins/input/kismet/kismet_datasource.hpp | 16 ++++++++++------ plugins/input/kismet/kismet_types.hpp | 1 + plugins/input/occi/occi_datasource.hpp | 10 +++++++++- plugins/input/ogr/ogr_converter.hpp | 1 + plugins/input/ogr/ogr_datasource.hpp | 10 +++++++++- plugins/input/osm/osm_datasource.hpp | 13 +++++++++++++ plugins/input/postgis/postgis_datasource.hpp | 10 ++++++++++ plugins/input/raster/raster_datasource.cpp | 1 + plugins/input/raster/raster_datasource.hpp | 17 +++++++++++++++-- plugins/input/raster/raster_featureset.cpp | 1 + .../input/rasterlite/rasterlite_datasource.hpp | 11 +++++++++++ plugins/input/shape/shape_datasource.hpp | 10 ++++++++++ plugins/input/shape/shape_utils.cpp | 1 + plugins/input/sqlite/sqlite_connection.hpp | 1 + plugins/input/sqlite/sqlite_datasource.hpp | 10 +++++++++- plugins/input/sqlite/sqlite_prepared.hpp | 1 + plugins/input/sqlite/sqlite_resultset.hpp | 1 + plugins/input/sqlite/sqlite_utils.hpp | 1 + .../templates/helloworld/hello_datasource.hpp | 13 +++++++++++++ 26 files changed, 167 insertions(+), 12 deletions(-) diff --git a/plugins/input/csv/csv_datasource.hpp b/plugins/input/csv/csv_datasource.hpp index 22a99a2b8..056d2391d 100644 --- a/plugins/input/csv/csv_datasource.hpp +++ b/plugins/input/csv/csv_datasource.hpp @@ -25,9 +25,19 @@ // mapnik #include +#include +#include +#include +#include +#include +#include + +// boost +#include // stl #include +#include class csv_datasource : public mapnik::datasource { diff --git a/plugins/input/gdal/gdal_datasource.hpp b/plugins/input/gdal/gdal_datasource.hpp index 989b30135..15654fae9 100644 --- a/plugins/input/gdal/gdal_datasource.hpp +++ b/plugins/input/gdal/gdal_datasource.hpp @@ -25,9 +25,19 @@ // mapnik #include +#include +#include +#include +#include +#include +#include // boost -#include +#include + +// stl +#include +#include // gdal #include diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp index 959b1d009..008194ff9 100644 --- a/plugins/input/gdal/gdal_featureset.cpp +++ b/plugins/input/gdal/gdal_featureset.cpp @@ -23,6 +23,7 @@ // mapnik #include #include +#include #include // boost diff --git a/plugins/input/gdal/gdal_featureset.hpp b/plugins/input/gdal/gdal_featureset.hpp index a9912e70e..fc3856574 100644 --- a/plugins/input/gdal/gdal_featureset.hpp +++ b/plugins/input/gdal/gdal_featureset.hpp @@ -31,6 +31,8 @@ #include #include +#include "gdal_datasource.hpp" + class GDALDataset; class GDALRasterBand; diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 3ce9140e8..58354b6f8 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -36,6 +36,7 @@ #include // mapnik #include +#include #include #include #include diff --git a/plugins/input/geojson/geojson_datasource.hpp b/plugins/input/geojson/geojson_datasource.hpp index 231339cc0..9f9ce42d0 100644 --- a/plugins/input/geojson/geojson_datasource.hpp +++ b/plugins/input/geojson/geojson_datasource.hpp @@ -25,7 +25,16 @@ // mapnik #include +#include +#include +#include +#include +#include +#include + // boost +#include +#include #include #include #include @@ -33,6 +42,12 @@ #include #include +// stl +#include +#include +#include +#include + class geojson_datasource : public mapnik::datasource { public: diff --git a/plugins/input/geos/geos_datasource.hpp b/plugins/input/geos/geos_datasource.hpp index 752a89ffc..6127e9fbd 100644 --- a/plugins/input/geos/geos_datasource.hpp +++ b/plugins/input/geos/geos_datasource.hpp @@ -25,12 +25,21 @@ // mapnik #include +#include +#include #include +#include +#include #include // boost +#include #include +// stl +#include +#include + #include "geos_feature_ptr.hpp" class geos_datasource : public mapnik::datasource diff --git a/plugins/input/kismet/kismet_datasource.hpp b/plugins/input/kismet/kismet_datasource.hpp index 6e54d9c23..85504839b 100644 --- a/plugins/input/kismet/kismet_datasource.hpp +++ b/plugins/input/kismet/kismet_datasource.hpp @@ -23,21 +23,25 @@ #ifndef KISMET_DATASOURCE_HPP #define KISMET_DATASOURCE_HPP -// stl -#include - // mapnik #include +#include +#include #include +#include +#include #include -#include // boost +#include #include -#include #include -// sqlite +// stl +#include +#include +#include + #include "kismet_types.hpp" class kismet_datasource : public mapnik::datasource diff --git a/plugins/input/kismet/kismet_types.hpp b/plugins/input/kismet/kismet_types.hpp index c3393d74e..519577897 100644 --- a/plugins/input/kismet/kismet_types.hpp +++ b/plugins/input/kismet/kismet_types.hpp @@ -25,6 +25,7 @@ // mapnik #include +#include // boost #include diff --git a/plugins/input/occi/occi_datasource.hpp b/plugins/input/occi/occi_datasource.hpp index bbc57970d..7e85de7b0 100644 --- a/plugins/input/occi/occi_datasource.hpp +++ b/plugins/input/occi/occi_datasource.hpp @@ -25,13 +25,21 @@ // mapnik #include -#include +#include +#include #include +#include +#include #include // boost +#include #include +// stl +#include +#include + // oci #include "occi_types.hpp" diff --git a/plugins/input/ogr/ogr_converter.hpp b/plugins/input/ogr/ogr_converter.hpp index 94b198d54..a52ab66ce 100644 --- a/plugins/input/ogr/ogr_converter.hpp +++ b/plugins/input/ogr/ogr_converter.hpp @@ -25,6 +25,7 @@ // mapnik #include +#include // ogr #include diff --git a/plugins/input/ogr/ogr_datasource.hpp b/plugins/input/ogr/ogr_datasource.hpp index 1898397e0..67dc5799c 100644 --- a/plugins/input/ogr/ogr_datasource.hpp +++ b/plugins/input/ogr/ogr_datasource.hpp @@ -25,15 +25,23 @@ // mapnik #include +#include +#include #include +#include +#include #include // boost +#include #include +// stl +#include +#include + // ogr #include - #include "ogr_layer_ptr.hpp" class ogr_datasource : public mapnik::datasource diff --git a/plugins/input/osm/osm_datasource.hpp b/plugins/input/osm/osm_datasource.hpp index 1b99718ed..fc79faa88 100644 --- a/plugins/input/osm/osm_datasource.hpp +++ b/plugins/input/osm/osm_datasource.hpp @@ -25,7 +25,20 @@ // mapnik #include +#include +#include +#include #include +#include +#include + +// boost +#include +#include + +// stl +#include +#include #include "osm.h" diff --git a/plugins/input/postgis/postgis_datasource.hpp b/plugins/input/postgis/postgis_datasource.hpp index f484837c8..5cb786569 100644 --- a/plugins/input/postgis/postgis_datasource.hpp +++ b/plugins/input/postgis/postgis_datasource.hpp @@ -25,12 +25,22 @@ // mapnik #include +#include +#include +#include #include +#include #include // boost +#include +#include #include +// stl +#include +#include + #include "connection_manager.hpp" #include "resultset.hpp" #include "cursorresultset.hpp" diff --git a/plugins/input/raster/raster_datasource.cpp b/plugins/input/raster/raster_datasource.cpp index efbd38233..1c66c462e 100644 --- a/plugins/input/raster/raster_datasource.cpp +++ b/plugins/input/raster/raster_datasource.cpp @@ -26,6 +26,7 @@ // mapnik #include +#include #include #include diff --git a/plugins/input/raster/raster_datasource.hpp b/plugins/input/raster/raster_datasource.hpp index 9b84380e5..c79afbbe6 100644 --- a/plugins/input/raster/raster_datasource.hpp +++ b/plugins/input/raster/raster_datasource.hpp @@ -24,9 +24,22 @@ #define RASTER_DATASOURCE_HPP // mapnik -#include -#include #include +#include +#include +#include +#include +#include +#include + +// boost +#include +#include + +// stl +#include +#include + class raster_datasource : public mapnik::datasource { diff --git a/plugins/input/raster/raster_featureset.cpp b/plugins/input/raster/raster_featureset.cpp index bd26a076f..b39bf237b 100644 --- a/plugins/input/raster/raster_featureset.cpp +++ b/plugins/input/raster/raster_featureset.cpp @@ -22,6 +22,7 @@ // mapnik #include +#include #include #include #include diff --git a/plugins/input/rasterlite/rasterlite_datasource.hpp b/plugins/input/rasterlite/rasterlite_datasource.hpp index 4971b2d1d..e2a8137d9 100644 --- a/plugins/input/rasterlite/rasterlite_datasource.hpp +++ b/plugins/input/rasterlite/rasterlite_datasource.hpp @@ -25,10 +25,21 @@ // mapnik #include +#include +#include +#include +#include +#include +#include // boost +#include #include +// stl +#include +#include + #include "rasterlite_include.hpp" class rasterlite_datasource : public mapnik::datasource diff --git a/plugins/input/shape/shape_datasource.hpp b/plugins/input/shape/shape_datasource.hpp index 522365dde..56ea052fc 100644 --- a/plugins/input/shape/shape_datasource.hpp +++ b/plugins/input/shape/shape_datasource.hpp @@ -25,11 +25,21 @@ // mapnik #include +#include +#include +#include #include +#include +#include // boost +#include #include +// stl +#include +#include + #include "shape_io.hpp" using mapnik::datasource; diff --git a/plugins/input/shape/shape_utils.cpp b/plugins/input/shape/shape_utils.cpp index 56cd7c8a2..a2685e67c 100644 --- a/plugins/input/shape/shape_utils.cpp +++ b/plugins/input/shape/shape_utils.cpp @@ -22,6 +22,7 @@ // mapnik #include +#include #include "shape_utils.hpp" // boost diff --git a/plugins/input/sqlite/sqlite_connection.hpp b/plugins/input/sqlite/sqlite_connection.hpp index 1a38062e2..b28c4c97e 100644 --- a/plugins/input/sqlite/sqlite_connection.hpp +++ b/plugins/input/sqlite/sqlite_connection.hpp @@ -28,6 +28,7 @@ // mapnik #include +#include #include #include diff --git a/plugins/input/sqlite/sqlite_datasource.hpp b/plugins/input/sqlite/sqlite_datasource.hpp index c1f840212..063ccaf75 100644 --- a/plugins/input/sqlite/sqlite_datasource.hpp +++ b/plugins/input/sqlite/sqlite_datasource.hpp @@ -25,18 +25,26 @@ // mapnik #include +#include +#include #include +#include +#include #include #include // boost +#include #include #include +// stl +#include +#include + // sqlite #include "sqlite_connection.hpp" - class sqlite_datasource : public mapnik::datasource { public: diff --git a/plugins/input/sqlite/sqlite_prepared.hpp b/plugins/input/sqlite/sqlite_prepared.hpp index c18591f04..f6bf45339 100644 --- a/plugins/input/sqlite/sqlite_prepared.hpp +++ b/plugins/input/sqlite/sqlite_prepared.hpp @@ -25,6 +25,7 @@ // mapnik #include +#include #include // boost diff --git a/plugins/input/sqlite/sqlite_resultset.hpp b/plugins/input/sqlite/sqlite_resultset.hpp index c1582f8ba..9c10eb0f3 100644 --- a/plugins/input/sqlite/sqlite_resultset.hpp +++ b/plugins/input/sqlite/sqlite_resultset.hpp @@ -25,6 +25,7 @@ // mapnik #include +#include // stl #include diff --git a/plugins/input/sqlite/sqlite_utils.hpp b/plugins/input/sqlite/sqlite_utils.hpp index 891150506..fb81ce62b 100644 --- a/plugins/input/sqlite/sqlite_utils.hpp +++ b/plugins/input/sqlite/sqlite_utils.hpp @@ -29,6 +29,7 @@ // mapnik #include +#include #include #include diff --git a/plugins/input/templates/helloworld/hello_datasource.hpp b/plugins/input/templates/helloworld/hello_datasource.hpp index f2e172f56..b7e3dfbbc 100644 --- a/plugins/input/templates/helloworld/hello_datasource.hpp +++ b/plugins/input/templates/helloworld/hello_datasource.hpp @@ -3,6 +3,19 @@ // mapnik #include +#include +#include +#include +#include +#include +#include + +// boost +#include +#include + +// stl +#include class hello_datasource : public mapnik::datasource { From 6396b443efb1a12dd19baa61a0b7b3da281ff3c0 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 19:48:22 -0700 Subject: [PATCH 33/66] default to MARKER_POINT_PLACEMENT for markers --- src/load_map.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/load_map.cpp b/src/load_map.cpp index b8905a690..b23545a90 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -1058,7 +1058,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node) if (parse_stroke(strk,node)) sym.set_stroke(strk); - marker_placement_e placement = node.get_attr("placement", MARKER_LINE_PLACEMENT); + marker_placement_e placement = node.get_attr("placement", MARKER_POINT_PLACEMENT); sym.set_marker_placement(placement); parse_symbolizer_base(sym, node); rule.append(sym); From 1dfde7846b97107c78753a74b2e320f09d2592b6 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 19:56:08 -0700 Subject: [PATCH 34/66] default to not clipping for markers_symbolizer as a temporarily workaround for #1341 --- src/build.py | 4 ++++ src/markers_symbolizer.cpp | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/build.py b/src/build.py index 35b612d2b..2257132b5 100644 --- a/src/build.py +++ b/src/build.py @@ -25,11 +25,15 @@ import sys import glob from copy import copy from subprocess import Popen, PIPE +from colorizer import colorizer +col = colorizer() Import('env') lib_env = env.Clone() +col.colorize(lib_env) + def call(cmd, silent=True): stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate() if not stderr: diff --git a/src/markers_symbolizer.cpp b/src/markers_symbolizer.cpp index 03554e03c..c494bf7fc 100644 --- a/src/markers_symbolizer.cpp +++ b/src/markers_symbolizer.cpp @@ -45,7 +45,10 @@ markers_symbolizer::markers_symbolizer() allow_overlap_(false), spacing_(100.0), max_error_(0.2), - marker_p_(MARKER_POINT_PLACEMENT) {} + marker_p_(MARKER_POINT_PLACEMENT) { + // override the default for clipping in symbolizer base + this->set_clip(false); + } markers_symbolizer::markers_symbolizer(path_expression_ptr const& filename) : symbolizer_with_image(filename), @@ -56,7 +59,10 @@ markers_symbolizer::markers_symbolizer(path_expression_ptr const& filename) allow_overlap_(false), spacing_(100.0), max_error_(0.2), - marker_p_(MARKER_POINT_PLACEMENT) {} + marker_p_(MARKER_POINT_PLACEMENT) { + // override the default for clipping in symbolizer base + this->set_clip(false); + } markers_symbolizer::markers_symbolizer(markers_symbolizer const& rhs) : symbolizer_with_image(rhs), From ad90db2eb0d988fe6c5e0e7df2fde9a3c0f2f4b4 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 23:40:28 -0700 Subject: [PATCH 35/66] remove duplicate declaration --- src/expression_node.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/expression_node.cpp b/src/expression_node.cpp index 5c997044d..f5f9bad8b 100644 --- a/src/expression_node.cpp +++ b/src/expression_node.cpp @@ -37,7 +37,6 @@ regex_replace_node::regex_replace_node (expr_node const& a, UnicodeString const& format(f) {} #else -regex_match_node::pattern boost::regex; regex_match_node::regex_match_node (expr_node const& a, std::string const& str) : expr(a), From 5270f0b005534a0eff71cb63c25ba06f59278328 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 25 Jul 2012 09:20:29 +0100 Subject: [PATCH 36/66] + use assignment for built-in types init --- include/mapnik/geom_util.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index a8a058b5e..d2f6ef4d2 100644 --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.hpp @@ -334,10 +334,10 @@ template bool hit_test(PathType & path, double x, double y, double tol) { bool inside=false; - double x0(0); - double y0(0); - double x1(0); - double y1(0); + double x0 = 0 ; + double y0 = 0; + double x1 = 0; + double y1 = 0; path.rewind(0); unsigned command = path.vertex(&x0, &y0); if (command == SEG_END) return false; From f0ada2b284110a7ad90827a11c780fedce9d9da0 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 25 Jul 2012 10:00:08 +0100 Subject: [PATCH 37/66] + remove colorizer (@springmeyer - was it intentional?) --- src/build.py | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/build.py b/src/build.py index 2257132b5..a56aac0ea 100644 --- a/src/build.py +++ b/src/build.py @@ -25,15 +25,11 @@ import sys import glob from copy import copy from subprocess import Popen, PIPE -from colorizer import colorizer -col = colorizer() Import('env') lib_env = env.Clone() -col.colorize(lib_env) - def call(cmd, silent=True): stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate() if not stderr: @@ -288,21 +284,21 @@ source += Split( if env['SVG_RENDERER']: # svg backend source += Split( """ - svg/svg_renderer.cpp - svg/svg_generator.cpp - svg/svg_output_attributes.cpp - svg/process_symbolizers.cpp - svg/process_building_symbolizer.cpp - svg/process_line_pattern_symbolizer.cpp - svg/process_line_symbolizer.cpp - svg/process_markers_symbolizer.cpp - svg/process_point_symbolizer.cpp - svg/process_polygon_pattern_symbolizer.cpp - svg/process_polygon_symbolizer.cpp - svg/process_raster_symbolizer.cpp - svg/process_shield_symbolizer.cpp - svg/process_text_symbolizer.cpp - """) + svg/svg_renderer.cpp + svg/svg_generator.cpp + svg/svg_output_attributes.cpp + svg/process_symbolizers.cpp + svg/process_building_symbolizer.cpp + svg/process_line_pattern_symbolizer.cpp + svg/process_line_symbolizer.cpp + svg/process_markers_symbolizer.cpp + svg/process_point_symbolizer.cpp + svg/process_polygon_pattern_symbolizer.cpp + svg/process_polygon_symbolizer.cpp + svg/process_raster_symbolizer.cpp + svg/process_shield_symbolizer.cpp + svg/process_text_symbolizer.cpp + """) lib_env.Append(CXXFLAGS = '-DSVG_RENDERER') libmapnik_cxxflags.append('-DSVG_RENDERER') From e48057b274599bbc66e18ecbb091a6a5a197380c Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 25 Jul 2012 10:00:58 +0100 Subject: [PATCH 38/66] + remove unused member variable + format --- include/mapnik/text_placements/dummy.hpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/include/mapnik/text_placements/dummy.hpp b/include/mapnik/text_placements/dummy.hpp index 0a67744b8..fd58c8b4c 100644 --- a/include/mapnik/text_placements/dummy.hpp +++ b/include/mapnik/text_placements/dummy.hpp @@ -22,33 +22,36 @@ #ifndef PLACEMENTS_DUMMY_HPP #define PLACEMENTS_DUMMY_HPP +// mapnik #include #include +// boost +#include namespace mapnik { class text_placements_info_dummy; -/** Dummy placement algorithm. Always takes the default value. */ +// Dummy placement algorithm. Always takes the default value. class MAPNIK_DECL text_placements_dummy: public text_placements { public: - text_placement_info_ptr get_placement_info(double scale_factor) const; - friend class text_placement_info_dummy; +text_placement_info_ptr get_placement_info(double scale_factor) const; +friend class text_placement_info_dummy; }; -/** Placement info object for dummy placement algorithm. Always takes the default value. */ +// Placement info object for dummy placement algorithm. Always takes the default value. class MAPNIK_DECL text_placement_info_dummy : public text_placement_info { public: - text_placement_info_dummy(text_placements_dummy const* parent, double scale_factor) - : text_placement_info(parent, scale_factor), - state(0), parent_(parent) {} +text_placement_info_dummy(text_placements_dummy const* parent, double scale_factor) + : text_placement_info(parent, scale_factor), + state(0) {} + bool next(); private: - unsigned state; - text_placements_dummy const* parent_; +unsigned state; }; } //ns mapnik From 774e1b1d77a7dffc700044c8a30b39511dc14286 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 25 Jul 2012 11:43:43 +0100 Subject: [PATCH 39/66] + avoid applying scaling_factor twice for raster markers + cleanup --- src/agg/process_markers_symbolizer.cpp | 31 ++++++++++---------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index 11f90def7..d57b22b11 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -142,26 +142,18 @@ private: }; template -void render_raster_marker(Rasterizer & ras, RendererBuffer & renb, agg::scanline_u8 & sl, - pixel_position const& pos, image_data_32 const& src, - agg::trans_affine const& tr,double opacity, - double scale_factor) +void render_raster_marker(Rasterizer & ras, RendererBuffer & renb, + agg::scanline_u8 & sl, image_data_32 const& src, + agg::trans_affine const& marker_tr, double opacity) { double width = src.width(); double height = src.height(); double p[8]; - p[0] = pos.x; p[1] = pos.y; - p[2] = pos.x + width; p[3] = pos.y; - p[4] = pos.x + width; p[5] = pos.y + height; - p[6] = pos.x; p[7] = pos.y + height; - - agg::trans_affine marker_tr; - - marker_tr *= agg::trans_affine_translation(-pos.x,-pos.y); - marker_tr *= tr; - marker_tr *= agg::trans_affine_scaling(scale_factor); - marker_tr *= agg::trans_affine_translation(pos.x,pos.y); + p[0] = 0; p[1] = 0; + p[2] = width; p[3] = 0; + p[4] = width; p[5] = height; + p[6] = 0; p[7] = height; marker_tr.transform(&p[0], &p[1]); marker_tr.transform(&p[2], &p[3]); @@ -244,8 +236,8 @@ struct raster_markers_rasterizer_dispatch detector_.has_placement(transformed_bbox)) { - render_raster_marker(ras_, renb_, sl_, pixel_position(x,y), src_, - marker_trans_, sym_.get_opacity(), scale_factor_); + render_raster_marker(ras_, renb_, sl_, src_, + matrix, sym_.get_opacity()); if (!sym_.get_ignore_placement()) detector_.insert(transformed_bbox); } @@ -261,8 +253,9 @@ struct raster_markers_rasterizer_dispatch { agg::trans_affine matrix = marker_trans_; matrix.rotate(angle); - render_raster_marker(ras_, renb_, sl_, pixel_position(x,y), src_, - matrix, sym_.get_opacity(), scale_factor_); + matrix.translate(x,y); + render_raster_marker(ras_, renb_, sl_, src_, + matrix, sym_.get_opacity()); } } } From b68ea3bb1d75e1f2cda1bfda26c7dc9fe4251184 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 08:47:10 -0700 Subject: [PATCH 40/66] new patch from @lightmare for protecting against expression.to_string misusage - closes #1232 --- include/mapnik/expression_string.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/mapnik/expression_string.hpp b/include/mapnik/expression_string.hpp index aae6fa09e..dcf333815 100644 --- a/include/mapnik/expression_string.hpp +++ b/include/mapnik/expression_string.hpp @@ -36,7 +36,7 @@ MAPNIK_DECL std::string to_expression_string(expr_node const& node); /* The following two templates are intentionally invalid and will prompt -a compile error if ever instanciated. This should prevent accidentally +a compile error if ever instantiated. This should prevent accidentally passing a pointer (either raw or shared) as the argument. Without them, the compiler could construct a temporary expr_node(bool) using implicit pointer-to-bool conversion, thus any non-null pointer @@ -44,19 +44,19 @@ would yield "true". */ template -std::string to_expression_string(T const* x) +std::string to_expression_string(T const* expr_node_ptr) { - x = 0; throw std::logic_error("to_expression_string() called with pointer argument"); - return std::string(); + // compile error intended here; comment on the next line shows in clang output + return expr_node_ptr; // to_expression_string() called with pointer argument } template -std::string to_expression_string(boost::shared_ptr const& x) +std::string to_expression_string(boost::shared_ptr const& expr_node_ptr) { - x = 0; throw std::logic_error("to_expression_string() called with pointer argument"); - return std::string(); + // compile error intended here; comment on the next line shows in clang output + return expr_node_ptr; // to_expression_string() called with pointer argument } } From 6df998cf39ee8fb733537fcc5890dd22b5b3a76a Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 09:29:21 -0700 Subject: [PATCH 41/66] fixup various plugin includes --- plugins/input/geos/geos_featureset.cpp | 3 --- plugins/input/kismet/kismet_featureset.hpp | 2 ++ plugins/input/occi/occi_featureset.cpp | 1 - plugins/input/ogr/ogr_featureset.cpp | 1 - plugins/input/ogr/ogr_index_featureset.cpp | 1 - plugins/input/raster/raster_featureset.cpp | 3 +-- plugins/input/rasterlite/rasterlite_featureset.cpp | 1 - plugins/input/sqlite/sqlite_featureset.cpp | 1 - 8 files changed, 3 insertions(+), 10 deletions(-) diff --git a/plugins/input/geos/geos_featureset.cpp b/plugins/input/geos/geos_featureset.cpp index d3058a989..08b1e44ca 100644 --- a/plugins/input/geos/geos_featureset.cpp +++ b/plugins/input/geos/geos_featureset.cpp @@ -40,15 +40,12 @@ using mapnik::query; using mapnik::box2d; -using mapnik::coord2d; -using mapnik::CoordTransform; using mapnik::Feature; using mapnik::feature_ptr; using mapnik::geometry_utils; using mapnik::transcoder; using mapnik::feature_factory; - geos_featureset::geos_featureset(GEOSGeometry* geometry, GEOSGeometry* extent, int identifier, diff --git a/plugins/input/kismet/kismet_featureset.hpp b/plugins/input/kismet/kismet_featureset.hpp index 7fd1ba551..2982ac927 100644 --- a/plugins/input/kismet/kismet_featureset.hpp +++ b/plugins/input/kismet/kismet_featureset.hpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include // boost #include diff --git a/plugins/input/occi/occi_featureset.cpp b/plugins/input/occi/occi_featureset.cpp index 55203bd8e..8717f6e73 100644 --- a/plugins/input/occi/occi_featureset.cpp +++ b/plugins/input/occi/occi_featureset.cpp @@ -37,7 +37,6 @@ using mapnik::query; using mapnik::box2d; -using mapnik::CoordTransform; using mapnik::Feature; using mapnik::feature_ptr; using mapnik::geometry_type; diff --git a/plugins/input/ogr/ogr_featureset.cpp b/plugins/input/ogr/ogr_featureset.cpp index 2d675c964..e40225776 100644 --- a/plugins/input/ogr/ogr_featureset.cpp +++ b/plugins/input/ogr/ogr_featureset.cpp @@ -39,7 +39,6 @@ using mapnik::query; using mapnik::box2d; -using mapnik::CoordTransform; using mapnik::Feature; using mapnik::feature_ptr; using mapnik::geometry_utils; diff --git a/plugins/input/ogr/ogr_index_featureset.cpp b/plugins/input/ogr/ogr_index_featureset.cpp index 98cb9da3b..3f28395aa 100644 --- a/plugins/input/ogr/ogr_index_featureset.cpp +++ b/plugins/input/ogr/ogr_index_featureset.cpp @@ -44,7 +44,6 @@ using mapnik::query; using mapnik::box2d; -using mapnik::CoordTransform; using mapnik::Feature; using mapnik::feature_ptr; using mapnik::geometry_utils; diff --git a/plugins/input/raster/raster_featureset.cpp b/plugins/input/raster/raster_featureset.cpp index b39bf237b..affe873be 100644 --- a/plugins/input/raster/raster_featureset.cpp +++ b/plugins/input/raster/raster_featureset.cpp @@ -33,7 +33,6 @@ #include "raster_featureset.hpp" using mapnik::query; -using mapnik::CoordTransform; using mapnik::image_reader; using mapnik::Feature; using mapnik::feature_ptr; @@ -81,7 +80,7 @@ feature_ptr raster_featureset::next() if (image_width > 0 && image_height > 0) { - CoordTransform t(image_width, image_height, extent_, 0, 0); + mapnik::CoordTransform t(image_width, image_height, extent_, 0, 0); box2d intersect = bbox_.intersect(curIter_->envelope()); box2d ext = t.forward(intersect); box2d rem = policy_.transform(ext); diff --git a/plugins/input/rasterlite/rasterlite_featureset.cpp b/plugins/input/rasterlite/rasterlite_featureset.cpp index 772ccc3fa..46817784a 100644 --- a/plugins/input/rasterlite/rasterlite_featureset.cpp +++ b/plugins/input/rasterlite/rasterlite_featureset.cpp @@ -36,7 +36,6 @@ using mapnik::coord2d; using mapnik::box2d; using mapnik::Feature; using mapnik::feature_ptr; -using mapnik::CoordTransform; using mapnik::geometry_type; using mapnik::query; using mapnik::feature_factory; diff --git a/plugins/input/sqlite/sqlite_featureset.cpp b/plugins/input/sqlite/sqlite_featureset.cpp index df2203710..d4e698db8 100644 --- a/plugins/input/sqlite/sqlite_featureset.cpp +++ b/plugins/input/sqlite/sqlite_featureset.cpp @@ -38,7 +38,6 @@ using mapnik::query; using mapnik::box2d; -using mapnik::CoordTransform; using mapnik::Feature; using mapnik::feature_ptr; using mapnik::geometry_utils; From 2680f941eb1202902b090dcf72e32f5c9631fb23 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 09:31:57 -0700 Subject: [PATCH 42/66] clean up unused code and includes --- include/mapnik/ctrans.hpp | 21 --------------------- include/mapnik/datasource.hpp | 1 - include/mapnik/offset_converter.hpp | 1 - include/mapnik/wkb.hpp | 3 +-- src/wkb.cpp | 4 ++++ 5 files changed, 5 insertions(+), 25 deletions(-) diff --git a/include/mapnik/ctrans.hpp b/include/mapnik/ctrans.hpp index c1cc2f926..a06872422 100644 --- a/include/mapnik/ctrans.hpp +++ b/include/mapnik/ctrans.hpp @@ -27,7 +27,6 @@ #include #include #include -#include #include // stl @@ -36,8 +35,6 @@ namespace mapnik { -typedef coord_array CoordinateArray; - template struct MAPNIK_DECL coord_transform { @@ -228,24 +225,6 @@ public: return box2d(x0, y0, x1, y1); } - inline CoordinateArray& forward(CoordinateArray& coords) const - { - for (unsigned i = 0; i < coords.size(); ++i) - { - forward(coords[i]); - } - return coords; - } - - inline CoordinateArray& backward(CoordinateArray& coords) const - { - for (unsigned i = 0; i < coords.size(); ++i) - { - backward(coords[i]); - } - return coords; - } - inline box2d const& extent() const { return extent_; diff --git a/include/mapnik/datasource.hpp b/include/mapnik/datasource.hpp index 127265377..b9c13f47b 100644 --- a/include/mapnik/datasource.hpp +++ b/include/mapnik/datasource.hpp @@ -25,7 +25,6 @@ // mapnik #include -#include #include #include #include diff --git a/include/mapnik/offset_converter.hpp b/include/mapnik/offset_converter.hpp index 7005d9d03..ed7f074b2 100644 --- a/include/mapnik/offset_converter.hpp +++ b/include/mapnik/offset_converter.hpp @@ -26,7 +26,6 @@ #include #include #include -#include #include // boost diff --git a/include/mapnik/wkb.hpp b/include/mapnik/wkb.hpp index 38fa2b259..5f546fe69 100644 --- a/include/mapnik/wkb.hpp +++ b/include/mapnik/wkb.hpp @@ -25,8 +25,7 @@ // mapnik #include -#include -#include + // boost #include diff --git a/src/wkb.cpp b/src/wkb.cpp index a26122a88..1d800fd44 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,9 @@ namespace mapnik { + +typedef coord_array CoordinateArray; + struct wkb_reader : boost::noncopyable { private: From cc8f86e873d51ec33e028fca6a1c7027a206b62f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 11:14:23 -0700 Subject: [PATCH 43/66] ensure simple invalid inputs to wkb do not crash - closes #1333 --- tests/python_tests/geometry_io_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/python_tests/geometry_io_test.py b/tests/python_tests/geometry_io_test.py index 1eeef4db6..d93b72605 100644 --- a/tests/python_tests/geometry_io_test.py +++ b/tests/python_tests/geometry_io_test.py @@ -54,6 +54,10 @@ wkbs = [ [ 1, "GEOMETRYCOLLECTION(POINT EMPTY,MULTIPOINT(0 0))", '010700000002000000010400000000000000010400000001000000010100000000000000000000000000000000000000'], [ 0, "LINESTRING EMPTY", '010200000000000000' ], [ 1, "Point(0 0)", '010100000000000000000000000000000000000000' ], + # a few bogus inputs + [ 0, "", '' ], + [ 0, "00", '01' ], + [ 0, "0000", '0104' ], ] def test_wkb_parsing(): From b298e21f8e49b82accd0be63dadf4e5f01e0894d Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 13:16:46 -0700 Subject: [PATCH 44/66] add test for #997- closes #997 --- tests/data/good_maps/raster-alpha-gradient.xml | 8 ++++---- tests/data/good_maps/raster-alpha.xml | 2 +- .../images/support/raster-alpha-gradient.png | Bin 0 -> 72010 bytes tests/python_tests/raster_alpha_test.py | 12 ++++++++++++ 4 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 tests/python_tests/images/support/raster-alpha-gradient.png diff --git a/tests/data/good_maps/raster-alpha-gradient.xml b/tests/data/good_maps/raster-alpha-gradient.xml index a3638cf87..b906668f2 100644 --- a/tests/data/good_maps/raster-alpha-gradient.xml +++ b/tests/data/good_maps/raster-alpha-gradient.xml @@ -1,15 +1,15 @@ - + - - - white + transp ../raster/transp.tiff gdal diff --git a/tests/data/good_maps/raster-alpha.xml b/tests/data/good_maps/raster-alpha.xml index 163bd463c..9ac1422ca 100644 --- a/tests/data/good_maps/raster-alpha.xml +++ b/tests/data/good_maps/raster-alpha.xml @@ -2,7 +2,7 @@ - + + + + + countries + + ../../data/shp/ne_110m_admin_0_countries.shp + shape + + + + + style + + + x,y + -170,20 + -122,48 + -122.2,48.2 + -122.2,48.2 + -122.3,48.3 + -122.1,48.4 + -122.1,48.2 + -115,36 + 90,30 + 0,0 + 1,1 + 10,10 + -10,-10 + -20,-20 + + csv + + + + \ No newline at end of file diff --git a/tests/data/images/marker.png b/tests/data/images/marker.png new file mode 100644 index 0000000000000000000000000000000000000000..3e3ea29678bd1307e965c3d1e387e1394be15b9b GIT binary patch literal 1803 zcmV+m2lV)fP)Yz5K}?wnND^Q?01&H7P$ZR% z0FmMbf`GaNu!quS0wTF74&sX${>uTTINa8LLGU>Ua#z&>;;B5AT$t#(?gEk&Wk>+} zsTG5hPc8GxVw{r~{9$4DtWmW%@FjrQ$;p*`kMxKa)S zDKFaB&_-GXxG@e#Qp)~%`+Mx~&0W?$W$0YOh39p1A%4$>4(hLx*CrqmjdCNL=uSXP)kwfCX!Oh0flJK^(?cX zm1pj@l5m0C0t6)`EFhkE)q;Q&5S*nMdUeJO1fwu8R#L|8K(Ya5QFaDL0=}dY50FK1 zQxb&2U{uF807~k+%w;8~Lb78&y?|k{=E_hUk>ZC1V-pln2ln@^{r+}W4AB5BMrh5Ty26PM%^(Ru5!VMqewKPk7zYZ?p1Wst^kb%F)$gjFq<~tpMllYTOu%*3GQ7 zefovY%`-maw$7TVqpWlUNQyP1Zmx&Ifgl*(pYTe(utOowp9M2 zC1p-+0LbvtLLW-i*_^ArQgWMBVle9F zEI^k9b#H*y3M&x|D}UF!AEKpF ztv*-R6JzRtTG|Xi&>pola?-NdH6tI%%j(_KlW^HVb&kj+wX{2dkYi$}fv|Ss2*5@; zx|%{zEYV60tf8_sv7|eIAa!H_!*e5mq`1UN$8&pEppqxq)l$|3Q&P!oK=zq3Qb$#` zYSTc>SP7RDSU^za)YFJ5TEJh8dC4t6NLl#H9gJ0(TV#jw_~`6NeTX*VdO8FBs?1kT zxt&u~P)$}r6*Yz*T4P8QRk%}C;qC^BI`xTw5XGGwXf_~3aj%of56Ld?+dD{Yeik>JGd7)}C&!$Bba?_c_i_QI;S2`dDUXsG=WU;uh!M`nk%rC|U7002ovPDHLkV1kchKDGb= literal 0 HcmV?d00001 From 4ad15db23d976ead675e5652eaff4259f122227b Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 16:11:51 -0700 Subject: [PATCH 48/66] collect attribute descriptions in geojson plugin (TODO: sorting of attributes is returned in reverse order) --- plugins/input/geojson/geojson_datasource.cpp | 53 ++++++++++++++-- plugins/input/geojson/geojson_datasource.hpp | 1 - tests/python_tests/geojson_plugin_test.py | 65 ++++++++++++++++++++ 3 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 tests/python_tests/geojson_plugin_test.py diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 58354b6f8..70e86ec50 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -25,7 +25,10 @@ #include #include +#include + // boost +#include #include #include #include @@ -64,6 +67,44 @@ geojson_datasource::geojson_datasource(parameters const& params, bool bind) } } +struct attr_value_converter : public boost::static_visitor +{ + mapnik::eAttributeType operator() (int /*val*/) const + { + return mapnik::Integer; + } + + mapnik::eAttributeType operator() (double /*val*/) const + { + return mapnik::Double; + } + + mapnik::eAttributeType operator() (float /*val*/) const + { + return mapnik::Double; + } + + mapnik::eAttributeType operator() (bool /*val*/) const + { + return mapnik::Boolean; + } + + mapnik::eAttributeType operator() (std::string const& /*val*/) const + { + return mapnik::String; + } + + mapnik::eAttributeType operator() (UnicodeString const& /*val*/) const + { + return mapnik::String; + } + + mapnik::eAttributeType operator() (mapnik::value_null const& /*val*/) const + { + return mapnik::String; + } +}; + void geojson_datasource::bind() const { if (is_bound_) return; @@ -95,6 +136,13 @@ void geojson_datasource::bind() const { extent_ = box; first = false; + mapnik::feature_kv_iterator itr = f->begin(); + mapnik::feature_kv_iterator end = f->end(); + for ( ;itr!=end; ++itr) + { + desc_.add_descriptor(mapnik::attribute_descriptor(boost::get<0>(*itr), + boost::apply_visitor(attr_value_converter(),boost::get<1>(*itr).base()))); + } } else { @@ -122,11 +170,6 @@ mapnik::datasource::datasource_t geojson_datasource::type() const return type_; } -std::map geojson_datasource::get_statistics() const -{ - return statistics_; -} - mapnik::box2d geojson_datasource::envelope() const { if (!is_bound_) bind(); diff --git a/plugins/input/geojson/geojson_datasource.hpp b/plugins/input/geojson/geojson_datasource.hpp index 9f9ce42d0..14fd9af0f 100644 --- a/plugins/input/geojson/geojson_datasource.hpp +++ b/plugins/input/geojson/geojson_datasource.hpp @@ -64,7 +64,6 @@ public: mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::box2d envelope() const; mapnik::layer_descriptor get_descriptor() const; - std::map get_statistics() const; boost::optional get_geometry_type() const; void bind() const; private: diff --git a/tests/python_tests/geojson_plugin_test.py b/tests/python_tests/geojson_plugin_test.py new file mode 100644 index 000000000..0706fd8e5 --- /dev/null +++ b/tests/python_tests/geojson_plugin_test.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from nose.tools import * +from utilities import execution_path + +import os, mapnik + +def setup(): + # All of the paths used are relative, if we run the tests + # from another directory we need to chdir() + os.chdir(execution_path('.')) + +if 'geojson' in mapnik.DatasourceCache.instance().plugin_names(): + + def test_geojson_init(): + s = mapnik.Datasource(type='geojson',file='../data/json/escaped.json') + e = s.envelope() + assert_almost_equal(e.minx, -81.705583, places=7) + assert_almost_equal(e.miny, 41.480573, places=6) + assert_almost_equal(e.maxx, -81.705583, places=5) + assert_almost_equal(e.maxy, 41.480573, places=3) + + def test_geojson_properties(): + s = mapnik.Datasource(type='geojson',file='../data/json/escaped.json') + f = s.features_at_point(s.envelope().center()).features[0] + + eq_(f['name'], u'test') + eq_(f['description'], u'Test: \u005C') + eq_(f['int'], 1) + eq_(f['double'], u'Quebec') + eq_(f['boolean'], True) + eq_(f['NOM_FR'], u'Qu\xe9bec') + eq_(f['NOM_FR'], u'Québec') + + def test_geojson_properties(): + s = mapnik.Datasource(type='geojson',file='../data/json/escaped.json') + f = s.all_features()[0] + + eq_(f['name'], u'Test') + eq_(f['int'], 1) + eq_(f['double'], 1.1) + eq_(f['boolean'], True) + eq_(f['NOM_FR'], u'Qu\xe9bec') + eq_(f['NOM_FR'], u'Québec') + #eq_(f['description'], u'Test: \u005C') + +# @raises(RuntimeError) + def test_that_nonexistant_query_field_throws(**kwargs): + ds = mapnik.Datasource(type='geojson',file='../data/json/escaped.json') + eq_(len(ds.fields()),6) + # TODO - this sorting is messed up + eq_(ds.fields(),['name', 'int', 'double', 'description', 'boolean', 'NOM_FR']) + eq_(ds.field_types(),['str', 'int', 'float', 'str', 'bool', 'str']) +# TODO - should geojson plugin throw like others? +# query = mapnik.Query(ds.envelope()) +# for fld in ds.fields(): +# query.add_property_name(fld) +# # also add an invalid one, triggering throw +# query.add_property_name('bogus') +# fs = ds.features(query) + +if __name__ == "__main__": + setup() + [eval(run)() for run in dir() if 'test_' in run] From 3da72ff8cb6d3ff871c1ef880eb6b771b2a14b08 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 16:37:05 -0700 Subject: [PATCH 49/66] unmask failing test - refs #1345 --- tests/data/json/escaped.json | 28 +++++++++++++++++++++++ tests/python_tests/geojson_plugin_test.py | 9 ++++---- 2 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 tests/data/json/escaped.json diff --git a/tests/data/json/escaped.json b/tests/data/json/escaped.json new file mode 100644 index 000000000..bb7ce918b --- /dev/null +++ b/tests/data/json/escaped.json @@ -0,0 +1,28 @@ +{ + "type":"FeatureCollection", + "features": + [ + { + "type":"Feature", + "geometry": + { + "type":"Point", + "coordinates": + [ + -81.705583, + 41.480573 + ] + }, + "properties": + { + "name":"Test", + "int":1, + "description":"Test: \u005C", + "spaces":"this has spaces", + "double":1.1, + "boolean":true, + "NOM_FR":"Québec" + } + } + ] +} \ No newline at end of file diff --git a/tests/python_tests/geojson_plugin_test.py b/tests/python_tests/geojson_plugin_test.py index 0706fd8e5..f13b83f3f 100644 --- a/tests/python_tests/geojson_plugin_test.py +++ b/tests/python_tests/geojson_plugin_test.py @@ -43,15 +43,16 @@ if 'geojson' in mapnik.DatasourceCache.instance().plugin_names(): eq_(f['boolean'], True) eq_(f['NOM_FR'], u'Qu\xe9bec') eq_(f['NOM_FR'], u'Québec') - #eq_(f['description'], u'Test: \u005C') + eq_(f['spaces'], u'this has spaces') + eq_(f['description'], u'Test: \u005C') # @raises(RuntimeError) def test_that_nonexistant_query_field_throws(**kwargs): ds = mapnik.Datasource(type='geojson',file='../data/json/escaped.json') - eq_(len(ds.fields()),6) + eq_(len(ds.fields()),7) # TODO - this sorting is messed up - eq_(ds.fields(),['name', 'int', 'double', 'description', 'boolean', 'NOM_FR']) - eq_(ds.field_types(),['str', 'int', 'float', 'str', 'bool', 'str']) + #eq_(ds.fields(),['name', 'int', 'double', 'description', 'boolean', 'NOM_FR']) + #eq_(ds.field_types(),['str', 'int', 'float', 'str', 'bool', 'str']) # TODO - should geojson plugin throw like others? # query = mapnik.Query(ds.envelope()) # for fld in ds.fields(): From 827b015d15715fc37d6c5e2ad437750bc7b49c0f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 16:57:47 -0700 Subject: [PATCH 50/66] add a geometry collection to csv wkt test --- tests/data/csv/wkt.csv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/data/csv/wkt.csv b/tests/data/csv/wkt.csv index 201ff899b..e276bf8ce 100644 --- a/tests/data/csv/wkt.csv +++ b/tests/data/csv/wkt.csv @@ -6,4 +6,5 @@ polygon, "POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 multipoint, "MULTIPOINT ((10 40), (40 30), (20 20), (30 10))" multilinestring, "MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))" multipolygon, "MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))" -multipolygon, "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),(30 20, 20 25, 20 15, 30 20)))" \ No newline at end of file +multipolygon, "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),(30 20, 20 25, 20 15, 30 20)))" +collection, "GEOMETRYCOLLECTION(POLYGON((1 1,2 1,2 2,1 2,1 1)),POINT(2 3),LINESTRING(2 3,3 4))" \ No newline at end of file From 5bd0bec0e9368625a5dc43f63f1c6aee2c04ed3e Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 16:58:45 -0700 Subject: [PATCH 51/66] add render target --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index d88e216bb..9ed95ef70 100755 --- a/Makefile +++ b/Makefile @@ -38,4 +38,9 @@ grind: valgrind --leak-check=full --log-fd=1 $${FILE} | grep definitely; \ done +render: + @for FILE in tests/data/good_maps/*xml; do \ + nik2img.py $${FILE} /tmp/$$(basename $${FILE}).png; \ + done + .PHONY: clean reset uninstall test install From 9f064960e360a52a1453f2ce2e11b72a0e65a51b Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 18:19:41 -0700 Subject: [PATCH 52/66] load_map: a stroke-width=0 is valid for markers now (for restyling svg) --- src/load_map.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/load_map.cpp b/src/load_map.cpp index b23545a90..fce62fa79 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -1055,8 +1055,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node) if (height) sym.set_height(*height); stroke strk; - if (parse_stroke(strk,node)) - sym.set_stroke(strk); + sym.set_stroke(strk); marker_placement_e placement = node.get_attr("placement", MARKER_POINT_PLACEMENT); sym.set_marker_placement(placement); @@ -1302,7 +1301,6 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym) bool map_parser::parse_stroke(stroke & strk, xml_node const & sym) { - bool result = false; // stroke color optional c = sym.get_opt_attr("stroke"); if (c) @@ -1313,7 +1311,7 @@ bool map_parser::parse_stroke(stroke & strk, xml_node const & sym) // stroke-width optional width = sym.get_opt_attr("stroke-width"); - if (width && *width > 0) + if (width) { strk.set_width(*width); result = true; From bd74d18f6d648dd3f4b197000f79c6490474b296 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 18:26:34 -0700 Subject: [PATCH 53/66] no need anymore to have parse_stroke return a bool --- src/load_map.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/load_map.cpp b/src/load_map.cpp index fce62fa79..da47c6640 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -111,7 +111,7 @@ private: void parse_markers_symbolizer(rule & rule, xml_node const& sym); void parse_raster_colorizer(raster_colorizer_ptr const& rc, xml_node const& node); - bool parse_stroke(stroke & strk, xml_node const & sym); + void parse_stroke(stroke & strk, xml_node const & sym); void ensure_font_face(std::string const& face_name); void find_unused_nodes(xml_node const& root); @@ -1055,6 +1055,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node) if (height) sym.set_height(*height); stroke strk; + parse_stroke(strk,node); sym.set_stroke(strk); marker_placement_e placement = node.get_attr("placement", MARKER_POINT_PLACEMENT); @@ -1299,22 +1300,20 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym) } } -bool map_parser::parse_stroke(stroke & strk, xml_node const & sym) +void map_parser::parse_stroke(stroke & strk, xml_node const & sym) { // stroke color optional c = sym.get_opt_attr("stroke"); if (c) { strk.set_color(*c); - result = true; } // stroke-width - optional width = sym.get_opt_attr("stroke-width"); + optional width = sym.get_opt_attr("stroke-width"); if (width) { strk.set_width(*width); - result = true; } // stroke-opacity @@ -1374,7 +1373,6 @@ bool map_parser::parse_stroke(stroke & strk, xml_node const & sym) // stroke-miterlimit optional miterlimit = sym.get_opt_attr("stroke-miterlimit"); if (miterlimit) strk.set_miterlimit(*miterlimit); - return result; } void map_parser::parse_line_symbolizer(rule & rule, xml_node const & sym) From 4fbe353d4a754206ad84a19c31cd6a04d89e7cc0 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 25 Jul 2012 19:29:43 -0700 Subject: [PATCH 54/66] make stock ellipse a true ellipse --- src/marker_cache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/marker_cache.cpp b/src/marker_cache.cpp index 42be35040..c50a59026 100644 --- a/src/marker_cache.cpp +++ b/src/marker_cache.cpp @@ -54,7 +54,7 @@ marker_cache::marker_cache() insert_svg("ellipse", "" "" - "" + "" ""); insert_svg("arrow", "" From 07ec5c31d0289fb3ddd38224c57ac8a7edbed230 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 26 Jul 2012 11:45:34 +0100 Subject: [PATCH 55/66] + turns off white space skipping --- src/json/feature_grammar.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/json/feature_grammar.cpp b/src/json/feature_grammar.cpp index 59be9386e..8c6386422 100644 --- a/src/json/feature_grammar.cpp +++ b/src/json/feature_grammar.cpp @@ -99,10 +99,13 @@ feature_grammar::feature_grammar(mapnik::transcoder const& ("\\r", '\r') // carrige return ("\\t", '\t') // tab ; - - string_ %= lit('"') >> *(unesc_char | "\\u" >> hex4 | (char_ - lit('"'))) >> lit('"') +#if BOOST_VERSION > 104200 + string_ %= lit('"') >> no_skip[*(unesc_char | "\\u" >> hex4 | (char_ - lit('"')))] >> lit('"') ; - +#else + string_ %= lit('"') >> lexeme[*(unesc_char | "\\u" >> hex4 | (char_ - lit('"')))] >> lit('"') + ; +#endif // geojson types feature_type = lit("\"type\"") @@ -224,4 +227,4 @@ feature_grammar::feature_grammar(mapnik::transcoder const& template struct mapnik::json::feature_grammar; template struct mapnik::json::feature_grammar >,mapnik::Feature>; -}} \ No newline at end of file +}} From 690b56a511b1db0565d8c315eef8de916a891375 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 26 Jul 2012 11:57:41 +0100 Subject: [PATCH 56/66] + use std::auto_ptr --- plugins/input/shape/shape_io.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index 7b8c27fe3..123485b03 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -107,7 +107,7 @@ void shape_io::read_polyline(mapnik::geometry_container & geom) int num_points = record.read_ndr_integer(); if (num_parts == 1) { - geometry_type* line = new geometry_type(mapnik::LineString); + std::auto_ptr line(new geometry_type(mapnik::LineString)); record.skip(4); double x = record.read_double(); double y = record.read_double(); @@ -131,7 +131,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); + std::auto_ptr line(new geometry_type(mapnik::LineString)); start = parts[k]; if (k == num_parts - 1) { @@ -190,7 +190,7 @@ void shape_io::read_polygon(mapnik::geometry_container & geom) for (int k = 0; k < num_parts; k++) { - geometry_type* poly = new geometry_type(mapnik::Polygon); + std::auto_ptr poly(new geometry_type(mapnik::Polygon)); int start = parts[k]; int end; if (k == num_parts - 1) From 4ddddba2544377aae2271a051fae91a1d37c0d67 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 26 Jul 2012 11:58:48 +0100 Subject: [PATCH 57/66] + use pre-increment op --- plugins/input/shape/shape_io.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index 123485b03..f757a7a77 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -188,7 +188,7 @@ void shape_io::read_polygon(mapnik::geometry_container & geom) parts[i] = record.read_ndr_integer(); } - for (int k = 0; k < num_parts; k++) + for (int k = 0; k < num_parts; ++k) { std::auto_ptr poly(new geometry_type(mapnik::Polygon)); int start = parts[k]; From 1844217615f9b6af358b8b45752b811cd21c0919 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 26 Jul 2012 15:19:11 +0100 Subject: [PATCH 58/66] + fix SEG_CLOSE value to be compatible with agg --- include/mapnik/vertex.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mapnik/vertex.hpp b/include/mapnik/vertex.hpp index 09cbb64bf..306758ba4 100644 --- a/include/mapnik/vertex.hpp +++ b/include/mapnik/vertex.hpp @@ -29,10 +29,10 @@ namespace mapnik { enum CommandType { - SEG_END =0, - SEG_MOVETO=1, - SEG_LINETO=2, - SEG_CLOSE =3 + SEG_END = 0, + SEG_MOVETO = 1, + SEG_LINETO = 2, + SEG_CLOSE = (0x40 | 0x0f) }; template From 618bc1ba0f93dd4df89b671cb966669eefa88a96 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 26 Jul 2012 15:20:23 +0100 Subject: [PATCH 59/66] + close polygon --- plugins/input/shape/shape_io.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index f757a7a77..ac2c7e01b 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -206,12 +206,16 @@ void shape_io::read_polygon(mapnik::geometry_container & geom) double y = record.read_double(); poly->move_to(x, y); - for (int j=start+1;jline_to(x, y); } + x = record.read_double(); + y = record.read_double(); + poly->close(x, y); + geom.push_back(poly); } // z-range From ec2d0cc21069e13609f14b0d6ee5bda122be416e Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 26 Jul 2012 15:20:56 +0100 Subject: [PATCH 60/66] + wkb reader : close polygons --- src/wkb.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wkb.cpp b/src/wkb.cpp index 1d800fd44..2e57b8600 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -353,10 +353,11 @@ private: CoordinateArray ar(num_points); read_coords(ar); poly->move_to(ar[0].x, ar[0].y); - for (int j = 1; j < num_points; ++j) + for (int j = 1; j < num_points - 1; ++j) { poly->line_to(ar[j].x, ar[j].y); } + poly->close(ar[num_points-1].x, ar[num_points-1].y); } } if (poly->size() > 2) // ignore if polygon has less than 3 vertices @@ -388,10 +389,11 @@ private: CoordinateArray ar(num_points); read_coords_xyz(ar); poly->move_to(ar[0].x, ar[0].y); - for (int j = 1; j < num_points; ++j) + for (int j = 1; j < num_points - 1; ++j) { poly->line_to(ar[j].x, ar[j].y); } + poly->close(ar[num_points-1].x, ar[num_points-1].y); } } if (poly->size() > 2) // ignore if polygon has less than 3 vertices From 1b805abc23bb40b98114472ace8aa92f5dcf8efc Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 26 Jul 2012 15:21:25 +0100 Subject: [PATCH 61/66] + add close(x,y) method to geometry --- include/mapnik/geometry.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 31bfeb337..3a7bc2db1 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -121,6 +121,11 @@ public: push_vertex(x,y,SEG_MOVETO); } + void close(coord_type x, coord_type y) + { + push_vertex(x,y,SEG_CLOSE); + } + unsigned vertex(double* x, double* y) const { return cont_.get_vertex(itr_++,x,y); From fe4cfea53673ddf83174affa5461b2969394869a Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 26 Jul 2012 15:49:58 +0100 Subject: [PATCH 62/66] + add call to close_path() if SEG_CLOSE --- src/cairo_renderer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index 10b22cb1b..9529c9d69 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -496,6 +496,11 @@ public: { line_to(x, y); } + else if (cm == SEG_CLOSE) + { + line_to(x, y); + close_path(); + } } } From 03422de504eabd3520ee10164d71b9a937215257 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 26 Jul 2012 15:51:10 +0100 Subject: [PATCH 63/66] + close polygons (SEG_CLOSE) --- plugins/input/ogr/ogr_converter.cpp | 33 ++++++++++++++++------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/plugins/input/ogr/ogr_converter.cpp b/plugins/input/ogr/ogr_converter.cpp index ffee9cb9a..7388ff9d4 100644 --- a/plugins/input/ogr/ogr_converter.cpp +++ b/plugins/input/ogr/ogr_converter.cpp @@ -79,21 +79,21 @@ void ogr_converter::convert_geometry(OGRGeometry* geom, feature_ptr feature) void ogr_converter::convert_point(OGRPoint* geom, feature_ptr feature) { - geometry_type * point = new geometry_type(mapnik::Point); + std::auto_ptr point(new geometry_type(mapnik::Point)); point->move_to(geom->getX(), geom->getY()); - feature->add_geometry(point); + feature->paths().push_back(point); } void ogr_converter::convert_linestring(OGRLineString* geom, feature_ptr feature) { int num_points = geom->getNumPoints(); - geometry_type* line = new geometry_type(mapnik::LineString); + std::auto_ptr line(new geometry_type(mapnik::LineString)); line->move_to(geom->getX(0), geom->getY(0)); for (int i = 1; i < num_points; ++i) { line->line_to (geom->getX(i), geom->getY(i)); } - feature->add_geometry(line); + feature->paths().push_back(line); } void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature) @@ -102,34 +102,38 @@ void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature) int num_points = exterior->getNumPoints(); int num_interior = geom->getNumInteriorRings(); int capacity = 0; - for (int r = 0; r < num_interior; r++) + for (int r = 0; r < num_interior; ++r) { OGRLinearRing* interior = geom->getInteriorRing(r); capacity += interior->getNumPoints(); } - geometry_type* poly = new geometry_type(mapnik::Polygon); + + std::auto_ptr poly(new geometry_type(mapnik::Polygon)); + poly->move_to(exterior->getX(0), exterior->getY(0)); - for (int i = 1; i < num_points; ++i) + for (int i = 1; i < num_points - 1; ++i) { poly->line_to(exterior->getX(i), exterior->getY(i)); } - for (int r = 0; r < num_interior; r++) + poly->close(exterior->getX(num_points-1), exterior->getY(num_points-1)); + for (int r = 0; r < num_interior; ++r) { OGRLinearRing* interior = geom->getInteriorRing(r); num_points = interior->getNumPoints(); poly->move_to(interior->getX(0), interior->getY(0)); - for (int i = 1; i < num_points; ++i) + for (int i = 1; i < num_points - 1; ++i) { poly->line_to(interior->getX(i), interior->getY(i)); } + poly->close(interior->getX(num_points-1), interior->getY(num_points-1)); } - feature->add_geometry(poly); + feature->paths().push_back(poly); } void ogr_converter::convert_multipoint(OGRMultiPoint* geom, feature_ptr feature) { int num_geometries = geom->getNumGeometries(); - for (int i = 0; i < num_geometries; i++) + for (int i = 0; i < num_geometries; ++i) { convert_point(static_cast(geom->getGeometryRef(i)), feature); } @@ -138,7 +142,7 @@ void ogr_converter::convert_multipoint(OGRMultiPoint* geom, feature_ptr feature) void ogr_converter::convert_multilinestring(OGRMultiLineString* geom, feature_ptr feature) { int num_geometries = geom->getNumGeometries(); - for (int i = 0; i < num_geometries; i++) + for (int i = 0; i < num_geometries; ++i) { convert_linestring(static_cast(geom->getGeometryRef(i)), feature); } @@ -147,7 +151,7 @@ void ogr_converter::convert_multilinestring(OGRMultiLineString* geom, feature_pt void ogr_converter::convert_multipolygon(OGRMultiPolygon* geom, feature_ptr feature) { int num_geometries = geom->getNumGeometries(); - for (int i = 0; i < num_geometries; i++) + for (int i = 0; i < num_geometries; ++i) { convert_polygon(static_cast(geom->getGeometryRef(i)), feature); } @@ -156,7 +160,7 @@ void ogr_converter::convert_multipolygon(OGRMultiPolygon* geom, feature_ptr feat void ogr_converter::convert_collection(OGRGeometryCollection* geom, feature_ptr feature) { int num_geometries = geom->getNumGeometries(); - for (int i = 0; i < num_geometries; i++) + for (int i = 0; i < num_geometries; ++i) { OGRGeometry* g = geom->getGeometryRef(i); if (g != NULL) @@ -165,4 +169,3 @@ void ogr_converter::convert_collection(OGRGeometryCollection* geom, feature_ptr } } } - From 4340e9a60533c62d2a6948869d29d4e4d79cce25 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 27 Jul 2012 10:56:24 -0700 Subject: [PATCH 64/66] scons: fixup LIBDIR value settings - closes #1349 --- SConstruct | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/SConstruct b/SConstruct index 2b0f716e7..a46916c9e 100644 --- a/SConstruct +++ b/SConstruct @@ -32,6 +32,10 @@ try: except: HAS_DISTUTILS = False +if platform.uname()[4] == 'ppc64': + LIBDIR_SCHEMA='lib64' +else: + LIBDIR_SCHEMA='lib' py3 = None @@ -237,14 +241,6 @@ def sort_paths(items,priority): new.extend(v) return new -if platform.dist()[0] in ('Ubuntu','debian'): - LIBDIR_SCHEMA='lib' -elif platform.uname()[4] == 'ppc64': - LIBDIR_SCHEMA='lib64' -else: - LIBDIR_SCHEMA='lib' - - def pretty_dep(dep): pretty = pretty_dep_names.get(dep) if pretty: From e213f49d7cb7bdba4fbbc2e2cbdbfafbdc7722d5 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 27 Jul 2012 19:21:46 -0700 Subject: [PATCH 65/66] re-implement conditional stroke application in markers_symbolizer initially added in 9d756165e01, amended in 9f064960e360, and wrongly disabled in bd74d18f6d648dd3f4b197000f79c6490474b296 --- src/load_map.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/load_map.cpp b/src/load_map.cpp index da47c6640..7349d0f8e 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -111,7 +111,7 @@ private: 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); + bool parse_stroke(stroke & strk, xml_node const & sym); void ensure_font_face(std::string const& face_name); void find_unused_nodes(xml_node const& root); @@ -1055,8 +1055,10 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node) if (height) sym.set_height(*height); stroke strk; - parse_stroke(strk,node); - sym.set_stroke(strk); + if (parse_stroke(strk,node)) + { + sym.set_stroke(strk); + } marker_placement_e placement = node.get_attr("placement", MARKER_POINT_PLACEMENT); sym.set_marker_placement(placement); @@ -1300,12 +1302,15 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym) } } -void map_parser::parse_stroke(stroke & strk, xml_node const & sym) +bool map_parser::parse_stroke(stroke & strk, xml_node const & sym) { + bool result = false; + // stroke color optional c = sym.get_opt_attr("stroke"); if (c) { + result = true; strk.set_color(*c); } @@ -1313,12 +1318,17 @@ void map_parser::parse_stroke(stroke & strk, xml_node const & sym) optional width = sym.get_opt_attr("stroke-width"); if (width) { + result = true; strk.set_width(*width); } // stroke-opacity optional opacity = sym.get_opt_attr("stroke-opacity"); - if (opacity) strk.set_opacity(*opacity); + if (opacity) + { + result = true; + strk.set_opacity(*opacity); + } // stroke-linejoin optional line_join = sym.get_opt_attr("stroke-linejoin"); @@ -1373,6 +1383,7 @@ void map_parser::parse_stroke(stroke & strk, xml_node const & sym) // stroke-miterlimit optional miterlimit = sym.get_opt_attr("stroke-miterlimit"); if (miterlimit) strk.set_miterlimit(*miterlimit); + return result; } void map_parser::parse_line_symbolizer(rule & rule, xml_node const & sym) From 81937f7317777e7a9a262985590a2507be9c1b03 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Sat, 28 Jul 2012 09:27:37 -0700 Subject: [PATCH 66/66] only allow restyling of svg paths that already have visible display of stroke/fill --- include/mapnik/marker_helpers.hpp | 7 ++----- src/marker_cache.cpp | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/mapnik/marker_helpers.hpp b/include/mapnik/marker_helpers.hpp index fd26b8ca6..efc565fc2 100644 --- a/include/mapnik/marker_helpers.hpp +++ b/include/mapnik/marker_helpers.hpp @@ -44,18 +44,15 @@ bool push_explicit_style(Attr const& src, Attr & dst, markers_symbolizer const& { mapnik::svg::path_attributes attr = src[i]; - if (strk) + if (strk && attr.stroke_flag) { - attr.stroke_flag = true; attr.stroke_width = strk->get_width(); color const& s_color = strk->get_color(); attr.stroke_color = agg::rgba(s_color.red()/255.0,s_color.green()/255.0, s_color.blue()/255.0,(s_color.alpha()*strk->get_opacity())/255.0); } - if (fill) + if (fill && attr.fill_flag) { - - attr.fill_flag = true; color const& f_color = *fill; attr.fill_color = agg::rgba(f_color.red()/255.0,f_color.green()/255.0, f_color.blue()/255.0,(f_color.alpha()*sym.get_opacity())/255.0); diff --git a/src/marker_cache.cpp b/src/marker_cache.cpp index c50a59026..96c0e0a45 100644 --- a/src/marker_cache.cpp +++ b/src/marker_cache.cpp @@ -59,7 +59,7 @@ marker_cache::marker_cache() insert_svg("arrow", "" "" - "" + "" ""); }