diff --git a/CHANGELOG.md b/CHANGELOG.md index e8753967a..3a8a48d2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ For a complete change history, see the git log. Not yet released +- Added support for filtering on a features geometry type, either `point`, `linestring`, 'polygon`, + or `collection` using the expression keyword of `[mapnik::geometry_type]` (#546) + - MarkersSymbolizer width and height moved to expressions (#1102) - Added style-level 'opacity' (#314) 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 diff --git a/SConstruct b/SConstruct index 78786d6e7..896ce5cad 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 @@ -238,14 +242,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: @@ -1531,7 +1527,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') 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 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/mapnik_shield_symbolizer.cpp b/bindings/python/mapnik_shield_symbolizer.cpp index 913fbedb2..653469f2b 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) { - pixel_position const& pos = t.get_displacement(); + pixel_position const& pos = t.get_placement_options()->defaults.displacement; return boost::python::make_tuple(pos.x, pos.y); } @@ -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/bindings/python/python_grid_utils.cpp b/bindings/python/python_grid_utils.cpp new file mode 100644 index 000000000..f0b99f714 --- /dev/null +++ b/bindings/python/python_grid_utils.cpp @@ -0,0 +1,507 @@ +/***************************************************************************** + * + * 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 +#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 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/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index de32ff8e0..2ce89a290 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.hpp @@ -30,6 +30,7 @@ #include #include #include +#include // for all symbolizers // boost #include @@ -48,6 +49,7 @@ struct trans_affine; namespace mapnik { class marker; + struct rasterizer; template diff --git a/include/mapnik/attribute.hpp b/include/mapnik/attribute.hpp index a9ae97169..9ff0ab063 100644 --- a/include/mapnik/attribute.hpp +++ b/include/mapnik/attribute.hpp @@ -26,8 +26,7 @@ // mapnik #include #include -// boost -#include + // stl #include @@ -53,15 +52,18 @@ struct geometry_type_attribute template V value(F const& f) const { - int result = 0; - + int type = 0; geometry_container::const_iterator itr = f.paths().begin(); geometry_container::const_iterator end = f.paths().end(); for ( ; itr != end; ++itr) { - result = itr->type(); + if (type != 0 && itr->type() != type) + { + return 4; // Collection + } + type = itr->type(); } - return result; + return type; } }; diff --git a/include/mapnik/cairo_renderer.hpp b/include/mapnik/cairo_renderer.hpp index 0054e3f49..25d1c08f3 100644 --- a/include/mapnik/cairo_renderer.hpp +++ b/include/mapnik/cairo_renderer.hpp @@ -32,6 +32,7 @@ #include #include #include +#include // for all symbolizers // cairo #include 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/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/expression_grammar.hpp b/include/mapnik/expression_grammar.hpp index 8f11aea55..31f6e912e 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_; }; @@ -128,8 +114,9 @@ struct geometry_types : qi::symbols { add ("point",1) - ("line", 2) + ("linestring", 2) ("polygon",3) + ("collection",4) ; } }; @@ -139,134 +126,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/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 } } diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index 808b34b0f..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; + 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; @@ -285,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; @@ -299,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) @@ -318,7 +334,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 +382,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/geometry.hpp b/include/mapnik/geometry.hpp index 20356dc84..3a7bc2db1 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 #include #include -//#include +#include // for all symbolizers #include #include diff --git a/include/mapnik/grid/grid_util.hpp b/include/mapnik/grid/grid_util.hpp index 517c4ccc1..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 { /* @@ -45,15 +48,20 @@ static inline void scale_grid(mapnik::grid::data_type & target, if (source_width<1 || source_height<1 || target_width<1 || target_height<1) return; - int x=0,y=0,xs=0,ys=0; + int x = 0; + int y = 0; + int xs = 0; + int ys = 0; int tw2 = target_width/2; int th2 = target_height/2; int offs_x = rint((source_width-target_width-x_off_f*2*source_width)/2); int offs_y = rint((source_height-target_height-y_off_f*2*source_height)/2); - unsigned yprt(0); - unsigned yprt1(0); - unsigned xprt(0); - unsigned xprt1(0); + unsigned yprt = 0; + 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){ 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/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/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 { 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/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/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/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 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 diff --git a/include/mapnik/text_symbolizer.hpp b/include/mapnik/text_symbolizer.hpp index 125591ab3..e199a9e6b 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 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... 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/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/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/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 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/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()) { 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..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 @@ -36,6 +39,7 @@ #include // mapnik #include +#include #include #include #include @@ -63,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; @@ -94,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 { @@ -121,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 231339cc0..14fd9af0f 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: @@ -49,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/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/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_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_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/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/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_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 } } } - 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/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/osm/basiccurl.cpp b/plugins/input/osm/basiccurl.cpp index ef8c32f4e..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; @@ -39,7 +41,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 +49,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/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/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_; }; 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..affe873be 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 @@ -32,7 +33,6 @@ #include "raster_featureset.hpp" using mapnik::query; -using mapnik::CoordTransform; using mapnik::image_reader; using mapnik::Feature; using mapnik::feature_ptr; @@ -80,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_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/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/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_io.cpp b/plugins/input/shape/shape_io.cpp index 7b8c27fe3..ac2c7e01b 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) { @@ -188,9 +188,9 @@ 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) { - 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) @@ -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 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_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; 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 { diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index bff971757..92cda8973 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -21,6 +21,8 @@ *****************************************************************************/ // mapnik +#include +#include #include #include #include @@ -239,7 +241,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 +258,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); } diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index ce1fc7310..d57b22b11 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,53 @@ private: double scale_factor_; }; +template +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) +{ -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] = 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]); + 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 +197,97 @@ 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_, src_, + matrix, sym_.get_opacity()); + 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); + matrix.translate(x,y); + render_raster_marker(ras_, renb_, sl_, src_, + matrix, sym_.get_opacity()); + } + } + } +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 +295,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); + } } } } 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 +#include #include #include #include @@ -51,7 +53,6 @@ #include // agg - #include "agg_conv_clip_polyline.h" #include "agg_conv_clip_polygon.h" #include "agg_conv_smooth_poly1.h" @@ -494,6 +495,11 @@ public: { line_to(x, y); } + else if (cm == SEG_CLOSE) + { + line_to(x, y); + close_path(); + } } } 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/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/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..f5f9bad8b --- /dev/null +++ b/src/expression_node.cpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * 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::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 diff --git a/src/feature_style_processor.cpp b/src/feature_style_processor.cpp index 3fc1f7d32..f3226240a 100644 --- a/src/feature_style_processor.cpp +++ b/src/feature_style_processor.cpp @@ -20,8 +20,10 @@ * *****************************************************************************/ -//mapnik +// mapnik #include +#include +#include #include #include #include @@ -37,7 +39,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/json/feature_grammar.cpp b/src/json/feature_grammar.cpp new file mode 100644 index 000000000..8c6386422 --- /dev/null +++ b/src/json/feature_grammar.cpp @@ -0,0 +1,230 @@ +/***************************************************************************** + * + * 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 + ; +#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\"") + >> 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>; + +}} diff --git a/src/load_map.cpp b/src/load_map.cpp index c5d20fd36..221c0b88f 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 @@ -1062,9 +1056,11 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node) stroke strk; 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); @@ -1309,25 +1305,30 @@ 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) { - strk.set_color(*c); result = true; + strk.set_color(*c); } // stroke-width - optional width = sym.get_opt_attr("stroke-width"); - if (width && *width > 0) + optional width = sym.get_opt_attr("stroke-width"); + if (width) { - strk.set_width(*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"); 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/marker_cache.cpp b/src/marker_cache.cpp index 42be35040..96c0e0a45 100644 --- a/src/marker_cache.cpp +++ b/src/marker_cache.cpp @@ -54,12 +54,12 @@ marker_cache::marker_cache() insert_svg("ellipse", "" "" - "" + "" ""); insert_svg("arrow", "" "" - "" + "" ""); } 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), 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 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; + +} diff --git a/src/save_map.cpp b/src/save_map.cpp index 6dae344db..dbe06c293 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -21,6 +21,8 @@ *****************************************************************************/ // mapnik +#include +#include #include #include #include @@ -201,9 +203,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); } pixel_position displacement = sym.get_shield_displacement(); if (displacement.x != dfl.get_shield_displacement().x || explicit_defaults_) 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 diff --git a/src/wkb.cpp b/src/wkb.cpp index 0551034cd..2e57b8600 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: @@ -113,9 +117,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 +247,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 +266,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 +286,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 +313,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 +341,28 @@ 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 - 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 + paths.push_back(poly); } - paths.push_back(poly); } void read_multipolygon(boost::ptr_vector & paths) @@ -364,22 +377,28 @@ 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 - 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 + paths.push_back(poly); } - paths.push_back(poly); } void read_multipolygon_xyz(boost::ptr_vector & paths) @@ -402,33 +421,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, 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 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 diff --git a/tests/data/good_maps/colorize-alpha.xml b/tests/data/good_maps/colorize-alpha.xml new file mode 100644 index 000000000..625a55b40 --- /dev/null +++ b/tests/data/good_maps/colorize-alpha.xml @@ -0,0 +1,49 @@ + + + + + + + + + + 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/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 @@ -