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:
commit
4e3e5cb0b0
111 changed files with 2588 additions and 1649 deletions
|
@ -11,6 +11,9 @@ For a complete change history, see the git log.
|
|||
|
||||
Not yet released
|
||||
|
||||
- Added support for filtering on a features geometry type, either `point`, `linestring`, 'polygon`,
|
||||
or `collection` using the expression keyword of `[mapnik::geometry_type]` (#546)
|
||||
|
||||
- MarkersSymbolizer width and height moved to expressions (#1102)
|
||||
|
||||
- Added style-level 'opacity' (#314)
|
||||
|
|
5
Makefile
5
Makefile
|
@ -38,4 +38,9 @@ grind:
|
|||
valgrind --leak-check=full --log-fd=1 $${FILE} | grep definitely; \
|
||||
done
|
||||
|
||||
render:
|
||||
@for FILE in tests/data/good_maps/*xml; do \
|
||||
nik2img.py $${FILE} /tmp/$$(basename $${FILE}).png; \
|
||||
done
|
||||
|
||||
.PHONY: clean reset uninstall test install
|
||||
|
|
14
SConstruct
14
SConstruct
|
@ -32,6 +32,10 @@ try:
|
|||
except:
|
||||
HAS_DISTUTILS = False
|
||||
|
||||
if platform.uname()[4] == 'ppc64':
|
||||
LIBDIR_SCHEMA='lib64'
|
||||
else:
|
||||
LIBDIR_SCHEMA='lib'
|
||||
|
||||
py3 = None
|
||||
|
||||
|
@ -238,14 +242,6 @@ def sort_paths(items,priority):
|
|||
new.extend(v)
|
||||
return new
|
||||
|
||||
if platform.dist()[0] in ('Ubuntu','debian'):
|
||||
LIBDIR_SCHEMA='lib'
|
||||
elif platform.uname()[4] == 'ppc64':
|
||||
LIBDIR_SCHEMA='lib64'
|
||||
else:
|
||||
LIBDIR_SCHEMA='lib'
|
||||
|
||||
|
||||
def pretty_dep(dep):
|
||||
pretty = pretty_dep_names.get(dep)
|
||||
if pretty:
|
||||
|
@ -1531,7 +1527,7 @@ if not preconfigured:
|
|||
if env['DEBUG']:
|
||||
env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags)
|
||||
else:
|
||||
env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags))
|
||||
env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -fno-strict-aliasing -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags))
|
||||
|
||||
if env['DEBUG_UNDEFINED']:
|
||||
env.Append(CXXFLAGS = '-fcatch-undefined-behavior -ftrapv -fwrapv')
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
|
|
@ -72,6 +72,7 @@ void export_logger();
|
|||
|
||||
#include <mapnik/version.hpp>
|
||||
#include <mapnik/value_error.hpp>
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#ifdef HAVE_CAIRO
|
||||
|
|
|
@ -21,6 +21,13 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* The functions in this file produce deprecation warnings.
|
||||
* But as shield symbolizer doesn't fully support more than one
|
||||
* placement from python yet these functions are actually the
|
||||
* correct ones.
|
||||
*/
|
||||
#define NO_DEPRECATION_WARNINGS
|
||||
|
||||
// boost
|
||||
#include <boost/python.hpp>
|
||||
|
||||
|
@ -53,12 +60,13 @@ tuple get_shield_displacement(const shield_symbolizer& s)
|
|||
|
||||
void set_shield_displacement(shield_symbolizer & s, boost::python::tuple arg)
|
||||
{
|
||||
s.set_shield_displacement(extract<double>(arg[0]),extract<double>(arg[1]));
|
||||
s.get_placement_options()->defaults.displacement.first = extract<double>(arg[0]);
|
||||
s.get_placement_options()->defaults.displacement.second = extract<double>(arg[1]);
|
||||
}
|
||||
|
||||
tuple get_text_displacement(const shield_symbolizer& t)
|
||||
{
|
||||
pixel_position const& pos = t.get_displacement();
|
||||
pixel_position const& pos = t.get_placement_options()->defaults.displacement;
|
||||
return boost::python::make_tuple(pos.x, pos.y);
|
||||
}
|
||||
|
||||
|
@ -79,46 +87,6 @@ void set_filename(shield_symbolizer & t, std::string const& file_expr)
|
|||
|
||||
}
|
||||
|
||||
struct shield_symbolizer_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
static boost::python::tuple
|
||||
getinitargs(const shield_symbolizer& s)
|
||||
{
|
||||
std::string filename = path_processor_type::to_string(*s.get_filename());
|
||||
//(name, font name, font size, font color, image file, image type, width, height)
|
||||
return boost::python::make_tuple( "TODO",//s.get_name(),
|
||||
s.get_face_name(),s.get_text_size(),s.get_fill(),filename,guess_type(filename));
|
||||
|
||||
}
|
||||
|
||||
static boost::python::tuple
|
||||
getstate(const shield_symbolizer& s)
|
||||
{
|
||||
return boost::python::make_tuple(s.get_halo_fill(),s.get_halo_radius());
|
||||
}
|
||||
|
||||
// TODO add lots more...
|
||||
static void
|
||||
setstate (shield_symbolizer& s, boost::python::tuple state)
|
||||
{
|
||||
using namespace boost::python;
|
||||
/*if (len(state) != 1)
|
||||
{
|
||||
PyErr_SetObject(PyExc_ValueError,
|
||||
("expected 1-item tuple in call to __setstate__; got %s"
|
||||
% state).ptr()
|
||||
);
|
||||
throw_error_already_set();
|
||||
}*/
|
||||
|
||||
s.set_halo_fill(extract<color>(state[0]));
|
||||
s.set_halo_radius(extract<float>(state[1]));
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
void export_shield_symbolizer()
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
@ -126,7 +94,7 @@ void export_shield_symbolizer()
|
|||
init<expression_ptr,
|
||||
std::string const&,
|
||||
unsigned, mapnik::color const&,
|
||||
path_expression_ptr>("TODO")
|
||||
path_expression_ptr>()
|
||||
)
|
||||
//.def_pickle(shield_symbolizer_pickle_suite())
|
||||
.add_property("allow_overlap",
|
||||
|
|
507
bindings/python/python_grid_utils.cpp
Normal file
507
bindings/python/python_grid_utils.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -24,483 +24,66 @@
|
|||
|
||||
// boost
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/grid/grid_renderer.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/grid/grid.hpp>
|
||||
#include <mapnik/grid/grid_util.hpp>
|
||||
#include <mapnik/grid/grid_view.hpp>
|
||||
#include <mapnik/value_error.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/feature_kv_iterator.hpp>
|
||||
#include "mapnik_value_converter.hpp"
|
||||
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
|
||||
template <typename T>
|
||||
static void grid2utf(T const& grid_type,
|
||||
void grid2utf(T const& grid_type,
|
||||
boost::python::list& l,
|
||||
std::vector<grid::lookup_type>& key_order)
|
||||
{
|
||||
typedef std::map< typename T::lookup_type, typename T::value_type> keys_type;
|
||||
typedef typename keys_type::const_iterator keys_iterator;
|
||||
|
||||
typename T::data_type const& data = grid_type.data();
|
||||
typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys();
|
||||
typename T::feature_key_type::const_iterator feature_pos;
|
||||
|
||||
keys_type keys;
|
||||
// start counting at utf8 codepoint 32, aka space character
|
||||
boost::uint16_t codepoint = 32;
|
||||
|
||||
unsigned array_size = data.width();
|
||||
for (unsigned y = 0; y < data.height(); ++y)
|
||||
{
|
||||
boost::uint16_t idx = 0;
|
||||
boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]);
|
||||
typename T::value_type const* row = data.getRow(y);
|
||||
for (unsigned x = 0; x < data.width(); ++x)
|
||||
{
|
||||
typename T::value_type feature_id = row[x];
|
||||
feature_pos = feature_keys.find(feature_id);
|
||||
if (feature_pos != feature_keys.end())
|
||||
{
|
||||
mapnik::grid::lookup_type val = feature_pos->second;
|
||||
keys_iterator key_pos = keys.find(val);
|
||||
if (key_pos == keys.end())
|
||||
{
|
||||
// Create a new entry for this key. Skip the codepoints that
|
||||
// can't be encoded directly in JSON.
|
||||
if (codepoint == 34) ++codepoint; // Skip "
|
||||
else if (codepoint == 92) ++codepoint; // Skip backslash
|
||||
if (feature_id == mapnik::grid::base_mask)
|
||||
{
|
||||
keys[""] = codepoint;
|
||||
key_order.push_back("");
|
||||
}
|
||||
else
|
||||
{
|
||||
keys[val] = codepoint;
|
||||
key_order.push_back(val);
|
||||
}
|
||||
line[idx++] = static_cast<Py_UNICODE>(codepoint);
|
||||
++codepoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
|
||||
}
|
||||
}
|
||||
// else, shouldn't get here...
|
||||
}
|
||||
l.append(boost::python::object(
|
||||
boost::python::handle<>(
|
||||
PyUnicode_FromUnicode(line.get(), array_size))));
|
||||
}
|
||||
}
|
||||
std::vector<typename T::lookup_type>& key_order);
|
||||
|
||||
|
||||
template <typename T>
|
||||
static void grid2utf(T const& grid_type,
|
||||
void grid2utf(T const& grid_type,
|
||||
boost::python::list& l,
|
||||
std::vector<typename T::lookup_type>& key_order,
|
||||
unsigned int resolution)
|
||||
{
|
||||
typedef std::map< typename T::lookup_type, typename T::value_type> keys_type;
|
||||
typedef typename keys_type::const_iterator keys_iterator;
|
||||
|
||||
typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys();
|
||||
typename T::feature_key_type::const_iterator feature_pos;
|
||||
|
||||
keys_type keys;
|
||||
// start counting at utf8 codepoint 32, aka space character
|
||||
boost::uint16_t codepoint = 32;
|
||||
|
||||
// TODO - use double?
|
||||
unsigned array_size = static_cast<unsigned int>(grid_type.width()/resolution);
|
||||
for (unsigned y = 0; y < grid_type.height(); y=y+resolution)
|
||||
{
|
||||
boost::uint16_t idx = 0;
|
||||
boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]);
|
||||
mapnik::grid::value_type const* row = grid_type.getRow(y);
|
||||
for (unsigned x = 0; x < grid_type.width(); x=x+resolution)
|
||||
{
|
||||
typename T::value_type feature_id = row[x];
|
||||
feature_pos = feature_keys.find(feature_id);
|
||||
if (feature_pos != feature_keys.end())
|
||||
{
|
||||
mapnik::grid::lookup_type val = feature_pos->second;
|
||||
keys_iterator key_pos = keys.find(val);
|
||||
if (key_pos == keys.end())
|
||||
{
|
||||
// Create a new entry for this key. Skip the codepoints that
|
||||
// can't be encoded directly in JSON.
|
||||
if (codepoint == 34) ++codepoint; // Skip "
|
||||
else if (codepoint == 92) ++codepoint; // Skip backslash
|
||||
if (feature_id == mapnik::grid::base_mask)
|
||||
{
|
||||
keys[""] = codepoint;
|
||||
key_order.push_back("");
|
||||
}
|
||||
else
|
||||
{
|
||||
keys[val] = codepoint;
|
||||
key_order.push_back(val);
|
||||
}
|
||||
line[idx++] = static_cast<Py_UNICODE>(codepoint);
|
||||
++codepoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
|
||||
}
|
||||
}
|
||||
// else, shouldn't get here...
|
||||
}
|
||||
l.append(boost::python::object(
|
||||
boost::python::handle<>(
|
||||
PyUnicode_FromUnicode(line.get(), array_size))));
|
||||
}
|
||||
}
|
||||
unsigned int resolution);
|
||||
|
||||
|
||||
template <typename T>
|
||||
static void grid2utf2(T const& grid_type,
|
||||
void grid2utf2(T const& grid_type,
|
||||
boost::python::list& l,
|
||||
std::vector<typename T::lookup_type>& key_order,
|
||||
unsigned int resolution)
|
||||
{
|
||||
typedef std::map< typename T::lookup_type, typename T::value_type> keys_type;
|
||||
typedef typename keys_type::const_iterator keys_iterator;
|
||||
|
||||
typename T::data_type const& data = grid_type.data();
|
||||
typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys();
|
||||
typename T::feature_key_type::const_iterator feature_pos;
|
||||
|
||||
keys_type keys;
|
||||
// start counting at utf8 codepoint 32, aka space character
|
||||
uint16_t codepoint = 32;
|
||||
|
||||
mapnik::grid::data_type target(data.width()/resolution,data.height()/resolution);
|
||||
mapnik::scale_grid(target,grid_type.data(),0.0,0.0);
|
||||
|
||||
unsigned array_size = target.width();
|
||||
for (unsigned y = 0; y < target.height(); ++y)
|
||||
{
|
||||
uint16_t idx = 0;
|
||||
boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]);
|
||||
mapnik::grid::value_type * row = target.getRow(y);
|
||||
unsigned x;
|
||||
for (x = 0; x < target.width(); ++x)
|
||||
{
|
||||
feature_pos = feature_keys.find(row[x]);
|
||||
if (feature_pos != feature_keys.end())
|
||||
{
|
||||
mapnik::grid::lookup_type val = feature_pos->second;
|
||||
keys_iterator key_pos = keys.find(val);
|
||||
if (key_pos == keys.end())
|
||||
{
|
||||
// Create a new entry for this key. Skip the codepoints that
|
||||
// can't be encoded directly in JSON.
|
||||
if (codepoint == 34) ++codepoint; // Skip "
|
||||
else if (codepoint == 92) ++codepoint; // Skip backslash
|
||||
keys[val] = codepoint;
|
||||
key_order.push_back(val);
|
||||
line[idx++] = static_cast<Py_UNICODE>(codepoint);
|
||||
++codepoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
|
||||
}
|
||||
}
|
||||
// else, shouldn't get here...
|
||||
}
|
||||
l.append(boost::python::object(
|
||||
boost::python::handle<>(
|
||||
PyUnicode_FromUnicode(line.get(), array_size))));
|
||||
}
|
||||
}
|
||||
unsigned int resolution);
|
||||
|
||||
|
||||
template <typename T>
|
||||
static void write_features(T const& grid_type,
|
||||
void write_features(T const& grid_type,
|
||||
boost::python::dict& feature_data,
|
||||
std::vector<typename T::lookup_type> const& key_order)
|
||||
{
|
||||
std::string const& key = grid_type.get_key();
|
||||
std::set<std::string> const& attributes = grid_type.property_names();
|
||||
typename T::feature_type const& g_features = grid_type.get_grid_features();
|
||||
typename T::feature_type::const_iterator feat_itr = g_features.begin();
|
||||
typename T::feature_type::const_iterator feat_end = g_features.end();
|
||||
bool include_key = (attributes.find(key) != attributes.end());
|
||||
for (; feat_itr != feat_end; ++feat_itr)
|
||||
{
|
||||
mapnik::feature_ptr feature = feat_itr->second;
|
||||
boost::optional<std::string> join_value;
|
||||
if (key == grid_type.key_name())
|
||||
{
|
||||
join_value = feat_itr->first;
|
||||
}
|
||||
else if (feature->has_key(key))
|
||||
{
|
||||
join_value = feature->get(key).to_string();
|
||||
}
|
||||
|
||||
if (join_value)
|
||||
{
|
||||
// only serialize features visible in the grid
|
||||
if(std::find(key_order.begin(), key_order.end(), *join_value) != key_order.end()) {
|
||||
boost::python::dict feat;
|
||||
bool found = false;
|
||||
if (key == grid_type.key_name())
|
||||
{
|
||||
// drop key unless requested
|
||||
if (include_key) {
|
||||
found = true;
|
||||
//TODO - add __id__ as data key?
|
||||
//feat[key] = *join_value;
|
||||
}
|
||||
}
|
||||
|
||||
feature_kv_iterator itr = feature->begin();
|
||||
feature_kv_iterator end = feature->end();
|
||||
for ( ;itr!=end; ++itr)
|
||||
{
|
||||
std::string const& key_name = boost::get<0>(*itr);
|
||||
if (key_name == key) {
|
||||
// drop key unless requested
|
||||
if (include_key) {
|
||||
found = true;
|
||||
feat[key_name] = boost::get<1>(*itr);
|
||||
}
|
||||
}
|
||||
else if ( (attributes.find(key_name) != attributes.end()) )
|
||||
{
|
||||
found = true;
|
||||
feat[key_name] = boost::get<1>(*itr);
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
feature_data[feat_itr->first] = feat;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MAPNIK_LOG_DEBUG(bindings) << "write_features: Should not get here: key " << key << " not found in grid feature properties";
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<typename T::lookup_type> const& key_order);
|
||||
|
||||
template <typename T>
|
||||
static void grid_encode_utf(T const& grid_type,
|
||||
void grid_encode_utf(T const& grid_type,
|
||||
boost::python::dict & json,
|
||||
bool add_features,
|
||||
unsigned int resolution)
|
||||
{
|
||||
// convert buffer to utf and gather key order
|
||||
boost::python::list l;
|
||||
std::vector<typename T::lookup_type> key_order;
|
||||
|
||||
if (resolution != 1) {
|
||||
// resample on the fly - faster, less accurate
|
||||
mapnik::grid2utf<T>(grid_type,l,key_order,resolution);
|
||||
|
||||
// resample first - slower, more accurate
|
||||
//mapnik::grid2utf2<T>(grid_type,l,key_order,resolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapnik::grid2utf<T>(grid_type,l,key_order);
|
||||
}
|
||||
|
||||
// convert key order to proper python list
|
||||
boost::python::list keys_a;
|
||||
BOOST_FOREACH ( typename T::lookup_type const& key_id, key_order )
|
||||
{
|
||||
keys_a.append(key_id);
|
||||
}
|
||||
|
||||
// gather feature data
|
||||
boost::python::dict feature_data;
|
||||
if (add_features) {
|
||||
mapnik::write_features<T>(grid_type,feature_data,key_order);
|
||||
}
|
||||
|
||||
json["grid"] = l;
|
||||
json["keys"] = keys_a;
|
||||
json["data"] = feature_data;
|
||||
|
||||
}
|
||||
unsigned int resolution);
|
||||
|
||||
template <typename T>
|
||||
static boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution)
|
||||
{
|
||||
if (format == "utf") {
|
||||
boost::python::dict json;
|
||||
grid_encode_utf<T>(grid,json,add_features,resolution);
|
||||
return json;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "'utf' is currently the only supported encoding format.";
|
||||
throw mapnik::value_error(s.str());
|
||||
}
|
||||
}
|
||||
boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution);
|
||||
|
||||
/* new approach: key comes from grid object
|
||||
* grid size should be same as the map
|
||||
* encoding, resizing handled as method on grid object
|
||||
* whether features are dumped is determined by argument not 'fields'
|
||||
*/
|
||||
static void render_layer_for_grid(const mapnik::Map& map,
|
||||
void render_layer_for_grid(const mapnik::Map& map,
|
||||
mapnik::grid& grid,
|
||||
unsigned layer_idx, // TODO - layer by name or index
|
||||
boost::python::list const& fields)
|
||||
{
|
||||
std::vector<mapnik::layer> const& layers = map.layers();
|
||||
std::size_t layer_num = layers.size();
|
||||
if (layer_idx >= layer_num) {
|
||||
std::ostringstream s;
|
||||
s << "Zero-based layer index '" << layer_idx << "' not valid, only '"
|
||||
<< layer_num << "' layers are in map\n";
|
||||
throw std::runtime_error(s.str());
|
||||
}
|
||||
|
||||
// convert python list to std::vector
|
||||
boost::python::ssize_t num_fields = boost::python::len(fields);
|
||||
for(boost::python::ssize_t i=0; i<num_fields; i++) {
|
||||
boost::python::extract<std::string> name(fields[i]);
|
||||
if (name.check()) {
|
||||
grid.add_property_name(name());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "list of field names must be strings";
|
||||
throw mapnik::value_error(s.str());
|
||||
}
|
||||
}
|
||||
|
||||
// copy property names
|
||||
std::set<std::string> attributes = grid.property_names();
|
||||
std::string const& key = grid.get_key();
|
||||
|
||||
// if key is special __id__ keyword
|
||||
if (key == grid.key_name())
|
||||
{
|
||||
// TODO - should feature.id() be a first class attribute?
|
||||
|
||||
// if __id__ is requested to be dumped out
|
||||
// remove it so that datasource queries will not break
|
||||
if (attributes.find(key) != attributes.end())
|
||||
{
|
||||
attributes.erase(key);
|
||||
}
|
||||
}
|
||||
// if key is not the special __id__ keyword
|
||||
else if (attributes.find(key) == attributes.end())
|
||||
{
|
||||
// them make sure the datasource query includes this field
|
||||
attributes.insert(key);
|
||||
}
|
||||
|
||||
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
|
||||
mapnik::layer const& layer = layers[layer_idx];
|
||||
ren.apply(layer,attributes);
|
||||
}
|
||||
boost::python::list const& fields);
|
||||
|
||||
/* old, original impl - to be removed after further testing
|
||||
* grid object is created on the fly at potentially reduced size
|
||||
*/
|
||||
static boost::python::dict render_grid(const mapnik::Map& map,
|
||||
boost::python::dict render_grid(const mapnik::Map& map,
|
||||
unsigned layer_idx, // layer
|
||||
std::string const& key, // key_name
|
||||
unsigned int step, // resolution
|
||||
boost::python::list const& fields)
|
||||
{
|
||||
|
||||
std::vector<mapnik::layer> const& layers = map.layers();
|
||||
std::size_t layer_num = layers.size();
|
||||
if (layer_idx >= layer_num) {
|
||||
std::ostringstream s;
|
||||
s << "Zero-based layer index '" << layer_idx << "' not valid, only '"
|
||||
<< layer_num << "' layers are in map\n";
|
||||
throw std::runtime_error(s.str());
|
||||
}
|
||||
|
||||
unsigned int grid_width = map.width()/step;
|
||||
unsigned int grid_height = map.height()/step;
|
||||
|
||||
// TODO - no need to pass step here
|
||||
mapnik::grid grid(grid_width,grid_height,key,step);
|
||||
|
||||
// convert python list to std::vector
|
||||
boost::python::ssize_t num_fields = boost::python::len(fields);
|
||||
for(boost::python::ssize_t i=0; i<num_fields; i++) {
|
||||
boost::python::extract<std::string> name(fields[i]);
|
||||
if (name.check()) {
|
||||
grid.add_property_name(name());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "list of field names must be strings";
|
||||
throw mapnik::value_error(s.str());
|
||||
}
|
||||
}
|
||||
|
||||
// copy property names
|
||||
std::set<std::string> attributes = grid.property_names();
|
||||
|
||||
// if key is special __id__ keyword
|
||||
if (key == grid.key_name())
|
||||
{
|
||||
// TODO - should feature.id() be a first class attribute?
|
||||
|
||||
// if __id__ is requested to be dumped out
|
||||
// remove it so that datasource queries will not break
|
||||
if (attributes.find(key) != attributes.end())
|
||||
{
|
||||
attributes.erase(key);
|
||||
}
|
||||
}
|
||||
// if key is not the special __id__ keyword
|
||||
else if (attributes.find(key) == attributes.end())
|
||||
{
|
||||
// them make sure the datasource query includes this field
|
||||
attributes.insert(key);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
|
||||
mapnik::layer const& layer = layers[layer_idx];
|
||||
ren.apply(layer,attributes);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
bool add_features = false;
|
||||
if (num_fields > 0)
|
||||
add_features = true;
|
||||
// build dictionary and return to python
|
||||
boost::python::dict json;
|
||||
grid_encode_utf(grid,json,add_features,1);
|
||||
return json;
|
||||
}
|
||||
|
||||
boost::python::list const& fields);
|
||||
}
|
||||
|
||||
#endif // MAPNIK_PYTHON_BINDING_GRID_UTILS_INCLUDED
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/rule.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
#include <mapnik/font_engine_freetype.hpp>
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <mapnik/label_collision_detector.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/pixel_position.hpp>
|
||||
#include <mapnik/rule.hpp> // for all symbolizers
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
|
@ -48,6 +49,7 @@ struct trans_affine;
|
|||
namespace mapnik {
|
||||
|
||||
class marker;
|
||||
|
||||
struct rasterizer;
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -26,8 +26,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
// boost
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
|
@ -53,15 +52,18 @@ struct geometry_type_attribute
|
|||
template <typename V, typename F>
|
||||
V value(F const& f) const
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
int type = 0;
|
||||
geometry_container::const_iterator itr = f.paths().begin();
|
||||
geometry_container::const_iterator end = f.paths().end();
|
||||
for ( ; itr != end; ++itr)
|
||||
{
|
||||
result = itr->type();
|
||||
if (type != 0 && itr->type() != type)
|
||||
{
|
||||
return 4; // Collection
|
||||
}
|
||||
type = itr->type();
|
||||
}
|
||||
return result;
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <mapnik/label_collision_detector.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/pixel_position.hpp>
|
||||
#include <mapnik/rule.hpp> // for all symbolizers
|
||||
|
||||
// cairo
|
||||
#include <cairomm/context.h>
|
||||
|
|
|
@ -63,162 +63,10 @@ typedef boost::spirit::ascii::space_type ascii_space_type;
|
|||
|
||||
struct named_colors_ : qi::symbols<char,color>
|
||||
{
|
||||
named_colors_()
|
||||
{
|
||||
add
|
||||
("aliceblue", color(240, 248, 255))
|
||||
("antiquewhite", color(250, 235, 215))
|
||||
("aqua", color(0, 255, 255))
|
||||
("aquamarine", color(127, 255, 212))
|
||||
("azure", color(240, 255, 255))
|
||||
("beige", color(245, 245, 220))
|
||||
("bisque", color(255, 228, 196))
|
||||
("black", color(0, 0, 0))
|
||||
("blanchedalmond", color(255,235,205))
|
||||
("blue", color(0, 0, 255))
|
||||
("blueviolet", color(138, 43, 226))
|
||||
("brown", color(165, 42, 42))
|
||||
("burlywood", color(222, 184, 135))
|
||||
("cadetblue", color(95, 158, 160))
|
||||
("chartreuse", color(127, 255, 0))
|
||||
("chocolate", color(210, 105, 30))
|
||||
("coral", color(255, 127, 80))
|
||||
("cornflowerblue", color(100, 149, 237))
|
||||
("cornsilk", color(255, 248, 220))
|
||||
("crimson", color(220, 20, 60))
|
||||
("cyan", color(0, 255, 255))
|
||||
("darkblue", color(0, 0, 139))
|
||||
("darkcyan", color(0, 139, 139))
|
||||
("darkgoldenrod", color(184, 134, 11))
|
||||
("darkgray", color(169, 169, 169))
|
||||
("darkgreen", color(0, 100, 0))
|
||||
("darkgrey", color(169, 169, 169))
|
||||
("darkkhaki", color(189, 183, 107))
|
||||
("darkmagenta", color(139, 0, 139))
|
||||
("darkolivegreen", color(85, 107, 47))
|
||||
("darkorange", color(255, 140, 0))
|
||||
("darkorchid", color(153, 50, 204))
|
||||
("darkred", color(139, 0, 0))
|
||||
("darksalmon", color(233, 150, 122))
|
||||
("darkseagreen", color(143, 188, 143))
|
||||
("darkslateblue", color(72, 61, 139))
|
||||
("darkslategrey", color(47, 79, 79))
|
||||
("darkturquoise", color(0, 206, 209))
|
||||
("darkviolet", color(148, 0, 211))
|
||||
("deeppink", color(255, 20, 147))
|
||||
("deepskyblue", color(0, 191, 255))
|
||||
("dimgray", color(105, 105, 105))
|
||||
("dimgrey", color(105, 105, 105))
|
||||
("dodgerblue", color(30, 144, 255))
|
||||
("firebrick", color(178, 34, 34))
|
||||
("floralwhite", color(255, 250, 240))
|
||||
("forestgreen", color(34, 139, 34))
|
||||
("fuchsia", color(255, 0, 255))
|
||||
("gainsboro", color(220, 220, 220))
|
||||
("ghostwhite", color(248, 248, 255))
|
||||
("gold", color(255, 215, 0))
|
||||
("goldenrod", color(218, 165, 32))
|
||||
("gray", color(128, 128, 128))
|
||||
("grey", color(128, 128, 128))
|
||||
("green", color(0, 128, 0))
|
||||
("greenyellow", color(173, 255, 47))
|
||||
("honeydew", color(240, 255, 240))
|
||||
("hotpink", color(255, 105, 180))
|
||||
("indianred", color(205, 92, 92))
|
||||
("indigo", color(75, 0, 130))
|
||||
("ivory", color(255, 255, 240))
|
||||
("khaki", color(240, 230, 140))
|
||||
("lavender", color(230, 230, 250))
|
||||
("lavenderblush", color(255, 240, 245))
|
||||
("lawngreen", color(124, 252, 0))
|
||||
("lemonchiffon", color(255, 250, 205))
|
||||
("lightblue", color(173, 216, 230))
|
||||
("lightcoral", color(240, 128, 128))
|
||||
("lightcyan", color(224, 255, 255))
|
||||
("lightgoldenrodyellow", color(250, 250, 210))
|
||||
("lightgray", color(211, 211, 211))
|
||||
("lightgreen", color(144, 238, 144))
|
||||
("lightgrey", color(211, 211, 211))
|
||||
("lightpink", color(255, 182, 193))
|
||||
("lightsalmon", color(255, 160, 122))
|
||||
("lightseagreen", color(32, 178, 170))
|
||||
("lightskyblue", color(135, 206, 250))
|
||||
("lightslategray", color(119, 136, 153))
|
||||
("lightslategrey", color(119, 136, 153))
|
||||
("lightsteelblue", color(176, 196, 222))
|
||||
("lightyellow", color(255, 255, 224))
|
||||
("lime", color(0, 255, 0))
|
||||
("limegreen", color(50, 205, 50))
|
||||
("linen", color(250, 240, 230))
|
||||
("magenta", color(255, 0, 255))
|
||||
("maroon", color(128, 0, 0))
|
||||
("mediumaquamarine", color(102, 205, 170))
|
||||
("mediumblue", color(0, 0, 205))
|
||||
("mediumorchid", color(186, 85, 211))
|
||||
("mediumpurple", color(147, 112, 219))
|
||||
("mediumseagreen", color(60, 179, 113))
|
||||
("mediumslateblue", color(123, 104, 238))
|
||||
("mediumspringgreen", color(0, 250, 154))
|
||||
("mediumturquoise", color(72, 209, 204))
|
||||
("mediumvioletred", color(199, 21, 133))
|
||||
("midnightblue", color(25, 25, 112))
|
||||
("mintcream", color(245, 255, 250))
|
||||
("mistyrose", color(255, 228, 225))
|
||||
("moccasin", color(255, 228, 181))
|
||||
("navajowhite", color(255, 222, 173))
|
||||
("navy", color(0, 0, 128))
|
||||
("oldlace", color(253, 245, 230))
|
||||
("olive", color(128, 128, 0))
|
||||
("olivedrab", color(107, 142, 35))
|
||||
("orange", color(255, 165, 0))
|
||||
("orangered", color(255, 69, 0))
|
||||
("orchid", color(218, 112, 214))
|
||||
("palegoldenrod", color(238, 232, 170))
|
||||
("palegreen", color(152, 251, 152))
|
||||
("paleturquoise", color(175, 238, 238))
|
||||
("palevioletred", color(219, 112, 147))
|
||||
("papayawhip", color(255, 239, 213))
|
||||
("peachpuff", color(255, 218, 185))
|
||||
("peru", color(205, 133, 63))
|
||||
("pink", color(255, 192, 203))
|
||||
("plum", color(221, 160, 221))
|
||||
("powderblue", color(176, 224, 230))
|
||||
("purple", color(128, 0, 128))
|
||||
("red", color(255, 0, 0))
|
||||
("rosybrown", color(188, 143, 143))
|
||||
("royalblue", color(65, 105, 225))
|
||||
("saddlebrown", color(139, 69, 19))
|
||||
("salmon", color(250, 128, 114))
|
||||
("sandybrown", color(244, 164, 96))
|
||||
("seagreen", color(46, 139, 87))
|
||||
("seashell", color(255, 245, 238))
|
||||
("sienna", color(160, 82, 45))
|
||||
("silver", color(192, 192, 192))
|
||||
("skyblue", color(135, 206, 235))
|
||||
("slateblue", color(106, 90, 205))
|
||||
("slategray", color(112, 128, 144))
|
||||
("slategrey", color(112, 128, 144))
|
||||
("snow", color(255, 250, 250))
|
||||
("springgreen", color(0, 255, 127))
|
||||
("steelblue", color(70, 130, 180))
|
||||
("tan", color(210, 180, 140))
|
||||
("teal", color(0, 128, 128))
|
||||
("thistle", color(216, 191, 216))
|
||||
("tomato", color(255, 99, 71))
|
||||
("turquoise", color(64, 224, 208))
|
||||
("violet", color(238, 130, 238))
|
||||
("wheat", color(245, 222, 179))
|
||||
("white", color(255, 255, 255))
|
||||
("whitesmoke", color(245, 245, 245))
|
||||
("yellow", color(255, 255, 0))
|
||||
("yellowgreen", color(154, 205, 50))
|
||||
("transparent", color(0, 0, 0, 0))
|
||||
;
|
||||
}
|
||||
named_colors_();
|
||||
} ;
|
||||
|
||||
// clipper helper
|
||||
|
||||
template <int MIN,int MAX>
|
||||
inline int clip_int(int val)
|
||||
{
|
||||
|
@ -256,19 +104,7 @@ struct alpha_conv_impl
|
|||
};
|
||||
|
||||
// http://www.w3.org/TR/css3-color/#hsl-color
|
||||
inline double hue_to_rgb( double m1, double m2, double h)
|
||||
{
|
||||
if (h < 0.0) h = h + 1.0;
|
||||
else if (h > 1) h = h - 1.0;
|
||||
|
||||
if (h * 6 < 1.0)
|
||||
return m1 + (m2 - m1) * h * 6.0;
|
||||
if (h * 2 < 1.0)
|
||||
return m2;
|
||||
if (h * 3 < 2.0)
|
||||
return m1 + (m2 - m1)* (2.0/3.0 - h) * 6.0;
|
||||
return m1;
|
||||
}
|
||||
inline double hue_to_rgb( double m1, double m2, double h);
|
||||
|
||||
struct hsl_conv_impl
|
||||
{
|
||||
|
@ -307,70 +143,7 @@ struct hsl_conv_impl
|
|||
template <typename Iterator>
|
||||
struct css_color_grammar : qi::grammar<Iterator, color(), ascii_space_type>
|
||||
{
|
||||
|
||||
css_color_grammar()
|
||||
: css_color_grammar::base_type(css_color)
|
||||
|
||||
{
|
||||
using qi::lit;
|
||||
using qi::_val;
|
||||
using qi::double_;
|
||||
using qi::_1;
|
||||
using qi::_a;
|
||||
using qi::_b;
|
||||
using qi::_c;
|
||||
using ascii::no_case;
|
||||
using phoenix::at_c;
|
||||
|
||||
css_color %= rgba_color
|
||||
| rgba_percent_color
|
||||
| hsl_percent_color
|
||||
| hex_color
|
||||
| hex_color_small
|
||||
| no_case[named];
|
||||
|
||||
hex_color = lit('#')
|
||||
>> hex2 [ at_c<0>(_val) = _1 ]
|
||||
>> hex2 [ at_c<1>(_val) = _1 ]
|
||||
>> hex2 [ at_c<2>(_val) = _1 ]
|
||||
>>-hex2 [ at_c<3>(_val) = _1 ]
|
||||
;
|
||||
|
||||
hex_color_small = lit('#')
|
||||
>> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ]
|
||||
>> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ]
|
||||
>> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ]
|
||||
>>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ]
|
||||
;
|
||||
|
||||
rgba_color = lit("rgb") >> -lit('a')
|
||||
>> lit('(')
|
||||
>> dec3 [at_c<0>(_val) = _1] >> ','
|
||||
>> dec3 [at_c<1>(_val) = _1] >> ','
|
||||
>> dec3 [at_c<2>(_val) = _1]
|
||||
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)])
|
||||
>> lit(')')
|
||||
;
|
||||
|
||||
rgba_percent_color = lit("rgb") >> -lit('a')
|
||||
>> lit('(')
|
||||
>> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ','
|
||||
>> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ','
|
||||
>> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%'
|
||||
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)])
|
||||
>> lit(')')
|
||||
;
|
||||
|
||||
hsl_percent_color = lit("hsl") >> -lit('a')
|
||||
>> lit('(')
|
||||
>> double_ [ _a = _1] >> ',' // hue 0..360
|
||||
>> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100%
|
||||
>> double_ [ _c = _1] >> '%' // lightness 0..100%
|
||||
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1
|
||||
>> lit (')') [ hsl_converter(_val,_a,_b,_c)]
|
||||
;
|
||||
}
|
||||
|
||||
css_color_grammar();
|
||||
qi::uint_parser< unsigned, 16, 2, 2 > hex2 ;
|
||||
qi::uint_parser< unsigned, 16, 1, 1 > hex1 ;
|
||||
qi::uint_parser< unsigned, 10, 1, 3 > dec3 ;
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/vertex.hpp>
|
||||
#include <mapnik/coord_array.hpp>
|
||||
#include <mapnik/proj_transform.hpp>
|
||||
|
||||
// stl
|
||||
|
@ -36,8 +35,6 @@
|
|||
namespace mapnik
|
||||
{
|
||||
|
||||
typedef coord_array<coord2d> CoordinateArray;
|
||||
|
||||
template <typename Transform, typename Geometry>
|
||||
struct MAPNIK_DECL coord_transform
|
||||
{
|
||||
|
@ -228,24 +225,6 @@ public:
|
|||
return box2d<double>(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
inline CoordinateArray& forward(CoordinateArray& coords) const
|
||||
{
|
||||
for (unsigned i = 0; i < coords.size(); ++i)
|
||||
{
|
||||
forward(coords[i]);
|
||||
}
|
||||
return coords;
|
||||
}
|
||||
|
||||
inline CoordinateArray& backward(CoordinateArray& coords) const
|
||||
{
|
||||
for (unsigned i = 0; i < coords.size(); ++i)
|
||||
{
|
||||
backward(coords[i]);
|
||||
}
|
||||
return coords;
|
||||
}
|
||||
|
||||
inline box2d<double> const& extent() const
|
||||
{
|
||||
return extent_;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
|
|
|
@ -86,14 +86,7 @@ struct regex_match_impl
|
|||
: tr_(tr) {}
|
||||
|
||||
template <typename T0,typename T1>
|
||||
expr_node operator() (T0 & node, T1 const& pattern) const
|
||||
{
|
||||
#if defined(BOOST_REGEX_HAS_ICU)
|
||||
return regex_match_node(node,tr_.transcode(pattern.c_str()));
|
||||
#else
|
||||
return regex_match_node(node,pattern);
|
||||
#endif
|
||||
}
|
||||
expr_node operator() (T0 & node, T1 const& pattern) const;
|
||||
|
||||
mapnik::transcoder const& tr_;
|
||||
};
|
||||
|
@ -110,14 +103,7 @@ struct regex_replace_impl
|
|||
: tr_(tr) {}
|
||||
|
||||
template <typename T0,typename T1,typename T2>
|
||||
expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const
|
||||
{
|
||||
#if defined(BOOST_REGEX_HAS_ICU)
|
||||
return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str()));
|
||||
#else
|
||||
return regex_replace_node(node,pattern,format);
|
||||
#endif
|
||||
}
|
||||
expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const;
|
||||
|
||||
mapnik::transcoder const& tr_;
|
||||
};
|
||||
|
@ -128,8 +114,9 @@ struct geometry_types : qi::symbols<char,int>
|
|||
{
|
||||
add
|
||||
("point",1)
|
||||
("line", 2)
|
||||
("linestring", 2)
|
||||
("polygon",3)
|
||||
("collection",4)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
@ -139,134 +126,12 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
|||
{
|
||||
typedef qi::rule<Iterator, expr_node(), space_type> rule_type;
|
||||
|
||||
explicit expression_grammar(mapnik::transcoder const& tr)
|
||||
: expression_grammar::base_type(expr),
|
||||
unicode_(unicode_impl(tr)),
|
||||
regex_match_(regex_match_impl(tr)),
|
||||
regex_replace_(regex_replace_impl(tr))
|
||||
{
|
||||
using boost::phoenix::construct;
|
||||
using qi::_1;
|
||||
using qi::_a;
|
||||
using qi::_b;
|
||||
using qi::_r1;
|
||||
#if BOOST_VERSION > 104200
|
||||
using qi::no_skip;
|
||||
#endif
|
||||
using qi::lexeme;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::int_;
|
||||
using qi::double_;
|
||||
using qi::hex;
|
||||
using qi::omit;
|
||||
using standard_wide::char_;
|
||||
using standard_wide::no_case;
|
||||
expr = logical_expr.alias();
|
||||
|
||||
logical_expr = not_expr [_val = _1]
|
||||
>>
|
||||
*( ( ( lit("and") | lit("&&")) >> not_expr [_val && _1] )
|
||||
| (( lit("or") | lit("||")) >> not_expr [_val || _1])
|
||||
)
|
||||
;
|
||||
|
||||
not_expr =
|
||||
cond_expr [_val = _1 ]
|
||||
| ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ])
|
||||
;
|
||||
|
||||
cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1]
|
||||
;
|
||||
|
||||
equality_expr =
|
||||
relational_expr [_val = _1]
|
||||
>> *( ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1])
|
||||
| (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1])
|
||||
)
|
||||
;
|
||||
|
||||
regex_match_expr = lit(".match")
|
||||
>> lit('(')
|
||||
>> ustring [_val = _1]
|
||||
>> lit(')')
|
||||
;
|
||||
|
||||
regex_replace_expr =
|
||||
lit(".replace")
|
||||
>> lit('(')
|
||||
>> ustring [_a = _1]
|
||||
>> lit(',')
|
||||
>> ustring [_b = _1]
|
||||
>> lit(')') [_val = regex_replace_(_r1,_a,_b)]
|
||||
;
|
||||
|
||||
relational_expr = additive_expr[_val = _1]
|
||||
>>
|
||||
*( ( (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ])
|
||||
| ( (lit('<') | lit("lt") ) >> additive_expr [ _val < _1 ])
|
||||
| ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ])
|
||||
| ( (lit('>') | lit("gt") ) >> additive_expr [ _val > _1 ])
|
||||
)
|
||||
;
|
||||
|
||||
additive_expr = multiplicative_expr [_val = _1]
|
||||
>> * ( '+' >> multiplicative_expr[_val += _1]
|
||||
| '-' >> multiplicative_expr[_val -= _1]
|
||||
)
|
||||
;
|
||||
|
||||
multiplicative_expr = unary_expr [_val = _1]
|
||||
>> *( '*' >> unary_expr [_val *= _1]
|
||||
| '/' >> unary_expr [_val /= _1]
|
||||
| '%' >> unary_expr [_val %= _1]
|
||||
| regex_match_expr[_val = regex_match_(_val, _1)]
|
||||
| regex_replace_expr(_val) [_val = _1]
|
||||
)
|
||||
;
|
||||
|
||||
unary_expr = primary_expr [_val = _1]
|
||||
| '+' >> primary_expr [_val = _1]
|
||||
| '-' >> primary_expr [_val = -_1]
|
||||
;
|
||||
|
||||
primary_expr = strict_double [_val = _1]
|
||||
| int_ [_val = _1]
|
||||
| no_case[lit("true")] [_val = true]
|
||||
| no_case[lit("false")] [_val = false]
|
||||
| no_case[lit("null")] [_val = value_null() ]
|
||||
| no_case[geom_type][_val = _1 ]
|
||||
| ustring [_val = unicode_(_1) ]
|
||||
| lit("[mapnik::geometry_type]")[_val = construct<mapnik::geometry_type_attribute>()]
|
||||
| attr [_val = construct<mapnik::attribute>( _1 ) ]
|
||||
| '(' >> expr [_val = _1 ] >> ')'
|
||||
;
|
||||
|
||||
unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n')
|
||||
("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\')
|
||||
("\\\'", '\'')("\\\"", '\"')
|
||||
;
|
||||
|
||||
#if BOOST_VERSION > 104500
|
||||
quote_char %= char_('\'') | char_('"');
|
||||
ustring %= omit[quote_char[_a = _1]]
|
||||
>> *(unesc_char | "\\x" >> hex | (char_ - lit(_a)))
|
||||
>> lit(_a);
|
||||
attr %= '[' >> no_skip[+~char_(']')] >> ']';
|
||||
#else
|
||||
ustring %= lit('\'')
|
||||
>> *(unesc_char | "\\x" >> hex | (char_ - lit('\'')))
|
||||
>> lit('\'');
|
||||
attr %= '[' >> lexeme[+(char_ - ']')] >> ']';
|
||||
#endif
|
||||
|
||||
}
|
||||
explicit expression_grammar(mapnik::transcoder const& tr);
|
||||
|
||||
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
|
||||
boost::phoenix::function<unicode_impl> unicode_;
|
||||
boost::phoenix::function<regex_match_impl> regex_match_;
|
||||
boost::phoenix::function<regex_replace_impl> regex_replace_;
|
||||
//
|
||||
rule_type expr;
|
||||
rule_type equality_expr;
|
||||
rule_type cond_expr;
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
#include <mapnik/attribute.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#if defined(BOOST_REGEX_HAS_ICU)
|
||||
#include <boost/regex/icu.hpp>
|
||||
#endif
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
namespace mapnik
|
||||
|
@ -240,12 +240,10 @@ struct binary_node
|
|||
};
|
||||
|
||||
#if defined(BOOST_REGEX_HAS_ICU)
|
||||
|
||||
struct regex_match_node
|
||||
{
|
||||
regex_match_node (expr_node const& a, UnicodeString const& ustr)
|
||||
: expr(a),
|
||||
pattern(boost::make_u32regex(ustr)) {}
|
||||
|
||||
regex_match_node (expr_node const& a, UnicodeString const& ustr);
|
||||
expr_node expr;
|
||||
boost::u32regex pattern;
|
||||
};
|
||||
|
@ -253,22 +251,17 @@ struct regex_match_node
|
|||
|
||||
struct regex_replace_node
|
||||
{
|
||||
regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f)
|
||||
: expr(a),
|
||||
pattern(boost::make_u32regex(ustr)),
|
||||
format(f) {}
|
||||
|
||||
regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f);
|
||||
expr_node expr;
|
||||
boost::u32regex pattern;
|
||||
UnicodeString format;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct regex_match_node
|
||||
{
|
||||
regex_match_node (expr_node const& a, std::string const& str)
|
||||
: expr(a),
|
||||
pattern(str) {}
|
||||
|
||||
regex_match_node (expr_node const& a, std::string const& str);
|
||||
expr_node expr;
|
||||
boost::regex pattern;
|
||||
};
|
||||
|
@ -276,11 +269,7 @@ struct regex_match_node
|
|||
|
||||
struct regex_replace_node
|
||||
{
|
||||
regex_replace_node (expr_node const& a, std::string const& str, std::string const& f)
|
||||
: expr(a),
|
||||
pattern(str),
|
||||
format(f) {}
|
||||
|
||||
regex_replace_node (expr_node const& a, std::string const& str, std::string const& f);
|
||||
expr_node expr;
|
||||
boost::regex pattern;
|
||||
std::string format;
|
||||
|
|
|
@ -36,7 +36,7 @@ MAPNIK_DECL std::string to_expression_string(expr_node const& node);
|
|||
|
||||
/*
|
||||
The following two templates are intentionally invalid and will prompt
|
||||
a compile error if ever instanciated. This should prevent accidentally
|
||||
a compile error if ever instantiated. This should prevent accidentally
|
||||
passing a pointer (either raw or shared) as the argument. Without them,
|
||||
the compiler could construct a temporary expr_node(bool) using
|
||||
implicit pointer-to-bool conversion, thus any non-null pointer
|
||||
|
@ -44,19 +44,19 @@ would yield "true".
|
|||
*/
|
||||
|
||||
template <typename T>
|
||||
std::string to_expression_string(T const* x)
|
||||
std::string to_expression_string(T const* expr_node_ptr)
|
||||
{
|
||||
x = 0;
|
||||
throw std::logic_error("to_expression_string() called with pointer argument");
|
||||
return std::string();
|
||||
// compile error intended here; comment on the next line shows in clang output
|
||||
return expr_node_ptr; // to_expression_string() called with pointer argument
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string to_expression_string(boost::shared_ptr<T> const& x)
|
||||
std::string to_expression_string(boost::shared_ptr<T> const& expr_node_ptr)
|
||||
{
|
||||
x = 0;
|
||||
throw std::logic_error("to_expression_string() called with pointer argument");
|
||||
return std::string();
|
||||
// compile error intended here; comment on the next line shows in clang output
|
||||
return expr_node_ptr; // to_expression_string() called with pointer argument
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace mapnik
|
|||
template <typename T>
|
||||
bool clip_test(T p,T q,double& tmin,double& tmax)
|
||||
{
|
||||
double r;
|
||||
double r = 0;
|
||||
bool result=true;
|
||||
if (p<0.0)
|
||||
{
|
||||
|
@ -96,7 +96,8 @@ inline bool point_inside_path(double x,double y,Iter start,Iter end)
|
|||
double x0=boost::get<0>(*start);
|
||||
double y0=boost::get<1>(*start);
|
||||
|
||||
double x1,y1;
|
||||
double x1 = 0;
|
||||
double y1 = 0;
|
||||
while (++start!=end)
|
||||
{
|
||||
if ( boost::get<2>(*start) == SEG_MOVETO)
|
||||
|
@ -173,7 +174,8 @@ inline bool point_on_path(double x,double y,Iter start,Iter end, double tol)
|
|||
{
|
||||
double x0=boost::get<0>(*start);
|
||||
double y0=boost::get<1>(*start);
|
||||
double x1,y1;
|
||||
double x1 = 0;
|
||||
double y1 = 0;
|
||||
while (++start != end)
|
||||
{
|
||||
if ( boost::get<2>(*start) == SEG_MOVETO)
|
||||
|
@ -222,7 +224,10 @@ struct filter_at_point
|
|||
template <typename PathType>
|
||||
double path_length(PathType & path)
|
||||
{
|
||||
double x0,y0,x1,y1;
|
||||
double x0 = 0;
|
||||
double y0 = 0;
|
||||
double x1 = 0;
|
||||
double y1 = 0;
|
||||
path.rewind(0);
|
||||
unsigned command = path.vertex(&x0,&y0);
|
||||
if (command == SEG_END) return 0;
|
||||
|
@ -239,7 +244,10 @@ double path_length(PathType & path)
|
|||
template <typename PathType>
|
||||
bool middle_point(PathType & path, double & x, double & y)
|
||||
{
|
||||
double x0,y0,x1,y1;
|
||||
double x0 = 0;
|
||||
double y0 = 0;
|
||||
double x1 = 0;
|
||||
double y1 = 0;
|
||||
double mid_length = 0.5 * path_length(path);
|
||||
path.rewind(0);
|
||||
unsigned command = path.vertex(&x0,&y0);
|
||||
|
@ -268,10 +276,10 @@ namespace label {
|
|||
template <typename PathType>
|
||||
bool centroid(PathType & path, double & x, double & y)
|
||||
{
|
||||
double x0;
|
||||
double y0;
|
||||
double x1;
|
||||
double y1;
|
||||
double x0 = 0;
|
||||
double y0 = 0;
|
||||
double x1 = 0;
|
||||
double y1 = 0;
|
||||
double start_x;
|
||||
double start_y;
|
||||
|
||||
|
@ -285,7 +293,7 @@ bool centroid(PathType & path, double & x, double & y)
|
|||
double atmp = 0;
|
||||
double xtmp = 0;
|
||||
double ytmp = 0;
|
||||
|
||||
unsigned count = 1;
|
||||
while (SEG_END != (command = path.vertex(&x1, &y1)))
|
||||
{
|
||||
double dx0 = x0 - start_x;
|
||||
|
@ -299,6 +307,14 @@ bool centroid(PathType & path, double & x, double & y)
|
|||
ytmp += (dy1 + dy0) * ai;
|
||||
x0 = x1;
|
||||
y0 = y1;
|
||||
++count;
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
x = start_x;
|
||||
y = start_y;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (atmp != 0)
|
||||
|
@ -318,7 +334,10 @@ template <typename PathType>
|
|||
bool hit_test(PathType & path, double x, double y, double tol)
|
||||
{
|
||||
bool inside=false;
|
||||
double x0, y0, x1, y1;
|
||||
double x0 = 0;
|
||||
double y0 = 0;
|
||||
double x1 = 0;
|
||||
double y1 = 0;
|
||||
path.rewind(0);
|
||||
unsigned command = path.vertex(&x0, &y0);
|
||||
if (command == SEG_END) return false;
|
||||
|
@ -363,11 +382,12 @@ void interior_position(PathType & path, double & x, double & y)
|
|||
|
||||
std::vector<double> intersections; // only need to store the X as we know the y
|
||||
|
||||
double x0;
|
||||
double y0;
|
||||
double x0 = 0;
|
||||
double y0 = 0;
|
||||
path.rewind(0);
|
||||
unsigned command = path.vertex(&x0, &y0);
|
||||
double x1,y1;
|
||||
double x1 = 0;
|
||||
double y1 = 0;
|
||||
while (SEG_END != (command = path.vertex(&x1, &y1)))
|
||||
{
|
||||
if (command != SEG_MOVETO)
|
||||
|
|
|
@ -88,8 +88,8 @@ public:
|
|||
box2d<double> envelope() const
|
||||
{
|
||||
box2d<double> result;
|
||||
double x(0);
|
||||
double y(0);
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
rewind(0);
|
||||
for (unsigned i=0;i<size();++i)
|
||||
{
|
||||
|
@ -121,6 +121,11 @@ public:
|
|||
push_vertex(x,y,SEG_MOVETO);
|
||||
}
|
||||
|
||||
void close(coord_type x, coord_type y)
|
||||
{
|
||||
push_vertex(x,y,SEG_CLOSE);
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y) const
|
||||
{
|
||||
return cont_.get_vertex(itr_++,x,y);
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
return id_name_;
|
||||
}
|
||||
|
||||
inline void add_feature(mapnik::feature_impl & feature);
|
||||
void add_feature(mapnik::feature_impl & feature);
|
||||
|
||||
inline void add_property_name(std::string const& name)
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <mapnik/font_engine_freetype.hpp>
|
||||
#include <mapnik/label_collision_detector.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
//#include <mapnik/marker.hpp>
|
||||
#include <mapnik/rule.hpp> // for all symbolizers
|
||||
#include <mapnik/grid/grid.hpp>
|
||||
#include <mapnik/pixel_position.hpp>
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
// mapnik
|
||||
#include <mapnik/grid/grid.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
/*
|
||||
|
@ -45,15 +48,20 @@ static inline void scale_grid(mapnik::grid::data_type & target,
|
|||
|
||||
if (source_width<1 || source_height<1 ||
|
||||
target_width<1 || target_height<1) return;
|
||||
int x=0,y=0,xs=0,ys=0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int xs = 0;
|
||||
int ys = 0;
|
||||
int tw2 = target_width/2;
|
||||
int th2 = target_height/2;
|
||||
int offs_x = rint((source_width-target_width-x_off_f*2*source_width)/2);
|
||||
int offs_y = rint((source_height-target_height-y_off_f*2*source_height)/2);
|
||||
unsigned yprt(0);
|
||||
unsigned yprt1(0);
|
||||
unsigned xprt(0);
|
||||
unsigned xprt1(0);
|
||||
unsigned yprt = 0;
|
||||
unsigned yprt1 = 0;
|
||||
unsigned xprt = 0;
|
||||
unsigned xprt1 = 0;
|
||||
boost::ignore_unused_variable_warning(yprt1);
|
||||
boost::ignore_unused_variable_warning(xprt1);
|
||||
|
||||
//no scaling or subpixel offset
|
||||
if (target_height == source_height && target_width == source_width && offs_x == 0 && offs_y == 0){
|
||||
|
|
|
@ -46,9 +46,6 @@ struct agg_stack_blur
|
|||
{
|
||||
agg_stack_blur(unsigned rx_, unsigned ry_)
|
||||
: rx(rx_),ry(ry_) {}
|
||||
// an attempt to support older boost spirit (< 1.46)
|
||||
agg_stack_blur()
|
||||
: rx(1),ry(1) {}
|
||||
unsigned rx;
|
||||
unsigned ry;
|
||||
};
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
|
||||
// spirit::qi
|
||||
#include <boost/config/warning_disable.hpp>
|
||||
|
@ -135,196 +136,7 @@ struct feature_grammar :
|
|||
qi::grammar<Iterator, void(FeatureType&),
|
||||
space_type>
|
||||
{
|
||||
feature_grammar(mapnik::transcoder const& tr)
|
||||
: feature_grammar::base_type(feature,"feature"),
|
||||
put_property_(put_property(tr))
|
||||
{
|
||||
using qi::lit;
|
||||
using qi::int_;
|
||||
using qi::double_;
|
||||
#if BOOST_VERSION > 104200
|
||||
using qi::no_skip;
|
||||
#else
|
||||
using qi::lexeme;
|
||||
#endif
|
||||
using standard_wide::char_;
|
||||
using qi::_val;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::_a;
|
||||
using qi::_b;
|
||||
using qi::_r1;
|
||||
using qi::_r2;
|
||||
using qi::fail;
|
||||
using qi::on_error;
|
||||
using qi::_pass;
|
||||
using qi::eps;
|
||||
using qi::raw;
|
||||
|
||||
using phoenix::new_;
|
||||
using phoenix::push_back;
|
||||
using phoenix::construct;
|
||||
|
||||
// generic json types
|
||||
value = object | array | string_
|
||||
| number
|
||||
;
|
||||
|
||||
pairs = key_value % lit(',')
|
||||
;
|
||||
|
||||
key_value = (string_ >> lit(':') >> value)
|
||||
;
|
||||
|
||||
object = lit('{')
|
||||
>> *pairs
|
||||
>> lit('}')
|
||||
;
|
||||
array = lit('[')
|
||||
>> value >> *(lit(',') >> value)
|
||||
>> lit(']')
|
||||
;
|
||||
|
||||
number %= strict_double
|
||||
| int_
|
||||
| lit("true") [_val = true]
|
||||
| lit ("false") [_val = false]
|
||||
| lit("null")[_val = construct<value_null>()]
|
||||
;
|
||||
|
||||
unesc_char.add
|
||||
("\\\"", '\"') // quotation mark
|
||||
("\\\\", '\\') // reverse solidus
|
||||
("\\/", '/') // solidus
|
||||
("\\b", '\b') // backspace
|
||||
("\\f", '\f') // formfeed
|
||||
("\\n", '\n') // newline
|
||||
("\\r", '\r') // carrige return
|
||||
("\\t", '\t') // tab
|
||||
;
|
||||
|
||||
string_ %= lit('"') >> *(unesc_char | "\\u" >> hex4 | (char_ - lit('"'))) >> lit('"')
|
||||
;
|
||||
|
||||
// geojson types
|
||||
|
||||
feature_type = lit("\"type\"")
|
||||
>> lit(':')
|
||||
>> lit("\"Feature\"")
|
||||
;
|
||||
|
||||
feature = lit('{')
|
||||
>> (feature_type | (lit("\"geometry\"") > lit(':') > geometry(_r1)) | properties(_r1) | key_value) % lit(',')
|
||||
>> lit('}')
|
||||
;
|
||||
|
||||
properties = lit("\"properties\"")
|
||||
>> lit(':') >> (lit('{') >> attributes(_r1) >> lit('}')) | lit("null")
|
||||
;
|
||||
|
||||
attributes = (string_ [_a = _1] >> lit(':') >> attribute_value [put_property_(_r1,_a,_1)]) % lit(',')
|
||||
;
|
||||
|
||||
attribute_value %= number | string_ ;
|
||||
|
||||
// Nabialek trick - FIXME: how to bind argument to dispatch rule?
|
||||
// geometry = lit("\"geometry\"")
|
||||
// >> lit(':') >> lit('{')
|
||||
// >> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1]
|
||||
// >> lit(',') >> lit("\"coordinates\"") >> lit(':')
|
||||
// >> qi::lazy(*_a)
|
||||
// >> lit('}')
|
||||
// ;
|
||||
// geometry_dispatch.add
|
||||
// ("\"Point\"",&point_coordinates)
|
||||
// ("\"LineString\"",&linestring_coordinates)
|
||||
// ("\"Polygon\"",&polygon_coordinates)
|
||||
// ;
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
geometry = (lit('{')[_a = 0 ]
|
||||
>> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1] // <---- should be Nabialek trick!
|
||||
>> lit(',')
|
||||
>> (lit("\"coordinates\"") > lit(':') > coordinates(_r1,_a)
|
||||
|
|
||||
lit("\"geometries\"") > lit(':')
|
||||
>> lit('[') >> geometry_collection(_r1) >> lit(']'))
|
||||
>> lit('}'))
|
||||
| lit("null")
|
||||
;
|
||||
|
||||
geometry_dispatch.add
|
||||
("\"Point\"",1)
|
||||
("\"LineString\"",2)
|
||||
("\"Polygon\"",3)
|
||||
("\"MultiPoint\"",4)
|
||||
("\"MultiLineString\"",5)
|
||||
("\"MultiPolygon\"",6)
|
||||
("\"GeometryCollection\"",7)
|
||||
//
|
||||
;
|
||||
|
||||
coordinates = (eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1)))
|
||||
| (eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1)))
|
||||
| (eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1)))
|
||||
| (eps(_r2 == 4) > multipoint_coordinates(extract_geometry_(_r1)))
|
||||
| (eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1)))
|
||||
| (eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1)))
|
||||
;
|
||||
|
||||
point_coordinates = eps[ _a = new_<geometry_type>(Point) ]
|
||||
> ( point(SEG_MOVETO,_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false] )
|
||||
;
|
||||
|
||||
linestring_coordinates = eps[ _a = new_<geometry_type>(LineString)]
|
||||
> -(points(_a) [push_back(_r1,_a)]
|
||||
| eps[cleanup_(_a)][_pass = false])
|
||||
;
|
||||
|
||||
polygon_coordinates = eps[ _a = new_<geometry_type>(Polygon) ]
|
||||
> ((lit('[')
|
||||
> -(points(_a) % lit(','))
|
||||
> lit(']')) [push_back(_r1,_a)]
|
||||
| eps[cleanup_(_a)][_pass = false])
|
||||
;
|
||||
|
||||
multipoint_coordinates = lit('[')
|
||||
> -(point_coordinates(_r1) % lit(','))
|
||||
> lit(']')
|
||||
;
|
||||
|
||||
multilinestring_coordinates = lit('[')
|
||||
> -(linestring_coordinates(_r1) % lit(','))
|
||||
> lit(']')
|
||||
;
|
||||
|
||||
multipolygon_coordinates = lit('[')
|
||||
> -(polygon_coordinates(_r1) % lit(','))
|
||||
> lit(']')
|
||||
;
|
||||
|
||||
geometry_collection = *geometry(_r1) >> *(lit(',') >> geometry(_r1))
|
||||
;
|
||||
|
||||
// point
|
||||
point = lit('[') > -((double_ > lit(',') > double_)[push_vertex_(_r1,_r2,_1,_2)]) > lit(']');
|
||||
// points
|
||||
points = lit('[')[_a = SEG_MOVETO] > -(point (_a,_r1) % lit(',')[_a = SEG_LINETO]) > lit(']');
|
||||
on_error<fail>
|
||||
(
|
||||
feature
|
||||
, std::clog
|
||||
<< phoenix::val("Error! Expecting ")
|
||||
<< _4 // what failed?
|
||||
<< phoenix::val(" here: \"")
|
||||
<< construct<std::string>(_3, _2) // iterators to error-pos, end
|
||||
<< phoenix::val("\"")
|
||||
<< std::endl
|
||||
);
|
||||
|
||||
}
|
||||
feature_grammar(mapnik::transcoder const& tr);
|
||||
|
||||
// start
|
||||
// generic JSON
|
||||
|
|
|
@ -65,19 +65,21 @@ public:
|
|||
(*bitmap_data_)->set(0xff000000);
|
||||
}
|
||||
|
||||
marker(const boost::optional<mapnik::image_ptr> &data) : bitmap_data_(data)
|
||||
marker(const boost::optional<mapnik::image_ptr> &data)
|
||||
: bitmap_data_(data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
marker(const boost::optional<mapnik::path_ptr> &data) : vector_data_(data)
|
||||
marker(const boost::optional<mapnik::path_ptr> &data)
|
||||
: vector_data_(data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
marker(const marker& rhs) : bitmap_data_(rhs.bitmap_data_), vector_data_(rhs.vector_data_)
|
||||
{
|
||||
}
|
||||
marker(const marker& rhs)
|
||||
: bitmap_data_(rhs.bitmap_data_), vector_data_(rhs.vector_data_)
|
||||
{}
|
||||
|
||||
box2d<double> bounding_box() const
|
||||
{
|
||||
|
|
|
@ -44,18 +44,15 @@ bool push_explicit_style(Attr const& src, Attr & dst, markers_symbolizer const&
|
|||
{
|
||||
mapnik::svg::path_attributes attr = src[i];
|
||||
|
||||
if (strk)
|
||||
if (strk && attr.stroke_flag)
|
||||
{
|
||||
attr.stroke_flag = true;
|
||||
attr.stroke_width = strk->get_width();
|
||||
color const& s_color = strk->get_color();
|
||||
attr.stroke_color = agg::rgba(s_color.red()/255.0,s_color.green()/255.0,
|
||||
s_color.blue()/255.0,(s_color.alpha()*strk->get_opacity())/255.0);
|
||||
}
|
||||
if (fill)
|
||||
if (fill && attr.fill_flag)
|
||||
{
|
||||
|
||||
attr.fill_flag = true;
|
||||
color const& f_color = *fill;
|
||||
attr.fill_color = agg::rgba(f_color.red()/255.0,f_color.green()/255.0,
|
||||
f_color.blue()/255.0,(f_color.alpha()*sym.get_opacity())/255.0);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/vertex.hpp>
|
||||
#include <mapnik/coord_array.hpp>
|
||||
#include <mapnik/proj_transform.hpp>
|
||||
|
||||
// boost
|
||||
|
|
|
@ -24,29 +24,15 @@
|
|||
#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/expression_node.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/attribute.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
// spirit2
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/qi_action.hpp>
|
||||
|
||||
// fusion
|
||||
#include <boost/fusion/include/adapt_struct.hpp>
|
||||
|
||||
// phoenix
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
#include <boost/spirit/include/phoenix_object.hpp>
|
||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||
#include <boost/spirit/include/phoenix_function.hpp>
|
||||
#include <boost/spirit/include/phoenix_stl.hpp>
|
||||
#include <boost/spirit/home/phoenix/object/construct.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -65,29 +51,7 @@ typedef boost::variant<std::string, attribute> path_component;
|
|||
template <typename Iterator>
|
||||
struct path_expression_grammar : qi::grammar<Iterator, std::vector<path_component>(), space_type>
|
||||
{
|
||||
path_expression_grammar()
|
||||
: path_expression_grammar::base_type(expr)
|
||||
{
|
||||
using boost::phoenix::construct;
|
||||
using standard_wide::char_;
|
||||
using qi::_1;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::lexeme;
|
||||
using phoenix::push_back;
|
||||
|
||||
expr =
|
||||
* (
|
||||
str [ push_back(_val, _1)]
|
||||
|
|
||||
( '[' >> attr [ push_back(_val, construct<mapnik::attribute>( _1 )) ] >> ']')
|
||||
)
|
||||
;
|
||||
|
||||
attr %= +(char_ - ']');
|
||||
str %= lexeme[+(char_ -'[')];
|
||||
}
|
||||
|
||||
path_expression_grammar();
|
||||
qi::rule<Iterator, std::vector<path_component>() , space_type> expr;
|
||||
qi::rule<Iterator, std::string() , space_type> attr;
|
||||
qi::rule<Iterator, std::string() > str;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#ifndef MAPNIK_RULE_HPP
|
||||
#define MAPNIK_RULE_HPP
|
||||
|
||||
// mapni
|
||||
// mapnik
|
||||
#include <mapnik/building_symbolizer.hpp>
|
||||
#include <mapnik/line_symbolizer.hpp>
|
||||
#include <mapnik/line_pattern_symbolizer.hpp>
|
||||
|
|
|
@ -22,33 +22,36 @@
|
|||
#ifndef PLACEMENTS_DUMMY_HPP
|
||||
#define PLACEMENTS_DUMMY_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/text_placements/base.hpp>
|
||||
// boost
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
class text_placements_info_dummy;
|
||||
|
||||
/** Dummy placement algorithm. Always takes the default value. */
|
||||
// Dummy placement algorithm. Always takes the default value.
|
||||
class MAPNIK_DECL text_placements_dummy: public text_placements
|
||||
{
|
||||
public:
|
||||
text_placement_info_ptr get_placement_info(double scale_factor) const;
|
||||
friend class text_placement_info_dummy;
|
||||
text_placement_info_ptr get_placement_info(double scale_factor) const;
|
||||
friend class text_placement_info_dummy;
|
||||
};
|
||||
|
||||
/** Placement info object for dummy placement algorithm. Always takes the default value. */
|
||||
// Placement info object for dummy placement algorithm. Always takes the default value.
|
||||
class MAPNIK_DECL text_placement_info_dummy : public text_placement_info
|
||||
{
|
||||
public:
|
||||
text_placement_info_dummy(text_placements_dummy const* parent, double scale_factor)
|
||||
: text_placement_info(parent, scale_factor),
|
||||
state(0), parent_(parent) {}
|
||||
text_placement_info_dummy(text_placements_dummy const* parent, double scale_factor)
|
||||
: text_placement_info(parent, scale_factor),
|
||||
state(0) {}
|
||||
|
||||
bool next();
|
||||
private:
|
||||
unsigned state;
|
||||
text_placements_dummy const* parent_;
|
||||
unsigned state;
|
||||
};
|
||||
|
||||
} //ns mapnik
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
// stl
|
||||
#include <string>
|
||||
|
||||
#if (1 && __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#if (!defined(NO_DEPRECATION_WARNINGS) && __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#define func_deprecated __attribute__ ((deprecated))
|
||||
#else
|
||||
#define func_deprecated
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace detail {
|
|||
|
||||
// boost::spirit::traits::clear<T>(T& val) [with T = boost::variant<...>]
|
||||
// attempts to assign to the variant's current value a default-constructed
|
||||
// value ot the same type, which not only requires that each value-type is
|
||||
// value of the same type, which not only requires that each value-type is
|
||||
// default-constructible, but also makes little sense with our variant of
|
||||
// transform nodes...
|
||||
|
||||
|
|
|
@ -39,65 +39,7 @@ namespace mapnik {
|
|||
struct transform_expression_grammar
|
||||
: qi::grammar<Iterator, transform_list(), space_type>
|
||||
{
|
||||
explicit transform_expression_grammar(expression_grammar<Iterator> const& g)
|
||||
: transform_expression_grammar::base_type(start)
|
||||
{
|
||||
using boost::phoenix::construct;
|
||||
using qi::_a; using qi::_1; using qi::_4;
|
||||
using qi::_b; using qi::_2; using qi::_5;
|
||||
using qi::_c; using qi::_3; using qi::_6;
|
||||
using qi::_val;
|
||||
using qi::char_;
|
||||
using qi::lit;
|
||||
using qi::no_case;
|
||||
using qi::no_skip;
|
||||
|
||||
start = transform_ % no_skip[char_(", ")] ;
|
||||
|
||||
transform_ = matrix | translate | scale | rotate | skewX | skewY ;
|
||||
|
||||
matrix = no_case[lit("matrix")]
|
||||
>> (lit('(')
|
||||
>> expr >> -lit(',')
|
||||
>> expr >> -lit(',')
|
||||
>> expr >> -lit(',')
|
||||
>> expr >> -lit(',')
|
||||
>> expr >> -lit(',')
|
||||
>> expr >> lit(')'))
|
||||
[ _val = construct<matrix_node>(_1,_2,_3,_4,_5,_6) ];
|
||||
|
||||
translate = no_case[lit("translate")]
|
||||
>> (lit('(')
|
||||
>> expr >> -lit(',')
|
||||
>> -expr >> lit(')'))
|
||||
[ _val = construct<translate_node>(_1,_2) ];
|
||||
|
||||
scale = no_case[lit("scale")]
|
||||
>> (lit('(')
|
||||
>> expr >> -lit(',')
|
||||
>> -expr >> lit(')'))
|
||||
[ _val = construct<scale_node>(_1,_2) ];
|
||||
|
||||
rotate = no_case[lit("rotate")]
|
||||
>> lit('(')
|
||||
>> expr[_a = _1] >> -lit(',')
|
||||
>> -(expr [_b = _1] >> -lit(',') >> expr[_c = _1])
|
||||
>> lit(')')
|
||||
[ _val = construct<rotate_node>(_a,_b,_c) ];
|
||||
|
||||
skewX = no_case[lit("skewX")]
|
||||
>> lit('(')
|
||||
>> expr [ _val = construct<skewX_node>(_1) ]
|
||||
>> lit(')');
|
||||
|
||||
skewY = no_case[lit("skewY")]
|
||||
>> lit('(')
|
||||
>> expr [ _val = construct<skewY_node>(_1) ]
|
||||
>> lit(')');
|
||||
|
||||
expr = g.expr.alias();
|
||||
}
|
||||
|
||||
explicit transform_expression_grammar(expression_grammar<Iterator> const& g);
|
||||
typedef qi::locals<expr_node, boost::optional<expr_node>,
|
||||
boost::optional<expr_node>
|
||||
> rotate_locals;
|
||||
|
|
|
@ -126,7 +126,8 @@ namespace mapnik { namespace util {
|
|||
ss.write(reinterpret_cast<char*>(&byte_order),1);
|
||||
int type = static_cast<int>(mapnik::Point);
|
||||
write(ss,type,4,byte_order);
|
||||
double x,y;
|
||||
double x(0);
|
||||
double y(0);
|
||||
g.vertex(0,&x,&y);
|
||||
write(ss,x,8,byte_order);
|
||||
write(ss,y,8,byte_order);
|
||||
|
@ -145,7 +146,8 @@ namespace mapnik { namespace util {
|
|||
int type = static_cast<int>(mapnik::LineString);
|
||||
write(ss,type,4,byte_order);
|
||||
write(ss,num_points,4,byte_order);
|
||||
double x,y;
|
||||
double x(0);
|
||||
double y(0);
|
||||
for (unsigned i=0; i< num_points; ++i)
|
||||
{
|
||||
g.vertex(i,&x,&y);
|
||||
|
@ -165,7 +167,8 @@ namespace mapnik { namespace util {
|
|||
typedef std::vector<point_type> linear_ring;
|
||||
boost::ptr_vector<linear_ring> rings;
|
||||
|
||||
double x,y;
|
||||
double x(0);
|
||||
double y(0);
|
||||
std::size_t size = 1 + 4 + 4 ; // byteOrder + wkbType + numRings
|
||||
for (unsigned i=0; i< num_points; ++i)
|
||||
{
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/util/vertex_iterator.hpp>
|
||||
#include <mapnik/util/container_adapter.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
@ -55,161 +53,88 @@ struct is_container<mapnik::geometry_container>
|
|||
|
||||
namespace mapnik { namespace util {
|
||||
|
||||
namespace karma = boost::spirit::karma;
|
||||
namespace phoenix = boost::phoenix;
|
||||
|
||||
namespace {
|
||||
|
||||
struct get_type
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef int type; };
|
||||
|
||||
int operator() (geometry_type const& geom) const
|
||||
{
|
||||
return static_cast<int>(geom.type());
|
||||
}
|
||||
};
|
||||
|
||||
struct get_first
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef geometry_type::value_type const type; };
|
||||
|
||||
geometry_type::value_type const operator() (geometry_type const& geom) const
|
||||
{
|
||||
geometry_type::value_type coord;
|
||||
boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord));
|
||||
return coord;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct multi_geometry_
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef bool type; };
|
||||
|
||||
bool operator() (geometry_container const& geom) const
|
||||
{
|
||||
return geom.size() > 1 ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
struct multi_geometry_type
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef boost::tuple<unsigned,bool> type; };
|
||||
|
||||
boost::tuple<unsigned,bool> operator() (geometry_container const& geom) const
|
||||
{
|
||||
unsigned type = 0u;
|
||||
bool collection = false;
|
||||
|
||||
geometry_container::const_iterator itr = geom.begin();
|
||||
geometry_container::const_iterator end = geom.end();
|
||||
|
||||
for ( ; itr != end; ++itr)
|
||||
{
|
||||
if (type != 0 && itr->type() != type)
|
||||
{
|
||||
collection = true;
|
||||
break;
|
||||
}
|
||||
type = itr->type();
|
||||
}
|
||||
return boost::tuple<unsigned,bool>(type, collection);
|
||||
}
|
||||
};
|
||||
namespace karma = boost::spirit::karma;
|
||||
namespace phoenix = boost::phoenix;
|
||||
|
||||
namespace {
|
||||
|
||||
struct get_type
|
||||
{
|
||||
template <typename T>
|
||||
struct wkt_coordinate_policy : karma::real_policies<T>
|
||||
{
|
||||
typedef boost::spirit::karma::real_policies<T> base_type;
|
||||
static int floatfield(T n) { return base_type::fmtflags::fixed; }
|
||||
static unsigned precision(T n) { return 6 ;}
|
||||
};
|
||||
struct result { typedef int type; };
|
||||
|
||||
int operator() (geometry_type const& geom) const
|
||||
{
|
||||
return static_cast<int>(geom.type());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OutputIterator>
|
||||
struct wkt_generator :
|
||||
karma::grammar<OutputIterator, geometry_type const& ()>
|
||||
struct get_first
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef geometry_type::value_type const type; };
|
||||
|
||||
geometry_type::value_type const operator() (geometry_type const& geom) const
|
||||
{
|
||||
geometry_type::value_type coord;
|
||||
boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord));
|
||||
return coord;
|
||||
}
|
||||
};
|
||||
|
||||
wkt_generator(bool single = false)
|
||||
: wkt_generator::base_type(wkt)
|
||||
{
|
||||
using boost::spirit::karma::uint_;
|
||||
using boost::spirit::karma::_val;
|
||||
using boost::spirit::karma::_1;
|
||||
using boost::spirit::karma::lit;
|
||||
using boost::spirit::karma::_a;
|
||||
using boost::spirit::karma::_r1;
|
||||
using boost::spirit::karma::eps;
|
||||
using boost::spirit::karma::string;
|
||||
|
||||
wkt = point | linestring | polygon
|
||||
;
|
||||
struct multi_geometry_
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef bool type; };
|
||||
|
||||
point = &uint_(mapnik::Point)[_1 = _type(_val)]
|
||||
<< string[ phoenix::if_ (single) [_1 = "Point("]
|
||||
.else_[_1 = "("]]
|
||||
<< point_coord [_1 = _first(_val)] << lit(')')
|
||||
;
|
||||
bool operator() (geometry_container const& geom) const
|
||||
{
|
||||
return geom.size() > 1 ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
linestring = &uint_(mapnik::LineString)[_1 = _type(_val)]
|
||||
<< string[ phoenix::if_ (single) [_1 = "LineString("]
|
||||
.else_[_1 = "("]]
|
||||
<< coords
|
||||
<< lit(')')
|
||||
;
|
||||
struct multi_geometry_type
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef boost::tuple<unsigned,bool> type; };
|
||||
|
||||
polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)]
|
||||
<< string[ phoenix::if_ (single) [_1 = "Polygon("]
|
||||
.else_[_1 = "("]]
|
||||
<< coords2
|
||||
<< lit("))")
|
||||
;
|
||||
boost::tuple<unsigned,bool> operator() (geometry_container const& geom) const;
|
||||
};
|
||||
|
||||
point_coord = &uint_ << coord_type << lit(' ') << coord_type
|
||||
;
|
||||
|
||||
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1]
|
||||
<< string[ if_ (_r1 > 1) [_1 = "),("]
|
||||
.else_[_1 = "("] ] | &uint_ << ",")
|
||||
<< coord_type
|
||||
<< lit(' ')
|
||||
<< coord_type
|
||||
;
|
||||
template <typename T>
|
||||
struct wkt_coordinate_policy : karma::real_policies<T>
|
||||
{
|
||||
typedef boost::spirit::karma::real_policies<T> base_type;
|
||||
static int floatfield(T n) { return base_type::fmtflags::fixed; }
|
||||
static unsigned precision(T n) { return 6 ;}
|
||||
};
|
||||
|
||||
coords2 %= *polygon_coord(_a)
|
||||
;
|
||||
}
|
||||
|
||||
coords = point_coord % lit(',')
|
||||
;
|
||||
template <typename OutputIterator>
|
||||
struct wkt_generator :
|
||||
karma::grammar<OutputIterator, geometry_type const& ()>
|
||||
{
|
||||
wkt_generator(bool single = false);
|
||||
// rules
|
||||
karma::rule<OutputIterator, geometry_type const& ()> wkt;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> point;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> linestring;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> polygon;
|
||||
|
||||
}
|
||||
// rules
|
||||
karma::rule<OutputIterator, geometry_type const& ()> wkt;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> point;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> linestring;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> polygon;
|
||||
|
||||
karma::rule<OutputIterator, geometry_type const& ()> coords;
|
||||
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2;
|
||||
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord;
|
||||
karma::rule<OutputIterator, geometry_type::value_type (unsigned& )> polygon_coord;
|
||||
|
||||
// phoenix functions
|
||||
phoenix::function<get_type > _type;
|
||||
phoenix::function<get_first> _first;
|
||||
//
|
||||
karma::real_generator<double, wkt_coordinate_policy<double> > coord_type;
|
||||
|
||||
};
|
||||
karma::rule<OutputIterator, geometry_type const& ()> coords;
|
||||
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2;
|
||||
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord;
|
||||
karma::rule<OutputIterator, geometry_type::value_type (unsigned& )> polygon_coord;
|
||||
|
||||
// phoenix functions
|
||||
phoenix::function<get_type > _type;
|
||||
phoenix::function<get_first> _first;
|
||||
//
|
||||
karma::real_generator<double, wkt_coordinate_policy<double> > coord_type;
|
||||
};
|
||||
|
||||
|
||||
template <typename OutputIterator>
|
||||
|
@ -217,38 +142,7 @@ struct wkt_multi_generator :
|
|||
karma::grammar<OutputIterator, karma::locals< boost::tuple<unsigned,bool> >, geometry_container const& ()>
|
||||
{
|
||||
|
||||
wkt_multi_generator()
|
||||
: wkt_multi_generator::base_type(wkt)
|
||||
{
|
||||
using boost::spirit::karma::lit;
|
||||
using boost::spirit::karma::eps;
|
||||
using boost::spirit::karma::_val;
|
||||
using boost::spirit::karma::_1;
|
||||
using boost::spirit::karma::_a;
|
||||
|
||||
geometry_types.add
|
||||
(mapnik::Point,"Point")
|
||||
(mapnik::LineString,"LineString")
|
||||
(mapnik::Polygon,"Polygon")
|
||||
;
|
||||
|
||||
wkt = eps(phoenix::at_c<1>(_a))[_a = _multi_type(_val)]
|
||||
<< lit("GeometryCollection(") << geometry << lit(")")
|
||||
| eps(is_multi(_val)) << lit("Multi") << geometry_types[_1 = phoenix::at_c<0>(_a)]
|
||||
<< "(" << multi_geometry << ")"
|
||||
| geometry
|
||||
;
|
||||
|
||||
geometry = -(single_geometry % lit(','))
|
||||
;
|
||||
|
||||
single_geometry = geometry_types[_1 = _type(_val)] << path
|
||||
;
|
||||
|
||||
multi_geometry = -(path % lit(','))
|
||||
;
|
||||
|
||||
}
|
||||
wkt_multi_generator();
|
||||
// rules
|
||||
karma::rule<OutputIterator, karma::locals<boost::tuple<unsigned,bool> >, geometry_container const& ()> wkt;
|
||||
karma::rule<OutputIterator, geometry_container const& ()> geometry;
|
||||
|
|
|
@ -29,10 +29,10 @@ namespace mapnik
|
|||
{
|
||||
|
||||
enum CommandType {
|
||||
SEG_END =0,
|
||||
SEG_MOVETO=1,
|
||||
SEG_LINETO=2,
|
||||
SEG_CLOSE =3
|
||||
SEG_END = 0,
|
||||
SEG_MOVETO = 1,
|
||||
SEG_LINETO = 2,
|
||||
SEG_CLOSE = (0x40 | 0x0f)
|
||||
};
|
||||
|
||||
template <typename T,int dim>
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
|
|
|
@ -277,9 +277,9 @@ void csv_datasource::parse_csv(T& stream,
|
|||
bool has_wkt_field = false;
|
||||
bool has_lat_field = false;
|
||||
bool has_lon_field = false;
|
||||
unsigned wkt_idx;
|
||||
unsigned lat_idx;
|
||||
unsigned lon_idx;
|
||||
unsigned wkt_idx(0);
|
||||
unsigned lat_idx(0);
|
||||
unsigned lon_idx(0);
|
||||
|
||||
if (!manual_headers_.empty())
|
||||
{
|
||||
|
|
|
@ -25,9 +25,19 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class csv_datasource : public mapnik::datasource
|
||||
{
|
||||
|
|
|
@ -25,9 +25,19 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// gdal
|
||||
#include <gdal_priv.h>
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/feature_factory.hpp>
|
||||
|
||||
// boost
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include <boost/variant.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include "gdal_datasource.hpp"
|
||||
|
||||
class GDALDataset;
|
||||
class GDALRasterBand;
|
||||
|
||||
|
|
|
@ -25,7 +25,10 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
// boost
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/spirit/include/support_multi_pass.hpp>
|
||||
|
@ -36,6 +39,7 @@
|
|||
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||
// mapnik
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/proj_transform.hpp>
|
||||
#include <mapnik/projection.hpp>
|
||||
#include <mapnik/json/feature_collection_parser.hpp>
|
||||
|
@ -63,6 +67,44 @@ geojson_datasource::geojson_datasource(parameters const& params, bool bind)
|
|||
}
|
||||
}
|
||||
|
||||
struct attr_value_converter : public boost::static_visitor<mapnik::eAttributeType>
|
||||
{
|
||||
mapnik::eAttributeType operator() (int /*val*/) const
|
||||
{
|
||||
return mapnik::Integer;
|
||||
}
|
||||
|
||||
mapnik::eAttributeType operator() (double /*val*/) const
|
||||
{
|
||||
return mapnik::Double;
|
||||
}
|
||||
|
||||
mapnik::eAttributeType operator() (float /*val*/) const
|
||||
{
|
||||
return mapnik::Double;
|
||||
}
|
||||
|
||||
mapnik::eAttributeType operator() (bool /*val*/) const
|
||||
{
|
||||
return mapnik::Boolean;
|
||||
}
|
||||
|
||||
mapnik::eAttributeType operator() (std::string const& /*val*/) const
|
||||
{
|
||||
return mapnik::String;
|
||||
}
|
||||
|
||||
mapnik::eAttributeType operator() (UnicodeString const& /*val*/) const
|
||||
{
|
||||
return mapnik::String;
|
||||
}
|
||||
|
||||
mapnik::eAttributeType operator() (mapnik::value_null const& /*val*/) const
|
||||
{
|
||||
return mapnik::String;
|
||||
}
|
||||
};
|
||||
|
||||
void geojson_datasource::bind() const
|
||||
{
|
||||
if (is_bound_) return;
|
||||
|
@ -94,6 +136,13 @@ void geojson_datasource::bind() const
|
|||
{
|
||||
extent_ = box;
|
||||
first = false;
|
||||
mapnik::feature_kv_iterator itr = f->begin();
|
||||
mapnik::feature_kv_iterator end = f->end();
|
||||
for ( ;itr!=end; ++itr)
|
||||
{
|
||||
desc_.add_descriptor(mapnik::attribute_descriptor(boost::get<0>(*itr),
|
||||
boost::apply_visitor(attr_value_converter(),boost::get<1>(*itr).base())));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -121,11 +170,6 @@ mapnik::datasource::datasource_t geojson_datasource::type() const
|
|||
return type_;
|
||||
}
|
||||
|
||||
std::map<std::string, mapnik::parameters> geojson_datasource::get_statistics() const
|
||||
{
|
||||
return statistics_;
|
||||
}
|
||||
|
||||
mapnik::box2d<double> geojson_datasource::envelope() const
|
||||
{
|
||||
if (!is_bound_) bind();
|
||||
|
|
|
@ -25,7 +25,16 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
|
@ -33,6 +42,12 @@
|
|||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
class geojson_datasource : public mapnik::datasource
|
||||
{
|
||||
public:
|
||||
|
@ -49,7 +64,6 @@ public:
|
|||
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
std::map<std::string, mapnik::parameters> get_statistics() const;
|
||||
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||
void bind() const;
|
||||
private:
|
||||
|
|
|
@ -25,12 +25,21 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "geos_feature_ptr.hpp"
|
||||
|
||||
class geos_datasource : public mapnik::datasource
|
||||
|
|
|
@ -40,15 +40,12 @@
|
|||
|
||||
using mapnik::query;
|
||||
using mapnik::box2d;
|
||||
using mapnik::coord2d;
|
||||
using mapnik::CoordTransform;
|
||||
using mapnik::Feature;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::geometry_utils;
|
||||
using mapnik::transcoder;
|
||||
using mapnik::feature_factory;
|
||||
|
||||
|
||||
geos_featureset::geos_featureset(GEOSGeometry* geometry,
|
||||
GEOSGeometry* extent,
|
||||
int identifier,
|
||||
|
|
|
@ -23,21 +23,25 @@
|
|||
#ifndef KISMET_DATASOURCE_HPP
|
||||
#define KISMET_DATASOURCE_HPP
|
||||
|
||||
// stl
|
||||
#include <list>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
// sqlite
|
||||
// stl
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "kismet_types.hpp"
|
||||
|
||||
class kismet_datasource : public mapnik::datasource
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
#include <mapnik/projection.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
|
|
@ -25,13 +25,21 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// oci
|
||||
#include "occi_types.hpp"
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
using mapnik::query;
|
||||
using mapnik::box2d;
|
||||
using mapnik::CoordTransform;
|
||||
using mapnik::Feature;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::geometry_type;
|
||||
|
|
|
@ -79,21 +79,21 @@ void ogr_converter::convert_geometry(OGRGeometry* geom, feature_ptr feature)
|
|||
|
||||
void ogr_converter::convert_point(OGRPoint* geom, feature_ptr feature)
|
||||
{
|
||||
geometry_type * point = new geometry_type(mapnik::Point);
|
||||
std::auto_ptr<geometry_type> point(new geometry_type(mapnik::Point));
|
||||
point->move_to(geom->getX(), geom->getY());
|
||||
feature->add_geometry(point);
|
||||
feature->paths().push_back(point);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_linestring(OGRLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_points = geom->getNumPoints();
|
||||
geometry_type* line = new geometry_type(mapnik::LineString);
|
||||
std::auto_ptr<geometry_type> line(new geometry_type(mapnik::LineString));
|
||||
line->move_to(geom->getX(0), geom->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
line->line_to (geom->getX(i), geom->getY(i));
|
||||
}
|
||||
feature->add_geometry(line);
|
||||
feature->paths().push_back(line);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature)
|
||||
|
@ -102,34 +102,38 @@ void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature)
|
|||
int num_points = exterior->getNumPoints();
|
||||
int num_interior = geom->getNumInteriorRings();
|
||||
int capacity = 0;
|
||||
for (int r = 0; r < num_interior; r++)
|
||||
for (int r = 0; r < num_interior; ++r)
|
||||
{
|
||||
OGRLinearRing* interior = geom->getInteriorRing(r);
|
||||
capacity += interior->getNumPoints();
|
||||
}
|
||||
geometry_type* poly = new geometry_type(mapnik::Polygon);
|
||||
|
||||
std::auto_ptr<geometry_type> poly(new geometry_type(mapnik::Polygon));
|
||||
|
||||
poly->move_to(exterior->getX(0), exterior->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
for (int i = 1; i < num_points - 1; ++i)
|
||||
{
|
||||
poly->line_to(exterior->getX(i), exterior->getY(i));
|
||||
}
|
||||
for (int r = 0; r < num_interior; r++)
|
||||
poly->close(exterior->getX(num_points-1), exterior->getY(num_points-1));
|
||||
for (int r = 0; r < num_interior; ++r)
|
||||
{
|
||||
OGRLinearRing* interior = geom->getInteriorRing(r);
|
||||
num_points = interior->getNumPoints();
|
||||
poly->move_to(interior->getX(0), interior->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
for (int i = 1; i < num_points - 1; ++i)
|
||||
{
|
||||
poly->line_to(interior->getX(i), interior->getY(i));
|
||||
}
|
||||
poly->close(interior->getX(num_points-1), interior->getY(num_points-1));
|
||||
}
|
||||
feature->add_geometry(poly);
|
||||
feature->paths().push_back(poly);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multipoint(OGRMultiPoint* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
for (int i = 0; i < num_geometries; ++i)
|
||||
{
|
||||
convert_point(static_cast<OGRPoint*>(geom->getGeometryRef(i)), feature);
|
||||
}
|
||||
|
@ -138,7 +142,7 @@ void ogr_converter::convert_multipoint(OGRMultiPoint* geom, feature_ptr feature)
|
|||
void ogr_converter::convert_multilinestring(OGRMultiLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
for (int i = 0; i < num_geometries; ++i)
|
||||
{
|
||||
convert_linestring(static_cast<OGRLineString*>(geom->getGeometryRef(i)), feature);
|
||||
}
|
||||
|
@ -147,7 +151,7 @@ void ogr_converter::convert_multilinestring(OGRMultiLineString* geom, feature_pt
|
|||
void ogr_converter::convert_multipolygon(OGRMultiPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
for (int i = 0; i < num_geometries; ++i)
|
||||
{
|
||||
convert_polygon(static_cast<OGRPolygon*>(geom->getGeometryRef(i)), feature);
|
||||
}
|
||||
|
@ -156,7 +160,7 @@ void ogr_converter::convert_multipolygon(OGRMultiPolygon* geom, feature_ptr feat
|
|||
void ogr_converter::convert_collection(OGRGeometryCollection* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries();
|
||||
for (int i = 0; i < num_geometries; i++)
|
||||
for (int i = 0; i < num_geometries; ++i)
|
||||
{
|
||||
OGRGeometry* g = geom->getGeometryRef(i);
|
||||
if (g != NULL)
|
||||
|
@ -165,4 +169,3 @@ void ogr_converter::convert_collection(OGRGeometryCollection* geom, feature_ptr
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
|
||||
// ogr
|
||||
#include <ogrsf_frmts.h>
|
||||
|
|
|
@ -25,15 +25,23 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// ogr
|
||||
#include <ogrsf_frmts.h>
|
||||
|
||||
#include "ogr_layer_ptr.hpp"
|
||||
|
||||
class ogr_datasource : public mapnik::datasource
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
using mapnik::query;
|
||||
using mapnik::box2d;
|
||||
using mapnik::CoordTransform;
|
||||
using mapnik::Feature;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::geometry_utils;
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
|
||||
using mapnik::query;
|
||||
using mapnik::box2d;
|
||||
using mapnik::CoordTransform;
|
||||
using mapnik::Feature;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::geometry_utils;
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "basiccurl.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
CURL_LOAD_DATA* grab_http_response(const char* url)
|
||||
{
|
||||
CURL_LOAD_DATA* data;
|
||||
|
@ -39,7 +41,6 @@ CURL_LOAD_DATA* grab_http_response(const char* url)
|
|||
|
||||
CURL_LOAD_DATA* do_grab(CURL* curl,const char* url)
|
||||
{
|
||||
CURLcode res;
|
||||
CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)malloc(sizeof(CURL_LOAD_DATA));
|
||||
data->data = NULL;
|
||||
data->nbytes = 0;
|
||||
|
@ -48,7 +49,10 @@ CURL_LOAD_DATA* do_grab(CURL* curl,const char* url)
|
|||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
CURLcode res = curl_easy_perform(curl);
|
||||
if (res !=0) {
|
||||
std::clog << "error grabbing data\n";
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,20 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "osm.h"
|
||||
|
||||
|
|
|
@ -25,12 +25,22 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "connection_manager.hpp"
|
||||
#include "resultset.hpp"
|
||||
#include "cursorresultset.hpp"
|
||||
|
|
|
@ -112,7 +112,7 @@ feature_ptr postgis_featureset::next()
|
|||
|
||||
totalGeomSize_ += size;
|
||||
|
||||
int num_attrs = ctx_->size() + 1;
|
||||
unsigned num_attrs = ctx_->size() + 1;
|
||||
for (; pos < num_attrs; ++pos)
|
||||
{
|
||||
std::string name = rs_->getFieldName(pos);
|
||||
|
|
|
@ -55,7 +55,7 @@ private:
|
|||
boost::shared_ptr<IResultSet> rs_;
|
||||
context_ptr ctx_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
int totalGeomSize_;
|
||||
unsigned totalGeomSize_;
|
||||
int feature_id_;
|
||||
bool key_field_;
|
||||
};
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/image_reader.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
|
||||
|
|
|
@ -24,9 +24,22 @@
|
|||
#define RASTER_DATASOURCE_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
class raster_datasource : public mapnik::datasource
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/image_reader.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/feature_factory.hpp>
|
||||
|
@ -32,7 +33,6 @@
|
|||
#include "raster_featureset.hpp"
|
||||
|
||||
using mapnik::query;
|
||||
using mapnik::CoordTransform;
|
||||
using mapnik::image_reader;
|
||||
using mapnik::Feature;
|
||||
using mapnik::feature_ptr;
|
||||
|
@ -80,7 +80,7 @@ feature_ptr raster_featureset<LookupPolicy>::next()
|
|||
|
||||
if (image_width > 0 && image_height > 0)
|
||||
{
|
||||
CoordTransform t(image_width, image_height, extent_, 0, 0);
|
||||
mapnik::CoordTransform t(image_width, image_height, extent_, 0, 0);
|
||||
box2d<double> intersect = bbox_.intersect(curIter_->envelope());
|
||||
box2d<double> ext = t.forward(intersect);
|
||||
box2d<double> rem = policy_.transform(ext);
|
||||
|
|
|
@ -25,10 +25,21 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "rasterlite_include.hpp"
|
||||
|
||||
class rasterlite_datasource : public mapnik::datasource
|
||||
|
|
|
@ -36,7 +36,6 @@ using mapnik::coord2d;
|
|||
using mapnik::box2d;
|
||||
using mapnik::Feature;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::CoordTransform;
|
||||
using mapnik::geometry_type;
|
||||
using mapnik::query;
|
||||
using mapnik::feature_factory;
|
||||
|
|
|
@ -25,11 +25,21 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "shape_io.hpp"
|
||||
|
||||
using mapnik::datasource;
|
||||
|
|
|
@ -107,7 +107,7 @@ void shape_io::read_polyline(mapnik::geometry_container & geom)
|
|||
int num_points = record.read_ndr_integer();
|
||||
if (num_parts == 1)
|
||||
{
|
||||
geometry_type* line = new geometry_type(mapnik::LineString);
|
||||
std::auto_ptr<geometry_type> line(new geometry_type(mapnik::LineString));
|
||||
record.skip(4);
|
||||
double x = record.read_double();
|
||||
double y = record.read_double();
|
||||
|
@ -131,7 +131,7 @@ void shape_io::read_polyline(mapnik::geometry_container & geom)
|
|||
int start, end;
|
||||
for (int k = 0; k < num_parts; ++k)
|
||||
{
|
||||
geometry_type* line = new geometry_type(mapnik::LineString);
|
||||
std::auto_ptr<geometry_type> line(new geometry_type(mapnik::LineString));
|
||||
start = parts[k];
|
||||
if (k == num_parts - 1)
|
||||
{
|
||||
|
@ -188,9 +188,9 @@ void shape_io::read_polygon(mapnik::geometry_container & geom)
|
|||
parts[i] = record.read_ndr_integer();
|
||||
}
|
||||
|
||||
for (int k = 0; k < num_parts; k++)
|
||||
for (int k = 0; k < num_parts; ++k)
|
||||
{
|
||||
geometry_type* poly = new geometry_type(mapnik::Polygon);
|
||||
std::auto_ptr<geometry_type> poly(new geometry_type(mapnik::Polygon));
|
||||
int start = parts[k];
|
||||
int end;
|
||||
if (k == num_parts - 1)
|
||||
|
@ -206,12 +206,16 @@ void shape_io::read_polygon(mapnik::geometry_container & geom)
|
|||
double y = record.read_double();
|
||||
poly->move_to(x, y);
|
||||
|
||||
for (int j=start+1;j<end;j++)
|
||||
for (int j=start+1;j<end-1;j++)
|
||||
{
|
||||
x = record.read_double();
|
||||
y = record.read_double();
|
||||
poly->line_to(x, y);
|
||||
}
|
||||
x = record.read_double();
|
||||
y = record.read_double();
|
||||
poly->close(x, y);
|
||||
|
||||
geom.push_back(poly);
|
||||
}
|
||||
// z-range
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include "shape_utils.hpp"
|
||||
|
||||
// boost
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/sql_utils.hpp>
|
||||
#include <mapnik/timer.hpp>
|
||||
|
||||
|
|
|
@ -25,18 +25,26 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// sqlite
|
||||
#include "sqlite_connection.hpp"
|
||||
|
||||
|
||||
class sqlite_datasource : public mapnik::datasource
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
|
||||
using mapnik::query;
|
||||
using mapnik::box2d;
|
||||
using mapnik::CoordTransform;
|
||||
using mapnik::Feature;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::geometry_utils;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
|
||||
// boost
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
|
||||
// stl
|
||||
#include <string.h>
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/sql_utils.hpp>
|
||||
|
||||
|
|
|
@ -3,6 +3,19 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
class hello_datasource : public mapnik::datasource
|
||||
{
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
|
@ -239,7 +241,7 @@ void agg_renderer<T>::end_style_processing(feature_type_style const& st)
|
|||
{
|
||||
blend_from = true;
|
||||
mapnik::filter::filter_visitor<image_32> visitor(*current_buffer_);
|
||||
BOOST_FOREACH(mapnik::filter::filter_type filter_tag, st.image_filters())
|
||||
BOOST_FOREACH(mapnik::filter::filter_type const& filter_tag, st.image_filters())
|
||||
{
|
||||
boost::apply_visitor(visitor, filter_tag);
|
||||
}
|
||||
|
@ -256,7 +258,7 @@ void agg_renderer<T>::end_style_processing(feature_type_style const& st)
|
|||
|
||||
// apply any 'direct' image filters
|
||||
mapnik::filter::filter_visitor<image_32> visitor(pixmap_);
|
||||
BOOST_FOREACH(mapnik::filter::filter_type filter_tag, st.direct_image_filters())
|
||||
BOOST_FOREACH(mapnik::filter::filter_type const& filter_tag, st.direct_image_filters())
|
||||
{
|
||||
boost::apply_visitor(visitor, filter_tag);
|
||||
}
|
||||
|
|
|
@ -45,14 +45,18 @@
|
|||
#include "agg_path_storage.h"
|
||||
#include "agg_conv_clip_polyline.h"
|
||||
#include "agg_conv_transform.h"
|
||||
|
||||
#include "agg_image_filters.h"
|
||||
#include "agg_trans_bilinear.h"
|
||||
#include "agg_span_allocator.h"
|
||||
#include "agg_image_accessors.h"
|
||||
#include "agg_span_image_filter_rgba.h"
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
template <typename BufferType, typename SvgRenderer, typename Rasterizer, typename Detector>
|
||||
struct markers_rasterizer_dispatch
|
||||
struct vector_markers_rasterizer_dispatch
|
||||
{
|
||||
typedef agg::rgba8 color_type;
|
||||
typedef agg::order_rgba order_type;
|
||||
|
@ -62,7 +66,7 @@ struct markers_rasterizer_dispatch
|
|||
typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
|
||||
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
|
||||
|
||||
markers_rasterizer_dispatch(BufferType & image_buffer,
|
||||
vector_markers_rasterizer_dispatch(BufferType & image_buffer,
|
||||
SvgRenderer & svg_renderer,
|
||||
Rasterizer & ras,
|
||||
box2d<double> const& bbox,
|
||||
|
@ -91,7 +95,6 @@ struct markers_rasterizer_dispatch
|
|||
|
||||
if (placement_method == MARKER_POINT_PLACEMENT)
|
||||
{
|
||||
|
||||
double x,y;
|
||||
path.rewind(0);
|
||||
label::interior_position(path, x, y);
|
||||
|
@ -124,7 +127,6 @@ struct markers_rasterizer_dispatch
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
agg::scanline_u8 sl_;
|
||||
agg::rendering_buffer buf_;
|
||||
|
@ -139,11 +141,53 @@ private:
|
|||
double scale_factor_;
|
||||
};
|
||||
|
||||
template <typename Rasterizer, typename RendererBuffer>
|
||||
void render_raster_marker(Rasterizer & ras, RendererBuffer & renb,
|
||||
agg::scanline_u8 & sl, image_data_32 const& src,
|
||||
agg::trans_affine const& marker_tr, double opacity)
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
double width = src.width();
|
||||
double height = src.height();
|
||||
double p[8];
|
||||
p[0] = 0; p[1] = 0;
|
||||
p[2] = width; p[3] = 0;
|
||||
p[4] = width; p[5] = height;
|
||||
p[6] = 0; p[7] = height;
|
||||
|
||||
marker_tr.transform(&p[0], &p[1]);
|
||||
marker_tr.transform(&p[2], &p[3]);
|
||||
marker_tr.transform(&p[4], &p[5]);
|
||||
marker_tr.transform(&p[6], &p[7]);
|
||||
|
||||
ras.move_to_d(p[0],p[1]);
|
||||
ras.line_to_d(p[2],p[3]);
|
||||
ras.line_to_d(p[4],p[5]);
|
||||
ras.line_to_d(p[6],p[7]);
|
||||
|
||||
typedef agg::rgba8 color_type;
|
||||
agg::span_allocator<color_type> sa;
|
||||
agg::image_filter_bilinear filter_kernel;
|
||||
agg::image_filter_lut filter(filter_kernel, false);
|
||||
|
||||
agg::rendering_buffer marker_buf((unsigned char *)src.getBytes(),
|
||||
src.width(),
|
||||
src.height(),
|
||||
src.width()*4);
|
||||
agg::pixfmt_rgba32_pre pixf(marker_buf);
|
||||
|
||||
typedef agg::image_accessor_clone<agg::pixfmt_rgba32_pre> img_accessor_type;
|
||||
typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
|
||||
typedef agg::span_image_filter_rgba_2x2<img_accessor_type,
|
||||
interpolator_type> span_gen_type;
|
||||
img_accessor_type ia(pixf);
|
||||
interpolator_type interpolator(agg::trans_affine(p, 0, 0, width, height) );
|
||||
span_gen_type sg(ia, interpolator, filter);
|
||||
agg::render_scanlines_aa(ras, sl, renb, sa, sg);
|
||||
}
|
||||
|
||||
template <typename BufferType, typename Rasterizer, typename Detector>
|
||||
struct raster_markers_rasterizer_dispatch
|
||||
{
|
||||
typedef agg::rgba8 color_type;
|
||||
typedef agg::order_rgba order_type;
|
||||
|
@ -153,6 +197,97 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
|
||||
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
|
||||
|
||||
raster_markers_rasterizer_dispatch(BufferType & image_buffer,
|
||||
Rasterizer & ras,
|
||||
image_data_32 const& src,
|
||||
agg::trans_affine const& marker_trans,
|
||||
markers_symbolizer const& sym,
|
||||
Detector & detector,
|
||||
double scale_factor)
|
||||
: buf_(image_buffer.raw_data(), image_buffer.width(), image_buffer.height(), image_buffer.width() * 4),
|
||||
pixf_(buf_),
|
||||
renb_(pixf_),
|
||||
ras_(ras),
|
||||
src_(src),
|
||||
marker_trans_(marker_trans),
|
||||
sym_(sym),
|
||||
detector_(detector),
|
||||
scale_factor_(scale_factor)
|
||||
{
|
||||
pixf_.comp_op(static_cast<agg::comp_op_e>(sym_.comp_op()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void add_path(T & path)
|
||||
{
|
||||
marker_placement_e placement_method = sym_.get_marker_placement();
|
||||
box2d<double> bbox_(0,0, src_.width(),src_.height());
|
||||
|
||||
if (placement_method == MARKER_POINT_PLACEMENT)
|
||||
{
|
||||
double x,y;
|
||||
path.rewind(0);
|
||||
label::interior_position(path, x, y);
|
||||
agg::trans_affine matrix = marker_trans_;
|
||||
matrix.translate(x,y);
|
||||
box2d<double> transformed_bbox = bbox_ * matrix;
|
||||
|
||||
if (sym_.get_allow_overlap() ||
|
||||
detector_.has_placement(transformed_bbox))
|
||||
{
|
||||
|
||||
render_raster_marker(ras_, renb_, sl_, src_,
|
||||
matrix, sym_.get_opacity());
|
||||
if (!sym_.get_ignore_placement())
|
||||
detector_.insert(transformed_bbox);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_,
|
||||
sym_.get_spacing() * scale_factor_,
|
||||
sym_.get_max_error(),
|
||||
sym_.get_allow_overlap());
|
||||
double x, y, angle;
|
||||
while (placement.get_point(x, y, angle))
|
||||
{
|
||||
agg::trans_affine matrix = marker_trans_;
|
||||
matrix.rotate(angle);
|
||||
matrix.translate(x,y);
|
||||
render_raster_marker(ras_, renb_, sl_, src_,
|
||||
matrix, sym_.get_opacity());
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
agg::scanline_u8 sl_;
|
||||
agg::rendering_buffer buf_;
|
||||
pixfmt_comp_type pixf_;
|
||||
renderer_base renb_;
|
||||
Rasterizer & ras_;
|
||||
image_data_32 const& src_;
|
||||
agg::trans_affine const& marker_trans_;
|
||||
markers_symbolizer const& sym_;
|
||||
Detector & detector_;
|
||||
double scale_factor_;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||
feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
typedef agg::rgba8 color_type;
|
||||
typedef agg::order_rgba order_type;
|
||||
typedef agg::pixel32_type pixel_type;
|
||||
typedef agg::comp_op_adaptor_rgba_pre<color_type, order_type> blender_type; // comp blender
|
||||
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_comp_type;
|
||||
typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
|
||||
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
|
||||
typedef label_collision_detector4 detector_type;
|
||||
typedef boost::mpl::vector<clip_line_tag,transform_tag,smooth_tag> conv_types;
|
||||
|
||||
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
|
||||
|
||||
if (!filename.empty())
|
||||
|
@ -160,61 +295,76 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance()->find(filename, true);
|
||||
if (mark && *mark)
|
||||
{
|
||||
if (!(*mark)->is_vector())
|
||||
{
|
||||
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: markers_symbolizer does not yet support non-SVG markers";
|
||||
return;
|
||||
}
|
||||
|
||||
ras_ptr->reset();
|
||||
ras_ptr->gamma(agg::gamma_power());
|
||||
|
||||
agg::trans_affine geom_tr;
|
||||
evaluate_transform(geom_tr, feature, sym.get_transform());
|
||||
|
||||
boost::optional<path_ptr> marker = (*mark)->get_vector_data();
|
||||
box2d<double> const& bbox = (*marker)->bounding_box();
|
||||
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
agg::trans_affine tr;
|
||||
setup_label_transform(tr, bbox, feature, sym);
|
||||
tr = agg::trans_affine_scaling(scale_factor_) * tr;
|
||||
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
|
||||
using namespace mapnik::svg;
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage((*marker)->source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
|
||||
agg::pod_bvector<path_attributes> attributes;
|
||||
bool result = push_explicit_style( (*marker)->attributes(), attributes, sym);
|
||||
|
||||
typedef label_collision_detector4 detector_type;
|
||||
typedef svg_renderer<svg_path_adapter,
|
||||
agg::pod_bvector<path_attributes>,
|
||||
renderer_type,
|
||||
agg::pixfmt_rgba32 > svg_renderer_type;
|
||||
typedef markers_rasterizer_dispatch<buffer_type, svg_renderer_type, rasterizer, detector_type> markers_rasterizer_dispatch_type;
|
||||
typedef boost::mpl::vector<clip_line_tag,transform_tag,smooth_tag> conv_types;
|
||||
|
||||
svg_renderer_type svg_renderer(svg_path, result ? attributes : (*marker)->attributes());
|
||||
|
||||
markers_rasterizer_dispatch_type rasterizer_dispatch(*current_buffer_,svg_renderer,*ras_ptr,
|
||||
bbox, marker_trans, sym, *detector_, scale_factor_);
|
||||
|
||||
|
||||
vertex_converter<box2d<double>, markers_rasterizer_dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(query_extent_* 1.1,rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
|
||||
|
||||
if (sym.clip()) converter.template set<clip_line_tag>(); //optional clip (default: true)
|
||||
converter.template set<transform_tag>(); //always transform
|
||||
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||
|
||||
BOOST_FOREACH(geometry_type & geom, feature.paths())
|
||||
if ((*mark)->is_vector())
|
||||
{
|
||||
converter.apply(geom);
|
||||
using namespace mapnik::svg;
|
||||
boost::optional<path_ptr> marker = (*mark)->get_vector_data();
|
||||
|
||||
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage((*marker)->source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
|
||||
agg::pod_bvector<path_attributes> attributes;
|
||||
bool result = push_explicit_style( (*marker)->attributes(), attributes, sym);
|
||||
|
||||
typedef svg_renderer<svg_path_adapter,
|
||||
agg::pod_bvector<path_attributes>,
|
||||
renderer_type,
|
||||
agg::pixfmt_rgba32 > svg_renderer_type;
|
||||
typedef vector_markers_rasterizer_dispatch<buffer_type, svg_renderer_type, rasterizer, detector_type> dispatch_type;
|
||||
|
||||
|
||||
svg_renderer_type svg_renderer(svg_path, result ? attributes : (*marker)->attributes());
|
||||
|
||||
dispatch_type rasterizer_dispatch(*current_buffer_,svg_renderer,*ras_ptr,
|
||||
bbox, marker_trans, sym, *detector_, scale_factor_);
|
||||
|
||||
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(query_extent_* 1.1,rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
|
||||
|
||||
if (sym.clip()) converter.template set<clip_line_tag>(); //optional clip (default: true)
|
||||
converter.template set<transform_tag>(); //always transform
|
||||
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||
|
||||
BOOST_FOREACH(geometry_type & geom, feature.paths())
|
||||
{
|
||||
converter.apply(geom);
|
||||
}
|
||||
}
|
||||
else // raster markers
|
||||
{
|
||||
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
|
||||
typedef raster_markers_rasterizer_dispatch<buffer_type,rasterizer, detector_type> dispatch_type;
|
||||
dispatch_type rasterizer_dispatch(*current_buffer_,*ras_ptr, **marker,
|
||||
marker_trans, sym, *detector_, scale_factor_);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(query_extent_* 1.1, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
|
||||
|
||||
if (sym.clip()) converter.template set<clip_line_tag>(); //optional clip (default: true)
|
||||
converter.template set<transform_tag>(); //always transform
|
||||
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||
|
||||
BOOST_FOREACH(geometry_type & geom, feature.paths())
|
||||
{
|
||||
converter.apply(geom);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,14 +65,14 @@ void agg_renderer<T>::process(point_symbolizer const& sym,
|
|||
if (marker)
|
||||
{
|
||||
box2d<double> const& bbox = (*marker)->bounding_box();
|
||||
coord2d const center = bbox.center();
|
||||
coord2d center = bbox.center();
|
||||
|
||||
agg::trans_affine tr;
|
||||
evaluate_transform(tr, feature, sym.get_image_transform());
|
||||
tr = agg::trans_affine_scaling(scale_factor_) * tr;
|
||||
|
||||
agg::trans_affine_translation const recenter(-center.x, -center.y);
|
||||
agg::trans_affine const recenter_tr = recenter * tr;
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine recenter_tr = recenter * tr;
|
||||
box2d<double> label_ext = bbox * recenter_tr;
|
||||
|
||||
for (unsigned i=0; i<feature.num_geometries(); ++i)
|
||||
|
|
37
src/build.py
37
src/build.py
|
@ -101,6 +101,7 @@ else: # unix, non-macos
|
|||
source = Split(
|
||||
"""
|
||||
color.cpp
|
||||
css_color_grammar.cpp
|
||||
conversions.cpp
|
||||
image_compositing.cpp
|
||||
image_scaling.cpp
|
||||
|
@ -109,8 +110,11 @@ source = Split(
|
|||
datasource_cache.cpp
|
||||
debug.cpp
|
||||
deepcopy.cpp
|
||||
expression_node.cpp
|
||||
expression_grammar.cpp
|
||||
expression_string.cpp
|
||||
expression.cpp
|
||||
transform_expression_grammar.cpp
|
||||
transform_expression.cpp
|
||||
feature_kv_iterator.cpp
|
||||
feature_type_style.cpp
|
||||
|
@ -130,6 +134,7 @@ source = Split(
|
|||
parse_path.cpp
|
||||
parse_transform.cpp
|
||||
palette.cpp
|
||||
path_expression_grammar.cpp
|
||||
plugin.cpp
|
||||
png_reader.cpp
|
||||
point_symbolizer.cpp
|
||||
|
@ -140,6 +145,7 @@ source = Split(
|
|||
text_symbolizer.cpp
|
||||
tiff_reader.cpp
|
||||
wkb.cpp
|
||||
wkb_generator.cpp
|
||||
projection.cpp
|
||||
proj_transform.cpp
|
||||
distance.cpp
|
||||
|
@ -162,6 +168,7 @@ source = Split(
|
|||
svg_points_parser.cpp
|
||||
svg_transform_parser.cpp
|
||||
warp.cpp
|
||||
json/feature_grammar.cpp
|
||||
json/feature_collection_parser.cpp
|
||||
json/geojson_generator.cpp
|
||||
markers_placement.cpp
|
||||
|
@ -282,21 +289,21 @@ source += Split(
|
|||
if env['SVG_RENDERER']: # svg backend
|
||||
source += Split(
|
||||
"""
|
||||
svg/svg_renderer.cpp
|
||||
svg/svg_generator.cpp
|
||||
svg/svg_output_attributes.cpp
|
||||
svg/process_symbolizers.cpp
|
||||
svg/process_building_symbolizer.cpp
|
||||
svg/process_line_pattern_symbolizer.cpp
|
||||
svg/process_line_symbolizer.cpp
|
||||
svg/process_markers_symbolizer.cpp
|
||||
svg/process_point_symbolizer.cpp
|
||||
svg/process_polygon_pattern_symbolizer.cpp
|
||||
svg/process_polygon_symbolizer.cpp
|
||||
svg/process_raster_symbolizer.cpp
|
||||
svg/process_shield_symbolizer.cpp
|
||||
svg/process_text_symbolizer.cpp
|
||||
""")
|
||||
svg/svg_renderer.cpp
|
||||
svg/svg_generator.cpp
|
||||
svg/svg_output_attributes.cpp
|
||||
svg/process_symbolizers.cpp
|
||||
svg/process_building_symbolizer.cpp
|
||||
svg/process_line_pattern_symbolizer.cpp
|
||||
svg/process_line_symbolizer.cpp
|
||||
svg/process_markers_symbolizer.cpp
|
||||
svg/process_point_symbolizer.cpp
|
||||
svg/process_polygon_pattern_symbolizer.cpp
|
||||
svg/process_polygon_symbolizer.cpp
|
||||
svg/process_raster_symbolizer.cpp
|
||||
svg/process_shield_symbolizer.cpp
|
||||
svg/process_text_symbolizer.cpp
|
||||
""")
|
||||
lib_env.Append(CXXFLAGS = '-DSVG_RENDERER')
|
||||
libmapnik_cxxflags.append('-DSVG_RENDERER')
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#if defined(HAVE_CAIRO)
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/cairo_renderer.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
|
@ -51,7 +53,6 @@
|
|||
#include <boost/make_shared.hpp>
|
||||
|
||||
// agg
|
||||
|
||||
#include "agg_conv_clip_polyline.h"
|
||||
#include "agg_conv_clip_polygon.h"
|
||||
#include "agg_conv_smooth_poly1.h"
|
||||
|
@ -494,6 +495,11 @@ public:
|
|||
{
|
||||
line_to(x, y);
|
||||
}
|
||||
else if (cm == SEG_CLOSE)
|
||||
{
|
||||
line_to(x, y);
|
||||
close_path();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
262
src/css_color_grammar.cpp
Normal file
262
src/css_color_grammar.cpp
Normal 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>;
|
||||
|
||||
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/layer.hpp>
|
||||
|
|
174
src/expression_grammar.cpp
Normal file
174
src/expression_grammar.cpp
Normal 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
51
src/expression_node.cpp
Normal 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
|
||||
|
||||
}
|
|
@ -20,8 +20,10 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//mapnik
|
||||
// mapnik
|
||||
#include <mapnik/feature_style_processor.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/memory_datasource.hpp>
|
||||
|
@ -37,7 +39,8 @@
|
|||
// boost
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
//stl
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
|
||||
#if defined(HAVE_CAIRO)
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/grid/grid_rasterizer.hpp>
|
||||
#include <mapnik/grid/grid_renderer.hpp>
|
||||
|
|
230
src/json/feature_grammar.cpp
Normal file
230
src/json/feature_grammar.cpp
Normal 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>;
|
||||
|
||||
}}
|
|
@ -22,9 +22,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
|
||||
#include <mapnik/load_map.hpp>
|
||||
|
||||
#include <mapnik/xml_tree.hpp>
|
||||
#include <mapnik/version.hpp>
|
||||
#include <mapnik/image_compositing.hpp>
|
||||
|
@ -39,16 +37,12 @@
|
|||
#include <mapnik/font_engine_freetype.hpp>
|
||||
#include <mapnik/font_set.hpp>
|
||||
#include <mapnik/xml_loader.hpp>
|
||||
|
||||
#include <mapnik/expression.hpp>
|
||||
#include <mapnik/parse_path.hpp>
|
||||
#include <mapnik/parse_transform.hpp>
|
||||
#include <mapnik/raster_colorizer.hpp>
|
||||
|
||||
#include <mapnik/svg/svg_path_parser.hpp>
|
||||
|
||||
#include <mapnik/metawriter_factory.hpp>
|
||||
|
||||
#include <mapnik/text_placements/registry.hpp>
|
||||
#include <mapnik/text_placements/dummy.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
@ -1062,9 +1056,11 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node)
|
|||
|
||||
stroke strk;
|
||||
if (parse_stroke(strk,node))
|
||||
{
|
||||
sym.set_stroke(strk);
|
||||
}
|
||||
|
||||
marker_placement_e placement = node.get_attr<marker_placement_e>("placement", MARKER_LINE_PLACEMENT);
|
||||
marker_placement_e placement = node.get_attr<marker_placement_e>("placement", MARKER_POINT_PLACEMENT);
|
||||
sym.set_marker_placement(placement);
|
||||
parse_symbolizer_base(sym, node);
|
||||
rule.append(sym);
|
||||
|
@ -1309,25 +1305,30 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym)
|
|||
bool map_parser::parse_stroke(stroke & strk, xml_node const & sym)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
// stroke color
|
||||
optional<color> c = sym.get_opt_attr<color>("stroke");
|
||||
if (c)
|
||||
{
|
||||
strk.set_color(*c);
|
||||
result = true;
|
||||
strk.set_color(*c);
|
||||
}
|
||||
|
||||
// stroke-width
|
||||
optional<double> width = sym.get_opt_attr<double>("stroke-width");
|
||||
if (width && *width > 0)
|
||||
optional<double> width = sym.get_opt_attr<double>("stroke-width");
|
||||
if (width)
|
||||
{
|
||||
strk.set_width(*width);
|
||||
result = true;
|
||||
strk.set_width(*width);
|
||||
}
|
||||
|
||||
// stroke-opacity
|
||||
optional<double> opacity = sym.get_opt_attr<double>("stroke-opacity");
|
||||
if (opacity) strk.set_opacity(*opacity);
|
||||
if (opacity)
|
||||
{
|
||||
result = true;
|
||||
strk.set_opacity(*opacity);
|
||||
}
|
||||
|
||||
// stroke-linejoin
|
||||
optional<line_join_e> line_join = sym.get_opt_attr<line_join_e>("stroke-linejoin");
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//mapnik
|
||||
// mapnik
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
|
|
|
@ -54,12 +54,12 @@ marker_cache::marker_cache()
|
|||
insert_svg("ellipse",
|
||||
"<?xml version='1.0' standalone='no'?>"
|
||||
"<svg width='100%' height='100%' version='1.1' xmlns='http://www.w3.org/2000/svg'>"
|
||||
"<circle r='10' fill='#0000FF'/>"
|
||||
"<ellipse rx='5' ry='5' fill='#0000FF' stroke='black' stroke-width='.5'/>"
|
||||
"</svg>");
|
||||
insert_svg("arrow",
|
||||
"<?xml version='1.0' standalone='no'?>"
|
||||
"<svg width='100%' height='100%' version='1.1' xmlns='http://www.w3.org/2000/svg'>"
|
||||
"<path fill='#93a7ac' d='m 31.698405,7.5302648 -8.910967,-6.0263712 0.594993,4.8210971 -18.9822542,0 0,2.4105482 18.9822542,0 -0.594993,4.8210971 z'/>"
|
||||
"<path fill='#0000FF' stroke='black' stroke-width='.5' d='m 31.698405,7.5302648 -8.910967,-6.0263712 0.594993,4.8210971 -18.9822542,0 0,2.4105482 18.9822542,0 -0.594993,4.8210971 z'/>"
|
||||
"</svg>");
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,10 @@ markers_symbolizer::markers_symbolizer()
|
|||
allow_overlap_(false),
|
||||
spacing_(100.0),
|
||||
max_error_(0.2),
|
||||
marker_p_(MARKER_POINT_PLACEMENT) {}
|
||||
marker_p_(MARKER_POINT_PLACEMENT) {
|
||||
// override the default for clipping in symbolizer base
|
||||
this->set_clip(false);
|
||||
}
|
||||
|
||||
markers_symbolizer::markers_symbolizer(path_expression_ptr const& filename)
|
||||
: symbolizer_with_image(filename),
|
||||
|
@ -56,7 +59,10 @@ markers_symbolizer::markers_symbolizer(path_expression_ptr const& filename)
|
|||
allow_overlap_(false),
|
||||
spacing_(100.0),
|
||||
max_error_(0.2),
|
||||
marker_p_(MARKER_POINT_PLACEMENT) {}
|
||||
marker_p_(MARKER_POINT_PLACEMENT) {
|
||||
// override the default for clipping in symbolizer base
|
||||
this->set_clip(false);
|
||||
}
|
||||
|
||||
markers_symbolizer::markers_symbolizer(markers_symbolizer const& rhs)
|
||||
: symbolizer_with_image(rhs),
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/memory_datasource.hpp>
|
||||
#include <mapnik/memory_featureset.hpp>
|
||||
#include <mapnik/feature_factory.hpp>
|
||||
|
|
62
src/path_expression_grammar.cpp
Normal file
62
src/path_expression_grammar.cpp
Normal 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>;
|
||||
|
||||
}
|
|
@ -21,6 +21,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/save_map.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
|
@ -201,9 +203,11 @@ public:
|
|||
{
|
||||
set_attr(sym_node, "unlock-image", sym.get_unlock_image());
|
||||
}
|
||||
if (sym.get_text_opacity() != dfl.get_text_opacity() || explicit_defaults_)
|
||||
|
||||
if (sym.get_placement_options()->defaults.format.text_opacity !=
|
||||
dfl.get_placement_options()->defaults.format.text_opacity || explicit_defaults_)
|
||||
{
|
||||
set_attr(sym_node, "text-opacity", sym.get_text_opacity());
|
||||
set_attr(sym_node, "text-opacity", sym.get_placement_options()->defaults.format.text_opacity);
|
||||
}
|
||||
pixel_position displacement = sym.get_shield_displacement();
|
||||
if (displacement.x != dfl.get_shield_displacement().x || explicit_defaults_)
|
||||
|
|
91
src/transform_expression_grammar.cpp
Normal file
91
src/transform_expression_grammar.cpp
Normal 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>;
|
||||
|
||||
}
|
134
src/wkb.cpp
134
src/wkb.cpp
|
@ -24,6 +24,7 @@
|
|||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
#include <mapnik/coord_array.hpp>
|
||||
#include <mapnik/geom_util.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
|
||||
|
@ -33,6 +34,9 @@
|
|||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
typedef coord_array<coord2d> CoordinateArray;
|
||||
|
||||
struct wkb_reader : boost::noncopyable
|
||||
{
|
||||
private:
|
||||
|
@ -113,9 +117,6 @@ public:
|
|||
{
|
||||
int type = read_integer();
|
||||
|
||||
#ifdef MAPNIK_LOG
|
||||
MAPNIK_LOG_DEBUG(wkb_reader) << "wkb_reader: Read=" << wkb_geometry_type_string(type) << "," << type;
|
||||
#endif
|
||||
switch (type)
|
||||
{
|
||||
case wkbPoint:
|
||||
|
@ -246,9 +247,9 @@ private:
|
|||
|
||||
void read_point(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type* pt = new geometry_type(Point);
|
||||
double x = read_double();
|
||||
double y = read_double();
|
||||
std::auto_ptr<geometry_type> pt(new geometry_type(Point));
|
||||
pt->move_to(x, y);
|
||||
paths.push_back(pt);
|
||||
}
|
||||
|
@ -265,9 +266,9 @@ private:
|
|||
|
||||
void read_point_xyz(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type* pt = new geometry_type(Point);
|
||||
double x = read_double();
|
||||
double y = read_double();
|
||||
std::auto_ptr<geometry_type> pt(new geometry_type(Point));
|
||||
pos_ += 8; // double z = read_double();
|
||||
pt->move_to(x, y);
|
||||
paths.push_back(pt);
|
||||
|
@ -285,16 +286,19 @@ private:
|
|||
|
||||
void read_linestring(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type* line = new geometry_type(LineString);
|
||||
int num_points = read_integer();
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
line->move_to(ar[0].x, ar[0].y);
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
if (num_points > 0)
|
||||
{
|
||||
line->line_to(ar[i].x, ar[i].y);
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
std::auto_ptr<geometry_type> line(new geometry_type(LineString));
|
||||
line->move_to(ar[0].x, ar[0].y);
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
line->line_to(ar[i].x, ar[i].y);
|
||||
}
|
||||
paths.push_back(line);
|
||||
}
|
||||
paths.push_back(line);
|
||||
}
|
||||
|
||||
void read_multilinestring(boost::ptr_vector<geometry_type> & paths)
|
||||
|
@ -309,16 +313,19 @@ private:
|
|||
|
||||
void read_linestring_xyz(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type* line = new geometry_type(LineString);
|
||||
int num_points = read_integer();
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords_xyz(ar);
|
||||
line->move_to(ar[0].x, ar[0].y);
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
if (num_points > 0)
|
||||
{
|
||||
line->line_to(ar[i].x, ar[i].y);
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords_xyz(ar);
|
||||
std::auto_ptr<geometry_type> line(new geometry_type(LineString));
|
||||
line->move_to(ar[0].x, ar[0].y);
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
line->line_to(ar[i].x, ar[i].y);
|
||||
}
|
||||
paths.push_back(line);
|
||||
}
|
||||
paths.push_back(line);
|
||||
}
|
||||
|
||||
void read_multilinestring_xyz(boost::ptr_vector<geometry_type> & paths)
|
||||
|
@ -334,22 +341,28 @@ private:
|
|||
|
||||
void read_polygon(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type* poly = new geometry_type(Polygon);
|
||||
int num_rings = read_integer();
|
||||
unsigned capacity = 0;
|
||||
for (int i = 0; i < num_rings; ++i)
|
||||
if (num_rings > 0)
|
||||
{
|
||||
int num_points = read_integer();
|
||||
capacity += num_points;
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
poly->move_to(ar[0].x, ar[0].y);
|
||||
for (int j = 1; j < num_points; ++j)
|
||||
std::auto_ptr<geometry_type> poly(new geometry_type(Polygon));
|
||||
for (int i = 0; i < num_rings; ++i)
|
||||
{
|
||||
poly->line_to(ar[j].x, ar[j].y);
|
||||
int num_points = read_integer();
|
||||
if (num_points > 0)
|
||||
{
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
poly->move_to(ar[0].x, ar[0].y);
|
||||
for (int j = 1; j < num_points - 1; ++j)
|
||||
{
|
||||
poly->line_to(ar[j].x, ar[j].y);
|
||||
}
|
||||
poly->close(ar[num_points-1].x, ar[num_points-1].y);
|
||||
}
|
||||
}
|
||||
if (poly->size() > 2) // ignore if polygon has less than 3 vertices
|
||||
paths.push_back(poly);
|
||||
}
|
||||
paths.push_back(poly);
|
||||
}
|
||||
|
||||
void read_multipolygon(boost::ptr_vector<geometry_type> & paths)
|
||||
|
@ -364,22 +377,28 @@ private:
|
|||
|
||||
void read_polygon_xyz(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type* poly = new geometry_type(Polygon);
|
||||
int num_rings = read_integer();
|
||||
unsigned capacity = 0;
|
||||
for (int i = 0; i < num_rings; ++i)
|
||||
if (num_rings > 0)
|
||||
{
|
||||
int num_points = read_integer();
|
||||
capacity += num_points;
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords_xyz(ar);
|
||||
poly->move_to(ar[0].x, ar[0].y);
|
||||
for (int j = 1; j < num_points; ++j)
|
||||
std::auto_ptr<geometry_type> poly(new geometry_type(Polygon));
|
||||
for (int i = 0; i < num_rings; ++i)
|
||||
{
|
||||
poly->line_to(ar[j].x, ar[j].y);
|
||||
int num_points = read_integer();
|
||||
if (num_points > 0)
|
||||
{
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords_xyz(ar);
|
||||
poly->move_to(ar[0].x, ar[0].y);
|
||||
for (int j = 1; j < num_points - 1; ++j)
|
||||
{
|
||||
poly->line_to(ar[j].x, ar[j].y);
|
||||
}
|
||||
poly->close(ar[num_points-1].x, ar[num_points-1].y);
|
||||
}
|
||||
}
|
||||
if (poly->size() > 2) // ignore if polygon has less than 3 vertices
|
||||
paths.push_back(poly);
|
||||
}
|
||||
paths.push_back(poly);
|
||||
}
|
||||
|
||||
void read_multipolygon_xyz(boost::ptr_vector<geometry_type> & paths)
|
||||
|
@ -402,33 +421,32 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_LOG
|
||||
std::string wkb_geometry_type_string(int type)
|
||||
{
|
||||
std::stringstream s;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case wkbPoint: s << "wkbPoint"; break;
|
||||
case wkbLineString: s << "wkbLineString"; break;
|
||||
case wkbPolygon: s << "wkbPolygon"; break;
|
||||
case wkbMultiPoint: s << "wkbMultiPoint"; break;
|
||||
case wkbMultiLineString: s << "wkbMultiLineString"; break;
|
||||
case wkbMultiPolygon: s << "wkbMultiPolygon"; break;
|
||||
case wkbGeometryCollection: s << "wkbGeometryCollection"; break;
|
||||
case wkbPointZ: s << "wkbPointZ"; break;
|
||||
case wkbLineStringZ: s << "wkbLineStringZ"; break;
|
||||
case wkbPolygonZ: s << "wkbPolygonZ"; break;
|
||||
case wkbMultiPointZ: s << "wkbMultiPointZ"; break;
|
||||
case wkbMultiLineStringZ: s << "wkbMultiLineStringZ"; break;
|
||||
case wkbMultiPolygonZ: s << "wkbMultiPolygonZ"; break;
|
||||
case wkbGeometryCollectionZ: s << "wkbGeometryCollectionZ"; break;
|
||||
default: s << "wkbUknown"; break;
|
||||
case wkbPoint: s << "Point"; break;
|
||||
case wkbLineString: s << "LineString"; break;
|
||||
case wkbPolygon: s << "Polygon"; break;
|
||||
case wkbMultiPoint: s << "MultiPoint"; break;
|
||||
case wkbMultiLineString: s << "MultiLineString"; break;
|
||||
case wkbMultiPolygon: s << "MultiPolygon"; break;
|
||||
case wkbGeometryCollection: s << "GeometryCollection"; break;
|
||||
case wkbPointZ: s << "PointZ"; break;
|
||||
case wkbLineStringZ: s << "LineStringZ"; break;
|
||||
case wkbPolygonZ: s << "PolygonZ"; break;
|
||||
case wkbMultiPointZ: s << "MultiPointZ"; break;
|
||||
case wkbMultiLineStringZ: s << "MultiLineStringZ"; break;
|
||||
case wkbMultiPolygonZ: s << "MultiPolygonZ"; break;
|
||||
case wkbGeometryCollectionZ: s << "GeometryCollectionZ"; break;
|
||||
default: s << "wkbUknown(" << type << ")"; break;
|
||||
}
|
||||
|
||||
return s.str();
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
bool geometry_utils::from_wkb(boost::ptr_vector<geometry_type>& paths,
|
||||
|
|
141
src/wkb_generator.cpp
Normal file
141
src/wkb_generator.cpp
Normal 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> >;
|
||||
|
||||
|
||||
}}
|
|
@ -7,3 +7,4 @@ multipoint, "MULTIPOINT ((10 40), (40 30), (20 20), (30 10))"
|
|||
multilinestring, "MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))"
|
||||
multipolygon, "MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))"
|
||||
multipolygon, "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),(30 20, 20 25, 20 15, 30 20)))"
|
||||
collection, "GEOMETRYCOLLECTION(POLYGON((1 1,2 1,2 2,1 2,1 1)),POINT(2 3),LINESTRING(2 3,3 4))"
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue