Merge branch 'master' into harfbuzz

Conflicts:
	bindings/python/mapnik_shield_symbolizer.cpp
	include/mapnik/agg_renderer.hpp
	include/mapnik/cairo_renderer.hpp
	src/build.py
This commit is contained in:
Hermann Kraus 2012-07-28 20:59:42 +02:00
commit 4e3e5cb0b0
111 changed files with 2588 additions and 1649 deletions

View file

@ -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)

View file

@ -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

View file

@ -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')

View file

@ -30,6 +30,8 @@
// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/query.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/feature_layer_desc.hpp>

View file

@ -72,6 +72,7 @@ void export_logger();
#include <mapnik/version.hpp>
#include <mapnik/value_error.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/agg_renderer.hpp>
#ifdef HAVE_CAIRO

View file

@ -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 <boost/python.hpp>
@ -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<double>(arg[0]),extract<double>(arg[1]));
s.get_placement_options()->defaults.displacement.first = extract<double>(arg[0]);
s.get_placement_options()->defaults.displacement.second = extract<double>(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<color>(state[0]));
s.set_halo_radius(extract<float>(state[1]));
}
};
void export_shield_symbolizer()
{
using namespace boost::python;
@ -126,7 +94,7 @@ void export_shield_symbolizer()
init<expression_ptr,
std::string const&,
unsigned, mapnik::color const&,
path_expression_ptr>("TODO")
path_expression_ptr>()
)
//.def_pickle(shield_symbolizer_pickle_suite())
.add_property("allow_overlap",

View file

@ -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 <boost/python.hpp>
#include <boost/scoped_array.hpp>
#include <boost/foreach.hpp>
// mapnik
#include <mapnik/map.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid.hpp>
#include <mapnik/grid/grid_util.hpp>
#include <mapnik/grid/grid_view.hpp>
#include <mapnik/value_error.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_kv_iterator.hpp>
#include "mapnik_value_converter.hpp"
#include "python_grid_utils.hpp"
namespace mapnik {
template <typename T>
void grid2utf(T const& grid_type,
boost::python::list& l,
std::vector<grid::lookup_type>& 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<Py_UNICODE> 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<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
template <typename T>
void grid2utf(T const& grid_type,
boost::python::list& l,
std::vector<typename T::lookup_type>& 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<unsigned int>(grid_type.width()/resolution);
for (unsigned y = 0; y < grid_type.height(); y=y+resolution)
{
boost::uint16_t idx = 0;
boost::scoped_array<Py_UNICODE> 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<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
template <typename T>
void grid2utf2(T const& grid_type,
boost::python::list& l,
std::vector<typename T::lookup_type>& 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<Py_UNICODE> 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<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
template <typename T>
void write_features(T const& grid_type,
boost::python::dict& feature_data,
std::vector<typename T::lookup_type> const& key_order)
{
std::string const& key = grid_type.get_key();
std::set<std::string> 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<std::string> 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 <typename T>
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<typename T::lookup_type> key_order;
if (resolution != 1) {
// resample on the fly - faster, less accurate
mapnik::grid2utf<T>(grid_type,l,key_order,resolution);
// resample first - slower, more accurate
//mapnik::grid2utf2<T>(grid_type,l,key_order,resolution);
}
else
{
mapnik::grid2utf<T>(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<T>(grid_type,feature_data,key_order);
}
json["grid"] = l;
json["keys"] = keys_a;
json["data"] = feature_data;
}
template <typename T>
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<T>(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<mapnik::layer> 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<num_fields; i++) {
boost::python::extract<std::string> 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<std::string> 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<mapnik::grid> 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<mapnik::layer> 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<num_fields; i++) {
boost::python::extract<std::string> 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<std::string> 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<mapnik::grid> 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;
}
}

View file

@ -24,483 +24,66 @@
// boost
#include <boost/python.hpp>
#include <boost/scoped_array.hpp>
#include <boost/foreach.hpp>
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/grid/grid.hpp>
#include <mapnik/grid/grid_util.hpp>
#include <mapnik/grid/grid_view.hpp>
#include <mapnik/value_error.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_kv_iterator.hpp>
#include "mapnik_value_converter.hpp"
namespace mapnik {
template <typename T>
static void grid2utf(T const& grid_type,
void grid2utf(T const& grid_type,
boost::python::list& l,
std::vector<grid::lookup_type>& 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<Py_UNICODE> 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<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
std::vector<typename T::lookup_type>& key_order);
template <typename T>
static void grid2utf(T const& grid_type,
void grid2utf(T const& grid_type,
boost::python::list& l,
std::vector<typename T::lookup_type>& 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<unsigned int>(grid_type.width()/resolution);
for (unsigned y = 0; y < grid_type.height(); y=y+resolution)
{
boost::uint16_t idx = 0;
boost::scoped_array<Py_UNICODE> 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<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(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 <typename T>
static void grid2utf2(T const& grid_type,
void grid2utf2(T const& grid_type,
boost::python::list& l,
std::vector<typename T::lookup_type>& 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<Py_UNICODE> 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<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(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 <typename T>
static void write_features(T const& grid_type,
void write_features(T const& grid_type,
boost::python::dict& feature_data,
std::vector<typename T::lookup_type> const& key_order)
{
std::string const& key = grid_type.get_key();
std::set<std::string> 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<std::string> 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<typename T::lookup_type> const& key_order);
template <typename T>
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<typename T::lookup_type> key_order;
if (resolution != 1) {
// resample on the fly - faster, less accurate
mapnik::grid2utf<T>(grid_type,l,key_order,resolution);
// resample first - slower, more accurate
//mapnik::grid2utf2<T>(grid_type,l,key_order,resolution);
}
else
{
mapnik::grid2utf<T>(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<T>(grid_type,feature_data,key_order);
}
json["grid"] = l;
json["keys"] = keys_a;
json["data"] = feature_data;
}
unsigned int resolution);
template <typename T>
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<T>(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<mapnik::layer> 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<num_fields; i++) {
boost::python::extract<std::string> 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<std::string> 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<mapnik::grid> 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<mapnik::layer> 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<num_fields; i++) {
boost::python::extract<std::string> 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<std::string> 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<mapnik::grid> 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

View file

@ -21,6 +21,9 @@
*****************************************************************************/
#include <mapnik/map.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/rule.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>

View file

@ -30,6 +30,7 @@
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/map.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/rule.hpp> // for all symbolizers
// boost
#include <boost/utility.hpp>
@ -48,6 +49,7 @@ struct trans_affine;
namespace mapnik {
class marker;
struct rasterizer;
template <typename T>

View file

@ -26,8 +26,7 @@
// mapnik
#include <mapnik/value.hpp>
#include <mapnik/geometry.hpp>
// boost
#include <boost/foreach.hpp>
// stl
#include <string>
@ -53,15 +52,18 @@ struct geometry_type_attribute
template <typename V, typename F>
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;
}
};

View file

@ -32,6 +32,7 @@
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/map.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/rule.hpp> // for all symbolizers
// cairo
#include <cairomm/context.h>

View file

@ -63,162 +63,10 @@ typedef boost::spirit::ascii::space_type ascii_space_type;
struct named_colors_ : qi::symbols<char,color>
{
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 <int MIN,int MAX>
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 <typename Iterator>
struct css_color_grammar : qi::grammar<Iterator, color(), ascii_space_type>
{
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 ;

View file

@ -27,7 +27,6 @@
#include <mapnik/debug.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/vertex.hpp>
#include <mapnik/coord_array.hpp>
#include <mapnik/proj_transform.hpp>
// stl
@ -36,8 +35,6 @@
namespace mapnik
{
typedef coord_array<coord2d> CoordinateArray;
template <typename Transform, typename Geometry>
struct MAPNIK_DECL coord_transform
{
@ -228,24 +225,6 @@ public:
return box2d<double>(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<double> const& extent() const
{
return extent_;

View file

@ -25,7 +25,6 @@
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/params.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/query.hpp>

View file

@ -86,14 +86,7 @@ struct regex_match_impl
: tr_(tr) {}
template <typename T0,typename T1>
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 <typename T0,typename T1,typename T2>
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<char,int>
{
add
("point",1)
("line", 2)
("linestring", 2)
("polygon",3)
("collection",4)
;
}
};
@ -139,134 +126,12 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
{
typedef qi::rule<Iterator, expr_node(), space_type> 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<mapnik::geometry_type_attribute>()]
| attr [_val = construct<mapnik::attribute>( _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<double, qi::strict_real_policies<double> > strict_double;
boost::phoenix::function<unicode_impl> unicode_;
boost::phoenix::function<regex_match_impl> regex_match_;
boost::phoenix::function<regex_replace_impl> regex_replace_;
//
rule_type expr;
rule_type equality_expr;
rule_type cond_expr;

View file

@ -28,12 +28,12 @@
#include <mapnik/attribute.hpp>
// boost
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/regex.hpp>
#if defined(BOOST_REGEX_HAS_ICU)
#include <boost/regex/icu.hpp>
#endif
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
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;

View file

@ -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 <typename T>
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 <typename T>
std::string to_expression_string(boost::shared_ptr<T> const& x)
std::string to_expression_string(boost::shared_ptr<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
}
}

View file

@ -39,7 +39,7 @@ namespace mapnik
template <typename T>
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 <typename PathType>
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 <typename PathType>
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 <typename PathType>
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 <typename PathType>
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<double> 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)

View file

@ -88,8 +88,8 @@ public:
box2d<double> envelope() const
{
box2d<double> result;
double x(0);
double y(0);
double x = 0;
double y = 0;
rewind(0);
for (unsigned i=0;i<size();++i)
{
@ -121,6 +121,11 @@ public:
push_vertex(x,y,SEG_MOVETO);
}
void close(coord_type x, coord_type y)
{
push_vertex(x,y,SEG_CLOSE);
}
unsigned vertex(double* x, double* y) const
{
return cont_.get_vertex(itr_++,x,y);

View file

@ -97,7 +97,7 @@ public:
return id_name_;
}
inline void add_feature(mapnik::feature_impl & feature);
void add_feature(mapnik::feature_impl & feature);
inline void add_property_name(std::string const& name)
{

View file

@ -29,7 +29,7 @@
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/map.hpp>
//#include <mapnik/marker.hpp>
#include <mapnik/rule.hpp> // for all symbolizers
#include <mapnik/grid/grid.hpp>
#include <mapnik/pixel_position.hpp>

View file

@ -26,6 +26,9 @@
// mapnik
#include <mapnik/grid/grid.hpp>
// boost
#include <boost/concept_check.hpp>
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){

View file

@ -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;
};

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/value.hpp>
// spirit::qi
#include <boost/config/warning_disable.hpp>
@ -135,196 +136,7 @@ struct feature_grammar :
qi::grammar<Iterator, void(FeatureType&),
space_type>
{
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<value_null>()]
;
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_<geometry_type>(Point) ]
> ( point(SEG_MOVETO,_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false] )
;
linestring_coordinates = eps[ _a = new_<geometry_type>(LineString)]
> -(points(_a) [push_back(_r1,_a)]
| eps[cleanup_(_a)][_pass = false])
;
polygon_coordinates = eps[ _a = new_<geometry_type>(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<fail>
(
feature
, std::clog
<< phoenix::val("Error! Expecting ")
<< _4 // what failed?
<< phoenix::val(" here: \"")
<< construct<std::string>(_3, _2) // iterators to error-pos, end
<< phoenix::val("\"")
<< std::endl
);
}
feature_grammar(mapnik::transcoder const& tr);
// start
// generic JSON

View file

@ -65,19 +65,21 @@ public:
(*bitmap_data_)->set(0xff000000);
}
marker(const boost::optional<mapnik::image_ptr> &data) : bitmap_data_(data)
marker(const boost::optional<mapnik::image_ptr> &data)
: bitmap_data_(data)
{
}
marker(const boost::optional<mapnik::path_ptr> &data) : vector_data_(data)
marker(const boost::optional<mapnik::path_ptr> &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<double> bounding_box() const
{

View file

@ -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);

View file

@ -26,7 +26,6 @@
#include <mapnik/debug.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/vertex.hpp>
#include <mapnik/coord_array.hpp>
#include <mapnik/proj_transform.hpp>
// boost

View file

@ -24,29 +24,15 @@
#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP
// mapnik
#include <mapnik/unicode.hpp>
#include <mapnik/expression_node.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/attribute.hpp>
// boost
#include <boost/variant.hpp>
#include <boost/concept_check.hpp>
// spirit2
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
// fusion
#include <boost/fusion/include/adapt_struct.hpp>
// phoenix
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/home/phoenix/object/construct.hpp>
// stl
#include <string>
#include <vector>
@ -65,29 +51,7 @@ typedef boost::variant<std::string, attribute> path_component;
template <typename Iterator>
struct path_expression_grammar : qi::grammar<Iterator, std::vector<path_component>(), 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<mapnik::attribute>( _1 )) ] >> ']')
)
;
attr %= +(char_ - ']');
str %= lexeme[+(char_ -'[')];
}
path_expression_grammar();
qi::rule<Iterator, std::vector<path_component>() , space_type> expr;
qi::rule<Iterator, std::string() , space_type> attr;
qi::rule<Iterator, std::string() > str;

View file

@ -23,7 +23,7 @@
#ifndef MAPNIK_RULE_HPP
#define MAPNIK_RULE_HPP
// mapni
// mapnik
#include <mapnik/building_symbolizer.hpp>
#include <mapnik/line_symbolizer.hpp>
#include <mapnik/line_pattern_symbolizer.hpp>

View file

@ -22,33 +22,36 @@
#ifndef PLACEMENTS_DUMMY_HPP
#define PLACEMENTS_DUMMY_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/text_placements/base.hpp>
// boost
#include <boost/concept_check.hpp>
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

View file

@ -37,7 +37,7 @@
// stl
#include <string>
#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

View file

@ -115,7 +115,7 @@ namespace detail {
// boost::spirit::traits::clear<T>(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...

View file

@ -39,65 +39,7 @@ namespace mapnik {
struct transform_expression_grammar
: qi::grammar<Iterator, transform_list(), space_type>
{
explicit transform_expression_grammar(expression_grammar<Iterator> 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<matrix_node>(_1,_2,_3,_4,_5,_6) ];
translate = no_case[lit("translate")]
>> (lit('(')
>> expr >> -lit(',')
>> -expr >> lit(')'))
[ _val = construct<translate_node>(_1,_2) ];
scale = no_case[lit("scale")]
>> (lit('(')
>> expr >> -lit(',')
>> -expr >> lit(')'))
[ _val = construct<scale_node>(_1,_2) ];
rotate = no_case[lit("rotate")]
>> lit('(')
>> expr[_a = _1] >> -lit(',')
>> -(expr [_b = _1] >> -lit(',') >> expr[_c = _1])
>> lit(')')
[ _val = construct<rotate_node>(_a,_b,_c) ];
skewX = no_case[lit("skewX")]
>> lit('(')
>> expr [ _val = construct<skewX_node>(_1) ]
>> lit(')');
skewY = no_case[lit("skewY")]
>> lit('(')
>> expr [ _val = construct<skewY_node>(_1) ]
>> lit(')');
expr = g.expr.alias();
}
explicit transform_expression_grammar(expression_grammar<Iterator> const& g);
typedef qi::locals<expr_node, boost::optional<expr_node>,
boost::optional<expr_node>
> rotate_locals;

View file

@ -126,7 +126,8 @@ namespace mapnik { namespace util {
ss.write(reinterpret_cast<char*>(&byte_order),1);
int type = static_cast<int>(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<int>(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<point_type> linear_ring;
boost::ptr_vector<linear_ring> 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)
{

View file

@ -26,8 +26,6 @@
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/util/vertex_iterator.hpp>
#include <mapnik/util/container_adapter.hpp>
// boost
#include <boost/tuple/tuple.hpp>
@ -55,161 +53,88 @@ struct is_container<mapnik::geometry_container>
namespace mapnik { namespace util {
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
namespace {
struct get_type
{
template <typename T>
struct result { typedef int type; };
int operator() (geometry_type const& geom) const
{
return static_cast<int>(geom.type());
}
};
struct get_first
{
template <typename T>
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 <typename T>
struct result { typedef bool type; };
bool operator() (geometry_container const& geom) const
{
return geom.size() > 1 ? true : false;
}
};
struct multi_geometry_type
{
template <typename T>
struct result { typedef boost::tuple<unsigned,bool> type; };
boost::tuple<unsigned,bool> 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<unsigned,bool>(type, collection);
}
};
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
namespace {
struct get_type
{
template <typename T>
struct wkt_coordinate_policy : karma::real_policies<T>
{
typedef boost::spirit::karma::real_policies<T> 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<int>(geom.type());
}
};
template <typename OutputIterator>
struct wkt_generator :
karma::grammar<OutputIterator, geometry_type const& ()>
struct get_first
{
template <typename T>
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 <typename T>
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 <typename T>
struct result { typedef boost::tuple<unsigned,bool> type; };
polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)]
<< string[ phoenix::if_ (single) [_1 = "Polygon("]
.else_[_1 = "("]]
<< coords2
<< lit("))")
;
boost::tuple<unsigned,bool> 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 <typename T>
struct wkt_coordinate_policy : karma::real_policies<T>
{
typedef boost::spirit::karma::real_policies<T> 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 <typename OutputIterator>
struct wkt_generator :
karma::grammar<OutputIterator, geometry_type const& ()>
{
wkt_generator(bool single = false);
// rules
karma::rule<OutputIterator, geometry_type const& ()> wkt;
karma::rule<OutputIterator, geometry_type const& ()> point;
karma::rule<OutputIterator, geometry_type const& ()> linestring;
karma::rule<OutputIterator, geometry_type const& ()> polygon;
}
// rules
karma::rule<OutputIterator, geometry_type const& ()> wkt;
karma::rule<OutputIterator, geometry_type const& ()> point;
karma::rule<OutputIterator, geometry_type const& ()> linestring;
karma::rule<OutputIterator, geometry_type const& ()> polygon;
karma::rule<OutputIterator, geometry_type const& ()> coords;
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2;
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord;
karma::rule<OutputIterator, geometry_type::value_type (unsigned& )> polygon_coord;
// phoenix functions
phoenix::function<get_type > _type;
phoenix::function<get_first> _first;
//
karma::real_generator<double, wkt_coordinate_policy<double> > coord_type;
};
karma::rule<OutputIterator, geometry_type const& ()> coords;
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2;
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord;
karma::rule<OutputIterator, geometry_type::value_type (unsigned& )> polygon_coord;
// phoenix functions
phoenix::function<get_type > _type;
phoenix::function<get_first> _first;
//
karma::real_generator<double, wkt_coordinate_policy<double> > coord_type;
};
template <typename OutputIterator>
@ -217,38 +142,7 @@ struct wkt_multi_generator :
karma::grammar<OutputIterator, karma::locals< boost::tuple<unsigned,bool> >, 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<OutputIterator, karma::locals<boost::tuple<unsigned,bool> >, geometry_container const& ()> wkt;
karma::rule<OutputIterator, geometry_container const& ()> geometry;

View file

@ -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 <typename T,int dim>

View file

@ -25,8 +25,7 @@
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/feature.hpp>
// boost
#include <boost/utility.hpp>

View file

@ -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())
{

View file

@ -25,9 +25,19 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
// stl
#include <vector>
#include <string>
class csv_datasource : public mapnik::datasource
{

View file

@ -25,9 +25,19 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/shared_ptr.hpp>
#include <boost/optional.hpp>
// stl
#include <vector>
#include <string>
// gdal
#include <gdal_priv.h>

View file

@ -23,6 +23,7 @@
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/feature_factory.hpp>
// boost

View file

@ -31,6 +31,8 @@
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include "gdal_datasource.hpp"
class GDALDataset;
class GDALRasterBand;

View file

@ -25,7 +25,10 @@
#include <fstream>
#include <iostream>
#include <algorithm>
// boost
#include <boost/variant.hpp>
#include <boost/make_shared.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
@ -36,6 +39,7 @@
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/json/feature_collection_parser.hpp>
@ -63,6 +67,44 @@ geojson_datasource::geojson_datasource(parameters const& params, bool bind)
}
}
struct attr_value_converter : public boost::static_visitor<mapnik::eAttributeType>
{
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<std::string, mapnik::parameters> geojson_datasource::get_statistics() const
{
return statistics_;
}
mapnik::box2d<double> geojson_datasource::envelope() const
{
if (!is_bound_) bind();

View file

@ -25,7 +25,16 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/algorithms/area.hpp>
@ -33,6 +42,12 @@
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
// stl
#include <vector>
#include <string>
#include <map>
#include <deque>
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<double> envelope() const;
mapnik::layer_descriptor get_descriptor() const;
std::map<std::string, mapnik::parameters> get_statistics() const;
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
void bind() const;
private:

View file

@ -25,12 +25,21 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
// stl
#include <vector>
#include <string>
#include "geos_feature_ptr.hpp"
class geos_datasource : public mapnik::datasource

View file

@ -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,

View file

@ -23,21 +23,25 @@
#ifndef KISMET_DATASOURCE_HPP
#define KISMET_DATASOURCE_HPP
// stl
#include <list>
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/wkb.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/thread.hpp>
// sqlite
// stl
#include <list>
#include <vector>
#include <string>
#include "kismet_types.hpp"
class kismet_datasource : public mapnik::datasource

View file

@ -27,6 +27,8 @@
#include <mapnik/datasource.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/feature.hpp>
// boost
#include <boost/scoped_ptr.hpp>

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
// boost
#include <boost/shared_ptr.hpp>

View file

@ -25,13 +25,21 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
// stl
#include <vector>
#include <string>
// oci
#include "occi_types.hpp"

View file

@ -37,7 +37,6 @@
using mapnik::query;
using mapnik::box2d;
using mapnik::CoordTransform;
using mapnik::Feature;
using mapnik::feature_ptr;
using mapnik::geometry_type;

View file

@ -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<geometry_type> 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<geometry_type> 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<geometry_type> 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<OGRPoint*>(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<OGRLineString*>(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<OGRPolygon*>(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
}
}
}

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
// ogr
#include <ogrsf_frmts.h>

View file

@ -25,15 +25,23 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
// stl
#include <vector>
#include <string>
// ogr
#include <ogrsf_frmts.h>
#include "ogr_layer_ptr.hpp"
class ogr_datasource : public mapnik::datasource

View file

@ -39,7 +39,6 @@
using mapnik::query;
using mapnik::box2d;
using mapnik::CoordTransform;
using mapnik::Feature;
using mapnik::feature_ptr;
using mapnik::geometry_utils;

View file

@ -44,7 +44,6 @@
using mapnik::query;
using mapnik::box2d;
using mapnik::CoordTransform;
using mapnik::Feature;
using mapnik::feature_ptr;
using mapnik::geometry_utils;

View file

@ -22,6 +22,8 @@
#include "basiccurl.h"
#include <iostream>
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;
}

View file

@ -25,7 +25,20 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
// stl
#include <vector>
#include <string>
#include "osm.h"

View file

@ -25,12 +25,22 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
// stl
#include <vector>
#include <string>
#include "connection_manager.hpp"
#include "resultset.hpp"
#include "cursorresultset.hpp"

View file

@ -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);

View file

@ -55,7 +55,7 @@ private:
boost::shared_ptr<IResultSet> rs_;
context_ptr ctx_;
boost::scoped_ptr<mapnik::transcoder> tr_;
int totalGeomSize_;
unsigned totalGeomSize_;
int feature_id_;
bool key_field_;
};

View file

@ -26,6 +26,7 @@
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/image_reader.hpp>
#include <mapnik/boolean.hpp>

View file

@ -24,9 +24,22 @@
#define RASTER_DATASOURCE_HPP
// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
// stl
#include <vector>
#include <string>
class raster_datasource : public mapnik::datasource
{

View file

@ -22,6 +22,7 @@
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/image_reader.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/feature_factory.hpp>
@ -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<LookupPolicy>::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<double> intersect = bbox_.intersect(curIter_->envelope());
box2d<double> ext = t.forward(intersect);
box2d<double> rem = policy_.transform(ext);

View file

@ -25,10 +25,21 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
// stl
#include <vector>
#include <string>
#include "rasterlite_include.hpp"
class rasterlite_datasource : public mapnik::datasource

View file

@ -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;

View file

@ -25,11 +25,21 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
// stl
#include <vector>
#include <string>
#include "shape_io.hpp"
using mapnik::datasource;

View file

@ -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<geometry_type> 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<geometry_type> 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<geometry_type> 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;j<end;j++)
for (int j=start+1;j<end-1;j++)
{
x = record.read_double();
y = record.read_double();
poly->line_to(x, y);
}
x = record.read_double();
y = record.read_double();
poly->close(x, y);
geom.push_back(poly);
}
// z-range

View file

@ -22,6 +22,7 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include "shape_utils.hpp"
// boost

View file

@ -28,6 +28,7 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/sql_utils.hpp>
#include <mapnik/timer.hpp>

View file

@ -25,18 +25,26 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/wkb.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
// stl
#include <vector>
#include <string>
// sqlite
#include "sqlite_connection.hpp"
class sqlite_datasource : public mapnik::datasource
{
public:

View file

@ -38,7 +38,6 @@
using mapnik::query;
using mapnik::box2d;
using mapnik::CoordTransform;
using mapnik::Feature;
using mapnik::feature_ptr;
using mapnik::geometry_utils;

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/box2d.hpp>
// boost

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
// stl
#include <string.h>

View file

@ -29,6 +29,7 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/sql_utils.hpp>

View file

@ -3,6 +3,19 @@
// mapnik
#include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
// stl
#include <string>
class hello_datasource : public mapnik::datasource
{

View file

@ -21,6 +21,8 @@
*****************************************************************************/
// mapnik
#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_rasterizer.hpp>
@ -239,7 +241,7 @@ void agg_renderer<T>::end_style_processing(feature_type_style const& st)
{
blend_from = true;
mapnik::filter::filter_visitor<image_32> 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<T>::end_style_processing(feature_type_style const& st)
// apply any 'direct' image filters
mapnik::filter::filter_visitor<image_32> 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);
}

View file

@ -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 <boost/optional.hpp>
namespace mapnik {
template <typename BufferType, typename SvgRenderer, typename Rasterizer, typename Detector>
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<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
markers_rasterizer_dispatch(BufferType & image_buffer,
vector_markers_rasterizer_dispatch(BufferType & image_buffer,
SvgRenderer & svg_renderer,
Rasterizer & ras,
box2d<double> 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 <typename Rasterizer, typename RendererBuffer>
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 <typename T>
void agg_renderer<T>::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<color_type> 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<agg::pixfmt_rgba32_pre> img_accessor_type;
typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
typedef agg::span_image_filter_rgba_2x2<img_accessor_type,
interpolator_type> 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 <typename BufferType, typename Rasterizer, typename Detector>
struct raster_markers_rasterizer_dispatch
{
typedef agg::rgba8 color_type;
typedef agg::order_rgba order_type;
@ -153,6 +197,97 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> 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<agg::comp_op_e>(sym_.comp_op()));
}
template <typename T>
void add_path(T & path)
{
marker_placement_e placement_method = sym_.get_marker_placement();
box2d<double> 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<double> 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<T, label_collision_detector4> 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 <typename T>
void agg_renderer<T>::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<color_type, order_type> blender_type; // comp blender
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_comp_type;
typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
typedef label_collision_detector4 detector_type;
typedef boost::mpl::vector<clip_line_tag,transform_tag,smooth_tag> conv_types;
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
if (!filename.empty())
@ -160,61 +295,76 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
boost::optional<marker_ptr> 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<path_ptr> marker = (*mark)->get_vector_data();
box2d<double> const& bbox = (*marker)->bounding_box();
box2d<double> 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<svg_path_storage> stl_storage((*marker)->source());
svg_path_adapter svg_path(stl_storage);
agg::pod_bvector<path_attributes> attributes;
bool result = push_explicit_style( (*marker)->attributes(), attributes, sym);
typedef label_collision_detector4 detector_type;
typedef svg_renderer<svg_path_adapter,
agg::pod_bvector<path_attributes>,
renderer_type,
agg::pixfmt_rgba32 > svg_renderer_type;
typedef markers_rasterizer_dispatch<buffer_type, svg_renderer_type, rasterizer, detector_type> markers_rasterizer_dispatch_type;
typedef boost::mpl::vector<clip_line_tag,transform_tag,smooth_tag> 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<box2d<double>, 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<clip_line_tag>(); //optional clip (default: true)
converter.template set<transform_tag>(); //always transform
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
BOOST_FOREACH(geometry_type & geom, feature.paths())
if ((*mark)->is_vector())
{
converter.apply(geom);
using namespace mapnik::svg;
boost::optional<path_ptr> marker = (*mark)->get_vector_data();
vertex_stl_adapter<svg_path_storage> stl_storage((*marker)->source());
svg_path_adapter svg_path(stl_storage);
agg::pod_bvector<path_attributes> attributes;
bool result = push_explicit_style( (*marker)->attributes(), attributes, sym);
typedef svg_renderer<svg_path_adapter,
agg::pod_bvector<path_attributes>,
renderer_type,
agg::pixfmt_rgba32 > svg_renderer_type;
typedef vector_markers_rasterizer_dispatch<buffer_type, svg_renderer_type, rasterizer, detector_type> 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<box2d<double>, 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<clip_line_tag>(); //optional clip (default: true)
converter.template set<transform_tag>(); //always transform
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
BOOST_FOREACH(geometry_type & geom, feature.paths())
{
converter.apply(geom);
}
}
else // raster markers
{
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
typedef raster_markers_rasterizer_dispatch<buffer_type,rasterizer, detector_type> dispatch_type;
dispatch_type rasterizer_dispatch(*current_buffer_,*ras_ptr, **marker,
marker_trans, sym, *detector_, scale_factor_);
vertex_converter<box2d<double>, 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<clip_line_tag>(); //optional clip (default: true)
converter.template set<transform_tag>(); //always transform
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
BOOST_FOREACH(geometry_type & geom, feature.paths())
{
converter.apply(geom);
}
}
}
}

View file

@ -65,14 +65,14 @@ void agg_renderer<T>::process(point_symbolizer const& sym,
if (marker)
{
box2d<double> 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<double> label_ext = bbox * recenter_tr;
for (unsigned i=0; i<feature.num_geometries(); ++i)

View file

@ -101,6 +101,7 @@ else: # unix, non-macos
source = Split(
"""
color.cpp
css_color_grammar.cpp
conversions.cpp
image_compositing.cpp
image_scaling.cpp
@ -109,8 +110,11 @@ source = Split(
datasource_cache.cpp
debug.cpp
deepcopy.cpp
expression_node.cpp
expression_grammar.cpp
expression_string.cpp
expression.cpp
transform_expression_grammar.cpp
transform_expression.cpp
feature_kv_iterator.cpp
feature_type_style.cpp
@ -130,6 +134,7 @@ source = Split(
parse_path.cpp
parse_transform.cpp
palette.cpp
path_expression_grammar.cpp
plugin.cpp
png_reader.cpp
point_symbolizer.cpp
@ -140,6 +145,7 @@ source = Split(
text_symbolizer.cpp
tiff_reader.cpp
wkb.cpp
wkb_generator.cpp
projection.cpp
proj_transform.cpp
distance.cpp
@ -162,6 +168,7 @@ source = Split(
svg_points_parser.cpp
svg_transform_parser.cpp
warp.cpp
json/feature_grammar.cpp
json/feature_collection_parser.cpp
json/geojson_generator.cpp
markers_placement.cpp
@ -282,21 +289,21 @@ source += Split(
if env['SVG_RENDERER']: # svg backend
source += Split(
"""
svg/svg_renderer.cpp
svg/svg_generator.cpp
svg/svg_output_attributes.cpp
svg/process_symbolizers.cpp
svg/process_building_symbolizer.cpp
svg/process_line_pattern_symbolizer.cpp
svg/process_line_symbolizer.cpp
svg/process_markers_symbolizer.cpp
svg/process_point_symbolizer.cpp
svg/process_polygon_pattern_symbolizer.cpp
svg/process_polygon_symbolizer.cpp
svg/process_raster_symbolizer.cpp
svg/process_shield_symbolizer.cpp
svg/process_text_symbolizer.cpp
""")
svg/svg_renderer.cpp
svg/svg_generator.cpp
svg/svg_output_attributes.cpp
svg/process_symbolizers.cpp
svg/process_building_symbolizer.cpp
svg/process_line_pattern_symbolizer.cpp
svg/process_line_symbolizer.cpp
svg/process_markers_symbolizer.cpp
svg/process_point_symbolizer.cpp
svg/process_polygon_pattern_symbolizer.cpp
svg/process_polygon_symbolizer.cpp
svg/process_raster_symbolizer.cpp
svg/process_shield_symbolizer.cpp
svg/process_text_symbolizer.cpp
""")
lib_env.Append(CXXFLAGS = '-DSVG_RENDERER')
libmapnik_cxxflags.append('-DSVG_RENDERER')

View file

@ -23,6 +23,8 @@
#if defined(HAVE_CAIRO)
// mapnik
#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/cairo_renderer.hpp>
#include <mapnik/image_util.hpp>
@ -51,7 +53,6 @@
#include <boost/make_shared.hpp>
// 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();
}
}
}

262
src/css_color_grammar.cpp Normal file
View file

@ -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 <mapnik/css_color_grammar.hpp>
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 <typename Iterator>
css_color_grammar<Iterator>::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<std::string::const_iterator>;
}

View file

@ -21,6 +21,7 @@
*****************************************************************************/
// mapnik
#include <mapnik/feature_type_style.hpp>
#include <mapnik/map.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/layer.hpp>

174
src/expression_grammar.cpp Normal file
View file

@ -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 <mapnik/expression_grammar.hpp>
namespace mapnik
{
template <typename T0,typename T1>
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 <typename T0,typename T1,typename T2>
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 <typename Iterator>
expression_grammar<Iterator>::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<mapnik::geometry_type_attribute>()]
| attr [_val = construct<mapnik::attribute>( _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<std::string::const_iterator>;
}

51
src/expression_node.cpp Normal file
View file

@ -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 <mapnik/expression_node.hpp>
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
}

View file

@ -20,8 +20,10 @@
*
*****************************************************************************/
//mapnik
// mapnik
#include <mapnik/feature_style_processor.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/memory_datasource.hpp>
@ -37,7 +39,8 @@
// boost
#include <boost/foreach.hpp>
#include <boost/concept_check.hpp>
//stl
// stl
#include <vector>
#if defined(HAVE_CAIRO)

View file

@ -21,6 +21,8 @@
*****************************************************************************/
// mapnik
#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/grid/grid_rasterizer.hpp>
#include <mapnik/grid/grid_renderer.hpp>

View file

@ -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 <mapnik/feature.hpp>
#include <mapnik/json/feature_grammar.hpp>
// boost
#include <boost/spirit/include/support_multi_pass.hpp>
namespace mapnik { namespace json {
template <typename Iterator, typename FeatureType>
feature_grammar<Iterator,FeatureType>::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<value_null>()]
;
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_<geometry_type>(Point) ]
> ( point(SEG_MOVETO,_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false] )
;
linestring_coordinates = eps[ _a = new_<geometry_type>(LineString)]
> -(points(_a) [push_back(_r1,_a)]
| eps[cleanup_(_a)][_pass = false])
;
polygon_coordinates = eps[ _a = new_<geometry_type>(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<fail>
(
feature
, std::clog
<< phoenix::val("Error! Expecting ")
<< _4 // what failed?
<< phoenix::val(" here: \"")
<< construct<std::string>(_3, _2) // iterators to error-pos, end
<< phoenix::val("\"")
<< std::endl
);
}
template struct mapnik::json::feature_grammar<std::string::const_iterator,mapnik::Feature>;
template struct mapnik::json::feature_grammar<boost::spirit::multi_pass<std::istreambuf_iterator<char> >,mapnik::Feature>;
}}

View file

@ -22,9 +22,7 @@
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/load_map.hpp>
#include <mapnik/xml_tree.hpp>
#include <mapnik/version.hpp>
#include <mapnik/image_compositing.hpp>
@ -39,16 +37,12 @@
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/font_set.hpp>
#include <mapnik/xml_loader.hpp>
#include <mapnik/expression.hpp>
#include <mapnik/parse_path.hpp>
#include <mapnik/parse_transform.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/svg/svg_path_parser.hpp>
#include <mapnik/metawriter_factory.hpp>
#include <mapnik/text_placements/registry.hpp>
#include <mapnik/text_placements/dummy.hpp>
#include <mapnik/symbolizer.hpp>
@ -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<marker_placement_e>("placement", MARKER_LINE_PLACEMENT);
marker_placement_e placement = node.get_attr<marker_placement_e>("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<color> c = sym.get_opt_attr<color>("stroke");
if (c)
{
strk.set_color(*c);
result = true;
strk.set_color(*c);
}
// stroke-width
optional<double> width = sym.get_opt_attr<double>("stroke-width");
if (width && *width > 0)
optional<double> width = sym.get_opt_attr<double>("stroke-width");
if (width)
{
strk.set_width(*width);
result = true;
strk.set_width(*width);
}
// stroke-opacity
optional<double> opacity = sym.get_opt_attr<double>("stroke-opacity");
if (opacity) strk.set_opacity(*opacity);
if (opacity)
{
result = true;
strk.set_opacity(*opacity);
}
// stroke-linejoin
optional<line_join_e> line_join = sym.get_opt_attr<line_join_e>("stroke-linejoin");

View file

@ -20,7 +20,9 @@
*
*****************************************************************************/
//mapnik
// mapnik
#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/map.hpp>
#include <mapnik/datasource.hpp>

View file

@ -54,12 +54,12 @@ marker_cache::marker_cache()
insert_svg("ellipse",
"<?xml version='1.0' standalone='no'?>"
"<svg width='100%' height='100%' version='1.1' xmlns='http://www.w3.org/2000/svg'>"
"<circle r='10' fill='#0000FF'/>"
"<ellipse rx='5' ry='5' fill='#0000FF' stroke='black' stroke-width='.5'/>"
"</svg>");
insert_svg("arrow",
"<?xml version='1.0' standalone='no'?>"
"<svg width='100%' height='100%' version='1.1' xmlns='http://www.w3.org/2000/svg'>"
"<path fill='#93a7ac' d='m 31.698405,7.5302648 -8.910967,-6.0263712 0.594993,4.8210971 -18.9822542,0 0,2.4105482 18.9822542,0 -0.594993,4.8210971 z'/>"
"<path fill='#0000FF' stroke='black' stroke-width='.5' d='m 31.698405,7.5302648 -8.910967,-6.0263712 0.594993,4.8210971 -18.9822542,0 0,2.4105482 18.9822542,0 -0.594993,4.8210971 z'/>"
"</svg>");
}

View file

@ -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),

View file

@ -22,6 +22,8 @@
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/query.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/memory_datasource.hpp>
#include <mapnik/memory_featureset.hpp>
#include <mapnik/feature_factory.hpp>

View file

@ -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 <mapnik/path_expression_grammar.hpp>
#include <mapnik/attribute.hpp>
// boost
#include <boost/spirit/home/phoenix/object/construct.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
namespace mapnik
{
template <typename Iterator>
path_expression_grammar<Iterator>::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<mapnik::attribute>( _1 )) ] >> ']')
)
;
attr %= +(char_ - ']');
str %= lexeme[+(char_ -'[')];
}
template struct mapnik::path_expression_grammar<std::string::const_iterator>;
}

View file

@ -21,6 +21,8 @@
*****************************************************************************/
// mapnik
#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/save_map.hpp>
#include <mapnik/map.hpp>
@ -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_)

View file

@ -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 <mapnik/transform_expression_grammar.hpp>
namespace mapnik {
namespace qi = boost::spirit::qi;
template <typename Iterator>
transform_expression_grammar<Iterator>::transform_expression_grammar(expression_grammar<Iterator> 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<matrix_node>(_1,_2,_3,_4,_5,_6) ];
translate = no_case[lit("translate")]
>> (lit('(')
>> expr >> -lit(',')
>> -expr >> lit(')'))
[ _val = construct<translate_node>(_1,_2) ];
scale = no_case[lit("scale")]
>> (lit('(')
>> expr >> -lit(',')
>> -expr >> lit(')'))
[ _val = construct<scale_node>(_1,_2) ];
rotate = no_case[lit("rotate")]
>> lit('(')
>> expr[_a = _1] >> -lit(',')
>> -(expr [_b = _1] >> -lit(',') >> expr[_c = _1])
>> lit(')')
[ _val = construct<rotate_node>(_a,_b,_c) ];
skewX = no_case[lit("skewX")]
>> lit('(')
>> expr [ _val = construct<skewX_node>(_1) ]
>> lit(')');
skewY = no_case[lit("skewY")]
>> lit('(')
>> expr [ _val = construct<skewY_node>(_1) ]
>> lit(')');
expr = g.expr.alias();
}
template struct mapnik::transform_expression_grammar<std::string::const_iterator>;
}

View file

@ -24,6 +24,7 @@
#include <mapnik/debug.hpp>
#include <mapnik/global.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/coord_array.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/feature.hpp>
@ -33,6 +34,9 @@
namespace mapnik
{
typedef coord_array<coord2d> 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<geometry_type> & paths)
{
geometry_type* pt = new geometry_type(Point);
double x = read_double();
double y = read_double();
std::auto_ptr<geometry_type> 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<geometry_type> & paths)
{
geometry_type* pt = new geometry_type(Point);
double x = read_double();
double y = read_double();
std::auto_ptr<geometry_type> 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<geometry_type> & 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<geometry_type> 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<geometry_type> & paths)
@ -309,16 +313,19 @@ private:
void read_linestring_xyz(boost::ptr_vector<geometry_type> & 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<geometry_type> 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<geometry_type> & paths)
@ -334,22 +341,28 @@ private:
void read_polygon(boost::ptr_vector<geometry_type> & 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<geometry_type> 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<geometry_type> & paths)
@ -364,22 +377,28 @@ private:
void read_polygon_xyz(boost::ptr_vector<geometry_type> & 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<geometry_type> 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<geometry_type> & 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<geometry_type>& paths,

141
src/wkb_generator.cpp Normal file
View file

@ -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 <mapnik/util/geometry_wkt_generator.hpp>
#include <mapnik/util/vertex_iterator.hpp>
#include <mapnik/util/container_adapter.hpp>
namespace mapnik { namespace util {
boost::tuple<unsigned,bool> 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<unsigned,bool>(type, collection);
}
template <typename OutputIterator>
wkt_generator<OutputIterator>::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 <typename OutputIterator>
wkt_multi_generator<OutputIterator>::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<std::back_insert_iterator<std::string> >;
template struct mapnik::util::wkt_multi_generator<std::back_insert_iterator<std::string> >;
}}

View file

@ -7,3 +7,4 @@ 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)))"
collection, "GEOMETRYCOLLECTION(POLYGON((1 1,2 1,2 2,1 2,1 1)),POINT(2 3),LINESTRING(2 3,3 4))"
1 type WKT
7 multilinestring MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))
8 multipolygon MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))
9 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)))
10 collection GEOMETRYCOLLECTION(POLYGON((1 1,2 1,2 2,1 2,1 1)),POINT(2 3),LINESTRING(2 3,3 4))

Some files were not shown because too many files have changed in this diff Show more