Merge branch 'master' of github.com:mapnik/mapnik

This commit is contained in:
Hermann Kraus 2012-07-25 00:21:30 +02:00
commit 3054145103
174 changed files with 4982 additions and 3534 deletions

View file

@ -1,13 +1,13 @@
all: mapnik
install:
python scons/scons.py install
@python scons/scons.py --config=cache --implicit-deps-unchanged --max-drift=1 install
mapnik:
python scons/scons.py
@python scons/scons.py --config=cache --implicit-deps-unchanged --max-drift=1
clean:
python scons/scons.py -c
python scons/scons.py -c --config=cache --implicit-deps-unchanged --max-drift=1
reset:
if test -e ".sconf_temp/"; then rm -r ".sconf_temp/"; fi
@ -15,7 +15,7 @@ reset:
if test -e "config.cache"; then rm "config.cache"; fi
uninstall:
python scons/scons.py uninstall
python scons/scons.py --config=cache --implicit-deps-unchanged --max-drift=1 uninstall
test:
@echo "*** Running visual tests..."

View file

@ -33,6 +33,8 @@ except:
HAS_DISTUTILS = False
py3 = None
# local file to hold custom user configuration variables
# Todo check timestamp, reload if changed?
SCONS_LOCAL_CONFIG = 'config.py'
@ -85,7 +87,7 @@ pretty_dep_names = {
# Core plugin build configuration
# opts.AddVariables still hardcoded however...
PLUGINS = { # plugins with external dependencies
# configured by calling project, henche 'path':None
# configured by calling project, hence 'path':None
'postgis': {'default':True,'path':None,'inc':'libpq-fe.h','lib':'pq','lang':'C'},
'gdal': {'default':True,'path':None,'inc':'gdal_priv.h','lib':'gdal','lang':'C++'},
'ogr': {'default':True,'path':None,'inc':'ogrsf_frmts.h','lib':'gdal','lang':'C++'},
@ -109,6 +111,8 @@ PLUGINS = { # plugins with external dependencies
#### SCons build options and initial setup ####
env = Environment(ENV=os.environ)
env.Decider('MD5-timestamp')
env.SourceCode(".", None)
def color_print(color,text,newline=True):
# 1 - red
@ -235,8 +239,6 @@ def sort_paths(items,priority):
if platform.dist()[0] in ('Ubuntu','debian'):
LIBDIR_SCHEMA='lib'
elif platform.uname()[4] == 'x86_64' and platform.system() == 'Linux':
LIBDIR_SCHEMA='lib64'
elif platform.uname()[4] == 'ppc64':
LIBDIR_SCHEMA='lib64'
else:
@ -302,7 +304,7 @@ opts.AddVariables(
('BOOST_TOOLKIT','Specify boost toolkit, e.g., gcc41.','',False),
('BOOST_ABI', 'Specify boost ABI, e.g., d.','',False),
('BOOST_VERSION','Specify boost version, e.g., 1_35.','',False),
('BOOST_PYTHON_LIB','Specify library name to specific Boost Python lib (e.g. "boost_python-py26")',''),
('BOOST_PYTHON_LIB','Specify library name to specific Boost Python lib (e.g. "boost_python-py26")','boost_python'),
# Variables for required dependencies
('FREETYPE_CONFIG', 'The path to the freetype-config executable.', 'freetype-config'),
@ -932,6 +934,8 @@ if not preconfigured:
color_print(1,"SCons CONFIG not found: '%s'" % conf)
# Recreate the base environment using modified `opts`
env = Environment(ENV=os.environ,options=opts)
env.Decider('MD5-timestamp')
env.SourceCode(".", None)
env['USE_CONFIG'] = True
else:
color_print(4,'SCons USE_CONFIG specified as false, will not inherit variables python config file...')
@ -1146,6 +1150,7 @@ if not preconfigured:
# if the user is not setting custom boost configuration
# enforce boost version greater than or equal to BOOST_MIN_VERSION
if not conf.CheckBoost(BOOST_MIN_VERSION):
color_print(4,'Found boost lib version... %s' % env.get('BOOST_LIB_VERSION_FROM_HEADER') )
color_print(1,'Boost version %s or greater is required' % BOOST_MIN_VERSION)
if not env['BOOST_VERSION']:
env['MISSING_DEPS'].append('boost version >=%s' % BOOST_MIN_VERSION)
@ -1326,12 +1331,74 @@ if not preconfigured:
color_print(4,'Not building with cairo support, pass CAIRO=True to enable')
if 'python' in env['BINDINGS']:
# checklibwithheader does not work for boost_python since we can't feed it
# multiple header files, so we fall back on a simple check for boost_python headers
if not os.access(env['PYTHON'], os.X_OK):
color_print(1,"Cannot run python interpreter at '%s', make sure that you have the permissions to execute it." % env['PYTHON'])
Exit(1)
py3 = 'True' in os.popen('''%s -c "import sys as s;s.stdout.write(str(s.version_info[0] == 3))"''' % env['PYTHON']).read().strip()
if py3:
sys_prefix = '''%s -c "import sys; print(sys.prefix)"''' % env['PYTHON']
else:
sys_prefix = '''%s -c "import sys; print sys.prefix"''' % env['PYTHON']
env['PYTHON_SYS_PREFIX'] = call(sys_prefix)
if HAS_DISTUTILS:
if py3:
sys_version = '''%s -c "from distutils.sysconfig import get_python_version; print(get_python_version())"''' % env['PYTHON']
else:
sys_version = '''%s -c "from distutils.sysconfig import get_python_version; print get_python_version()"''' % env['PYTHON']
env['PYTHON_VERSION'] = call(sys_version)
if py3:
py_includes = '''%s -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())"''' % env['PYTHON']
else:
py_includes = '''%s -c "from distutils.sysconfig import get_python_inc; print get_python_inc()"''' % env['PYTHON']
env['PYTHON_INCLUDES'] = call(py_includes)
# Note: we use the plat_specific argument here to make sure to respect the arch-specific site-packages location
if py3:
site_packages = '''%s -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific=True))"''' % env['PYTHON']
else:
site_packages = '''%s -c "from distutils.sysconfig import get_python_lib; print get_python_lib(plat_specific=True)"''' % env['PYTHON']
env['PYTHON_SITE_PACKAGES'] = call(site_packages)
else:
env['PYTHON_SYS_PREFIX'] = os.popen('''%s -c "import sys; print sys.prefix"''' % env['PYTHON']).read().strip()
env['PYTHON_VERSION'] = os.popen('''%s -c "import sys; print sys.version"''' % env['PYTHON']).read()[0:3]
env['PYTHON_INCLUDES'] = env['PYTHON_SYS_PREFIX'] + '/include/python' + env['PYTHON_VERSION']
env['PYTHON_SITE_PACKAGES'] = env['DESTDIR'] + os.path.sep + env['PYTHON_SYS_PREFIX'] + os.path.sep + env['LIBDIR_SCHEMA'] + '/python' + env['PYTHON_VERSION'] + '/site-packages/'
# if user-requested custom prefix fall back to manual concatenation for building subdirectories
if env['PYTHON_PREFIX']:
py_relative_install = env['LIBDIR_SCHEMA'] + '/python' + env['PYTHON_VERSION'] + '/site-packages/'
env['PYTHON_INSTALL_LOCATION'] = env['DESTDIR'] + os.path.sep + env['PYTHON_PREFIX'] + os.path.sep + py_relative_install
else:
env['PYTHON_INSTALL_LOCATION'] = env['DESTDIR'] + os.path.sep + env['PYTHON_SITE_PACKAGES']
if py3:
is_64_bit = '''%s -c "import sys; print(sys.maxsize == 9223372036854775807)"''' % env['PYTHON']
else:
is_64_bit = '''%s -c "import sys; print sys.maxint == 9223372036854775807"''' % env['PYTHON']
if is_64_bit:
env['PYTHON_IS_64BIT'] = True
else:
env['PYTHON_IS_64BIT'] = False
if py3 and env['BOOST_PYTHON_LIB'] == 'boost_python':
env['BOOST_PYTHON_LIB'] = 'boost_python3%s' % env['BOOST_APPEND']
elif env['BOOST_PYTHON_LIB'] == 'boost_python':
env['BOOST_PYTHON_LIB'] = 'boost_python%s' % env['BOOST_APPEND']
if not conf.CheckHeader(header='boost/python/detail/config.hpp',language='C++'):
color_print(1,'Could not find required header files for boost python')
env['MISSING_DEPS'].append('boost python')
if not conf.CheckLibWithHeader(libs=[env['BOOST_PYTHON_LIB'],'python%s' % env['PYTHON_VERSION']], header='boost/python/detail/config.hpp', language='C++'):
color_print(1, 'Could not find library "%s" for boost python bindings' % env['BOOST_PYTHON_LIB'])
# failing on launchpad, so let's make it a warning for now
#env['MISSING_DEPS'].append('boost python')
if env['CAIRO']:
if conf.CheckPKGConfig('0.15.0') and conf.CheckPKG('pycairo'):
env['HAS_PYCAIRO'] = True
@ -1459,68 +1526,13 @@ if not preconfigured:
if env['DEBUG']:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags)
else:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags))
env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -fno-strict-aliasing -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags))
if env['DEBUG_UNDEFINED']:
env.Append(CXXFLAGS = '-fcatch-undefined-behavior -ftrapv -fwrapv')
if 'python' in env['BINDINGS']:
if not os.access(env['PYTHON'], os.X_OK):
color_print(1,"Cannot run python interpreter at '%s', make sure that you have the permissions to execute it." % env['PYTHON'])
Exit(1)
py3 = 'True' in os.popen('''%s -c "import sys as s;s.stdout.write(str(s.version_info[0] == 3))"''' % env['PYTHON']).read().strip()
if py3:
sys_prefix = '''%s -c "import sys; print(sys.prefix)"''' % env['PYTHON']
else:
sys_prefix = '''%s -c "import sys; print sys.prefix"''' % env['PYTHON']
env['PYTHON_SYS_PREFIX'] = call(sys_prefix)
if HAS_DISTUTILS:
if py3:
sys_version = '''%s -c "from distutils.sysconfig import get_python_version; print(get_python_version())"''' % env['PYTHON']
else:
sys_version = '''%s -c "from distutils.sysconfig import get_python_version; print get_python_version()"''' % env['PYTHON']
env['PYTHON_VERSION'] = call(sys_version)
if py3:
py_includes = '''%s -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())"''' % env['PYTHON']
else:
py_includes = '''%s -c "from distutils.sysconfig import get_python_inc; print get_python_inc()"''' % env['PYTHON']
env['PYTHON_INCLUDES'] = call(py_includes)
# Note: we use the plat_specific argument here to make sure to respect the arch-specific site-packages location
if py3:
site_packages = '''%s -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific=True))"''' % env['PYTHON']
else:
site_packages = '''%s -c "from distutils.sysconfig import get_python_lib; print get_python_lib(plat_specific=True)"''' % env['PYTHON']
env['PYTHON_SITE_PACKAGES'] = call(site_packages)
else:
env['PYTHON_SYS_PREFIX'] = os.popen('''%s -c "import sys; print sys.prefix"''' % env['PYTHON']).read().strip()
env['PYTHON_VERSION'] = os.popen('''%s -c "import sys; print sys.version"''' % env['PYTHON']).read()[0:3]
env['PYTHON_INCLUDES'] = env['PYTHON_SYS_PREFIX'] + '/include/python' + env['PYTHON_VERSION']
env['PYTHON_SITE_PACKAGES'] = env['DESTDIR'] + os.path.sep + env['PYTHON_SYS_PREFIX'] + os.path.sep + env['LIBDIR_SCHEMA'] + '/python' + env['PYTHON_VERSION'] + '/site-packages/'
# if user-requested custom prefix fall back to manual concatenation for building subdirectories
if env['PYTHON_PREFIX']:
py_relative_install = env['LIBDIR_SCHEMA'] + '/python' + env['PYTHON_VERSION'] + '/site-packages/'
env['PYTHON_INSTALL_LOCATION'] = env['DESTDIR'] + os.path.sep + env['PYTHON_PREFIX'] + os.path.sep + py_relative_install
else:
env['PYTHON_INSTALL_LOCATION'] = env['DESTDIR'] + os.path.sep + env['PYTHON_SITE_PACKAGES']
if py3:
is_64_bit = '''%s -c "import sys; print(sys.maxsize == 9223372036854775807)"''' % env['PYTHON']
else:
is_64_bit = '''%s -c "import sys; print sys.maxint == 9223372036854775807"''' % env['PYTHON']
if is_64_bit:
env['PYTHON_IS_64BIT'] = True
else:
env['PYTHON_IS_64BIT'] = False
majver, minver = env['PYTHON_VERSION'].split('.')
# we don't want the includes it in the main environment...
# as they are later set in the python build.py
# ugly hack needed until we have env specific conf
@ -1535,11 +1547,6 @@ if not preconfigured:
color_print(1,"Python version 2.2 or greater required")
Exit(1)
if env['BOOST_PYTHON_LIB']:
if not conf.CheckLibWithHeader(libs=[env['BOOST_PYTHON_LIB']], header='boost/python/detail/config.hpp', language='C++'):
color_print(1, 'Could not find library %s for boost python' % env['BOOST_PYTHON_LIB'])
Exit(1)
color_print(4,'Bindings Python version... %s' % env['PYTHON_VERSION'])
color_print(4,'Python %s prefix... %s' % (env['PYTHON_VERSION'], env['PYTHON_SYS_PREFIX']))
color_print(4,'Python bindings will install in... %s' % os.path.normpath(env['PYTHON_INSTALL_LOCATION']))
@ -1656,7 +1663,6 @@ if not HELP_REQUESTED:
# But let's also cache implicit deps...
EnsureSConsVersion(0,98)
SetOption('implicit_cache', 1)
env.Decider('MD5-timestamp')
SetOption('max_drift', 1)
else:

View file

@ -43,15 +43,7 @@ prefix = env['PREFIX']
target_path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik')
target_path_deprecated = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')
libraries = ['mapnik']
if env['BOOST_PYTHON_LIB']:
libraries.append(env['BOOST_PYTHON_LIB'])
else:
if is_py3():
libraries.append('boost_python3%s' % env['BOOST_APPEND'])
else:
libraries.append('boost_python%s' % env['BOOST_APPEND'])
libraries = ['mapnik',env['BOOST_PYTHON_LIB']]
# TODO - do solaris/fedora need direct linking too?
if env['PLATFORM'] == 'Darwin':

View file

@ -60,9 +60,9 @@ void add_wkt_impl(path_type& p, std::string const& wkt)
if (!result) throw std::runtime_error("Failed to parse WKT");
}
void add_wkb_impl(path_type& p, std::string const& wkb)
bool add_wkb_impl(path_type& p, std::string const& wkb)
{
mapnik::geometry_utils::from_wkb(p, wkb.c_str(), wkb.size());
return mapnik::geometry_utils::from_wkb(p, wkb.c_str(), wkb.size());
}
boost::shared_ptr<path_type> from_wkt_impl(std::string const& wkt)

View file

@ -118,6 +118,18 @@ bool painted(mapnik::image_32 const& im)
return im.painted();
}
unsigned get_pixel(mapnik::image_32 const& im, int x, int y)
{
if (x < static_cast<int>(im.width()) && y < static_cast<int>(im.height()))
{
mapnik::image_data_32 const & data = im.data();
return data(x,y);
}
PyErr_SetString(PyExc_IndexError, "invalid x,y for image dimensions");
boost::python::throw_error_already_set();
return 0;
}
void set_pixel(mapnik::image_32 & im, unsigned x, unsigned y, mapnik::color const& c)
{
im.setPixel(x, y, c.rgba());
@ -216,6 +228,7 @@ void export_image()
.def("premultiply",&image_32::premultiply)
.def("demultiply",&image_32::demultiply)
.def("set_pixel",&set_pixel)
.def("get_pixel",&get_pixel)
//TODO(haoyu) The method name 'tostring' might be confusing since they actually return bytes in Python 3
.def("tostring",&tostring1)

View file

@ -97,7 +97,7 @@ void export_markers_symbolizer()
;
class_<markers_symbolizer>("MarkersSymbolizer",
init<>("Default Markers Symbolizer - blue arrow"))
init<>("Default Markers Symbolizer - circle"))
.def (init<mapnik::path_expression_ptr>("<path expression ptr>"))
//.def_pickle(markers_symbolizer_pickle_suite())
.add_property("filename",
@ -123,21 +123,21 @@ void export_markers_symbolizer()
&mapnik::get_svg_transform<markers_symbolizer>,
&mapnik::set_svg_transform<markers_symbolizer>)
.add_property("width",
&markers_symbolizer::get_width,
make_function(&markers_symbolizer::get_width,
return_value_policy<copy_const_reference>()),
&markers_symbolizer::set_width,
"Set/get the marker width")
.add_property("height",
&markers_symbolizer::get_height,
make_function(&markers_symbolizer::get_height,
return_value_policy<copy_const_reference>()),
&markers_symbolizer::set_height,
"Set/get the marker height")
.add_property("fill",
make_function(&markers_symbolizer::get_fill,
return_value_policy<copy_const_reference>()),
&markers_symbolizer::get_fill,
&markers_symbolizer::set_fill,
"Set/get the marker fill color")
.add_property("stroke",
make_function(&markers_symbolizer::get_stroke,
return_value_policy<copy_const_reference>()),
&markers_symbolizer::get_stroke,
&markers_symbolizer::set_stroke,
"Set/get the marker stroke (outline)")
.add_property("placement",

View file

@ -37,6 +37,7 @@ void export_palette();
void export_image();
void export_image_view();
void export_gamma_method();
void export_scaling_method();
void export_grid();
void export_grid_view();
void export_map();
@ -88,6 +89,15 @@ void export_logger();
#include "mapnik_value_converter.hpp"
#include "mapnik_threads.hpp"
#include "python_optional.hpp"
#include <mapnik/marker_cache.hpp>
#include <mapnik/mapped_memory_cache.hpp>
void clear_cache()
{
mapnik::marker_cache::instance()->clear();
mapnik::mapped_memory_cache::instance()->clear();
}
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
#include <pycairo.h>
@ -150,12 +160,13 @@ void render_layer2(const mapnik::Map& map,
void render3(const mapnik::Map& map,
PycairoSurface* surface,
double scale_factor = 1.0,
unsigned offset_x = 0,
unsigned offset_y = 0)
{
python_unblock_auto_block b;
Cairo::RefPtr<Cairo::Surface> s(new Cairo::Surface(surface->surface));
mapnik::cairo_renderer<Cairo::Surface> ren(map,s,offset_x, offset_y);
mapnik::cairo_renderer<Cairo::Surface> ren(map,s,scale_factor,offset_x,offset_y);
ren.apply();
}
@ -169,12 +180,13 @@ void render4(const mapnik::Map& map, PycairoSurface* surface)
void render5(const mapnik::Map& map,
PycairoContext* context,
double scale_factor = 1.0,
unsigned offset_x = 0,
unsigned offset_y = 0)
{
python_unblock_auto_block b;
Cairo::RefPtr<Cairo::Context> c(new Cairo::Context(context->ctx));
mapnik::cairo_renderer<Cairo::Context> ren(map,c,offset_x, offset_y);
mapnik::cairo_renderer<Cairo::Context> ren(map,c,scale_factor,offset_x, offset_y);
ren.apply();
}
@ -207,7 +219,7 @@ void render_to_file1(const mapnik::Map& map,
if (format == "pdf" || format == "svg" || format =="ps" || format == "ARGB32" || format == "RGB24")
{
#if defined(HAVE_CAIRO)
mapnik::save_to_cairo_file(map,filename,format);
mapnik::save_to_cairo_file(map,filename,format,1.0);
#else
throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format);
#endif
@ -226,7 +238,7 @@ void render_to_file2(const mapnik::Map& map,const std::string& filename)
if (format == "pdf" || format == "svg" || format =="ps")
{
#if defined(HAVE_CAIRO)
mapnik::save_to_cairo_file(map,filename,format);
mapnik::save_to_cairo_file(map,filename,format,1.0);
#else
throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format);
#endif
@ -248,7 +260,7 @@ void render_to_file3(const mapnik::Map& map,
if (format == "pdf" || format == "svg" || format =="ps" || format == "ARGB32" || format == "RGB24")
{
#if defined(HAVE_CAIRO)
mapnik::save_to_cairo_file(map,filename,format);
mapnik::save_to_cairo_file(map,filename,format,scale_factor);
#else
throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format);
#endif
@ -360,6 +372,7 @@ BOOST_PYTHON_MODULE(_mapnik)
export_image();
export_image_view();
export_gamma_method();
export_scaling_method();
export_grid();
export_grid_view();
export_expression();
@ -389,6 +402,15 @@ BOOST_PYTHON_MODULE(_mapnik)
export_label_collision_detector();
export_logger();
def("clear_cache", &clear_cache,
"\n"
"Clear all global caches of markers and mapped memory regions.\n"
"\n"
"Usage:\n"
">>> from mapnik import clear_cache\n"
">>> clear_cache()\n"
);
def("render_grid",&render_grid,
( arg("map"),
arg("layer"),

View file

@ -30,6 +30,8 @@
using mapnik::query;
using mapnik::box2d;
namespace python = boost::python;
struct query_pickle_suite : boost::python::pickle_suite
{
static boost::python::tuple
@ -39,10 +41,26 @@ struct query_pickle_suite : boost::python::pickle_suite
}
};
struct resolution_to_tuple
{
static PyObject* convert(query::resolution_type const& x)
{
python::object tuple(python::make_tuple(x.get<0>(), x.get<1>()));
return python::incref(tuple.ptr());
}
static PyTypeObject const* get_pytype()
{
return &PyTuple_Type;
}
};
void export_query()
{
using namespace boost::python;
to_python_converter<query::resolution_type, resolution_to_tuple> ();
class_<query>("Query", "a spatial query data object",
init<box2d<double>,query::resolution_type const&,double>() )
.def(init<box2d<double> >())

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/raster_symbolizer.hpp>
#include <mapnik/image_scaling.hpp>
using mapnik::raster_symbolizer;
@ -39,13 +40,13 @@ struct raster_symbolizer_pickle_suite : boost::python::pickle_suite
*/
static boost::python::tuple
getstate(const raster_symbolizer& r)
getstate(raster_symbolizer const& r)
{
return boost::python::make_tuple(r.get_mode(),r.get_scaling(),r.get_opacity(),r.get_filter_factor(),r.get_mesh_size());
return boost::python::make_tuple(r.get_mode(),r.get_scaling_method(),r.get_opacity(),r.get_filter_factor(),r.get_mesh_size());
}
static void
setstate (raster_symbolizer& r, boost::python::tuple state)
setstate (raster_symbolizer & r, boost::python::tuple state)
{
using namespace boost::python;
if (len(state) != 5)
@ -58,7 +59,7 @@ struct raster_symbolizer_pickle_suite : boost::python::pickle_suite
}
r.set_mode(extract<std::string>(state[0]));
r.set_scaling(extract<std::string>(state[1]));
r.set_scaling_method(extract<mapnik::scaling_method_e>(state[1]));
r.set_opacity(extract<float>(state[2]));
r.set_filter_factor(extract<float>(state[3]));
r.set_mesh_size(extract<unsigned>(state[4]));
@ -91,17 +92,15 @@ void export_raster_symbolizer()
)
.add_property("scaling",
make_function(&raster_symbolizer::get_scaling,return_value_policy<copy_const_reference>()),
&raster_symbolizer::set_scaling,
&raster_symbolizer::get_scaling_method,
&raster_symbolizer::set_scaling_method,
"Get/Set scaling algorithm.\n"
"Possible values are:\n"
"fast, bilinear, and bilinear8\n"
"\n"
"Usage:\n"
"\n"
">>> from mapnik import RasterSymbolizer\n"
">>> r = RasterSymbolizer()\n"
">>> r.scaling = 'bilinear8'\n"
">>> r.scaling = 'mapnik.scaling_method.GAUSSIAN'\n"
)
.add_property("opacity",

View file

@ -0,0 +1,53 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 Artem Pavlenko, Jean-Francois Doyon
*
* 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
*
*****************************************************************************/
//$Id$
#include <boost/python.hpp>
#include <mapnik/image_scaling.hpp>
#include "mapnik_enumeration.hpp"
void export_scaling_method()
{
using namespace boost::python;
enum_<mapnik::scaling_method_e>("scaling_method")
.value("NEAR", mapnik::SCALING_NEAR)
.value("BILINEAR", mapnik::SCALING_BILINEAR)
.value("BICUBIC", mapnik::SCALING_BICUBIC)
.value("SPLINE16", mapnik::SCALING_SPLINE16)
.value("SPLINE36", mapnik::SCALING_SPLINE36)
.value("HANNING", mapnik::SCALING_HANNING)
.value("HAMMING", mapnik::SCALING_HAMMING)
.value("HERMITE", mapnik::SCALING_HERMITE)
.value("KAISER", mapnik::SCALING_KAISER)
.value("QUADRIC", mapnik::SCALING_QUADRIC)
.value("CATROM", mapnik::SCALING_CATROM)
.value("GAUSSIAN", mapnik::SCALING_GAUSSIAN)
.value("BESSEL", mapnik::SCALING_BESSEL)
.value("MITCHELL", mapnik::SCALING_MITCHELL)
.value("SINC", mapnik::SCALING_SINC)
.value("LANCZOS", mapnik::SCALING_LANCZOS)
.value("BLACKMAN", mapnik::SCALING_BLACKMAN)
.value("BILINEAR8", mapnik::SCALING_BILINEAR8)
;
}

View file

@ -0,0 +1,505 @@
/*****************************************************************************
*
* 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/debug.hpp>
#include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid.hpp>
#include <mapnik/grid/grid_util.hpp>
#include <mapnik/grid/grid_view.hpp>
#include <mapnik/value_error.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_kv_iterator.hpp>
#include "mapnik_value_converter.hpp"
#include "python_grid_utils.hpp"
namespace mapnik {
template <typename T>
void grid2utf(T const& grid_type,
boost::python::list& l,
std::vector<grid::lookup_type>& key_order)
{
typedef std::map< typename T::lookup_type, typename T::value_type> keys_type;
typedef typename keys_type::const_iterator keys_iterator;
typename T::data_type const& data = grid_type.data();
typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys();
typename T::feature_key_type::const_iterator feature_pos;
keys_type keys;
// start counting at utf8 codepoint 32, aka space character
boost::uint16_t codepoint = 32;
unsigned array_size = data.width();
for (unsigned y = 0; y < data.height(); ++y)
{
boost::uint16_t idx = 0;
boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]);
typename T::value_type const* row = data.getRow(y);
for (unsigned x = 0; x < data.width(); ++x)
{
typename T::value_type feature_id = row[x];
feature_pos = feature_keys.find(feature_id);
if (feature_pos != feature_keys.end())
{
mapnik::grid::lookup_type val = feature_pos->second;
keys_iterator key_pos = keys.find(val);
if (key_pos == keys.end())
{
// Create a new entry for this key. Skip the codepoints that
// can't be encoded directly in JSON.
if (codepoint == 34) ++codepoint; // Skip "
else if (codepoint == 92) ++codepoint; // Skip backslash
if (feature_id == mapnik::grid::base_mask)
{
keys[""] = codepoint;
key_order.push_back("");
}
else
{
keys[val] = codepoint;
key_order.push_back(val);
}
line[idx++] = static_cast<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
template <typename T>
void grid2utf(T const& grid_type,
boost::python::list& l,
std::vector<typename T::lookup_type>& key_order,
unsigned int resolution)
{
typedef std::map< typename T::lookup_type, typename T::value_type> keys_type;
typedef typename keys_type::const_iterator keys_iterator;
typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys();
typename T::feature_key_type::const_iterator feature_pos;
keys_type keys;
// start counting at utf8 codepoint 32, aka space character
boost::uint16_t codepoint = 32;
// TODO - use double?
unsigned array_size = static_cast<unsigned int>(grid_type.width()/resolution);
for (unsigned y = 0; y < grid_type.height(); y=y+resolution)
{
boost::uint16_t idx = 0;
boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]);
mapnik::grid::value_type const* row = grid_type.getRow(y);
for (unsigned x = 0; x < grid_type.width(); x=x+resolution)
{
typename T::value_type feature_id = row[x];
feature_pos = feature_keys.find(feature_id);
if (feature_pos != feature_keys.end())
{
mapnik::grid::lookup_type val = feature_pos->second;
keys_iterator key_pos = keys.find(val);
if (key_pos == keys.end())
{
// Create a new entry for this key. Skip the codepoints that
// can't be encoded directly in JSON.
if (codepoint == 34) ++codepoint; // Skip "
else if (codepoint == 92) ++codepoint; // Skip backslash
if (feature_id == mapnik::grid::base_mask)
{
keys[""] = codepoint;
key_order.push_back("");
}
else
{
keys[val] = codepoint;
key_order.push_back(val);
}
line[idx++] = static_cast<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
template <typename T>
void grid2utf2(T const& grid_type,
boost::python::list& l,
std::vector<typename T::lookup_type>& key_order,
unsigned int resolution)
{
typedef std::map< typename T::lookup_type, typename T::value_type> keys_type;
typedef typename keys_type::const_iterator keys_iterator;
typename T::data_type const& data = grid_type.data();
typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys();
typename T::feature_key_type::const_iterator feature_pos;
keys_type keys;
// start counting at utf8 codepoint 32, aka space character
uint16_t codepoint = 32;
mapnik::grid::data_type target(data.width()/resolution,data.height()/resolution);
mapnik::scale_grid(target,grid_type.data(),0.0,0.0);
unsigned array_size = target.width();
for (unsigned y = 0; y < target.height(); ++y)
{
uint16_t idx = 0;
boost::scoped_array<Py_UNICODE> line(new Py_UNICODE[array_size]);
mapnik::grid::value_type * row = target.getRow(y);
unsigned x;
for (x = 0; x < target.width(); ++x)
{
feature_pos = feature_keys.find(row[x]);
if (feature_pos != feature_keys.end())
{
mapnik::grid::lookup_type val = feature_pos->second;
keys_iterator key_pos = keys.find(val);
if (key_pos == keys.end())
{
// Create a new entry for this key. Skip the codepoints that
// can't be encoded directly in JSON.
if (codepoint == 34) ++codepoint; // Skip "
else if (codepoint == 92) ++codepoint; // Skip backslash
keys[val] = codepoint;
key_order.push_back(val);
line[idx++] = static_cast<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
template <typename T>
void write_features(T const& grid_type,
boost::python::dict& feature_data,
std::vector<typename T::lookup_type> const& key_order)
{
std::string const& key = grid_type.get_key();
std::set<std::string> const& attributes = grid_type.property_names();
typename T::feature_type const& g_features = grid_type.get_grid_features();
typename T::feature_type::const_iterator feat_itr = g_features.begin();
typename T::feature_type::const_iterator feat_end = g_features.end();
bool include_key = (attributes.find(key) != attributes.end());
for (; feat_itr != feat_end; ++feat_itr)
{
mapnik::feature_ptr feature = feat_itr->second;
boost::optional<std::string> join_value;
if (key == grid_type.key_name())
{
join_value = feat_itr->first;
}
else if (feature->has_key(key))
{
join_value = feature->get(key).to_string();
}
if (join_value)
{
// only serialize features visible in the grid
if(std::find(key_order.begin(), key_order.end(), *join_value) != key_order.end()) {
boost::python::dict feat;
bool found = false;
if (key == grid_type.key_name())
{
// drop key unless requested
if (include_key) {
found = true;
//TODO - add __id__ as data key?
//feat[key] = *join_value;
}
}
feature_kv_iterator itr = feature->begin();
feature_kv_iterator end = feature->end();
for ( ;itr!=end; ++itr)
{
std::string const& key_name = boost::get<0>(*itr);
if (key_name == key) {
// drop key unless requested
if (include_key) {
found = true;
feat[key_name] = boost::get<1>(*itr);
}
}
else if ( (attributes.find(key_name) != attributes.end()) )
{
found = true;
feat[key_name] = boost::get<1>(*itr);
}
}
if (found)
{
feature_data[feat_itr->first] = feat;
}
}
}
else
{
MAPNIK_LOG_DEBUG(bindings) << "write_features: Should not get here: key " << key << " not found in grid feature properties";
}
}
}
template <typename T>
void grid_encode_utf(T const& grid_type,
boost::python::dict & json,
bool add_features,
unsigned int resolution)
{
// convert buffer to utf and gather key order
boost::python::list l;
std::vector<typename T::lookup_type> key_order;
if (resolution != 1) {
// resample on the fly - faster, less accurate
mapnik::grid2utf<T>(grid_type,l,key_order,resolution);
// resample first - slower, more accurate
//mapnik::grid2utf2<T>(grid_type,l,key_order,resolution);
}
else
{
mapnik::grid2utf<T>(grid_type,l,key_order);
}
// convert key order to proper python list
boost::python::list keys_a;
BOOST_FOREACH ( typename T::lookup_type const& key_id, key_order )
{
keys_a.append(key_id);
}
// gather feature data
boost::python::dict feature_data;
if (add_features) {
mapnik::write_features<T>(grid_type,feature_data,key_order);
}
json["grid"] = l;
json["keys"] = keys_a;
json["data"] = feature_data;
}
template <typename T>
boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution)
{
if (format == "utf") {
boost::python::dict json;
grid_encode_utf<T>(grid,json,add_features,resolution);
return json;
}
else
{
std::stringstream s;
s << "'utf' is currently the only supported encoding format.";
throw mapnik::value_error(s.str());
}
}
template boost::python::dict grid_encode( mapnik::grid const& grid, std::string format, bool add_features, unsigned int resolution);
template boost::python::dict grid_encode( mapnik::grid_view const& grid, std::string format, bool add_features, unsigned int resolution);
/* new approach: key comes from grid object
* grid size should be same as the map
* encoding, resizing handled as method on grid object
* whether features are dumped is determined by argument not 'fields'
*/
void render_layer_for_grid(const mapnik::Map& map,
mapnik::grid& grid,
unsigned layer_idx, // TODO - layer by name or index
boost::python::list const& fields)
{
std::vector<mapnik::layer> const& layers = map.layers();
std::size_t layer_num = layers.size();
if (layer_idx >= layer_num) {
std::ostringstream s;
s << "Zero-based layer index '" << layer_idx << "' not valid, only '"
<< layer_num << "' layers are in map\n";
throw std::runtime_error(s.str());
}
// convert python list to std::vector
boost::python::ssize_t num_fields = boost::python::len(fields);
for(boost::python::ssize_t i=0; i<num_fields; i++) {
boost::python::extract<std::string> name(fields[i]);
if (name.check()) {
grid.add_property_name(name());
}
else
{
std::stringstream s;
s << "list of field names must be strings";
throw mapnik::value_error(s.str());
}
}
// copy property names
std::set<std::string> attributes = grid.property_names();
std::string const& key = grid.get_key();
// if key is special __id__ keyword
if (key == grid.key_name())
{
// TODO - should feature.id() be a first class attribute?
// if __id__ is requested to be dumped out
// remove it so that datasource queries will not break
if (attributes.find(key) != attributes.end())
{
attributes.erase(key);
}
}
// if key is not the special __id__ keyword
else if (attributes.find(key) == attributes.end())
{
// them make sure the datasource query includes this field
attributes.insert(key);
}
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
mapnik::layer const& layer = layers[layer_idx];
ren.apply(layer,attributes);
}
/* old, original impl - to be removed after further testing
* grid object is created on the fly at potentially reduced size
*/
boost::python::dict render_grid(const mapnik::Map& map,
unsigned layer_idx, // layer
std::string const& key, // key_name
unsigned int step, // resolution
boost::python::list const& fields)
{
std::vector<mapnik::layer> const& layers = map.layers();
std::size_t layer_num = layers.size();
if (layer_idx >= layer_num) {
std::ostringstream s;
s << "Zero-based layer index '" << layer_idx << "' not valid, only '"
<< layer_num << "' layers are in map\n";
throw std::runtime_error(s.str());
}
unsigned int grid_width = map.width()/step;
unsigned int grid_height = map.height()/step;
// TODO - no need to pass step here
mapnik::grid grid(grid_width,grid_height,key,step);
// convert python list to std::vector
boost::python::ssize_t num_fields = boost::python::len(fields);
for(boost::python::ssize_t i=0; i<num_fields; i++) {
boost::python::extract<std::string> name(fields[i]);
if (name.check()) {
grid.add_property_name(name());
}
else
{
std::stringstream s;
s << "list of field names must be strings";
throw mapnik::value_error(s.str());
}
}
// copy property names
std::set<std::string> attributes = grid.property_names();
// if key is special __id__ keyword
if (key == grid.key_name())
{
// TODO - should feature.id() be a first class attribute?
// if __id__ is requested to be dumped out
// remove it so that datasource queries will not break
if (attributes.find(key) != attributes.end())
{
attributes.erase(key);
}
}
// if key is not the special __id__ keyword
else if (attributes.find(key) == attributes.end())
{
// them make sure the datasource query includes this field
attributes.insert(key);
}
try
{
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
mapnik::layer const& layer = layers[layer_idx];
ren.apply(layer,attributes);
}
catch (...)
{
throw;
}
bool add_features = false;
if (num_fields > 0)
add_features = true;
// build dictionary and return to python
boost::python::dict json;
grid_encode_utf(grid,json,add_features,1);
return json;
}
}

View file

@ -24,475 +24,66 @@
// boost
#include <boost/python.hpp>
#include <boost/scoped_array.hpp>
#include <boost/foreach.hpp>
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/grid/grid.hpp>
#include <mapnik/grid/grid_util.hpp>
#include <mapnik/grid/grid_view.hpp>
#include <mapnik/value_error.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_kv_iterator.hpp>
#include "mapnik_value_converter.hpp"
namespace mapnik {
template <typename T>
static void grid2utf(T const& grid_type,
void grid2utf(T const& grid_type,
boost::python::list& l,
std::vector<grid::lookup_type>& key_order)
{
typename T::data_type const& data = grid_type.data();
typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys();
typename T::key_type keys;
typename T::key_type::const_iterator key_pos;
typename T::feature_key_type::const_iterator feature_pos;
// 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;
key_pos = keys.find(val);
if (key_pos == keys.end())
{
// Create a new entry for this key. Skip the codepoints that
// can't be encoded directly in JSON.
if (codepoint == 34) ++codepoint; // Skip "
else if (codepoint == 92) ++codepoint; // Skip backslash
if (feature_id == mapnik::grid::base_mask)
{
keys[""] = codepoint;
key_order.push_back("");
}
else
{
keys[val] = codepoint;
key_order.push_back(val);
}
line[idx++] = static_cast<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
std::vector<typename T::lookup_type>& key_order);
template <typename T>
static void grid2utf(T const& grid_type,
void grid2utf(T const& grid_type,
boost::python::list& l,
std::vector<typename T::lookup_type>& key_order,
unsigned int resolution)
{
//typename T::data_type const& data = grid_type.data();
typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys();
typename T::key_type keys;
typename T::key_type::const_iterator key_pos;
typename T::feature_key_type::const_iterator feature_pos;
// 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;
key_pos = keys.find(val);
if (key_pos == keys.end())
{
// Create a new entry for this key. Skip the codepoints that
// can't be encoded directly in JSON.
if (codepoint == 34) ++codepoint; // Skip "
else if (codepoint == 92) ++codepoint; // Skip backslash
if (feature_id == mapnik::grid::base_mask)
{
keys[""] = codepoint;
key_order.push_back("");
}
else
{
keys[val] = codepoint;
key_order.push_back(val);
}
line[idx++] = static_cast<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
unsigned int resolution);
template <typename T>
static void grid2utf2(T const& grid_type,
void grid2utf2(T const& grid_type,
boost::python::list& l,
std::vector<typename T::lookup_type>& key_order,
unsigned int resolution)
{
typename T::data_type const& data = grid_type.data();
typename T::feature_key_type const& feature_keys = grid_type.get_feature_keys();
typename T::key_type keys;
typename T::key_type::const_iterator key_pos;
typename T::feature_key_type::const_iterator feature_pos;
// 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;
key_pos = keys.find(val);
if (key_pos == keys.end())
{
// Create a new entry for this key. Skip the codepoints that
// can't be encoded directly in JSON.
if (codepoint == 34) ++codepoint; // Skip "
else if (codepoint == 92) ++codepoint; // Skip backslash
keys[val] = codepoint;
key_order.push_back(val);
line[idx++] = static_cast<Py_UNICODE>(codepoint);
++codepoint;
}
else
{
line[idx++] = static_cast<Py_UNICODE>(key_pos->second);
}
}
// else, shouldn't get here...
}
l.append(boost::python::object(
boost::python::handle<>(
PyUnicode_FromUnicode(line.get(), array_size))));
}
}
unsigned int resolution);
template <typename T>
static void write_features(T const& grid_type,
void write_features(T const& grid_type,
boost::python::dict& feature_data,
std::vector<typename T::lookup_type> const& key_order)
{
std::string const& key = grid_type.get_key();
std::set<std::string> const& attributes = grid_type.property_names();
typename T::feature_type const& g_features = grid_type.get_grid_features();
typename T::feature_type::const_iterator feat_itr = g_features.begin();
typename T::feature_type::const_iterator feat_end = g_features.end();
bool include_key = (attributes.find(key) != attributes.end());
for (; feat_itr != feat_end; ++feat_itr)
{
mapnik::feature_ptr feature = feat_itr->second;
boost::optional<std::string> join_value;
if (key == grid_type.key_name())
{
join_value = feat_itr->first;
}
else if (feature->has_key(key))
{
join_value = feature->get(key).to_string();
}
if (join_value)
{
// only serialize features visible in the grid
if(std::find(key_order.begin(), key_order.end(), *join_value) != key_order.end()) {
boost::python::dict feat;
bool found = false;
if (key == grid_type.key_name())
{
// drop key unless requested
if (include_key) {
found = true;
//TODO - add __id__ as data key?
//feat[key] = *join_value;
}
}
feature_kv_iterator itr = feature->begin();
feature_kv_iterator end = feature->end();
for ( ;itr!=end; ++itr)
{
std::string const& key_name = boost::get<0>(*itr);
if (key_name == key) {
// drop key unless requested
if (include_key) {
found = true;
feat[key_name] = boost::get<1>(*itr);
}
}
else if ( (attributes.find(key_name) != attributes.end()) )
{
found = true;
feat[key_name] = boost::get<1>(*itr);
}
}
if (found)
{
feature_data[feat_itr->first] = feat;
}
}
}
else
{
MAPNIK_LOG_DEBUG(bindings) << "write_features: Should not get here: key " << key << " not found in grid feature properties";
}
}
}
std::vector<typename T::lookup_type> const& key_order);
template <typename T>
static void grid_encode_utf(T const& grid_type,
void grid_encode_utf(T const& grid_type,
boost::python::dict & json,
bool add_features,
unsigned int resolution)
{
// convert buffer to utf and gather key order
boost::python::list l;
std::vector<typename T::lookup_type> key_order;
if (resolution != 1) {
// resample on the fly - faster, less accurate
mapnik::grid2utf<T>(grid_type,l,key_order,resolution);
// resample first - slower, more accurate
//mapnik::grid2utf2<T>(grid_type,l,key_order,resolution);
}
else
{
mapnik::grid2utf<T>(grid_type,l,key_order);
}
// convert key order to proper python list
boost::python::list keys_a;
BOOST_FOREACH ( typename T::lookup_type const& key_id, key_order )
{
keys_a.append(key_id);
}
// gather feature data
boost::python::dict feature_data;
if (add_features) {
mapnik::write_features<T>(grid_type,feature_data,key_order);
}
json["grid"] = l;
json["keys"] = keys_a;
json["data"] = feature_data;
}
unsigned int resolution);
template <typename T>
static boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution)
{
if (format == "utf") {
boost::python::dict json;
grid_encode_utf<T>(grid,json,add_features,resolution);
return json;
}
else
{
std::stringstream s;
s << "'utf' is currently the only supported encoding format.";
throw mapnik::value_error(s.str());
}
}
boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution);
/* new approach: key comes from grid object
* grid size should be same as the map
* encoding, resizing handled as method on grid object
* whether features are dumped is determined by argument not 'fields'
*/
static void render_layer_for_grid(const mapnik::Map& map,
void render_layer_for_grid(const mapnik::Map& map,
mapnik::grid& grid,
unsigned layer_idx, // TODO - layer by name or index
boost::python::list const& fields)
{
std::vector<mapnik::layer> const& layers = map.layers();
std::size_t layer_num = layers.size();
if (layer_idx >= layer_num) {
std::ostringstream s;
s << "Zero-based layer index '" << layer_idx << "' not valid, only '"
<< layer_num << "' layers are in map\n";
throw std::runtime_error(s.str());
}
// convert python list to std::vector
boost::python::ssize_t num_fields = boost::python::len(fields);
for(boost::python::ssize_t i=0; i<num_fields; i++) {
boost::python::extract<std::string> name(fields[i]);
if (name.check()) {
grid.add_property_name(name());
}
else
{
std::stringstream s;
s << "list of field names must be strings";
throw mapnik::value_error(s.str());
}
}
// copy property names
std::set<std::string> attributes = grid.property_names();
std::string const& key = grid.get_key();
// if key is special __id__ keyword
if (key == grid.key_name())
{
// TODO - should feature.id() be a first class attribute?
// if __id__ is requested to be dumped out
// remove it so that datasource queries will not break
if (attributes.find(key) != attributes.end())
{
attributes.erase(key);
}
}
// if key is not the special __id__ keyword
else if (attributes.find(key) == attributes.end())
{
// them make sure the datasource query includes this field
attributes.insert(key);
}
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
mapnik::layer const& layer = layers[layer_idx];
ren.apply(layer,attributes);
}
boost::python::list const& fields);
/* old, original impl - to be removed after further testing
* grid object is created on the fly at potentially reduced size
*/
static boost::python::dict render_grid(const mapnik::Map& map,
boost::python::dict render_grid(const mapnik::Map& map,
unsigned layer_idx, // layer
std::string const& key, // key_name
unsigned int step, // resolution
boost::python::list const& fields)
{
std::vector<mapnik::layer> const& layers = map.layers();
std::size_t layer_num = layers.size();
if (layer_idx >= layer_num) {
std::ostringstream s;
s << "Zero-based layer index '" << layer_idx << "' not valid, only '"
<< layer_num << "' layers are in map\n";
throw std::runtime_error(s.str());
}
unsigned int grid_width = map.width()/step;
unsigned int grid_height = map.height()/step;
// TODO - no need to pass step here
mapnik::grid grid(grid_width,grid_height,key,step);
// convert python list to std::vector
boost::python::ssize_t num_fields = boost::python::len(fields);
for(boost::python::ssize_t i=0; i<num_fields; i++) {
boost::python::extract<std::string> name(fields[i]);
if (name.check()) {
grid.add_property_name(name());
}
else
{
std::stringstream s;
s << "list of field names must be strings";
throw mapnik::value_error(s.str());
}
}
// copy property names
std::set<std::string> attributes = grid.property_names();
// if key is special __id__ keyword
if (key == grid.key_name())
{
// TODO - should feature.id() be a first class attribute?
// if __id__ is requested to be dumped out
// remove it so that datasource queries will not break
if (attributes.find(key) != attributes.end())
{
attributes.erase(key);
}
}
// if key is not the special __id__ keyword
else if (attributes.find(key) == attributes.end())
{
// them make sure the datasource query includes this field
attributes.insert(key);
}
try
{
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
mapnik::layer const& layer = layers[layer_idx];
ren.apply(layer,attributes);
}
catch (...)
{
throw;
}
bool add_features = false;
if (num_fields > 0)
add_features = true;
// build dictionary and return to python
boost::python::dict json;
grid_encode_utf(grid,json,add_features,1);
return json;
}
boost::python::list const& fields);
}
#endif // MAPNIK_PYTHON_BINDING_GRID_UTILS_INCLUDED

2
configure vendored
View file

@ -1,3 +1,3 @@
#!/bin/sh
python scons/scons.py configure "$@"
python scons/scons.py --implicit-cache configure "$@"

View file

@ -32,6 +32,7 @@
#include <QItemDelegate>
#include <QSlider>
#include <QComboBox>
#include <QDoubleSpinBox>
// mapnik
@ -97,12 +98,15 @@ MainWindow::MainWindow()
//connect mapview to layerlist
connect(mapWidget_, SIGNAL(mapViewChanged()),layerTab_, SLOT(update()));
// slider
connect(slider_,SIGNAL(valueChanged(int)),mapWidget_,SLOT(zoomToLevel(int)));
connect(slider_,SIGNAL(valueChanged(int)),mapWidget_,SLOT(zoomToLevel(int)));
// renderer selector
connect(renderer_selector_,SIGNAL(currentIndexChanged(QString const&)),
connect(renderer_selector_,SIGNAL(currentIndexChanged(QString const&)),
mapWidget_, SLOT(updateRenderer(QString const&)));
//
// scale factor
connect(scale_factor_,SIGNAL(valueChanged(double)),
mapWidget_, SLOT(updateScaleFactor(double)));
//
connect(layerTab_,SIGNAL(update_mapwidget()),mapWidget_,SLOT(updateMap()));
connect(layerTab_,SIGNAL(layerSelected(int)),
mapWidget_,SLOT(layerSelected(int)));
@ -373,16 +377,23 @@ void MainWindow::createToolBars()
fileToolBar->addAction(infoAct);
fileToolBar->addAction(reloadAct);
fileToolBar->addAction(printAct);
renderer_selector_ = new QComboBox(fileToolBar);
renderer_selector_->setFocusPolicy(Qt::NoFocus);
renderer_selector_->addItem("AGG");
#ifdef HAVE_CAIRO
renderer_selector_->addItem("Cairo");
#endif
renderer_selector_->addItem("Grid");
renderer_selector_->addItem("Grid");
fileToolBar->addWidget(renderer_selector_);
scale_factor_ = new QDoubleSpinBox(fileToolBar);
scale_factor_->setMinimum(0.1);
scale_factor_->setMaximum(5.0);
scale_factor_->setSingleStep(0.1);
scale_factor_->setValue(1.0);
fileToolBar->addWidget(scale_factor_);
slider_ = new QSlider(Qt::Horizontal,fileToolBar);
slider_->setRange(1,18);
slider_->setTickPosition(QSlider::TicksBelow);

View file

@ -28,6 +28,7 @@
#include <QActionGroup>
#include <QStatusBar>
#include <QAbstractItemModel>
#include <QDoubleSpinBox>
#include "mapwidget.hpp"
@ -37,6 +38,7 @@ class LayerTab;
class StyleTab;
class QSlider;
class QComboBox;
class QDoubleSpinBox;
class MainWindow : public QMainWindow
{
@ -108,6 +110,7 @@ private:
QStatusBar *status;
QSlider * slider_;
QComboBox * renderer_selector_;
QDoubleSpinBox * scale_factor_;
mapnik::box2d<double> default_extent_;
};

View file

@ -184,29 +184,29 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
feature_ptr feat = fs->next();
if (feat)
{
feature_kv_iterator itr(*feat,true);
feature_kv_iterator end(*feat);
for ( ;itr!=end; ++itr)
{
info.push_back(QPair<QString,QString>(QString(boost::get<0>(*itr).c_str()),
boost::get<1>(*itr).to_string().c_str()));
}
typedef mapnik::coord_transform<mapnik::CoordTransform,mapnik::geometry_type> path_type;
for (unsigned i=0; i<feat->num_geometries();++i)
{
mapnik::geometry_type & geom = feat->get_geometry(i);
path_type path(t,geom,prj_trans);
if (geom.num_points() > 0)
if (geom.size() > 0)
{
QPainterPath qpath;
double x,y;
path.vertex(&x,&y);
qpath.moveTo(x,y);
for (unsigned j = 1; j < geom.num_points(); ++j)
for (unsigned j = 1; j < geom.size(); ++j)
{
path.vertex(&x,&y);
qpath.lineTo(x,y);
@ -498,12 +498,12 @@ void render_agg(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
{
unsigned width=map.width();
unsigned height=map.height();
image_32 buf(width,height);
mapnik::agg_renderer<image_32> ren(map,buf,scaling_factor);
try
{
{
ren.apply();
QImage image((uchar*)buf.raw_data(),width,height,QImage::Format_ARGB32);
pix = QPixmap::fromImage(image.rgbSwapped());
@ -527,23 +527,23 @@ void render_grid(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
{
unsigned width=map.width();
unsigned height=map.height();
mapnik::grid buf(width,height,"F_CODE", 1);
mapnik::grid_renderer<mapnik::grid> ren(map,buf,scaling_factor);
try
{
{
ren.apply();
int * imdata = static_cast<int*>(buf.raw_data());
QImage image(width,height,QImage::Format_RGB32);
for (unsigned i = 0 ; i < height ; ++i)
{
{
for (unsigned j = 0 ; j < width ; ++j)
{
image.setPixel(j,i,qRgb((uint8_t)(imdata[i*width+j]>>8),
(uint8_t)(imdata[i*width+j+1]>>8),
(uint8_t)(imdata[i*width+j+2]>>8)));
(uint8_t)(imdata[i*width+j+2]>>8)));
}
}
pix = QPixmap::fromImage(image);
@ -567,12 +567,12 @@ void render_cairo(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
{
#ifdef HAVE_CAIRO
Cairo::RefPtr<Cairo::ImageSurface> image_surface =
Cairo::RefPtr<Cairo::ImageSurface> image_surface =
Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, map.width(),map.height());
mapnik::cairo_renderer<Cairo::Surface> png_render(map, image_surface);
mapnik::cairo_renderer<Cairo::Surface> png_render(map, image_surface, scaling_factor);
png_render.apply();
image_32 buf(image_surface);
QImage image((uchar*)buf.raw_data(),buf.width(),buf.height(),QImage::Format_ARGB32);
pix = QPixmap::fromImage(image.rgbSwapped());
@ -588,6 +588,12 @@ void MapWidget::updateRenderer(QString const& txt)
updateMap();
}
void MapWidget::updateScaleFactor(double scale_factor)
{
set_scaling_factor(scale_factor);
updateMap();
}
void MapWidget::updateMap()
{
if (map_)
@ -611,7 +617,7 @@ void MapWidget::updateMap()
try
{
projection prj(map_->srs()); // map projection
projection prj(map_->srs()); // map projection
box2d<double> ext = map_->get_current_extent();
double x0 = ext.minx();
double y0 = ext.miny();
@ -623,7 +629,7 @@ void MapWidget::updateMap()
update();
// emit signal to interested widgets
emit mapViewChanged();
}
}
catch (...)
{
std::cerr << "Unknown exception caught!\n";

View file

@ -53,8 +53,8 @@ public:
AGG,
Cairo,
Grid
};
};
private:
boost::shared_ptr<mapnik::Map> map_;
int selected_;
@ -91,6 +91,7 @@ public slots:
void updateMap();
void layerSelected(int);
void updateRenderer(QString const& txt);
void updateScaleFactor(double scale_factor);
signals:
void mapViewChanged();
protected:

View file

@ -1,18 +1,11 @@
######################################################################
# Mapnik viewer - Copyright (C) 2007 Artem Pavlenko
######################################################################
CC = g++
TEMPLATE = app
INCLUDEPATH += /usr/local/include/
INCLUDEPATH += /usr/boost/include/
INCLUDEPATH += /usr/X11/include/
INCLUDEPATH += /usr/X11/include/freetype2
INCLUDEPATH += .
QMAKE_CXXFLAGS +=' -DDARWIN -Wno-missing-field-initializers -ansi'
unix:LIBS = -L/usr/local/lib -L/usr/X11/lib -lmapnik -lfreetype
unix:LIBS += -lboost_system -licuuc -lboost_filesystem -lboost_regex
QMAKE_CXX = clang++
QMAKE_CXXFLAGS += $$system(mapnik-config --cflags)
QMAKE_LFLAGS += $$system(mapnik-config --libs)
QMAKE_LFLAGS += $$system(mapnik-config --ldflags --dep-libs)
# Input

View file

@ -25,6 +25,9 @@
// mapnik
#include <mapnik/value.hpp>
#include <mapnik/geometry.hpp>
// boost
#include <boost/foreach.hpp>
// stl
#include <string>
@ -44,6 +47,24 @@ struct attribute
std::string const& name() const { return name_;}
};
struct geometry_type_attribute
{
template <typename V, typename F>
V value(F const& f) const
{
int result = 0;
geometry_container::const_iterator itr = f.paths().begin();
geometry_container::const_iterator end = f.paths().end();
for ( ; itr != end; ++itr)
{
result = itr->type();
}
return result;
}
};
}
#endif // MAPNIK_ATTRIBUTE_HPP

View file

@ -47,6 +47,11 @@ struct expression_attributes : boost::static_visitor<void>
boost::ignore_unused_variable_warning(x);
}
void operator() (geometry_type_attribute const& type) const
{
// do nothing
}
void operator() (attribute const& attr) const
{
names_.insert(attr.name());

View file

@ -72,7 +72,7 @@ private:
class MAPNIK_DECL cairo_renderer_base : private boost::noncopyable
{
protected:
cairo_renderer_base(Map const& m, Cairo::RefPtr<Cairo::Context> const& context, unsigned offset_x=0, unsigned offset_y=0);
cairo_renderer_base(Map const& m, Cairo::RefPtr<Cairo::Context> const& context, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
public:
~cairo_renderer_base();
void start_map_processing(Map const& map);
@ -127,6 +127,9 @@ protected:
Map const& m_;
Cairo::RefPtr<Cairo::Context> context_;
unsigned width_;
unsigned height_;
double scale_factor_;
CoordTransform t_;
boost::shared_ptr<freetype_engine> font_engine_;
face_manager<freetype_engine> font_manager_;
@ -141,7 +144,7 @@ class MAPNIK_DECL cairo_renderer : public feature_style_processor<cairo_renderer
{
public:
typedef cairo_renderer_base processor_impl_type;
cairo_renderer(Map const& m, Cairo::RefPtr<T> const& surface, unsigned offset_x=0, unsigned offset_y=0);
cairo_renderer(Map const& m, Cairo::RefPtr<T> const& surface, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
void end_map_processing(Map const& map);
};
}

View file

@ -126,7 +126,7 @@ protected:
mutable bool is_bound_;
};
typedef std::string datasource_name();
typedef const char * datasource_name();
typedef datasource* create_ds(const parameters& params, bool bind);
typedef void destroy_ds(datasource *ds);
@ -142,7 +142,7 @@ public:
typedef boost::shared_ptr<datasource> datasource_ptr;
#define DATASOURCE_PLUGIN(classname) \
extern "C" MAPNIK_EXP std::string datasource_name() \
extern "C" MAPNIK_EXP const char * datasource_name() \
{ \
return classname::name(); \
} \

View file

@ -50,6 +50,10 @@ struct evaluate : boost::static_visitor<T1>
return attr.value<value_type,feature_type>(feature_);
}
value_type operator() (geometry_type_attribute const& attr) const
{
return attr.value<value_type,feature_type>(feature_);
}
value_type operator() (binary_node<tags::logical_and> const & x) const
{

View file

@ -29,7 +29,6 @@
// boost
#include <boost/version.hpp>
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/concept_check.hpp>
@ -87,14 +86,7 @@ struct regex_match_impl
: tr_(tr) {}
template <typename T0,typename T1>
expr_node operator() (T0 & node, T1 const& pattern) const
{
#if defined(BOOST_REGEX_HAS_ICU)
return regex_match_node(node,tr_.transcode(pattern.c_str()));
#else
return regex_match_node(node,pattern);
#endif
}
expr_node operator() (T0 & node, T1 const& pattern) const;
mapnik::transcoder const& tr_;
};
@ -111,149 +103,34 @@ struct regex_replace_impl
: tr_(tr) {}
template <typename T0,typename T1,typename T2>
expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const
{
#if defined(BOOST_REGEX_HAS_ICU)
return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str()));
#else
return regex_replace_node(node,pattern,format);
#endif
}
expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const;
mapnik::transcoder const& tr_;
};
struct geometry_types : qi::symbols<char,int>
{
geometry_types()
{
add
("point",1)
("line", 2)
("polygon",3)
;
}
};
template <typename Iterator>
struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
{
typedef qi::rule<Iterator, expr_node(), space_type> rule_type;
explicit expression_grammar(mapnik::transcoder const& tr)
: expression_grammar::base_type(expr),
unicode_(unicode_impl(tr)),
regex_match_(regex_match_impl(tr)),
regex_replace_(regex_replace_impl(tr))
{
using boost::phoenix::construct;
using qi::_1;
using qi::_a;
using qi::_b;
using qi::_r1;
#if BOOST_VERSION > 104200
using qi::no_skip;
#endif
using qi::lexeme;
using qi::_val;
using qi::lit;
using qi::int_;
using qi::double_;
using qi::hex;
using qi::omit;
using standard_wide::char_;
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]
| lit("true") [_val = true]
| lit("false") [_val = false]
| lit("null") [_val = value_null() ]
| ustring [_val = unicode_(_1) ]
| attr [_val = construct<mapnik::attribute>( _1 ) ]
| '(' >> expr [_val = _1 ] >> ')'
;
unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n')
("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\')
("\\\'", '\'')("\\\"", '\"')
;
#if BOOST_VERSION > 104500
quote_char %= char_('\'') | char_('"');
ustring %= omit[quote_char[_a = _1]]
>> *(unesc_char | "\\x" >> hex | (char_ - lit(_a)))
>> lit(_a);
attr %= '[' >> no_skip[+~char_(']')] >> ']';
#else
ustring %= lit('\'')
>> *(unesc_char | "\\x" >> hex | (char_ - lit('\'')))
>> lit('\'');
attr %= '[' >> lexeme[+(char_ - ']')] >> ']';
#endif
}
explicit expression_grammar(mapnik::transcoder const& tr);
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
boost::phoenix::function<unicode_impl> unicode_;
boost::phoenix::function<regex_match_impl> regex_match_;
boost::phoenix::function<regex_replace_impl> regex_replace_;
//
rule_type expr;
rule_type equality_expr;
rule_type cond_expr;
@ -270,6 +147,7 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
qi::rule<Iterator, std::string(), qi::locals<char> > ustring;
qi::symbols<char const, char const> unesc_char;
qi::rule<Iterator, char() > quote_char;
geometry_types geom_type;
};
} // namespace

View file

@ -28,12 +28,12 @@
#include <mapnik/attribute.hpp>
// boost
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/regex.hpp>
#if defined(BOOST_REGEX_HAS_ICU)
#include <boost/regex/icu.hpp>
#endif
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
namespace mapnik
@ -174,6 +174,7 @@ typedef mapnik::value value_type;
typedef boost::variant <
value_type,
attribute,
geometry_type_attribute,
boost::recursive_wrapper<unary_node<tags::negate> >,
boost::recursive_wrapper<binary_node<tags::plus> >,
boost::recursive_wrapper<binary_node<tags::minus> >,
@ -239,12 +240,10 @@ struct binary_node
};
#if defined(BOOST_REGEX_HAS_ICU)
struct regex_match_node
{
regex_match_node (expr_node const& a, UnicodeString const& ustr)
: expr(a),
pattern(boost::make_u32regex(ustr)) {}
regex_match_node (expr_node const& a, UnicodeString const& ustr);
expr_node expr;
boost::u32regex pattern;
};
@ -252,22 +251,17 @@ struct regex_match_node
struct regex_replace_node
{
regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f)
: expr(a),
pattern(boost::make_u32regex(ustr)),
format(f) {}
regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f);
expr_node expr;
boost::u32regex pattern;
UnicodeString format;
};
#else
struct regex_match_node
{
regex_match_node (expr_node const& a, std::string const& str)
: expr(a),
pattern(str) {}
regex_match_node (expr_node const& a, std::string const& str);
expr_node expr;
boost::regex pattern;
};
@ -275,11 +269,7 @@ struct regex_match_node
struct regex_replace_node
{
regex_replace_node (expr_node const& a, std::string const& str, std::string const& f)
: expr(a),
pattern(str),
format(f) {}
regex_replace_node (expr_node const& a, std::string const& str, std::string const& f);
expr_node expr;
boost::regex pattern;
std::string format;

View file

@ -77,6 +77,11 @@ public:
return index;
}
void add(key_type const& name, size_type index)
{
mapping_.insert(std::make_pair(name, index));
}
size_type size() const { return mapping_.size(); }
const_iterator begin() const { return mapping_.begin();}
const_iterator end() const { return mapping_.end();}

View file

@ -365,7 +365,7 @@ struct text_renderer : private boost::noncopyable
stroker & s,
composite_mode_e comp_op = src_over,
double scale_factor=1.0);
box2d<double> prepare_glyphs(text_path *path);
box2d<double> prepare_glyphs(text_path const& path);
void render(pixel_position pos);
void render_id(int feature_id, pixel_position pos, double min_radius=1.0);

View file

@ -32,13 +32,14 @@
// stl
#include <cmath>
#include <vector>
namespace mapnik
{
template <typename T>
bool clip_test(T p,T q,double& tmin,double& tmax)
{
double r;
double r = 0;
bool result=true;
if (p<0.0)
{
@ -95,7 +96,8 @@ inline bool point_inside_path(double x,double y,Iter start,Iter end)
double x0=boost::get<0>(*start);
double y0=boost::get<1>(*start);
double x1,y1;
double x1 = 0;
double y1 = 0;
while (++start!=end)
{
if ( boost::get<2>(*start) == SEG_MOVETO)
@ -172,7 +174,8 @@ inline bool point_on_path(double x,double y,Iter start,Iter end, double tol)
{
double x0=boost::get<0>(*start);
double y0=boost::get<1>(*start);
double x1,y1;
double x1 = 0;
double y1 = 0;
while (++start != end)
{
if ( boost::get<2>(*start) == SEG_MOVETO)
@ -216,6 +219,226 @@ struct filter_at_point
return extent.contains(pt_);
}
};
////////////////////////////////////////////////////////////////////////////
template <typename PathType>
double path_length(PathType & path)
{
double x0 = 0;
double y0 = 0;
double x1 = 0;
double y1 = 0;
path.rewind(0);
unsigned command = path.vertex(&x0,&y0);
if (command == SEG_END) return 0;
double length = 0;
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
length += distance(x0,y0,x1,y1);
x0 = x1;
y0 = y1;
}
return length;
}
template <typename PathType>
bool middle_point(PathType & path, double & x, double & y)
{
double x0 = 0;
double y0 = 0;
double x1 = 0;
double y1 = 0;
double mid_length = 0.5 * path_length(path);
path.rewind(0);
unsigned command = path.vertex(&x0,&y0);
if (command == SEG_END) return false;
double dist = 0.0;
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
double seg_length = distance(x0, y0, x1, y1);
if ( dist + seg_length >= mid_length)
{
double r = (mid_length - dist)/seg_length;
x = x0 + (x1 - x0) * r;
y = y0 + (y1 - y0) * r;
break;
}
dist += seg_length;
x0 = x1;
y0 = y1;
}
return true;
}
namespace label {
template <typename PathType>
bool centroid(PathType & path, double & x, double & y)
{
double x0 = 0;
double y0 = 0;
double x1 = 0;
double y1 = 0;
double start_x;
double start_y;
path.rewind(0);
unsigned command = path.vertex(&x0, &y0);
if (command == SEG_END) return false;
start_x = x0;
start_y = y0;
double atmp = 0;
double xtmp = 0;
double ytmp = 0;
unsigned count = 1;
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
double dx0 = x0 - start_x;
double dy0 = y0 - start_y;
double dx1 = x1 - start_x;
double dy1 = y1 - start_y;
double ai = dx0 * dy1 - dx1 * dy0;
atmp += ai;
xtmp += (dx1 + dx0) * ai;
ytmp += (dy1 + dy0) * ai;
x0 = x1;
y0 = y1;
++count;
}
if (count == 1)
{
x = start_x;
y = start_y;
return true;
}
if (atmp != 0)
{
x = (xtmp/(3*atmp)) + start_x;
y = (ytmp/(3*atmp)) + start_y;
}
else
{
x = x0;
y = y0;
}
return true;
}
template <typename PathType>
bool hit_test(PathType & path, double x, double y, double tol)
{
bool inside=false;
double x0 = 0;
double y0 = 0;
double x1 = 0;
double y1 = 0;
path.rewind(0);
unsigned command = path.vertex(&x0, &y0);
if (command == SEG_END) return false;
unsigned count = 0;
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
++count;
if (command == SEG_MOVETO)
{
x0 = x1;
y0 = y1;
continue;
}
if ((((y1 <= y) && (y < y0)) ||
((y0 <= y) && (y < y1))) &&
(x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
inside=!inside;
x0 = x1;
y0 = y1;
}
if (count == 0) // one vertex
{
return distance(x, y, x0, y0) <= fabs(tol);
}
return inside;
}
template <typename PathType>
void interior_position(PathType & path, double & x, double & y)
{
// start with the centroid
label::centroid(path, x,y);
// if we are not a polygon, or the default is within the polygon we are done
if (hit_test(path,x,y,0.001))
return;
// otherwise we find a horizontal line across the polygon and then return the
// center of the widest intersection between the polygon and the line.
std::vector<double> intersections; // only need to store the X as we know the y
double x0 = 0;
double y0 = 0;
path.rewind(0);
unsigned command = path.vertex(&x0, &y0);
double x1 = 0;
double y1 = 0;
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
if (command != SEG_MOVETO)
{
// if the segments overlap
if (y0==y1)
{
if (y0==y)
{
double xi = (x0+x1)/2.0;
intersections.push_back(xi);
}
}
// if the path segment crosses the bisector
else if ((y0 <= y && y1 >= y) ||
(y0 >= y && y1 <= y))
{
// then calculate the intersection
double xi = x0;
if (x0 != x1)
{
double m = (y1-y0)/(x1-x0);
double c = y0 - m*x0;
xi = (y-c)/m;
}
intersections.push_back(xi);
}
}
x0 = x1;
y0 = y1;
}
// no intersections we just return the default
if (intersections.empty())
return;
x0=intersections[0];
double max_width = 0;
for (unsigned ii = 1; ii < intersections.size(); ++ii)
{
double x1=intersections[ii];
double xc=(x0+x1)/2.0;
double width = std::fabs(x1-x0);
if (width > max_width && hit_test(path,xc,y,0))
{
x=xc;
max_width = width;
break;
}
}
}
}}
#endif // MAPNIK_GEOM_UTIL_HPP

View file

@ -80,13 +80,18 @@ public:
return cont_;
}
size_type size() const
{
return cont_.size();
}
box2d<double> envelope() const
{
box2d<double> result;
double x(0);
double y(0);
double x = 0;
double y = 0;
rewind(0);
for (unsigned i=0;i<num_points();++i)
for (unsigned i=0;i<size();++i)
{
vertex(&x,&y);
if (i==0)
@ -101,225 +106,6 @@ public:
return result;
}
void label_interior_position(double *x, double *y) const
{
// start with the default label position
label_position(x,y);
unsigned size = cont_.size();
// if we are not a polygon, or the default is within the polygon we are done
if (size < 3 || hit_test(*x,*y,0))
return;
// otherwise we find a horizontal line across the polygon and then return the
// center of the widest intersection between the polygon and the line.
std::vector<double> intersections; // only need to store the X as we know the y
double x0=0;
double y0=0;
rewind(0);
unsigned command = vertex(&x0, &y0);
double x1,y1;
while (SEG_END != (command=vertex(&x1, &y1)))
{
if (command != SEG_MOVETO)
{
// if the segments overlap
if (y0==y1)
{
if (y0==*y)
{
double xi = (x0+x1)/2.0;
intersections.push_back(xi);
}
}
// if the path segment crosses the bisector
else if ((y0 <= *y && y1 >= *y) ||
(y0 >= *y && y1 <= *y))
{
// then calculate the intersection
double xi = x0;
if (x0 != x1)
{
double m = (y1-y0)/(x1-x0);
double c = y0 - m*x0;
xi = (*y-c)/m;
}
intersections.push_back(xi);
}
}
x0 = x1;
y0 = y1;
}
// no intersections we just return the default
if (intersections.empty())
return;
x0=intersections[0];
double max_width = 0;
for (unsigned ii = 1; ii < intersections.size(); ++ii)
{
double x1=intersections[ii];
double xc=(x0+x1)/2.0;
double width = fabs(x1-x0);
if (width > max_width && hit_test(xc,*y,0))
{
*x=xc;
max_width = width;
}
}
}
/* center of gravity centroid
- best visually but does not work with multipolygons
*/
void label_position(double *x, double *y) const
{
if (type_ == LineString)
{
middle_point(x,y);
return;
}
unsigned size = cont_.size();
if (size < 3)
{
cont_.get_vertex(0,x,y);
return;
}
double ai;
double atmp = 0;
double xtmp = 0;
double ytmp = 0;
double x0 =0;
double y0 =0;
double x1 =0;
double y1 =0;
double ox =0;
double oy =0;
unsigned i;
// Use first point as origin to improve numerical accuracy
cont_.get_vertex(0,&ox,&oy);
for (i = 0; i < size-1; i++)
{
cont_.get_vertex(i,&x0,&y0);
cont_.get_vertex(i+1,&x1,&y1);
x0 -= ox; y0 -= oy;
x1 -= ox; y1 -= oy;
ai = x0 * y1 - x1 * y0;
atmp += ai;
xtmp += (x1 + x0) * ai;
ytmp += (y1 + y0) * ai;
}
if (atmp != 0)
{
*x = (xtmp/(3*atmp)) + ox;
*y = (ytmp/(3*atmp)) + oy;
return;
}
*x=x0;
*y=y0;
}
/* center of bounding box centroid */
void label_position2(double *x, double *y) const
{
box2d<double> box = envelope();
*x = box.center().x;
*y = box.center().y;
}
/* summarized distance centroid */
void label_position3(double *x, double *y) const
{
if (type_ == LineString)
{
middle_point(x,y);
return;
}
unsigned i = 0;
double l = 0.0;
double tl = 0.0;
double cx = 0.0;
double cy = 0.0;
double x0 = 0.0;
double y0 = 0.0;
double x1 = 0.0;
double y1 = 0.0;
unsigned size = cont_.size();
for (i = 0; i < size-1; i++)
{
cont_.get_vertex(i,&x0,&y0);
cont_.get_vertex(i+1,&x1,&y1);
l = distance(x0,y0,x1,y1);
cx += l * (x1 + x0)/2;
cy += l * (y1 + y0)/2;
tl += l;
}
*x = cx / tl;
*y = cy / tl;
}
void middle_point(double *x, double *y) const
{
// calculate mid point on path
double x0=0;
double y0=0;
double x1=0;
double y1=0;
unsigned size = cont_.size();
if (size == 1)
{
cont_.get_vertex(0,x,y);
}
else if (size == 2)
{
cont_.get_vertex(0,&x0,&y0);
cont_.get_vertex(1,&x1,&y1);
*x = 0.5 * (x1 + x0);
*y = 0.5 * (y1 + y0);
}
else
{
double len=0.0;
for (unsigned pos = 1; pos < size; ++pos)
{
cont_.get_vertex(pos-1,&x0,&y0);
cont_.get_vertex(pos,&x1,&y1);
double dx = x1 - x0;
double dy = y1 - y0;
len += std::sqrt(dx * dx + dy * dy);
}
double midlen = 0.5 * len;
double dist = 0.0;
for (unsigned pos = 1; pos < size;++pos)
{
cont_.get_vertex(pos-1,&x0,&y0);
cont_.get_vertex(pos,&x1,&y1);
double dx = x1 - x0;
double dy = y1 - y0;
double seg_len = std::sqrt(dx * dx + dy * dy);
if (( dist + seg_len) >= midlen)
{
double r = (midlen - dist)/seg_len;
*x = x0 + (x1 - x0) * r;
*y = y0 + (y1 - y0) * r;
break;
}
dist += seg_len;
}
}
}
void push_vertex(coord_type x, coord_type y, CommandType c)
{
cont_.push_back(x,y,c);
@ -335,62 +121,20 @@ public:
push_vertex(x,y,SEG_MOVETO);
}
unsigned num_points() const
{
return cont_.size();
}
unsigned vertex(double* x, double* y) const
{
return cont_.get_vertex(itr_++,x,y);
}
unsigned get_vertex(unsigned pos, double* x, double* y) const
unsigned vertex(std::size_t index, double* x, double* y) const
{
return cont_.get_vertex(pos, x, y);
return cont_.get_vertex(index, x, y);
}
void rewind(unsigned ) const
{
itr_=0;
}
bool hit_test(coord_type x, coord_type y, double tol) const
{
if (cont_.size() == 1) {
// Handle points
double x0, y0;
cont_.get_vertex(0, &x0, &y0);
return distance(x, y, x0, y0) <= fabs(tol);
} else if (cont_.size() > 1) {
bool inside=false;
double x0=0;
double y0=0;
rewind(0);
vertex(&x0, &y0);
unsigned command;
double x1,y1;
while (SEG_END != (command=vertex(&x1, &y1)))
{
if (command == SEG_MOVETO)
{
x0 = x1;
y0 = y1;
continue;
}
if ((((y1 <= y) && (y < y0)) ||
((y0 <= y) && (y < y1))) &&
( x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
inside=!inside;
x0=x1;
y0=y1;
}
return inside;
}
return false;
}
};
typedef geometry<double,vertex_vector> geometry_type;

View file

@ -58,7 +58,6 @@ public:
typedef std::string lookup_type;
// mapping between pixel id and key
typedef std::map<value_type, lookup_type> feature_key_type;
typedef std::map<lookup_type, value_type> key_type;
typedef std::map<lookup_type, mapnik::feature_ptr> feature_type;
static const value_type base_mask;
@ -77,39 +76,9 @@ private:
public:
hit_grid(int width, int height, std::string const& key, unsigned int resolution)
:width_(width),
height_(height),
key_(key),
data_(width,height),
resolution_(resolution),
id_name_("__id__"),
painted_(false),
names_(),
f_keys_(),
features_(),
ctx_(boost::make_shared<mapnik::context_type>())
{
f_keys_[base_mask] = "";
data_.set(base_mask);
}
hit_grid(int width, int height, std::string const& key, unsigned int resolution);
hit_grid(const hit_grid<T>& rhs)
:width_(rhs.width_),
height_(rhs.height_),
key_(rhs.key_),
data_(rhs.data_),
resolution_(rhs.resolution_),
id_name_("__id__"),
painted_(rhs.painted_),
names_(rhs.names_),
f_keys_(rhs.f_keys_),
features_(rhs.features_),
ctx_(rhs.ctx_)
{
f_keys_[base_mask] = "";
data_.set(base_mask);
}
hit_grid(hit_grid<T> const& rhs);
~hit_grid() {}
@ -128,64 +97,7 @@ public:
return id_name_;
}
inline void add_feature(mapnik::feature_impl & feature)
{
int feature_id = feature.id();
// avoid adding duplicate features (e.g. in the case of both a line symbolizer and a polygon symbolizer)
typename feature_key_type::const_iterator feature_pos = f_keys_.find(feature_id);
if (feature_pos != f_keys_.end())
{
return;
}
if (ctx_->size() == 0) {
mapnik::feature_impl::iterator itr = feature.begin();
mapnik::feature_impl::iterator end = feature.end();
for ( ;itr!=end; ++itr)
{
ctx_->push(boost::get<0>(*itr));
}
}
// NOTE: currently lookup keys must be strings,
// but this should be revisited
lookup_type lookup_value;
if (key_ == id_name_)
{
mapnik::util::to_string(lookup_value,feature_id);
}
else
{
if (feature.has_key(key_))
{
lookup_value = feature.get(key_).to_string();
}
else
{
MAPNIK_LOG_DEBUG(grid) << "hit_grid: Should not get here: key '" << key_ << "' not found in feature properties";
}
}
if (!lookup_value.empty())
{
// TODO - consider shortcutting f_keys if feature_id == lookup_value
// create a mapping between the pixel id and the feature key
f_keys_.insert(std::make_pair(feature_id,lookup_value));
// if extra fields have been supplied, push them into grid memory
if (!names_.empty())
{
// it is ~ 2x faster to copy feature attributes compared
// to building up a in-memory cache of feature_ptrs
// https://github.com/mapnik/mapnik/issues/1198
mapnik::feature_ptr feature2(mapnik::feature_factory::create(ctx_,feature_id));
feature2->set_data(feature.get_data());
features_.insert(std::make_pair(lookup_value,feature2));
}
}
else
{
MAPNIK_LOG_DEBUG(grid) << "hit_grid: Warning - key '" << key_ << "' was blank for " << feature;
}
}
inline void add_feature(mapnik::feature_impl & feature);
inline void add_property_name(std::string const& name)
{
@ -197,27 +109,17 @@ public:
return names_;
}
inline const feature_type& get_grid_features() const
inline feature_type const& get_grid_features() const
{
return features_;
}
inline feature_type& get_grid_features()
{
return features_;
}
inline const feature_key_type& get_feature_keys() const
inline feature_key_type const& get_feature_keys() const
{
return f_keys_;
}
inline feature_key_type& get_feature_keys()
{
return f_keys_;
}
inline const std::string& get_key() const
inline std::string const& get_key() const
{
return key_;
}
@ -237,7 +139,7 @@ public:
resolution_ = res;
}
inline const data_type& data() const
inline data_type const& data() const
{
return data_;
}
@ -247,7 +149,7 @@ public:
return data_;
}
inline const T* raw_data() const
inline T const * raw_data() const
{
return data_.getData();
}
@ -257,7 +159,7 @@ public:
return data_.getData();
}
inline const value_type* getRow(unsigned row) const
inline value_type const * getRow(unsigned row) const
{
return data_.getRow(row);
}

View file

@ -65,7 +65,7 @@ public:
void end_layer_processing(layer const& lay);
void start_style_processing(feature_type_style const& st) {}
void end_style_processing(feature_type_style const& st) {}
void render_marker(mapnik::feature_impl & feature, unsigned int step, pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity);
void render_marker(mapnik::feature_impl & feature, unsigned int step, pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity, composite_mode_e comp_op);
void process(point_symbolizer const& sym,
mapnik::feature_impl & feature,
@ -119,6 +119,7 @@ private:
face_manager<freetype_engine> font_manager_;
label_collision_detector4 detector_;
boost::scoped_ptr<grid_rasterizer> ras_ptr;
box2d<double> query_extent_;
};
}

View file

@ -26,6 +26,9 @@
// mapnik
#include <mapnik/grid/grid.hpp>
// boost
#include <boost/concept_check.hpp>
namespace mapnik {
/*
@ -45,15 +48,20 @@ static inline void scale_grid(mapnik::grid::data_type & target,
if (source_width<1 || source_height<1 ||
target_width<1 || target_height<1) return;
int x=0,y=0,xs=0,ys=0;
int x = 0;
int y = 0;
int xs = 0;
int ys = 0;
int tw2 = target_width/2;
int th2 = target_height/2;
int offs_x = rint((source_width-target_width-x_off_f*2*source_width)/2);
int offs_y = rint((source_height-target_height-y_off_f*2*source_height)/2);
unsigned yprt(0);
unsigned yprt1(0);
unsigned xprt(0);
unsigned xprt1(0);
unsigned yprt = 0;
unsigned yprt1 = 0;
unsigned xprt = 0;
unsigned xprt1 = 0;
boost::ignore_unused_variable_warning(yprt1);
boost::ignore_unused_variable_warning(xprt1);
//no scaling or subpixel offset
if (target_height == source_height && target_width == source_width && offs_x == 0 && offs_y == 0){

View file

@ -53,7 +53,6 @@ public:
typedef typename T::pixel_type pixel_type;
typedef std::string lookup_type;
typedef std::map<value_type, lookup_type> feature_key_type;
typedef std::map<lookup_type, value_type> key_type;
typedef std::map<std::string, mapnik::feature_ptr> feature_type;
hit_grid_view(unsigned x, unsigned y,
@ -115,6 +114,7 @@ public:
names_ = rhs.names_;
f_keys_ = rhs.f_keys_;
features_ = rhs.features_;
return *this;
}
inline unsigned x() const
@ -142,7 +142,7 @@ public:
return id_name_;
}
inline const value_type* getRow(unsigned row) const
inline value_type const * getRow(unsigned row) const
{
return data_.getRow(row + y_) + x_;
}
@ -162,22 +162,22 @@ public:
return data_.getBytes();
}
std::set<std::string> const& property_names() const
inline std::set<std::string> const& property_names() const
{
return names_;
}
inline const feature_type& get_grid_features() const
inline feature_type const& get_grid_features() const
{
return features_;
}
inline const feature_key_type& get_feature_keys() const
inline feature_key_type const& get_feature_keys() const
{
return f_keys_;
}
inline const lookup_type& get_key() const
inline lookup_type const& get_key() const
{
return key_;
}
@ -206,4 +206,3 @@ typedef hit_grid_view<mapnik::ImageData<int> > grid_view;
}
#endif // MAPNIK_GRID_VIEW_HPP

View file

@ -25,6 +25,9 @@
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/geom_util.hpp>
// boost
#include <boost/foreach.hpp>
namespace mapnik {
class hit_test_filter
@ -35,12 +38,11 @@ public:
y_(y),
tol_(tol) {}
bool pass(Feature const& feature)
bool pass(Feature & feature)
{
for (unsigned i=0;i<feature.num_geometries();++i)
BOOST_FOREACH(geometry_type & geom, feature.paths())
{
geometry_type const& geom = feature.get_geometry(i);
if (geom.hit_test(x_,y_,tol_))
if (label::hit_test(geom, x_,y_,tol_))
return true;
}
return false;

View file

@ -79,6 +79,7 @@ enum composite_mode_e
};
MAPNIK_DECL boost::optional<composite_mode_e> comp_op_from_string(std::string const& name);
MAPNIK_DECL boost::optional<std::string> comp_op_to_string(composite_mode_e comp_op);
template <typename T1, typename T2>
MAPNIK_DECL void composite(T1 & dst, T2 & src,

View file

@ -487,7 +487,7 @@ struct filter_visitor : boost::static_visitor<void>
: src_(src) {}
template <typename T>
void operator () (T filter_tag)
void operator () (T const& filter_tag)
{
apply_filter(src_,filter_tag);
}
@ -495,7 +495,6 @@ struct filter_visitor : boost::static_visitor<void>
Src & src_;
};
}}
#endif // MAPNIK_IMAGE_FILTER_HPP

View file

@ -23,7 +23,12 @@
#ifndef MAPNIK_IMAGE_FILTER_TYPES_HPP
#define MAPNIK_IMAGE_FILTER_TYPES_HPP
// boost
#include <boost/variant.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/karma.hpp>
// stl
#include <iostream>
namespace mapnik { namespace filter {
@ -37,18 +42,14 @@ struct x_gradient {};
struct y_gradient {};
struct invert {};
struct agg_stack_blur
struct agg_stack_blur
{
agg_stack_blur(unsigned rx_, unsigned ry_)
: rx(rx_),ry(ry_) {}
// an attempt to support older boost spirit (< 1.46)
agg_stack_blur()
: rx(1),ry(1) {}
unsigned rx;
unsigned ry;
};
typedef boost::variant<filter::blur,
filter::gray,
filter::agg_stack_blur,
@ -60,6 +61,97 @@ typedef boost::variant<filter::blur,
filter::y_gradient,
filter::invert> filter_type;
inline std::ostream& operator<< (std::ostream& os, blur)
{
os << "blur";
return os;
}
inline std::ostream& operator<< (std::ostream& os, gray)
{
os << "gray";
return os;
}
inline std::ostream& operator<< (std::ostream& os, agg_stack_blur const& filter)
{
os << "agg-stack-blur:" << filter.rx << ',' << filter.ry;
return os;
}
inline std::ostream& operator<< (std::ostream& os, emboss)
{
os << "emboss";
return os;
}
inline std::ostream& operator<< (std::ostream& os, sharpen)
{
os << "sharpen";
return os;
}
inline std::ostream& operator<< (std::ostream& os, edge_detect)
{
os << "edge-detect";
return os;
}
inline std::ostream& operator<< (std::ostream& os, sobel)
{
os << "sobel";
return os;
}
inline std::ostream& operator<< (std::ostream& os, x_gradient)
{
os << "x-gradient";
return os;
}
inline std::ostream& operator<< (std::ostream& os, y_gradient)
{
os << "y-gradient";
return os;
}
inline std::ostream& operator<< (std::ostream& os, invert)
{
os << "invert";
return os;
}
template <typename Out>
struct to_string_visitor : boost::static_visitor<void>
{
to_string_visitor(Out & out)
: out_(out) {}
template <typename T>
void operator () (T const& filter_tag)
{
out_ << filter_tag;
}
Out & out_;
};
inline std::ostream& operator<< (std::ostream& os, filter_type const& filter)
{
to_string_visitor<std::ostream> visitor(os);
boost::apply_visitor(visitor, filter);
return os;
}
template <typename OutputIterator, typename Container>
bool generate_image_filters(OutputIterator& sink, Container const& v)
{
using boost::spirit::karma::stream;
using boost::spirit::karma::generate;
bool r = generate(sink, stream % ' ', v);
return r;
}
}}
#endif // MAPNIK_IMAGE_FILTER_TYPES_HPP

View file

@ -0,0 +1,83 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
#ifndef MAPNIK_IMAGE_SCALING_HPP
#define MAPNIK_IMAGE_SCALING_HPP
// stl
#include <string>
#include <boost/optional.hpp>
#include <mapnik/config.hpp>
namespace mapnik
{
enum scaling_method_e
{
SCALING_NEAR=0,
SCALING_BILINEAR,
SCALING_BICUBIC,
SCALING_SPLINE16,
SCALING_SPLINE36,
SCALING_HANNING,
SCALING_HAMMING,
SCALING_HERMITE,
SCALING_KAISER,
SCALING_QUADRIC,
SCALING_CATROM,
SCALING_GAUSSIAN,
SCALING_BESSEL,
SCALING_MITCHELL,
SCALING_SINC,
SCALING_LANCZOS,
SCALING_BLACKMAN,
SCALING_BILINEAR8
};
boost::optional<scaling_method_e> scaling_method_from_string(std::string const& name);
boost::optional<std::string> scaling_method_to_string(scaling_method_e scaling_method);
template <typename Image>
void scale_image_agg(Image & target,
Image const& source,
scaling_method_e scaling_method,
double scale_factor,
double x_off_f=0,
double y_off_f=0,
double filter_radius=2,
double ratio=1);
template <typename Image>
void scale_image_bilinear_old(Image & target,
Image const& source,
double x_off_f=0,
double y_off_f=0);
template <typename Image>
void scale_image_bilinear8(Image & target,
Image const& source,
double x_off_f=0,
double y_off_f=0);
}
#endif // MAPNIK_IMAGE_SCALING_HPP

View file

@ -60,7 +60,8 @@ public:
#if defined(HAVE_CAIRO)
MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map,
std::string const& filename,
std::string const& type);
std::string const& type,
double scale_factor=1.0);
#endif
template <typename T>
@ -184,38 +185,7 @@ void add_border(T & image)
}
}
// IMAGE SCALING
enum scaling_method_e
{
SCALING_NEAR=0,
SCALING_BILINEAR=1,
SCALING_BICUBIC=2,
SCALING_SPLINE16=3,
SCALING_SPLINE36=4,
SCALING_HANNING=5,
SCALING_HAMMING=6,
SCALING_HERMITE=7,
SCALING_KAISER=8,
SCALING_QUADRIC=9,
SCALING_CATROM=10,
SCALING_GAUSSIAN=11,
SCALING_BESSEL=12,
SCALING_MITCHELL=13,
SCALING_SINC=14,
SCALING_LANCZOS=15,
SCALING_BLACKMAN=16
};
scaling_method_e get_scaling_method_by_name (std::string name);
template <typename Image>
void scale_image_agg (Image& target,const Image& source, scaling_method_e scaling_method, double scale_factor, double x_off_f=0, double y_off_f=0, double filter_radius=2, double ratio=1);
template <typename Image>
void scale_image_bilinear_old (Image& target,const Image& source, double x_off_f=0, double y_off_f=0);
template <typename Image>
void scale_image_bilinear8 (Image& target,const Image& source, double x_off_f=0, double y_off_f=0);
/////////// save_to_file ////////////////////////////////////////////////
class image_32;

View file

@ -61,6 +61,7 @@ public:
width_ = rhs.width_;
height_ = rhs.height_;
data_ = rhs.data_;
return *this;
}
inline unsigned x() const
@ -77,6 +78,7 @@ public:
{
return width_;
}
inline unsigned height() const
{
return height_;

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/value.hpp>
// spirit::qi
#include <boost/config/warning_disable.hpp>
@ -135,196 +136,7 @@ struct feature_grammar :
qi::grammar<Iterator, void(FeatureType&),
space_type>
{
feature_grammar(mapnik::transcoder const& tr)
: feature_grammar::base_type(feature,"feature"),
put_property_(put_property(tr))
{
using qi::lit;
using qi::int_;
using qi::double_;
#if BOOST_VERSION > 104200
using qi::no_skip;
#else
using qi::lexeme;
#endif
using standard_wide::char_;
using qi::_val;
using qi::_1;
using qi::_2;
using qi::_3;
using qi::_4;
using qi::_a;
using qi::_b;
using qi::_r1;
using qi::_r2;
using qi::fail;
using qi::on_error;
using qi::_pass;
using qi::eps;
using qi::raw;
using phoenix::new_;
using phoenix::push_back;
using phoenix::construct;
// generic json types
value = object | array | string_
| number
;
pairs = key_value % lit(',')
;
key_value = (string_ >> lit(':') >> value)
;
object = lit('{')
>> *pairs
>> lit('}')
;
array = lit('[')
>> value >> *(lit(',') >> value)
>> lit(']')
;
number %= strict_double
| int_
| lit("true") [_val = true]
| lit ("false") [_val = false]
| lit("null")[_val = construct<value_null>()]
;
unesc_char.add
("\\\"", '\"') // quotation mark
("\\\\", '\\') // reverse solidus
("\\/", '/') // solidus
("\\b", '\b') // backspace
("\\f", '\f') // formfeed
("\\n", '\n') // newline
("\\r", '\r') // carrige return
("\\t", '\t') // tab
;
string_ %= lit('"') >> *(unesc_char | "\\u" >> hex4 | (char_ - lit('"'))) >> lit('"')
;
// geojson types
feature_type = lit("\"type\"")
>> lit(':')
>> lit("\"Feature\"")
;
feature = lit('{')
>> (feature_type | (lit("\"geometry\"") > lit(':') > geometry(_r1)) | properties(_r1) | key_value) % lit(',')
>> lit('}')
;
properties = lit("\"properties\"")
>> lit(':') >> (lit('{') >> attributes(_r1) >> lit('}')) | lit("null")
;
attributes = (string_ [_a = _1] >> lit(':') >> attribute_value [put_property_(_r1,_a,_1)]) % lit(',')
;
attribute_value %= number | string_ ;
// Nabialek trick - FIXME: how to bind argument to dispatch rule?
// geometry = lit("\"geometry\"")
// >> lit(':') >> lit('{')
// >> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1]
// >> lit(',') >> lit("\"coordinates\"") >> lit(':')
// >> qi::lazy(*_a)
// >> lit('}')
// ;
// geometry_dispatch.add
// ("\"Point\"",&point_coordinates)
// ("\"LineString\"",&linestring_coordinates)
// ("\"Polygon\"",&polygon_coordinates)
// ;
//////////////////////////////////////////////////////////////////
geometry = (lit('{')[_a = 0 ]
>> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1] // <---- should be Nabialek trick!
>> lit(',')
>> (lit("\"coordinates\"") > lit(':') > coordinates(_r1,_a)
|
lit("\"geometries\"") > lit(':')
>> lit('[') >> geometry_collection(_r1) >> lit(']'))
>> lit('}'))
| lit("null")
;
geometry_dispatch.add
("\"Point\"",1)
("\"LineString\"",2)
("\"Polygon\"",3)
("\"MultiPoint\"",4)
("\"MultiLineString\"",5)
("\"MultiPolygon\"",6)
("\"GeometryCollection\"",7)
//
;
coordinates = (eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1)))
| (eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1)))
| (eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1)))
| (eps(_r2 == 4) > multipoint_coordinates(extract_geometry_(_r1)))
| (eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1)))
| (eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1)))
;
point_coordinates = eps[ _a = new_<geometry_type>(Point) ]
> ( point(SEG_MOVETO,_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false] )
;
linestring_coordinates = eps[ _a = new_<geometry_type>(LineString)]
> -(points(_a) [push_back(_r1,_a)]
| eps[cleanup_(_a)][_pass = false])
;
polygon_coordinates = eps[ _a = new_<geometry_type>(Polygon) ]
> ((lit('[')
> -(points(_a) % lit(','))
> lit(']')) [push_back(_r1,_a)]
| eps[cleanup_(_a)][_pass = false])
;
multipoint_coordinates = lit('[')
> -(point_coordinates(_r1) % lit(','))
> lit(']')
;
multilinestring_coordinates = lit('[')
> -(linestring_coordinates(_r1) % lit(','))
> lit(']')
;
multipolygon_coordinates = lit('[')
> -(polygon_coordinates(_r1) % lit(','))
> lit(']')
;
geometry_collection = *geometry(_r1) >> *(lit(',') >> geometry(_r1))
;
// point
point = lit('[') > -((double_ > lit(',') > double_)[push_vertex_(_r1,_r2,_1,_2)]) > lit(']');
// points
points = lit('[')[_a = SEG_MOVETO] > -(point (_a,_r1) % lit(',')[_a = SEG_LINETO]) > lit(']');
on_error<fail>
(
feature
, std::clog
<< phoenix::val("Error! Expecting ")
<< _4 // what failed?
<< phoenix::val(" here: \"")
<< construct<std::string>(_3, _2) // iterators to error-pos, end
<< phoenix::val("\"")
<< std::endl
);
}
feature_grammar(mapnik::transcoder const& tr);
// start
// generic JSON

View file

@ -78,7 +78,7 @@ struct get_first
geometry_type::value_type const operator() (geometry_type const& geom) const
{
geometry_type::value_type coord;
boost::get<0>(coord) = geom.get_vertex(0,&boost::get<1>(coord),&boost::get<2>(coord));
boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord));
return coord;
}
};

View file

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

View file

@ -41,14 +41,21 @@ class marker;
typedef boost::shared_ptr<marker> marker_ptr;
struct MAPNIK_DECL marker_cache :
public singleton <marker_cache, CreateStatic>,
class MAPNIK_DECL marker_cache :
public singleton <marker_cache, CreateUsingNew>,
private boost::noncopyable
{
friend class CreateStatic<marker_cache>;
static boost::unordered_map<std::string,marker_ptr> cache_;
static bool insert(std::string const& key, marker_ptr);
friend class CreateUsingNew<marker_cache>;
private:
marker_cache();
~marker_cache();
static bool insert_marker(std::string const& key, marker_ptr path);
static boost::unordered_map<std::string,marker_ptr> marker_cache_;
static bool insert_svg(std::string const& name, std::string const& svg_string);
static boost::unordered_map<std::string,std::string> svg_cache_;
public:
static std::string known_svg_prefix_;
static bool is_uri(std::string const& path);
static boost::optional<marker_ptr> find(std::string const& key, bool update_cache = false);
static void clear();
};

View file

@ -0,0 +1,108 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
#ifndef MAPNIK_MARKER_HELPERS_HPP
#define MAPNIK_MARKER_HELPERS_HPP
#include <mapnik/color.hpp>
#include <mapnik/markers_symbolizer.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>
// boost
#include <boost/optional.hpp>
namespace mapnik {
template <typename Attr>
bool push_explicit_style(Attr const& src, Attr & dst, markers_symbolizer const& sym)
{
boost::optional<stroke> const& strk = sym.get_stroke();
boost::optional<color> const& fill = sym.get_fill();
if (strk || fill)
{
for(unsigned i = 0; i < src.size(); ++i)
{
mapnik::svg::path_attributes attr = src[i];
if (strk)
{
attr.stroke_flag = true;
attr.stroke_width = strk->get_width();
color const& s_color = strk->get_color();
attr.stroke_color = agg::rgba(s_color.red()/255.0,s_color.green()/255.0,
s_color.blue()/255.0,(s_color.alpha()*strk->get_opacity())/255.0);
}
if (fill)
{
attr.fill_flag = true;
color const& f_color = *fill;
attr.fill_color = agg::rgba(f_color.red()/255.0,f_color.green()/255.0,
f_color.blue()/255.0,(f_color.alpha()*sym.get_opacity())/255.0);
}
dst.push_back(attr);
}
return true;
}
return false;
}
template <typename T>
void setup_label_transform(agg::trans_affine & tr, box2d<double> const& bbox, mapnik::feature_impl const& feature, T const& sym)
{
double width = 0;
double height = 0;
expression_ptr const& width_expr = sym.get_width();
if (width_expr)
width = boost::apply_visitor(evaluate<Feature,value_type>(feature), *width_expr).to_double();
expression_ptr const& height_expr = sym.get_height();
if (height_expr)
height = boost::apply_visitor(evaluate<Feature,value_type>(feature), *height_expr).to_double();
if (width > 0 && height > 0)
{
double sx = width/bbox.width();
double sy = height/bbox.height();
tr *= agg::trans_affine_scaling(sx,sy);
}
else if (width > 0)
{
double sx = width/bbox.width();
tr *= agg::trans_affine_scaling(sx);
}
else if (height > 0)
{
double sy = height/bbox.height();
tr *= agg::trans_affine_scaling(sy);
}
else
{
evaluate_transform(tr, feature, sym.get_image_transform());
}
}
}
#endif //MAPNIK_MARKER_HELPERS_HPP

View file

@ -47,7 +47,7 @@ public:
* converted to a positive value with similar magnitude, but
* choosen to optimize marker placement. 0 = no markers
*/
markers_placement(Locator &locator, box2d<double> size, agg::trans_affine const& tr, Detector &detector, double spacing, double max_error, bool allow_overlap);
markers_placement(Locator &locator, box2d<double> const& size, agg::trans_affine const& tr, Detector &detector, double spacing, double max_error, bool allow_overlap);
/** Start again at first marker.
* \note Returns the same list of markers only works when they were NOT added
* to the detector.

View file

@ -31,6 +31,9 @@
#include <mapnik/enumeration.hpp>
#include <mapnik/expression.hpp>
// boost
#include <boost/optional.hpp>
namespace mapnik {
// TODO - consider merging with text_symbolizer label_placement_e
@ -46,9 +49,14 @@ struct MAPNIK_DECL markers_symbolizer :
public symbolizer_with_image, public symbolizer_base
{
public:
explicit markers_symbolizer();
markers_symbolizer(path_expression_ptr filename);
markers_symbolizer();
markers_symbolizer(path_expression_ptr const& filename);
markers_symbolizer(markers_symbolizer const& rhs);
void set_width(expression_ptr const& width);
expression_ptr const& get_width() const;
void set_height(expression_ptr const& height);
expression_ptr const& get_height() const;
void set_ignore_placement(bool ignore_placement);
bool get_ignore_placement() const;
void set_allow_overlap(bool overlap);
@ -57,28 +65,22 @@ public:
double get_spacing() const;
void set_max_error(double max_error);
double get_max_error() const;
void set_fill(color fill);
color const& get_fill() const;
void set_width(expression_ptr width);
expression_ptr get_width() const;
void set_height(expression_ptr height);
expression_ptr get_height() const;
stroke const& get_stroke() const;
void set_fill(color const& fill);
boost::optional<color> get_fill() const;
void set_stroke(stroke const& stroke);
boost::optional<stroke> get_stroke() const;
void set_marker_placement(marker_placement_e marker_p);
marker_placement_e get_marker_placement() const;
private:
bool ignore_placement_;
bool allow_overlap_;
color fill_;
double spacing_;
double max_error_;
expression_ptr width_;
expression_ptr height_;
stroke stroke_;
bool ignore_placement_;
bool allow_overlap_;
double spacing_;
double max_error_;
boost::optional<color> fill_;
boost::optional<stroke> stroke_;
marker_placement_e marker_p_;
};
}

View file

@ -110,7 +110,7 @@ public:
virtual void add_box(box2d<double> const& box, Feature const& feature,
CoordTransform const& t,
metawriter_properties const& properties)=0;
virtual void add_text(boost::ptr_vector<text_path> &placements,
virtual void add_text(boost::ptr_vector<text_path> const& placements,
box2d<double> const& extents,
Feature const& feature,
CoordTransform const& t,
@ -144,7 +144,11 @@ public:
*/
void set_size(int width, int height) { width_ = width; height_ = height; }
/** Set Map object's srs. */
virtual void set_map_srs(projection const& proj) { /* Not required when working with image coordinates. */ }
virtual void set_map_srs(projection const& proj)
{
boost::ignore_unused_variable_warning(proj);
}
/** Return the list of default properties. */
metawriter_properties const& get_default_properties() const { return dflt_properties_;}
protected:

View file

@ -65,7 +65,7 @@ public:
virtual void add_box(box2d<double> const& box, Feature const& feature,
CoordTransform const& t,
metawriter_properties const& properties);
virtual void add_text(boost::ptr_vector<text_path> &placements,
virtual void add_text(boost::ptr_vector<text_path> const& placements,
box2d<double> const& extents,
Feature const& feature,
CoordTransform const& t,

View file

@ -45,7 +45,7 @@ public:
virtual void add_box(box2d<double> const& box, Feature const& feature,
CoordTransform const& t,
metawriter_properties const& properties);
virtual void add_text(boost::ptr_vector<text_path> &placements,
virtual void add_text(boost::ptr_vector<text_path> const& placements,
box2d<double> const& extents,
Feature const& feature,
CoordTransform const& t,

View file

@ -80,14 +80,10 @@ public:
/** Remove old placements. */
void clear_placements();
inline placements_type &get_results() { return placements_; }
inline placements_type const& get_results() { return placements_; }
/** Additional boxes to take into account when finding placement.
* Used for finding line placements where multiple placements are returned.
* Boxes are relative to starting point of current placement.
* Only used for point placements!
*/
std::vector<box2d<double> > additional_boxes;
std::vector<box2d<double> > & additional_boxes() { return additional_boxes_;}
std::vector<box2d<double> > const& additional_boxes() const { return additional_boxes_;}
void set_collect_extents(bool collect) { collect_extents_ = collect; }
bool get_collect_extents() const { return collect_extents_; }
@ -160,6 +156,13 @@ private:
box2d<double> extents_;
/** Collect a bounding box of all texts placed. */
bool collect_extents_;
/** Additional boxes to take into account when finding placement.
* Used for finding line placements where multiple placements are returned.
* Boxes are relative to starting point of current placement.
* Only used for point placements!
*/
std::vector<box2d<double> > additional_boxes_;
};
}

View file

@ -25,9 +25,12 @@
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/image_scaling.hpp>
namespace mapnik
{
@ -37,7 +40,7 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
raster_symbolizer()
: symbolizer_base(),
mode_("normal"),
scaling_("fast"),
scaling_(SCALING_NEAR),
opacity_(1.0),
colorizer_(),
filter_factor_(-1),
@ -45,26 +48,40 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
raster_symbolizer(const raster_symbolizer &rhs)
: symbolizer_base(rhs),
mode_(rhs.get_mode()),
scaling_(rhs.get_scaling()),
opacity_(rhs.get_opacity()),
mode_(rhs.mode_),
scaling_(rhs.scaling_),
opacity_(rhs.opacity_),
colorizer_(rhs.colorizer_),
filter_factor_(rhs.filter_factor_),
mesh_size_(rhs.mesh_size_) {}
std::string const& get_mode() const
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "getting 'mode' is deprecated and will be removed in Mapnik 3.x, use 'comp-op' with Mapnik >= 2.1.x";
return mode_;
}
void set_mode(std::string const& mode)
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "setting 'mode' is deprecated and will be removed in Mapnik 3.x, use 'comp-op' with Mapnik >= 2.1.x";
mode_ = mode;
if (mode == "normal")
{
this->set_comp_op(src_over);
}
else
{
boost::optional<composite_mode_e> comp_op = comp_op_from_string(mode);
if (comp_op)
this->set_comp_op(*comp_op);
else
MAPNIK_LOG_ERROR(raster_symbolizer) << "could not convert mode into comp-op";
}
}
std::string const& get_scaling() const
scaling_method_e get_scaling_method() const
{
return scaling_;
}
void set_scaling(std::string const& scaling)
void set_scaling_method(scaling_method_e scaling)
{
scaling_ = scaling;
}
@ -99,13 +116,9 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
// respect explicitly specified values
return filter_factor_;
} else {
// No filter factor specified, calculate a sensible default value
// based on the scaling algorithm being employed.
scaling_method_e scaling = get_scaling_method_by_name (scaling_);
double ff = 1.0;
switch(scaling)
switch(scaling_)
{
case SCALING_NEAR:
ff = 1.0;
@ -114,6 +127,7 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
// TODO potentially some of these algorithms would use filter_factor >2.0.
// Contributions welcome from someone who knows more about them.
case SCALING_BILINEAR:
case SCALING_BILINEAR8:
case SCALING_BICUBIC:
case SCALING_SPLINE16:
case SCALING_SPLINE36:
@ -147,7 +161,7 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
private:
std::string mode_;
std::string scaling_;
scaling_method_e scaling_;
float opacity_;
raster_colorizer_ptr colorizer_;
double filter_factor_;

View file

@ -200,6 +200,7 @@ private:
template <class T>
void copy_text_ptr(T & sym) const
{
boost::ignore_unused_variable_warning(sym);
MAPNIK_LOG_WARN(rule) << "rule: deep copying TextSymbolizers is broken!";
}

View file

@ -193,7 +193,7 @@ public:
}
// Attribute setting functions.
void fill(const agg::rgba8& f)
void fill(agg::rgba8 const& f)
{
path_attributes& attr = cur_attr();
double a = attr.fill_color.opacity();
@ -202,19 +202,19 @@ public:
attr.fill_flag = true;
}
void add_fill_gradient(mapnik::gradient& grad)
void add_fill_gradient(mapnik::gradient const& grad)
{
path_attributes& attr = cur_attr();
attr.fill_gradient = grad;
}
void add_stroke_gradient(mapnik::gradient& grad)
void add_stroke_gradient(mapnik::gradient const& grad)
{
path_attributes& attr = cur_attr();
attr.stroke_gradient = grad;
}
void stroke(const agg::rgba8& s)
void stroke(agg::rgba8 const& s)
{
path_attributes& attr = cur_attr();
double a = attr.stroke_color.opacity();
@ -264,16 +264,17 @@ public:
void fill_opacity(double op)
{
cur_attr().fill_color.opacity(op);
cur_attr().fill_opacity = op;
}
void stroke_opacity(double op)
{
cur_attr().stroke_color.opacity(op);
cur_attr().stroke_opacity = op;
}
void opacity(double op)
{
cur_attr().opacity = op;
cur_attr().stroke_opacity = op;
cur_attr().fill_opacity = op;
}
void line_join(agg::line_join_e join)

View file

@ -44,7 +44,9 @@ namespace mapnik { namespace svg {
explicit svg_parser(svg_converter_type & path);
~svg_parser();
void parse(std::string const& filename);
void parse_from_string(std::string const& svg);
private:
bool parse_reader(xmlTextReaderPtr reader);
void process_node(xmlTextReaderPtr reader);
void start_element(xmlTextReaderPtr reader);
void end_element(xmlTextReaderPtr reader);

View file

@ -47,9 +47,9 @@ public:
typedef path_adapter<VertexContainer> self_type;
//--------------------------------------------------------------------
path_adapter(VertexContainer & vertices) : m_vertices(vertices), m_iterator(0) {}
//void remove_all() { m_vertices.remove_all(); m_iterator = 0; }
//void free_all() { m_vertices.free_all(); m_iterator = 0; }
path_adapter(VertexContainer & vertices) : vertices_(vertices), iterator_(0) {}
//void remove_all() { vertices_.remove_all(); iterator_ = 0; }
//void free_all() { vertices_.free_all(); iterator_ = 0; }
// Make path functions
//--------------------------------------------------------------------
@ -109,8 +109,8 @@ public:
// Accessors
//--------------------------------------------------------------------
const container_type& vertices() const { return m_vertices; }
container_type& vertices() { return m_vertices; }
const container_type& vertices() const { return vertices_; }
container_type& vertices() { return vertices_; }
unsigned total_vertices() const;
@ -160,7 +160,7 @@ public:
vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
m_vertices.add_vertex(x, y, cmd);
vertices_.add_vertex(x, y, cmd);
}
}
@ -185,7 +185,7 @@ public:
if(calc_distance(x, y, x0, y0) > vertex_dist_epsilon)
{
if(is_move_to(cmd)) cmd = path_cmd_line_to;
m_vertices.add_vertex(x, y, cmd);
vertices_.add_vertex(x, y, cmd);
}
}
else
@ -198,12 +198,12 @@ public:
{
if(is_move_to(cmd)) cmd = path_cmd_line_to;
}
m_vertices.add_vertex(x, y, cmd);
vertices_.add_vertex(x, y, cmd);
}
}
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
m_vertices.add_vertex(x, y, is_move_to(cmd) ?
vertices_.add_vertex(x, y, is_move_to(cmd) ?
unsigned(path_cmd_line_to) :
cmd);
}
@ -218,16 +218,16 @@ public:
template<class Trans>
void transform(const Trans& trans, unsigned path_id=0)
{
unsigned num_ver = m_vertices.total_vertices();
unsigned num_ver = vertices_.total_vertices();
for(; path_id < num_ver; path_id++)
{
double x, y;
unsigned cmd = m_vertices.vertex(path_id, &x, &y);
unsigned cmd = vertices_.vertex(path_id, &x, &y);
if(is_stop(cmd)) break;
if(is_vertex(cmd))
{
trans.transform(&x, &y);
m_vertices.modify_vertex(path_id, x, y);
vertices_.modify_vertex(path_id, x, y);
}
}
}
@ -237,14 +237,14 @@ public:
void transform_all_paths(const Trans& trans)
{
unsigned idx;
unsigned num_ver = m_vertices.total_vertices();
unsigned num_ver = vertices_.total_vertices();
for(idx = 0; idx < num_ver; idx++)
{
double x, y;
if(is_vertex(m_vertices.vertex(idx, &x, &y)))
if(is_vertex(vertices_.vertex(idx, &x, &y)))
{
trans.transform(&x, &y);
m_vertices.modify_vertex(idx, x, y);
vertices_.modify_vertex(idx, x, y);
}
}
}
@ -255,19 +255,21 @@ private:
unsigned perceive_polygon_orientation(unsigned start, unsigned end);
void invert_polygon(unsigned start, unsigned end);
VertexContainer & m_vertices;
unsigned m_iterator;
VertexContainer & vertices_;
unsigned iterator_;
double start_x_;
double start_y_;
};
//------------------------------------------------------------------------
template<class VC>
unsigned path_adapter<VC>::start_new_path()
{
if(!is_stop(m_vertices.last_command()))
if(!is_stop(vertices_.last_command()))
{
m_vertices.add_vertex(0.0, 0.0, path_cmd_stop);
vertices_.add_vertex(0.0, 0.0, path_cmd_stop);
}
return m_vertices.total_vertices();
return vertices_.total_vertices();
}
@ -275,17 +277,12 @@ unsigned path_adapter<VC>::start_new_path()
template<class VC>
inline void path_adapter<VC>::rel_to_abs(double* x, double* y) const
{
if(m_vertices.total_vertices())
if(vertices_.total_vertices())
{
double x2;
double y2;
if(is_vertex(m_vertices.last_vertex(&x2, &y2)))
{
*x += x2;
*y += y2;
}
else if (!is_stop(m_vertices.last_command()) &&
is_vertex(m_vertices.prev_vertex(&x2, &y2)))
if(is_vertex(vertices_.last_vertex(&x2, &y2))
|| !is_stop(vertices_.last_command()))
{
*x += x2;
*y += y2;
@ -297,7 +294,9 @@ inline void path_adapter<VC>::rel_to_abs(double* x, double* y) const
template<class VC>
inline void path_adapter<VC>::move_to(double x, double y)
{
m_vertices.add_vertex(x, y, path_cmd_move_to);
start_x_ = x;
start_y_ = y;
vertices_.add_vertex(x, y, path_cmd_move_to);
}
//------------------------------------------------------------------------
@ -305,14 +304,14 @@ template<class VC>
inline void path_adapter<VC>::move_rel(double dx, double dy)
{
rel_to_abs(&dx, &dy);
m_vertices.add_vertex(dx, dy, path_cmd_move_to);
vertices_.add_vertex(dx, dy, path_cmd_move_to);
}
//------------------------------------------------------------------------
template<class VC>
inline void path_adapter<VC>::line_to(double x, double y)
{
m_vertices.add_vertex(x, y, path_cmd_line_to);
vertices_.add_vertex(x, y, path_cmd_line_to);
}
//------------------------------------------------------------------------
@ -320,14 +319,14 @@ template<class VC>
inline void path_adapter<VC>::line_rel(double dx, double dy)
{
rel_to_abs(&dx, &dy);
m_vertices.add_vertex(dx, dy, path_cmd_line_to);
vertices_.add_vertex(dx, dy, path_cmd_line_to);
}
//------------------------------------------------------------------------
template<class VC>
inline void path_adapter<VC>::hline_to(double x)
{
m_vertices.add_vertex(x, last_y(), path_cmd_line_to);
vertices_.add_vertex(x, last_y(), path_cmd_line_to);
}
//------------------------------------------------------------------------
@ -336,14 +335,14 @@ inline void path_adapter<VC>::hline_rel(double dx)
{
double dy = 0;
rel_to_abs(&dx, &dy);
m_vertices.add_vertex(dx, dy, path_cmd_line_to);
vertices_.add_vertex(dx, dy, path_cmd_line_to);
}
//------------------------------------------------------------------------
template<class VC>
inline void path_adapter<VC>::vline_to(double y)
{
m_vertices.add_vertex(last_x(), y, path_cmd_line_to);
vertices_.add_vertex(last_x(), y, path_cmd_line_to);
}
//------------------------------------------------------------------------
@ -352,7 +351,7 @@ inline void path_adapter<VC>::vline_rel(double dy)
{
double dx = 0;
rel_to_abs(&dx, &dy);
m_vertices.add_vertex(dx, dy, path_cmd_line_to);
vertices_.add_vertex(dx, dy, path_cmd_line_to);
}
//------------------------------------------------------------------------
@ -363,12 +362,12 @@ void path_adapter<VC>::arc_to(double rx, double ry,
bool sweep_flag,
double x, double y)
{
if(m_vertices.total_vertices() && is_vertex(m_vertices.last_command()))
if(vertices_.total_vertices() && is_vertex(vertices_.last_command()))
{
const double epsilon = 1e-30;
double x0 = 0.0;
double y0 = 0.0;
m_vertices.last_vertex(&x0, &y0);
vertices_.last_vertex(&x0, &y0);
rx = fabs(rx);
ry = fabs(ry);
@ -420,8 +419,8 @@ template<class VC>
void path_adapter<VC>::curve3(double x_ctrl, double y_ctrl,
double x_to, double y_to)
{
m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3);
m_vertices.add_vertex(x_to, y_to, path_cmd_curve3);
vertices_.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3);
vertices_.add_vertex(x_to, y_to, path_cmd_curve3);
}
//------------------------------------------------------------------------
@ -431,8 +430,8 @@ void path_adapter<VC>::curve3_rel(double dx_ctrl, double dy_ctrl,
{
rel_to_abs(&dx_ctrl, &dy_ctrl);
rel_to_abs(&dx_to, &dy_to);
m_vertices.add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3);
m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve3);
vertices_.add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3);
vertices_.add_vertex(dx_to, dy_to, path_cmd_curve3);
}
//------------------------------------------------------------------------
@ -441,11 +440,11 @@ void path_adapter<VC>::curve3(double x_to, double y_to)
{
double x0;
double y0;
if(is_vertex(m_vertices.last_vertex(&x0, &y0)))
if(is_vertex(vertices_.last_vertex(&x0, &y0)))
{
double x_ctrl;
double y_ctrl;
unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl);
unsigned cmd = vertices_.prev_vertex(&x_ctrl, &y_ctrl);
if(is_curve(cmd))
{
x_ctrl = x0 + x0 - x_ctrl;
@ -474,9 +473,9 @@ void path_adapter<VC>::curve4(double x_ctrl1, double y_ctrl1,
double x_ctrl2, double y_ctrl2,
double x_to, double y_to)
{
m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4);
m_vertices.add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4);
m_vertices.add_vertex(x_to, y_to, path_cmd_curve4);
vertices_.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4);
vertices_.add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4);
vertices_.add_vertex(x_to, y_to, path_cmd_curve4);
}
//------------------------------------------------------------------------
@ -488,9 +487,9 @@ void path_adapter<VC>::curve4_rel(double dx_ctrl1, double dy_ctrl1,
rel_to_abs(&dx_ctrl1, &dy_ctrl1);
rel_to_abs(&dx_ctrl2, &dy_ctrl2);
rel_to_abs(&dx_to, &dy_to);
m_vertices.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4);
m_vertices.add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4);
m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve4);
vertices_.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4);
vertices_.add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4);
vertices_.add_vertex(dx_to, dy_to, path_cmd_curve4);
}
//------------------------------------------------------------------------
@ -533,9 +532,9 @@ void path_adapter<VC>::curve4_rel(double dx_ctrl2, double dy_ctrl2,
template<class VC>
inline void path_adapter<VC>::end_poly(unsigned flags)
{
if(is_vertex(m_vertices.last_command()))
if(is_vertex(vertices_.last_command()))
{
m_vertices.add_vertex(0.0, 0.0, path_cmd_end_poly | flags);
vertices_.add_vertex(start_x_, start_y_, path_cmd_end_poly | flags);
}
}
@ -550,85 +549,85 @@ inline void path_adapter<VC>::close_polygon(unsigned flags)
template<class VC>
inline unsigned path_adapter<VC>::total_vertices() const
{
return m_vertices.total_vertices();
return vertices_.total_vertices();
}
//------------------------------------------------------------------------
template<class VC>
inline unsigned path_adapter<VC>::last_vertex(double* x, double* y) const
{
return m_vertices.last_vertex(x, y);
return vertices_.last_vertex(x, y);
}
//------------------------------------------------------------------------
template<class VC>
inline unsigned path_adapter<VC>::prev_vertex(double* x, double* y) const
{
return m_vertices.prev_vertex(x, y);
return vertices_.prev_vertex(x, y);
}
//------------------------------------------------------------------------
template<class VC>
inline double path_adapter<VC>::last_x() const
{
return m_vertices.last_x();
return vertices_.last_x();
}
//------------------------------------------------------------------------
template<class VC>
inline double path_adapter<VC>::last_y() const
{
return m_vertices.last_y();
return vertices_.last_y();
}
//------------------------------------------------------------------------
template<class VC>
inline unsigned path_adapter<VC>::vertex(unsigned idx, double* x, double* y) const
{
return m_vertices.vertex(idx, x, y);
return vertices_.vertex(idx, x, y);
}
//------------------------------------------------------------------------
template<class VC>
inline unsigned path_adapter<VC>::command(unsigned idx) const
{
return m_vertices.command(idx);
return vertices_.command(idx);
}
//------------------------------------------------------------------------
template<class VC>
void path_adapter<VC>::modify_vertex(unsigned idx, double x, double y)
{
m_vertices.modify_vertex(idx, x, y);
vertices_.modify_vertex(idx, x, y);
}
//------------------------------------------------------------------------
template<class VC>
void path_adapter<VC>::modify_vertex(unsigned idx, double x, double y, unsigned cmd)
{
m_vertices.modify_vertex(idx, x, y, cmd);
vertices_.modify_vertex(idx, x, y, cmd);
}
//------------------------------------------------------------------------
template<class VC>
void path_adapter<VC>::modify_command(unsigned idx, unsigned cmd)
{
m_vertices.modify_command(idx, cmd);
vertices_.modify_command(idx, cmd);
}
//------------------------------------------------------------------------
template<class VC>
inline void path_adapter<VC>::rewind(unsigned path_id)
{
m_iterator = path_id;
iterator_ = path_id;
}
//------------------------------------------------------------------------
template<class VC>
inline unsigned path_adapter<VC>::vertex(double* x, double* y)
{
if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop;
return m_vertices.vertex(m_iterator++, x, y);
if(iterator_ >= vertices_.total_vertices()) return path_cmd_stop;
return vertices_.vertex(iterator_++, x, y);
}
//------------------------------------------------------------------------
@ -644,8 +643,8 @@ unsigned path_adapter<VC>::perceive_polygon_orientation(unsigned start,
for(i = 0; i < np; i++)
{
double x1, y1, x2, y2;
m_vertices.vertex(start + i, &x1, &y1);
m_vertices.vertex(start + (i + 1) % np, &x2, &y2);
vertices_.vertex(start + i, &x1, &y1);
vertices_.vertex(start + (i + 1) % np, &x2, &y2);
area += x1 * y2 - y1 * x2;
}
return (area < 0.0) ? path_flags_cw : path_flags_ccw;
@ -656,23 +655,23 @@ template<class VC>
void path_adapter<VC>::invert_polygon(unsigned start, unsigned end)
{
unsigned i;
unsigned tmp_cmd = m_vertices.command(start);
unsigned tmp_cmd = vertices_.command(start);
--end; // Make "end" inclusive
// Shift all commands to one position
for(i = start; i < end; i++)
{
m_vertices.modify_command(i, m_vertices.command(i + 1));
vertices_.modify_command(i, vertices_.command(i + 1));
}
// Assign starting command to the ending command
m_vertices.modify_command(end, tmp_cmd);
vertices_.modify_command(end, tmp_cmd);
// Reverse the polygon
while(end > start)
{
m_vertices.swap_vertices(start++, end--);
vertices_.swap_vertices(start++, end--);
}
}
@ -681,18 +680,18 @@ template<class VC>
void path_adapter<VC>::invert_polygon(unsigned start)
{
// Skip all non-vertices at the beginning
while(start < m_vertices.total_vertices() &&
!is_vertex(m_vertices.command(start))) ++start;
while(start < vertices_.total_vertices() &&
!is_vertex(vertices_.command(start))) ++start;
// Skip all insignificant move_to
while(start+1 < m_vertices.total_vertices() &&
is_move_to(m_vertices.command(start)) &&
is_move_to(m_vertices.command(start+1))) ++start;
while(start+1 < vertices_.total_vertices() &&
is_move_to(vertices_.command(start)) &&
is_move_to(vertices_.command(start+1))) ++start;
// Find the last vertex
unsigned end = start + 1;
while(end < m_vertices.total_vertices() &&
!is_next_poly(m_vertices.command(end))) ++end;
while(end < vertices_.total_vertices() &&
!is_next_poly(vertices_.command(end))) ++end;
invert_polygon(start, end);
}
@ -705,18 +704,18 @@ unsigned path_adapter<VC>::arrange_polygon_orientation(unsigned start,
if(orientation == path_flags_none) return start;
// Skip all non-vertices at the beginning
while(start < m_vertices.total_vertices() &&
!is_vertex(m_vertices.command(start))) ++start;
while(start < vertices_.total_vertices() &&
!is_vertex(vertices_.command(start))) ++start;
// Skip all insignificant move_to
while(start+1 < m_vertices.total_vertices() &&
is_move_to(m_vertices.command(start)) &&
is_move_to(m_vertices.command(start+1))) ++start;
while(start+1 < vertices_.total_vertices() &&
is_move_to(vertices_.command(start)) &&
is_move_to(vertices_.command(start+1))) ++start;
// Find the last vertex
unsigned end = start + 1;
while(end < m_vertices.total_vertices() &&
!is_next_poly(m_vertices.command(end))) ++end;
while(end < vertices_.total_vertices() &&
!is_next_poly(vertices_.command(end))) ++end;
if(end - start > 2)
{
@ -725,10 +724,10 @@ unsigned path_adapter<VC>::arrange_polygon_orientation(unsigned start,
// Invert polygon, set orientation flag, and skip all end_poly
invert_polygon(start, end);
unsigned cmd;
while(end < m_vertices.total_vertices() &&
is_end_poly(cmd = m_vertices.command(end)))
while(end < vertices_.total_vertices() &&
is_end_poly(cmd = vertices_.command(end)))
{
m_vertices.modify_command(end++, set_orientation(cmd, orientation));
vertices_.modify_command(end++, set_orientation(cmd, orientation));
}
}
}
@ -742,10 +741,10 @@ unsigned path_adapter<VC>::arrange_orientations(unsigned start,
{
if(orientation != path_flags_none)
{
while(start < m_vertices.total_vertices())
while(start < vertices_.total_vertices())
{
start = arrange_polygon_orientation(start, orientation);
if(is_stop(m_vertices.command(start)))
if(is_stop(vertices_.command(start)))
{
++start;
break;
@ -762,7 +761,7 @@ void path_adapter<VC>::arrange_orientations_all_paths(path_flags_e orientation)
if(orientation != path_flags_none)
{
unsigned start = 0;
while(start < m_vertices.total_vertices())
while(start < vertices_.total_vertices())
{
start = arrange_orientations(start, orientation);
}
@ -775,12 +774,12 @@ void path_adapter<VC>::flip_x(double x1, double x2)
{
unsigned i;
double x, y;
for(i = 0; i < m_vertices.total_vertices(); i++)
for(i = 0; i < vertices_.total_vertices(); i++)
{
unsigned cmd = m_vertices.vertex(i, &x, &y);
unsigned cmd = vertices_.vertex(i, &x, &y);
if(is_vertex(cmd))
{
m_vertices.modify_vertex(i, x2 - x + x1, y);
vertices_.modify_vertex(i, x2 - x + x1, y);
}
}
}
@ -791,12 +790,12 @@ void path_adapter<VC>::flip_y(double y1, double y2)
{
unsigned i;
double x, y;
for(i = 0; i < m_vertices.total_vertices(); i++)
for(i = 0; i < vertices_.total_vertices(); i++)
{
unsigned cmd = m_vertices.vertex(i, &x, &y);
unsigned cmd = vertices_.vertex(i, &x, &y);
if(is_vertex(cmd))
{
m_vertices.modify_vertex(i, x, y2 - y + y1);
vertices_.modify_vertex(i, x, y2 - y + y1);
}
}
}
@ -805,17 +804,17 @@ void path_adapter<VC>::flip_y(double y1, double y2)
template<class VC>
void path_adapter<VC>::translate(double dx, double dy, unsigned path_id)
{
unsigned num_ver = m_vertices.total_vertices();
unsigned num_ver = vertices_.total_vertices();
for(; path_id < num_ver; path_id++)
{
double x, y;
unsigned cmd = m_vertices.vertex(path_id, &x, &y);
unsigned cmd = vertices_.vertex(path_id, &x, &y);
if(is_stop(cmd)) break;
if(is_vertex(cmd))
{
x += dx;
y += dy;
m_vertices.modify_vertex(path_id, x, y);
vertices_.modify_vertex(path_id, x, y);
}
}
}
@ -825,15 +824,15 @@ template<class VC>
void path_adapter<VC>::translate_all_paths(double dx, double dy)
{
unsigned idx;
unsigned num_ver = m_vertices.total_vertices();
unsigned num_ver = vertices_.total_vertices();
for(idx = 0; idx < num_ver; idx++)
{
double x, y;
if(is_vertex(m_vertices.vertex(idx, &x, &y)))
if(is_vertex(vertices_.vertex(idx, &x, &y)))
{
x += dx;
y += dy;
m_vertices.modify_vertex(idx, x, y);
vertices_.modify_vertex(idx, x, y);
}
}
}
@ -847,25 +846,25 @@ public:
typedef typename vertex_type::value_type value_type;
explicit vertex_stl_adapter(Container & vertices)
: m_vertices(vertices) {}
: vertices_(vertices) {}
void add_vertex(double x, double y, unsigned cmd)
{
m_vertices.push_back(vertex_type(value_type(x),
vertices_.push_back(vertex_type(value_type(x),
value_type(y),
int8u(cmd)));
}
void modify_vertex(unsigned idx, double x, double y)
{
vertex_type& v = m_vertices[idx];
vertex_type& v = vertices_[idx];
v.x = value_type(x);
v.y = value_type(y);
}
void modify_vertex(unsigned idx, double x, double y, unsigned cmd)
{
vertex_type& v = m_vertices[idx];
vertex_type& v = vertices_[idx];
v.x = value_type(x);
v.y = value_type(y);
v.cmd = int8u(cmd);
@ -873,61 +872,61 @@ public:
void modify_command(unsigned idx, unsigned cmd)
{
m_vertices[idx].cmd = int8u(cmd);
vertices_[idx].cmd = int8u(cmd);
}
void swap_vertices(unsigned v1, unsigned v2)
{
vertex_type t = m_vertices[v1];
m_vertices[v1] = m_vertices[v2];
m_vertices[v2] = t;
vertex_type t = vertices_[v1];
vertices_[v1] = vertices_[v2];
vertices_[v2] = t;
}
unsigned last_command() const
{
return m_vertices.size() ?
m_vertices[m_vertices.size() - 1].cmd :
return vertices_.size() ?
vertices_[vertices_.size() - 1].cmd :
(unsigned)path_cmd_stop;
}
unsigned last_vertex(double* x, double* y) const
{
if(m_vertices.size() == 0)
if(vertices_.size() == 0)
{
*x = *y = 0.0;
return path_cmd_stop;
}
return vertex(m_vertices.size() - 1, x, y);
return vertex(vertices_.size() - 1, x, y);
}
unsigned prev_vertex(double* x, double* y) const
{
if(m_vertices.size() < 2)
if(vertices_.size() < 2)
{
*x = *y = 0.0;
return path_cmd_stop;
}
return vertex(m_vertices.size() - 2, x, y);
return vertex(vertices_.size() - 2, x, y);
}
double last_x() const
{
return m_vertices.size() ? m_vertices[m_vertices.size() - 1].x : 0.0;
return vertices_.size() ? vertices_[vertices_.size() - 1].x : 0.0;
}
double last_y() const
{
return m_vertices.size() ? m_vertices[m_vertices.size() - 1].y : 0.0;
return vertices_.size() ? vertices_[vertices_.size() - 1].y : 0.0;
}
unsigned total_vertices() const
{
return m_vertices.size();
return vertices_.size();
}
unsigned vertex(unsigned idx, double* x, double* y) const
{
const vertex_type& v = m_vertices[idx];
const vertex_type& v = vertices_[idx];
*x = v.x;
*y = v.y;
return v.cmd;
@ -935,11 +934,11 @@ public:
unsigned command(unsigned idx) const
{
return m_vertices[idx].cmd;
return vertices_[idx].cmd;
}
private:
Container & m_vertices;
Container & vertices_;
};

View file

@ -39,8 +39,9 @@ struct path_attributes
{
unsigned index;
agg::rgba8 fill_color;
double fill_opacity;
agg::rgba8 stroke_color;
double opacity;
double stroke_opacity;
bool fill_flag;
bool stroke_flag;
bool even_odd_flag;
@ -58,8 +59,9 @@ struct path_attributes
path_attributes() :
index(0),
fill_color(agg::rgba(0,0,0)),
fill_opacity(1.0),
stroke_color(agg::rgba(0,0,0)),
opacity(1.0),
stroke_opacity(1.0),
fill_flag(true),
stroke_flag(false),
even_odd_flag(false),
@ -79,8 +81,9 @@ struct path_attributes
path_attributes(const path_attributes& attr)
: index(attr.index),
fill_color(attr.fill_color),
fill_opacity(attr.fill_opacity),
stroke_color(attr.stroke_color),
opacity(attr.opacity),
stroke_opacity(attr.stroke_opacity),
fill_flag(attr.fill_flag),
stroke_flag(attr.stroke_flag),
even_odd_flag(attr.even_odd_flag),
@ -99,8 +102,9 @@ struct path_attributes
path_attributes(path_attributes const& attr, unsigned idx)
: index(idx),
fill_color(attr.fill_color),
fill_opacity(attr.fill_opacity),
stroke_color(attr.stroke_color),
opacity(attr.opacity),
stroke_opacity(attr.stroke_opacity),
fill_flag(attr.fill_flag),
stroke_flag(attr.stroke_flag),
even_odd_flag(attr.even_odd_flag),

View file

@ -35,232 +35,232 @@
namespace mapnik { namespace svg {
using namespace boost::fusion;
using namespace boost::fusion;
inline double deg2rad(double deg)
inline double deg2rad(double deg)
{
return (M_PI * deg)/180.0;
}
template <typename PathType>
struct move_to
{
template <typename T0, typename T1>
struct result
{
return (M_PI * deg)/180.0;
typedef void type;
};
explicit move_to(PathType & path)
: path_(path) {}
template <typename T0, typename T1>
void operator() (T0 v, T1 rel) const
{
path_.move_to(at_c<0>(v),at_c<1>(v),rel); // impl
}
template <typename PathType>
struct move_to
PathType & path_;
};
template <typename PathType>
struct hline_to
{
template <typename T0, typename T1>
struct result
{
template <typename T0, typename T1>
struct result
{
typedef void type;
};
explicit move_to(PathType & path)
: path_(path) {}
template <typename T0, typename T1>
void operator() (T0 v, T1 rel) const
{
path_.move_to(at_c<0>(v),at_c<1>(v),rel); // impl
}
PathType & path_;
typedef void type;
};
template <typename PathType>
struct hline_to
explicit hline_to(PathType & path)
: path_(path) {}
template <typename T0, typename T1>
void operator() (T0 const& x, T1 rel) const
{
template <typename T0, typename T1>
struct result
{
typedef void type;
};
path_.hline_to(x,rel);
}
explicit hline_to(PathType & path)
: path_(path) {}
PathType & path_;
};
template <typename T0, typename T1>
void operator() (T0 const& x, T1 rel) const
{
path_.hline_to(x,rel);
}
PathType & path_;
template <typename PathType>
struct vline_to
{
template <typename T0, typename T1>
struct result
{
typedef void type;
};
explicit vline_to(PathType & path)
: path_(path) {}
template <typename PathType>
struct vline_to
template <typename T0, typename T1>
void operator() (T0 const& y, T1 rel) const
{
template <typename T0, typename T1>
struct result
{
typedef void type;
};
path_.vline_to(y,rel);
}
explicit vline_to(PathType & path)
: path_(path) {}
PathType & path_;
};
template <typename T0, typename T1>
void operator() (T0 const& y, T1 rel) const
{
path_.vline_to(y,rel);
}
PathType & path_;
template <typename PathType>
struct line_to
{
template <typename T0, typename T1>
struct result
{
typedef void type;
};
template <typename PathType>
struct line_to
explicit line_to(PathType & path)
: path_(path) {}
template <typename T0, typename T1>
void operator() (T0 const& v, T1 rel) const
{
template <typename T0, typename T1>
struct result
{
typedef void type;
};
path_.line_to(at_c<0>(v),at_c<1>(v),rel); // impl
}
explicit line_to(PathType & path)
: path_(path) {}
PathType & path_;
};
template <typename T0, typename T1>
void operator() (T0 const& v, T1 rel) const
{
path_.line_to(at_c<0>(v),at_c<1>(v),rel); // impl
}
PathType & path_;
template <typename PathType>
struct curve4
{
template <typename T0, typename T1, typename T2, typename T3>
struct result
{
typedef void type;
};
explicit curve4(PathType & path)
: path_(path) {}
template <typename PathType>
struct curve4
template <typename T0, typename T1,typename T2, typename T3>
void operator() (T0 const& v0, T1 const& v1, T2 const& v2, T3 rel) const
{
template <typename T0, typename T1, typename T2, typename T3>
struct result
{
typedef void type;
};
path_.curve4(at_c<0>(v0),at_c<1>(v0),
at_c<0>(v1),at_c<1>(v1),
at_c<0>(v2),at_c<1>(v2),
rel); // impl
}
explicit curve4(PathType & path)
: path_(path) {}
PathType & path_;
};
template <typename T0, typename T1,typename T2, typename T3>
void operator() (T0 const& v0, T1 const& v1, T2 const& v2, T3 rel) const
{
path_.curve4(at_c<0>(v0),at_c<1>(v0),
at_c<0>(v1),at_c<1>(v1),
at_c<0>(v2),at_c<1>(v2),
rel); // impl
}
PathType & path_;
template <typename PathType>
struct curve4_smooth
{
template <typename T0, typename T1, typename T2>
struct result
{
typedef void type;
};
explicit curve4_smooth(PathType & path)
: path_(path) {}
template <typename PathType>
struct curve4_smooth
template <typename T0, typename T1,typename T2>
void operator() (T0 const& v0, T1 const& v1, T2 rel) const
{
template <typename T0, typename T1, typename T2>
struct result
{
typedef void type;
};
path_.curve4(at_c<0>(v0),at_c<1>(v0),
at_c<0>(v1),at_c<1>(v1),
rel); // impl
}
PathType & path_;
};
explicit curve4_smooth(PathType & path)
: path_(path) {}
template <typename T0, typename T1,typename T2>
void operator() (T0 const& v0, T1 const& v1, T2 rel) const
{
path_.curve4(at_c<0>(v0),at_c<1>(v0),
at_c<0>(v1),at_c<1>(v1),
rel); // impl
}
PathType & path_;
template <typename PathType>
struct curve3
{
template <typename T0, typename T1, typename T2>
struct result
{
typedef void type;
};
template <typename PathType>
struct curve3
explicit curve3(PathType & path)
: path_(path) {}
template <typename T0, typename T1,typename T2>
void operator() (T0 const& v0, T1 const& v1, T2 rel) const
{
template <typename T0, typename T1, typename T2>
struct result
{
typedef void type;
};
path_.curve3(at_c<0>(v0),at_c<1>(v0),
at_c<0>(v1),at_c<1>(v1),
rel); // impl
}
explicit curve3(PathType & path)
: path_(path) {}
PathType & path_;
};
template <typename T0, typename T1,typename T2>
void operator() (T0 const& v0, T1 const& v1, T2 rel) const
{
path_.curve3(at_c<0>(v0),at_c<1>(v0),
at_c<0>(v1),at_c<1>(v1),
rel); // impl
}
PathType & path_;
template <typename PathType>
struct curve3_smooth
{
template <typename T0, typename T1>
struct result
{
typedef void type;
};
template <typename PathType>
struct curve3_smooth
explicit curve3_smooth(PathType & path)
: path_(path) {}
template <typename T0, typename T1>
void operator() (T0 const& v0, T1 rel) const
{
template <typename T0, typename T1>
struct result
{
typedef void type;
};
path_.curve3(at_c<0>(v0),at_c<1>(v0),
rel); // impl
}
explicit curve3_smooth(PathType & path)
: path_(path) {}
PathType & path_;
};
template <typename T0, typename T1>
void operator() (T0 const& v0, T1 rel) const
{
path_.curve3(at_c<0>(v0),at_c<1>(v0),
rel); // impl
}
PathType & path_;
template <typename PathType>
struct arc_to
{
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
struct result
{
typedef void type;
};
template <typename PathType>
struct arc_to
explicit arc_to(PathType & path)
: path_(path) {}
template <typename T0, typename T1,typename T2, typename T3, typename T4, typename T5>
void operator() (T0 const& rv, T1 const& angle, T2 large_arc_flag, T3 sweep_flag, T4 const& v, T5 rel) const
{
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
struct result
{
typedef void type;
};
path_.arc_to(at_c<0>(rv),at_c<1>(rv),
deg2rad(angle),large_arc_flag,sweep_flag,
at_c<0>(v),at_c<1>(v),
rel);
}
explicit arc_to(PathType & path)
: path_(path) {}
PathType & path_;
};
template <typename T0, typename T1,typename T2, typename T3, typename T4, typename T5>
void operator() (T0 const& rv, T1 const& angle, T2 large_arc_flag, T3 sweep_flag, T4 const& v, T5 rel) const
{
path_.arc_to(at_c<0>(rv),at_c<1>(rv),
deg2rad(angle),large_arc_flag,sweep_flag,
at_c<0>(v),at_c<1>(v),
rel);
}
template <typename PathType>
struct close
{
typedef void result_type;
PathType & path_;
};
explicit close(PathType & path)
: path_(path) {}
template <typename PathType>
struct close
void operator()() const
{
typedef void result_type;
path_.close_subpath();
}
explicit close(PathType & path)
: path_(path) {}
PathType & path_;
};
void operator()() const
{
path_.close_subpath();
}
PathType & path_;
};
}}
}}
#endif // MAPNIK_SVG_COMMANDS_HPP

View file

@ -243,7 +243,7 @@ public:
Renderer& ren,
agg::trans_affine const& mtx,
double opacity,
const box2d<double> &symbol_bbox)
box2d<double> const& symbol_bbox)
{
using namespace agg;
@ -292,13 +292,13 @@ public:
if(attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
{
render_gradient(ras, sl, ren, attr.fill_gradient, transform, attr.opacity * opacity, symbol_bbox, path_bbox);
render_gradient(ras, sl, ren, attr.fill_gradient, transform, attr.fill_opacity * opacity, symbol_bbox, path_bbox);
}
else
{
ras.filling_rule(attr.even_odd_flag ? fill_even_odd : fill_non_zero);
color = attr.fill_color;
color.opacity(color.opacity() * attr.opacity * opacity);
color.opacity(color.opacity() * attr.fill_opacity * opacity);
ScanlineRenderer ren_s(ren);
color.premultiply();
ren_s.color(color);
@ -328,13 +328,13 @@ public:
if(attr.stroke_gradient.get_gradient_type() != NO_GRADIENT)
{
render_gradient(ras, sl, ren, attr.stroke_gradient, transform, attr.opacity * opacity, symbol_bbox, path_bbox);
render_gradient(ras, sl, ren, attr.stroke_gradient, transform, attr.stroke_opacity * opacity, symbol_bbox, path_bbox);
}
else
{
ras.filling_rule(fill_non_zero);
color = attr.stroke_color;
color.opacity(color.opacity() * attr.opacity * opacity);
color.opacity(color.opacity() * attr.stroke_opacity * opacity);
ScanlineRenderer ren_s(ren);
color.premultiply();
ren_s.color(color);

View file

@ -85,10 +85,11 @@ public:
bool next();
/** Get current placement. next() has to be called before! */
placements_type & placements() const;
placements_type const& placements() const;
protected:
bool next_point_placement();
bool next_line_placement();
bool next_line_placement_clipped();
bool next_placement();
void initialize_geometries();
void initialize_points();

View file

@ -140,7 +140,7 @@ class text_path : boost::noncopyable
~character_node() {}
void vertex(char_info_ptr *c_, double *x_, double *y_, double *angle_)
void vertex(char_info_ptr *c_, double *x_, double *y_, double *angle_) const
{
*c_ = c;
*x_ = pos.x;
@ -149,7 +149,7 @@ class text_path : boost::noncopyable
}
};
int itr_;
mutable int itr_;
public:
typedef std::vector<character_node> character_nodes_t;
pixel_position center;
@ -172,13 +172,13 @@ public:
}
/** Return node. Always returns a new node. Has no way to report that there are no more nodes. */
void vertex(char_info_ptr *c, double *x, double *y, double *angle)
void vertex(char_info_ptr *c, double *x, double *y, double *angle) const
{
nodes_[itr_++].vertex(c, x, y, angle);
}
/** Start again at first node. */
void rewind()
void rewind() const
{
itr_ = 0;
}

View file

@ -115,7 +115,7 @@ namespace detail {
// boost::spirit::traits::clear<T>(T& val) [with T = boost::variant<...>]
// attempts to assign to the variant's current value a default-constructed
// value ot the same type, which not only requires that each value-type is
// value of the same type, which not only requires that each value-type is
// default-constructible, but also makes little sense with our variant of
// transform nodes...

View file

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

View file

@ -66,7 +66,7 @@ namespace mapnik { namespace util {
geometry_type::value_type const operator() (geometry_type const& geom) const
{
geometry_type::value_type coord;
boost::get<0>(coord) = geom.get_vertex(0,&boost::get<1>(coord),&boost::get<2>(coord));
boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord));
return coord;
}
};

View file

@ -119,15 +119,16 @@ namespace mapnik { namespace util {
wkb_buffer_ptr to_point_wkb( geometry_type const& g, wkbByteOrder byte_order)
{
assert(g.num_points() == 1);
assert(g.size() == 1);
std::size_t size = 1 + 4 + 8*2 ; // byteOrder + wkbType + Point
wkb_buffer_ptr wkb = boost::make_shared<wkb_buffer>(size);
boost::interprocess::bufferstream ss(wkb->buffer(), wkb->size(), std::ios::out | std::ios::binary);
ss.write(reinterpret_cast<char*>(&byte_order),1);
int type = static_cast<int>(mapnik::Point);
write(ss,type,4,byte_order);
double x,y;
g.get_vertex(0,&x,&y);
double x(0);
double y(0);
g.vertex(0,&x,&y);
write(ss,x,8,byte_order);
write(ss,y,8,byte_order);
assert(ss.good());
@ -136,7 +137,7 @@ namespace mapnik { namespace util {
wkb_buffer_ptr to_line_string_wkb( geometry_type const& g, wkbByteOrder byte_order)
{
unsigned num_points = g.num_points();
unsigned num_points = g.size();
assert(num_points > 1);
std::size_t size = 1 + 4 + 4 + 8*2*num_points ; // byteOrder + wkbType + numPoints + Point*numPoints
wkb_buffer_ptr wkb = boost::make_shared<wkb_buffer>(size);
@ -145,10 +146,11 @@ namespace mapnik { namespace util {
int type = static_cast<int>(mapnik::LineString);
write(ss,type,4,byte_order);
write(ss,num_points,4,byte_order);
double x,y;
double x(0);
double y(0);
for (unsigned i=0; i< num_points; ++i)
{
g.get_vertex(i,&x,&y);
g.vertex(i,&x,&y);
write(ss,x,8,byte_order);
write(ss,y,8,byte_order);
}
@ -158,18 +160,19 @@ namespace mapnik { namespace util {
wkb_buffer_ptr to_polygon_wkb( geometry_type const& g, wkbByteOrder byte_order)
{
unsigned num_points = g.num_points();
unsigned num_points = g.size();
assert(num_points > 1);
typedef std::pair<double,double> point_type;
typedef std::vector<point_type> linear_ring;
boost::ptr_vector<linear_ring> rings;
double x,y;
double x(0);
double y(0);
std::size_t size = 1 + 4 + 4 ; // byteOrder + wkbType + numRings
for (unsigned i=0; i< num_points; ++i)
{
unsigned command = g.get_vertex(i,&x,&y);
unsigned command = g.vertex(i,&x,&y);
if (command == SEG_MOVETO)
{
rings.push_back(new linear_ring); // start new loop

View file

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

View file

@ -71,19 +71,39 @@ inline void to_utf8(UnicodeString const& input, std::string & target)
struct value_null
{
template <typename T>
value_null operator+ (T const& other) const { return *this; }
value_null operator+ (T const& other) const
{
boost::ignore_unused_variable_warning(other);
return *this;
}
template <typename T>
value_null operator- (T const& other) const { return *this; }
value_null operator- (T const& other) const
{
boost::ignore_unused_variable_warning(other);
return *this;
}
template <typename T>
value_null operator* (T const& other) const { return *this; }
value_null operator* (T const& other) const
{
boost::ignore_unused_variable_warning(other);
return *this;
}
template <typename T>
value_null operator/ (T const& other) const { return *this; }
value_null operator/ (T const& other) const
{
boost::ignore_unused_variable_warning(other);
return *this;
}
template <typename T>
value_null operator% (T const& other) const { return *this; }
value_null operator% (T const& other) const
{
boost::ignore_unused_variable_warning(other);
return *this;
}
};
typedef boost::variant<value_null,bool,int,double,UnicodeString> value_base;
@ -352,7 +372,7 @@ struct add : public boost::static_visitor<V>
{
return lhs + rhs;
}
value_type operator() (UnicodeString const& lhs, value_null rhs) const
{
boost::ignore_unused_variable_warning(rhs);
@ -557,6 +577,11 @@ struct negate : public boost::static_visitor<V>
return val;
}
value_type operator() (bool val) const
{
return val ? -1 : 0;
}
value_type operator() (UnicodeString const& ustr) const
{
UnicodeString inplace(ustr);

View file

@ -26,16 +26,17 @@
// mapnik
#include <mapnik/raster.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/image_scaling.hpp>
namespace mapnik {
void reproject_raster(raster &target, raster const& source,
proj_transform const& prj_trans,
double offset_x, double offset_y,
unsigned mesh_size,
double filter_radius,
double scale_factor,
std::string scaling_method_name);
void reproject_and_scale_raster(raster & target,
raster const& source,
proj_transform const& prj_trans,
double offset_x, double offset_y,
unsigned mesh_size,
double filter_radius,
scaling_method_e scaling_method);
}

View file

@ -55,7 +55,7 @@ class MAPNIK_DECL geometry_utils : private boost::noncopyable
{
public:
static void from_wkb (boost::ptr_vector<geometry_type>& paths,
static bool from_wkb (boost::ptr_vector<geometry_type>& paths,
const char* wkb,
unsigned size,
wkbFormat format = wkbGeneric);

View file

@ -277,9 +277,9 @@ void csv_datasource::parse_csv(T& stream,
bool has_wkt_field = false;
bool has_lat_field = false;
bool has_lon_field = false;
unsigned wkt_idx;
unsigned lat_idx;
unsigned lon_idx;
unsigned wkt_idx(0);
unsigned lat_idx(0);
unsigned lon_idx(0);
if (!manual_headers_.empty())
{
@ -852,7 +852,7 @@ void csv_datasource::parse_csv(T& stream,
}
}
std::string csv_datasource::name()
const char * csv_datasource::name()
{
return "csv";
}

View file

@ -35,7 +35,7 @@ public:
csv_datasource(mapnik::parameters const& params, bool bind=true);
virtual ~csv_datasource ();
mapnik::datasource::datasource_t type() const;
static std::string name();
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;

View file

@ -200,7 +200,7 @@ datasource::datasource_t gdal_datasource::type() const
return datasource::Raster;
}
std::string gdal_datasource::name()
const char * gdal_datasource::name()
{
return "gdal";
}

View file

@ -38,7 +38,7 @@ public:
gdal_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~gdal_datasource();
mapnik::datasource::datasource_t type() const;
static std::string name();
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;

View file

@ -106,11 +106,9 @@ void geojson_datasource::bind() const
geojson_datasource::~geojson_datasource() { }
std::string const geojson_datasource::name_="geojson";
std::string geojson_datasource::name()
const char * geojson_datasource::name()
{
return name_;
return "geojson";
}
boost::optional<mapnik::datasource::geometry_t> geojson_datasource::get_geometry_type() const

View file

@ -44,7 +44,7 @@ public:
geojson_datasource(mapnik::parameters const& params, bool bind=true);
virtual ~geojson_datasource ();
mapnik::datasource::datasource_t type() const;
static std::string name();
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;
@ -52,8 +52,7 @@ public:
std::map<std::string, mapnik::parameters> get_statistics() const;
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
void bind() const;
private:
static const std::string name_;
private:
mapnik::datasource::datasource_t type_;
mutable std::map<std::string, mapnik::parameters> statistics_;
mutable mapnik::layer_descriptor desc_;

View file

@ -226,7 +226,7 @@ void geos_datasource::bind() const
is_bound_ = true;
}
std::string geos_datasource::name()
const char * geos_datasource::name()
{
return "geos";
}

View file

@ -39,7 +39,7 @@ public:
geos_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~geos_datasource ();
mapnik::datasource::datasource_t type() const;
static std::string name();
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;

View file

@ -117,10 +117,10 @@ feature_ptr geos_featureset::next()
{
feature_ptr feature(feature_factory::create(ctx_,identifier_));
geometry_utils::from_wkb(feature->paths(),
if (geometry_utils::from_wkb(feature->paths(),
wkb.data(),
wkb.size());
if (field_ != "")
wkb.size())
&& field_ != "")
{
feature->put(field_name_, tr_->transcode(field_.c_str()));
}

View file

@ -122,7 +122,7 @@ kismet_datasource::~kismet_datasource()
{
}
std::string kismet_datasource::name()
const char * kismet_datasource::name()
{
return "kismet";
}

View file

@ -46,7 +46,7 @@ public:
kismet_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~kismet_datasource ();
datasource::datasource_t type() const;
static std::string name();
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;

View file

@ -49,7 +49,6 @@ public:
private:
std::list<kismet_network_data> const& knd_list_;
boost::scoped_ptr<mapnik::transcoder> tr_;
mapnik::wkbFormat format_;
int feature_id_;
std::list<kismet_network_data>::const_iterator knd_list_it;
mapnik::projection source_;

View file

@ -352,7 +352,7 @@ void occi_datasource::bind() const
is_bound_ = true;
}
std::string occi_datasource::name()
const char * occi_datasource::name()
{
return "occi";
}

View file

@ -41,7 +41,7 @@ public:
occi_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~occi_datasource ();
mapnik::datasource::datasource_t type() const;
static std::string name();
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;

View file

@ -333,7 +333,7 @@ void ogr_datasource::bind() const
is_bound_ = true;
}
std::string ogr_datasource::name()
const char * ogr_datasource::name()
{
return "ogr";
}
@ -502,7 +502,6 @@ featureset_ptr ogr_datasource::features(query const& q) const
filter_in_box filter(q.get_bbox());
return featureset_ptr(new ogr_index_featureset<filter_in_box>(ctx,
*dataset_,
*layer,
filter,
index_name_,
@ -510,8 +509,7 @@ featureset_ptr ogr_datasource::features(query const& q) const
}
else
{
return featureset_ptr(new ogr_featureset (ctx,
*dataset_,
return featureset_ptr(new ogr_featureset(ctx,
*layer,
q.get_bbox(),
desc_.get_encoding()));
@ -546,7 +544,6 @@ featureset_ptr ogr_datasource::features_at_point(coord2d const& pt) const
filter_at_point filter(pt);
return featureset_ptr(new ogr_index_featureset<filter_at_point> (ctx,
*dataset_,
*layer,
filter,
index_name_,
@ -559,7 +556,6 @@ featureset_ptr ogr_datasource::features_at_point(coord2d const& pt) const
point.setY (pt.y);
return featureset_ptr(new ogr_featureset (ctx,
*dataset_,
*layer,
point,
desc_.get_encoding()));

View file

@ -42,7 +42,7 @@ public:
ogr_datasource(mapnik::parameters const& params, bool bind=true);
virtual ~ogr_datasource ();
mapnik::datasource::datasource_t type() const;
static std::string name();
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;

View file

@ -48,12 +48,10 @@ using mapnik::feature_factory;
ogr_featureset::ogr_featureset(mapnik::context_ptr const & ctx,
OGRDataSource & dataset,
OGRLayer & layer,
OGRGeometry & extent,
std::string const& encoding)
: ctx_(ctx),
dataset_(dataset),
layer_(layer),
layerdef_(layer.GetLayerDefn()),
tr_(new transcoder(encoding)),
@ -65,12 +63,10 @@ ogr_featureset::ogr_featureset(mapnik::context_ptr const & ctx,
}
ogr_featureset::ogr_featureset(mapnik::context_ptr const& ctx,
OGRDataSource & dataset,
OGRLayer & layer,
mapnik::box2d<double> const& extent,
std::string const& encoding)
: ctx_(ctx),
dataset_(dataset),
layer_(layer),
layerdef_(layer.GetLayerDefn()),
tr_(new transcoder(encoding)),

View file

@ -38,29 +38,24 @@ class ogr_featureset : public mapnik::Featureset
{
public:
ogr_featureset(mapnik::context_ptr const& ctx,
OGRDataSource & dataset,
OGRLayer & layer,
OGRGeometry & extent,
std::string const& encoding);
ogr_featureset(mapnik::context_ptr const& ctx,
OGRDataSource & dataset,
OGRLayer & layer,
mapnik::box2d<double> const& extent,
std::string const& encoding);
virtual ~ogr_featureset();
mapnik::feature_ptr next();
private:
mapnik::context_ptr ctx_;
OGRDataSource& dataset_;
OGRLayer& layer_;
OGRFeatureDefn* layerdef_;
boost::scoped_ptr<mapnik::transcoder> tr_;
const char* fidcolumn_;
mutable int count_;
};
#endif // OGR_FEATURESET_HPP

View file

@ -53,13 +53,11 @@ using mapnik::feature_factory;
template <typename filterT>
ogr_index_featureset<filterT>::ogr_index_featureset(mapnik::context_ptr const & ctx,
OGRDataSource & dataset,
OGRLayer & layer,
filterT const& filter,
std::string const& index_file,
std::string const& encoding)
: ctx_(ctx),
dataset_(dataset),
layer_(layer),
layerdef_(layer.GetLayerDefn()),
filter_(filter),

View file

@ -33,7 +33,6 @@ class ogr_index_featureset : public mapnik::Featureset
{
public:
ogr_index_featureset(mapnik::context_ptr const& ctx,
OGRDataSource& dataset,
OGRLayer& layer,
filterT const& filter,
std::string const& index_file,
@ -41,10 +40,8 @@ public:
virtual ~ogr_index_featureset();
mapnik::feature_ptr next();
private:
mapnik::context_ptr ctx_;
OGRDataSource& dataset_;
OGRLayer& layer_;
OGRFeatureDefn* layerdef_;
filterT filter_;

View file

@ -22,6 +22,8 @@
#include "basiccurl.h"
#include <iostream>
CURL_LOAD_DATA* grab_http_response(const char* url)
{
CURL_LOAD_DATA* data;
@ -39,7 +41,6 @@ CURL_LOAD_DATA* grab_http_response(const char* url)
CURL_LOAD_DATA* do_grab(CURL* curl,const char* url)
{
CURLcode res;
CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)malloc(sizeof(CURL_LOAD_DATA));
data->data = NULL;
data->nbytes = 0;
@ -48,7 +49,10 @@ CURL_LOAD_DATA* do_grab(CURL* curl,const char* url)
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);
res = curl_easy_perform(curl);
CURLcode res = curl_easy_perform(curl);
if (res !=0) {
std::clog << "error grabbing data\n";
}
return data;
}

View file

@ -130,7 +130,7 @@ osm_datasource::~osm_datasource()
//delete osm_data_;
}
std::string osm_datasource::name()
const char * osm_datasource::name()
{
return "osm";
}

View file

@ -43,7 +43,7 @@ public:
osm_datasource(const parameters& params, bool bind = true);
virtual ~osm_datasource();
mapnik::datasource::datasource_t type() const;
static std::string name();
static const char * name();
featureset_ptr features(const query& q) const;
featureset_ptr features_at_point(coord2d const& pt) const;
box2d<double> envelope() const;

View file

@ -313,7 +313,7 @@ void postgis_datasource::bind() const
{
srid_ = -1;
MAPNIK_LOG_DEBUG(postgis) << "postgis_datasource: Table " << table_ << " is using SRID=-1";
MAPNIK_LOG_DEBUG(postgis) << "postgis_datasource: Table " << table_ << " is using SRID=" << srid_;
}
// At this point the geometry_field may still not be known
@ -439,7 +439,7 @@ postgis_datasource::~postgis_datasource()
}
}
std::string postgis_datasource::name()
const char * postgis_datasource::name()
{
return "postgis";
}

View file

@ -51,7 +51,7 @@ public:
postgis_datasource(const parameters &params, bool bind=true);
~postgis_datasource();
mapnik::datasource::datasource_t type() const;
static std::string name();
static const char * name();
featureset_ptr features(const query& q) const;
featureset_ptr features_at_point(coord2d const& pt) const;
mapnik::box2d<double> envelope() const;

View file

@ -62,7 +62,7 @@ postgis_featureset::postgis_featureset(boost::shared_ptr<IResultSet> const& rs,
feature_ptr postgis_featureset::next()
{
if (rs_->next())
while (rs_->next())
{
// new feature
unsigned pos = 1;
@ -107,10 +107,12 @@ feature_ptr postgis_featureset::next()
// parse geometry
int size = rs_->getFieldLength(0);
const char *data = rs_->getValue(0);
geometry_utils::from_wkb(feature->paths(), data, size);
if (!geometry_utils::from_wkb(feature->paths(), data, size))
continue;
totalGeomSize_ += size;
int num_attrs = ctx_->size() + 1;
unsigned num_attrs = ctx_->size() + 1;
for (; pos < num_attrs; ++pos)
{
std::string name = rs_->getFieldName(pos);
@ -207,11 +209,7 @@ feature_ptr postgis_featureset::next()
}
return feature;
}
else
{
rs_->close();
return feature_ptr();
}
return feature_ptr();
}

View file

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

View file

@ -159,7 +159,7 @@ mapnik::datasource::datasource_t raster_datasource::type() const
return datasource::Raster;
}
std::string raster_datasource::name()
const char * raster_datasource::name()
{
return "raster";
}

View file

@ -34,7 +34,7 @@ public:
raster_datasource(const mapnik::parameters& params, bool bind=true);
virtual ~raster_datasource();
datasource::datasource_t type() const;
static std::string name();
static const char * name();
mapnik::featureset_ptr features(const mapnik::query& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;

View file

@ -166,7 +166,7 @@ rasterlite_datasource::~rasterlite_datasource()
{
}
std::string rasterlite_datasource::name()
const char * rasterlite_datasource::name()
{
return "rasterlite";
}

View file

@ -37,7 +37,7 @@ public:
rasterlite_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~rasterlite_datasource ();
mapnik::datasource::datasource_t type() const;
static std::string name();
static const char * name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;

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