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

View file

@ -33,6 +33,8 @@ except:
HAS_DISTUTILS = False HAS_DISTUTILS = False
py3 = None
# local file to hold custom user configuration variables # local file to hold custom user configuration variables
# Todo check timestamp, reload if changed? # Todo check timestamp, reload if changed?
SCONS_LOCAL_CONFIG = 'config.py' SCONS_LOCAL_CONFIG = 'config.py'
@ -85,7 +87,7 @@ pretty_dep_names = {
# Core plugin build configuration # Core plugin build configuration
# opts.AddVariables still hardcoded however... # opts.AddVariables still hardcoded however...
PLUGINS = { # plugins with external dependencies 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'}, '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++'}, '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++'}, '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 #### #### SCons build options and initial setup ####
env = Environment(ENV=os.environ) env = Environment(ENV=os.environ)
env.Decider('MD5-timestamp')
env.SourceCode(".", None)
def color_print(color,text,newline=True): def color_print(color,text,newline=True):
# 1 - red # 1 - red
@ -235,8 +239,6 @@ def sort_paths(items,priority):
if platform.dist()[0] in ('Ubuntu','debian'): if platform.dist()[0] in ('Ubuntu','debian'):
LIBDIR_SCHEMA='lib' LIBDIR_SCHEMA='lib'
elif platform.uname()[4] == 'x86_64' and platform.system() == 'Linux':
LIBDIR_SCHEMA='lib64'
elif platform.uname()[4] == 'ppc64': elif platform.uname()[4] == 'ppc64':
LIBDIR_SCHEMA='lib64' LIBDIR_SCHEMA='lib64'
else: else:
@ -302,7 +304,7 @@ opts.AddVariables(
('BOOST_TOOLKIT','Specify boost toolkit, e.g., gcc41.','',False), ('BOOST_TOOLKIT','Specify boost toolkit, e.g., gcc41.','',False),
('BOOST_ABI', 'Specify boost ABI, e.g., d.','',False), ('BOOST_ABI', 'Specify boost ABI, e.g., d.','',False),
('BOOST_VERSION','Specify boost version, e.g., 1_35.','',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 # Variables for required dependencies
('FREETYPE_CONFIG', 'The path to the freetype-config executable.', 'freetype-config'), ('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) color_print(1,"SCons CONFIG not found: '%s'" % conf)
# Recreate the base environment using modified `opts` # Recreate the base environment using modified `opts`
env = Environment(ENV=os.environ,options=opts) env = Environment(ENV=os.environ,options=opts)
env.Decider('MD5-timestamp')
env.SourceCode(".", None)
env['USE_CONFIG'] = True env['USE_CONFIG'] = True
else: else:
color_print(4,'SCons USE_CONFIG specified as false, will not inherit variables python config file...') 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 # if the user is not setting custom boost configuration
# enforce boost version greater than or equal to BOOST_MIN_VERSION # enforce boost version greater than or equal to BOOST_MIN_VERSION
if not conf.CheckBoost(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) color_print(1,'Boost version %s or greater is required' % BOOST_MIN_VERSION)
if not env['BOOST_VERSION']: if not env['BOOST_VERSION']:
env['MISSING_DEPS'].append('boost version >=%s' % BOOST_MIN_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') color_print(4,'Not building with cairo support, pass CAIRO=True to enable')
if 'python' in env['BINDINGS']: if 'python' in env['BINDINGS']:
# checklibwithheader does not work for boost_python since we can't feed it if not os.access(env['PYTHON'], os.X_OK):
# multiple header files, so we fall back on a simple check for boost_python headers 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++'): if not conf.CheckHeader(header='boost/python/detail/config.hpp',language='C++'):
color_print(1,'Could not find required header files for boost python') color_print(1,'Could not find required header files for boost python')
env['MISSING_DEPS'].append('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 env['CAIRO']:
if conf.CheckPKGConfig('0.15.0') and conf.CheckPKG('pycairo'): if conf.CheckPKGConfig('0.15.0') and conf.CheckPKG('pycairo'):
env['HAS_PYCAIRO'] = True env['HAS_PYCAIRO'] = True
@ -1459,68 +1526,13 @@ if not preconfigured:
if env['DEBUG']: if env['DEBUG']:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags) env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags)
else: else:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags)) env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -fno-strict-aliasing -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags))
if env['DEBUG_UNDEFINED']: if env['DEBUG_UNDEFINED']:
env.Append(CXXFLAGS = '-fcatch-undefined-behavior -ftrapv -fwrapv') env.Append(CXXFLAGS = '-fcatch-undefined-behavior -ftrapv -fwrapv')
if 'python' in env['BINDINGS']: 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('.') majver, minver = env['PYTHON_VERSION'].split('.')
# we don't want the includes it in the main environment... # we don't want the includes it in the main environment...
# as they are later set in the python build.py # as they are later set in the python build.py
# ugly hack needed until we have env specific conf # 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") color_print(1,"Python version 2.2 or greater required")
Exit(1) 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,'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 %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'])) 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... # But let's also cache implicit deps...
EnsureSConsVersion(0,98) EnsureSConsVersion(0,98)
SetOption('implicit_cache', 1) SetOption('implicit_cache', 1)
env.Decider('MD5-timestamp')
SetOption('max_drift', 1) SetOption('max_drift', 1)
else: 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 = 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') target_path_deprecated = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')
libraries = ['mapnik'] libraries = ['mapnik',env['BOOST_PYTHON_LIB']]
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'])
# TODO - do solaris/fedora need direct linking too? # TODO - do solaris/fedora need direct linking too?
if env['PLATFORM'] == 'Darwin': 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"); 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) 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(); 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) void set_pixel(mapnik::image_32 & im, unsigned x, unsigned y, mapnik::color const& c)
{ {
im.setPixel(x, y, c.rgba()); im.setPixel(x, y, c.rgba());
@ -216,6 +228,7 @@ void export_image()
.def("premultiply",&image_32::premultiply) .def("premultiply",&image_32::premultiply)
.def("demultiply",&image_32::demultiply) .def("demultiply",&image_32::demultiply)
.def("set_pixel",&set_pixel) .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 //TODO(haoyu) The method name 'tostring' might be confusing since they actually return bytes in Python 3
.def("tostring",&tostring1) .def("tostring",&tostring1)

View file

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

View file

@ -37,6 +37,7 @@ void export_palette();
void export_image(); void export_image();
void export_image_view(); void export_image_view();
void export_gamma_method(); void export_gamma_method();
void export_scaling_method();
void export_grid(); void export_grid();
void export_grid_view(); void export_grid_view();
void export_map(); void export_map();
@ -88,6 +89,15 @@ void export_logger();
#include "mapnik_value_converter.hpp" #include "mapnik_value_converter.hpp"
#include "mapnik_threads.hpp" #include "mapnik_threads.hpp"
#include "python_optional.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) #if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
#include <pycairo.h> #include <pycairo.h>
@ -150,12 +160,13 @@ void render_layer2(const mapnik::Map& map,
void render3(const mapnik::Map& map, void render3(const mapnik::Map& map,
PycairoSurface* surface, PycairoSurface* surface,
double scale_factor = 1.0,
unsigned offset_x = 0, unsigned offset_x = 0,
unsigned offset_y = 0) unsigned offset_y = 0)
{ {
python_unblock_auto_block b; python_unblock_auto_block b;
Cairo::RefPtr<Cairo::Surface> s(new Cairo::Surface(surface->surface)); 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(); ren.apply();
} }
@ -169,12 +180,13 @@ void render4(const mapnik::Map& map, PycairoSurface* surface)
void render5(const mapnik::Map& map, void render5(const mapnik::Map& map,
PycairoContext* context, PycairoContext* context,
double scale_factor = 1.0,
unsigned offset_x = 0, unsigned offset_x = 0,
unsigned offset_y = 0) unsigned offset_y = 0)
{ {
python_unblock_auto_block b; python_unblock_auto_block b;
Cairo::RefPtr<Cairo::Context> c(new Cairo::Context(context->ctx)); 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(); 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 (format == "pdf" || format == "svg" || format =="ps" || format == "ARGB32" || format == "RGB24")
{ {
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
mapnik::save_to_cairo_file(map,filename,format); mapnik::save_to_cairo_file(map,filename,format,1.0);
#else #else
throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format); throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format);
#endif #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 (format == "pdf" || format == "svg" || format =="ps")
{ {
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
mapnik::save_to_cairo_file(map,filename,format); mapnik::save_to_cairo_file(map,filename,format,1.0);
#else #else
throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format); throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format);
#endif #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 (format == "pdf" || format == "svg" || format =="ps" || format == "ARGB32" || format == "RGB24")
{ {
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
mapnik::save_to_cairo_file(map,filename,format); mapnik::save_to_cairo_file(map,filename,format,scale_factor);
#else #else
throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format); throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format);
#endif #endif
@ -360,6 +372,7 @@ BOOST_PYTHON_MODULE(_mapnik)
export_image(); export_image();
export_image_view(); export_image_view();
export_gamma_method(); export_gamma_method();
export_scaling_method();
export_grid(); export_grid();
export_grid_view(); export_grid_view();
export_expression(); export_expression();
@ -389,6 +402,15 @@ BOOST_PYTHON_MODULE(_mapnik)
export_label_collision_detector(); export_label_collision_detector();
export_logger(); 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, def("render_grid",&render_grid,
( arg("map"), ( arg("map"),
arg("layer"), arg("layer"),

View file

@ -30,6 +30,8 @@
using mapnik::query; using mapnik::query;
using mapnik::box2d; using mapnik::box2d;
namespace python = boost::python;
struct query_pickle_suite : boost::python::pickle_suite struct query_pickle_suite : boost::python::pickle_suite
{ {
static boost::python::tuple 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() void export_query()
{ {
using namespace boost::python; using namespace boost::python;
to_python_converter<query::resolution_type, resolution_to_tuple> ();
class_<query>("Query", "a spatial query data object", class_<query>("Query", "a spatial query data object",
init<box2d<double>,query::resolution_type const&,double>() ) init<box2d<double>,query::resolution_type const&,double>() )
.def(init<box2d<double> >()) .def(init<box2d<double> >())

View file

@ -25,6 +25,7 @@
// mapnik // mapnik
#include <mapnik/raster_symbolizer.hpp> #include <mapnik/raster_symbolizer.hpp>
#include <mapnik/image_scaling.hpp>
using mapnik::raster_symbolizer; using mapnik::raster_symbolizer;
@ -39,13 +40,13 @@ struct raster_symbolizer_pickle_suite : boost::python::pickle_suite
*/ */
static boost::python::tuple 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 static void
setstate (raster_symbolizer& r, boost::python::tuple state) setstate (raster_symbolizer & r, boost::python::tuple state)
{ {
using namespace boost::python; using namespace boost::python;
if (len(state) != 5) 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_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_opacity(extract<float>(state[2]));
r.set_filter_factor(extract<float>(state[3])); r.set_filter_factor(extract<float>(state[3]));
r.set_mesh_size(extract<unsigned>(state[4])); r.set_mesh_size(extract<unsigned>(state[4]));
@ -91,17 +92,15 @@ void export_raster_symbolizer()
) )
.add_property("scaling", .add_property("scaling",
make_function(&raster_symbolizer::get_scaling,return_value_policy<copy_const_reference>()), &raster_symbolizer::get_scaling_method,
&raster_symbolizer::set_scaling, &raster_symbolizer::set_scaling_method,
"Get/Set scaling algorithm.\n" "Get/Set scaling algorithm.\n"
"Possible values are:\n"
"fast, bilinear, and bilinear8\n"
"\n" "\n"
"Usage:\n" "Usage:\n"
"\n" "\n"
">>> from mapnik import RasterSymbolizer\n" ">>> from mapnik import RasterSymbolizer\n"
">>> r = RasterSymbolizer()\n" ">>> r = RasterSymbolizer()\n"
">>> r.scaling = 'bilinear8'\n" ">>> r.scaling = 'mapnik.scaling_method.GAUSSIAN'\n"
) )
.add_property("opacity", .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 // boost
#include <boost/python.hpp> #include <boost/python.hpp>
#include <boost/scoped_array.hpp>
#include <boost/foreach.hpp>
// mapnik // mapnik
#include <mapnik/debug.hpp> #include <mapnik/map.hpp>
#include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/grid/grid_util.hpp>
#include <mapnik/grid/grid_view.hpp>
#include <mapnik/value_error.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_kv_iterator.hpp>
#include "mapnik_value_converter.hpp"
namespace mapnik { namespace mapnik {
template <typename T> template <typename T>
static void grid2utf(T const& grid_type, void grid2utf(T const& grid_type,
boost::python::list& l, boost::python::list& l,
std::vector<grid::lookup_type>& key_order) std::vector<typename T::lookup_type>& key_order);
{
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))));
}
}
template <typename T> template <typename T>
static void grid2utf(T const& grid_type, void grid2utf(T const& grid_type,
boost::python::list& l, boost::python::list& l,
std::vector<typename T::lookup_type>& key_order, std::vector<typename T::lookup_type>& key_order,
unsigned int resolution) unsigned int resolution);
{
//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))));
}
}
template <typename T> template <typename T>
static void grid2utf2(T const& grid_type, void grid2utf2(T const& grid_type,
boost::python::list& l, boost::python::list& l,
std::vector<typename T::lookup_type>& key_order, std::vector<typename T::lookup_type>& key_order,
unsigned int resolution) unsigned int resolution);
{
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))));
}
}
template <typename T> template <typename T>
static void write_features(T const& grid_type, void write_features(T const& grid_type,
boost::python::dict& feature_data, boost::python::dict& feature_data,
std::vector<typename T::lookup_type> const& key_order) std::vector<typename T::lookup_type> const& key_order);
{
std::string const& key = grid_type.get_key();
std::set<std::string> const& attributes = grid_type.property_names();
typename T::feature_type const& g_features = grid_type.get_grid_features();
typename T::feature_type::const_iterator feat_itr = g_features.begin();
typename T::feature_type::const_iterator feat_end = g_features.end();
bool include_key = (attributes.find(key) != attributes.end());
for (; feat_itr != feat_end; ++feat_itr)
{
mapnik::feature_ptr feature = feat_itr->second;
boost::optional<std::string> join_value;
if (key == grid_type.key_name())
{
join_value = feat_itr->first;
}
else if (feature->has_key(key))
{
join_value = feature->get(key).to_string();
}
if (join_value)
{
// only serialize features visible in the grid
if(std::find(key_order.begin(), key_order.end(), *join_value) != key_order.end()) {
boost::python::dict feat;
bool found = false;
if (key == grid_type.key_name())
{
// drop key unless requested
if (include_key) {
found = true;
//TODO - add __id__ as data key?
//feat[key] = *join_value;
}
}
feature_kv_iterator itr = feature->begin();
feature_kv_iterator end = feature->end();
for ( ;itr!=end; ++itr)
{
std::string const& key_name = boost::get<0>(*itr);
if (key_name == key) {
// drop key unless requested
if (include_key) {
found = true;
feat[key_name] = boost::get<1>(*itr);
}
}
else if ( (attributes.find(key_name) != attributes.end()) )
{
found = true;
feat[key_name] = boost::get<1>(*itr);
}
}
if (found)
{
feature_data[feat_itr->first] = feat;
}
}
}
else
{
MAPNIK_LOG_DEBUG(bindings) << "write_features: Should not get here: key " << key << " not found in grid feature properties";
}
}
}
template <typename T> template <typename T>
static void grid_encode_utf(T const& grid_type, void grid_encode_utf(T const& grid_type,
boost::python::dict & json, boost::python::dict & json,
bool add_features, bool add_features,
unsigned int resolution) unsigned int resolution);
{
// convert buffer to utf and gather key order
boost::python::list l;
std::vector<typename T::lookup_type> key_order;
if (resolution != 1) {
// resample on the fly - faster, less accurate
mapnik::grid2utf<T>(grid_type,l,key_order,resolution);
// resample first - slower, more accurate
//mapnik::grid2utf2<T>(grid_type,l,key_order,resolution);
}
else
{
mapnik::grid2utf<T>(grid_type,l,key_order);
}
// convert key order to proper python list
boost::python::list keys_a;
BOOST_FOREACH ( typename T::lookup_type const& key_id, key_order )
{
keys_a.append(key_id);
}
// gather feature data
boost::python::dict feature_data;
if (add_features) {
mapnik::write_features<T>(grid_type,feature_data,key_order);
}
json["grid"] = l;
json["keys"] = keys_a;
json["data"] = feature_data;
}
template <typename T> template <typename T>
static boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution) boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution);
{
if (format == "utf") {
boost::python::dict json;
grid_encode_utf<T>(grid,json,add_features,resolution);
return json;
}
else
{
std::stringstream s;
s << "'utf' is currently the only supported encoding format.";
throw mapnik::value_error(s.str());
}
}
/* new approach: key comes from grid object /* new approach: key comes from grid object
* grid size should be same as the map * grid size should be same as the map
* encoding, resizing handled as method on grid object * encoding, resizing handled as method on grid object
* whether features are dumped is determined by argument not 'fields' * whether features are dumped is determined by argument not 'fields'
*/ */
static void render_layer_for_grid(const mapnik::Map& map, void render_layer_for_grid(const mapnik::Map& map,
mapnik::grid& grid, mapnik::grid& grid,
unsigned layer_idx, // TODO - layer by name or index unsigned layer_idx, // TODO - layer by name or index
boost::python::list const& fields) boost::python::list const& fields);
{
std::vector<mapnik::layer> const& layers = map.layers();
std::size_t layer_num = layers.size();
if (layer_idx >= layer_num) {
std::ostringstream s;
s << "Zero-based layer index '" << layer_idx << "' not valid, only '"
<< layer_num << "' layers are in map\n";
throw std::runtime_error(s.str());
}
// convert python list to std::vector
boost::python::ssize_t num_fields = boost::python::len(fields);
for(boost::python::ssize_t i=0; i<num_fields; i++) {
boost::python::extract<std::string> name(fields[i]);
if (name.check()) {
grid.add_property_name(name());
}
else
{
std::stringstream s;
s << "list of field names must be strings";
throw mapnik::value_error(s.str());
}
}
// copy property names
std::set<std::string> attributes = grid.property_names();
std::string const& key = grid.get_key();
// if key is special __id__ keyword
if (key == grid.key_name())
{
// TODO - should feature.id() be a first class attribute?
// if __id__ is requested to be dumped out
// remove it so that datasource queries will not break
if (attributes.find(key) != attributes.end())
{
attributes.erase(key);
}
}
// if key is not the special __id__ keyword
else if (attributes.find(key) == attributes.end())
{
// them make sure the datasource query includes this field
attributes.insert(key);
}
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
mapnik::layer const& layer = layers[layer_idx];
ren.apply(layer,attributes);
}
/* old, original impl - to be removed after further testing /* old, original impl - to be removed after further testing
* grid object is created on the fly at potentially reduced size * grid object is created on the fly at potentially reduced size
*/ */
static boost::python::dict render_grid(const mapnik::Map& map, boost::python::dict render_grid(const mapnik::Map& map,
unsigned layer_idx, // layer unsigned layer_idx, // layer
std::string const& key, // key_name std::string const& key, // key_name
unsigned int step, // resolution unsigned int step, // resolution
boost::python::list const& fields) boost::python::list const& fields);
{
std::vector<mapnik::layer> const& layers = map.layers();
std::size_t layer_num = layers.size();
if (layer_idx >= layer_num) {
std::ostringstream s;
s << "Zero-based layer index '" << layer_idx << "' not valid, only '"
<< layer_num << "' layers are in map\n";
throw std::runtime_error(s.str());
}
unsigned int grid_width = map.width()/step;
unsigned int grid_height = map.height()/step;
// TODO - no need to pass step here
mapnik::grid grid(grid_width,grid_height,key,step);
// convert python list to std::vector
boost::python::ssize_t num_fields = boost::python::len(fields);
for(boost::python::ssize_t i=0; i<num_fields; i++) {
boost::python::extract<std::string> name(fields[i]);
if (name.check()) {
grid.add_property_name(name());
}
else
{
std::stringstream s;
s << "list of field names must be strings";
throw mapnik::value_error(s.str());
}
}
// copy property names
std::set<std::string> attributes = grid.property_names();
// if key is special __id__ keyword
if (key == grid.key_name())
{
// TODO - should feature.id() be a first class attribute?
// if __id__ is requested to be dumped out
// remove it so that datasource queries will not break
if (attributes.find(key) != attributes.end())
{
attributes.erase(key);
}
}
// if key is not the special __id__ keyword
else if (attributes.find(key) == attributes.end())
{
// them make sure the datasource query includes this field
attributes.insert(key);
}
try
{
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
mapnik::layer const& layer = layers[layer_idx];
ren.apply(layer,attributes);
}
catch (...)
{
throw;
}
bool add_features = false;
if (num_fields > 0)
add_features = true;
// build dictionary and return to python
boost::python::dict json;
grid_encode_utf(grid,json,add_features,1);
return json;
}
} }
#endif // MAPNIK_PYTHON_BINDING_GRID_UTILS_INCLUDED #endif // MAPNIK_PYTHON_BINDING_GRID_UTILS_INCLUDED

2
configure vendored
View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,18 +1,11 @@
###################################################################### ######################################################################
# Mapnik viewer - Copyright (C) 2007 Artem Pavlenko # Mapnik viewer - Copyright (C) 2007 Artem Pavlenko
###################################################################### ######################################################################
CC = g++
TEMPLATE = app TEMPLATE = app
QMAKE_CXX = clang++
INCLUDEPATH += /usr/local/include/ QMAKE_CXXFLAGS += $$system(mapnik-config --cflags)
INCLUDEPATH += /usr/boost/include/ QMAKE_LFLAGS += $$system(mapnik-config --libs)
INCLUDEPATH += /usr/X11/include/ QMAKE_LFLAGS += $$system(mapnik-config --ldflags --dep-libs)
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
# Input # Input

View file

@ -25,6 +25,9 @@
// mapnik // mapnik
#include <mapnik/value.hpp> #include <mapnik/value.hpp>
#include <mapnik/geometry.hpp>
// boost
#include <boost/foreach.hpp>
// stl // stl
#include <string> #include <string>
@ -44,6 +47,24 @@ struct attribute
std::string const& name() const { return name_;} 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 #endif // MAPNIK_ATTRIBUTE_HPP

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -77,6 +77,11 @@ public:
return index; 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(); } size_type size() const { return mapping_.size(); }
const_iterator begin() const { return mapping_.begin();} const_iterator begin() const { return mapping_.begin();}
const_iterator end() const { return mapping_.end();} const_iterator end() const { return mapping_.end();}

View file

@ -365,7 +365,7 @@ struct text_renderer : private boost::noncopyable
stroker & s, stroker & s,
composite_mode_e comp_op = src_over, composite_mode_e comp_op = src_over,
double scale_factor=1.0); 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(pixel_position pos);
void render_id(int feature_id, pixel_position pos, double min_radius=1.0); void render_id(int feature_id, pixel_position pos, double min_radius=1.0);

View file

@ -32,13 +32,14 @@
// stl // stl
#include <cmath> #include <cmath>
#include <vector>
namespace mapnik namespace mapnik
{ {
template <typename T> template <typename T>
bool clip_test(T p,T q,double& tmin,double& tmax) bool clip_test(T p,T q,double& tmin,double& tmax)
{ {
double r; double r = 0;
bool result=true; bool result=true;
if (p<0.0) if (p<0.0)
{ {
@ -95,7 +96,8 @@ inline bool point_inside_path(double x,double y,Iter start,Iter end)
double x0=boost::get<0>(*start); double x0=boost::get<0>(*start);
double y0=boost::get<1>(*start); double y0=boost::get<1>(*start);
double x1,y1; double x1 = 0;
double y1 = 0;
while (++start!=end) while (++start!=end)
{ {
if ( boost::get<2>(*start) == SEG_MOVETO) if ( boost::get<2>(*start) == SEG_MOVETO)
@ -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 x0=boost::get<0>(*start);
double y0=boost::get<1>(*start); double y0=boost::get<1>(*start);
double x1,y1; double x1 = 0;
double y1 = 0;
while (++start != end) while (++start != end)
{ {
if ( boost::get<2>(*start) == SEG_MOVETO) if ( boost::get<2>(*start) == SEG_MOVETO)
@ -216,6 +219,226 @@ struct filter_at_point
return extent.contains(pt_); 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 #endif // MAPNIK_GEOM_UTIL_HPP

View file

@ -80,13 +80,18 @@ public:
return cont_; return cont_;
} }
size_type size() const
{
return cont_.size();
}
box2d<double> envelope() const box2d<double> envelope() const
{ {
box2d<double> result; box2d<double> result;
double x(0); double x = 0;
double y(0); double y = 0;
rewind(0); rewind(0);
for (unsigned i=0;i<num_points();++i) for (unsigned i=0;i<size();++i)
{ {
vertex(&x,&y); vertex(&x,&y);
if (i==0) if (i==0)
@ -101,225 +106,6 @@ public:
return result; 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) void push_vertex(coord_type x, coord_type y, CommandType c)
{ {
cont_.push_back(x,y,c); cont_.push_back(x,y,c);
@ -335,62 +121,20 @@ public:
push_vertex(x,y,SEG_MOVETO); push_vertex(x,y,SEG_MOVETO);
} }
unsigned num_points() const
{
return cont_.size();
}
unsigned vertex(double* x, double* y) const unsigned vertex(double* x, double* y) const
{ {
return cont_.get_vertex(itr_++,x,y); return cont_.get_vertex(itr_++,x,y);
} }
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 void rewind(unsigned ) const
{ {
itr_=0; 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; typedef geometry<double,vertex_vector> geometry_type;

View file

@ -58,7 +58,6 @@ public:
typedef std::string lookup_type; typedef std::string lookup_type;
// mapping between pixel id and key // mapping between pixel id and key
typedef std::map<value_type, lookup_type> feature_key_type; 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; typedef std::map<lookup_type, mapnik::feature_ptr> feature_type;
static const value_type base_mask; static const value_type base_mask;
@ -77,39 +76,9 @@ private:
public: public:
hit_grid(int width, int height, std::string const& key, unsigned int resolution) 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(const hit_grid<T>& rhs) hit_grid(hit_grid<T> const& 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() {}
@ -128,64 +97,7 @@ public:
return id_name_; return id_name_;
} }
inline void add_feature(mapnik::feature_impl & feature) 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_property_name(std::string const& name) inline void add_property_name(std::string const& name)
{ {
@ -197,27 +109,17 @@ public:
return names_; return names_;
} }
inline const feature_type& get_grid_features() const inline feature_type const& get_grid_features() const
{ {
return features_; return features_;
} }
inline feature_type& get_grid_features() inline feature_key_type const& get_feature_keys() const
{
return features_;
}
inline const feature_key_type& get_feature_keys() const
{ {
return f_keys_; return f_keys_;
} }
inline feature_key_type& get_feature_keys() inline std::string const& get_key() const
{
return f_keys_;
}
inline const std::string& get_key() const
{ {
return key_; return key_;
} }
@ -237,7 +139,7 @@ public:
resolution_ = res; resolution_ = res;
} }
inline const data_type& data() const inline data_type const& data() const
{ {
return data_; return data_;
} }
@ -247,7 +149,7 @@ public:
return data_; return data_;
} }
inline const T* raw_data() const inline T const * raw_data() const
{ {
return data_.getData(); return data_.getData();
} }
@ -257,7 +159,7 @@ public:
return data_.getData(); return data_.getData();
} }
inline const value_type* getRow(unsigned row) const inline value_type const * getRow(unsigned row) const
{ {
return data_.getRow(row); return data_.getRow(row);
} }

View file

@ -65,7 +65,7 @@ public:
void end_layer_processing(layer const& lay); void end_layer_processing(layer const& lay);
void start_style_processing(feature_type_style const& st) {} void start_style_processing(feature_type_style const& st) {}
void end_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, void process(point_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
@ -119,6 +119,7 @@ private:
face_manager<freetype_engine> font_manager_; face_manager<freetype_engine> font_manager_;
label_collision_detector4 detector_; label_collision_detector4 detector_;
boost::scoped_ptr<grid_rasterizer> ras_ptr; boost::scoped_ptr<grid_rasterizer> ras_ptr;
box2d<double> query_extent_;
}; };
} }

View file

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

View file

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

View file

@ -25,6 +25,9 @@
// mapnik // mapnik
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/geom_util.hpp>
// boost
#include <boost/foreach.hpp>
namespace mapnik { namespace mapnik {
class hit_test_filter class hit_test_filter
@ -35,12 +38,11 @@ public:
y_(y), y_(y),
tol_(tol) {} 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 (label::hit_test(geom, x_,y_,tol_))
if (geom.hit_test(x_,y_,tol_))
return true; return true;
} }
return false; 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<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> template <typename T1, typename T2>
MAPNIK_DECL void composite(T1 & dst, T2 & src, MAPNIK_DECL void composite(T1 & dst, T2 & src,

View file

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

View file

@ -23,7 +23,12 @@
#ifndef MAPNIK_IMAGE_FILTER_TYPES_HPP #ifndef MAPNIK_IMAGE_FILTER_TYPES_HPP
#define MAPNIK_IMAGE_FILTER_TYPES_HPP #define MAPNIK_IMAGE_FILTER_TYPES_HPP
// boost
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/karma.hpp>
// stl
#include <iostream>
namespace mapnik { namespace filter { namespace mapnik { namespace filter {
@ -37,18 +42,14 @@ struct x_gradient {};
struct y_gradient {}; struct y_gradient {};
struct invert {}; struct invert {};
struct agg_stack_blur struct agg_stack_blur
{ {
agg_stack_blur(unsigned rx_, unsigned ry_) agg_stack_blur(unsigned rx_, unsigned ry_)
: rx(rx_),ry(ry_) {} : rx(rx_),ry(ry_) {}
// an attempt to support older boost spirit (< 1.46)
agg_stack_blur()
: rx(1),ry(1) {}
unsigned rx; unsigned rx;
unsigned ry; unsigned ry;
}; };
typedef boost::variant<filter::blur, typedef boost::variant<filter::blur,
filter::gray, filter::gray,
filter::agg_stack_blur, filter::agg_stack_blur,
@ -60,6 +61,97 @@ typedef boost::variant<filter::blur,
filter::y_gradient, filter::y_gradient,
filter::invert> filter_type; 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 #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) #if defined(HAVE_CAIRO)
MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map, MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map,
std::string const& filename, std::string const& filename,
std::string const& type); std::string const& type,
double scale_factor=1.0);
#endif #endif
template <typename T> 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 //////////////////////////////////////////////// /////////// save_to_file ////////////////////////////////////////////////
class image_32; class image_32;

View file

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

View file

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

View file

@ -78,7 +78,7 @@ struct get_first
geometry_type::value_type const operator() (geometry_type const& geom) const geometry_type::value_type const operator() (geometry_type const& geom) const
{ {
geometry_type::value_type coord; 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; return coord;
} }
}; };

View file

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

View file

@ -41,14 +41,21 @@ class marker;
typedef boost::shared_ptr<marker> marker_ptr; typedef boost::shared_ptr<marker> marker_ptr;
struct MAPNIK_DECL marker_cache : class MAPNIK_DECL marker_cache :
public singleton <marker_cache, CreateStatic>, public singleton <marker_cache, CreateUsingNew>,
private boost::noncopyable private boost::noncopyable
{ {
friend class CreateUsingNew<marker_cache>;
friend class CreateStatic<marker_cache>; private:
static boost::unordered_map<std::string,marker_ptr> cache_; marker_cache();
static bool insert(std::string const& key, marker_ptr); ~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 boost::optional<marker_ptr> find(std::string const& key, bool update_cache = false);
static void clear(); 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 * converted to a positive value with similar magnitude, but
* choosen to optimize marker placement. 0 = no markers * 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. /** Start again at first marker.
* \note Returns the same list of markers only works when they were NOT added * \note Returns the same list of markers only works when they were NOT added
* to the detector. * to the detector.

View file

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

View file

@ -110,7 +110,7 @@ public:
virtual void add_box(box2d<double> const& box, Feature const& feature, virtual void add_box(box2d<double> const& box, Feature const& feature,
CoordTransform const& t, CoordTransform const& t,
metawriter_properties const& properties)=0; 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, box2d<double> const& extents,
Feature const& feature, Feature const& feature,
CoordTransform const& t, CoordTransform const& t,
@ -144,7 +144,11 @@ public:
*/ */
void set_size(int width, int height) { width_ = width; height_ = height; } void set_size(int width, int height) { width_ = width; height_ = height; }
/** Set Map object's srs. */ /** 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. */ /** Return the list of default properties. */
metawriter_properties const& get_default_properties() const { return dflt_properties_;} metawriter_properties const& get_default_properties() const { return dflt_properties_;}
protected: protected:

View file

@ -65,7 +65,7 @@ public:
virtual void add_box(box2d<double> const& box, Feature const& feature, virtual void add_box(box2d<double> const& box, Feature const& feature,
CoordTransform const& t, CoordTransform const& t,
metawriter_properties const& properties); 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, box2d<double> const& extents,
Feature const& feature, Feature const& feature,
CoordTransform const& t, CoordTransform const& t,

View file

@ -45,7 +45,7 @@ public:
virtual void add_box(box2d<double> const& box, Feature const& feature, virtual void add_box(box2d<double> const& box, Feature const& feature,
CoordTransform const& t, CoordTransform const& t,
metawriter_properties const& properties); 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, box2d<double> const& extents,
Feature const& feature, Feature const& feature,
CoordTransform const& t, CoordTransform const& t,

View file

@ -80,14 +80,10 @@ public:
/** Remove old placements. */ /** Remove old placements. */
void clear_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. std::vector<box2d<double> > & additional_boxes() { return additional_boxes_;}
* Used for finding line placements where multiple placements are returned. std::vector<box2d<double> > const& additional_boxes() const { return additional_boxes_;}
* Boxes are relative to starting point of current placement.
* Only used for point placements!
*/
std::vector<box2d<double> > additional_boxes;
void set_collect_extents(bool collect) { collect_extents_ = collect; } void set_collect_extents(bool collect) { collect_extents_ = collect; }
bool get_collect_extents() const { return collect_extents_; } bool get_collect_extents() const { return collect_extents_; }
@ -160,6 +156,13 @@ private:
box2d<double> extents_; box2d<double> extents_;
/** Collect a bounding box of all texts placed. */ /** Collect a bounding box of all texts placed. */
bool collect_extents_; 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 // mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/raster_colorizer.hpp> #include <mapnik/raster_colorizer.hpp>
#include <mapnik/symbolizer.hpp> #include <mapnik/symbolizer.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/image_scaling.hpp>
namespace mapnik namespace mapnik
{ {
@ -37,7 +40,7 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
raster_symbolizer() raster_symbolizer()
: symbolizer_base(), : symbolizer_base(),
mode_("normal"), mode_("normal"),
scaling_("fast"), scaling_(SCALING_NEAR),
opacity_(1.0), opacity_(1.0),
colorizer_(), colorizer_(),
filter_factor_(-1), filter_factor_(-1),
@ -45,26 +48,40 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
raster_symbolizer(const raster_symbolizer &rhs) raster_symbolizer(const raster_symbolizer &rhs)
: symbolizer_base(rhs), : symbolizer_base(rhs),
mode_(rhs.get_mode()), mode_(rhs.mode_),
scaling_(rhs.get_scaling()), scaling_(rhs.scaling_),
opacity_(rhs.get_opacity()), opacity_(rhs.opacity_),
colorizer_(rhs.colorizer_), colorizer_(rhs.colorizer_),
filter_factor_(rhs.filter_factor_), filter_factor_(rhs.filter_factor_),
mesh_size_(rhs.mesh_size_) {} mesh_size_(rhs.mesh_size_) {}
std::string const& get_mode() const 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_; return mode_;
} }
void set_mode(std::string const& 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; 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_; return scaling_;
} }
void set_scaling(std::string const& scaling) void set_scaling_method(scaling_method_e scaling)
{ {
scaling_ = scaling; scaling_ = scaling;
} }
@ -99,13 +116,9 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
// respect explicitly specified values // respect explicitly specified values
return filter_factor_; return filter_factor_;
} else { } 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; double ff = 1.0;
switch(scaling) switch(scaling_)
{ {
case SCALING_NEAR: case SCALING_NEAR:
ff = 1.0; 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. // TODO potentially some of these algorithms would use filter_factor >2.0.
// Contributions welcome from someone who knows more about them. // Contributions welcome from someone who knows more about them.
case SCALING_BILINEAR: case SCALING_BILINEAR:
case SCALING_BILINEAR8:
case SCALING_BICUBIC: case SCALING_BICUBIC:
case SCALING_SPLINE16: case SCALING_SPLINE16:
case SCALING_SPLINE36: case SCALING_SPLINE36:
@ -147,7 +161,7 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
private: private:
std::string mode_; std::string mode_;
std::string scaling_; scaling_method_e scaling_;
float opacity_; float opacity_;
raster_colorizer_ptr colorizer_; raster_colorizer_ptr colorizer_;
double filter_factor_; double filter_factor_;

View file

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

View file

@ -193,7 +193,7 @@ public:
} }
// Attribute setting functions. // Attribute setting functions.
void fill(const agg::rgba8& f) void fill(agg::rgba8 const& f)
{ {
path_attributes& attr = cur_attr(); path_attributes& attr = cur_attr();
double a = attr.fill_color.opacity(); double a = attr.fill_color.opacity();
@ -202,19 +202,19 @@ public:
attr.fill_flag = true; attr.fill_flag = true;
} }
void add_fill_gradient(mapnik::gradient& grad) void add_fill_gradient(mapnik::gradient const& grad)
{ {
path_attributes& attr = cur_attr(); path_attributes& attr = cur_attr();
attr.fill_gradient = grad; attr.fill_gradient = grad;
} }
void add_stroke_gradient(mapnik::gradient& grad) void add_stroke_gradient(mapnik::gradient const& grad)
{ {
path_attributes& attr = cur_attr(); path_attributes& attr = cur_attr();
attr.stroke_gradient = grad; attr.stroke_gradient = grad;
} }
void stroke(const agg::rgba8& s) void stroke(agg::rgba8 const& s)
{ {
path_attributes& attr = cur_attr(); path_attributes& attr = cur_attr();
double a = attr.stroke_color.opacity(); double a = attr.stroke_color.opacity();
@ -264,16 +264,17 @@ public:
void fill_opacity(double op) void fill_opacity(double op)
{ {
cur_attr().fill_color.opacity(op); cur_attr().fill_opacity = op;
} }
void stroke_opacity(double op) void stroke_opacity(double op)
{ {
cur_attr().stroke_color.opacity(op); cur_attr().stroke_opacity = op;
} }
void opacity(double 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) 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); explicit svg_parser(svg_converter_type & path);
~svg_parser(); ~svg_parser();
void parse(std::string const& filename); void parse(std::string const& filename);
void parse_from_string(std::string const& svg);
private: private:
bool parse_reader(xmlTextReaderPtr reader);
void process_node(xmlTextReaderPtr reader); void process_node(xmlTextReaderPtr reader);
void start_element(xmlTextReaderPtr reader); void start_element(xmlTextReaderPtr reader);
void end_element(xmlTextReaderPtr reader); void end_element(xmlTextReaderPtr reader);

View file

@ -47,9 +47,9 @@ public:
typedef path_adapter<VertexContainer> self_type; typedef path_adapter<VertexContainer> self_type;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
path_adapter(VertexContainer & vertices) : m_vertices(vertices), m_iterator(0) {} path_adapter(VertexContainer & vertices) : vertices_(vertices), iterator_(0) {}
//void remove_all() { m_vertices.remove_all(); m_iterator = 0; } //void remove_all() { vertices_.remove_all(); iterator_ = 0; }
//void free_all() { m_vertices.free_all(); m_iterator = 0; } //void free_all() { vertices_.free_all(); iterator_ = 0; }
// Make path functions // Make path functions
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -109,8 +109,8 @@ public:
// Accessors // Accessors
//-------------------------------------------------------------------- //--------------------------------------------------------------------
const container_type& vertices() const { return m_vertices; } const container_type& vertices() const { return vertices_; }
container_type& vertices() { return m_vertices; } container_type& vertices() { return vertices_; }
unsigned total_vertices() const; unsigned total_vertices() const;
@ -160,7 +160,7 @@ public:
vs.rewind(path_id); vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y))) 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(calc_distance(x, y, x0, y0) > vertex_dist_epsilon)
{ {
if(is_move_to(cmd)) cmd = path_cmd_line_to; if(is_move_to(cmd)) cmd = path_cmd_line_to;
m_vertices.add_vertex(x, y, cmd); vertices_.add_vertex(x, y, cmd);
} }
} }
else else
@ -198,12 +198,12 @@ public:
{ {
if(is_move_to(cmd)) cmd = path_cmd_line_to; 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))) 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) : unsigned(path_cmd_line_to) :
cmd); cmd);
} }
@ -218,16 +218,16 @@ public:
template<class Trans> template<class Trans>
void transform(const Trans& trans, unsigned path_id=0) 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++) for(; path_id < num_ver; path_id++)
{ {
double x, y; 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_stop(cmd)) break;
if(is_vertex(cmd)) if(is_vertex(cmd))
{ {
trans.transform(&x, &y); 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) void transform_all_paths(const Trans& trans)
{ {
unsigned idx; unsigned idx;
unsigned num_ver = m_vertices.total_vertices(); unsigned num_ver = vertices_.total_vertices();
for(idx = 0; idx < num_ver; idx++) for(idx = 0; idx < num_ver; idx++)
{ {
double x, y; double x, y;
if(is_vertex(m_vertices.vertex(idx, &x, &y))) if(is_vertex(vertices_.vertex(idx, &x, &y)))
{ {
trans.transform(&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); unsigned perceive_polygon_orientation(unsigned start, unsigned end);
void invert_polygon(unsigned start, unsigned end); void invert_polygon(unsigned start, unsigned end);
VertexContainer & m_vertices; VertexContainer & vertices_;
unsigned m_iterator; unsigned iterator_;
double start_x_;
double start_y_;
}; };
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
unsigned path_adapter<VC>::start_new_path() 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> template<class VC>
inline void path_adapter<VC>::rel_to_abs(double* x, double* y) const 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 x2;
double y2; double y2;
if(is_vertex(m_vertices.last_vertex(&x2, &y2))) if(is_vertex(vertices_.last_vertex(&x2, &y2))
{ || !is_stop(vertices_.last_command()))
*x += x2;
*y += y2;
}
else if (!is_stop(m_vertices.last_command()) &&
is_vertex(m_vertices.prev_vertex(&x2, &y2)))
{ {
*x += x2; *x += x2;
*y += y2; *y += y2;
@ -297,7 +294,9 @@ inline void path_adapter<VC>::rel_to_abs(double* x, double* y) const
template<class VC> template<class VC>
inline void path_adapter<VC>::move_to(double x, double y) 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) inline void path_adapter<VC>::move_rel(double dx, double dy)
{ {
rel_to_abs(&dx, &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> template<class VC>
inline void path_adapter<VC>::line_to(double x, double y) 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) inline void path_adapter<VC>::line_rel(double dx, double dy)
{ {
rel_to_abs(&dx, &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> template<class VC>
inline void path_adapter<VC>::hline_to(double x) 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; double dy = 0;
rel_to_abs(&dx, &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> template<class VC>
inline void path_adapter<VC>::vline_to(double y) 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; double dx = 0;
rel_to_abs(&dx, &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);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
@ -363,12 +362,12 @@ void path_adapter<VC>::arc_to(double rx, double ry,
bool sweep_flag, bool sweep_flag,
double x, double y) 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; const double epsilon = 1e-30;
double x0 = 0.0; double x0 = 0.0;
double y0 = 0.0; double y0 = 0.0;
m_vertices.last_vertex(&x0, &y0); vertices_.last_vertex(&x0, &y0);
rx = fabs(rx); rx = fabs(rx);
ry = fabs(ry); ry = fabs(ry);
@ -420,8 +419,8 @@ template<class VC>
void path_adapter<VC>::curve3(double x_ctrl, double y_ctrl, void path_adapter<VC>::curve3(double x_ctrl, double y_ctrl,
double x_to, double y_to) double x_to, double y_to)
{ {
m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); 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_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_ctrl, &dy_ctrl);
rel_to_abs(&dx_to, &dy_to); rel_to_abs(&dx_to, &dy_to);
m_vertices.add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3); 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_to, dy_to, path_cmd_curve3);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
@ -441,11 +440,11 @@ void path_adapter<VC>::curve3(double x_to, double y_to)
{ {
double x0; double x0;
double y0; double y0;
if(is_vertex(m_vertices.last_vertex(&x0, &y0))) if(is_vertex(vertices_.last_vertex(&x0, &y0)))
{ {
double x_ctrl; double x_ctrl;
double y_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)) if(is_curve(cmd))
{ {
x_ctrl = x0 + x0 - x_ctrl; 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_ctrl2, double y_ctrl2,
double x_to, double y_to) double x_to, double y_to)
{ {
m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); vertices_.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4);
m_vertices.add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4); 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_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_ctrl1, &dy_ctrl1);
rel_to_abs(&dx_ctrl2, &dy_ctrl2); rel_to_abs(&dx_ctrl2, &dy_ctrl2);
rel_to_abs(&dx_to, &dy_to); rel_to_abs(&dx_to, &dy_to);
m_vertices.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4); vertices_.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4);
m_vertices.add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4); 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_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> template<class VC>
inline void path_adapter<VC>::end_poly(unsigned flags) 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> template<class VC>
inline unsigned path_adapter<VC>::total_vertices() const inline unsigned path_adapter<VC>::total_vertices() const
{ {
return m_vertices.total_vertices(); return vertices_.total_vertices();
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline unsigned path_adapter<VC>::last_vertex(double* x, double* y) const 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> template<class VC>
inline unsigned path_adapter<VC>::prev_vertex(double* x, double* y) const 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> template<class VC>
inline double path_adapter<VC>::last_x() const inline double path_adapter<VC>::last_x() const
{ {
return m_vertices.last_x(); return vertices_.last_x();
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline double path_adapter<VC>::last_y() const inline double path_adapter<VC>::last_y() const
{ {
return m_vertices.last_y(); return vertices_.last_y();
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline unsigned path_adapter<VC>::vertex(unsigned idx, double* x, double* y) const 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> template<class VC>
inline unsigned path_adapter<VC>::command(unsigned idx) const inline unsigned path_adapter<VC>::command(unsigned idx) const
{ {
return m_vertices.command(idx); return vertices_.command(idx);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_adapter<VC>::modify_vertex(unsigned idx, double x, double y) 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> template<class VC>
void path_adapter<VC>::modify_vertex(unsigned idx, double x, double y, unsigned cmd) 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> template<class VC>
void path_adapter<VC>::modify_command(unsigned idx, unsigned cmd) void path_adapter<VC>::modify_command(unsigned idx, unsigned cmd)
{ {
m_vertices.modify_command(idx, cmd); vertices_.modify_command(idx, cmd);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_adapter<VC>::rewind(unsigned path_id) inline void path_adapter<VC>::rewind(unsigned path_id)
{ {
m_iterator = path_id; iterator_ = path_id;
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline unsigned path_adapter<VC>::vertex(double* x, double* y) inline unsigned path_adapter<VC>::vertex(double* x, double* y)
{ {
if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop; if(iterator_ >= vertices_.total_vertices()) return path_cmd_stop;
return m_vertices.vertex(m_iterator++, x, y); 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++) for(i = 0; i < np; i++)
{ {
double x1, y1, x2, y2; double x1, y1, x2, y2;
m_vertices.vertex(start + i, &x1, &y1); vertices_.vertex(start + i, &x1, &y1);
m_vertices.vertex(start + (i + 1) % np, &x2, &y2); vertices_.vertex(start + (i + 1) % np, &x2, &y2);
area += x1 * y2 - y1 * x2; area += x1 * y2 - y1 * x2;
} }
return (area < 0.0) ? path_flags_cw : path_flags_ccw; 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) void path_adapter<VC>::invert_polygon(unsigned start, unsigned end)
{ {
unsigned i; unsigned i;
unsigned tmp_cmd = m_vertices.command(start); unsigned tmp_cmd = vertices_.command(start);
--end; // Make "end" inclusive --end; // Make "end" inclusive
// Shift all commands to one position // Shift all commands to one position
for(i = start; i < end; i++) 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 // Assign starting command to the ending command
m_vertices.modify_command(end, tmp_cmd); vertices_.modify_command(end, tmp_cmd);
// Reverse the polygon // Reverse the polygon
while(end > start) 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) void path_adapter<VC>::invert_polygon(unsigned start)
{ {
// Skip all non-vertices at the beginning // Skip all non-vertices at the beginning
while(start < m_vertices.total_vertices() && while(start < vertices_.total_vertices() &&
!is_vertex(m_vertices.command(start))) ++start; !is_vertex(vertices_.command(start))) ++start;
// Skip all insignificant move_to // Skip all insignificant move_to
while(start+1 < m_vertices.total_vertices() && while(start+1 < vertices_.total_vertices() &&
is_move_to(m_vertices.command(start)) && is_move_to(vertices_.command(start)) &&
is_move_to(m_vertices.command(start+1))) ++start; is_move_to(vertices_.command(start+1))) ++start;
// Find the last vertex // Find the last vertex
unsigned end = start + 1; unsigned end = start + 1;
while(end < m_vertices.total_vertices() && while(end < vertices_.total_vertices() &&
!is_next_poly(m_vertices.command(end))) ++end; !is_next_poly(vertices_.command(end))) ++end;
invert_polygon(start, 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; if(orientation == path_flags_none) return start;
// Skip all non-vertices at the beginning // Skip all non-vertices at the beginning
while(start < m_vertices.total_vertices() && while(start < vertices_.total_vertices() &&
!is_vertex(m_vertices.command(start))) ++start; !is_vertex(vertices_.command(start))) ++start;
// Skip all insignificant move_to // Skip all insignificant move_to
while(start+1 < m_vertices.total_vertices() && while(start+1 < vertices_.total_vertices() &&
is_move_to(m_vertices.command(start)) && is_move_to(vertices_.command(start)) &&
is_move_to(m_vertices.command(start+1))) ++start; is_move_to(vertices_.command(start+1))) ++start;
// Find the last vertex // Find the last vertex
unsigned end = start + 1; unsigned end = start + 1;
while(end < m_vertices.total_vertices() && while(end < vertices_.total_vertices() &&
!is_next_poly(m_vertices.command(end))) ++end; !is_next_poly(vertices_.command(end))) ++end;
if(end - start > 2) 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, set orientation flag, and skip all end_poly
invert_polygon(start, end); invert_polygon(start, end);
unsigned cmd; unsigned cmd;
while(end < m_vertices.total_vertices() && while(end < vertices_.total_vertices() &&
is_end_poly(cmd = m_vertices.command(end))) 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) if(orientation != path_flags_none)
{ {
while(start < m_vertices.total_vertices()) while(start < vertices_.total_vertices())
{ {
start = arrange_polygon_orientation(start, orientation); start = arrange_polygon_orientation(start, orientation);
if(is_stop(m_vertices.command(start))) if(is_stop(vertices_.command(start)))
{ {
++start; ++start;
break; break;
@ -762,7 +761,7 @@ void path_adapter<VC>::arrange_orientations_all_paths(path_flags_e orientation)
if(orientation != path_flags_none) if(orientation != path_flags_none)
{ {
unsigned start = 0; unsigned start = 0;
while(start < m_vertices.total_vertices()) while(start < vertices_.total_vertices())
{ {
start = arrange_orientations(start, orientation); start = arrange_orientations(start, orientation);
} }
@ -775,12 +774,12 @@ void path_adapter<VC>::flip_x(double x1, double x2)
{ {
unsigned i; unsigned i;
double x, y; 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)) 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; unsigned i;
double x, y; 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)) 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> template<class VC>
void path_adapter<VC>::translate(double dx, double dy, unsigned path_id) 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++) for(; path_id < num_ver; path_id++)
{ {
double x, y; 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_stop(cmd)) break;
if(is_vertex(cmd)) if(is_vertex(cmd))
{ {
x += dx; x += dx;
y += dy; 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) void path_adapter<VC>::translate_all_paths(double dx, double dy)
{ {
unsigned idx; unsigned idx;
unsigned num_ver = m_vertices.total_vertices(); unsigned num_ver = vertices_.total_vertices();
for(idx = 0; idx < num_ver; idx++) for(idx = 0; idx < num_ver; idx++)
{ {
double x, y; double x, y;
if(is_vertex(m_vertices.vertex(idx, &x, &y))) if(is_vertex(vertices_.vertex(idx, &x, &y)))
{ {
x += dx; x += dx;
y += dy; 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; typedef typename vertex_type::value_type value_type;
explicit vertex_stl_adapter(Container & vertices) explicit vertex_stl_adapter(Container & vertices)
: m_vertices(vertices) {} : vertices_(vertices) {}
void add_vertex(double x, double y, unsigned cmd) 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), value_type(y),
int8u(cmd))); int8u(cmd)));
} }
void modify_vertex(unsigned idx, double x, double y) 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.x = value_type(x);
v.y = value_type(y); v.y = value_type(y);
} }
void modify_vertex(unsigned idx, double x, double y, unsigned cmd) 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.x = value_type(x);
v.y = value_type(y); v.y = value_type(y);
v.cmd = int8u(cmd); v.cmd = int8u(cmd);
@ -873,61 +872,61 @@ public:
void modify_command(unsigned idx, unsigned cmd) 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) void swap_vertices(unsigned v1, unsigned v2)
{ {
vertex_type t = m_vertices[v1]; vertex_type t = vertices_[v1];
m_vertices[v1] = m_vertices[v2]; vertices_[v1] = vertices_[v2];
m_vertices[v2] = t; vertices_[v2] = t;
} }
unsigned last_command() const unsigned last_command() const
{ {
return m_vertices.size() ? return vertices_.size() ?
m_vertices[m_vertices.size() - 1].cmd : vertices_[vertices_.size() - 1].cmd :
(unsigned)path_cmd_stop; (unsigned)path_cmd_stop;
} }
unsigned last_vertex(double* x, double* y) const unsigned last_vertex(double* x, double* y) const
{ {
if(m_vertices.size() == 0) if(vertices_.size() == 0)
{ {
*x = *y = 0.0; *x = *y = 0.0;
return path_cmd_stop; 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 unsigned prev_vertex(double* x, double* y) const
{ {
if(m_vertices.size() < 2) if(vertices_.size() < 2)
{ {
*x = *y = 0.0; *x = *y = 0.0;
return path_cmd_stop; return path_cmd_stop;
} }
return vertex(m_vertices.size() - 2, x, y); return vertex(vertices_.size() - 2, x, y);
} }
double last_x() const 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 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 unsigned total_vertices() const
{ {
return m_vertices.size(); return vertices_.size();
} }
unsigned vertex(unsigned idx, double* x, double* y) const 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; *x = v.x;
*y = v.y; *y = v.y;
return v.cmd; return v.cmd;
@ -935,11 +934,11 @@ public:
unsigned command(unsigned idx) const unsigned command(unsigned idx) const
{ {
return m_vertices[idx].cmd; return vertices_[idx].cmd;
} }
private: private:
Container & m_vertices; Container & vertices_;
}; };

View file

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

View file

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

View file

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

View file

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

View file

@ -140,7 +140,7 @@ class text_path : boost::noncopyable
~character_node() {} ~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; *c_ = c;
*x_ = pos.x; *x_ = pos.x;
@ -149,7 +149,7 @@ class text_path : boost::noncopyable
} }
}; };
int itr_; mutable int itr_;
public: public:
typedef std::vector<character_node> character_nodes_t; typedef std::vector<character_node> character_nodes_t;
pixel_position center; 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. */ /** 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); nodes_[itr_++].vertex(c, x, y, angle);
} }
/** Start again at first node. */ /** Start again at first node. */
void rewind() void rewind() const
{ {
itr_ = 0; itr_ = 0;
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -71,19 +71,39 @@ inline void to_utf8(UnicodeString const& input, std::string & target)
struct value_null struct value_null
{ {
template <typename T> 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> 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> 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> 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> 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; 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; return lhs + rhs;
} }
value_type operator() (UnicodeString const& lhs, value_null rhs) const value_type operator() (UnicodeString const& lhs, value_null rhs) const
{ {
boost::ignore_unused_variable_warning(rhs); boost::ignore_unused_variable_warning(rhs);
@ -557,6 +577,11 @@ struct negate : public boost::static_visitor<V>
return val; return val;
} }
value_type operator() (bool val) const
{
return val ? -1 : 0;
}
value_type operator() (UnicodeString const& ustr) const value_type operator() (UnicodeString const& ustr) const
{ {
UnicodeString inplace(ustr); UnicodeString inplace(ustr);

View file

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

View file

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

View file

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

View file

@ -35,7 +35,7 @@ public:
csv_datasource(mapnik::parameters const& params, bool bind=true); csv_datasource(mapnik::parameters const& params, bool bind=true);
virtual ~csv_datasource (); virtual ~csv_datasource ();
mapnik::datasource::datasource_t type() const; 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(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const; mapnik::box2d<double> envelope() const;

View file

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

View file

@ -38,7 +38,7 @@ public:
gdal_datasource(mapnik::parameters const& params, bool bind = true); gdal_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~gdal_datasource(); virtual ~gdal_datasource();
mapnik::datasource::datasource_t type() const; 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(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const; mapnik::box2d<double> envelope() const;

View file

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

View file

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

View file

@ -39,7 +39,7 @@ public:
geos_datasource(mapnik::parameters const& params, bool bind = true); geos_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~geos_datasource (); virtual ~geos_datasource ();
mapnik::datasource::datasource_t type() const; 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(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const; mapnik::box2d<double> envelope() const;

View file

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

View file

@ -46,7 +46,7 @@ public:
kismet_datasource(mapnik::parameters const& params, bool bind = true); kismet_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~kismet_datasource (); virtual ~kismet_datasource ();
datasource::datasource_t type() const; 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(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const; mapnik::box2d<double> envelope() const;

View file

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

View file

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

View file

@ -41,7 +41,7 @@ public:
occi_datasource(mapnik::parameters const& params, bool bind = true); occi_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~occi_datasource (); virtual ~occi_datasource ();
mapnik::datasource::datasource_t type() const; 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(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const; mapnik::box2d<double> envelope() const;

View file

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

View file

@ -42,7 +42,7 @@ public:
ogr_datasource(mapnik::parameters const& params, bool bind=true); ogr_datasource(mapnik::parameters const& params, bool bind=true);
virtual ~ogr_datasource (); virtual ~ogr_datasource ();
mapnik::datasource::datasource_t type() const; 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(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const; mapnik::box2d<double> envelope() const;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -313,7 +313,7 @@ void postgis_datasource::bind() const
{ {
srid_ = -1; 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 // 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"; return "postgis";
} }

View file

@ -51,7 +51,7 @@ public:
postgis_datasource(const parameters &params, bool bind=true); postgis_datasource(const parameters &params, bool bind=true);
~postgis_datasource(); ~postgis_datasource();
mapnik::datasource::datasource_t type() const; mapnik::datasource::datasource_t type() const;
static std::string name(); static const char * name();
featureset_ptr features(const query& q) const; featureset_ptr features(const query& q) const;
featureset_ptr features_at_point(coord2d const& pt) const; featureset_ptr features_at_point(coord2d const& pt) const;
mapnik::box2d<double> envelope() 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() feature_ptr postgis_featureset::next()
{ {
if (rs_->next()) while (rs_->next())
{ {
// new feature // new feature
unsigned pos = 1; unsigned pos = 1;
@ -107,10 +107,12 @@ feature_ptr postgis_featureset::next()
// parse geometry // parse geometry
int size = rs_->getFieldLength(0); int size = rs_->getFieldLength(0);
const char *data = rs_->getValue(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; totalGeomSize_ += size;
int num_attrs = ctx_->size() + 1; unsigned num_attrs = ctx_->size() + 1;
for (; pos < num_attrs; ++pos) for (; pos < num_attrs; ++pos)
{ {
std::string name = rs_->getFieldName(pos); std::string name = rs_->getFieldName(pos);
@ -207,11 +209,7 @@ feature_ptr postgis_featureset::next()
} }
return feature; return feature;
} }
else return feature_ptr();
{
rs_->close();
return feature_ptr();
}
} }

View file

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

View file

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

View file

@ -34,7 +34,7 @@ public:
raster_datasource(const mapnik::parameters& params, bool bind=true); raster_datasource(const mapnik::parameters& params, bool bind=true);
virtual ~raster_datasource(); virtual ~raster_datasource();
datasource::datasource_t type() const; 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(const mapnik::query& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const; mapnik::box2d<double> envelope() const;

View file

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

View file

@ -37,7 +37,7 @@ public:
rasterlite_datasource(mapnik::parameters const& params, bool bind = true); rasterlite_datasource(mapnik::parameters const& params, bool bind = true);
virtual ~rasterlite_datasource (); virtual ~rasterlite_datasource ();
mapnik::datasource::datasource_t type() const; 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(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const; mapnik::box2d<double> envelope() const;

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