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