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 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) - MarkersSymbolizer width and height moved to expressions (#1102)
- Added style-level 'opacity' (#314) - Added style-level 'opacity' (#314)

View file

@ -38,4 +38,9 @@ grind:
valgrind --leak-check=full --log-fd=1 $${FILE} | grep definitely; \ valgrind --leak-check=full --log-fd=1 $${FILE} | grep definitely; \
done 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 .PHONY: clean reset uninstall test install

View file

@ -32,6 +32,10 @@ try:
except: except:
HAS_DISTUTILS = False HAS_DISTUTILS = False
if platform.uname()[4] == 'ppc64':
LIBDIR_SCHEMA='lib64'
else:
LIBDIR_SCHEMA='lib'
py3 = None py3 = None
@ -238,14 +242,6 @@ def sort_paths(items,priority):
new.extend(v) new.extend(v)
return new 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): def pretty_dep(dep):
pretty = pretty_dep_names.get(dep) pretty = pretty_dep_names.get(dep)
if pretty: if pretty:
@ -1531,7 +1527,7 @@ if not preconfigured:
if env['DEBUG']: if env['DEBUG']:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags) env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags)
else: 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']: if env['DEBUG_UNDEFINED']:
env.Append(CXXFLAGS = '-fcatch-undefined-behavior -ftrapv -fwrapv') env.Append(CXXFLAGS = '-fcatch-undefined-behavior -ftrapv -fwrapv')

View file

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

View file

@ -72,6 +72,7 @@ void export_logger();
#include <mapnik/version.hpp> #include <mapnik/version.hpp>
#include <mapnik/value_error.hpp> #include <mapnik/value_error.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
#ifdef HAVE_CAIRO #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 // boost
#include <boost/python.hpp> #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) 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) 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); 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() void export_shield_symbolizer()
{ {
using namespace boost::python; using namespace boost::python;
@ -126,7 +94,7 @@ void export_shield_symbolizer()
init<expression_ptr, init<expression_ptr,
std::string const&, std::string const&,
unsigned, mapnik::color const&, unsigned, mapnik::color const&,
path_expression_ptr>("TODO") path_expression_ptr>()
) )
//.def_pickle(shield_symbolizer_pickle_suite()) //.def_pickle(shield_symbolizer_pickle_suite())
.add_property("allow_overlap", .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 // boost
#include <boost/python.hpp> #include <boost/python.hpp>
#include <boost/scoped_array.hpp>
#include <boost/foreach.hpp>
// mapnik // mapnik
#include <mapnik/debug.hpp> #include <mapnik/map.hpp>
#include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid.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 { namespace mapnik {
template <typename T> template <typename T>
static void grid2utf(T const& grid_type, void grid2utf(T const& grid_type,
boost::python::list& l, boost::python::list& l,
std::vector<grid::lookup_type>& key_order) std::vector<typename T::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> template <typename T>
static void grid2utf(T const& grid_type, void grid2utf(T const& grid_type,
boost::python::list& l, boost::python::list& l,
std::vector<typename T::lookup_type>& key_order, std::vector<typename T::lookup_type>& key_order,
unsigned int resolution) 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> template <typename T>
static void grid2utf2(T const& grid_type, void grid2utf2(T const& grid_type,
boost::python::list& l, boost::python::list& l,
std::vector<typename T::lookup_type>& key_order, std::vector<typename T::lookup_type>& key_order,
unsigned int resolution) 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> template <typename T>
static void write_features(T const& grid_type, void write_features(T const& grid_type,
boost::python::dict& feature_data, boost::python::dict& feature_data,
std::vector<typename T::lookup_type> const& key_order) 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> template <typename T>
static void grid_encode_utf(T const& grid_type, void grid_encode_utf(T const& grid_type,
boost::python::dict & json, boost::python::dict & json,
bool add_features, bool add_features,
unsigned int resolution) 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> template <typename T>
static boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution) 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());
}
}
/* new approach: key comes from grid object /* new approach: key comes from grid object
* grid size should be same as the map * grid size should be same as the map
* encoding, resizing handled as method on grid object * encoding, resizing handled as method on grid object
* whether features are dumped is determined by argument not 'fields' * 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, mapnik::grid& grid,
unsigned layer_idx, // TODO - layer by name or index unsigned layer_idx, // TODO - layer by name or index
boost::python::list const& fields) 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 /* old, original impl - to be removed after further testing
* grid object is created on the fly at potentially reduced size * 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 unsigned layer_idx, // layer
std::string const& key, // key_name std::string const& key, // key_name
unsigned int step, // resolution unsigned int step, // resolution
boost::python::list const& fields) 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;
}
} }
#endif // MAPNIK_PYTHON_BINDING_GRID_UTILS_INCLUDED #endif // MAPNIK_PYTHON_BINDING_GRID_UTILS_INCLUDED

View file

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

View file

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

View file

@ -26,8 +26,7 @@
// mapnik // mapnik
#include <mapnik/value.hpp> #include <mapnik/value.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
// boost
#include <boost/foreach.hpp>
// stl // stl
#include <string> #include <string>
@ -53,15 +52,18 @@ struct geometry_type_attribute
template <typename V, typename F> template <typename V, typename F>
V value(F const& f) const V value(F const& f) const
{ {
int result = 0; int type = 0;
geometry_container::const_iterator itr = f.paths().begin(); geometry_container::const_iterator itr = f.paths().begin();
geometry_container::const_iterator end = f.paths().end(); geometry_container::const_iterator end = f.paths().end();
for ( ; itr != end; ++itr) 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/label_collision_detector.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#include <mapnik/pixel_position.hpp> #include <mapnik/pixel_position.hpp>
#include <mapnik/rule.hpp> // for all symbolizers
// cairo // cairo
#include <cairomm/context.h> #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> struct named_colors_ : qi::symbols<char,color>
{ {
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))
;
}
} ; } ;
// clipper helper // clipper helper
template <int MIN,int MAX> template <int MIN,int MAX>
inline int clip_int(int val) inline int clip_int(int val)
{ {
@ -256,19 +104,7 @@ struct alpha_conv_impl
}; };
// http://www.w3.org/TR/css3-color/#hsl-color // http://www.w3.org/TR/css3-color/#hsl-color
inline double hue_to_rgb( double m1, double m2, double h) 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;
}
struct hsl_conv_impl struct hsl_conv_impl
{ {
@ -307,70 +143,7 @@ struct hsl_conv_impl
template <typename Iterator> template <typename Iterator>
struct css_color_grammar : qi::grammar<Iterator, color(), ascii_space_type> struct css_color_grammar : qi::grammar<Iterator, color(), ascii_space_type>
{ {
css_color_grammar();
css_color_grammar()
: css_color_grammar::base_type(css_color)
{
using qi::lit;
using qi::_val;
using qi::double_;
using qi::_1;
using qi::_a;
using qi::_b;
using qi::_c;
using ascii::no_case;
using phoenix::at_c;
css_color %= rgba_color
| rgba_percent_color
| hsl_percent_color
| hex_color
| hex_color_small
| no_case[named];
hex_color = lit('#')
>> hex2 [ at_c<0>(_val) = _1 ]
>> hex2 [ at_c<1>(_val) = _1 ]
>> hex2 [ at_c<2>(_val) = _1 ]
>>-hex2 [ at_c<3>(_val) = _1 ]
;
hex_color_small = lit('#')
>> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ]
>> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ]
>> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ]
>>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ]
;
rgba_color = lit("rgb") >> -lit('a')
>> lit('(')
>> dec3 [at_c<0>(_val) = _1] >> ','
>> dec3 [at_c<1>(_val) = _1] >> ','
>> dec3 [at_c<2>(_val) = _1]
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)])
>> lit(')')
;
rgba_percent_color = lit("rgb") >> -lit('a')
>> lit('(')
>> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ','
>> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ','
>> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%'
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)])
>> lit(')')
;
hsl_percent_color = lit("hsl") >> -lit('a')
>> lit('(')
>> double_ [ _a = _1] >> ',' // hue 0..360
>> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100%
>> double_ [ _c = _1] >> '%' // lightness 0..100%
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1
>> lit (')') [ hsl_converter(_val,_a,_b,_c)]
;
}
qi::uint_parser< unsigned, 16, 2, 2 > hex2 ; qi::uint_parser< unsigned, 16, 2, 2 > hex2 ;
qi::uint_parser< unsigned, 16, 1, 1 > hex1 ; qi::uint_parser< unsigned, 16, 1, 1 > hex1 ;
qi::uint_parser< unsigned, 10, 1, 3 > dec3 ; qi::uint_parser< unsigned, 10, 1, 3 > dec3 ;

View file

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

View file

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

View file

@ -86,14 +86,7 @@ struct regex_match_impl
: tr_(tr) {} : tr_(tr) {}
template <typename T0,typename T1> template <typename T0,typename T1>
expr_node operator() (T0 & node, T1 const& pattern) const 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
}
mapnik::transcoder const& tr_; mapnik::transcoder const& tr_;
}; };
@ -110,14 +103,7 @@ struct regex_replace_impl
: tr_(tr) {} : tr_(tr) {}
template <typename T0,typename T1,typename T2> template <typename T0,typename T1,typename T2>
expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const 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
}
mapnik::transcoder const& tr_; mapnik::transcoder const& tr_;
}; };
@ -128,8 +114,9 @@ struct geometry_types : qi::symbols<char,int>
{ {
add add
("point",1) ("point",1)
("line", 2) ("linestring", 2)
("polygon",3) ("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; typedef qi::rule<Iterator, expr_node(), space_type> rule_type;
explicit expression_grammar(mapnik::transcoder const& tr) 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
}
qi::real_parser<double, qi::strict_real_policies<double> > strict_double; qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
boost::phoenix::function<unicode_impl> unicode_; boost::phoenix::function<unicode_impl> unicode_;
boost::phoenix::function<regex_match_impl> regex_match_; boost::phoenix::function<regex_match_impl> regex_match_;
boost::phoenix::function<regex_replace_impl> regex_replace_; boost::phoenix::function<regex_replace_impl> regex_replace_;
//
rule_type expr; rule_type expr;
rule_type equality_expr; rule_type equality_expr;
rule_type cond_expr; rule_type cond_expr;

View file

@ -28,12 +28,12 @@
#include <mapnik/attribute.hpp> #include <mapnik/attribute.hpp>
// boost // boost
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#if defined(BOOST_REGEX_HAS_ICU) #if defined(BOOST_REGEX_HAS_ICU)
#include <boost/regex/icu.hpp> #include <boost/regex/icu.hpp>
#endif #endif
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp> #include <boost/function.hpp>
namespace mapnik namespace mapnik
@ -240,12 +240,10 @@ struct binary_node
}; };
#if defined(BOOST_REGEX_HAS_ICU) #if defined(BOOST_REGEX_HAS_ICU)
struct regex_match_node struct regex_match_node
{ {
regex_match_node (expr_node const& a, UnicodeString const& ustr) regex_match_node (expr_node const& a, UnicodeString const& ustr);
: expr(a),
pattern(boost::make_u32regex(ustr)) {}
expr_node expr; expr_node expr;
boost::u32regex pattern; boost::u32regex pattern;
}; };
@ -253,22 +251,17 @@ struct regex_match_node
struct regex_replace_node struct regex_replace_node
{ {
regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f) regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f);
: expr(a),
pattern(boost::make_u32regex(ustr)),
format(f) {}
expr_node expr; expr_node expr;
boost::u32regex pattern; boost::u32regex pattern;
UnicodeString format; UnicodeString format;
}; };
#else #else
struct regex_match_node struct regex_match_node
{ {
regex_match_node (expr_node const& a, std::string const& str) regex_match_node (expr_node const& a, std::string const& str);
: expr(a),
pattern(str) {}
expr_node expr; expr_node expr;
boost::regex pattern; boost::regex pattern;
}; };
@ -276,11 +269,7 @@ struct regex_match_node
struct regex_replace_node struct regex_replace_node
{ {
regex_replace_node (expr_node const& a, std::string const& str, std::string const& f) regex_replace_node (expr_node const& a, std::string const& str, std::string const& f);
: expr(a),
pattern(str),
format(f) {}
expr_node expr; expr_node expr;
boost::regex pattern; boost::regex pattern;
std::string format; 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 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, passing a pointer (either raw or shared) as the argument. Without them,
the compiler could construct a temporary expr_node(bool) using the compiler could construct a temporary expr_node(bool) using
implicit pointer-to-bool conversion, thus any non-null pointer implicit pointer-to-bool conversion, thus any non-null pointer
@ -44,19 +44,19 @@ would yield "true".
*/ */
template <typename T> 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"); 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> 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"); 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> template <typename T>
bool clip_test(T p,T q,double& tmin,double& tmax) bool clip_test(T p,T q,double& tmin,double& tmax)
{ {
double r; double r = 0;
bool result=true; bool result=true;
if (p<0.0) 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 x0=boost::get<0>(*start);
double y0=boost::get<1>(*start); double y0=boost::get<1>(*start);
double x1,y1; double x1 = 0;
double y1 = 0;
while (++start!=end) while (++start!=end)
{ {
if ( boost::get<2>(*start) == SEG_MOVETO) 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 x0=boost::get<0>(*start);
double y0=boost::get<1>(*start); double y0=boost::get<1>(*start);
double x1,y1; double x1 = 0;
double y1 = 0;
while (++start != end) while (++start != end)
{ {
if ( boost::get<2>(*start) == SEG_MOVETO) if ( boost::get<2>(*start) == SEG_MOVETO)
@ -222,7 +224,10 @@ struct filter_at_point
template <typename PathType> template <typename PathType>
double path_length(PathType & path) 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); path.rewind(0);
unsigned command = path.vertex(&x0,&y0); unsigned command = path.vertex(&x0,&y0);
if (command == SEG_END) return 0; if (command == SEG_END) return 0;
@ -239,7 +244,10 @@ double path_length(PathType & path)
template <typename PathType> template <typename PathType>
bool middle_point(PathType & path, double & x, double & y) 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); double mid_length = 0.5 * path_length(path);
path.rewind(0); path.rewind(0);
unsigned command = path.vertex(&x0,&y0); unsigned command = path.vertex(&x0,&y0);
@ -268,10 +276,10 @@ namespace label {
template <typename PathType> template <typename PathType>
bool centroid(PathType & path, double & x, double & y) bool centroid(PathType & path, double & x, double & y)
{ {
double x0; double x0 = 0;
double y0; double y0 = 0;
double x1; double x1 = 0;
double y1; double y1 = 0;
double start_x; double start_x;
double start_y; double start_y;
@ -285,7 +293,7 @@ bool centroid(PathType & path, double & x, double & y)
double atmp = 0; double atmp = 0;
double xtmp = 0; double xtmp = 0;
double ytmp = 0; double ytmp = 0;
unsigned count = 1;
while (SEG_END != (command = path.vertex(&x1, &y1))) while (SEG_END != (command = path.vertex(&x1, &y1)))
{ {
double dx0 = x0 - start_x; double dx0 = x0 - start_x;
@ -299,6 +307,14 @@ bool centroid(PathType & path, double & x, double & y)
ytmp += (dy1 + dy0) * ai; ytmp += (dy1 + dy0) * ai;
x0 = x1; x0 = x1;
y0 = y1; y0 = y1;
++count;
}
if (count == 1)
{
x = start_x;
y = start_y;
return true;
} }
if (atmp != 0) if (atmp != 0)
@ -318,7 +334,10 @@ template <typename PathType>
bool hit_test(PathType & path, double x, double y, double tol) bool hit_test(PathType & path, double x, double y, double tol)
{ {
bool inside=false; bool inside=false;
double x0, y0, x1, y1; double x0 = 0;
double y0 = 0;
double x1 = 0;
double y1 = 0;
path.rewind(0); path.rewind(0);
unsigned command = path.vertex(&x0, &y0); unsigned command = path.vertex(&x0, &y0);
if (command == SEG_END) return false; 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 std::vector<double> intersections; // only need to store the X as we know the y
double x0; double x0 = 0;
double y0; double y0 = 0;
path.rewind(0); path.rewind(0);
unsigned command = path.vertex(&x0, &y0); unsigned command = path.vertex(&x0, &y0);
double x1,y1; double x1 = 0;
double y1 = 0;
while (SEG_END != (command = path.vertex(&x1, &y1))) while (SEG_END != (command = path.vertex(&x1, &y1)))
{ {
if (command != SEG_MOVETO) if (command != SEG_MOVETO)

View file

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

View file

@ -97,7 +97,7 @@ public:
return id_name_; 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) inline void add_property_name(std::string const& name)
{ {

View file

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

View file

@ -26,6 +26,9 @@
// mapnik // mapnik
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
// boost
#include <boost/concept_check.hpp>
namespace mapnik { namespace mapnik {
/* /*
@ -45,15 +48,20 @@ static inline void scale_grid(mapnik::grid::data_type & target,
if (source_width<1 || source_height<1 || if (source_width<1 || source_height<1 ||
target_width<1 || target_height<1) return; 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 tw2 = target_width/2;
int th2 = target_height/2; int th2 = target_height/2;
int offs_x = rint((source_width-target_width-x_off_f*2*source_width)/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); int offs_y = rint((source_height-target_height-y_off_f*2*source_height)/2);
unsigned yprt(0); unsigned yprt = 0;
unsigned yprt1(0); unsigned yprt1 = 0;
unsigned xprt(0); unsigned xprt = 0;
unsigned xprt1(0); unsigned xprt1 = 0;
boost::ignore_unused_variable_warning(yprt1);
boost::ignore_unused_variable_warning(xprt1);
//no scaling or subpixel offset //no scaling or subpixel offset
if (target_height == source_height && target_width == source_width && offs_x == 0 && offs_y == 0){ 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_) agg_stack_blur(unsigned rx_, unsigned ry_)
: rx(rx_),ry(ry_) {} : rx(rx_),ry(ry_) {}
// an attempt to support older boost spirit (< 1.46)
agg_stack_blur()
: rx(1),ry(1) {}
unsigned rx; unsigned rx;
unsigned ry; unsigned ry;
}; };

View file

@ -25,6 +25,7 @@
// mapnik // mapnik
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/value.hpp>
// spirit::qi // spirit::qi
#include <boost/config/warning_disable.hpp> #include <boost/config/warning_disable.hpp>
@ -135,196 +136,7 @@ struct feature_grammar :
qi::grammar<Iterator, void(FeatureType&), qi::grammar<Iterator, void(FeatureType&),
space_type> space_type>
{ {
feature_grammar(mapnik::transcoder const& tr) 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
);
}
// start // start
// generic JSON // generic JSON

View file

@ -65,19 +65,21 @@ public:
(*bitmap_data_)->set(0xff000000); (*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 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]; mapnik::svg::path_attributes attr = src[i];
if (strk) if (strk && attr.stroke_flag)
{ {
attr.stroke_flag = true;
attr.stroke_width = strk->get_width(); attr.stroke_width = strk->get_width();
color const& s_color = strk->get_color(); color const& s_color = strk->get_color();
attr.stroke_color = agg::rgba(s_color.red()/255.0,s_color.green()/255.0, 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); 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; color const& f_color = *fill;
attr.fill_color = agg::rgba(f_color.red()/255.0,f_color.green()/255.0, 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); 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/debug.hpp>
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/vertex.hpp> #include <mapnik/vertex.hpp>
#include <mapnik/coord_array.hpp>
#include <mapnik/proj_transform.hpp> #include <mapnik/proj_transform.hpp>
// boost // boost

View file

@ -24,29 +24,15 @@
#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP #define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP
// mapnik // mapnik
#include <mapnik/unicode.hpp> #include <mapnik/attribute.hpp>
#include <mapnik/expression_node.hpp>
#include <mapnik/feature.hpp>
// boost // boost
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <boost/concept_check.hpp>
// spirit2 // spirit2
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.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 // stl
#include <string> #include <string>
#include <vector> #include <vector>
@ -65,29 +51,7 @@ typedef boost::variant<std::string, attribute> path_component;
template <typename Iterator> template <typename Iterator>
struct path_expression_grammar : qi::grammar<Iterator, std::vector<path_component>(), space_type> struct path_expression_grammar : qi::grammar<Iterator, std::vector<path_component>(), space_type>
{ {
path_expression_grammar() path_expression_grammar();
: path_expression_grammar::base_type(expr)
{
using boost::phoenix::construct;
using standard_wide::char_;
using qi::_1;
using qi::_val;
using qi::lit;
using qi::lexeme;
using phoenix::push_back;
expr =
* (
str [ push_back(_val, _1)]
|
( '[' >> attr [ push_back(_val, construct<mapnik::attribute>( _1 )) ] >> ']')
)
;
attr %= +(char_ - ']');
str %= lexeme[+(char_ -'[')];
}
qi::rule<Iterator, std::vector<path_component>() , space_type> expr; qi::rule<Iterator, std::vector<path_component>() , space_type> expr;
qi::rule<Iterator, std::string() , space_type> attr; qi::rule<Iterator, std::string() , space_type> attr;
qi::rule<Iterator, std::string() > str; qi::rule<Iterator, std::string() > str;

View file

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

View file

@ -22,33 +22,36 @@
#ifndef PLACEMENTS_DUMMY_HPP #ifndef PLACEMENTS_DUMMY_HPP
#define PLACEMENTS_DUMMY_HPP #define PLACEMENTS_DUMMY_HPP
// mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/text_placements/base.hpp> #include <mapnik/text_placements/base.hpp>
// boost
#include <boost/concept_check.hpp>
namespace mapnik namespace mapnik
{ {
class text_placements_info_dummy; 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 class MAPNIK_DECL text_placements_dummy: public text_placements
{ {
public: public:
text_placement_info_ptr get_placement_info(double scale_factor) const; text_placement_info_ptr get_placement_info(double scale_factor) const;
friend class text_placement_info_dummy; 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 class MAPNIK_DECL text_placement_info_dummy : public text_placement_info
{ {
public: public:
text_placement_info_dummy(text_placements_dummy const* parent, double scale_factor) text_placement_info_dummy(text_placements_dummy const* parent, double scale_factor)
: text_placement_info(parent, scale_factor), : text_placement_info(parent, scale_factor),
state(0), parent_(parent) {} state(0) {}
bool next(); bool next();
private: private:
unsigned state; unsigned state;
text_placements_dummy const* parent_;
}; };
} //ns mapnik } //ns mapnik

View file

@ -37,7 +37,7 @@
// stl // stl
#include <string> #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)) #define func_deprecated __attribute__ ((deprecated))
#else #else
#define func_deprecated #define func_deprecated

View file

@ -115,7 +115,7 @@ namespace detail {
// boost::spirit::traits::clear<T>(T& val) [with T = boost::variant<...>] // boost::spirit::traits::clear<T>(T& val) [with T = boost::variant<...>]
// attempts to assign to the variant's current value a default-constructed // 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 // default-constructible, but also makes little sense with our variant of
// transform nodes... // transform nodes...

View file

@ -39,65 +39,7 @@ namespace mapnik {
struct transform_expression_grammar struct transform_expression_grammar
: qi::grammar<Iterator, transform_list(), space_type> : qi::grammar<Iterator, transform_list(), space_type>
{ {
explicit transform_expression_grammar(expression_grammar<Iterator> const& g) 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();
}
typedef qi::locals<expr_node, boost::optional<expr_node>, typedef qi::locals<expr_node, boost::optional<expr_node>,
boost::optional<expr_node> boost::optional<expr_node>
> rotate_locals; > rotate_locals;

View file

@ -126,7 +126,8 @@ namespace mapnik { namespace util {
ss.write(reinterpret_cast<char*>(&byte_order),1); ss.write(reinterpret_cast<char*>(&byte_order),1);
int type = static_cast<int>(mapnik::Point); int type = static_cast<int>(mapnik::Point);
write(ss,type,4,byte_order); write(ss,type,4,byte_order);
double x,y; double x(0);
double y(0);
g.vertex(0,&x,&y); g.vertex(0,&x,&y);
write(ss,x,8,byte_order); write(ss,x,8,byte_order);
write(ss,y,8,byte_order); write(ss,y,8,byte_order);
@ -145,7 +146,8 @@ namespace mapnik { namespace util {
int type = static_cast<int>(mapnik::LineString); int type = static_cast<int>(mapnik::LineString);
write(ss,type,4,byte_order); write(ss,type,4,byte_order);
write(ss,num_points,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) for (unsigned i=0; i< num_points; ++i)
{ {
g.vertex(i,&x,&y); g.vertex(i,&x,&y);
@ -165,7 +167,8 @@ namespace mapnik { namespace util {
typedef std::vector<point_type> linear_ring; typedef std::vector<point_type> linear_ring;
boost::ptr_vector<linear_ring> rings; 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 std::size_t size = 1 + 4 + 4 ; // byteOrder + wkbType + numRings
for (unsigned i=0; i< num_points; ++i) for (unsigned i=0; i< num_points; ++i)
{ {

View file

@ -26,8 +26,6 @@
// mapnik // mapnik
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/util/vertex_iterator.hpp>
#include <mapnik/util/container_adapter.hpp>
// boost // boost
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
@ -55,161 +53,88 @@ struct is_container<mapnik::geometry_container>
namespace mapnik { namespace util { namespace mapnik { namespace util {
namespace karma = boost::spirit::karma; namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix; 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 {
struct get_type
{
template <typename T> template <typename T>
struct wkt_coordinate_policy : karma::real_policies<T> struct result { typedef int type; };
{
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 ;}
};
int operator() (geometry_type const& geom) const
{
return static_cast<int>(geom.type());
} }
};
template <typename OutputIterator> struct get_first
struct wkt_generator : {
karma::grammar<OutputIterator, geometry_type const& ()> 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)] bool operator() (geometry_container const& geom) const
<< string[ phoenix::if_ (single) [_1 = "Point("] {
.else_[_1 = "("]] return geom.size() > 1 ? true : false;
<< point_coord [_1 = _first(_val)] << lit(')') }
; };
linestring = &uint_(mapnik::LineString)[_1 = _type(_val)] struct multi_geometry_type
<< string[ phoenix::if_ (single) [_1 = "LineString("] {
.else_[_1 = "("]] template <typename T>
<< coords struct result { typedef boost::tuple<unsigned,bool> type; };
<< lit(')')
;
polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)] boost::tuple<unsigned,bool> operator() (geometry_container const& geom) const;
<< 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] template <typename T>
<< string[ if_ (_r1 > 1) [_1 = "),("] struct wkt_coordinate_policy : karma::real_policies<T>
.else_[_1 = "("] ] | &uint_ << ",") {
<< coord_type typedef boost::spirit::karma::real_policies<T> base_type;
<< lit(' ') static int floatfield(T n) { return base_type::fmtflags::fixed; }
<< coord_type 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;
} karma::rule<OutputIterator, geometry_type const& ()> coords;
// rules karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2;
karma::rule<OutputIterator, geometry_type const& ()> wkt; karma::rule<OutputIterator, geometry_type::value_type ()> point_coord;
karma::rule<OutputIterator, geometry_type const& ()> point; karma::rule<OutputIterator, geometry_type::value_type (unsigned& )> polygon_coord;
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;
};
// 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> template <typename OutputIterator>
@ -217,38 +142,7 @@ struct wkt_multi_generator :
karma::grammar<OutputIterator, karma::locals< boost::tuple<unsigned,bool> >, geometry_container const& ()> karma::grammar<OutputIterator, karma::locals< boost::tuple<unsigned,bool> >, geometry_container const& ()>
{ {
wkt_multi_generator() wkt_multi_generator();
: wkt_multi_generator::base_type(wkt)
{
using boost::spirit::karma::lit;
using boost::spirit::karma::eps;
using boost::spirit::karma::_val;
using boost::spirit::karma::_1;
using boost::spirit::karma::_a;
geometry_types.add
(mapnik::Point,"Point")
(mapnik::LineString,"LineString")
(mapnik::Polygon,"Polygon")
;
wkt = eps(phoenix::at_c<1>(_a))[_a = _multi_type(_val)]
<< lit("GeometryCollection(") << geometry << lit(")")
| eps(is_multi(_val)) << lit("Multi") << geometry_types[_1 = phoenix::at_c<0>(_a)]
<< "(" << multi_geometry << ")"
| geometry
;
geometry = -(single_geometry % lit(','))
;
single_geometry = geometry_types[_1 = _type(_val)] << path
;
multi_geometry = -(path % lit(','))
;
}
// rules // rules
karma::rule<OutputIterator, karma::locals<boost::tuple<unsigned,bool> >, geometry_container const& ()> wkt; karma::rule<OutputIterator, karma::locals<boost::tuple<unsigned,bool> >, geometry_container const& ()> wkt;
karma::rule<OutputIterator, geometry_container const& ()> geometry; karma::rule<OutputIterator, geometry_container const& ()> geometry;

View file

@ -29,10 +29,10 @@ namespace mapnik
{ {
enum CommandType { enum CommandType {
SEG_END =0, SEG_END = 0,
SEG_MOVETO=1, SEG_MOVETO = 1,
SEG_LINETO=2, SEG_LINETO = 2,
SEG_CLOSE =3 SEG_CLOSE = (0x40 | 0x0f)
}; };
template <typename T,int dim> template <typename T,int dim>

View file

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

View file

@ -277,9 +277,9 @@ void csv_datasource::parse_csv(T& stream,
bool has_wkt_field = false; bool has_wkt_field = false;
bool has_lat_field = false; bool has_lat_field = false;
bool has_lon_field = false; bool has_lon_field = false;
unsigned wkt_idx; unsigned wkt_idx(0);
unsigned lat_idx; unsigned lat_idx(0);
unsigned lon_idx; unsigned lon_idx(0);
if (!manual_headers_.empty()) if (!manual_headers_.empty())
{ {

View file

@ -25,9 +25,19 @@
// mapnik // mapnik
#include <mapnik/datasource.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>
// stl // stl
#include <vector> #include <vector>
#include <string>
class csv_datasource : public mapnik::datasource class csv_datasource : public mapnik::datasource
{ {

View file

@ -25,9 +25,19 @@
// mapnik // mapnik
#include <mapnik/datasource.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 // boost
#include <boost/shared_ptr.hpp> #include <boost/optional.hpp>
// stl
#include <vector>
#include <string>
// gdal // gdal
#include <gdal_priv.h> #include <gdal_priv.h>

View file

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

View file

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

View file

@ -25,7 +25,10 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <algorithm>
// boost // boost
#include <boost/variant.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/spirit/include/support_multi_pass.hpp> #include <boost/spirit/include/support_multi_pass.hpp>
@ -36,6 +39,7 @@
#include <boost/geometry/extensions/index/rtree/rtree.hpp> #include <boost/geometry/extensions/index/rtree/rtree.hpp>
// mapnik // mapnik
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/proj_transform.hpp> #include <mapnik/proj_transform.hpp>
#include <mapnik/projection.hpp> #include <mapnik/projection.hpp>
#include <mapnik/json/feature_collection_parser.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 void geojson_datasource::bind() const
{ {
if (is_bound_) return; if (is_bound_) return;
@ -94,6 +136,13 @@ void geojson_datasource::bind() const
{ {
extent_ = box; extent_ = box;
first = false; 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 else
{ {
@ -121,11 +170,6 @@ mapnik::datasource::datasource_t geojson_datasource::type() const
return type_; return type_;
} }
std::map<std::string, mapnik::parameters> geojson_datasource::get_statistics() const
{
return statistics_;
}
mapnik::box2d<double> geojson_datasource::envelope() const mapnik::box2d<double> geojson_datasource::envelope() const
{ {
if (!is_bound_) bind(); if (!is_bound_) bind();

View file

@ -25,7 +25,16 @@
// mapnik // mapnik
#include <mapnik/datasource.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 // boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/geometry/geometries/box.hpp> #include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/point_xy.hpp> #include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/algorithms/area.hpp> #include <boost/geometry/algorithms/area.hpp>
@ -33,6 +42,12 @@
#include <boost/geometry/geometries/geometries.hpp> #include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/extensions/index/rtree/rtree.hpp> #include <boost/geometry/extensions/index/rtree/rtree.hpp>
// stl
#include <vector>
#include <string>
#include <map>
#include <deque>
class geojson_datasource : public mapnik::datasource class geojson_datasource : public mapnik::datasource
{ {
public: public:
@ -49,7 +64,6 @@ public:
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const; mapnik::box2d<double> envelope() const;
mapnik::layer_descriptor get_descriptor() 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; boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
void bind() const; void bind() const;
private: private:

View file

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

View file

@ -40,15 +40,12 @@
using mapnik::query; using mapnik::query;
using mapnik::box2d; using mapnik::box2d;
using mapnik::coord2d;
using mapnik::CoordTransform;
using mapnik::Feature; using mapnik::Feature;
using mapnik::feature_ptr; using mapnik::feature_ptr;
using mapnik::geometry_utils; using mapnik::geometry_utils;
using mapnik::transcoder; using mapnik::transcoder;
using mapnik::feature_factory; using mapnik::feature_factory;
geos_featureset::geos_featureset(GEOSGeometry* geometry, geos_featureset::geos_featureset(GEOSGeometry* geometry,
GEOSGeometry* extent, GEOSGeometry* extent,
int identifier, int identifier,

View file

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

View file

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

View file

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

View file

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

View file

@ -37,7 +37,6 @@
using mapnik::query; using mapnik::query;
using mapnik::box2d; using mapnik::box2d;
using mapnik::CoordTransform;
using mapnik::Feature; using mapnik::Feature;
using mapnik::feature_ptr; using mapnik::feature_ptr;
using mapnik::geometry_type; 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) 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()); 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) void ogr_converter::convert_linestring(OGRLineString* geom, feature_ptr feature)
{ {
int num_points = geom->getNumPoints(); 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)); line->move_to(geom->getX(0), geom->getY(0));
for (int i = 1; i < num_points; ++i) for (int i = 1; i < num_points; ++i)
{ {
line->line_to (geom->getX(i), geom->getY(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) 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_points = exterior->getNumPoints();
int num_interior = geom->getNumInteriorRings(); int num_interior = geom->getNumInteriorRings();
int capacity = 0; int capacity = 0;
for (int r = 0; r < num_interior; r++) for (int r = 0; r < num_interior; ++r)
{ {
OGRLinearRing* interior = geom->getInteriorRing(r); OGRLinearRing* interior = geom->getInteriorRing(r);
capacity += interior->getNumPoints(); 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)); 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)); 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); OGRLinearRing* interior = geom->getInteriorRing(r);
num_points = interior->getNumPoints(); num_points = interior->getNumPoints();
poly->move_to(interior->getX(0), interior->getY(0)); 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->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) void ogr_converter::convert_multipoint(OGRMultiPoint* geom, feature_ptr feature)
{ {
int num_geometries = geom->getNumGeometries(); 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); 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) void ogr_converter::convert_multilinestring(OGRMultiLineString* geom, feature_ptr feature)
{ {
int num_geometries = geom->getNumGeometries(); 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); 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) void ogr_converter::convert_multipolygon(OGRMultiPolygon* geom, feature_ptr feature)
{ {
int num_geometries = geom->getNumGeometries(); 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); 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) void ogr_converter::convert_collection(OGRGeometryCollection* geom, feature_ptr feature)
{ {
int num_geometries = geom->getNumGeometries(); 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); OGRGeometry* g = geom->getGeometryRef(i);
if (g != NULL) if (g != NULL)
@ -165,4 +169,3 @@ void ogr_converter::convert_collection(OGRGeometryCollection* geom, feature_ptr
} }
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -22,6 +22,8 @@
#include "basiccurl.h" #include "basiccurl.h"
#include <iostream>
CURL_LOAD_DATA* grab_http_response(const char* url) CURL_LOAD_DATA* grab_http_response(const char* url)
{ {
CURL_LOAD_DATA* data; 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) CURL_LOAD_DATA* do_grab(CURL* curl,const char* url)
{ {
CURLcode res;
CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)malloc(sizeof(CURL_LOAD_DATA)); CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)malloc(sizeof(CURL_LOAD_DATA));
data->data = NULL; data->data = NULL;
data->nbytes = 0; 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_WRITEFUNCTION, response_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, data); 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; return data;
} }

View file

@ -25,7 +25,20 @@
// mapnik // mapnik
#include <mapnik/datasource.hpp> #include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.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" #include "osm.h"

View file

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

View file

@ -112,7 +112,7 @@ feature_ptr postgis_featureset::next()
totalGeomSize_ += size; totalGeomSize_ += size;
int num_attrs = ctx_->size() + 1; unsigned num_attrs = ctx_->size() + 1;
for (; pos < num_attrs; ++pos) for (; pos < num_attrs; ++pos)
{ {
std::string name = rs_->getFieldName(pos); std::string name = rs_->getFieldName(pos);

View file

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

View file

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

View file

@ -24,9 +24,22 @@
#define RASTER_DATASOURCE_HPP #define RASTER_DATASOURCE_HPP
// mapnik // mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/datasource.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 class raster_datasource : public mapnik::datasource
{ {

View file

@ -22,6 +22,7 @@
// mapnik // mapnik
#include <mapnik/debug.hpp> #include <mapnik/debug.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/image_reader.hpp> #include <mapnik/image_reader.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/feature_factory.hpp> #include <mapnik/feature_factory.hpp>
@ -32,7 +33,6 @@
#include "raster_featureset.hpp" #include "raster_featureset.hpp"
using mapnik::query; using mapnik::query;
using mapnik::CoordTransform;
using mapnik::image_reader; using mapnik::image_reader;
using mapnik::Feature; using mapnik::Feature;
using mapnik::feature_ptr; using mapnik::feature_ptr;
@ -80,7 +80,7 @@ feature_ptr raster_featureset<LookupPolicy>::next()
if (image_width > 0 && image_height > 0) 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> intersect = bbox_.intersect(curIter_->envelope());
box2d<double> ext = t.forward(intersect); box2d<double> ext = t.forward(intersect);
box2d<double> rem = policy_.transform(ext); box2d<double> rem = policy_.transform(ext);

View file

@ -25,10 +25,21 @@
// mapnik // mapnik
#include <mapnik/datasource.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 // boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
// stl
#include <vector>
#include <string>
#include "rasterlite_include.hpp" #include "rasterlite_include.hpp"
class rasterlite_datasource : public mapnik::datasource class rasterlite_datasource : public mapnik::datasource

View file

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

View file

@ -25,11 +25,21 @@
// mapnik // mapnik
#include <mapnik/datasource.hpp> #include <mapnik/datasource.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
// boost // boost
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
// stl
#include <vector>
#include <string>
#include "shape_io.hpp" #include "shape_io.hpp"
using mapnik::datasource; 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(); int num_points = record.read_ndr_integer();
if (num_parts == 1) 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); record.skip(4);
double x = record.read_double(); double x = record.read_double();
double y = record.read_double(); double y = record.read_double();
@ -131,7 +131,7 @@ void shape_io::read_polyline(mapnik::geometry_container & geom)
int start, end; int start, end;
for (int k = 0; k < num_parts; ++k) 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]; start = parts[k];
if (k == num_parts - 1) if (k == num_parts - 1)
{ {
@ -188,9 +188,9 @@ void shape_io::read_polygon(mapnik::geometry_container & geom)
parts[i] = record.read_ndr_integer(); 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 start = parts[k];
int end; int end;
if (k == num_parts - 1) if (k == num_parts - 1)
@ -206,12 +206,16 @@ void shape_io::read_polygon(mapnik::geometry_container & geom)
double y = record.read_double(); double y = record.read_double();
poly->move_to(x, y); 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(); x = record.read_double();
y = record.read_double(); y = record.read_double();
poly->line_to(x, y); poly->line_to(x, y);
} }
x = record.read_double();
y = record.read_double();
poly->close(x, y);
geom.push_back(poly); geom.push_back(poly);
} }
// z-range // z-range

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -3,6 +3,19 @@
// mapnik // mapnik
#include <mapnik/datasource.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 <string>
class hello_datasource : public mapnik::datasource class hello_datasource : public mapnik::datasource
{ {

View file

@ -21,6 +21,8 @@
*****************************************************************************/ *****************************************************************************/
// mapnik // mapnik
#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/graphics.hpp> #include <mapnik/graphics.hpp>
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_rasterizer.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; blend_from = true;
mapnik::filter::filter_visitor<image_32> visitor(*current_buffer_); 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); 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 // apply any 'direct' image filters
mapnik::filter::filter_visitor<image_32> visitor(pixmap_); 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); boost::apply_visitor(visitor, filter_tag);
} }

View file

@ -45,14 +45,18 @@
#include "agg_path_storage.h" #include "agg_path_storage.h"
#include "agg_conv_clip_polyline.h" #include "agg_conv_clip_polyline.h"
#include "agg_conv_transform.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 // boost
#include <boost/optional.hpp> #include <boost/optional.hpp>
namespace mapnik { namespace mapnik {
template <typename BufferType, typename SvgRenderer, typename Rasterizer, typename Detector> 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::rgba8 color_type;
typedef agg::order_rgba order_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_base<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type; 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, SvgRenderer & svg_renderer,
Rasterizer & ras, Rasterizer & ras,
box2d<double> const& bbox, box2d<double> const& bbox,
@ -91,7 +95,6 @@ struct markers_rasterizer_dispatch
if (placement_method == MARKER_POINT_PLACEMENT) if (placement_method == MARKER_POINT_PLACEMENT)
{ {
double x,y; double x,y;
path.rewind(0); path.rewind(0);
label::interior_position(path, x, y); label::interior_position(path, x, y);
@ -124,7 +127,6 @@ struct markers_rasterizer_dispatch
} }
} }
} }
private: private:
agg::scanline_u8 sl_; agg::scanline_u8 sl_;
agg::rendering_buffer buf_; agg::rendering_buffer buf_;
@ -139,11 +141,53 @@ private:
double scale_factor_; 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> double width = src.width();
void agg_renderer<T>::process(markers_symbolizer const& sym, double height = src.height();
mapnik::feature_impl & feature, double p[8];
proj_transform const& prj_trans) 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::rgba8 color_type;
typedef agg::order_rgba order_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_base<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type; 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); std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
if (!filename.empty()) 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); boost::optional<marker_ptr> mark = mapnik::marker_cache::instance()->find(filename, true);
if (mark && *mark) 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->reset();
ras_ptr->gamma(agg::gamma_power()); ras_ptr->gamma(agg::gamma_power());
agg::trans_affine geom_tr; agg::trans_affine geom_tr;
evaluate_transform(geom_tr, feature, sym.get_transform()); evaluate_transform(geom_tr, feature, sym.get_transform());
boost::optional<path_ptr> marker = (*mark)->get_vector_data(); box2d<double> const& bbox = (*mark)->bounding_box();
box2d<double> const& bbox = (*marker)->bounding_box();
agg::trans_affine tr; agg::trans_affine tr;
setup_label_transform(tr, bbox, feature, sym); setup_label_transform(tr, bbox, feature, sym);
tr = agg::trans_affine_scaling(scale_factor_) * tr; tr = agg::trans_affine_scaling(scale_factor_) * tr;
coord2d center = bbox.center(); coord2d center = bbox.center();
agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine_translation recenter(-center.x, -center.y);
agg::trans_affine marker_trans = recenter * tr; agg::trans_affine marker_trans = recenter * tr;
using namespace mapnik::svg; if ((*mark)->is_vector())
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())
{ {
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) if (marker)
{ {
box2d<double> const& bbox = (*marker)->bounding_box(); box2d<double> const& bbox = (*marker)->bounding_box();
coord2d const center = bbox.center(); coord2d center = bbox.center();
agg::trans_affine tr; agg::trans_affine tr;
evaluate_transform(tr, feature, sym.get_image_transform()); evaluate_transform(tr, feature, sym.get_image_transform());
tr = agg::trans_affine_scaling(scale_factor_) * tr; tr = agg::trans_affine_scaling(scale_factor_) * tr;
agg::trans_affine_translation const recenter(-center.x, -center.y); agg::trans_affine_translation recenter(-center.x, -center.y);
agg::trans_affine const recenter_tr = recenter * tr; agg::trans_affine recenter_tr = recenter * tr;
box2d<double> label_ext = bbox * recenter_tr; box2d<double> label_ext = bbox * recenter_tr;
for (unsigned i=0; i<feature.num_geometries(); ++i) for (unsigned i=0; i<feature.num_geometries(); ++i)

View file

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

View file

@ -23,6 +23,8 @@
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
// mapnik // mapnik
#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/debug.hpp> #include <mapnik/debug.hpp>
#include <mapnik/cairo_renderer.hpp> #include <mapnik/cairo_renderer.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
@ -51,7 +53,6 @@
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
// agg // agg
#include "agg_conv_clip_polyline.h" #include "agg_conv_clip_polyline.h"
#include "agg_conv_clip_polygon.h" #include "agg_conv_clip_polygon.h"
#include "agg_conv_smooth_poly1.h" #include "agg_conv_smooth_poly1.h"
@ -494,6 +495,11 @@ public:
{ {
line_to(x, y); 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 // mapnik
#include <mapnik/feature_type_style.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/layer.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/feature_style_processor.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp> #include <mapnik/datasource.hpp>
#include <mapnik/memory_datasource.hpp> #include <mapnik/memory_datasource.hpp>
@ -37,7 +39,8 @@
// boost // boost
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
//stl
// stl
#include <vector> #include <vector>
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)

View file

@ -21,6 +21,8 @@
*****************************************************************************/ *****************************************************************************/
// mapnik // mapnik
#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/debug.hpp> #include <mapnik/debug.hpp>
#include <mapnik/grid/grid_rasterizer.hpp> #include <mapnik/grid/grid_rasterizer.hpp>
#include <mapnik/grid/grid_renderer.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 // mapnik
#include <mapnik/debug.hpp> #include <mapnik/debug.hpp>
#include <mapnik/load_map.hpp> #include <mapnik/load_map.hpp>
#include <mapnik/xml_tree.hpp> #include <mapnik/xml_tree.hpp>
#include <mapnik/version.hpp> #include <mapnik/version.hpp>
#include <mapnik/image_compositing.hpp> #include <mapnik/image_compositing.hpp>
@ -39,16 +37,12 @@
#include <mapnik/font_engine_freetype.hpp> #include <mapnik/font_engine_freetype.hpp>
#include <mapnik/font_set.hpp> #include <mapnik/font_set.hpp>
#include <mapnik/xml_loader.hpp> #include <mapnik/xml_loader.hpp>
#include <mapnik/expression.hpp> #include <mapnik/expression.hpp>
#include <mapnik/parse_path.hpp> #include <mapnik/parse_path.hpp>
#include <mapnik/parse_transform.hpp> #include <mapnik/parse_transform.hpp>
#include <mapnik/raster_colorizer.hpp> #include <mapnik/raster_colorizer.hpp>
#include <mapnik/svg/svg_path_parser.hpp> #include <mapnik/svg/svg_path_parser.hpp>
#include <mapnik/metawriter_factory.hpp> #include <mapnik/metawriter_factory.hpp>
#include <mapnik/text_placements/registry.hpp> #include <mapnik/text_placements/registry.hpp>
#include <mapnik/text_placements/dummy.hpp> #include <mapnik/text_placements/dummy.hpp>
#include <mapnik/symbolizer.hpp> #include <mapnik/symbolizer.hpp>
@ -1062,9 +1056,11 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node)
stroke strk; stroke strk;
if (parse_stroke(strk,node)) if (parse_stroke(strk,node))
{
sym.set_stroke(strk); 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); sym.set_marker_placement(placement);
parse_symbolizer_base(sym, node); parse_symbolizer_base(sym, node);
rule.append(sym); 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 map_parser::parse_stroke(stroke & strk, xml_node const & sym)
{ {
bool result = false; bool result = false;
// stroke color // stroke color
optional<color> c = sym.get_opt_attr<color>("stroke"); optional<color> c = sym.get_opt_attr<color>("stroke");
if (c) if (c)
{ {
strk.set_color(*c);
result = true; result = true;
strk.set_color(*c);
} }
// stroke-width // stroke-width
optional<double> width = sym.get_opt_attr<double>("stroke-width"); optional<double> width = sym.get_opt_attr<double>("stroke-width");
if (width && *width > 0) if (width)
{ {
strk.set_width(*width);
result = true; result = true;
strk.set_width(*width);
} }
// stroke-opacity // stroke-opacity
optional<double> opacity = sym.get_opt_attr<double>("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 // stroke-linejoin
optional<line_join_e> line_join = sym.get_opt_attr<line_join_e>("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/debug.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#include <mapnik/datasource.hpp> #include <mapnik/datasource.hpp>

View file

@ -54,12 +54,12 @@ marker_cache::marker_cache()
insert_svg("ellipse", insert_svg("ellipse",
"<?xml version='1.0' standalone='no'?>" "<?xml version='1.0' standalone='no'?>"
"<svg width='100%' height='100%' version='1.1' xmlns='http://www.w3.org/2000/svg'>" "<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>"); "</svg>");
insert_svg("arrow", insert_svg("arrow",
"<?xml version='1.0' standalone='no'?>" "<?xml version='1.0' standalone='no'?>"
"<svg width='100%' height='100%' version='1.1' xmlns='http://www.w3.org/2000/svg'>" "<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>"); "</svg>");
} }

View file

@ -45,7 +45,10 @@ markers_symbolizer::markers_symbolizer()
allow_overlap_(false), allow_overlap_(false),
spacing_(100.0), spacing_(100.0),
max_error_(0.2), 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) markers_symbolizer::markers_symbolizer(path_expression_ptr const& filename)
: symbolizer_with_image(filename), : symbolizer_with_image(filename),
@ -56,7 +59,10 @@ markers_symbolizer::markers_symbolizer(path_expression_ptr const& filename)
allow_overlap_(false), allow_overlap_(false),
spacing_(100.0), spacing_(100.0),
max_error_(0.2), 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) markers_symbolizer::markers_symbolizer(markers_symbolizer const& rhs)
: symbolizer_with_image(rhs), : symbolizer_with_image(rhs),

View file

@ -22,6 +22,8 @@
// mapnik // mapnik
#include <mapnik/debug.hpp> #include <mapnik/debug.hpp>
#include <mapnik/query.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/memory_datasource.hpp> #include <mapnik/memory_datasource.hpp>
#include <mapnik/memory_featureset.hpp> #include <mapnik/memory_featureset.hpp>
#include <mapnik/feature_factory.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 // mapnik
#include <mapnik/layer.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/debug.hpp> #include <mapnik/debug.hpp>
#include <mapnik/save_map.hpp> #include <mapnik/save_map.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
@ -201,9 +203,11 @@ public:
{ {
set_attr(sym_node, "unlock-image", sym.get_unlock_image()); 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(); pixel_position displacement = sym.get_shield_displacement();
if (displacement.x != dfl.get_shield_displacement().x || explicit_defaults_) 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/debug.hpp>
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/wkb.hpp> #include <mapnik/wkb.hpp>
#include <mapnik/coord_array.hpp>
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
@ -33,6 +34,9 @@
namespace mapnik namespace mapnik
{ {
typedef coord_array<coord2d> CoordinateArray;
struct wkb_reader : boost::noncopyable struct wkb_reader : boost::noncopyable
{ {
private: private:
@ -113,9 +117,6 @@ public:
{ {
int type = read_integer(); int type = read_integer();
#ifdef MAPNIK_LOG
MAPNIK_LOG_DEBUG(wkb_reader) << "wkb_reader: Read=" << wkb_geometry_type_string(type) << "," << type;
#endif
switch (type) switch (type)
{ {
case wkbPoint: case wkbPoint:
@ -246,9 +247,9 @@ private:
void read_point(boost::ptr_vector<geometry_type> & paths) void read_point(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type* pt = new geometry_type(Point);
double x = read_double(); double x = read_double();
double y = read_double(); double y = read_double();
std::auto_ptr<geometry_type> pt(new geometry_type(Point));
pt->move_to(x, y); pt->move_to(x, y);
paths.push_back(pt); paths.push_back(pt);
} }
@ -265,9 +266,9 @@ private:
void read_point_xyz(boost::ptr_vector<geometry_type> & paths) void read_point_xyz(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type* pt = new geometry_type(Point);
double x = read_double(); double x = read_double();
double y = read_double(); double y = read_double();
std::auto_ptr<geometry_type> pt(new geometry_type(Point));
pos_ += 8; // double z = read_double(); pos_ += 8; // double z = read_double();
pt->move_to(x, y); pt->move_to(x, y);
paths.push_back(pt); paths.push_back(pt);
@ -285,16 +286,19 @@ private:
void read_linestring(boost::ptr_vector<geometry_type> & paths) void read_linestring(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type* line = new geometry_type(LineString);
int num_points = read_integer(); int num_points = read_integer();
CoordinateArray ar(num_points); if (num_points > 0)
read_coords(ar);
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); 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) void read_multilinestring(boost::ptr_vector<geometry_type> & paths)
@ -309,16 +313,19 @@ private:
void read_linestring_xyz(boost::ptr_vector<geometry_type> & paths) void read_linestring_xyz(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type* line = new geometry_type(LineString);
int num_points = read_integer(); int num_points = read_integer();
CoordinateArray ar(num_points); if (num_points > 0)
read_coords_xyz(ar);
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); 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) void read_multilinestring_xyz(boost::ptr_vector<geometry_type> & paths)
@ -334,22 +341,28 @@ private:
void read_polygon(boost::ptr_vector<geometry_type> & paths) void read_polygon(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type* poly = new geometry_type(Polygon);
int num_rings = read_integer(); int num_rings = read_integer();
unsigned capacity = 0; if (num_rings > 0)
for (int i = 0; i < num_rings; ++i)
{ {
int num_points = read_integer(); std::auto_ptr<geometry_type> poly(new geometry_type(Polygon));
capacity += num_points; for (int i = 0; i < num_rings; ++i)
CoordinateArray ar(num_points);
read_coords(ar);
poly->move_to(ar[0].x, ar[0].y);
for (int j = 1; j < num_points; ++j)
{ {
poly->line_to(ar[j].x, ar[j].y); 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) void read_multipolygon(boost::ptr_vector<geometry_type> & paths)
@ -364,22 +377,28 @@ private:
void read_polygon_xyz(boost::ptr_vector<geometry_type> & paths) void read_polygon_xyz(boost::ptr_vector<geometry_type> & paths)
{ {
geometry_type* poly = new geometry_type(Polygon);
int num_rings = read_integer(); int num_rings = read_integer();
unsigned capacity = 0; if (num_rings > 0)
for (int i = 0; i < num_rings; ++i)
{ {
int num_points = read_integer(); std::auto_ptr<geometry_type> poly(new geometry_type(Polygon));
capacity += num_points; for (int i = 0; i < num_rings; ++i)
CoordinateArray ar(num_points);
read_coords_xyz(ar);
poly->move_to(ar[0].x, ar[0].y);
for (int j = 1; j < num_points; ++j)
{ {
poly->line_to(ar[j].x, ar[j].y); 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) 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::string wkb_geometry_type_string(int type)
{ {
std::stringstream s; std::stringstream s;
switch (type) switch (type)
{ {
case wkbPoint: s << "wkbPoint"; break; case wkbPoint: s << "Point"; break;
case wkbLineString: s << "wkbLineString"; break; case wkbLineString: s << "LineString"; break;
case wkbPolygon: s << "wkbPolygon"; break; case wkbPolygon: s << "Polygon"; break;
case wkbMultiPoint: s << "wkbMultiPoint"; break; case wkbMultiPoint: s << "MultiPoint"; break;
case wkbMultiLineString: s << "wkbMultiLineString"; break; case wkbMultiLineString: s << "MultiLineString"; break;
case wkbMultiPolygon: s << "wkbMultiPolygon"; break; case wkbMultiPolygon: s << "MultiPolygon"; break;
case wkbGeometryCollection: s << "wkbGeometryCollection"; break; case wkbGeometryCollection: s << "GeometryCollection"; break;
case wkbPointZ: s << "wkbPointZ"; break; case wkbPointZ: s << "PointZ"; break;
case wkbLineStringZ: s << "wkbLineStringZ"; break; case wkbLineStringZ: s << "LineStringZ"; break;
case wkbPolygonZ: s << "wkbPolygonZ"; break; case wkbPolygonZ: s << "PolygonZ"; break;
case wkbMultiPointZ: s << "wkbMultiPointZ"; break; case wkbMultiPointZ: s << "MultiPointZ"; break;
case wkbMultiLineStringZ: s << "wkbMultiLineStringZ"; break; case wkbMultiLineStringZ: s << "MultiLineStringZ"; break;
case wkbMultiPolygonZ: s << "wkbMultiPolygonZ"; break; case wkbMultiPolygonZ: s << "MultiPolygonZ"; break;
case wkbGeometryCollectionZ: s << "wkbGeometryCollectionZ"; break; case wkbGeometryCollectionZ: s << "GeometryCollectionZ"; break;
default: s << "wkbUknown"; break; default: s << "wkbUknown(" << type << ")"; break;
} }
return s.str(); return s.str();
} }
#endif
}; };
bool geometry_utils::from_wkb(boost::ptr_vector<geometry_type>& paths, 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

@ -6,4 +6,5 @@ polygon, "POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30
multipoint, "MULTIPOINT ((10 40), (40 30), (20 20), (30 10))" 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))" 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 (((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)))" 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
6 multipoint MULTIPOINT ((10 40), (40 30), (20 20), (30 10))
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