Merge branch 'master' of github.com:mapnik/mapnik
This commit is contained in:
commit
3054145103
174 changed files with 4982 additions and 3534 deletions
8
Makefile
8
Makefile
|
@ -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..."
|
||||||
|
|
142
SConstruct
142
SConstruct
|
@ -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:
|
||||||
|
|
|
@ -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':
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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> >())
|
||||||
|
|
|
@ -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",
|
||||||
|
|
53
bindings/python/mapnik_scaling_method.cpp
Normal file
53
bindings/python/mapnik_scaling_method.cpp
Normal 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)
|
||||||
|
;
|
||||||
|
}
|
505
bindings/python/python_grid_utils.cpp
Normal file
505
bindings/python/python_grid_utils.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
2
configure
vendored
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
python scons/scons.py configure "$@"
|
python scons/scons.py --implicit-cache configure "$@"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(); \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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){
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
83
include/mapnik/image_scaling.hpp
Normal file
83
include/mapnik/image_scaling.hpp
Normal 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
|
|
@ -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;
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
108
include/mapnik/marker_helpers.hpp
Normal file
108
include/mapnik/marker_helpers.hpp
Normal 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
|
|
@ -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.
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace detail {
|
||||||
|
|
||||||
// boost::spirit::traits::clear<T>(T& val) [with T = boost::variant<...>]
|
// boost::spirit::traits::clear<T>(T& val) [with T = boost::variant<...>]
|
||||||
// attempts to assign to the variant's current value a default-constructed
|
// attempts to assign to the variant's current value a default-constructed
|
||||||
// value ot the same type, which not only requires that each value-type is
|
// value of the same type, which not only requires that each value-type is
|
||||||
// default-constructible, but also makes little sense with our variant of
|
// default-constructible, but also makes little sense with our variant of
|
||||||
// transform nodes...
|
// transform nodes...
|
||||||
|
|
||||||
|
|
|
@ -39,65 +39,7 @@ namespace mapnik {
|
||||||
struct transform_expression_grammar
|
struct transform_expression_grammar
|
||||||
: qi::grammar<Iterator, transform_list(), space_type>
|
: qi::grammar<Iterator, transform_list(), space_type>
|
||||||
{
|
{
|
||||||
explicit transform_expression_grammar(expression_grammar<Iterator> const& g)
|
explicit transform_expression_grammar(expression_grammar<Iterator> const& g);
|
||||||
: transform_expression_grammar::base_type(start)
|
|
||||||
{
|
|
||||||
using boost::phoenix::construct;
|
|
||||||
using qi::_a; using qi::_1; using qi::_4;
|
|
||||||
using qi::_b; using qi::_2; using qi::_5;
|
|
||||||
using qi::_c; using qi::_3; using qi::_6;
|
|
||||||
using qi::_val;
|
|
||||||
using qi::char_;
|
|
||||||
using qi::lit;
|
|
||||||
using qi::no_case;
|
|
||||||
using qi::no_skip;
|
|
||||||
|
|
||||||
start = transform_ % no_skip[char_(", ")] ;
|
|
||||||
|
|
||||||
transform_ = matrix | translate | scale | rotate | skewX | skewY ;
|
|
||||||
|
|
||||||
matrix = no_case[lit("matrix")]
|
|
||||||
>> (lit('(')
|
|
||||||
>> expr >> -lit(',')
|
|
||||||
>> expr >> -lit(',')
|
|
||||||
>> expr >> -lit(',')
|
|
||||||
>> expr >> -lit(',')
|
|
||||||
>> expr >> -lit(',')
|
|
||||||
>> expr >> lit(')'))
|
|
||||||
[ _val = construct<matrix_node>(_1,_2,_3,_4,_5,_6) ];
|
|
||||||
|
|
||||||
translate = no_case[lit("translate")]
|
|
||||||
>> (lit('(')
|
|
||||||
>> expr >> -lit(',')
|
|
||||||
>> -expr >> lit(')'))
|
|
||||||
[ _val = construct<translate_node>(_1,_2) ];
|
|
||||||
|
|
||||||
scale = no_case[lit("scale")]
|
|
||||||
>> (lit('(')
|
|
||||||
>> expr >> -lit(',')
|
|
||||||
>> -expr >> lit(')'))
|
|
||||||
[ _val = construct<scale_node>(_1,_2) ];
|
|
||||||
|
|
||||||
rotate = no_case[lit("rotate")]
|
|
||||||
>> lit('(')
|
|
||||||
>> expr[_a = _1] >> -lit(',')
|
|
||||||
>> -(expr [_b = _1] >> -lit(',') >> expr[_c = _1])
|
|
||||||
>> lit(')')
|
|
||||||
[ _val = construct<rotate_node>(_a,_b,_c) ];
|
|
||||||
|
|
||||||
skewX = no_case[lit("skewX")]
|
|
||||||
>> lit('(')
|
|
||||||
>> expr [ _val = construct<skewX_node>(_1) ]
|
|
||||||
>> lit(')');
|
|
||||||
|
|
||||||
skewY = no_case[lit("skewY")]
|
|
||||||
>> lit('(')
|
|
||||||
>> expr [ _val = construct<skewY_node>(_1) ]
|
|
||||||
>> lit(')');
|
|
||||||
|
|
||||||
expr = g.expr.alias();
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef qi::locals<expr_node, boost::optional<expr_node>,
|
typedef qi::locals<expr_node, boost::optional<expr_node>,
|
||||||
boost::optional<expr_node>
|
boost::optional<expr_node>
|
||||||
> rotate_locals;
|
> rotate_locals;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ kismet_datasource::~kismet_datasource()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string kismet_datasource::name()
|
const char * kismet_datasource::name()
|
||||||
{
|
{
|
||||||
return "kismet";
|
return "kismet";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
postgis_datasource(const parameters ¶ms, bool bind=true);
|
postgis_datasource(const parameters ¶ms, 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;
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -166,7 +166,7 @@ rasterlite_datasource::~rasterlite_datasource()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string rasterlite_datasource::name()
|
const char * rasterlite_datasource::name()
|
||||||
{
|
{
|
||||||
return "rasterlite";
|
return "rasterlite";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue