+ merge mapnik2 to trunk
This commit is contained in:
parent
0ccdac028e
commit
47dc1e197b
220 changed files with 6656 additions and 11603 deletions
|
@ -17,6 +17,8 @@ Mapnik 0.7.0 Release
|
||||||
|
|
||||||
- Gdal Plugin: Add support for Gdal overviews, enabling fast loading of > 1GB rasters (#54)
|
- Gdal Plugin: Add support for Gdal overviews, enabling fast loading of > 1GB rasters (#54)
|
||||||
|
|
||||||
|
- Rasterlite Plugin: Experimental support for Rasterlite, to practically use sqlite database with wavelet compressed rasters
|
||||||
|
|
||||||
- PostGIS: Added an optional 'geometry_table' parameter. This is used by Mapnik to look up metadata in the
|
- PostGIS: Added an optional 'geometry_table' parameter. This is used by Mapnik to look up metadata in the
|
||||||
geometry_columns and calculate extents (when the 'geometry_field' and 'srid' parameters are not supplied).
|
geometry_columns and calculate extents (when the 'geometry_field' and 'srid' parameters are not supplied).
|
||||||
If 'geometry_table' is not specified Mapnik will attempt to determine the name of the table to query based
|
If 'geometry_table' is not specified Mapnik will attempt to determine the name of the table to query based
|
||||||
|
|
17
SConstruct
17
SConstruct
|
@ -93,6 +93,7 @@ PLUGINS = { # plugins with external dependencies
|
||||||
'ogr': {'default':False,'path':None,'inc':'ogrsf_frmts.h','lib':'gdal','lang':'C++'},
|
'ogr': {'default':False,'path':None,'inc':'ogrsf_frmts.h','lib':'gdal','lang':'C++'},
|
||||||
'occi': {'default':False,'path':'OCCI','inc':'occi.h','lib':'ociei','lang':'C++'},
|
'occi': {'default':False,'path':'OCCI','inc':'occi.h','lib':'ociei','lang':'C++'},
|
||||||
'sqlite': {'default':False,'path':'SQLITE','inc':'sqlite3.h','lib':'sqlite3','lang':'C'},
|
'sqlite': {'default':False,'path':'SQLITE','inc':'sqlite3.h','lib':'sqlite3','lang':'C'},
|
||||||
|
'rasterlite': {'default':False,'path':'RASTERLITE','inc':['sqlite3.h','rasterlite.h'],'lib':'rasterlite','lang':'C'},
|
||||||
|
|
||||||
# plugins without external dependencies requiring CheckLibWithHeader...
|
# plugins without external dependencies requiring CheckLibWithHeader...
|
||||||
# note: osm plugin does depend on libxml2
|
# note: osm plugin does depend on libxml2
|
||||||
|
@ -169,6 +170,8 @@ opts.AddVariables(
|
||||||
PathVariable('OCCI_LIBS', 'Search path for OCCI library files', '/usr/lib/oracle/10.2.0.3/client/'+ LIBDIR_SCHEMA, PathVariable.PathAccept),
|
PathVariable('OCCI_LIBS', 'Search path for OCCI library files', '/usr/lib/oracle/10.2.0.3/client/'+ LIBDIR_SCHEMA, PathVariable.PathAccept),
|
||||||
PathVariable('SQLITE_INCLUDES', 'Search path for SQLITE include files', '/usr/include/', PathVariable.PathAccept),
|
PathVariable('SQLITE_INCLUDES', 'Search path for SQLITE include files', '/usr/include/', PathVariable.PathAccept),
|
||||||
PathVariable('SQLITE_LIBS', 'Search path for SQLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept),
|
PathVariable('SQLITE_LIBS', 'Search path for SQLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept),
|
||||||
|
PathVariable('RASTERLITE_INCLUDES', 'Search path for RASTERLITE include files', '/usr/include/', PathVariable.PathAccept),
|
||||||
|
PathVariable('RASTERLITE_LIBS', 'Search path for RASTERLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept),
|
||||||
|
|
||||||
# Other variables
|
# Other variables
|
||||||
BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'),
|
BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'),
|
||||||
|
@ -375,7 +378,7 @@ def FindBoost(context, prefixes, thread_flag):
|
||||||
search_lib = 'libboost_thread'
|
search_lib = 'libboost_thread'
|
||||||
else:
|
else:
|
||||||
search_lib = 'libboost_filesystem'
|
search_lib = 'libboost_filesystem'
|
||||||
|
|
||||||
prefixes.insert(0,os.path.dirname(env['BOOST_INCLUDES']))
|
prefixes.insert(0,os.path.dirname(env['BOOST_INCLUDES']))
|
||||||
prefixes.insert(0,os.path.dirname(env['BOOST_LIBS']))
|
prefixes.insert(0,os.path.dirname(env['BOOST_LIBS']))
|
||||||
for searchDir in prefixes:
|
for searchDir in prefixes:
|
||||||
|
@ -698,11 +701,11 @@ if not preconfigured:
|
||||||
BOOST_LIBSHEADERS.append(['thread', 'boost/thread/mutex.hpp', True])
|
BOOST_LIBSHEADERS.append(['thread', 'boost/thread/mutex.hpp', True])
|
||||||
|
|
||||||
# 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 1.34
|
# enforce boost version greater than or equal to 1.41
|
||||||
if not conf.CheckBoost('1.34'):
|
if not conf.CheckBoost('1.41'):
|
||||||
color_print (1,'Boost version 1.34 or greater is requred')
|
color_print (1,'Boost version 1.41 or greater is requred')
|
||||||
if not env['BOOST_VERSION']:
|
if not env['BOOST_VERSION']:
|
||||||
env['MISSING_DEPS'].append('boost version >=1.34')
|
env['MISSING_DEPS'].append('boost version >=1.41')
|
||||||
else:
|
else:
|
||||||
color_print (4,'Found boost lib version... %s' % boost_lib_version_from_header )
|
color_print (4,'Found boost lib version... %s' % boost_lib_version_from_header )
|
||||||
|
|
||||||
|
@ -783,7 +786,7 @@ if not preconfigured:
|
||||||
if env['SKIPPED_DEPS']:
|
if env['SKIPPED_DEPS']:
|
||||||
color_print(4,'\nAlso, these optional dependencies were not found:\n - %s' % '\n - '.join(env['SKIPPED_DEPS']))
|
color_print(4,'\nAlso, these optional dependencies were not found:\n - %s' % '\n - '.join(env['SKIPPED_DEPS']))
|
||||||
color_print(4,"\nSet custom paths to these libraries and header files on the command-line or in a file called '%s'" % SCONS_LOCAL_CONFIG)
|
color_print(4,"\nSet custom paths to these libraries and header files on the command-line or in a file called '%s'" % SCONS_LOCAL_CONFIG)
|
||||||
color_print(4," ie. $ python scons/scons.py BOOST_INCLUDES=/usr/local/include/boost-1_37 BOOST_LIBS=/usr/local/lib")
|
color_print(4," ie. $ python scons/scons.py BOOST_INCLUDES=/usr/local/include BOOST_LIBS=/usr/local/lib")
|
||||||
color_print(4, "\nOnce all required dependencies are found a local '%s' will be saved and then install:" % SCONS_LOCAL_CONFIG)
|
color_print(4, "\nOnce all required dependencies are found a local '%s' will be saved and then install:" % SCONS_LOCAL_CONFIG)
|
||||||
color_print(4," $ sudo python scons/scons.py install")
|
color_print(4," $ sudo python scons/scons.py install")
|
||||||
color_print(4,"\nTo view available path variables:\n $ python scons/scons.py --help or -h")
|
color_print(4,"\nTo view available path variables:\n $ python scons/scons.py --help or -h")
|
||||||
|
@ -866,7 +869,7 @@ if not preconfigured:
|
||||||
env.Append(CXXFLAGS = common_cxx_flags + '-O %s' % ndebug_flags)
|
env.Append(CXXFLAGS = common_cxx_flags + '-O %s' % ndebug_flags)
|
||||||
else:
|
else:
|
||||||
# Common flags for GCC.
|
# Common flags for GCC.
|
||||||
gcc_cxx_flags = '-ansi -Wall %s -ftemplate-depth-100 %s' % (pthread, common_cxx_flags)
|
gcc_cxx_flags = '-ansi -Wall %s -ftemplate-depth-200 %s' % (pthread, common_cxx_flags)
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -137,12 +137,12 @@ class _Coord(Coord,_injector):
|
||||||
"""
|
"""
|
||||||
return inverse_(self, projection)
|
return inverse_(self, projection)
|
||||||
|
|
||||||
class _Envelope(Envelope,_injector):
|
class _Box2d(Box2d,_injector):
|
||||||
"""
|
"""
|
||||||
Represents a spatial envelope (i.e. bounding box).
|
Represents a spatial envelope (i.e. bounding box).
|
||||||
|
|
||||||
|
|
||||||
Following operators are defined for Envelope:
|
Following operators are defined for Box2d:
|
||||||
|
|
||||||
Addition:
|
Addition:
|
||||||
e1 + e2 is equvalent to e1.expand_to_include(e2) but yields
|
e1 + e2 is equvalent to e1.expand_to_include(e2) but yields
|
||||||
|
@ -165,7 +165,7 @@ class _Envelope(Envelope,_injector):
|
||||||
Equality: two envelopes are equal if their corner points are equal.
|
Equality: two envelopes are equal if their corner points are equal.
|
||||||
"""
|
"""
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'Envelope(%s,%s,%s,%s)' % \
|
return 'Box2d(%s,%s,%s,%s)' % \
|
||||||
(self.minx,self.miny,self.maxx,self.maxy)
|
(self.minx,self.miny,self.maxx,self.maxy)
|
||||||
def forward(self, projection):
|
def forward(self, projection):
|
||||||
"""
|
"""
|
||||||
|
@ -193,21 +193,21 @@ class _Projection(Projection,_injector):
|
||||||
return "Projection('%s')" % self.params()
|
return "Projection('%s')" % self.params()
|
||||||
def forward(self,obj):
|
def forward(self,obj):
|
||||||
"""
|
"""
|
||||||
Projects the given object (Envelope or Coord)
|
Projects the given object (Box2d or Coord)
|
||||||
from the geographic space into the cartesian space.
|
from the geographic space into the cartesian space.
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
Envelope.forward(self, projection),
|
Box2d.forward(self, projection),
|
||||||
Coord.forward(self, projection).
|
Coord.forward(self, projection).
|
||||||
"""
|
"""
|
||||||
return forward_(obj,self)
|
return forward_(obj,self)
|
||||||
def inverse(self,obj):
|
def inverse(self,obj):
|
||||||
"""
|
"""
|
||||||
Projects the given object (Envelope or Coord)
|
Projects the given object (Box2d or Coord)
|
||||||
from the cartesian space into the geographic space.
|
from the cartesian space into the geographic space.
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
Envelope.inverse(self, projection),
|
Box2d.inverse(self, projection),
|
||||||
Coord.inverse(self, projection).
|
Coord.inverse(self, projection).
|
||||||
"""
|
"""
|
||||||
return inverse_(obj,self)
|
return inverse_(obj,self)
|
||||||
|
@ -337,7 +337,7 @@ def Raster(**keywords):
|
||||||
hix -- highest (max) x/longitude of tiff extent
|
hix -- highest (max) x/longitude of tiff extent
|
||||||
hiy -- highest (max) y/latitude of tiff extent
|
hiy -- highest (max) y/latitude of tiff extent
|
||||||
|
|
||||||
Hint: lox,loy,hix,hiy make a Mapnik Envelope
|
Hint: lox,loy,hix,hiy make a Mapnik Box2d
|
||||||
|
|
||||||
Optional keyword arguments:
|
Optional keyword arguments:
|
||||||
base -- path prefix (default None)
|
base -- path prefix (default None)
|
||||||
|
@ -450,6 +450,26 @@ def SQLite(**keywords):
|
||||||
keywords['type'] = 'sqlite'
|
keywords['type'] = 'sqlite'
|
||||||
return CreateDatasource(keywords)
|
return CreateDatasource(keywords)
|
||||||
|
|
||||||
|
def Rasterlite(**keywords):
|
||||||
|
"""Create a Rasterlite Datasource.
|
||||||
|
|
||||||
|
Required keyword arguments:
|
||||||
|
file -- path to Rasterlite database file
|
||||||
|
table -- table name or subselect query
|
||||||
|
|
||||||
|
Optional keyword arguments:
|
||||||
|
base -- path prefix (default None)
|
||||||
|
extent -- manually specified data extent (comma delimited string, default None)
|
||||||
|
|
||||||
|
>>> from mapnik import Rasterlite, Layer
|
||||||
|
>>> rasterlite = Rasterlite(base='/home/mapnik/data',file='osm.db',table='osm',extent='-20037508,-19929239,20037508,19929239')
|
||||||
|
>>> lyr = Layer('Rasterlite Layer')
|
||||||
|
>>> lyr.datasource = rasterlite
|
||||||
|
|
||||||
|
"""
|
||||||
|
keywords['type'] = 'rasterlite'
|
||||||
|
return CreateDatasource(keywords)
|
||||||
|
|
||||||
def Osm(**keywords):
|
def Osm(**keywords):
|
||||||
"""Create a Osm Datasource.
|
"""Create a Osm Datasource.
|
||||||
|
|
||||||
|
@ -524,7 +544,7 @@ __all__ = [
|
||||||
# classes
|
# classes
|
||||||
'Color', 'Coord',
|
'Color', 'Coord',
|
||||||
'DatasourceCache',
|
'DatasourceCache',
|
||||||
'Envelope',
|
'Box2d',
|
||||||
'Feature', 'Featureset', 'FontEngine',
|
'Feature', 'Featureset', 'FontEngine',
|
||||||
'Geometry2d',
|
'Geometry2d',
|
||||||
'Image', 'ImageView',
|
'Image', 'ImageView',
|
||||||
|
@ -537,7 +557,6 @@ __all__ = [
|
||||||
'PolygonPatternSymbolizer', 'PolygonSymbolizer',
|
'PolygonPatternSymbolizer', 'PolygonSymbolizer',
|
||||||
'ProjTransform',
|
'ProjTransform',
|
||||||
'Projection',
|
'Projection',
|
||||||
'Properties',
|
|
||||||
'Query',
|
'Query',
|
||||||
'RasterSymbolizer',
|
'RasterSymbolizer',
|
||||||
'Rule', 'Rules',
|
'Rule', 'Rules',
|
||||||
|
@ -562,7 +581,8 @@ __all__ = [
|
||||||
'mapnik_version_string', 'mapnik_version', 'mapnik_svn_revision',
|
'mapnik_version_string', 'mapnik_version', 'mapnik_svn_revision',
|
||||||
'has_cairo', 'has_pycairo',
|
'has_cairo', 'has_pycairo',
|
||||||
# factory methods
|
# factory methods
|
||||||
'Filter',
|
'Expression',
|
||||||
|
'PathExpression',
|
||||||
# load/save/render
|
# load/save/render
|
||||||
'load_map', 'load_map_from_string', 'save_map', 'save_map_to_string',
|
'load_map', 'load_map_from_string', 'save_map', 'save_map_to_string',
|
||||||
'render', 'render_tile_to_file', 'render_to_file',
|
'render', 'render_tile_to_file', 'render_to_file',
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
"""Core OGCServer classes and functions."""
|
"""Core OGCServer classes and functions."""
|
||||||
|
|
||||||
from exceptions import OGCException, ServerConfigurationError
|
from exceptions import OGCException, ServerConfigurationError
|
||||||
from mapnik import Map, Color, Envelope, render, Image, Layer, Style, Projection as MapnikProjection, Coord
|
from mapnik import Map, Color, Box2d, render, Image, Layer, Style, Projection as MapnikProjection, Coord
|
||||||
from PIL.Image import new
|
from PIL.Image import new
|
||||||
from PIL.ImageDraw import Draw
|
from PIL.ImageDraw import Draw
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
@ -409,7 +409,7 @@ class WMSBaseServiceHandler(BaseServiceHandler):
|
||||||
else:
|
else:
|
||||||
raise ServerConfigurationError('Layer "%s" refers to non-existent style "%s".' % (layername, stylename))
|
raise ServerConfigurationError('Layer "%s" refers to non-existent style "%s".' % (layername, stylename))
|
||||||
m.layers.append(layer)
|
m.layers.append(layer)
|
||||||
m.zoom_to_box(Envelope(params['bbox'][0], params['bbox'][1], params['bbox'][2], params['bbox'][3]))
|
m.zoom_to_box(Box2d(params['bbox'][0], params['bbox'][1], params['bbox'][2], params['bbox'][3]))
|
||||||
return m
|
return m
|
||||||
|
|
||||||
class BaseExceptionHandler:
|
class BaseExceptionHandler:
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
from common import ParameterDefinition, Response, Version, ListFactory, \
|
from common import ParameterDefinition, Response, Version, ListFactory, \
|
||||||
ColorFactory, CRSFactory, CRS, WMSBaseServiceHandler, \
|
ColorFactory, CRSFactory, CRS, WMSBaseServiceHandler, \
|
||||||
BaseExceptionHandler, Projection, Envelope
|
BaseExceptionHandler, Projection, Box2d
|
||||||
from exceptions import OGCException, ServerConfigurationError
|
from exceptions import OGCException, ServerConfigurationError
|
||||||
from mapnik import Coord
|
from mapnik import Coord
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ class ServiceHandler(WMSBaseServiceHandler):
|
||||||
m = WMSBaseServiceHandler._buildMap(self, params)
|
m = WMSBaseServiceHandler._buildMap(self, params)
|
||||||
# for range of epsg codes reverse axis
|
# for range of epsg codes reverse axis
|
||||||
if params['crs'].code >= 4000 and params['crs'].code < 5000:
|
if params['crs'].code >= 4000 and params['crs'].code < 5000:
|
||||||
m.zoom_to_box(Envelope(params['bbox'][1], params['bbox'][0], params['bbox'][3], params['bbox'][2]))
|
m.zoom_to_box(Box2d(params['bbox'][1], params['bbox'][0], params['bbox'][3], params['bbox'][2]))
|
||||||
return m
|
return m
|
||||||
|
|
||||||
class ExceptionHandler(BaseExceptionHandler):
|
class ExceptionHandler(BaseExceptionHandler):
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/envelope.hpp>
|
#include <mapnik/box2d.hpp>
|
||||||
#include <mapnik/datasource.hpp>
|
#include <mapnik/datasource.hpp>
|
||||||
#include <mapnik/datasource_cache.hpp>
|
#include <mapnik/datasource_cache.hpp>
|
||||||
#include <mapnik/feature_layer_desc.hpp>
|
#include <mapnik/feature_layer_desc.hpp>
|
||||||
|
|
|
@ -25,15 +25,15 @@
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/envelope.hpp>
|
#include <mapnik/box2d.hpp>
|
||||||
|
|
||||||
using mapnik::coord;
|
using mapnik::coord;
|
||||||
using mapnik::Envelope;
|
using mapnik::box2d;
|
||||||
|
|
||||||
struct envelope_pickle_suite : boost::python::pickle_suite
|
struct envelope_pickle_suite : boost::python::pickle_suite
|
||||||
{
|
{
|
||||||
static boost::python::tuple
|
static boost::python::tuple
|
||||||
getinitargs(const Envelope<double>& e)
|
getinitargs(const box2d<double>& e)
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
return boost::python::make_tuple(e.minx(),e.miny(),e.maxx(),e.maxy());
|
return boost::python::make_tuple(e.minx(),e.miny(),e.maxx(),e.maxy());
|
||||||
|
@ -41,135 +41,135 @@ struct envelope_pickle_suite : boost::python::pickle_suite
|
||||||
};
|
};
|
||||||
|
|
||||||
//define overloads here
|
//define overloads here
|
||||||
void (Envelope<double>::*width_p1)(double) = &Envelope<double>::width;
|
void (box2d<double>::*width_p1)(double) = &box2d<double>::width;
|
||||||
double (Envelope<double>::*width_p2)() const = &Envelope<double>::width;
|
double (box2d<double>::*width_p2)() const = &box2d<double>::width;
|
||||||
|
|
||||||
void (Envelope<double>::*height_p1)(double) = &Envelope<double>::height;
|
void (box2d<double>::*height_p1)(double) = &box2d<double>::height;
|
||||||
double (Envelope<double>::*height_p2)() const = &Envelope<double>::height;
|
double (box2d<double>::*height_p2)() const = &box2d<double>::height;
|
||||||
|
|
||||||
void (Envelope<double>::*expand_to_include_p1)(double,double) = &Envelope<double>::expand_to_include;
|
void (box2d<double>::*expand_to_include_p1)(double,double) = &box2d<double>::expand_to_include;
|
||||||
void (Envelope<double>::*expand_to_include_p2)(coord<double,2> const& ) = &Envelope<double>::expand_to_include;
|
void (box2d<double>::*expand_to_include_p2)(coord<double,2> const& ) = &box2d<double>::expand_to_include;
|
||||||
void (Envelope<double>::*expand_to_include_p3)(Envelope<double> const& ) = &Envelope<double>::expand_to_include;
|
void (box2d<double>::*expand_to_include_p3)(box2d<double> const& ) = &box2d<double>::expand_to_include;
|
||||||
|
|
||||||
bool (Envelope<double>::*contains_p1)(double,double) const = &Envelope<double>::contains;
|
bool (box2d<double>::*contains_p1)(double,double) const = &box2d<double>::contains;
|
||||||
bool (Envelope<double>::*contains_p2)(coord<double,2> const&) const = &Envelope<double>::contains;
|
bool (box2d<double>::*contains_p2)(coord<double,2> const&) const = &box2d<double>::contains;
|
||||||
bool (Envelope<double>::*contains_p3)(Envelope<double> const&) const = &Envelope<double>::contains;
|
bool (box2d<double>::*contains_p3)(box2d<double> const&) const = &box2d<double>::contains;
|
||||||
|
|
||||||
//intersects
|
//intersects
|
||||||
bool (Envelope<double>::*intersects_p1)(double,double) const = &Envelope<double>::intersects;
|
bool (box2d<double>::*intersects_p1)(double,double) const = &box2d<double>::intersects;
|
||||||
bool (Envelope<double>::*intersects_p2)(coord<double,2> const&) const = &Envelope<double>::intersects;
|
bool (box2d<double>::*intersects_p2)(coord<double,2> const&) const = &box2d<double>::intersects;
|
||||||
bool (Envelope<double>::*intersects_p3)(Envelope<double> const&) const = &Envelope<double>::intersects;
|
bool (box2d<double>::*intersects_p3)(box2d<double> const&) const = &box2d<double>::intersects;
|
||||||
|
|
||||||
// intersect
|
// intersect
|
||||||
Envelope<double> (Envelope<double>::*intersect)(Envelope<double> const&) const = &Envelope<double>::intersect;
|
box2d<double> (box2d<double>::*intersect)(box2d<double> const&) const = &box2d<double>::intersect;
|
||||||
|
|
||||||
void export_envelope()
|
void export_envelope()
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
class_<Envelope<double> >("Envelope",
|
class_<box2d<double> >("Box2d",
|
||||||
// class docstring is in mapnik/__init__.py, class _Coord
|
// class docstring is in mapnik/__init__.py, class _Coord
|
||||||
init<double,double,double,double>(
|
init<double,double,double,double>(
|
||||||
(arg("minx"),arg("miny"),arg("maxx"),arg("maxy")),
|
(arg("minx"),arg("miny"),arg("maxx"),arg("maxy")),
|
||||||
"Constructs a new envelope from the coordinates\n"
|
"Constructs a new envelope from the coordinates\n"
|
||||||
"of its lower left and upper right corner points.\n"))
|
"of its lower left and upper right corner points.\n"))
|
||||||
.def(init<>("Equivalent to Envelope(0, 0, -1, -1).\n"))
|
.def(init<>("Equivalent to box2d(0, 0, -1, -1).\n"))
|
||||||
.def(init<const coord<double,2>&, const coord<double,2>&>(
|
.def(init<const coord<double,2>&, const coord<double,2>&>(
|
||||||
(arg("ll"),arg("ur")),
|
(arg("ll"),arg("ur")),
|
||||||
"Equivalent to Envelope(ll.x, ll.y, ur.x, ur.y).\n"))
|
"Equivalent to box2d(ll.x, ll.y, ur.x, ur.y).\n"))
|
||||||
.add_property("minx", &Envelope<double>::minx,
|
.add_property("minx", &box2d<double>::minx,
|
||||||
"X coordinate for the lower left corner")
|
"X coordinate for the lower left corner")
|
||||||
.add_property("miny", &Envelope<double>::miny,
|
.add_property("miny", &box2d<double>::miny,
|
||||||
"Y coordinate for the lower left corner")
|
"Y coordinate for the lower left corner")
|
||||||
.add_property("maxx", &Envelope<double>::maxx,
|
.add_property("maxx", &box2d<double>::maxx,
|
||||||
"X coordinate for the upper right corner")
|
"X coordinate for the upper right corner")
|
||||||
.add_property("maxy", &Envelope<double>::maxy,
|
.add_property("maxy", &box2d<double>::maxy,
|
||||||
"Y coordinate for the upper right corner")
|
"Y coordinate for the upper right corner")
|
||||||
.def("center", &Envelope<double>::center,
|
.def("center", &box2d<double>::center,
|
||||||
"Returns the coordinates of the center of the bounding box.\n"
|
"Returns the coordinates of the center of the bounding box.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Example:\n"
|
"Example:\n"
|
||||||
">>> e = Envelope(0, 0, 100, 100)\n"
|
">>> e = box2d(0, 0, 100, 100)\n"
|
||||||
">>> e.center()\n"
|
">>> e.center()\n"
|
||||||
"Coord(50, 50)\n")
|
"Coord(50, 50)\n")
|
||||||
.def("center", &Envelope<double>::re_center,
|
.def("center", &box2d<double>::re_center,
|
||||||
(arg("x"), arg("y")),
|
(arg("x"), arg("y")),
|
||||||
"Moves the envelope so that the given coordinates become its new center.\n"
|
"Moves the envelope so that the given coordinates become its new center.\n"
|
||||||
"The width and the height are preserved.\n"
|
"The width and the height are preserved.\n"
|
||||||
"\n "
|
"\n "
|
||||||
"Example:\n"
|
"Example:\n"
|
||||||
">>> e = Envelope(0, 0, 100, 100)\n"
|
">>> e = box2d(0, 0, 100, 100)\n"
|
||||||
">>> e.center(60, 60)\n"
|
">>> e.center(60, 60)\n"
|
||||||
">>> e.center()\n"
|
">>> e.center()\n"
|
||||||
"Coord(60.0,60.0)\n"
|
"Coord(60.0,60.0)\n"
|
||||||
">>> (e.width(), e.height())\n"
|
">>> (e.width(), e.height())\n"
|
||||||
"(100.0, 100.0)\n"
|
"(100.0, 100.0)\n"
|
||||||
">>> e\n"
|
">>> e\n"
|
||||||
"Envelope(10.0, 10.0, 110.0, 110.0)\n"
|
"box2d(10.0, 10.0, 110.0, 110.0)\n"
|
||||||
)
|
)
|
||||||
.def("width", width_p1,
|
.def("width", width_p1,
|
||||||
(arg("new_width")),
|
(arg("new_width")),
|
||||||
"Sets the width to new_width of the envelope preserving its center.\n"
|
"Sets the width to new_width of the envelope preserving its center.\n"
|
||||||
"\n "
|
"\n "
|
||||||
"Example:\n"
|
"Example:\n"
|
||||||
">>> e = Envelope(0, 0, 100, 100)\n"
|
">>> e = box2d(0, 0, 100, 100)\n"
|
||||||
">>> e.width(120)\n"
|
">>> e.width(120)\n"
|
||||||
">>> e.center()\n"
|
">>> e.center()\n"
|
||||||
"Coord(50.0,50.0)\n"
|
"Coord(50.0,50.0)\n"
|
||||||
">>> e\n"
|
">>> e\n"
|
||||||
"Envelope(-10.0, 0.0, 110.0, 100.0)\n"
|
"box2d(-10.0, 0.0, 110.0, 100.0)\n"
|
||||||
)
|
)
|
||||||
.def("width", width_p2,
|
.def("width", width_p2,
|
||||||
"Returns the width of this envelope.\n"
|
"Returns the width of this envelope.\n"
|
||||||
)
|
)
|
||||||
.def("height", height_p1,
|
.def("height", height_p1,
|
||||||
(arg("new_height")),
|
(arg("new_height")),
|
||||||
"Sets the height to new_height of the envelope preserving its center.\n"
|
"Sets the height to new_height of the envelope preserving its center.\n"
|
||||||
"\n "
|
"\n "
|
||||||
"Example:\n"
|
"Example:\n"
|
||||||
">>> e = Envelope(0, 0, 100, 100)\n"
|
">>> e = box2d(0, 0, 100, 100)\n"
|
||||||
">>> e.height(120)\n"
|
">>> e.height(120)\n"
|
||||||
">>> e.center()\n"
|
">>> e.center()\n"
|
||||||
"Coord(50.0,50.0)\n"
|
"Coord(50.0,50.0)\n"
|
||||||
">>> e\n"
|
">>> e\n"
|
||||||
"Envelope(0.0, -10.0, 100.0, 110.0)\n"
|
"box2d(0.0, -10.0, 100.0, 110.0)\n"
|
||||||
)
|
)
|
||||||
.def("height", height_p2,
|
.def("height", height_p2,
|
||||||
"Returns the height of this envelope.\n"
|
"Returns the height of this envelope.\n"
|
||||||
)
|
)
|
||||||
.def("expand_to_include",expand_to_include_p1,
|
.def("expand_to_include",expand_to_include_p1,
|
||||||
(arg("x"),arg("y")),
|
(arg("x"),arg("y")),
|
||||||
"Expands this envelope to include the point given by x and y.\n"
|
"Expands this envelope to include the point given by x and y.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Example:\n",
|
"Example:\n",
|
||||||
">>> e = Envelope(0, 0, 100, 100)\n"
|
">>> e = box2d(0, 0, 100, 100)\n"
|
||||||
">>> e.expand_to_include(110, 110)\n"
|
">>> e.expand_to_include(110, 110)\n"
|
||||||
">>> e\n"
|
">>> e\n"
|
||||||
"Envelope(0.0, 00.0, 110.0, 110.0)\n"
|
"box2d(0.0, 00.0, 110.0, 110.0)\n"
|
||||||
)
|
)
|
||||||
.def("expand_to_include",expand_to_include_p2,
|
.def("expand_to_include",expand_to_include_p2,
|
||||||
(arg("p")),
|
(arg("p")),
|
||||||
"Equivalent to expand_to_include(p.x, p.y)\n"
|
"Equivalent to expand_to_include(p.x, p.y)\n"
|
||||||
)
|
)
|
||||||
.def("expand_to_include",expand_to_include_p3,
|
.def("expand_to_include",expand_to_include_p3,
|
||||||
(arg("other")),
|
(arg("other")),
|
||||||
"Equivalent to:\n"
|
"Equivalent to:\n"
|
||||||
" expand_to_include(other.minx, other.miny)\n"
|
" expand_to_include(other.minx, other.miny)\n"
|
||||||
" expand_to_include(other.maxx, other.maxy)\n"
|
" expand_to_include(other.maxx, other.maxy)\n"
|
||||||
)
|
)
|
||||||
.def("contains",contains_p1,
|
.def("contains",contains_p1,
|
||||||
(arg("x"),arg("y")),
|
(arg("x"),arg("y")),
|
||||||
"Returns True iff this envelope contains the point\n"
|
"Returns True iff this envelope contains the point\n"
|
||||||
"given by x and y.\n"
|
"given by x and y.\n"
|
||||||
)
|
)
|
||||||
.def("contains",contains_p2,
|
.def("contains",contains_p2,
|
||||||
(arg("p")),
|
(arg("p")),
|
||||||
"Equivalent to contains(p.x, p.y)\n"
|
"Equivalent to contains(p.x, p.y)\n"
|
||||||
)
|
)
|
||||||
.def("contains",contains_p3,
|
.def("contains",contains_p3,
|
||||||
(arg("other")),
|
(arg("other")),
|
||||||
"Equivalent to:\n"
|
"Equivalent to:\n"
|
||||||
" contains(other.minx, other.miny) and contains(other.maxx, other.maxy)\n"
|
" contains(other.minx, other.miny) and contains(other.maxx, other.maxy)\n"
|
||||||
)
|
)
|
||||||
.def("intersects",intersects_p1,
|
.def("intersects",intersects_p1,
|
||||||
(arg("x"),arg("y")),
|
(arg("x"),arg("y")),
|
||||||
"Returns True iff this envelope intersects the point\n"
|
"Returns True iff this envelope intersects the point\n"
|
||||||
|
@ -178,7 +178,7 @@ void export_envelope()
|
||||||
"Note: For points, intersection is equivalent\n"
|
"Note: For points, intersection is equivalent\n"
|
||||||
"to containment, i.e. the following holds:\n"
|
"to containment, i.e. the following holds:\n"
|
||||||
" e.contains(x, y) == e.intersects(x, y)\n"
|
" e.contains(x, y) == e.intersects(x, y)\n"
|
||||||
)
|
)
|
||||||
.def("intersects",intersects_p2,
|
.def("intersects",intersects_p2,
|
||||||
(arg("p")),
|
(arg("p")),
|
||||||
"Equivalent to contains(p.x, p.y)\n")
|
"Equivalent to contains(p.x, p.y)\n")
|
||||||
|
@ -188,24 +188,24 @@ void export_envelope()
|
||||||
"This relationship is symmetric."
|
"This relationship is symmetric."
|
||||||
"\n"
|
"\n"
|
||||||
"Example:\n"
|
"Example:\n"
|
||||||
">>> e1 = Envelope(0, 0, 100, 100)\n"
|
">>> e1 = box2d(0, 0, 100, 100)\n"
|
||||||
">>> e2 = Envelope(50, 50, 150, 150)\n"
|
">>> e2 = box2d(50, 50, 150, 150)\n"
|
||||||
">>> e1.intersects(e2)\n"
|
">>> e1.intersects(e2)\n"
|
||||||
"True\n"
|
"True\n"
|
||||||
">>> e1.contains(e2)\n"
|
">>> e1.contains(e2)\n"
|
||||||
"False\n"
|
"False\n"
|
||||||
)
|
)
|
||||||
.def("intersect",intersect,
|
.def("intersect",intersect,
|
||||||
(arg("other")),
|
(arg("other")),
|
||||||
"Returns the overlap of this envelope and the other envelope\n"
|
"Returns the overlap of this envelope and the other envelope\n"
|
||||||
"as a new envelope.\n"
|
"as a new envelope.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Example:\n"
|
"Example:\n"
|
||||||
">>> e1 = Envelope(0, 0, 100, 100)\n"
|
">>> e1 = box2d(0, 0, 100, 100)\n"
|
||||||
">>> e2 = Envelope(50, 50, 150, 150)\n"
|
">>> e2 = box2d(50, 50, 150, 150)\n"
|
||||||
">>> e1.intersect(e2)\n"
|
">>> e1.intersect(e2)\n"
|
||||||
"Envelope(50.0, 50.0, 100.0, 100.0)\n"
|
"box2d(50.0, 50.0, 100.0, 100.0)\n"
|
||||||
)
|
)
|
||||||
.def(self == self) // __eq__
|
.def(self == self) // __eq__
|
||||||
.def(self + self) // __add__
|
.def(self + self) // __add__
|
||||||
.def(self - self) // __sub__
|
.def(self - self) // __sub__
|
||||||
|
|
86
bindings/python/mapnik_expression.cpp
Normal file
86
bindings/python/mapnik_expression.cpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 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>
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/filter_factory.hpp>
|
||||||
|
#include <mapnik/expression_string.hpp>
|
||||||
|
#include <mapnik/expression_evaluator.hpp>
|
||||||
|
#include <mapnik/path_expression_grammar.hpp>
|
||||||
|
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
|
using mapnik::expression_ptr;
|
||||||
|
using mapnik::parse_expression;
|
||||||
|
using mapnik::to_expression_string;
|
||||||
|
using mapnik::path_expression_ptr;
|
||||||
|
|
||||||
|
// expression
|
||||||
|
expression_ptr parse_expression_(std::string const& wkt)
|
||||||
|
{
|
||||||
|
return parse_expression(wkt,"utf8");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string expression_evaluate_(mapnik::expr_node const& expr, mapnik::Feature const& f)
|
||||||
|
{
|
||||||
|
mapnik::value result = boost::apply_visitor(mapnik::evaluate<mapnik::Feature,mapnik::value>(f),expr);
|
||||||
|
return result.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
// path expression
|
||||||
|
path_expression_ptr parse_path_(std::string const& path)
|
||||||
|
{
|
||||||
|
return mapnik::parse_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string path_to_string_(mapnik::path_expression const& expr)
|
||||||
|
{
|
||||||
|
return mapnik::path_processor_type::to_string(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string path_evaluate_(mapnik::path_expression const& expr, mapnik::Feature const& f)
|
||||||
|
{
|
||||||
|
return mapnik::path_processor_type::evaluate(expr, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_expression()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
class_<mapnik::expr_node ,boost::noncopyable>("Expression",
|
||||||
|
"TODO"
|
||||||
|
"",no_init)
|
||||||
|
.def("evaluate", &expression_evaluate_)
|
||||||
|
.def("__str__",&to_expression_string);
|
||||||
|
;
|
||||||
|
|
||||||
|
def("Expression",&parse_expression_);
|
||||||
|
|
||||||
|
class_<mapnik::path_expression ,boost::noncopyable>("PathExpression",
|
||||||
|
"TODO"
|
||||||
|
"",no_init)
|
||||||
|
.def("evaluate", &path_evaluate_) // note: "pass" is a reserved word in Python
|
||||||
|
.def("__str__",&path_to_string_);
|
||||||
|
;
|
||||||
|
|
||||||
|
def("PathExpression",&parse_path_);
|
||||||
|
}
|
|
@ -30,197 +30,246 @@
|
||||||
#include <boost/scoped_array.hpp>
|
#include <boost/scoped_array.hpp>
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
|
||||||
mapnik::geometry2d & (mapnik::Feature::*get_geom1)(unsigned) = &mapnik::Feature::get_geometry;
|
mapnik::geometry2d & (mapnik::Feature::*get_geom1)(unsigned) = &mapnik::Feature::get_geometry;
|
||||||
|
|
||||||
namespace boost { namespace python {
|
namespace boost { namespace python {
|
||||||
struct value_converter : public boost::static_visitor<PyObject*>
|
struct value_converter : public boost::static_visitor<PyObject*>
|
||||||
{
|
{
|
||||||
PyObject * operator() (int val) const
|
PyObject * operator() (int val) const
|
||||||
{
|
{
|
||||||
return ::PyInt_FromLong(val);
|
return ::PyInt_FromLong(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * operator() (double val) const
|
PyObject * operator() (double val) const
|
||||||
{
|
{
|
||||||
return ::PyFloat_FromDouble(val);
|
return ::PyFloat_FromDouble(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * operator() (UnicodeString const& s) const
|
PyObject * operator() (UnicodeString const& s) const
|
||||||
{
|
{
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
mapnik::to_utf8(s,buffer);
|
mapnik::to_utf8(s,buffer);
|
||||||
PyObject *obj = Py_None;
|
PyObject *obj = Py_None;
|
||||||
obj = ::PyUnicode_DecodeUTF8(buffer.c_str(),implicit_cast<ssize_t>(buffer.length()),0);
|
obj = ::PyUnicode_DecodeUTF8(buffer.c_str(),implicit_cast<ssize_t>(buffer.length()),0);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * operator() (mapnik::value_null const& s) const
|
PyObject * operator() (mapnik::value_null const& s) const
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mapnik_value_to_python
|
struct mapnik_value_to_python
|
||||||
{
|
{
|
||||||
static PyObject* convert(mapnik::value const& v)
|
static PyObject* convert(mapnik::value const& v)
|
||||||
{
|
{
|
||||||
return boost::apply_visitor(value_converter(),v.base());
|
return boost::apply_visitor(value_converter(),v.base());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forward declaration
|
// Forward declaration
|
||||||
template <class Container, bool NoProxy, class DerivedPolicies>
|
template <class Container, bool NoProxy, class DerivedPolicies>
|
||||||
class map_indexing_suite2;
|
class map_indexing_suite2;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template <class Container, bool NoProxy>
|
template <class Container, bool NoProxy>
|
||||||
class final_map_derived_policies
|
class final_map_derived_policies
|
||||||
: public map_indexing_suite2<Container,
|
: public map_indexing_suite2<Container,
|
||||||
NoProxy, final_map_derived_policies<Container, NoProxy> > {};
|
NoProxy, final_map_derived_policies<Container, NoProxy> > {};
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
|
||||||
class Container,
|
|
||||||
bool NoProxy = false,
|
|
||||||
class DerivedPolicies
|
|
||||||
= detail::final_map_derived_policies<Container, NoProxy> >
|
|
||||||
class map_indexing_suite2
|
|
||||||
: public indexing_suite<
|
|
||||||
Container
|
|
||||||
, DerivedPolicies
|
|
||||||
, NoProxy
|
|
||||||
, true
|
|
||||||
, typename Container::value_type::second_type
|
|
||||||
, typename Container::key_type
|
|
||||||
, typename Container::key_type
|
|
||||||
>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename Container::value_type value_type;
|
|
||||||
typedef typename Container::value_type::second_type data_type;
|
|
||||||
typedef typename Container::key_type key_type;
|
|
||||||
typedef typename Container::key_type index_type;
|
|
||||||
typedef typename Container::size_type size_type;
|
|
||||||
typedef typename Container::difference_type difference_type;
|
|
||||||
|
|
||||||
template <class Class>
|
|
||||||
static void
|
|
||||||
extension_def(Class& cl)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static data_type&
|
|
||||||
get_item(Container& container, index_type i_)
|
|
||||||
{
|
|
||||||
typename Container::iterator i = container.find(i_);
|
|
||||||
if (i == container.end())
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_KeyError, "Invalid key");
|
|
||||||
throw_error_already_set();
|
|
||||||
}
|
|
||||||
return i->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_item(Container& container, index_type i, data_type const& v)
|
|
||||||
{
|
|
||||||
container[i] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
delete_item(Container& container, index_type i)
|
|
||||||
{
|
|
||||||
container.erase(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
size(Container& container)
|
|
||||||
{
|
|
||||||
return container.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
contains(Container& container, key_type const& key)
|
|
||||||
{
|
|
||||||
return container.find(key) != container.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
compare_index(Container& container, index_type a, index_type b)
|
|
||||||
{
|
|
||||||
return container.key_comp()(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static index_type
|
|
||||||
convert_index(Container& /*container*/, PyObject* i_)
|
|
||||||
{
|
|
||||||
extract<key_type const&> i(i_);
|
|
||||||
if (i.check())
|
|
||||||
{
|
|
||||||
return i();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
extract<key_type> i(i_);
|
|
||||||
if (i.check())
|
|
||||||
return i();
|
|
||||||
}
|
|
||||||
|
|
||||||
PyErr_SetString(PyExc_TypeError, "Invalid index type");
|
|
||||||
throw_error_already_set();
|
|
||||||
return index_type();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
struct std_pair_to_tuple
|
|
||||||
{
|
|
||||||
static PyObject* convert(std::pair<T1, T2> const& p)
|
|
||||||
{
|
|
||||||
return boost::python::incref(
|
|
||||||
boost::python::make_tuple(p.first, p.second).ptr());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
struct std_pair_to_python_converter
|
|
||||||
{
|
|
||||||
std_pair_to_python_converter()
|
|
||||||
{
|
|
||||||
boost::python::to_python_converter<
|
|
||||||
std::pair<T1, T2>,
|
|
||||||
std_pair_to_tuple<T1, T2> >();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Container,
|
||||||
|
bool NoProxy = false,
|
||||||
|
class DerivedPolicies
|
||||||
|
= detail::final_map_derived_policies<Container, NoProxy> >
|
||||||
|
class map_indexing_suite2
|
||||||
|
: public indexing_suite<
|
||||||
|
Container
|
||||||
|
, DerivedPolicies
|
||||||
|
, NoProxy
|
||||||
|
, true
|
||||||
|
, typename Container::value_type::second_type
|
||||||
|
, typename Container::key_type
|
||||||
|
, typename Container::key_type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
typedef typename Container::value_type::second_type data_type;
|
||||||
|
typedef typename Container::key_type key_type;
|
||||||
|
typedef typename Container::key_type index_type;
|
||||||
|
typedef typename Container::size_type size_type;
|
||||||
|
typedef typename Container::difference_type difference_type;
|
||||||
|
|
||||||
|
template <class Class>
|
||||||
|
static void
|
||||||
|
extension_def(Class& cl)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static data_type&
|
||||||
|
get_item(Container& container, index_type i_)
|
||||||
|
{
|
||||||
|
typename Container::iterator i = container.props().find(i_);
|
||||||
|
if (i == container.end())
|
||||||
|
{
|
||||||
|
PyErr_SetString(PyExc_KeyError, "Invalid key");
|
||||||
|
throw_error_already_set();
|
||||||
|
}
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_item(Container& container, index_type i, data_type const& v)
|
||||||
|
{
|
||||||
|
container[i] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
delete_item(Container& container, index_type i)
|
||||||
|
{
|
||||||
|
container.props().erase(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
size(Container& container)
|
||||||
|
{
|
||||||
|
return container.props().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
contains(Container& container, key_type const& key)
|
||||||
|
{
|
||||||
|
return container.props().find(key) != container.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
compare_index(Container& container, index_type a, index_type b)
|
||||||
|
{
|
||||||
|
return container.props().key_comp()(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static index_type
|
||||||
|
convert_index(Container& /*container*/, PyObject* i_)
|
||||||
|
{
|
||||||
|
extract<key_type const&> i(i_);
|
||||||
|
if (i.check())
|
||||||
|
{
|
||||||
|
return i();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extract<key_type> i(i_);
|
||||||
|
if (i.check())
|
||||||
|
return i();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Invalid index type");
|
||||||
|
throw_error_already_set();
|
||||||
|
return index_type();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
struct std_pair_to_tuple
|
||||||
|
{
|
||||||
|
static PyObject* convert(std::pair<T1, T2> const& p)
|
||||||
|
{
|
||||||
|
return boost::python::incref(
|
||||||
|
boost::python::make_tuple(p.first, p.second).ptr());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
struct std_pair_to_python_converter
|
||||||
|
{
|
||||||
|
std_pair_to_python_converter()
|
||||||
|
{
|
||||||
|
boost::python::to_python_converter<
|
||||||
|
std::pair<T1, T2>,
|
||||||
|
std_pair_to_tuple<T1, T2> >();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::feature_ptr create_feature_(int id)
|
||||||
|
{
|
||||||
|
return mapnik::feature_ptr(new mapnik::Feature(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UnicodeString_from_python_str
|
||||||
|
{
|
||||||
|
UnicodeString_from_python_str()
|
||||||
|
{
|
||||||
|
boost::python::converter::registry::push_back(
|
||||||
|
&convertible,
|
||||||
|
&construct,
|
||||||
|
boost::python::type_id<UnicodeString>());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* convertible(PyObject* obj_ptr)
|
||||||
|
{
|
||||||
|
if (!PyString_Check(obj_ptr)) return 0;
|
||||||
|
return obj_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void construct(
|
||||||
|
PyObject* obj_ptr,
|
||||||
|
boost::python::converter::rvalue_from_python_stage1_data* data)
|
||||||
|
{
|
||||||
|
const char* value = PyString_AsString(obj_ptr);
|
||||||
|
if (value == 0) boost::python::throw_error_already_set();
|
||||||
|
void* storage = (
|
||||||
|
(boost::python::converter::rvalue_from_python_storage<UnicodeString>*)
|
||||||
|
data)->storage.bytes;
|
||||||
|
new (storage) UnicodeString(value);
|
||||||
|
data->convertible = storage;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void export_feature()
|
void export_feature()
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
using mapnik::Feature;
|
using mapnik::Feature;
|
||||||
|
|
||||||
std_pair_to_python_converter<std::string const,mapnik::value>();
|
implicitly_convertible<int,mapnik::value>();
|
||||||
to_python_converter<mapnik::value,mapnik_value_to_python>();
|
implicitly_convertible<double,mapnik::value>();
|
||||||
class_<Feature,boost::shared_ptr<Feature>,
|
implicitly_convertible<UnicodeString,mapnik::value>();
|
||||||
boost::noncopyable>("Feature",no_init)
|
implicitly_convertible<bool,mapnik::value>();
|
||||||
.def("id",&Feature::id)
|
|
||||||
.def("__str__",&Feature::to_string)
|
|
||||||
.add_property("properties",
|
|
||||||
make_function(&Feature::props,return_value_policy<reference_existing_object>()))
|
|
||||||
// .def("add_geometry", // TODO define more mapnik::Feature methods
|
|
||||||
.def("num_geometries",&Feature::num_geometries)
|
|
||||||
.def("get_geometry", make_function(get_geom1,return_value_policy<reference_existing_object>()))
|
|
||||||
.def("envelope", &Feature::envelope)
|
|
||||||
;
|
|
||||||
|
|
||||||
class_<std::map<std::string, mapnik::value> >("Properties")
|
std_pair_to_python_converter<std::string const,mapnik::value>();
|
||||||
.def(map_indexing_suite2<std::map<std::string, mapnik::value>, true >())
|
to_python_converter<mapnik::value,mapnik_value_to_python>();
|
||||||
.def("iteritems",iterator<std::map<std::string,mapnik::value> > ())
|
UnicodeString_from_python_str();
|
||||||
;
|
|
||||||
|
class_<Feature,boost::shared_ptr<Feature>,
|
||||||
|
boost::noncopyable>("Feature",no_init)
|
||||||
|
.def("id",&Feature::id)
|
||||||
|
.def("__str__",&Feature::to_string)
|
||||||
|
// .add_property("properties",
|
||||||
|
// make_function(&Feature::props,return_value_policy<reference_existing_object>()))
|
||||||
|
// .def("add_geometry", // TODO define more mapnik::Feature methods
|
||||||
|
.def("num_geometries",&Feature::num_geometries)
|
||||||
|
.def("get_geometry", make_function(get_geom1,return_value_policy<reference_existing_object>()))
|
||||||
|
.def("envelope", &Feature::envelope)
|
||||||
|
.def("create",create_feature_)
|
||||||
|
.staticmethod("create")
|
||||||
|
.def(map_indexing_suite2<Feature, true >())
|
||||||
|
.def("iteritems",iterator<Feature> ())
|
||||||
|
;
|
||||||
|
|
||||||
|
//def("Feature", &create_feature_);
|
||||||
|
|
||||||
|
//class_<std::map<std::string, mapnik::value> >("Properties")
|
||||||
|
// .def(map_indexing_suite2<std::map<std::string, mapnik::value>, true >())
|
||||||
|
// .def("iteritems",iterator<std::map<std::string,mapnik::value> > ())
|
||||||
|
// ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,52 +43,57 @@ extern "C"
|
||||||
#include <pycairo.h>
|
#include <pycairo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using mapnik::Image32;
|
using mapnik::image_32;
|
||||||
using mapnik::ImageReader;
|
using mapnik::image_reader;
|
||||||
using mapnik::get_image_reader;
|
using mapnik::get_image_reader;
|
||||||
using mapnik::type_from_filename;
|
using mapnik::type_from_filename;
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
using mapnik::save_to_file;
|
using mapnik::save_to_file;
|
||||||
|
|
||||||
// output 'raw' pixels
|
// output 'raw' pixels
|
||||||
PyObject* tostring1( Image32 const& im)
|
PyObject* tostring1( image_32 const& im)
|
||||||
{
|
{
|
||||||
int size = im.width() * im.height() * 4;
|
int size = im.width() * im.height() * 4;
|
||||||
return ::PyString_FromStringAndSize((const char*)im.raw_data(),size);
|
return ::PyString_FromStringAndSize((const char*)im.raw_data(),size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// encode (png,jpeg)
|
// encode (png,jpeg)
|
||||||
PyObject* tostring2(Image32 const & im, std::string const& format)
|
PyObject* tostring2(image_32 const & im, std::string const& format)
|
||||||
{
|
{
|
||||||
std::string s = save_to_string(im, format);
|
std::string s = save_to_string(im, format);
|
||||||
return ::PyString_FromStringAndSize(s.data(),s.size());
|
return ::PyString_FromStringAndSize(s.data(),s.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*save_to_file1)( mapnik::Image32 const&, std::string const&,std::string const&) = mapnik::save_to_file;
|
void (*save_to_file1)( mapnik::image_32 const&, std::string const&,std::string const&) = mapnik::save_to_file;
|
||||||
void (*save_to_file2)( mapnik::Image32 const&, std::string const&) = mapnik::save_to_file;
|
void (*save_to_file2)( mapnik::image_32 const&, std::string const&) = mapnik::save_to_file;
|
||||||
|
|
||||||
boost::shared_ptr<Image32> open_from_file(std::string const& filename)
|
boost::shared_ptr<image_32> open_from_file(std::string const& filename)
|
||||||
{
|
{
|
||||||
std::auto_ptr<ImageReader> reader(get_image_reader(filename,type_from_filename(filename)));
|
boost::optional<std::string> type = type_from_filename(filename);
|
||||||
if (reader.get())
|
if (type)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Image32> image_ptr(new Image32(reader->width(),reader->height()));
|
std::auto_ptr<image_reader> reader(get_image_reader(filename,*type));
|
||||||
reader->read(0,0,image_ptr->data());
|
if (reader.get())
|
||||||
return image_ptr;
|
{
|
||||||
}
|
boost::shared_ptr<image_32> image_ptr(new image_32(reader->width(),reader->height()));
|
||||||
throw mapnik::ImageReaderException("FIXME: " + filename);
|
reader->read(0,0,image_ptr->data());
|
||||||
|
return image_ptr;
|
||||||
|
}
|
||||||
|
throw mapnik::image_reader_exception("Failed to load: " + filename);
|
||||||
|
}
|
||||||
|
throw mapnik::image_reader_exception("Unsupported image format:" + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void blend (Image32 & im, unsigned x, unsigned y, Image32 const& im2, float opacity)
|
void blend (image_32 & im, unsigned x, unsigned y, image_32 const& im2, float opacity)
|
||||||
{
|
{
|
||||||
im.set_rectangle_alpha2(im2.data(),x,y,opacity);
|
im.set_rectangle_alpha2(im2.data(),x,y,opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
||||||
boost::shared_ptr<Image32> from_cairo(PycairoSurface* surface)
|
boost::shared_ptr<image_32> from_cairo(PycairoSurface* surface)
|
||||||
{
|
{
|
||||||
Cairo::RefPtr<Cairo::ImageSurface> s(new Cairo::ImageSurface(surface->surface));
|
Cairo::RefPtr<Cairo::ImageSurface> s(new Cairo::ImageSurface(surface->surface));
|
||||||
boost::shared_ptr<Image32> image_ptr(new Image32(s));
|
boost::shared_ptr<image_32> image_ptr(new image_32(s));
|
||||||
return image_ptr;
|
return image_ptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -96,13 +101,13 @@ boost::shared_ptr<Image32> from_cairo(PycairoSurface* surface)
|
||||||
void export_image()
|
void export_image()
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
class_<Image32,boost::shared_ptr<Image32> >("Image","This class represents a 32 bit RGBA image.",init<int,int>())
|
class_<image_32,boost::shared_ptr<image_32> >("Image","This class represents a 32 bit RGBA image.",init<int,int>())
|
||||||
.def("width",&Image32::width)
|
.def("width",&image_32::width)
|
||||||
.def("height",&Image32::height)
|
.def("height",&image_32::height)
|
||||||
.def("view",&Image32::get_view)
|
.def("view",&image_32::get_view)
|
||||||
.add_property("background",make_function
|
.add_property("background",make_function
|
||||||
(&Image32::getBackground,return_value_policy<copy_const_reference>()),
|
(&image_32::get_background,return_value_policy<copy_const_reference>()),
|
||||||
&Image32::setBackground, "The background color of the image.")
|
&image_32::set_background, "The background color of the image.")
|
||||||
.def("blend",&blend)
|
.def("blend",&blend)
|
||||||
.def("tostring",&tostring1)
|
.def("tostring",&tostring1)
|
||||||
.def("tostring",&tostring2)
|
.def("tostring",&tostring2)
|
||||||
|
|
|
@ -33,38 +33,38 @@ extern "C"
|
||||||
#include <mapnik/png_io.hpp>
|
#include <mapnik/png_io.hpp>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
using mapnik::ImageData32;
|
using mapnik::image_data_32;
|
||||||
using mapnik::image_view;
|
using mapnik::image_view;
|
||||||
using mapnik::save_to_file;
|
using mapnik::save_to_file;
|
||||||
|
|
||||||
// output 'raw' pixels
|
// output 'raw' pixels
|
||||||
PyObject* view_tostring1(image_view<ImageData32> const& view)
|
PyObject* view_tostring1(image_view<image_data_32> const& view)
|
||||||
{
|
{
|
||||||
std::ostringstream ss(std::ios::out|std::ios::binary);
|
std::ostringstream ss(std::ios::out|std::ios::binary);
|
||||||
for (unsigned i=0;i<view.height();i++)
|
for (unsigned i=0;i<view.height();i++)
|
||||||
{
|
{
|
||||||
ss.write(reinterpret_cast<const char*>(view.getRow(i)),
|
ss.write(reinterpret_cast<const char*>(view.getRow(i)),
|
||||||
view.width() * sizeof(image_view<ImageData32>::pixel_type));
|
view.width() * sizeof(image_view<image_data_32>::pixel_type));
|
||||||
}
|
}
|
||||||
return ::PyString_FromStringAndSize((const char*)ss.str().c_str(),ss.str().size());
|
return ::PyString_FromStringAndSize((const char*)ss.str().c_str(),ss.str().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// encode (png,jpeg)
|
// encode (png,jpeg)
|
||||||
PyObject* view_tostring2(image_view<ImageData32> const & view, std::string const& format)
|
PyObject* view_tostring2(image_view<image_data_32> const & view, std::string const& format)
|
||||||
{
|
{
|
||||||
std::string s = save_to_string(view, format);
|
std::string s = save_to_string(view, format);
|
||||||
return ::PyString_FromStringAndSize(s.data(),s.size());
|
return ::PyString_FromStringAndSize(s.data(),s.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*save_view1)(image_view<ImageData32> const&, std::string const&,std::string const&) = mapnik::save_to_file;
|
void (*save_view1)(image_view<image_data_32> const&, std::string const&,std::string const&) = mapnik::save_to_file;
|
||||||
void (*save_view2)(image_view<ImageData32> const&, std::string const&) = mapnik::save_to_file;
|
void (*save_view2)(image_view<image_data_32> const&, std::string const&) = mapnik::save_to_file;
|
||||||
|
|
||||||
void export_image_view()
|
void export_image_view()
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
class_<image_view<ImageData32> >("ImageView","A view into an image.",no_init)
|
class_<image_view<image_data_32> >("ImageView","A view into an image.",no_init)
|
||||||
.def("width",&image_view<ImageData32>::width)
|
.def("width",&image_view<image_data_32>::width)
|
||||||
.def("height",&image_view<ImageData32>::height)
|
.def("height",&image_view<image_data_32>::height)
|
||||||
.def("tostring",&view_tostring1)
|
.def("tostring",&view_tostring1)
|
||||||
.def("tostring",&view_tostring2)
|
.def("tostring",&view_tostring2)
|
||||||
.def("save",save_view1)
|
.def("save",save_view1)
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <mapnik/datasource.hpp>
|
#include <mapnik/datasource.hpp>
|
||||||
#include <mapnik/datasource_cache.hpp>
|
#include <mapnik/datasource_cache.hpp>
|
||||||
|
|
||||||
using mapnik::Layer;
|
using mapnik::layer;
|
||||||
using mapnik::parameters;
|
using mapnik::parameters;
|
||||||
using mapnik::datasource_cache;
|
using mapnik::datasource_cache;
|
||||||
|
|
||||||
|
@ -40,13 +40,13 @@ using mapnik::datasource_cache;
|
||||||
struct layer_pickle_suite : boost::python::pickle_suite
|
struct layer_pickle_suite : boost::python::pickle_suite
|
||||||
{
|
{
|
||||||
static boost::python::tuple
|
static boost::python::tuple
|
||||||
getinitargs(const Layer& l)
|
getinitargs(const layer& l)
|
||||||
{
|
{
|
||||||
return boost::python::make_tuple(l.name(),l.srs());
|
return boost::python::make_tuple(l.name(),l.srs());
|
||||||
}
|
}
|
||||||
|
|
||||||
static boost::python::tuple
|
static boost::python::tuple
|
||||||
getstate(const Layer& l)
|
getstate(const layer& l)
|
||||||
{
|
{
|
||||||
boost::python::list s;
|
boost::python::list s;
|
||||||
std::vector<std::string> const& style_names = l.styles();
|
std::vector<std::string> const& style_names = l.styles();
|
||||||
|
@ -58,7 +58,7 @@ struct layer_pickle_suite : boost::python::pickle_suite
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setstate (Layer& l, boost::python::tuple state)
|
setstate (layer& l, boost::python::tuple state)
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
if (len(state) != 8)
|
if (len(state) != 8)
|
||||||
|
@ -114,7 +114,7 @@ struct layer_pickle_suite : boost::python::pickle_suite
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::string> & (mapnik::Layer::*_styles_)() = &mapnik::Layer::styles;
|
std::vector<std::string> & (mapnik::layer::*_styles_)() = &mapnik::layer::styles;
|
||||||
|
|
||||||
void export_layer()
|
void export_layer()
|
||||||
{
|
{
|
||||||
|
@ -123,7 +123,7 @@ void export_layer()
|
||||||
.def(vector_indexing_suite<std::vector<std::string>,true >())
|
.def(vector_indexing_suite<std::vector<std::string>,true >())
|
||||||
;
|
;
|
||||||
|
|
||||||
class_<Layer>("Layer", "A Mapnik map layer.", init<std::string const&,optional<std::string const&> >(
|
class_<layer>("Layer", "A Mapnik map layer.", init<std::string const&,optional<std::string const&> >(
|
||||||
"Create a Layer with a named string and, optionally, an srs string.\n"
|
"Create a Layer with a named string and, optionally, an srs string.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"The srs can be either a Proj.4 epsg code ('+init=epsg:<code>') or\n"
|
"The srs can be either a Proj.4 epsg code ('+init=epsg:<code>') or\n"
|
||||||
|
@ -139,7 +139,7 @@ void export_layer()
|
||||||
|
|
||||||
.def_pickle(layer_pickle_suite())
|
.def_pickle(layer_pickle_suite())
|
||||||
|
|
||||||
.def("envelope",&Layer::envelope,
|
.def("envelope",&layer::envelope,
|
||||||
"Return the geographic envelope/bounding box."
|
"Return the geographic envelope/bounding box."
|
||||||
"\n"
|
"\n"
|
||||||
"Determined based on the layer datasource.\n"
|
"Determined based on the layer datasource.\n"
|
||||||
|
@ -148,10 +148,10 @@ void export_layer()
|
||||||
">>> from mapnik import Layer\n"
|
">>> from mapnik import Layer\n"
|
||||||
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
|
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
|
||||||
">>> lyr.envelope()\n"
|
">>> lyr.envelope()\n"
|
||||||
"Envelope(-1.0,-1.0,0.0,0.0) # default until a datasource is loaded\n"
|
"box2d(-1.0,-1.0,0.0,0.0) # default until a datasource is loaded\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
.def("visible", &Layer::isVisible,
|
.def("visible", &layer::isVisible,
|
||||||
"Return True if this layer's data is active and visible at a given scale.\n"
|
"Return True if this layer's data is active and visible at a given scale.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Otherwise returns False.\n"
|
"Otherwise returns False.\n"
|
||||||
|
@ -172,8 +172,8 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("abstract",
|
.add_property("abstract",
|
||||||
make_function(&Layer::abstract,return_value_policy<copy_const_reference>()),
|
make_function(&layer::abstract,return_value_policy<copy_const_reference>()),
|
||||||
&Layer::set_abstract,
|
&layer::set_abstract,
|
||||||
"Get/Set the abstract of the layer.\n"
|
"Get/Set the abstract of the layer.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
|
@ -187,8 +187,8 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("active",
|
.add_property("active",
|
||||||
&Layer::isActive,
|
&layer::isActive,
|
||||||
&Layer::setActive,
|
&layer::setActive,
|
||||||
"Get/Set whether this layer is active and will be rendered.\n"
|
"Get/Set whether this layer is active and will be rendered.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
|
@ -202,8 +202,8 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("clear_label_cache",
|
.add_property("clear_label_cache",
|
||||||
&Layer::clear_label_cache,
|
&layer::clear_label_cache,
|
||||||
&Layer::set_clear_label_cache,
|
&layer::set_clear_label_cache,
|
||||||
"Get/Set whether this layer's labels are cached.\n"
|
"Get/Set whether this layer's labels are cached.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
|
@ -211,8 +211,8 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("datasource",
|
.add_property("datasource",
|
||||||
&Layer::datasource,
|
&layer::datasource,
|
||||||
&Layer::set_datasource,
|
&layer::set_datasource,
|
||||||
"The datasource attached to this layer.\n"
|
"The datasource attached to this layer.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
|
@ -224,8 +224,8 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("maxzoom",
|
.add_property("maxzoom",
|
||||||
&Layer::getMaxZoom,
|
&layer::getMaxZoom,
|
||||||
&Layer::setMaxZoom,
|
&layer::setMaxZoom,
|
||||||
"Get/Set the maximum zoom lever of the layer.\n"
|
"Get/Set the maximum zoom lever of the layer.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
|
@ -239,8 +239,8 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("minzoom",
|
.add_property("minzoom",
|
||||||
&Layer::getMinZoom,
|
&layer::getMinZoom,
|
||||||
&Layer::setMinZoom,
|
&layer::setMinZoom,
|
||||||
"Get/Set the minimum zoom lever of the layer.\n"
|
"Get/Set the minimum zoom lever of the layer.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
|
@ -254,8 +254,8 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("name",
|
.add_property("name",
|
||||||
make_function(&Layer::name, return_value_policy<copy_const_reference>()),
|
make_function(&layer::name, return_value_policy<copy_const_reference>()),
|
||||||
&Layer::set_name,
|
&layer::set_name,
|
||||||
"Get/Set the name of the layer.\n"
|
"Get/Set the name of the layer.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
|
@ -269,13 +269,13 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("queryable",
|
.add_property("queryable",
|
||||||
&Layer::isQueryable,
|
&layer::isQueryable,
|
||||||
&Layer::setQueryable,
|
&layer::setQueryable,
|
||||||
"Get/Set whether this layer is queryable.\n"
|
"Get/Set whether this layer is queryable.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> from mapnik import Layer\n"
|
">>> from mapnik import layer\n"
|
||||||
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
|
">>> lyr = layer('My layer','+proj=latlong +datum=WGS84')\n"
|
||||||
">>> lyr.queryable\n"
|
">>> lyr.queryable\n"
|
||||||
"False # Not queryable by default\n"
|
"False # Not queryable by default\n"
|
||||||
">>> lyr.queryable = True\n"
|
">>> lyr.queryable = True\n"
|
||||||
|
@ -284,13 +284,13 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("srs",
|
.add_property("srs",
|
||||||
make_function(&Layer::srs,return_value_policy<copy_const_reference>()),
|
make_function(&layer::srs,return_value_policy<copy_const_reference>()),
|
||||||
&Layer::set_srs,
|
&layer::set_srs,
|
||||||
"Get/Set the SRS of the layer.\n"
|
"Get/Set the SRS of the layer.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> from mapnik import Layer\n"
|
">>> from mapnik import layer\n"
|
||||||
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
|
">>> lyr = layer('My layer','+proj=latlong +datum=WGS84')\n"
|
||||||
">>> lyr.srs\n"
|
">>> lyr.srs\n"
|
||||||
"'+proj=latlong +datum=WGS84' # The default srs if not initialized with custom srs\n"
|
"'+proj=latlong +datum=WGS84' # The default srs if not initialized with custom srs\n"
|
||||||
">>> # set to google mercator with Proj.4 literal\n"
|
">>> # set to google mercator with Proj.4 literal\n"
|
||||||
|
@ -303,8 +303,8 @@ void export_layer()
|
||||||
"The styles list attached to this layer.\n"
|
"The styles list attached to this layer.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> from mapnik import Layer\n"
|
">>> from mapnik import layer\n"
|
||||||
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
|
">>> lyr = layer('My layer','+proj=latlong +datum=WGS84')\n"
|
||||||
">>> lyr.styles\n"
|
">>> lyr.styles\n"
|
||||||
"<mapnik._mapnik.Names object at 0x6d3e8>\n"
|
"<mapnik._mapnik.Names object at 0x6d3e8>\n"
|
||||||
">>> len(lyr.styles)\n"
|
">>> len(lyr.styles)\n"
|
||||||
|
@ -317,13 +317,13 @@ void export_layer()
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("title",
|
.add_property("title",
|
||||||
make_function(&Layer::title, return_value_policy<copy_const_reference>()),
|
make_function(&layer::title, return_value_policy<copy_const_reference>()),
|
||||||
&Layer::set_title,
|
&layer::set_title,
|
||||||
"Get/Set the title of the layer.\n"
|
"Get/Set the title of the layer.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> from mapnik import Layer\n"
|
">>> from mapnik import layer\n"
|
||||||
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
|
">>> lyr = layer('My layer','+proj=latlong +datum=WGS84')\n"
|
||||||
">>> lyr.title\n"
|
">>> lyr.title\n"
|
||||||
"''\n"
|
"''\n"
|
||||||
">>> lyr.title = 'My first layer'\n"
|
">>> lyr.title = 'My first layer'\n"
|
||||||
|
|
|
@ -22,19 +22,25 @@
|
||||||
//$Id$
|
//$Id$
|
||||||
|
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <mapnik/image_util.hpp>
|
|
||||||
#include <mapnik/line_pattern_symbolizer.hpp>
|
#include <mapnik/line_pattern_symbolizer.hpp>
|
||||||
|
#include <mapnik/path_expression_grammar.hpp>
|
||||||
|
#include <mapnik/image_util.hpp>
|
||||||
|
|
||||||
using mapnik::line_pattern_symbolizer;
|
using mapnik::line_pattern_symbolizer;
|
||||||
|
using mapnik::path_processor_type;
|
||||||
|
using mapnik::path_expression_ptr;
|
||||||
|
using mapnik::guess_type;
|
||||||
|
|
||||||
|
|
||||||
struct line_pattern_symbolizer_pickle_suite : boost::python::pickle_suite
|
struct line_pattern_symbolizer_pickle_suite : boost::python::pickle_suite
|
||||||
{
|
{
|
||||||
static boost::python::tuple
|
static boost::python::tuple
|
||||||
getinitargs(const line_pattern_symbolizer& l)
|
getinitargs(const line_pattern_symbolizer& l)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<mapnik::ImageData32> img = l.get_image();
|
std::string filename = path_processor_type::to_string(*l.get_filename());
|
||||||
const std::string & filename = l.get_filename();
|
// FIXME : Do we need "type" parameter at all ?
|
||||||
return boost::python::make_tuple(filename,mapnik::guess_type(filename),img->width(),img->height());
|
return boost::python::make_tuple(filename, guess_type(filename));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,8 +49,8 @@ void export_line_pattern_symbolizer()
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
|
||||||
class_<line_pattern_symbolizer>("LinePatternSymbolizer",
|
class_<line_pattern_symbolizer>("LinePatternSymbolizer",
|
||||||
init<std::string const&,
|
init<path_expression_ptr>
|
||||||
std::string const&,unsigned,unsigned>("TODO"))
|
("<image file expression>"))
|
||||||
.def_pickle(line_pattern_symbolizer_pickle_suite())
|
//.def_pickle(line_pattern_symbolizer_pickle_suite())
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
|
|
||||||
using mapnik::color;
|
using mapnik::color;
|
||||||
using mapnik::coord;
|
using mapnik::coord;
|
||||||
using mapnik::Envelope;
|
using mapnik::box2d;
|
||||||
using mapnik::Layer;
|
using mapnik::layer;
|
||||||
using mapnik::Map;
|
using mapnik::Map;
|
||||||
|
|
||||||
struct map_pickle_suite : boost::python::pickle_suite
|
struct map_pickle_suite : boost::python::pickle_suite
|
||||||
|
@ -84,7 +84,7 @@ struct map_pickle_suite : boost::python::pickle_suite
|
||||||
throw_error_already_set();
|
throw_error_already_set();
|
||||||
}
|
}
|
||||||
|
|
||||||
Envelope<double> ext = extract<Envelope<double> >(state[0]);
|
box2d<double> ext = extract<box2d<double> >(state[0]);
|
||||||
m.zoomToBox(ext);
|
m.zoomToBox(ext);
|
||||||
if (state[1])
|
if (state[1])
|
||||||
{
|
{
|
||||||
|
@ -95,7 +95,7 @@ struct map_pickle_suite : boost::python::pickle_suite
|
||||||
boost::python::list l=extract<boost::python::list>(state[2]);
|
boost::python::list l=extract<boost::python::list>(state[2]);
|
||||||
for (int i=0;i<len(l);++i)
|
for (int i=0;i<len(l);++i)
|
||||||
{
|
{
|
||||||
m.addLayer(extract<Layer>(l[i]));
|
m.addLayer(extract<layer>(l[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::python::list s=extract<boost::python::list>(state[3]);
|
boost::python::list s=extract<boost::python::list>(state[3]);
|
||||||
|
@ -109,8 +109,8 @@ struct map_pickle_suite : boost::python::pickle_suite
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Layer>& (Map::*layers_nonconst)() = &Map::layers;
|
std::vector<layer>& (Map::*layers_nonconst)() = &Map::layers;
|
||||||
std::vector<Layer> const& (Map::*layers_const)() const = &Map::layers;
|
std::vector<layer> const& (Map::*layers_const)() const = &Map::layers;
|
||||||
|
|
||||||
|
|
||||||
mapnik::feature_type_style find_style (mapnik::Map const& m, std::string const& name)
|
mapnik::feature_type_style find_style (mapnik::Map const& m, std::string const& name)
|
||||||
|
@ -141,8 +141,8 @@ void export_map()
|
||||||
;
|
;
|
||||||
|
|
||||||
python_optional<mapnik::color> ();
|
python_optional<mapnik::color> ();
|
||||||
class_<std::vector<Layer> >("Layers")
|
class_<std::vector<layer> >("Layers")
|
||||||
.def(vector_indexing_suite<std::vector<Layer> >())
|
.def(vector_indexing_suite<std::vector<layer> >())
|
||||||
;
|
;
|
||||||
|
|
||||||
class_<Map>("Map","The map object.",init<int,int,optional<std::string const&> >(
|
class_<Map>("Map","The map object.",init<int,int,optional<std::string const&> >(
|
||||||
|
@ -178,30 +178,30 @@ void export_map()
|
||||||
|
|
||||||
.def("buffered_envelope",
|
.def("buffered_envelope",
|
||||||
&Map::get_buffered_extent,
|
&Map::get_buffered_extent,
|
||||||
"Get the Envelope() of the Map given\n"
|
"Get the box2d() of the Map given\n"
|
||||||
"the Map.buffer_size.\n"
|
"the Map.buffer_size.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> m = Map(600,400)\n"
|
">>> m = Map(600,400)\n"
|
||||||
">>> m.envelope()\n"
|
">>> m.envelope()\n"
|
||||||
"Envelope(-1.0,-1.0,0.0,0.0)\n"
|
"box2d(-1.0,-1.0,0.0,0.0)\n"
|
||||||
">>> m.buffered_envelope()\n"
|
">>> m.buffered_envelope()\n"
|
||||||
"Envelope(-1.0,-1.0,0.0,0.0)\n"
|
"box2d(-1.0,-1.0,0.0,0.0)\n"
|
||||||
">>> m.buffer_size = 1\n"
|
">>> m.buffer_size = 1\n"
|
||||||
">>> m.buffered_envelope()\n"
|
">>> m.buffered_envelope()\n"
|
||||||
"Envelope(-1.02222222222,-1.02222222222,0.0222222222222,0.0222222222222)\n"
|
"box2d(-1.02222222222,-1.02222222222,0.0222222222222,0.0222222222222)\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
.def("envelope",
|
.def("envelope",
|
||||||
make_function(&Map::getCurrentExtent,
|
make_function(&Map::getCurrentExtent,
|
||||||
return_value_policy<copy_const_reference>()),
|
return_value_policy<copy_const_reference>()),
|
||||||
"Return the Map Envelope object\n"
|
"Return the Map box2d object\n"
|
||||||
"and print the string representation\n"
|
"and print the string representation\n"
|
||||||
"of the current extent of the map.\n"
|
"of the current extent of the map.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> m.envelope()\n"
|
">>> m.envelope()\n"
|
||||||
"Envelope(-0.185833333333,-0.96,0.189166666667,-0.71)\n"
|
"box2d(-0.185833333333,-0.96,0.189166666667,-0.71)\n"
|
||||||
">>> dir(m.envelope())\n"
|
">>> dir(m.envelope())\n"
|
||||||
"...'center', 'contains', 'expand_to_include', 'forward',\n"
|
"...'center', 'contains', 'expand_to_include', 'forward',\n"
|
||||||
"...'height', 'intersect', 'intersects', 'inverse', 'maxx',\n"
|
"...'height', 'intersect', 'intersects', 'inverse', 'maxx',\n"
|
||||||
|
@ -285,7 +285,7 @@ void export_map()
|
||||||
)
|
)
|
||||||
|
|
||||||
.def("remove_all",&Map::remove_all,
|
.def("remove_all",&Map::remove_all,
|
||||||
"Remove all Mapnik Styles and Layers from the Map.\n"
|
"Remove all Mapnik Styles and layers from the Map.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> m.remove_all()\n"
|
">>> m.remove_all()\n"
|
||||||
|
@ -343,10 +343,10 @@ void export_map()
|
||||||
|
|
||||||
.def("zoom_to_box",&Map::zoomToBox,
|
.def("zoom_to_box",&Map::zoomToBox,
|
||||||
"Set the geographical extent of the map\n"
|
"Set the geographical extent of the map\n"
|
||||||
"by specifying a Mapnik Envelope.\n"
|
"by specifying a Mapnik box2d.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> extext = Envelope(-180.0, -90.0, 180.0, 90.0)\n"
|
">>> extext = box2d(-180.0, -90.0, 180.0, 90.0)\n"
|
||||||
">>> m.zoom_to_box(extent)\n"
|
">>> m.zoom_to_box(extent)\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -401,9 +401,9 @@ void export_map()
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> m.layers\n"
|
">>> m.layers\n"
|
||||||
"<mapnik._mapnik.Layers object at 0x6d458>"
|
"<mapnik._mapnik.layers object at 0x6d458>"
|
||||||
">>> m.layers[0]\n"
|
">>> m.layers[0]\n"
|
||||||
"<mapnik._mapnik.Layer object at 0x5fe130>\n"
|
"<mapnik._mapnik.layer object at 0x5fe130>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
.add_property("srs",
|
.add_property("srs",
|
||||||
|
|
|
@ -25,25 +25,19 @@
|
||||||
#include <mapnik/graphics.hpp>
|
#include <mapnik/graphics.hpp>
|
||||||
#include <mapnik/image_util.hpp>
|
#include <mapnik/image_util.hpp>
|
||||||
#include <mapnik/point_symbolizer.hpp>
|
#include <mapnik/point_symbolizer.hpp>
|
||||||
|
#include <mapnik/path_expression_grammar.hpp>
|
||||||
|
|
||||||
using mapnik::point_symbolizer;
|
using mapnik::point_symbolizer;
|
||||||
using mapnik::symbolizer_with_image;
|
using mapnik::symbolizer_with_image;
|
||||||
|
using mapnik::path_processor_type;
|
||||||
|
|
||||||
struct point_symbolizer_pickle_suite : boost::python::pickle_suite
|
struct point_symbolizer_pickle_suite : boost::python::pickle_suite
|
||||||
{
|
{
|
||||||
static boost::python::tuple
|
static boost::python::tuple
|
||||||
getinitargs(const point_symbolizer& p)
|
getinitargs(const point_symbolizer& p)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<mapnik::ImageData32> img = p.get_image();
|
std::string filename = path_processor_type::to_string(*p.get_filename());
|
||||||
const std::string & filename = p.get_filename();
|
return boost::python::make_tuple(filename,mapnik::guess_type(filename));
|
||||||
|
|
||||||
if ( ! filename.empty() ) {
|
|
||||||
return boost::python::make_tuple(filename,mapnik::guess_type(filename),img->width(),img->height());
|
|
||||||
} else {
|
|
||||||
return boost::python::make_tuple();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boost::python::tuple
|
static boost::python::tuple
|
||||||
|
@ -74,12 +68,12 @@ struct point_symbolizer_pickle_suite : boost::python::pickle_suite
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
const std::string get_filename(mapnik::point_symbolizer& symbolizer)
|
||||||
|
{
|
||||||
|
return path_processor_type::to_string(*symbolizer.get_filename());
|
||||||
|
}
|
||||||
|
|
||||||
const char *get_filename(mapnik::point_symbolizer& symbolizer)
|
|
||||||
{
|
|
||||||
return symbolizer.get_filename().c_str();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void export_point_symbolizer()
|
void export_point_symbolizer()
|
||||||
|
@ -88,9 +82,8 @@ void export_point_symbolizer()
|
||||||
|
|
||||||
class_<point_symbolizer>("PointSymbolizer",
|
class_<point_symbolizer>("PointSymbolizer",
|
||||||
init<>("Default Point Symbolizer - 4x4 black square"))
|
init<>("Default Point Symbolizer - 4x4 black square"))
|
||||||
.def (init<std::string const&,
|
.def (init<mapnik::path_expression_ptr>("<path expression ptr>"))
|
||||||
std::string const&,unsigned,unsigned>("TODO"))
|
//.def_pickle(point_symbolizer_pickle_suite())
|
||||||
.def_pickle(point_symbolizer_pickle_suite())
|
|
||||||
.add_property("filename",
|
.add_property("filename",
|
||||||
// DS - Using workaround as the normal make_function does not work for unknown reasons...
|
// DS - Using workaround as the normal make_function does not work for unknown reasons...
|
||||||
//make_function(&point_symbolizer::get_filename,return_value_policy<copy_const_reference>()),
|
//make_function(&point_symbolizer::get_filename,return_value_policy<copy_const_reference>()),
|
||||||
|
|
|
@ -24,17 +24,20 @@
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <mapnik/image_util.hpp>
|
#include <mapnik/image_util.hpp>
|
||||||
#include <mapnik/polygon_pattern_symbolizer.hpp>
|
#include <mapnik/polygon_pattern_symbolizer.hpp>
|
||||||
|
#include <mapnik/path_expression_grammar.hpp>
|
||||||
|
|
||||||
using mapnik::polygon_pattern_symbolizer;
|
using mapnik::polygon_pattern_symbolizer;
|
||||||
|
using mapnik::path_expression_ptr;
|
||||||
|
using mapnik::path_processor_type;
|
||||||
|
using mapnik::guess_type;
|
||||||
|
|
||||||
struct polygon_pattern_symbolizer_pickle_suite : boost::python::pickle_suite
|
struct polygon_pattern_symbolizer_pickle_suite : boost::python::pickle_suite
|
||||||
{
|
{
|
||||||
static boost::python::tuple
|
static boost::python::tuple
|
||||||
getinitargs(const polygon_pattern_symbolizer& p)
|
getinitargs(const polygon_pattern_symbolizer& p)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<mapnik::ImageData32> img = p.get_image();
|
std::string filename = path_processor_type::to_string(*p.get_filename());
|
||||||
const std::string & filename = p.get_filename();
|
return boost::python::make_tuple(filename,guess_type(filename));
|
||||||
return boost::python::make_tuple(filename,mapnik::guess_type(filename),img->width(),img->height());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,8 +46,6 @@ void export_polygon_pattern_symbolizer()
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
|
||||||
class_<polygon_pattern_symbolizer>("PolygonPatternSymbolizer",
|
class_<polygon_pattern_symbolizer>("PolygonPatternSymbolizer",
|
||||||
init<std::string const&,
|
init<path_expression_ptr>("<path_expression_ptr>"))
|
||||||
std::string const&,
|
|
||||||
unsigned,unsigned>("TODO"))
|
|
||||||
.def_pickle(polygon_pattern_symbolizer_pickle_suite()) ;
|
.def_pickle(polygon_pattern_symbolizer_pickle_suite()) ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace {
|
||||||
return mapnik::coord2d(x,y);
|
return mapnik::coord2d(x,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::Envelope<double> forward_transform_env(mapnik::proj_transform& t, mapnik::Envelope<double> const & box)
|
mapnik::box2d<double> forward_transform_env(mapnik::proj_transform& t, mapnik::box2d<double> const & box)
|
||||||
{
|
{
|
||||||
double minx = box.minx();
|
double minx = box.minx();
|
||||||
double miny = box.miny();
|
double miny = box.miny();
|
||||||
|
@ -68,10 +68,10 @@ namespace {
|
||||||
double z = 0.0;
|
double z = 0.0;
|
||||||
t.forward(minx,miny,z);
|
t.forward(minx,miny,z);
|
||||||
t.forward(maxx,maxy,z);
|
t.forward(maxx,maxy,z);
|
||||||
return mapnik::Envelope<double>(minx,miny,maxx,maxy);
|
return mapnik::box2d<double>(minx,miny,maxx,maxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::Envelope<double> backward_transform_env(mapnik::proj_transform& t, mapnik::Envelope<double> const & box)
|
mapnik::box2d<double> backward_transform_env(mapnik::proj_transform& t, mapnik::box2d<double> const & box)
|
||||||
{
|
{
|
||||||
double minx = box.minx();
|
double minx = box.minx();
|
||||||
double miny = box.miny();
|
double miny = box.miny();
|
||||||
|
@ -80,7 +80,7 @@ namespace {
|
||||||
double z = 0.0;
|
double z = 0.0;
|
||||||
t.backward(minx,miny,z);
|
t.backward(minx,miny,z);
|
||||||
t.backward(maxx,maxy,z);
|
t.backward(maxx,maxy,z);
|
||||||
return mapnik::Envelope<double>(minx,miny,maxx,maxy);
|
return mapnik::box2d<double>(minx,miny,maxx,maxy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace {
|
||||||
return mapnik::coord2d(x,y);
|
return mapnik::coord2d(x,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::Envelope<double> forward_env(mapnik::Envelope<double> const & box,
|
mapnik::box2d<double> forward_env(mapnik::box2d<double> const & box,
|
||||||
mapnik::projection const& prj)
|
mapnik::projection const& prj)
|
||||||
{
|
{
|
||||||
double minx = box.minx();
|
double minx = box.minx();
|
||||||
|
@ -68,10 +68,10 @@ namespace {
|
||||||
double maxy = box.maxy();
|
double maxy = box.maxy();
|
||||||
prj.forward(minx,miny);
|
prj.forward(minx,miny);
|
||||||
prj.forward(maxx,maxy);
|
prj.forward(maxx,maxy);
|
||||||
return mapnik::Envelope<double>(minx,miny,maxx,maxy);
|
return mapnik::box2d<double>(minx,miny,maxx,maxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::Envelope<double> inverse_env(mapnik::Envelope<double> const & box,
|
mapnik::box2d<double> inverse_env(mapnik::box2d<double> const & box,
|
||||||
mapnik::projection const& prj)
|
mapnik::projection const& prj)
|
||||||
{
|
{
|
||||||
double minx = box.minx();
|
double minx = box.minx();
|
||||||
|
@ -80,7 +80,7 @@ namespace {
|
||||||
double maxy = box.maxy();
|
double maxy = box.maxy();
|
||||||
prj.inverse(minx,miny);
|
prj.inverse(minx,miny);
|
||||||
prj.inverse(maxx,maxy);
|
prj.inverse(maxx,maxy);
|
||||||
return mapnik::Envelope<double>(minx,miny,maxx,maxy);
|
return mapnik::box2d<double>(minx,miny,maxx,maxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ void export_image();
|
||||||
void export_image_view();
|
void export_image_view();
|
||||||
void export_map();
|
void export_map();
|
||||||
void export_python();
|
void export_python();
|
||||||
void export_filter();
|
void export_expression();
|
||||||
void export_rule();
|
void export_rule();
|
||||||
void export_style();
|
void export_style();
|
||||||
void export_stroke();
|
void export_stroke();
|
||||||
|
@ -77,12 +77,12 @@ void export_view_transform();
|
||||||
static Pycairo_CAPI_t *Pycairo_CAPI;
|
static Pycairo_CAPI_t *Pycairo_CAPI;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void render(const mapnik::Map& map,mapnik::Image32& image, unsigned offset_x = 0, unsigned offset_y = 0)
|
void render(const mapnik::Map& map,mapnik::image_32& image, unsigned offset_x = 0, unsigned offset_y = 0)
|
||||||
{
|
{
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mapnik::agg_renderer<mapnik::Image32> ren(map,image,offset_x, offset_y);
|
mapnik::agg_renderer<mapnik::image_32> ren(map,image,offset_x, offset_y);
|
||||||
ren.apply();
|
ren.apply();
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
@ -93,12 +93,12 @@ void render(const mapnik::Map& map,mapnik::Image32& image, unsigned offset_x = 0
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
|
|
||||||
void render2(const mapnik::Map& map,mapnik::Image32& image)
|
void render2(const mapnik::Map& map,mapnik::image_32& image)
|
||||||
{
|
{
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mapnik::agg_renderer<mapnik::Image32> ren(map,image);
|
mapnik::agg_renderer<mapnik::image_32> ren(map,image);
|
||||||
ren.apply();
|
ren.apply();
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
@ -187,7 +187,7 @@ void render_tile_to_file(const mapnik::Map& map,
|
||||||
const std::string& file,
|
const std::string& file,
|
||||||
const std::string& format)
|
const std::string& format)
|
||||||
{
|
{
|
||||||
mapnik::Image32 image(width,height);
|
mapnik::image_32 image(width,height);
|
||||||
render(map,image,offset_x, offset_y);
|
render(map,image,offset_x, offset_y);
|
||||||
mapnik::save_to_file(image.data(),file,format);
|
mapnik::save_to_file(image.data(),file,format);
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ void render_to_file1(const mapnik::Map& map,
|
||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const std::string& format)
|
const std::string& format)
|
||||||
{
|
{
|
||||||
mapnik::Image32 image(map.getWidth(),map.getHeight());
|
mapnik::image_32 image(map.getWidth(),map.getHeight());
|
||||||
render(map,image,0,0);
|
render(map,image,0,0);
|
||||||
mapnik::save_to_file(image,filename,format);
|
mapnik::save_to_file(image,filename,format);
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ void render_to_file1(const mapnik::Map& map,
|
||||||
void render_to_file2(const mapnik::Map& map,
|
void render_to_file2(const mapnik::Map& map,
|
||||||
const std::string& filename)
|
const std::string& filename)
|
||||||
{
|
{
|
||||||
mapnik::Image32 image(map.getWidth(),map.getHeight());
|
mapnik::image_32 image(map.getWidth(),map.getHeight());
|
||||||
render(map,image,0,0);
|
render(map,image,0,0);
|
||||||
mapnik::save_to_file(image,filename);
|
mapnik::save_to_file(image,filename);
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,7 @@ BOOST_PYTHON_MODULE(_mapnik)
|
||||||
export_envelope();
|
export_envelope();
|
||||||
export_image();
|
export_image();
|
||||||
export_image_view();
|
export_image_view();
|
||||||
export_filter();
|
export_expression();
|
||||||
export_rule();
|
export_rule();
|
||||||
export_style();
|
export_style();
|
||||||
export_layer();
|
export_layer();
|
||||||
|
@ -350,7 +350,7 @@ BOOST_PYTHON_MODULE(_mapnik)
|
||||||
|
|
||||||
def("render",&render,
|
def("render",&render,
|
||||||
"\n"
|
"\n"
|
||||||
"Render Map to an AGG Image32 using offsets\n"
|
"Render Map to an AGG image_32 using offsets\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> from mapnik import Map, Image, render, load_map\n"
|
">>> from mapnik import Map, Image, render, load_map\n"
|
||||||
|
@ -363,7 +363,7 @@ BOOST_PYTHON_MODULE(_mapnik)
|
||||||
|
|
||||||
def("render",&render2,
|
def("render",&render2,
|
||||||
"\n"
|
"\n"
|
||||||
"Render Map to an AGG Image32\n"
|
"Render Map to an AGG image_32\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
">>> from mapnik import Map, Image, render, load_map\n"
|
">>> from mapnik import Map, Image, render, load_map\n"
|
||||||
|
@ -473,5 +473,6 @@ BOOST_PYTHON_MODULE(_mapnik)
|
||||||
def("has_cairo", &has_cairo, "Get cairo library status");
|
def("has_cairo", &has_cairo, "Get cairo library status");
|
||||||
def("has_pycairo", &has_pycairo, "Get pycairo module status");
|
def("has_pycairo", &has_pycairo, "Get pycairo module status");
|
||||||
|
|
||||||
register_ptr_to_python<mapnik::filter_ptr>();
|
register_ptr_to_python<mapnik::expression_ptr>();
|
||||||
|
register_ptr_to_python<mapnik::path_expression_ptr>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
|
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <mapnik/query.hpp>
|
#include <mapnik/query.hpp>
|
||||||
#include <mapnik/envelope.hpp>
|
#include <mapnik/box2d.hpp>
|
||||||
using mapnik::query;
|
using mapnik::query;
|
||||||
using mapnik::Envelope;
|
using mapnik::box2d;
|
||||||
|
|
||||||
struct query_pickle_suite : boost::python::pickle_suite
|
struct query_pickle_suite : boost::python::pickle_suite
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@ void export_query()
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
|
||||||
class_<query>("Query", "a spatial query data object",
|
class_<query>("Query", "a spatial query data object",
|
||||||
init<Envelope<double>,double>() )
|
init<box2d<double>,double>() )
|
||||||
.def_pickle(query_pickle_suite())
|
.def_pickle(query_pickle_suite())
|
||||||
.add_property("resolution", &query::resolution)
|
.add_property("resolution", &query::resolution)
|
||||||
.add_property("bbox", make_function(&query::get_bbox,
|
.add_property("bbox", make_function(&query::get_bbox,
|
||||||
|
|
|
@ -28,11 +28,11 @@
|
||||||
|
|
||||||
#include <mapnik/rule.hpp>
|
#include <mapnik/rule.hpp>
|
||||||
#include <mapnik/filter_factory.hpp>
|
#include <mapnik/filter_factory.hpp>
|
||||||
|
#include <mapnik/expression_string.hpp>
|
||||||
|
|
||||||
using mapnik::rule_type;
|
using mapnik::rule_type;
|
||||||
using mapnik::filter;
|
using mapnik::expr_node;
|
||||||
using mapnik::filter_ptr;
|
using mapnik::expression_ptr;
|
||||||
using mapnik::filter_factory;
|
|
||||||
using mapnik::Feature;
|
using mapnik::Feature;
|
||||||
using mapnik::point_symbolizer;
|
using mapnik::point_symbolizer;
|
||||||
using mapnik::line_symbolizer;
|
using mapnik::line_symbolizer;
|
||||||
|
@ -45,7 +45,7 @@ using mapnik::text_symbolizer;
|
||||||
using mapnik::building_symbolizer;
|
using mapnik::building_symbolizer;
|
||||||
using mapnik::markers_symbolizer;
|
using mapnik::markers_symbolizer;
|
||||||
using mapnik::symbolizer;
|
using mapnik::symbolizer;
|
||||||
using mapnik::symbolizers;
|
using mapnik::to_expression_string;
|
||||||
|
|
||||||
struct pickle_symbolizer : public boost::static_visitor<>
|
struct pickle_symbolizer : public boost::static_visitor<>
|
||||||
{
|
{
|
||||||
|
@ -93,14 +93,14 @@ struct rule_pickle_suite : boost::python::pickle_suite
|
||||||
{
|
{
|
||||||
boost::python::list syms;
|
boost::python::list syms;
|
||||||
|
|
||||||
symbolizers::const_iterator begin = r.get_symbolizers().begin();
|
rule_type::symbolizers::const_iterator begin = r.get_symbolizers().begin();
|
||||||
symbolizers::const_iterator end = r.get_symbolizers().end();
|
rule_type::symbolizers::const_iterator end = r.get_symbolizers().end();
|
||||||
pickle_symbolizer serializer( syms );
|
pickle_symbolizer serializer( syms );
|
||||||
std::for_each( begin, end , boost::apply_visitor( serializer ));
|
std::for_each( begin, end , boost::apply_visitor( serializer ));
|
||||||
|
|
||||||
// Here the filter string is used rather than the actual Filter object
|
// We serialize filter expressions AST as strings
|
||||||
// Need to look into how to get the Filter object
|
std::string filter_expr = to_expression_string(*r.get_filter());
|
||||||
std::string filter_expr = r.get_filter()->to_string();
|
|
||||||
return boost::python::make_tuple(r.get_abstract(),filter_expr,r.has_else_filter(),syms);
|
return boost::python::make_tuple(r.get_abstract(),filter_expr,r.has_else_filter(),syms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,10 +126,10 @@ struct rule_pickle_suite : boost::python::pickle_suite
|
||||||
{
|
{
|
||||||
rule_type dfl;
|
rule_type dfl;
|
||||||
std::string filter = extract<std::string>(state[1]);
|
std::string filter = extract<std::string>(state[1]);
|
||||||
std::string default_filter = dfl.get_filter()->to_string();
|
std::string default_filter = "<TODO>";//dfl.get_filter()->to_string();
|
||||||
if ( filter != default_filter)
|
if ( filter != default_filter)
|
||||||
{
|
{
|
||||||
r.set_filter(mapnik::create_filter(filter,"utf8"));
|
r.set_filter(mapnik::parse_expression(filter,"utf8"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +162,8 @@ void export_rule()
|
||||||
implicitly_convertible<shield_symbolizer,symbolizer>();
|
implicitly_convertible<shield_symbolizer,symbolizer>();
|
||||||
implicitly_convertible<text_symbolizer,symbolizer>();
|
implicitly_convertible<text_symbolizer,symbolizer>();
|
||||||
|
|
||||||
class_<symbolizers>("Symbolizers",init<>("TODO"))
|
class_<rule_type::symbolizers>("Symbolizers",init<>("TODO"))
|
||||||
.def(vector_indexing_suite<symbolizers>())
|
.def(vector_indexing_suite<rule_type::symbolizers>())
|
||||||
;
|
;
|
||||||
|
|
||||||
class_<rule_type>("Rule",init<>("default constructor"))
|
class_<rule_type>("Rule",init<>("default constructor"))
|
||||||
|
|
|
@ -25,22 +25,26 @@
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <mapnik/shield_symbolizer.hpp>
|
#include <mapnik/shield_symbolizer.hpp>
|
||||||
#include <mapnik/image_util.hpp>
|
#include <mapnik/image_util.hpp>
|
||||||
|
#include <mapnik/path_expression_grammar.hpp>
|
||||||
|
|
||||||
using mapnik::color;
|
using mapnik::color;
|
||||||
using mapnik::shield_symbolizer;
|
using mapnik::shield_symbolizer;
|
||||||
using mapnik::text_symbolizer;
|
using mapnik::text_symbolizer;
|
||||||
using mapnik::symbolizer_with_image;
|
using mapnik::symbolizer_with_image;
|
||||||
|
using mapnik::path_processor_type;
|
||||||
|
using mapnik::path_expression_ptr;
|
||||||
|
using mapnik::guess_type;
|
||||||
|
using mapnik::expression_ptr;
|
||||||
|
|
||||||
struct shield_symbolizer_pickle_suite : boost::python::pickle_suite
|
struct shield_symbolizer_pickle_suite : boost::python::pickle_suite
|
||||||
{
|
{
|
||||||
static boost::python::tuple
|
static boost::python::tuple
|
||||||
getinitargs(const shield_symbolizer& s)
|
getinitargs(const shield_symbolizer& s)
|
||||||
{
|
{
|
||||||
|
std::string filename = path_processor_type::to_string(*s.get_filename());
|
||||||
boost::shared_ptr<mapnik::ImageData32> img = s.get_image();
|
//(name, font name, font size, font color, image file, image type, width, height)
|
||||||
const std::string & filename = s.get_filename();
|
return boost::python::make_tuple( "TODO",//s.get_name(),
|
||||||
//(name, font name, font size, font color, image file, image type, width, height)
|
s.get_face_name(),s.get_text_size(),s.get_fill(),filename,guess_type(filename));
|
||||||
return boost::python::make_tuple(s.get_name(),s.get_face_name(),s.get_text_size(),s.get_fill(),filename,mapnik::guess_type(filename),img->width(),img->height());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +79,9 @@ void export_shield_symbolizer()
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
class_< shield_symbolizer, bases<text_symbolizer> >("ShieldSymbolizer",
|
class_< shield_symbolizer, bases<text_symbolizer> >("ShieldSymbolizer",
|
||||||
init< std::string const&, std::string const&, unsigned, mapnik::color const&,
|
init<expression_ptr, std::string const&, unsigned, mapnik::color const&,
|
||||||
std::string const&, std::string const&,unsigned,unsigned>("TODO"))
|
path_expression_ptr>("TODO"))
|
||||||
.def_pickle(shield_symbolizer_pickle_suite())
|
//.def_pickle(shield_symbolizer_pickle_suite())
|
||||||
;
|
;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,9 @@ struct text_symbolizer_pickle_suite : boost::python::pickle_suite
|
||||||
getinitargs(const text_symbolizer& t)
|
getinitargs(const text_symbolizer& t)
|
||||||
{
|
{
|
||||||
|
|
||||||
return boost::python::make_tuple(t.get_name(),t.get_face_name(),t.get_text_size(),t.get_fill());
|
return boost::python::make_tuple("TODO",//t.get_name(),
|
||||||
|
t.get_face_name(),t.get_text_size(),t.get_fill());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boost::python::tuple
|
static boost::python::tuple
|
||||||
|
@ -164,8 +165,8 @@ using namespace boost::python;
|
||||||
.value("TOLOWER",TOLOWER)
|
.value("TOLOWER",TOLOWER)
|
||||||
;
|
;
|
||||||
|
|
||||||
class_<text_symbolizer>("TextSymbolizer",init<std::string const&,std::string const&, unsigned,color const&>())
|
class_<text_symbolizer>("TextSymbolizer",init<expression_ptr,std::string const&, unsigned,color const&>())
|
||||||
.def_pickle(text_symbolizer_pickle_suite())
|
//.def_pickle(text_symbolizer_pickle_suite())
|
||||||
.def("anchor",&text_symbolizer::set_anchor)
|
.def("anchor",&text_symbolizer::set_anchor)
|
||||||
.def("displacement",&text_symbolizer::set_displacement)
|
.def("displacement",&text_symbolizer::set_displacement)
|
||||||
.def("get_anchor",get_anchor_list)
|
.def("get_anchor",get_anchor_list)
|
||||||
|
@ -220,9 +221,9 @@ class_<text_symbolizer>("TextSymbolizer",init<std::string const&,std::string con
|
||||||
.add_property("minimum_distance",
|
.add_property("minimum_distance",
|
||||||
&text_symbolizer::get_minimum_distance,
|
&text_symbolizer::get_minimum_distance,
|
||||||
&text_symbolizer::set_minimum_distance)
|
&text_symbolizer::set_minimum_distance)
|
||||||
.add_property("name",
|
//.add_property("name",
|
||||||
make_function(&text_symbolizer::get_name,return_value_policy<copy_const_reference>()),
|
// make_function(&text_symbolizer::get_name,return_value_policy<copy_const_reference>()),
|
||||||
&text_symbolizer::set_name)
|
// &text_symbolizer::set_name)
|
||||||
.add_property("text_convert",
|
.add_property("text_convert",
|
||||||
&text_symbolizer::get_text_convert,
|
&text_symbolizer::get_text_convert,
|
||||||
&text_symbolizer::set_text_convert,
|
&text_symbolizer::set_text_convert,
|
||||||
|
|
|
@ -55,12 +55,12 @@ namespace {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::Envelope<double> forward_envelope(mapnik::CoordTransform const& t, mapnik::Envelope<double> const& in)
|
mapnik::box2d<double> forward_envelope(mapnik::CoordTransform const& t, mapnik::box2d<double> const& in)
|
||||||
{
|
{
|
||||||
return t.forward(in);
|
return t.forward(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::Envelope<double> backward_envelope(mapnik::CoordTransform const& t, mapnik::Envelope<double> const& in)
|
mapnik::box2d<double> backward_envelope(mapnik::CoordTransform const& t, mapnik::box2d<double> const& in)
|
||||||
{
|
{
|
||||||
return t.backward(in);
|
return t.backward(in);
|
||||||
}
|
}
|
||||||
|
@ -69,10 +69,10 @@ namespace {
|
||||||
void export_view_transform()
|
void export_view_transform()
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
using mapnik::Envelope;
|
using mapnik::box2d;
|
||||||
using mapnik::coord2d;
|
using mapnik::coord2d;
|
||||||
|
|
||||||
class_<CoordTransform>("ViewTransform",init<int,int,Envelope<double> const& > (
|
class_<CoordTransform>("ViewTransform",init<int,int,box2d<double> const& > (
|
||||||
"Create a ViewTransform with a width and height as integers and extent"))
|
"Create a ViewTransform with a width and height as integers and extent"))
|
||||||
.def_pickle(view_transform_pickle_suite())
|
.def_pickle(view_transform_pickle_suite())
|
||||||
.def("forward", forward_point)
|
.def("forward", forward_point)
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_CMDLINE_PARSER_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_CMDLINE_PARSER_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/ptree_utils.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace cmdline_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
void read_cmdline(int argc,
|
|
||||||
typename Ptree::char_type *argv[],
|
|
||||||
const std::basic_string<typename Ptree::char_type> &metachars,
|
|
||||||
Ptree &pt)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
|
|
||||||
Ptree local;
|
|
||||||
|
|
||||||
// For all arguments
|
|
||||||
for (int i = 0; i < argc; ++i)
|
|
||||||
{
|
|
||||||
Str text = detail::trim<Ch>(argv[i]);
|
|
||||||
if (!text.empty())
|
|
||||||
if (metachars.find(text[0]) != Str::npos)
|
|
||||||
{
|
|
||||||
if (text.size() == 1)
|
|
||||||
{
|
|
||||||
Ptree &child = local.put(text, Str());
|
|
||||||
Str key;
|
|
||||||
if (child.size() < 10)
|
|
||||||
key.push_back(typename Ptree::char_type('0' + child.size()));
|
|
||||||
child.push_back(std::make_pair(key, Ptree(child.data())));
|
|
||||||
}
|
|
||||||
else if (text.size() == 2)
|
|
||||||
{
|
|
||||||
Ptree &child = local.put(text.substr(1, 1), Str());
|
|
||||||
Str key;
|
|
||||||
if (child.size() < 10)
|
|
||||||
key.push_back(typename Ptree::char_type('0' + child.size()));
|
|
||||||
child.push_back(std::make_pair(key, Ptree(child.data())));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Ptree &child = local.put(text.substr(1, 1), detail::trim<Ch>(text.substr(2, Str::npos)));
|
|
||||||
Str key;
|
|
||||||
if (child.size() < 10)
|
|
||||||
key.push_back(typename Ptree::char_type('0' + child.size()));
|
|
||||||
child.push_back(std::make_pair(key, Ptree(child.data())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Ptree &child = local.put(Str(), detail::trim<Ch>(text));
|
|
||||||
Str key;
|
|
||||||
if (child.size() < 10)
|
|
||||||
key.push_back(typename Ptree::char_type('0' + child.size()));
|
|
||||||
child.push_back(std::make_pair(key, Ptree(child.data())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap local and pt
|
|
||||||
pt.swap(local);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree
|
|
||||||
{
|
|
||||||
using cmdline_parser::read_cmdline;
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,88 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree
|
|
||||||
{
|
|
||||||
|
|
||||||
//! File parse error
|
|
||||||
class file_parser_error: public ptree_error
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// Construction & destruction
|
|
||||||
|
|
||||||
// Construct error
|
|
||||||
file_parser_error(const std::string &message,
|
|
||||||
const std::string &filename,
|
|
||||||
unsigned long line):
|
|
||||||
ptree_error(format_what(message, filename, line)),
|
|
||||||
m_message(message), m_filename(filename), m_line(line)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~file_parser_error() throw()
|
|
||||||
// gcc 3.4.2 complains about lack of throw specifier on compiler generated dtor
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// Data access
|
|
||||||
|
|
||||||
// Get error message (without line and file - use what() to get full message)
|
|
||||||
std::string message()
|
|
||||||
{
|
|
||||||
return m_message;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get error filename
|
|
||||||
std::string filename()
|
|
||||||
{
|
|
||||||
return m_filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get error line number
|
|
||||||
unsigned long line()
|
|
||||||
{
|
|
||||||
return m_line;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::string m_message;
|
|
||||||
std::string m_filename;
|
|
||||||
unsigned long m_line;
|
|
||||||
|
|
||||||
// Format error message to be returned by std::runtime_error::what()
|
|
||||||
std::string format_what(const std::string &message,
|
|
||||||
const std::string &filename,
|
|
||||||
unsigned long line)
|
|
||||||
{
|
|
||||||
std::stringstream stream;
|
|
||||||
if (line > 0)
|
|
||||||
stream << (filename.empty() ? "<unspecified file>" : filename.c_str()) <<
|
|
||||||
'(' << line << "): " << message;
|
|
||||||
else
|
|
||||||
stream << (filename.empty() ? "<unspecified file>" : filename.c_str()) <<
|
|
||||||
": " << message;
|
|
||||||
return stream.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,32 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/detail/file_parser_error.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace info_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
class info_parser_error: public file_parser_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
info_parser_error(const std::string &message,
|
|
||||||
const std::string &filename,
|
|
||||||
unsigned long line):
|
|
||||||
file_parser_error(message, filename, line)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,369 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_READ_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_READ_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include "boost/property_tree/ptree.hpp"
|
|
||||||
#include "boost/property_tree/detail/info_parser_error.hpp"
|
|
||||||
#include "boost/property_tree/detail/info_parser_utils.hpp"
|
|
||||||
#include <iterator>
|
|
||||||
#include <string>
|
|
||||||
#include <stack>
|
|
||||||
#include <fstream>
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace info_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
// Expand known escape sequences
|
|
||||||
template<class It>
|
|
||||||
std::basic_string<typename std::iterator_traits<It>::value_type>
|
|
||||||
expand_escapes(It b, It e)
|
|
||||||
{
|
|
||||||
typedef typename std::iterator_traits<It>::value_type Ch;
|
|
||||||
std::basic_string<Ch> result;
|
|
||||||
while (b != e)
|
|
||||||
{
|
|
||||||
if (*b == Ch('\\'))
|
|
||||||
{
|
|
||||||
++b;
|
|
||||||
if (b == e)
|
|
||||||
throw info_parser_error("character expected after backslash", "", 0);
|
|
||||||
else if (*b == Ch('0')) result += Ch('\0');
|
|
||||||
else if (*b == Ch('a')) result += Ch('\a');
|
|
||||||
else if (*b == Ch('b')) result += Ch('\b');
|
|
||||||
else if (*b == Ch('f')) result += Ch('\f');
|
|
||||||
else if (*b == Ch('n')) result += Ch('\n');
|
|
||||||
else if (*b == Ch('r')) result += Ch('\r');
|
|
||||||
else if (*b == Ch('t')) result += Ch('\t');
|
|
||||||
else if (*b == Ch('v')) result += Ch('\v');
|
|
||||||
else if (*b == Ch('"')) result += Ch('"');
|
|
||||||
else if (*b == Ch('\'')) result += Ch('\'');
|
|
||||||
else if (*b == Ch('\\')) result += Ch('\\');
|
|
||||||
else
|
|
||||||
throw info_parser_error("unknown escape sequence", "", 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += *b;
|
|
||||||
++b;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Advance pointer past whitespace
|
|
||||||
template<class Ch>
|
|
||||||
void skip_whitespace(const Ch *&text)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
while (isspace(*text))
|
|
||||||
++text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract word (whitespace delimited) and advance pointer accordingly
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> read_word(const Ch *&text)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
skip_whitespace(text);
|
|
||||||
const Ch *start = text;
|
|
||||||
while (!isspace(*text) && *text != Ch(';') && *text != Ch('\0'))
|
|
||||||
++text;
|
|
||||||
return expand_escapes(start, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract line (eol delimited) and advance pointer accordingly
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> read_line(const Ch *&text)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
skip_whitespace(text);
|
|
||||||
const Ch *start = text;
|
|
||||||
while (*text != Ch('\0') && *text != Ch(';'))
|
|
||||||
++text;
|
|
||||||
while (text > start && isspace(*(text - 1)))
|
|
||||||
--text;
|
|
||||||
return expand_escapes(start, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract string (inside ""), and advance pointer accordingly
|
|
||||||
// Set need_more_lines to true if \ continuator found
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> read_string(const Ch *&text, bool *need_more_lines)
|
|
||||||
{
|
|
||||||
skip_whitespace(text);
|
|
||||||
if (*text == Ch('\"'))
|
|
||||||
{
|
|
||||||
|
|
||||||
// Skip "
|
|
||||||
++text;
|
|
||||||
|
|
||||||
// Find end of string, but skip escaped "
|
|
||||||
bool escaped = false;
|
|
||||||
const Ch *start = text;
|
|
||||||
while ((escaped || *text != Ch('\"')) && *text != Ch('\0'))
|
|
||||||
{
|
|
||||||
escaped = (!escaped && *text == Ch('\\'));
|
|
||||||
++text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If end of string found
|
|
||||||
if (*text == Ch('\"'))
|
|
||||||
{
|
|
||||||
std::basic_string<Ch> result = expand_escapes(start, text++);
|
|
||||||
skip_whitespace(text);
|
|
||||||
if (*text == Ch('\\'))
|
|
||||||
{
|
|
||||||
if (!need_more_lines)
|
|
||||||
throw info_parser_error("unexpected \\", "", 0);
|
|
||||||
++text;
|
|
||||||
skip_whitespace(text);
|
|
||||||
if (*text == Ch('\0') || *text == Ch(';'))
|
|
||||||
*need_more_lines = true;
|
|
||||||
else
|
|
||||||
throw info_parser_error("expected end of line after \\", "", 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (need_more_lines)
|
|
||||||
*need_more_lines = false;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw info_parser_error("unexpected end of line", "", 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw info_parser_error("expected \"", "", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract key
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> read_key(const Ch *&text)
|
|
||||||
{
|
|
||||||
skip_whitespace(text);
|
|
||||||
if (*text == Ch('\"'))
|
|
||||||
return read_string(text, NULL);
|
|
||||||
else
|
|
||||||
return read_word(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract data
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> read_data(const Ch *&text, bool *need_more_lines)
|
|
||||||
{
|
|
||||||
skip_whitespace(text);
|
|
||||||
if (*text == Ch('\"'))
|
|
||||||
return read_string(text, need_more_lines);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*need_more_lines = false;
|
|
||||||
return read_word(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build ptree from info stream
|
|
||||||
template<class Ptree>
|
|
||||||
void read_info_internal(std::basic_istream<typename Ptree::char_type> &stream,
|
|
||||||
Ptree &pt,
|
|
||||||
const std::string &filename,
|
|
||||||
int include_depth)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Character type
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
|
|
||||||
// Possible parser states
|
|
||||||
enum state_t {
|
|
||||||
s_key, // Parser expects key
|
|
||||||
s_data, // Parser expects data
|
|
||||||
s_data_cont // Parser expects data continuation
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned long line_no = 0;
|
|
||||||
state_t state = s_key; // Parser state
|
|
||||||
Ptree *last = NULL; // Pointer to last created ptree
|
|
||||||
std::basic_string<Ch> line; // Define line here to minimize reallocations
|
|
||||||
|
|
||||||
// Initialize ptree stack (used to handle nesting)
|
|
||||||
std::stack<Ptree *> stack;
|
|
||||||
stack.push(&pt); // Push root ptree on stack initially
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
// While there are characters in the stream
|
|
||||||
while (stream.good())
|
|
||||||
{
|
|
||||||
|
|
||||||
// Read one line from stream
|
|
||||||
++line_no;
|
|
||||||
std::getline(stream, line);
|
|
||||||
if (!stream.good() && !stream.eof())
|
|
||||||
throw info_parser_error("read error", "", 0);
|
|
||||||
const Ch *text = line.c_str();
|
|
||||||
|
|
||||||
// If directive found
|
|
||||||
skip_whitespace(text);
|
|
||||||
if (*text == Ch('#'))
|
|
||||||
{
|
|
||||||
|
|
||||||
// Determine directive type
|
|
||||||
++text; // skip #
|
|
||||||
std::basic_string<Ch> directive = read_word(text);
|
|
||||||
if (directive == convert_chtype<Ch, char>("include")) // #include
|
|
||||||
{
|
|
||||||
if (include_depth > 100)
|
|
||||||
throw info_parser_error("include depth too large, probably recursive include", "", 0);
|
|
||||||
std::basic_string<Ch> s = read_string(text, NULL);
|
|
||||||
std::string inc_name = convert_chtype<char, Ch>(s.c_str());
|
|
||||||
std::basic_ifstream<Ch> inc_stream(inc_name.c_str());
|
|
||||||
if (!inc_stream.good())
|
|
||||||
throw info_parser_error("cannot open include file " + inc_name, "", 0);
|
|
||||||
read_info_internal(inc_stream, *stack.top(), inc_name, include_depth + 1);
|
|
||||||
}
|
|
||||||
else // Unknown directive
|
|
||||||
throw info_parser_error("unknown directive", "", 0);
|
|
||||||
|
|
||||||
// Directive must be followed by end of line
|
|
||||||
skip_whitespace(text);
|
|
||||||
if (*text != Ch('\0'))
|
|
||||||
throw info_parser_error("expected end of line", "", 0);
|
|
||||||
|
|
||||||
// Go to next line
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// While there are characters left in line
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Stop parsing on end of line or comment
|
|
||||||
skip_whitespace(text);
|
|
||||||
if (*text == Ch('\0') || *text == Ch(';'))
|
|
||||||
{
|
|
||||||
if (state == s_data) // If there was no data set state to s_key
|
|
||||||
state = s_key;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process according to current parser state
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Parser expects key
|
|
||||||
case s_key:
|
|
||||||
{
|
|
||||||
|
|
||||||
if (*text == Ch('{')) // Brace opening found
|
|
||||||
{
|
|
||||||
if (!last)
|
|
||||||
throw info_parser_error("unexpected {", "", 0);
|
|
||||||
stack.push(last);
|
|
||||||
last = NULL;
|
|
||||||
++text;
|
|
||||||
}
|
|
||||||
else if (*text == Ch('}')) // Brace closing found
|
|
||||||
{
|
|
||||||
if (stack.size() <= 1)
|
|
||||||
throw info_parser_error("unmatched }", "", 0);
|
|
||||||
stack.pop();
|
|
||||||
last = NULL;
|
|
||||||
++text;
|
|
||||||
}
|
|
||||||
else // Key text found
|
|
||||||
{
|
|
||||||
std::basic_string<Ch> key = read_key(text);
|
|
||||||
last = &stack.top()->push_back(std::make_pair(key, Ptree()))->second;
|
|
||||||
state = s_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; break;
|
|
||||||
|
|
||||||
// Parser expects data
|
|
||||||
case s_data:
|
|
||||||
{
|
|
||||||
|
|
||||||
// Last ptree must be defined because we are going to add data to it
|
|
||||||
BOOST_ASSERT(last);
|
|
||||||
|
|
||||||
if (*text == Ch('{')) // Brace opening found
|
|
||||||
{
|
|
||||||
stack.push(last);
|
|
||||||
last = NULL;
|
|
||||||
++text;
|
|
||||||
state = s_key;
|
|
||||||
}
|
|
||||||
else if (*text == Ch('}')) // Brace closing found
|
|
||||||
{
|
|
||||||
if (stack.size() <= 1)
|
|
||||||
throw info_parser_error("unmatched }", "", 0);
|
|
||||||
stack.pop();
|
|
||||||
last = NULL;
|
|
||||||
++text;
|
|
||||||
state = s_key;
|
|
||||||
}
|
|
||||||
else // Data text found
|
|
||||||
{
|
|
||||||
bool need_more_lines;
|
|
||||||
std::basic_string<Ch> data = read_data(text, &need_more_lines);
|
|
||||||
last->data() = data;
|
|
||||||
state = need_more_lines ? s_data_cont : s_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}; break;
|
|
||||||
|
|
||||||
// Parser expects continuation of data after \ on previous line
|
|
||||||
case s_data_cont:
|
|
||||||
{
|
|
||||||
|
|
||||||
// Last ptree must be defined because we are going to update its data
|
|
||||||
BOOST_ASSERT(last);
|
|
||||||
|
|
||||||
if (*text == Ch('\"')) // Continuation must start with "
|
|
||||||
{
|
|
||||||
bool need_more_lines;
|
|
||||||
std::basic_string<Ch> data = read_string(text, &need_more_lines);
|
|
||||||
last->put_own(last->template get_own<std::basic_string<Ch> >() + data);
|
|
||||||
state = need_more_lines ? s_data_cont : s_key;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw info_parser_error("expected \" after \\ in previous line", "", 0);
|
|
||||||
|
|
||||||
}; break;
|
|
||||||
|
|
||||||
// Should never happen
|
|
||||||
default:
|
|
||||||
BOOST_ASSERT(0);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if stack has initial size, otherwise some {'s have not been closed
|
|
||||||
if (stack.size() != 1)
|
|
||||||
throw info_parser_error("unmatched {", "", 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (info_parser_error &e)
|
|
||||||
{
|
|
||||||
// If line undefined rethrow error with correct filename and line
|
|
||||||
if (e.line() == 0)
|
|
||||||
throw info_parser_error(e.message(), filename, line_no);
|
|
||||||
else
|
|
||||||
throw e;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,32 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace info_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
template<class ChDest, class ChSrc>
|
|
||||||
std::basic_string<ChDest> convert_chtype(const ChSrc *text)
|
|
||||||
{
|
|
||||||
std::basic_string<ChDest> result;
|
|
||||||
while (*text)
|
|
||||||
{
|
|
||||||
result += ChDest(*text);
|
|
||||||
++text;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,131 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include "boost/property_tree/ptree.hpp"
|
|
||||||
#include "boost/property_tree/detail/info_parser_utils.hpp"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace info_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
// Create necessary escape sequences from illegal characters
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s)
|
|
||||||
{
|
|
||||||
std::basic_string<Ch> result;
|
|
||||||
typename std::basic_string<Ch>::const_iterator b = s.begin();
|
|
||||||
typename std::basic_string<Ch>::const_iterator e = s.end();
|
|
||||||
while (b != e)
|
|
||||||
{
|
|
||||||
if (*b == Ch('\0')) result += Ch('\\'), result += Ch('0');
|
|
||||||
else if (*b == Ch('\a')) result += Ch('\\'), result += Ch('a');
|
|
||||||
else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b');
|
|
||||||
else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f');
|
|
||||||
else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n');
|
|
||||||
else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
|
|
||||||
else if (*b == Ch('\v')) result += Ch('\\'), result += Ch('v');
|
|
||||||
else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
|
|
||||||
else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
|
|
||||||
else
|
|
||||||
result += *b;
|
|
||||||
++b;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
bool is_simple_key(const std::basic_string<Ch> &key)
|
|
||||||
{
|
|
||||||
const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
|
|
||||||
return !key.empty() && key.find_first_of(chars) == key.npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
bool is_simple_data(const std::basic_string<Ch> &data)
|
|
||||||
{
|
|
||||||
const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
|
|
||||||
return !data.empty() && data.find_first_of(chars) == data.npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
void write_info_helper(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const Ptree &pt,
|
|
||||||
int indent)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Character type
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
|
|
||||||
// Write data
|
|
||||||
if (indent >= 0)
|
|
||||||
{
|
|
||||||
if (!pt.data().empty())
|
|
||||||
{
|
|
||||||
std::basic_string<Ch> data = create_escapes(pt.template get_own<std::basic_string<Ch> >());
|
|
||||||
if (is_simple_data(data))
|
|
||||||
stream << Ch(' ') << data << Ch('\n');
|
|
||||||
else
|
|
||||||
stream << Ch(' ') << Ch('\"') << data << Ch('\"') << Ch('\n');
|
|
||||||
}
|
|
||||||
else if (pt.empty())
|
|
||||||
stream << Ch(' ') << Ch('\"') << Ch('\"') << Ch('\n');
|
|
||||||
else
|
|
||||||
stream << Ch('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write keys
|
|
||||||
if (!pt.empty())
|
|
||||||
{
|
|
||||||
|
|
||||||
// Open brace
|
|
||||||
if (indent >= 0)
|
|
||||||
stream << std::basic_string<Ch>(4 * indent, Ch(' ')) << Ch('{') << Ch('\n');
|
|
||||||
|
|
||||||
// Write keys
|
|
||||||
typename Ptree::const_iterator it = pt.begin();
|
|
||||||
for (; it != pt.end(); ++it)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Output key
|
|
||||||
std::basic_string<Ch> key = create_escapes(it->first);
|
|
||||||
stream << std::basic_string<Ch>(4 * (indent + 1), Ch(' '));
|
|
||||||
if (is_simple_key(key))
|
|
||||||
stream << key;
|
|
||||||
else
|
|
||||||
stream << Ch('\"') << key << Ch('\"');
|
|
||||||
|
|
||||||
// Output data and children
|
|
||||||
write_info_helper(stream, it->second, indent + 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close brace
|
|
||||||
if (indent >= 0)
|
|
||||||
stream << std::basic_string<Ch>(4 * indent, Ch(' ')) << Ch('}') << Ch('\n');
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write ptree to info stream
|
|
||||||
template<class Ptree>
|
|
||||||
void write_info_internal(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const Ptree &pt,
|
|
||||||
const std::string &filename)
|
|
||||||
{
|
|
||||||
write_info_helper(stream, pt, -1);
|
|
||||||
if (!stream.good())
|
|
||||||
throw info_parser_error("write error", filename, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,33 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/detail/file_parser_error.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace json_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
//! Json parser error
|
|
||||||
class json_parser_error: public file_parser_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
json_parser_error(const std::string &message,
|
|
||||||
const std::string &filename,
|
|
||||||
unsigned long line):
|
|
||||||
file_parser_error(message, filename, line)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,316 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP_INCLUDED
|
|
||||||
|
|
||||||
//#define BOOST_SPIRIT_DEBUG
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/ptree_utils.hpp>
|
|
||||||
#include <boost/property_tree/detail/json_parser_error.hpp>
|
|
||||||
#include <boost/spirit.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <locale>
|
|
||||||
#include <istream>
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace json_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// Json parser context
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
struct context
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
typedef typename std::vector<Ch>::iterator It;
|
|
||||||
|
|
||||||
Str string;
|
|
||||||
Str name;
|
|
||||||
Ptree root;
|
|
||||||
std::vector<Ptree *> stack;
|
|
||||||
|
|
||||||
struct a_object_s
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_object_s(context &c): c(c) { }
|
|
||||||
void operator()(Ch) const
|
|
||||||
{
|
|
||||||
if (c.stack.empty())
|
|
||||||
c.stack.push_back(&c.root);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Ptree *parent = c.stack.back();
|
|
||||||
Ptree *child = &parent->push_back(std::make_pair(c.name, Ptree()))->second;
|
|
||||||
c.stack.push_back(child);
|
|
||||||
c.name.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_object_e
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_object_e(context &c): c(c) { }
|
|
||||||
void operator()(Ch) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(c.stack.size() >= 1);
|
|
||||||
c.stack.pop_back();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_name
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_name(context &c): c(c) { }
|
|
||||||
void operator()(It, It) const
|
|
||||||
{
|
|
||||||
c.name.swap(c.string);
|
|
||||||
c.string.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_string_val
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_string_val(context &c): c(c) { }
|
|
||||||
void operator()(It, It) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(c.stack.size() >= 1);
|
|
||||||
c.stack.back()->push_back(std::make_pair(c.name, Ptree(c.string)));
|
|
||||||
c.name.clear();
|
|
||||||
c.string.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_literal_val
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_literal_val(context &c): c(c) { }
|
|
||||||
void operator()(It b, It e) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(c.stack.size() >= 1);
|
|
||||||
c.stack.back()->push_back(std::make_pair(c.name, Str(b, e)));
|
|
||||||
c.name.clear();
|
|
||||||
c.string.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_char
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_char(context &c): c(c) { }
|
|
||||||
void operator()(It b, It e) const
|
|
||||||
{
|
|
||||||
c.string += *b;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_escape
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_escape(context &c): c(c) { }
|
|
||||||
void operator()(Ch ch) const
|
|
||||||
{
|
|
||||||
switch (ch)
|
|
||||||
{
|
|
||||||
case Ch('\"'): c.string += Ch('\"'); break;
|
|
||||||
case Ch('\\'): c.string += Ch('\\'); break;
|
|
||||||
case Ch('0'): c.string += Ch('\0'); break;
|
|
||||||
case Ch('b'): c.string += Ch('\b'); break;
|
|
||||||
case Ch('f'): c.string += Ch('\f'); break;
|
|
||||||
case Ch('n'): c.string += Ch('\n'); break;
|
|
||||||
case Ch('r'): c.string += Ch('\r'); break;
|
|
||||||
case Ch('t'): c.string += Ch('\t'); break;
|
|
||||||
default: BOOST_ASSERT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_unicode
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_unicode(context &c): c(c) { }
|
|
||||||
void operator()(unsigned long u) const
|
|
||||||
{
|
|
||||||
u = (std::min)(u, static_cast<unsigned long>((std::numeric_limits<Ch>::max)()));
|
|
||||||
c.string += Ch(u);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// Json grammar
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
struct json_grammar: public boost::spirit::grammar<json_grammar<Ptree> >
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef context<Ptree> Context;
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
|
|
||||||
mutable Context c;
|
|
||||||
|
|
||||||
template<class Scanner>
|
|
||||||
struct definition
|
|
||||||
{
|
|
||||||
|
|
||||||
boost::spirit::rule<Scanner> root, object, member, array, item, value, string, number;
|
|
||||||
boost::spirit::rule<typename boost::spirit::lexeme_scanner<Scanner>::type> character, escape;
|
|
||||||
|
|
||||||
definition(const json_grammar &self)
|
|
||||||
{
|
|
||||||
|
|
||||||
using namespace boost::spirit;
|
|
||||||
|
|
||||||
// Assertions
|
|
||||||
assertion<std::string> expect_object("expected object");
|
|
||||||
assertion<std::string> expect_eoi("expected end of input");
|
|
||||||
assertion<std::string> expect_objclose("expected ',' or '}'");
|
|
||||||
assertion<std::string> expect_arrclose("expected ',' or ']'");
|
|
||||||
assertion<std::string> expect_name("expected object name");
|
|
||||||
assertion<std::string> expect_colon("expected ':'");
|
|
||||||
assertion<std::string> expect_value("expected value");
|
|
||||||
assertion<std::string> expect_escape("invalid escape sequence");
|
|
||||||
|
|
||||||
// JSON grammar rules
|
|
||||||
root
|
|
||||||
= expect_object(object)
|
|
||||||
>> expect_eoi(end_p)
|
|
||||||
;
|
|
||||||
|
|
||||||
object
|
|
||||||
= ch_p('{')[typename Context::a_object_s(self.c)]
|
|
||||||
>> (ch_p('}')[typename Context::a_object_e(self.c)]
|
|
||||||
| (list_p(member, ch_p(','))
|
|
||||||
>> expect_objclose(ch_p('}')[typename Context::a_object_e(self.c)])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
member
|
|
||||||
= expect_name(string[typename Context::a_name(self.c)])
|
|
||||||
>> expect_colon(ch_p(':'))
|
|
||||||
>> expect_value(value)
|
|
||||||
;
|
|
||||||
|
|
||||||
array
|
|
||||||
= ch_p('[')[typename Context::a_object_s(self.c)]
|
|
||||||
>> (ch_p(']')[typename Context::a_object_e(self.c)]
|
|
||||||
| (list_p(item, ch_p(','))
|
|
||||||
>> expect_arrclose(ch_p(']')[typename Context::a_object_e(self.c)])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
item
|
|
||||||
= expect_value(value)
|
|
||||||
;
|
|
||||||
|
|
||||||
value
|
|
||||||
= string[typename Context::a_string_val(self.c)]
|
|
||||||
| (number | str_p("true") | "false" | "null")[typename Context::a_literal_val(self.c)]
|
|
||||||
| object
|
|
||||||
| array
|
|
||||||
;
|
|
||||||
|
|
||||||
number
|
|
||||||
= strict_real_p
|
|
||||||
| int_p
|
|
||||||
;
|
|
||||||
|
|
||||||
string
|
|
||||||
= +(lexeme_d[confix_p('\"', *character, '\"')])
|
|
||||||
;
|
|
||||||
|
|
||||||
character
|
|
||||||
= (anychar_p - "\\" - "\"")[typename Context::a_char(self.c)]
|
|
||||||
| ch_p("\\") >> expect_escape(escape)
|
|
||||||
;
|
|
||||||
|
|
||||||
escape
|
|
||||||
= chset_p(detail::widen<Ch>("\"\\0bfnrt").c_str())[typename Context::a_escape(self.c)]
|
|
||||||
| 'u' >> uint_parser<unsigned long, 16, 4, 4>()[typename Context::a_unicode(self.c)]
|
|
||||||
;
|
|
||||||
|
|
||||||
// Debug
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(root);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(object);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(member);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(array);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(item);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(value);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(string);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(number);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(escape);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(character);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::spirit::rule<Scanner> &start() const
|
|
||||||
{
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class It, class Ch>
|
|
||||||
unsigned long count_lines(It begin, It end)
|
|
||||||
{
|
|
||||||
return static_cast<unsigned long>(std::count(begin, end, Ch('\n')) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
void read_json_internal(std::basic_istream<typename Ptree::char_type> &stream,
|
|
||||||
Ptree &pt,
|
|
||||||
const std::string &filename)
|
|
||||||
{
|
|
||||||
|
|
||||||
using namespace boost::spirit;
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef typename std::vector<Ch>::iterator It;
|
|
||||||
|
|
||||||
// Load data into vector
|
|
||||||
std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
|
|
||||||
std::istreambuf_iterator<Ch>());
|
|
||||||
if (!stream.good())
|
|
||||||
throw json_parser_error("read error", filename, 0);
|
|
||||||
|
|
||||||
// Prepare grammar
|
|
||||||
json_grammar<Ptree> g;
|
|
||||||
|
|
||||||
// Parse
|
|
||||||
try
|
|
||||||
{
|
|
||||||
parse_info<It> pi = parse(v.begin(), v.end(), g,
|
|
||||||
space_p | comment_p("//") | comment_p("/*", "*/"));
|
|
||||||
if (!pi.hit || !pi.full)
|
|
||||||
throw parser_error<std::string, It>(v.begin(), "syntax error");
|
|
||||||
}
|
|
||||||
catch (parser_error<std::string, It> &e)
|
|
||||||
{
|
|
||||||
throw json_parser_error(e.descriptor, filename, count_lines<It, Ch>(v.begin(), e.where));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap grammar context root and pt
|
|
||||||
pt.swap(g.c.root);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,163 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <ostream>
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace json_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
// Create necessary escape sequences from illegal characters
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s,
|
|
||||||
const std::locale &loc)
|
|
||||||
{
|
|
||||||
std::basic_string<Ch> result;
|
|
||||||
typename std::basic_string<Ch>::const_iterator b = s.begin();
|
|
||||||
typename std::basic_string<Ch>::const_iterator e = s.end();
|
|
||||||
while (b != e)
|
|
||||||
{
|
|
||||||
if (*b == Ch('\0')) result += Ch('\\'), result += Ch('0');
|
|
||||||
else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b');
|
|
||||||
else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f');
|
|
||||||
else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n');
|
|
||||||
else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
|
|
||||||
else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
|
|
||||||
else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (std::isprint(*b, loc))
|
|
||||||
result += *b;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char *hexdigits = "0123456789ABCDEF";
|
|
||||||
unsigned long u = (std::min)(static_cast<unsigned long>(*b), 0xFFFFul);
|
|
||||||
int d1 = u / 4096; u -= d1 * 4096;
|
|
||||||
int d2 = u / 256; u -= d2 * 256;
|
|
||||||
int d3 = u / 16; u -= d3 * 16;
|
|
||||||
int d4 = u;
|
|
||||||
result += Ch('\\'); result += Ch('u');
|
|
||||||
result += Ch(hexdigits[d1]); result += Ch(hexdigits[d2]);
|
|
||||||
result += Ch(hexdigits[d3]); result += Ch(hexdigits[d4]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++b;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
void write_json_helper(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const Ptree &pt,
|
|
||||||
int indent)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef typename std::basic_string<Ch> Str;
|
|
||||||
|
|
||||||
// Value or object or array
|
|
||||||
if (indent > 0 && pt.empty())
|
|
||||||
{
|
|
||||||
|
|
||||||
// Write value
|
|
||||||
Str data = create_escapes(pt.template get_own<Str>(), stream.getloc());
|
|
||||||
stream << Ch('"') << data << Ch('"');
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (indent > 0 && pt.count(Str()) == pt.size())
|
|
||||||
{
|
|
||||||
|
|
||||||
// Write array
|
|
||||||
stream << Ch('[') << Ch('\n');
|
|
||||||
typename Ptree::const_iterator it = pt.begin();
|
|
||||||
for (; it != pt.end(); ++it)
|
|
||||||
{
|
|
||||||
stream << Str(4 * (indent + 1), Ch(' '));
|
|
||||||
write_json_helper(stream, it->second, indent + 1);
|
|
||||||
if (boost::next(it) != pt.end())
|
|
||||||
stream << Ch(',');
|
|
||||||
stream << Ch('\n');
|
|
||||||
}
|
|
||||||
stream << Str(4 * indent, Ch(' ')) << Ch(']');
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
// Write object
|
|
||||||
stream << Ch('{') << Ch('\n');
|
|
||||||
typename Ptree::const_iterator it = pt.begin();
|
|
||||||
for (; it != pt.end(); ++it)
|
|
||||||
{
|
|
||||||
stream << Str(4 * (indent + 1), Ch(' '));
|
|
||||||
stream << Ch('"') << create_escapes(it->first, stream.getloc()) << Ch('"') << Ch(':');
|
|
||||||
if (it->second.empty())
|
|
||||||
stream << Ch(' ');
|
|
||||||
else
|
|
||||||
stream << Ch('\n') << Str(4 * (indent + 1), Ch(' '));
|
|
||||||
write_json_helper(stream, it->second, indent + 1);
|
|
||||||
if (boost::next(it) != pt.end())
|
|
||||||
stream << Ch(',');
|
|
||||||
stream << Ch('\n');
|
|
||||||
}
|
|
||||||
stream << Str(4 * indent, Ch(' ')) << Ch('}');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify if ptree does not contain information that cannot be written to json
|
|
||||||
template<class Ptree>
|
|
||||||
bool verify_json(const Ptree &pt, int depth)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef typename std::basic_string<Ch> Str;
|
|
||||||
|
|
||||||
// Root ptree cannot have data
|
|
||||||
if (depth == 0 && !pt.template get_own<Str>().empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Ptree cannot have both children and data
|
|
||||||
if (!pt.template get_own<Str>().empty() && !pt.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check children
|
|
||||||
typename Ptree::const_iterator it = pt.begin();
|
|
||||||
for (; it != pt.end(); ++it)
|
|
||||||
if (!verify_json(it->second, depth + 1))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Success
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write ptree to json stream
|
|
||||||
template<class Ptree>
|
|
||||||
void write_json_internal(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const Ptree &pt,
|
|
||||||
const std::string &filename)
|
|
||||||
{
|
|
||||||
if (!verify_json(pt, 0))
|
|
||||||
throw json_parser_error("ptree contains data that cannot be represented in JSON format", filename, 0);
|
|
||||||
write_json_helper(stream, pt, 0);
|
|
||||||
stream << std::endl;
|
|
||||||
if (!stream.good())
|
|
||||||
throw json_parser_error("write error", filename, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,198 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_INTERFACE_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_PTREE_INTERFACE_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <utility> // For std::pair
|
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
#include "boost/property_tree/ptree_fwd.hpp"
|
|
||||||
|
|
||||||
#ifdef BOOST_PROPERTY_TREE_DEBUG
|
|
||||||
# include <boost/detail/lightweight_mutex.hpp> // For syncing debug instances counter
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree
|
|
||||||
{
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// basic_ptree class template
|
|
||||||
|
|
||||||
template<class Tr>
|
|
||||||
class basic_ptree
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Basic types
|
|
||||||
typedef Tr traits_type;
|
|
||||||
typedef typename traits_type::char_type char_type;
|
|
||||||
typedef typename traits_type::key_type key_type;
|
|
||||||
typedef typename traits_type::data_type data_type;
|
|
||||||
|
|
||||||
// Container-related types
|
|
||||||
typedef std::pair<key_type, basic_ptree<Tr> > value_type;
|
|
||||||
typedef std::list<value_type> container_type;
|
|
||||||
typedef typename container_type::size_type size_type;
|
|
||||||
typedef typename container_type::iterator iterator;
|
|
||||||
typedef typename container_type::const_iterator const_iterator;
|
|
||||||
typedef typename container_type::reverse_iterator reverse_iterator;
|
|
||||||
typedef typename container_type::const_reverse_iterator const_reverse_iterator;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Construction & destruction
|
|
||||||
|
|
||||||
basic_ptree();
|
|
||||||
explicit basic_ptree(const data_type &data);
|
|
||||||
basic_ptree(const basic_ptree<Tr> &rhs);
|
|
||||||
~basic_ptree();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Iterator access
|
|
||||||
|
|
||||||
iterator begin();
|
|
||||||
const_iterator begin() const;
|
|
||||||
iterator end();
|
|
||||||
const_iterator end() const;
|
|
||||||
reverse_iterator rbegin();
|
|
||||||
const_reverse_iterator rbegin() const;
|
|
||||||
reverse_iterator rend();
|
|
||||||
const_reverse_iterator rend() const;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Data access
|
|
||||||
|
|
||||||
size_type size() const;
|
|
||||||
bool empty() const;
|
|
||||||
|
|
||||||
data_type &data();
|
|
||||||
const data_type &data() const;
|
|
||||||
|
|
||||||
value_type &front();
|
|
||||||
const value_type &front() const;
|
|
||||||
value_type &back();
|
|
||||||
const value_type &back() const;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Operators
|
|
||||||
|
|
||||||
basic_ptree<Tr> &operator =(const basic_ptree<Tr> &rhs);
|
|
||||||
|
|
||||||
bool operator ==(const basic_ptree<Tr> &rhs) const;
|
|
||||||
bool operator !=(const basic_ptree<Tr> &rhs) const;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Container operations
|
|
||||||
|
|
||||||
iterator find(const key_type &key);
|
|
||||||
const_iterator find(const key_type &key) const;
|
|
||||||
|
|
||||||
size_type count(const key_type &key) const;
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
iterator insert(iterator where, const value_type &value);
|
|
||||||
template<class It> void insert(iterator where, It first, It last);
|
|
||||||
|
|
||||||
iterator erase(iterator where);
|
|
||||||
size_type erase(const key_type &key);
|
|
||||||
template<class It> iterator erase(It first, It last);
|
|
||||||
|
|
||||||
iterator push_front(const value_type &value);
|
|
||||||
iterator push_back(const value_type &value);
|
|
||||||
|
|
||||||
void pop_front();
|
|
||||||
void pop_back();
|
|
||||||
|
|
||||||
void swap(basic_ptree<Tr> &rhs);
|
|
||||||
|
|
||||||
void reverse();
|
|
||||||
template<class SortTr> void sort(SortTr tr);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// ptree operations
|
|
||||||
|
|
||||||
// Get child ptree with custom separator
|
|
||||||
basic_ptree<Tr> &get_child(char_type separator, const key_type &path);
|
|
||||||
const basic_ptree<Tr> &get_child(char_type separator, const key_type &path) const;
|
|
||||||
basic_ptree<Tr> &get_child(char_type separator, const key_type &path, basic_ptree<Tr> &default_value);
|
|
||||||
const basic_ptree<Tr> &get_child(char_type separator, const key_type &path, const basic_ptree<Tr> &default_value) const;
|
|
||||||
optional<basic_ptree<Tr> &> get_child_optional(char_type separator, const key_type &path);
|
|
||||||
optional<const basic_ptree<Tr> &> get_child_optional(char_type separator, const key_type &path) const;
|
|
||||||
|
|
||||||
// Get child ptree with default separator
|
|
||||||
basic_ptree<Tr> &get_child(const key_type &path);
|
|
||||||
const basic_ptree<Tr> &get_child(const key_type &path) const;
|
|
||||||
basic_ptree<Tr> &get_child(const key_type &path, basic_ptree<Tr> &default_value);
|
|
||||||
const basic_ptree<Tr> &get_child(const key_type &path, const basic_ptree<Tr> &default_value) const;
|
|
||||||
optional<basic_ptree<Tr> &> get_child_optional(const key_type &path);
|
|
||||||
optional<const basic_ptree<Tr> &> get_child_optional(const key_type &path) const;
|
|
||||||
|
|
||||||
// Put child ptree with custom separator
|
|
||||||
basic_ptree<Tr> &put_child(char_type separator, const key_type &path, const basic_ptree<Tr> &value, bool do_not_replace = false);
|
|
||||||
|
|
||||||
// Put child ptree with default separator
|
|
||||||
basic_ptree<Tr> &put_child(const key_type &path, const basic_ptree<Tr> &value, bool do_not_replace = false);
|
|
||||||
|
|
||||||
// Get value from data of ptree
|
|
||||||
template<class Type> Type get_own(const std::locale &loc = std::locale()) const;
|
|
||||||
template<class Type> Type get_own(const Type &default_value, const std::locale &loc = std::locale()) const;
|
|
||||||
template<class CharType> std::basic_string<CharType> get_own(const CharType *default_value, const std::locale &loc = std::locale()) const;
|
|
||||||
template<class Type> optional<Type> get_own_optional(const std::locale &loc = std::locale()) const;
|
|
||||||
|
|
||||||
// Get value from data of child ptree (custom path separator)
|
|
||||||
template<class Type> Type get(char_type separator, const key_type &path, const std::locale &loc = std::locale()) const;
|
|
||||||
template<class Type> Type get(char_type separator, const key_type &path, const Type &default_value, const std::locale &loc = std::locale()) const;
|
|
||||||
template<class CharType> std::basic_string<CharType> get(char_type separator, const key_type &path, const CharType *default_value, const std::locale &loc = std::locale()) const;
|
|
||||||
template<class Type> optional<Type> get_optional(char_type separator, const key_type &path, const std::locale &loc = std::locale()) const;
|
|
||||||
|
|
||||||
// Get value from data of child ptree (default path separator)
|
|
||||||
template<class Type> Type get(const key_type &path, const std::locale &loc = std::locale()) const;
|
|
||||||
template<class Type> Type get(const key_type &path, const Type &default_value, const std::locale &loc = std::locale()) const;
|
|
||||||
template<class CharType> std::basic_string<CharType> get(const key_type &path, const CharType *default_value, const std::locale &loc = std::locale()) const;
|
|
||||||
template<class Type> optional<Type> get_optional(const key_type &path, const std::locale &loc = std::locale()) const;
|
|
||||||
|
|
||||||
// Put value in data of ptree
|
|
||||||
template<class Type> void put_own(const Type &value, const std::locale &loc = std::locale());
|
|
||||||
|
|
||||||
// Put value in data of child ptree (custom path separator)
|
|
||||||
template<class Type> basic_ptree<Tr> &put(char_type separator, const key_type &path, const Type &value, bool do_not_replace = false, const std::locale &loc = std::locale());
|
|
||||||
|
|
||||||
// Put value in data of child ptree (default path separator)
|
|
||||||
template<class Type> basic_ptree<Tr> &put(const key_type &path, const Type &value, bool do_not_replace = false, const std::locale &loc = std::locale());
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef std::multimap<key_type, iterator, Tr> index_type;
|
|
||||||
|
|
||||||
struct impl;
|
|
||||||
impl *m_impl;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Debugging
|
|
||||||
|
|
||||||
#ifdef BOOST_PROPERTY_TREE_DEBUG
|
|
||||||
private:
|
|
||||||
static boost::detail::lightweight_mutex debug_mutex; // Mutex for syncing instances counter
|
|
||||||
static size_type debug_instances_count; // Total number of instances of this ptree class
|
|
||||||
public:
|
|
||||||
static size_type debug_get_instances_count();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,72 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
// Naively convert narrow string to another character type
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> widen(const char *text)
|
|
||||||
{
|
|
||||||
std::locale loc;
|
|
||||||
std::basic_string<Ch> result;
|
|
||||||
while (*text)
|
|
||||||
{
|
|
||||||
result += Ch(*text);
|
|
||||||
++text;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Naively convert string to narrow character type
|
|
||||||
template<class Ch>
|
|
||||||
std::string narrow(const Ch *text)
|
|
||||||
{
|
|
||||||
std::locale loc;
|
|
||||||
std::string result;
|
|
||||||
while (*text)
|
|
||||||
{
|
|
||||||
if (*text < 0 || *text > (std::numeric_limits<char>::max)())
|
|
||||||
result += '*';
|
|
||||||
else
|
|
||||||
result += char(*text);
|
|
||||||
++text;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove trailing and leading spaces
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> trim(const std::basic_string<Ch> &s,
|
|
||||||
const std::locale &loc = std::locale())
|
|
||||||
{
|
|
||||||
typename std::basic_string<Ch>::const_iterator first = s.begin();
|
|
||||||
typename std::basic_string<Ch>::const_iterator end = s.end();
|
|
||||||
while (first != end && std::isspace(*first, loc))
|
|
||||||
++first;
|
|
||||||
if (first == end)
|
|
||||||
return std::basic_string<Ch>();
|
|
||||||
typename std::basic_string<Ch>::const_iterator last = end;
|
|
||||||
do --last; while (std::isspace(*last, loc));
|
|
||||||
if (first != s.begin() || last + 1 != end)
|
|
||||||
return std::basic_string<Ch>(first, last + 1);
|
|
||||||
else
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,33 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/detail/file_parser_error.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace xml_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
//! Xml parser error
|
|
||||||
class xml_parser_error: public file_parser_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
xml_parser_error(const std::string &message,
|
|
||||||
const std::string &filename,
|
|
||||||
unsigned long line):
|
|
||||||
file_parser_error(message, filename, line)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,26 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace xml_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
static const int no_concat_text = 1; // Text elements should be put in separate keys, not concatenated in parent data
|
|
||||||
static const int no_comments = 2; // Comments should be omitted
|
|
||||||
|
|
||||||
inline bool validate_flags(int flags)
|
|
||||||
{
|
|
||||||
return (flags & ~(no_concat_text | no_comments)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,737 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Based on XML grammar by Daniel C. Nuffer
|
|
||||||
// http://spirit.sourceforge.net/repository/applications/xml.zip
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_SPIRIT_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_SPIRIT_HPP_INCLUDED
|
|
||||||
|
|
||||||
//#define BOOST_SPIRIT_DEBUG
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_error.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_flags.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_utils.hpp>
|
|
||||||
|
|
||||||
#if BOOST_VERSION < 103800
|
|
||||||
#include <boost/spirit.hpp>
|
|
||||||
#include <boost/spirit/iterator/position_iterator.hpp>
|
|
||||||
#else
|
|
||||||
#define BOOST_SPIRIT_USE_OLD_NAMESPACE
|
|
||||||
#include <boost/spirit/include/classic.hpp>
|
|
||||||
#include <boost/spirit/include/classic_position_iterator.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <locale>
|
|
||||||
#include <istream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace xml_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
// XML parser context
|
|
||||||
template<class Ptree>
|
|
||||||
struct context
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
typedef boost::spirit::position_iterator<typename std::vector<Ch>::const_iterator> It;
|
|
||||||
|
|
||||||
int flags;
|
|
||||||
std::vector<Ptree *> stack;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// Actions
|
|
||||||
|
|
||||||
struct a_key_s
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_key_s(context &c): c(c) { }
|
|
||||||
void operator()(It b, It e) const
|
|
||||||
{
|
|
||||||
if (c.stack.empty())
|
|
||||||
throw xml_parser_error("xml parse error",
|
|
||||||
b.get_position().file,
|
|
||||||
b.get_position().line);
|
|
||||||
Str name(b, e);
|
|
||||||
Ptree *child = &c.stack.back()->push_back(std::make_pair(name, Ptree()))->second;
|
|
||||||
c.stack.push_back(child);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_key_e
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_key_e(context &c): c(c) { }
|
|
||||||
void operator()(It b, It e) const
|
|
||||||
{
|
|
||||||
if (c.stack.size() <= 1)
|
|
||||||
throw xml_parser_error("xml parse error",
|
|
||||||
b.get_position().file,
|
|
||||||
b.get_position().line);
|
|
||||||
c.stack.pop_back();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_content
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_content(context &c): c(c) { }
|
|
||||||
void operator()(It b, It e) const
|
|
||||||
{
|
|
||||||
Str s = decode_char_entities(detail::trim(condense(Str(b, e))));
|
|
||||||
if (!s.empty())
|
|
||||||
{
|
|
||||||
if (c.flags & no_concat_text)
|
|
||||||
c.stack.back()->push_back(std::make_pair(xmltext<Ch>(), Ptree(s)));
|
|
||||||
else
|
|
||||||
c.stack.back()->put_own(c.stack.back()->template get_own<std::basic_string<Ch> >() + s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_attr_key
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_attr_key(context &c): c(c) { }
|
|
||||||
void operator()(It b, It e) const
|
|
||||||
{
|
|
||||||
c.stack.back()->put_child(Ch('/'), xmlattr<Ch>() + Ch('/') + Str(b, e), empty_ptree<Ptree>());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_attr_data
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_attr_data(context &c): c(c) { }
|
|
||||||
void operator()(It b, It e) const
|
|
||||||
{
|
|
||||||
Ptree &attr = c.stack.back()->get_child(xmlattr<Ch>());
|
|
||||||
attr.back().second.put_own(Str(b.base() + 1, e.base() - 1));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct a_comment
|
|
||||||
{
|
|
||||||
context &c;
|
|
||||||
a_comment(context &c): c(c) { }
|
|
||||||
void operator()(It b, It e) const
|
|
||||||
{
|
|
||||||
c.stack.back()->push_back(std::make_pair(xmlcomment<Ch>(), Ptree(Str(b, e))));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// Grammar
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
struct xml_grammar: public boost::spirit::grammar<xml_grammar<Ptree> >
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef context<Ptree> context_t;
|
|
||||||
|
|
||||||
mutable context_t c;
|
|
||||||
|
|
||||||
template<class ScannerT>
|
|
||||||
struct definition
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename ScannerT::value_t char_t;
|
|
||||||
typedef boost::spirit::chset<char_t> chset_t;
|
|
||||||
|
|
||||||
boost::spirit::rule<ScannerT>
|
|
||||||
prolog, element, Misc, PEReference, Reference, PITarget, CData,
|
|
||||||
doctypedecl, XMLDecl, SDDecl, VersionInfo, EncodingDecl, VersionNum,
|
|
||||||
Eq, DeclSep, ExternalID, markupdecl, NotationDecl, EntityDecl,
|
|
||||||
AttlistDecl, elementdecl, TextDecl, extSubsetDecl, conditionalSect,
|
|
||||||
EmptyElemTag, STag, content, ETag, Attribute, contentspec, Mixed,
|
|
||||||
children, choice, seq, cp, AttDef, AttType, DefaultDecl, StringType,
|
|
||||||
TokenizedType, EnumeratedType, NotationType, Enumeration, EntityValue,
|
|
||||||
AttValue, SystemLiteral, PubidLiteral, CharDataChar, CharData, Comment,
|
|
||||||
PI, CDSect, extSubset, includeSect, ignoreSect, ignoreSectContents,
|
|
||||||
Ignore, CharRef, EntityRef, GEDecl, PEDecl, EntityDef, PEDef,
|
|
||||||
NDataDecl, extParsedEnt, EncName, PublicID, document, S, Name, Names,
|
|
||||||
Nmtoken, Nmtokens, STagB, STagE1, STagE2;
|
|
||||||
|
|
||||||
definition(const xml_grammar &self)
|
|
||||||
{
|
|
||||||
|
|
||||||
using namespace boost::spirit;
|
|
||||||
|
|
||||||
// XML Char sets
|
|
||||||
chset_t Char("\x9\xA\xD\x20-\x7F");
|
|
||||||
chset_t Sch("\x20\x9\xD\xA");
|
|
||||||
chset_t Letter("\x41-\x5A\x61-\x7A");
|
|
||||||
chset_t Digit("0-9");
|
|
||||||
chset_t XDigit("0-9A-Fa-f");
|
|
||||||
chset_t Extender("\xB7");
|
|
||||||
chset_t NameChar =
|
|
||||||
Letter
|
|
||||||
| Digit
|
|
||||||
| (char_t)'.'
|
|
||||||
| (char_t)'-'
|
|
||||||
| (char_t)'_'
|
|
||||||
| (char_t)':'
|
|
||||||
| Extender;
|
|
||||||
|
|
||||||
document =
|
|
||||||
prolog >> element >> *Misc
|
|
||||||
;
|
|
||||||
|
|
||||||
S =
|
|
||||||
+(Sch)
|
|
||||||
;
|
|
||||||
|
|
||||||
Name =
|
|
||||||
(Letter | '_' | ':')
|
|
||||||
>> *(NameChar)
|
|
||||||
;
|
|
||||||
|
|
||||||
Names =
|
|
||||||
Name >> *(S >> Name)
|
|
||||||
;
|
|
||||||
|
|
||||||
Nmtoken =
|
|
||||||
+NameChar
|
|
||||||
;
|
|
||||||
|
|
||||||
Nmtokens =
|
|
||||||
Nmtoken >> *(S >> Nmtoken)
|
|
||||||
;
|
|
||||||
|
|
||||||
EntityValue =
|
|
||||||
'"' >> *( (anychar_p - (chset_t(detail::widen<char_t>("%&\"").c_str())))
|
|
||||||
| PEReference
|
|
||||||
| Reference)
|
|
||||||
>> '"'
|
|
||||||
| '\'' >> *( (anychar_p - (chset_t("%&'")))
|
|
||||||
| PEReference
|
|
||||||
| Reference)
|
|
||||||
>> '\''
|
|
||||||
;
|
|
||||||
|
|
||||||
AttValue =
|
|
||||||
'"' >> *( (anychar_p - (chset_t("<&\"")))
|
|
||||||
| Reference)
|
|
||||||
>> '"'
|
|
||||||
| '\'' >> *( (anychar_p - (chset_t("<&'")))
|
|
||||||
| Reference)
|
|
||||||
>> '\''
|
|
||||||
;
|
|
||||||
|
|
||||||
SystemLiteral=
|
|
||||||
('"' >> *(anychar_p - '"') >> '"')
|
|
||||||
| ('\'' >> *(anychar_p - '\'') >> '\'')
|
|
||||||
;
|
|
||||||
|
|
||||||
chset_t PubidChar("\x20\xD\xA'a-zA-Z0-9()+,./:=?;!*#@$_%-");
|
|
||||||
|
|
||||||
PubidLiteral =
|
|
||||||
'"' >> *PubidChar >> '"'
|
|
||||||
| '\'' >> *(PubidChar - '\'') >> '\''
|
|
||||||
;
|
|
||||||
|
|
||||||
CharDataChar =
|
|
||||||
//anychar_p - (chset_t("<&"))
|
|
||||||
anychar_p - (chset_t("<"))
|
|
||||||
;
|
|
||||||
|
|
||||||
CharData =
|
|
||||||
*(CharDataChar - "]]>")
|
|
||||||
;
|
|
||||||
|
|
||||||
Comment =
|
|
||||||
"<!--" >>
|
|
||||||
(
|
|
||||||
*(
|
|
||||||
(Char - '-')
|
|
||||||
| ('-' >> (Char - '-'))
|
|
||||||
)
|
|
||||||
)[typename context_t::a_comment(self.c)]
|
|
||||||
>> "-->"
|
|
||||||
;
|
|
||||||
|
|
||||||
PI =
|
|
||||||
"<?" >> PITarget >> !(S >> (*(Char - "?>"))) >> "?>"
|
|
||||||
;
|
|
||||||
|
|
||||||
PITarget =
|
|
||||||
Name - (as_lower_d["xml"])
|
|
||||||
;
|
|
||||||
|
|
||||||
CDSect =
|
|
||||||
"<![CDATA[" >> CData >> "]]>"
|
|
||||||
;
|
|
||||||
|
|
||||||
CData =
|
|
||||||
*(Char - "]]>")
|
|
||||||
;
|
|
||||||
|
|
||||||
prolog =
|
|
||||||
!XMLDecl >> *Misc >> !(doctypedecl >> *Misc)
|
|
||||||
;
|
|
||||||
|
|
||||||
XMLDecl =
|
|
||||||
"<?xml" >> VersionInfo >> !EncodingDecl >> !SDDecl
|
|
||||||
>> !S >> "?>"
|
|
||||||
;
|
|
||||||
|
|
||||||
VersionInfo =
|
|
||||||
S >> "version" >> Eq >>
|
|
||||||
(
|
|
||||||
'\'' >> VersionNum >> '\''
|
|
||||||
| '"' >> VersionNum >> '"'
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
Eq =
|
|
||||||
!S >> '=' >> !S
|
|
||||||
;
|
|
||||||
|
|
||||||
chset_t VersionNumCh("a-zA-Z0-9_.:-");
|
|
||||||
|
|
||||||
VersionNum =
|
|
||||||
+(VersionNumCh)
|
|
||||||
;
|
|
||||||
|
|
||||||
Misc =
|
|
||||||
Comment
|
|
||||||
| PI
|
|
||||||
| S
|
|
||||||
;
|
|
||||||
|
|
||||||
doctypedecl =
|
|
||||||
"<!DOCTYPE" >> S >> Name >> !(S >> ExternalID) >> !S >>
|
|
||||||
!(
|
|
||||||
'[' >> *(markupdecl | DeclSep) >> ']' >> !S
|
|
||||||
)
|
|
||||||
>> '>'
|
|
||||||
;
|
|
||||||
|
|
||||||
DeclSep =
|
|
||||||
PEReference
|
|
||||||
| S
|
|
||||||
;
|
|
||||||
|
|
||||||
markupdecl =
|
|
||||||
elementdecl
|
|
||||||
| AttlistDecl
|
|
||||||
| EntityDecl
|
|
||||||
| NotationDecl
|
|
||||||
| PI
|
|
||||||
| Comment
|
|
||||||
;
|
|
||||||
|
|
||||||
extSubset =
|
|
||||||
!TextDecl >> extSubsetDecl
|
|
||||||
;
|
|
||||||
|
|
||||||
extSubsetDecl =
|
|
||||||
*(
|
|
||||||
markupdecl
|
|
||||||
| conditionalSect
|
|
||||||
| DeclSep
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
SDDecl =
|
|
||||||
S >> "standalone" >> Eq >>
|
|
||||||
(
|
|
||||||
('\'' >> (str_p("yes") | "no") >> '\'')
|
|
||||||
| ('"' >> (str_p("yes") | "no") >> '"')
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
/*
|
|
||||||
element =
|
|
||||||
EmptyElemTag
|
|
||||||
| STag >> content >> ETag
|
|
||||||
;
|
|
||||||
*/
|
|
||||||
element =
|
|
||||||
STagB >> (STagE2 | (STagE1 >> content >> ETag))[typename context_t::a_key_e(self.c)]
|
|
||||||
;
|
|
||||||
|
|
||||||
STag =
|
|
||||||
'<' >> Name >> *(S >> Attribute) >> !S >> '>'
|
|
||||||
;
|
|
||||||
|
|
||||||
STagB =
|
|
||||||
'<'
|
|
||||||
>> Name[typename context_t::a_key_s(self.c)]
|
|
||||||
>> *(S >> Attribute)
|
|
||||||
>> !S
|
|
||||||
;
|
|
||||||
|
|
||||||
STagE1 =
|
|
||||||
ch_p(">")
|
|
||||||
;
|
|
||||||
|
|
||||||
STagE2 =
|
|
||||||
str_p("/>")
|
|
||||||
;
|
|
||||||
|
|
||||||
Attribute =
|
|
||||||
Name[typename context_t::a_attr_key(self.c)]
|
|
||||||
>> Eq
|
|
||||||
>> AttValue[typename context_t::a_attr_data(self.c)]
|
|
||||||
;
|
|
||||||
|
|
||||||
ETag =
|
|
||||||
"</" >> Name >> !S >> '>'
|
|
||||||
;
|
|
||||||
|
|
||||||
content =
|
|
||||||
!(CharData[typename context_t::a_content(self.c)]) >>
|
|
||||||
*(
|
|
||||||
(
|
|
||||||
element
|
|
||||||
// | Reference
|
|
||||||
| CDSect
|
|
||||||
| PI
|
|
||||||
| Comment
|
|
||||||
) >>
|
|
||||||
!(CharData[typename context_t::a_content(self.c)])
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
EmptyElemTag =
|
|
||||||
'<' >> Name >> *(S >> Attribute) >> !S >> "/>"
|
|
||||||
;
|
|
||||||
|
|
||||||
elementdecl =
|
|
||||||
"<!ELEMENT" >> S >> Name >> S >> contentspec >> !S >> '>'
|
|
||||||
;
|
|
||||||
|
|
||||||
contentspec =
|
|
||||||
str_p("EMPTY")
|
|
||||||
| "ANY"
|
|
||||||
| Mixed
|
|
||||||
| children
|
|
||||||
;
|
|
||||||
|
|
||||||
children =
|
|
||||||
(choice | seq) >> !(ch_p('?') | '*' | '+')
|
|
||||||
;
|
|
||||||
|
|
||||||
cp =
|
|
||||||
(Name | choice | seq) >> !(ch_p('?') | '*' | '+')
|
|
||||||
;
|
|
||||||
|
|
||||||
choice =
|
|
||||||
'(' >> !S >> cp
|
|
||||||
>> +(!S >> '|' >> !S >> cp)
|
|
||||||
>> !S >> ')'
|
|
||||||
;
|
|
||||||
|
|
||||||
seq =
|
|
||||||
'(' >> !S >> cp >>
|
|
||||||
*(!S >> ',' >> !S >> cp)
|
|
||||||
>> !S >> ')'
|
|
||||||
;
|
|
||||||
|
|
||||||
Mixed =
|
|
||||||
'(' >> !S >> "#PCDATA"
|
|
||||||
>> *(!S >> '|' >> !S >> Name)
|
|
||||||
>> !S >> ")*"
|
|
||||||
| '(' >> !S >> "#PCDATA" >> !S >> ')'
|
|
||||||
;
|
|
||||||
|
|
||||||
AttlistDecl =
|
|
||||||
"<!ATTLIST" >> S >> Name >> *AttDef >> !S >> '>'
|
|
||||||
;
|
|
||||||
|
|
||||||
AttDef =
|
|
||||||
S >> Name >> S >> AttType >> S >> DefaultDecl
|
|
||||||
;
|
|
||||||
|
|
||||||
AttType =
|
|
||||||
StringType
|
|
||||||
| TokenizedType
|
|
||||||
| EnumeratedType
|
|
||||||
;
|
|
||||||
|
|
||||||
StringType =
|
|
||||||
str_p("CDATA")
|
|
||||||
;
|
|
||||||
|
|
||||||
TokenizedType =
|
|
||||||
longest_d[
|
|
||||||
str_p("ID")
|
|
||||||
| "IDREF"
|
|
||||||
| "IDREFS"
|
|
||||||
| "ENTITY"
|
|
||||||
| "ENTITIES"
|
|
||||||
| "NMTOKEN"
|
|
||||||
| "NMTOKENS"
|
|
||||||
]
|
|
||||||
;
|
|
||||||
|
|
||||||
EnumeratedType =
|
|
||||||
NotationType
|
|
||||||
| Enumeration
|
|
||||||
;
|
|
||||||
|
|
||||||
NotationType =
|
|
||||||
"NOTATION" >> S >> '(' >> !S >> Name
|
|
||||||
>> *(!S >> '|' >> !S >> Name)
|
|
||||||
>> !S >> ')'
|
|
||||||
;
|
|
||||||
|
|
||||||
Enumeration =
|
|
||||||
'(' >> !S >> Nmtoken
|
|
||||||
>> *(!S >> '|' >> !S >> Nmtoken)
|
|
||||||
>> !S >> ')'
|
|
||||||
;
|
|
||||||
|
|
||||||
DefaultDecl =
|
|
||||||
str_p("#REQUIRED")
|
|
||||||
| "#IMPLIED"
|
|
||||||
| !("#FIXED" >> S) >> AttValue
|
|
||||||
;
|
|
||||||
|
|
||||||
conditionalSect =
|
|
||||||
includeSect
|
|
||||||
| ignoreSect
|
|
||||||
;
|
|
||||||
|
|
||||||
includeSect =
|
|
||||||
"<![" >> !S >> "INCLUDE" >> !S
|
|
||||||
>> '[' >> extSubsetDecl >> "]]>"
|
|
||||||
;
|
|
||||||
|
|
||||||
ignoreSect =
|
|
||||||
"<![" >> !S >> "IGNORE" >> !S
|
|
||||||
>> '[' >> *ignoreSectContents >> "]]>"
|
|
||||||
;
|
|
||||||
|
|
||||||
ignoreSectContents =
|
|
||||||
Ignore >> *("<![" >> ignoreSectContents >> "]]>" >> Ignore)
|
|
||||||
;
|
|
||||||
|
|
||||||
Ignore =
|
|
||||||
*(Char - (str_p("<![") | "]]>"))
|
|
||||||
;
|
|
||||||
|
|
||||||
CharRef =
|
|
||||||
"&#" >> +Digit >> ';'
|
|
||||||
| "&#x" >> +XDigit >> ';'
|
|
||||||
;
|
|
||||||
|
|
||||||
Reference =
|
|
||||||
EntityRef
|
|
||||||
| CharRef
|
|
||||||
;
|
|
||||||
|
|
||||||
EntityRef =
|
|
||||||
'&' >> Name >> ';'
|
|
||||||
;
|
|
||||||
|
|
||||||
PEReference =
|
|
||||||
'%' >> Name >> ';'
|
|
||||||
;
|
|
||||||
|
|
||||||
EntityDecl =
|
|
||||||
GEDecl
|
|
||||||
| PEDecl
|
|
||||||
;
|
|
||||||
|
|
||||||
GEDecl =
|
|
||||||
"<!ENTITY" >> S >> Name >> S >> EntityDef >> !S >> '>'
|
|
||||||
;
|
|
||||||
|
|
||||||
PEDecl =
|
|
||||||
"<!ENTITY" >> S >> '%' >> S >> Name >> S >> PEDef
|
|
||||||
>> !S >> '>'
|
|
||||||
;
|
|
||||||
|
|
||||||
EntityDef =
|
|
||||||
EntityValue
|
|
||||||
| ExternalID >> !NDataDecl
|
|
||||||
;
|
|
||||||
|
|
||||||
PEDef =
|
|
||||||
EntityValue
|
|
||||||
| ExternalID
|
|
||||||
;
|
|
||||||
|
|
||||||
ExternalID =
|
|
||||||
"SYSTEM" >> S >> SystemLiteral
|
|
||||||
| "PUBLIC" >> S >> PubidLiteral >> S >> SystemLiteral
|
|
||||||
;
|
|
||||||
|
|
||||||
NDataDecl =
|
|
||||||
S >> "NDATA" >> S >> Name
|
|
||||||
;
|
|
||||||
|
|
||||||
TextDecl =
|
|
||||||
"<?xml" >> !VersionInfo >> EncodingDecl >> !S >> "?>"
|
|
||||||
;
|
|
||||||
|
|
||||||
extParsedEnt =
|
|
||||||
!TextDecl >> content
|
|
||||||
;
|
|
||||||
|
|
||||||
EncodingDecl =
|
|
||||||
S >> "encoding" >> Eq
|
|
||||||
>> ( '"' >> EncName >> '"'
|
|
||||||
| '\'' >> EncName >> '\''
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
EncName =
|
|
||||||
Letter >> *(Letter | Digit | '.' | '_' | '-')
|
|
||||||
;
|
|
||||||
|
|
||||||
NotationDecl =
|
|
||||||
"<!NOTATION" >> S >> Name >> S
|
|
||||||
>> (ExternalID | PublicID) >> !S >> '>'
|
|
||||||
;
|
|
||||||
|
|
||||||
PublicID =
|
|
||||||
"PUBLIC" >> S >> PubidLiteral
|
|
||||||
;
|
|
||||||
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(document);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(prolog);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(element);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Misc);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(PEReference);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Reference);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(PITarget);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(CData);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(doctypedecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(XMLDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(SDDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(VersionInfo);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(EncodingDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(VersionNum);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Eq);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(DeclSep);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(ExternalID);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(markupdecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(NotationDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(EntityDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(AttlistDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(elementdecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(TextDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(extSubsetDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(conditionalSect);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(EmptyElemTag);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(STag);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(content);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(ETag);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Attribute);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(contentspec);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Mixed);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(children);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(choice);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(seq);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(cp);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(AttDef);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(AttType);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(DefaultDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(StringType);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(TokenizedType);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(EnumeratedType);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(NotationType);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Enumeration);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(EntityValue);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(AttValue);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(SystemLiteral);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(PubidLiteral);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(CharDataChar);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(CharData);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Comment);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(PI);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(CDSect);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(extSubset);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(includeSect);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(ignoreSect);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(ignoreSectContents);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Ignore);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(CharRef);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(EntityRef);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(GEDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(PEDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(EntityDef);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(PEDef);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(NDataDecl);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(extParsedEnt);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(EncName);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(PublicID);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(document);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(S);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Name);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Names);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Nmtoken);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(Nmtokens);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(STagB);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(STagE1);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(STagE2);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::spirit::rule<ScannerT> &start() const
|
|
||||||
{
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
void read_xml_internal(std::basic_istream<typename Ptree::char_type> &stream,
|
|
||||||
Ptree &pt,
|
|
||||||
int flags,
|
|
||||||
const std::string &filename)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef boost::spirit::position_iterator<typename std::vector<Ch>::const_iterator> It;
|
|
||||||
|
|
||||||
BOOST_ASSERT(validate_flags(flags));
|
|
||||||
|
|
||||||
// Load data into vector
|
|
||||||
std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
|
|
||||||
std::istreambuf_iterator<Ch>());
|
|
||||||
if (!stream.good())
|
|
||||||
throw xml_parser_error("read error", filename, 0);
|
|
||||||
|
|
||||||
// Initialize iterators
|
|
||||||
It begin(v.begin(), v.end());
|
|
||||||
It end(v.end(), v.end());
|
|
||||||
begin.set_position(filename);
|
|
||||||
|
|
||||||
// Prepare grammar
|
|
||||||
Ptree local;
|
|
||||||
xml_grammar<Ptree> g;
|
|
||||||
g.c.stack.push_back(&local); // Push root ptree on context stack
|
|
||||||
g.c.flags = flags;
|
|
||||||
|
|
||||||
// Parse into local
|
|
||||||
boost::spirit::parse_info<It> result = boost::spirit::parse(begin, end, g);
|
|
||||||
if (!result.full || g.c.stack.size() != 1)
|
|
||||||
throw xml_parser_error("xml parse error",
|
|
||||||
result.stop.get_position().file,
|
|
||||||
result.stop.get_position().line);
|
|
||||||
|
|
||||||
// Swap local and pt
|
|
||||||
pt.swap(local);
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,82 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_TINYXML_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_TINYXML_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_error.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_flags.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_utils.hpp>
|
|
||||||
|
|
||||||
#ifndef TIXML_USE_STL
|
|
||||||
#define TIXML_USE_STL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <tinyxml.h>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace xml_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
void read_xml_node(TiXmlNode *node, Ptree &pt, int flags)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
|
|
||||||
if (TiXmlElement *elem = node->ToElement())
|
|
||||||
{
|
|
||||||
Ptree &tmp = pt.push_back(std::make_pair(elem->Value(), Ptree()))->second;
|
|
||||||
for (TiXmlAttribute *attr = elem->FirstAttribute(); attr; attr = attr->Next())
|
|
||||||
tmp.put(Ch('/'), xmlattr<Ch>() + "/" + attr->Name(), attr->Value());
|
|
||||||
for (TiXmlNode *child = node->FirstChild(); child; child = child->NextSibling())
|
|
||||||
read_xml_node(child, tmp, flags);
|
|
||||||
}
|
|
||||||
else if (TiXmlText *text = node->ToText())
|
|
||||||
{
|
|
||||||
if (flags & no_concat_text)
|
|
||||||
pt.push_back(std::make_pair(xmltext<Ch>(), Ptree(text->Value())));
|
|
||||||
else
|
|
||||||
pt.data() += text->Value();
|
|
||||||
}
|
|
||||||
else if (TiXmlComment *comment = node->ToComment())
|
|
||||||
{
|
|
||||||
if (!(flags & no_comments))
|
|
||||||
pt.push_back(std::make_pair(xmlcomment<Ch>(), Ptree(comment->Value())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
void read_xml_internal(std::basic_istream<typename Ptree::char_type> &stream,
|
|
||||||
Ptree &pt,
|
|
||||||
int flags,
|
|
||||||
const std::string &filename)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Create and load document from stream
|
|
||||||
TiXmlDocument doc;
|
|
||||||
stream >> doc;
|
|
||||||
if (!stream.good())
|
|
||||||
throw xml_parser_error("read error", filename, 0);
|
|
||||||
if (doc.Error())
|
|
||||||
throw xml_parser_error(doc.ErrorDesc(), filename, doc.ErrorRow());
|
|
||||||
|
|
||||||
// Create ptree from nodes
|
|
||||||
Ptree local;
|
|
||||||
for (TiXmlNode *child = doc.FirstChild(); child; child = child->NextSibling())
|
|
||||||
read_xml_node(child, local, flags);
|
|
||||||
|
|
||||||
// Swap local and result ptrees
|
|
||||||
pt.swap(local);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,119 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/detail/ptree_utils.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_error.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace xml_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> condense(const std::basic_string<Ch> &s)
|
|
||||||
{
|
|
||||||
std::basic_string<Ch> r;
|
|
||||||
std::locale loc;
|
|
||||||
bool space = false;
|
|
||||||
typename std::basic_string<Ch>::const_iterator end = s.end();
|
|
||||||
for (typename std::basic_string<Ch>::const_iterator it = s.begin();
|
|
||||||
it != end; ++it)
|
|
||||||
{
|
|
||||||
if (isspace(*it, loc) || *it == Ch('\n'))
|
|
||||||
{
|
|
||||||
if (!space)
|
|
||||||
r += Ch(' '), space = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
r += *it, space = false;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> encode_char_entities(const std::basic_string<Ch> &s)
|
|
||||||
{
|
|
||||||
typedef typename std::basic_string<Ch> Str;
|
|
||||||
Str r;
|
|
||||||
typename Str::const_iterator end = s.end();
|
|
||||||
for (typename Str::const_iterator it = s.begin(); it != end; ++it)
|
|
||||||
{
|
|
||||||
switch (*it)
|
|
||||||
{
|
|
||||||
case Ch('<'): r += detail::widen<Ch>("<"); break;
|
|
||||||
case Ch('>'): r += detail::widen<Ch>(">"); break;
|
|
||||||
case Ch('&'): r += detail::widen<Ch>("&"); break;
|
|
||||||
default: r += *it; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> decode_char_entities(const std::basic_string<Ch> &s)
|
|
||||||
{
|
|
||||||
typedef typename std::basic_string<Ch> Str;
|
|
||||||
Str r;
|
|
||||||
typename Str::const_iterator end = s.end();
|
|
||||||
for (typename Str::const_iterator it = s.begin(); it != end; ++it)
|
|
||||||
{
|
|
||||||
if (*it == Ch('&'))
|
|
||||||
{
|
|
||||||
typename Str::const_iterator semicolon = std::find(it + 1, end, Ch(';'));
|
|
||||||
if (semicolon == end)
|
|
||||||
throw xml_parser_error("invalid character entity", "", 0);
|
|
||||||
Str ent(it + 1, semicolon);
|
|
||||||
if (ent == detail::widen<Ch>("lt")) r += Ch('<');
|
|
||||||
else if (ent == detail::widen<Ch>("gt")) r += Ch('>');
|
|
||||||
else if (ent == detail::widen<Ch>("amp")) r += Ch('&');
|
|
||||||
else
|
|
||||||
throw xml_parser_error("invalid character entity", "", 0);
|
|
||||||
it = semicolon;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
r += *it;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
const std::basic_string<Ch> &xmldecl()
|
|
||||||
{
|
|
||||||
static std::basic_string<Ch> s = detail::widen<Ch>("<?xml>");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
const std::basic_string<Ch> &xmlattr()
|
|
||||||
{
|
|
||||||
static std::basic_string<Ch> s = detail::widen<Ch>("<xmlattr>");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
const std::basic_string<Ch> &xmlcomment()
|
|
||||||
{
|
|
||||||
static std::basic_string<Ch> s = detail::widen<Ch>("<xmlcomment>");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
const std::basic_string<Ch> &xmltext()
|
|
||||||
{
|
|
||||||
static std::basic_string<Ch> s = detail::widen<Ch>("<xmltext>");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,145 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_utils.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <ostream>
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace xml_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
void write_xml_comment(std::basic_ostream<Ch> &stream,
|
|
||||||
const std::basic_string<Ch> &s,
|
|
||||||
int indent)
|
|
||||||
{
|
|
||||||
typedef typename std::basic_string<Ch> Str;
|
|
||||||
stream << Str(4 * indent, Ch(' '));
|
|
||||||
stream << Ch('<') << Ch('!') << Ch('-') << Ch('-');
|
|
||||||
stream << s;
|
|
||||||
stream << Ch('-') << Ch('-') << Ch('>') << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
void write_xml_text(std::basic_ostream<Ch> &stream,
|
|
||||||
const std::basic_string<Ch> &s,
|
|
||||||
int indent,
|
|
||||||
bool separate_line)
|
|
||||||
{
|
|
||||||
typedef typename std::basic_string<Ch> Str;
|
|
||||||
if (separate_line)
|
|
||||||
stream << Str(4 * indent, Ch(' '));
|
|
||||||
stream << encode_char_entities(s);
|
|
||||||
if (separate_line)
|
|
||||||
stream << Ch('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
void write_xml_element(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const std::basic_string<typename Ptree::char_type> &key,
|
|
||||||
const Ptree &pt,
|
|
||||||
int indent)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef typename std::basic_string<Ch> Str;
|
|
||||||
typedef typename Ptree::const_iterator It;
|
|
||||||
|
|
||||||
// Find if elements present
|
|
||||||
bool has_elements = false;
|
|
||||||
for (It it = pt.begin(), end = pt.end(); it != end; ++it)
|
|
||||||
if (it->first != xmlattr<Ch>() &&
|
|
||||||
it->first != xmltext<Ch>())
|
|
||||||
{
|
|
||||||
has_elements = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write element
|
|
||||||
if (pt.data().empty() && pt.empty()) // Empty key
|
|
||||||
{
|
|
||||||
if (indent >= 0)
|
|
||||||
stream << Str(4 * indent, Ch(' ')) << Ch('<') << key <<
|
|
||||||
Ch('/') << Ch('>') << std::endl;
|
|
||||||
}
|
|
||||||
else // Nonempty key
|
|
||||||
{
|
|
||||||
|
|
||||||
// Write opening tag, attributes and data
|
|
||||||
if (indent >= 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Write opening brace and key
|
|
||||||
stream << Str(4 * indent, Ch(' '));
|
|
||||||
stream << Ch('<') << key;
|
|
||||||
|
|
||||||
// Write attributes
|
|
||||||
if (optional<const Ptree &> attribs = pt.get_child_optional(xmlattr<Ch>()))
|
|
||||||
for (It it = attribs.get().begin(); it != attribs.get().end(); ++it)
|
|
||||||
stream << Ch(' ') << it->first << Ch('=') <<
|
|
||||||
Ch('"') << it->second.template get_own<std::basic_string<Ch> >() << Ch('"');
|
|
||||||
|
|
||||||
// Write closing brace
|
|
||||||
stream << Ch('>');
|
|
||||||
|
|
||||||
// Break line if needed
|
|
||||||
if (has_elements)
|
|
||||||
stream << Ch('\n');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write data text, if present
|
|
||||||
if (!pt.data().empty())
|
|
||||||
write_xml_text(stream, pt.template get_own<std::basic_string<Ch> >(), indent + 1, has_elements);
|
|
||||||
|
|
||||||
// Write elements, comments and texts
|
|
||||||
for (It it = pt.begin(); it != pt.end(); ++it)
|
|
||||||
{
|
|
||||||
if (it->first == xmlattr<Ch>())
|
|
||||||
continue;
|
|
||||||
else if (it->first == xmlcomment<Ch>())
|
|
||||||
write_xml_comment(stream, it->second.template get_own<std::basic_string<Ch> >(), indent + 1);
|
|
||||||
else if (it->first == xmltext<Ch>())
|
|
||||||
write_xml_text(stream, it->second.template get_own<std::basic_string<Ch> >(), indent + 1, has_elements);
|
|
||||||
else
|
|
||||||
write_xml_element(stream, it->first, it->second, indent + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write closing tag
|
|
||||||
if (indent >= 0)
|
|
||||||
{
|
|
||||||
if (has_elements)
|
|
||||||
stream << Str(4 * indent, Ch(' '));
|
|
||||||
stream << Ch('<') << Ch('/') << key << Ch('>') << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ptree>
|
|
||||||
void write_xml_internal(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const Ptree &pt,
|
|
||||||
const std::string &filename)
|
|
||||||
{
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef typename std::basic_string<Ch> Str;
|
|
||||||
stream << detail::widen<Ch>("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
|
||||||
write_xml_element(stream, Str(), pt, -1);
|
|
||||||
if (!stream)
|
|
||||||
throw xml_parser_error("write error", filename, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,77 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_INFO_PARSER_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_INFO_PARSER_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/info_parser_error.hpp>
|
|
||||||
#include <boost/property_tree/detail/info_parser_read.hpp>
|
|
||||||
#include <boost/property_tree/detail/info_parser_write.hpp>
|
|
||||||
#include <istream>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace info_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
// Read info from stream
|
|
||||||
template<class Ptree>
|
|
||||||
void read_info(std::basic_istream<typename Ptree::char_type> &stream,
|
|
||||||
Ptree &pt)
|
|
||||||
{
|
|
||||||
Ptree local;
|
|
||||||
read_info_internal(stream, local, std::string(), 0);
|
|
||||||
pt.swap(local);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read info from file
|
|
||||||
template<class Ptree>
|
|
||||||
void read_info(const std::string &filename,
|
|
||||||
Ptree &pt,
|
|
||||||
const std::locale &loc = std::locale())
|
|
||||||
{
|
|
||||||
std::basic_ifstream<typename Ptree::char_type> stream(filename.c_str());
|
|
||||||
if (!stream)
|
|
||||||
throw info_parser_error("cannot open file for reading", filename, 0);
|
|
||||||
stream.imbue(loc);
|
|
||||||
Ptree local;
|
|
||||||
read_info_internal(stream, local, filename, 0);
|
|
||||||
pt.swap(local);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write info to stream
|
|
||||||
template<class Ptree>
|
|
||||||
void write_info(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const Ptree &pt)
|
|
||||||
{
|
|
||||||
write_info_internal(stream, pt, std::string());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write info to file
|
|
||||||
template<class Ptree>
|
|
||||||
void write_info(const std::string &filename,
|
|
||||||
const Ptree &pt,
|
|
||||||
const std::locale &loc = std::locale())
|
|
||||||
{
|
|
||||||
std::basic_ofstream<typename Ptree::char_type> stream(filename.c_str());
|
|
||||||
if (!stream)
|
|
||||||
throw info_parser_error("cannot open file for writing", filename, 0);
|
|
||||||
stream.imbue(loc);
|
|
||||||
write_info_internal(stream, pt, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree
|
|
||||||
{
|
|
||||||
using info_parser::info_parser_error;
|
|
||||||
using info_parser::read_info;
|
|
||||||
using info_parser::write_info;
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,196 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_INI_PARSER_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_INI_PARSER_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/ptree_utils.hpp>
|
|
||||||
#include <boost/property_tree/detail/file_parser_error.hpp>
|
|
||||||
#include <istream>
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace ini_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
static const int skip_ini_validity_check = 1; // Skip check if ptree is a valid ini
|
|
||||||
|
|
||||||
inline bool validate_flags(int flags)
|
|
||||||
{
|
|
||||||
return (flags & ~skip_ini_validity_check) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Ini parser error
|
|
||||||
class ini_parser_error: public file_parser_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ini_parser_error(const std::string &message,
|
|
||||||
const std::string &filename,
|
|
||||||
unsigned long line):
|
|
||||||
file_parser_error(message, filename, line)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Read ini from stream
|
|
||||||
template<class Ptree>
|
|
||||||
void read_ini(std::basic_istream<typename Ptree::char_type> &stream,
|
|
||||||
Ptree &pt)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
|
|
||||||
Ptree local;
|
|
||||||
unsigned long line_no = 0;
|
|
||||||
Ptree *section = 0;
|
|
||||||
Str line;
|
|
||||||
|
|
||||||
// For all lines
|
|
||||||
while (stream.good())
|
|
||||||
{
|
|
||||||
|
|
||||||
// Get line from stream
|
|
||||||
++line_no;
|
|
||||||
std::getline(stream, line);
|
|
||||||
if (!stream.good() && !stream.eof())
|
|
||||||
throw ini_parser_error("read error", "", line_no);
|
|
||||||
|
|
||||||
// If line is non-empty
|
|
||||||
line = detail::trim(line, stream.getloc());
|
|
||||||
if (!line.empty())
|
|
||||||
{
|
|
||||||
|
|
||||||
// Comment, section or key?
|
|
||||||
if (line[0] == Ch(';'))
|
|
||||||
{
|
|
||||||
// Ignore comments
|
|
||||||
}
|
|
||||||
else if (line[0] == Ch('['))
|
|
||||||
{
|
|
||||||
typename Str::size_type end = line.find(Ch(']'));
|
|
||||||
if (end == Str::npos)
|
|
||||||
throw ini_parser_error("unmatched '['", "", line_no);
|
|
||||||
Str key = detail::trim(line.substr(1, end - 1), stream.getloc());
|
|
||||||
if (local.find(key) != local.end())
|
|
||||||
throw ini_parser_error("duplicate section name", "", line_no);
|
|
||||||
section = &local.push_back(std::make_pair(key, Ptree()))->second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!section)
|
|
||||||
throw ini_parser_error("section expected", "", line_no);
|
|
||||||
typename Str::size_type eqpos = line.find(Ch('='));
|
|
||||||
if (eqpos == Str::npos)
|
|
||||||
throw ini_parser_error("'=' character not found in line", "", line_no);
|
|
||||||
if (eqpos == 0)
|
|
||||||
throw ini_parser_error("key expected", "", line_no);
|
|
||||||
Str key = detail::trim(line.substr(0, eqpos), stream.getloc());
|
|
||||||
Str data = detail::trim(line.substr(eqpos + 1, Str::npos), stream.getloc());
|
|
||||||
if (section->find(key) != section->end())
|
|
||||||
throw ini_parser_error("duplicate key name", "", line_no);
|
|
||||||
section->push_back(std::make_pair(key, Ptree(data)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap local ptree with result ptree
|
|
||||||
pt.swap(local);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Read ini from file
|
|
||||||
template<class Ptree>
|
|
||||||
void read_ini(const std::string &filename,
|
|
||||||
Ptree &pt,
|
|
||||||
const std::locale &loc = std::locale())
|
|
||||||
{
|
|
||||||
std::basic_ifstream<typename Ptree::char_type> stream(filename.c_str());
|
|
||||||
if (!stream)
|
|
||||||
throw ini_parser_error("cannot open file", filename, 0);
|
|
||||||
stream.imbue(loc);
|
|
||||||
try {
|
|
||||||
read_ini(stream, pt);
|
|
||||||
}
|
|
||||||
catch (ini_parser_error &e) {
|
|
||||||
throw ini_parser_error(e.message(), filename, e.line());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Write ini to stream
|
|
||||||
template<class Ptree>
|
|
||||||
void write_ini(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const Ptree &pt,
|
|
||||||
int flags = 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
|
|
||||||
BOOST_ASSERT(validate_flags(flags));
|
|
||||||
|
|
||||||
// Verify if ptree is not too rich to be saved as ini
|
|
||||||
if (!(flags & skip_ini_validity_check))
|
|
||||||
for (typename Ptree::const_iterator it = pt.begin(), end = pt.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
if (!it->second.data().empty())
|
|
||||||
throw ini_parser_error("ptree has data on root level keys", "", 0);
|
|
||||||
if (pt.count(it->first) > 1)
|
|
||||||
throw ini_parser_error("duplicate section name", "", 0);
|
|
||||||
for (typename Ptree::const_iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; ++it2)
|
|
||||||
{
|
|
||||||
if (!it2->second.empty())
|
|
||||||
throw ini_parser_error("ptree is too deep", "", 0);
|
|
||||||
if (it->second.count(it2->first) > 1)
|
|
||||||
throw ini_parser_error("duplicate key name", "", 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write ini
|
|
||||||
for (typename Ptree::const_iterator it = pt.begin(), end = pt.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
stream << Ch('[') << it->first << Ch(']') << Ch('\n');
|
|
||||||
for (typename Ptree::const_iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; ++it2)
|
|
||||||
stream << it2->first << Ch('=') << it2->second.template get_own<std::basic_string<Ch> >() << Ch('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write ini to file
|
|
||||||
template<class Ptree>
|
|
||||||
void write_ini(const std::string &filename,
|
|
||||||
const Ptree &pt,
|
|
||||||
int flags = 0,
|
|
||||||
const std::locale &loc = std::locale())
|
|
||||||
{
|
|
||||||
std::basic_ofstream<typename Ptree::char_type> stream(filename.c_str());
|
|
||||||
if (!stream)
|
|
||||||
throw ini_parser_error("cannot open file", filename, 0);
|
|
||||||
stream.imbue(loc);
|
|
||||||
try {
|
|
||||||
write_ini(stream, pt, flags);
|
|
||||||
}
|
|
||||||
catch (ini_parser_error &e) {
|
|
||||||
throw ini_parser_error(e.message(), filename, e.line());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree
|
|
||||||
{
|
|
||||||
using ini_parser::ini_parser_error;
|
|
||||||
using ini_parser::read_ini;
|
|
||||||
using ini_parser::write_ini;
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,76 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_JSON_PARSER_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_JSON_PARSER_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/json_parser_read.hpp>
|
|
||||||
#include <boost/property_tree/detail/json_parser_write.hpp>
|
|
||||||
#include <boost/property_tree/detail/json_parser_error.hpp>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace json_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
// Read json from stream
|
|
||||||
template<class Ptree>
|
|
||||||
void read_json(std::basic_istream<typename Ptree::char_type> &stream,
|
|
||||||
Ptree &pt)
|
|
||||||
{
|
|
||||||
read_json_internal(stream, pt, std::string());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read json from file
|
|
||||||
template<class Ptree>
|
|
||||||
void read_json(const std::string &filename,
|
|
||||||
Ptree &pt,
|
|
||||||
const std::locale &loc = std::locale())
|
|
||||||
{
|
|
||||||
std::basic_ifstream<typename Ptree::char_type> stream(filename.c_str());
|
|
||||||
if (!stream)
|
|
||||||
throw json_parser_error("cannot open file", filename, 0);
|
|
||||||
stream.imbue(loc);
|
|
||||||
read_json_internal(stream, pt, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write json to stream
|
|
||||||
template<class Ptree>
|
|
||||||
void write_json(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const Ptree &pt)
|
|
||||||
{
|
|
||||||
write_json_internal(stream, pt, std::string());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write json to file
|
|
||||||
template<class Ptree>
|
|
||||||
void write_json(const std::string &filename,
|
|
||||||
const Ptree &pt,
|
|
||||||
const std::locale &loc = std::locale())
|
|
||||||
{
|
|
||||||
std::basic_ofstream<typename Ptree::char_type> stream(filename.c_str());
|
|
||||||
if (!stream)
|
|
||||||
throw json_parser_error("cannot open file", filename, 0);
|
|
||||||
stream.imbue(loc);
|
|
||||||
write_json_internal(stream, pt, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree
|
|
||||||
{
|
|
||||||
using json_parser::read_json;
|
|
||||||
using json_parser::write_json;
|
|
||||||
using json_parser::json_parser_error;
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,16 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/detail/ptree_interface.hpp>
|
|
||||||
#include <boost/property_tree/detail/ptree_implementation.hpp>
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,54 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree
|
|
||||||
{
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Traits
|
|
||||||
|
|
||||||
template<class Ch> struct ptree_traits;
|
|
||||||
template<class Ch> struct iptree_traits;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Exceptions
|
|
||||||
|
|
||||||
class ptree_error;
|
|
||||||
class bad_ptree_data;
|
|
||||||
class bad_ptree_path;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// basic_ptree class template
|
|
||||||
|
|
||||||
template<class Tr> class basic_ptree;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Typedefs
|
|
||||||
|
|
||||||
typedef basic_ptree<ptree_traits<char> > ptree; // case sensitive, narrow char
|
|
||||||
typedef basic_ptree<iptree_traits<char> > iptree; // case insensitive, narrow char
|
|
||||||
#ifndef BOOST_NO_CWCHAR
|
|
||||||
typedef basic_ptree<ptree_traits<wchar_t> > wptree; // case sensitive, wide char
|
|
||||||
typedef basic_ptree<iptree_traits<wchar_t> > wiptree; // case insensitive, wide char
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Free functions
|
|
||||||
|
|
||||||
template<class Tr> void swap(basic_ptree<Tr> &pt1, basic_ptree<Tr> &pt2);
|
|
||||||
template<class Ptree> const Ptree &empty_ptree();
|
|
||||||
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,520 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_REGISTRY_PARSER_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_REGISTRY_PARSER_HPP_INCLUDED
|
|
||||||
|
|
||||||
// Include minimal version of windows.h if not included yet
|
|
||||||
#ifndef _WINDOWS_
|
|
||||||
#ifndef NOMINMAX
|
|
||||||
#define NOMINMAX
|
|
||||||
#endif
|
|
||||||
#define STRICT
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#define VC_EXTRALEAN
|
|
||||||
#define NOGDICAPMASKS
|
|
||||||
#define NOVIRTUALKEYCODES
|
|
||||||
#define NOWINMESSAGES
|
|
||||||
#define NOWINSTYLES
|
|
||||||
#define NOSYSMETRICS
|
|
||||||
#define NOMENUS
|
|
||||||
#define NOICONS
|
|
||||||
#define NOKEYSTATES
|
|
||||||
#define NOSYSCOMMANDS
|
|
||||||
#define NORASTEROPS
|
|
||||||
#define NOSHOWWINDOW
|
|
||||||
#define OEMRESOURCE
|
|
||||||
#define NOATOM
|
|
||||||
#define NOCLIPBOARD
|
|
||||||
#define NOCOLOR
|
|
||||||
#define NOCTLMGR
|
|
||||||
#define NODRAWTEXT
|
|
||||||
#define NOGDI
|
|
||||||
#define NOKERNEL
|
|
||||||
#define NOUSER
|
|
||||||
#define NONLS
|
|
||||||
#define NOMB
|
|
||||||
#define NOMEMMGR
|
|
||||||
#define NOMETAFILE
|
|
||||||
#define NOMSG
|
|
||||||
#define NOOPENFILE
|
|
||||||
#define NOSCROLL
|
|
||||||
#define NOSERVICE
|
|
||||||
#define NOSOUND
|
|
||||||
#define NOTEXTMETRIC
|
|
||||||
#define NOWH
|
|
||||||
#define NOWINOFFSETS
|
|
||||||
#define NOCOMM
|
|
||||||
#define NOKANJI
|
|
||||||
#define NOHELP
|
|
||||||
#define NOPROFILER
|
|
||||||
#define NODEFERWINDOWPOS
|
|
||||||
#define NOMCX
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/ptree_utils.hpp>
|
|
||||||
#include <boost/cstdint.hpp> // for 64 bit int
|
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace registry_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
//! Registry parser error
|
|
||||||
class registry_parser_error: public ptree_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Construct error
|
|
||||||
registry_parser_error(const std::string &message, DWORD windows_error):
|
|
||||||
ptree_error(format_what(message, windows_error)),
|
|
||||||
m_windows_error(windows_error)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get windows error
|
|
||||||
DWORD windows_error()
|
|
||||||
{
|
|
||||||
return m_windows_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
DWORD m_windows_error;
|
|
||||||
|
|
||||||
// Format error message to be returned by std::runtime_error::what()
|
|
||||||
std::string format_what(const std::string &message,
|
|
||||||
DWORD windows_error)
|
|
||||||
{
|
|
||||||
std::stringstream stream;
|
|
||||||
if (windows_error)
|
|
||||||
stream << message << " (windows error 0x" << std::hex << windows_error << ")";
|
|
||||||
else
|
|
||||||
stream << message;
|
|
||||||
return stream.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Translate from binary buffer to string
|
|
||||||
template<class Ch>
|
|
||||||
std::basic_string<Ch> translate(DWORD type, const std::vector<BYTE> &data)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
typedef std::basic_stringstream<Ch> Stream;
|
|
||||||
|
|
||||||
Str value;
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
|
|
||||||
// No data
|
|
||||||
case REG_NONE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Binary data
|
|
||||||
case REG_BINARY:
|
|
||||||
if (!data.empty())
|
|
||||||
{
|
|
||||||
Stream stream;
|
|
||||||
stream << std::hex << std::setfill(Ch('0'));
|
|
||||||
for (std::vector<BYTE>::const_iterator it = data.begin(), end = data.end();
|
|
||||||
it != end; ++it)
|
|
||||||
stream << std::setw(2) << static_cast<int>(*it) << Ch(' ');
|
|
||||||
value = stream.str();
|
|
||||||
value.resize(value.size() - 1); // remove final space
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DWORD value
|
|
||||||
case REG_DWORD:
|
|
||||||
if (!data.empty())
|
|
||||||
{
|
|
||||||
Stream stream;
|
|
||||||
stream << *reinterpret_cast<const DWORD *>(&data.front());
|
|
||||||
value = stream.str();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// QWORD value
|
|
||||||
case REG_QWORD:
|
|
||||||
if (!data.empty())
|
|
||||||
{
|
|
||||||
Stream stream;
|
|
||||||
stream << *reinterpret_cast<const boost::uint64_t *>(&data.front());
|
|
||||||
value = stream.str();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Zero terminated string
|
|
||||||
case REG_SZ: case REG_EXPAND_SZ:
|
|
||||||
if (!data.empty())
|
|
||||||
value.assign(reinterpret_cast<const Ch *>(&data.front()));
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Unknown data type
|
|
||||||
default:
|
|
||||||
throw registry_parser_error("unsupported data type", 0);
|
|
||||||
|
|
||||||
};
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate from string to binary buffer
|
|
||||||
template<class Ch>
|
|
||||||
std::vector<BYTE> translate(DWORD type, const std::basic_string<Ch> &s)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
typedef std::basic_stringstream<Ch> Stream;
|
|
||||||
|
|
||||||
std::vector<BYTE> data;
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
|
|
||||||
// No data
|
|
||||||
case REG_NONE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Binary data
|
|
||||||
case REG_BINARY:
|
|
||||||
{
|
|
||||||
int v;
|
|
||||||
Stream stream(s);
|
|
||||||
stream >> std::hex;
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
stream >> v >> std::ws;
|
|
||||||
if (stream.fail() || stream.bad())
|
|
||||||
throw registry_parser_error("bad REG_BINARY value", 0);
|
|
||||||
data.push_back(v);
|
|
||||||
if (stream.eof())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DWORD value
|
|
||||||
case REG_DWORD:
|
|
||||||
{
|
|
||||||
DWORD v;
|
|
||||||
Stream stream(s);
|
|
||||||
stream >> v >> std::ws;
|
|
||||||
if (!stream.eof() || stream.fail() || stream.bad())
|
|
||||||
throw registry_parser_error("bad REG_DWORD value", 0);
|
|
||||||
for (size_t i = 0; i < sizeof(v); ++i)
|
|
||||||
data.push_back(*(reinterpret_cast<BYTE *>(&v) + i));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// QWORD value
|
|
||||||
case REG_QWORD:
|
|
||||||
{
|
|
||||||
boost::uint64_t v;
|
|
||||||
Stream stream(s);
|
|
||||||
stream >> v;
|
|
||||||
if (!stream.eof() || stream.fail() || stream.bad())
|
|
||||||
throw registry_parser_error("bad REG_QWORD value", 0);
|
|
||||||
for (size_t i = 0; i < sizeof(v); ++i)
|
|
||||||
data.push_back(*(reinterpret_cast<BYTE *>(&v) + i));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Zero terminated string
|
|
||||||
case REG_SZ: case REG_EXPAND_SZ:
|
|
||||||
{
|
|
||||||
const Ch *sz = s.c_str();
|
|
||||||
size_t len = (s.size() + 1) * sizeof(Ch);
|
|
||||||
for (size_t i = 0; i < len; ++i)
|
|
||||||
data.push_back(*(reinterpret_cast<const BYTE *>(sz) + i));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Unknown data type
|
|
||||||
default:
|
|
||||||
throw registry_parser_error("unsupported data type", 0);
|
|
||||||
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Registry functions wrappers
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
inline LONG reg_create_key_ex(HKEY hkey, const Ch *subkey, REGSAM sam, HKEY *result);
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_create_key_ex<char>(HKEY hkey, const char *subkey, REGSAM sam, HKEY *result)
|
|
||||||
{
|
|
||||||
return RegCreateKeyExA(hkey, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, sam, NULL, result, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_create_key_ex<wchar_t>(HKEY hkey, const wchar_t *subkey, REGSAM sam, HKEY *result)
|
|
||||||
{
|
|
||||||
return RegCreateKeyExW(hkey, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, sam, NULL, result, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
inline LONG reg_set_value_ex(HKEY hkey, const Ch *name, DWORD type, const BYTE *data, DWORD size);
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_set_value_ex<char>(HKEY hkey, const char *name, DWORD type, const BYTE *data, DWORD size)
|
|
||||||
{
|
|
||||||
return RegSetValueExA(hkey, name, 0, type, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_set_value_ex<wchar_t>(HKEY hkey, const wchar_t *name, DWORD type, const BYTE *data, DWORD size)
|
|
||||||
{
|
|
||||||
return RegSetValueExW(hkey, name, 0, type, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
inline LONG reg_open_key_ex(HKEY hkey, const Ch *subkey, REGSAM sam, HKEY *result);
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_open_key_ex<char>(HKEY hkey, const char *subkey, REGSAM sam, HKEY *result)
|
|
||||||
{
|
|
||||||
return RegOpenKeyExA(hkey, subkey, 0, sam, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_open_key_ex<wchar_t>(HKEY hkey, const wchar_t *subkey, REGSAM sam, HKEY *result)
|
|
||||||
{
|
|
||||||
return RegOpenKeyExW(hkey, subkey, 0, sam, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
inline LONG reg_enum_key_ex(HKEY hkey, DWORD index, Ch *name, DWORD *size);
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_enum_key_ex<char>(HKEY hkey, DWORD index, char *name, DWORD *size)
|
|
||||||
{
|
|
||||||
FILETIME ft;
|
|
||||||
return RegEnumKeyExA(hkey, index, name, size, 0, NULL, NULL, &ft);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_enum_key_ex<wchar_t>(HKEY hkey, DWORD index, wchar_t *name, DWORD *size)
|
|
||||||
{
|
|
||||||
FILETIME ft;
|
|
||||||
return RegEnumKeyExW(hkey, index, name, size, 0, NULL, NULL, &ft);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
inline LONG reg_enum_value(HKEY hkey, DWORD index, Ch *name, DWORD *name_size, DWORD *type, BYTE *data, DWORD *data_size);
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_enum_value<char>(HKEY hkey, DWORD index, char *name, DWORD *name_size, DWORD *type, BYTE *data, DWORD *data_size)
|
|
||||||
{
|
|
||||||
return RegEnumValueA(hkey, index, name, name_size, NULL, type, data, data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_enum_value<wchar_t>(HKEY hkey, DWORD index, wchar_t *name, DWORD *name_size, DWORD *type, BYTE *data, DWORD *data_size)
|
|
||||||
{
|
|
||||||
return RegEnumValueW(hkey, index, name, name_size, NULL, type, data, data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
inline LONG reg_query_info_key(HKEY hkey, DWORD *max_subkey_len, DWORD *max_name_len, DWORD *max_value_len);
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_query_info_key<char>(HKEY hkey, DWORD *max_subkey_len, DWORD *max_name_len, DWORD *max_value_len)
|
|
||||||
{
|
|
||||||
return RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, max_subkey_len, NULL, NULL, max_name_len, max_value_len, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline LONG reg_query_info_key<wchar_t>(HKEY hkey, DWORD *max_subkey_len, DWORD *max_name_len, DWORD *max_value_len)
|
|
||||||
{
|
|
||||||
return RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, max_subkey_len, NULL, NULL, max_name_len, max_value_len, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Registry key handle wrapper
|
|
||||||
|
|
||||||
template<class Ch>
|
|
||||||
class reg_key
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
reg_key(HKEY root, const std::basic_string<Ch> &key, bool create):
|
|
||||||
hkey(0)
|
|
||||||
{
|
|
||||||
if (create)
|
|
||||||
{
|
|
||||||
LONG result = reg_create_key_ex(root, key.c_str(), KEY_WRITE, &hkey);
|
|
||||||
if (result != ERROR_SUCCESS)
|
|
||||||
throw registry_parser_error("RegCreateKeyEx failed", result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LONG result = reg_open_key_ex(root, key.c_str(), KEY_READ, &hkey);
|
|
||||||
if (result != ERROR_SUCCESS)
|
|
||||||
throw registry_parser_error("RegOpenKeyEx failed", result);
|
|
||||||
}
|
|
||||||
BOOST_ASSERT(hkey);
|
|
||||||
}
|
|
||||||
~reg_key()
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(hkey);
|
|
||||||
RegCloseKey(hkey);
|
|
||||||
}
|
|
||||||
HKEY handle()
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(hkey);
|
|
||||||
return hkey;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
HKEY hkey;
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Registry parser
|
|
||||||
|
|
||||||
//! Read registry
|
|
||||||
template<class Ptree>
|
|
||||||
void read_registry(HKEY root,
|
|
||||||
const std::basic_string<typename Ptree::char_type> &key,
|
|
||||||
Ptree &pt)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
typedef std::basic_stringstream<Ch> Stream;
|
|
||||||
|
|
||||||
Ptree local;
|
|
||||||
|
|
||||||
// Open key
|
|
||||||
reg_key<Ch> rk(root, key, false);
|
|
||||||
|
|
||||||
// Query key info
|
|
||||||
DWORD max_subkey_len, max_name_len, max_value_len;
|
|
||||||
LONG result = reg_query_info_key<Ch>(rk.handle(), &max_subkey_len, &max_name_len, &max_value_len);
|
|
||||||
if (result != ERROR_SUCCESS)
|
|
||||||
throw registry_parser_error("RegQueryInfoKey failed", result);
|
|
||||||
|
|
||||||
// For all subkeys
|
|
||||||
std::vector<Ch> subkey(max_subkey_len + 1);
|
|
||||||
for (DWORD index = 0; true; ++index)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Get subkey name
|
|
||||||
DWORD size = static_cast<DWORD>(subkey.size());
|
|
||||||
LONG result = reg_enum_key_ex(rk.handle(), index, &subkey.front(), &size);
|
|
||||||
if (result == ERROR_NO_MORE_ITEMS)
|
|
||||||
break;
|
|
||||||
if (result != ERROR_SUCCESS)
|
|
||||||
throw registry_parser_error("RegEnumKeyEx failed", result);
|
|
||||||
|
|
||||||
// Parse recursively
|
|
||||||
Ptree &child = local.push_back(typename Ptree::value_type(&subkey.front(), Ptree()))->second;
|
|
||||||
read_registry<Ptree>(rk.handle(), &subkey.front(), child);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// For all values
|
|
||||||
for (DWORD index = 0; true; ++index)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Resize data to max size
|
|
||||||
std::vector<Ch> name(max_name_len + 1);
|
|
||||||
std::vector<BYTE> data(max_value_len + 1);
|
|
||||||
|
|
||||||
// Get name and value from registry
|
|
||||||
DWORD name_size = static_cast<DWORD>(name.size());
|
|
||||||
DWORD data_size = static_cast<DWORD>(data.size());
|
|
||||||
DWORD type;
|
|
||||||
result = reg_enum_value<Ch>(rk.handle(), index, &name.front(), &name_size, &type, &data.front(), &data_size);
|
|
||||||
if (result == ERROR_NO_MORE_ITEMS)
|
|
||||||
break;
|
|
||||||
if (result != ERROR_SUCCESS)
|
|
||||||
throw registry_parser_error("RegEnumValue failed", result);
|
|
||||||
|
|
||||||
// Truncate data to actual size
|
|
||||||
name.resize(name_size + 1);
|
|
||||||
data.resize(data_size);
|
|
||||||
|
|
||||||
// Translate and put value in tree
|
|
||||||
Str value = translate<Ch>(type, data);
|
|
||||||
if (name_size > 0)
|
|
||||||
{
|
|
||||||
local.put(Str(detail::widen<Ch>("\\values.") + &name.front()), value);
|
|
||||||
local.put(Str(detail::widen<Ch>("\\types.") + &name.front()), type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
local.data() = value;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap pt and local
|
|
||||||
pt.swap(local);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Write registry
|
|
||||||
template<class Ptree>
|
|
||||||
void write_registry(HKEY root,
|
|
||||||
const std::basic_string<typename Ptree::char_type> &key,
|
|
||||||
const Ptree &pt)
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef typename Ptree::char_type Ch;
|
|
||||||
typedef std::basic_string<Ch> Str;
|
|
||||||
typedef std::basic_stringstream<Ch> Stream;
|
|
||||||
|
|
||||||
// Create key
|
|
||||||
reg_key<Ch> rk(root, key, true);
|
|
||||||
|
|
||||||
// Set default key value
|
|
||||||
if (!pt.data().empty())
|
|
||||||
{
|
|
||||||
std::vector<BYTE> data = translate<Ch>(REG_SZ, pt.data());
|
|
||||||
reg_set_value_ex<Ch>(rk.handle(), NULL, REG_SZ,
|
|
||||||
data.empty() ? NULL : &data.front(),
|
|
||||||
static_cast<DWORD>(data.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create values
|
|
||||||
const Ptree &values = pt.get_child(detail::widen<Ch>("\\values"), empty_ptree<Ptree>());
|
|
||||||
const Ptree &types = pt.get_child(detail::widen<Ch>("\\types"), empty_ptree<Ptree>());
|
|
||||||
for (typename Ptree::const_iterator it = values.begin(), end = values.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
DWORD type = types.get(it->first, REG_SZ);
|
|
||||||
std::vector<BYTE> data = translate<Ch>(type, it->second.data());
|
|
||||||
reg_set_value_ex<Ch>(rk.handle(), it->first.c_str(), type,
|
|
||||||
data.empty() ? NULL : &data.front(),
|
|
||||||
static_cast<DWORD>(data.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create subkeys
|
|
||||||
for (typename Ptree::const_iterator it = pt.begin(), end = pt.end(); it != end; ++it)
|
|
||||||
if (&it->second != &values && &it->second != &types)
|
|
||||||
write_registry(rk.handle(), it->first, it->second);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree
|
|
||||||
{
|
|
||||||
using registry_parser::read_registry;
|
|
||||||
using registry_parser::write_registry;
|
|
||||||
using registry_parser::registry_parser_error;
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,86 +0,0 @@
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2002-2005 Marcin Kalicinski
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// For more information, see www.boost.org
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifndef BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
|
|
||||||
#define BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_write.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_error.hpp>
|
|
||||||
#include <boost/property_tree/detail/xml_parser_flags.hpp>
|
|
||||||
|
|
||||||
// Include proper parser
|
|
||||||
#ifdef BOOST_PROPERTY_TREE_XML_PARSER_TINYXML
|
|
||||||
#include <boost/property_tree/detail/xml_parser_read_tinyxml.hpp>
|
|
||||||
#else
|
|
||||||
#include <boost/property_tree/detail/xml_parser_read_spirit.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree { namespace xml_parser
|
|
||||||
{
|
|
||||||
|
|
||||||
// Read XML from stream
|
|
||||||
template<class Ptree>
|
|
||||||
void read_xml(std::basic_istream<typename Ptree::char_type> &stream,
|
|
||||||
Ptree &pt,
|
|
||||||
int flags = 0)
|
|
||||||
{
|
|
||||||
read_xml_internal(stream, pt, flags, std::string());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read XML from file
|
|
||||||
template<class Ptree>
|
|
||||||
void read_xml(const std::string &filename,
|
|
||||||
Ptree &pt,
|
|
||||||
int flags = 0,
|
|
||||||
const std::locale &loc = std::locale())
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(validate_flags(flags));
|
|
||||||
std::basic_ifstream<typename Ptree::char_type> stream(filename.c_str());
|
|
||||||
if (!stream)
|
|
||||||
throw xml_parser_error("cannot open file", filename, 0);
|
|
||||||
stream.imbue(loc);
|
|
||||||
read_xml_internal(stream, pt, flags, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write XML to stream
|
|
||||||
template<class Ptree>
|
|
||||||
void write_xml(std::basic_ostream<typename Ptree::char_type> &stream,
|
|
||||||
const Ptree &pt)
|
|
||||||
{
|
|
||||||
write_xml_internal(stream, pt, std::string());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write XML to file
|
|
||||||
template<class Ptree>
|
|
||||||
void write_xml(const std::string &filename,
|
|
||||||
const Ptree &pt,
|
|
||||||
const std::locale &loc = std::locale())
|
|
||||||
{
|
|
||||||
std::basic_ofstream<typename Ptree::char_type> stream(filename.c_str());
|
|
||||||
if (!stream)
|
|
||||||
throw xml_parser_error("cannot open file", filename, 0);
|
|
||||||
stream.imbue(loc);
|
|
||||||
write_xml_internal(stream, pt, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
} } }
|
|
||||||
|
|
||||||
namespace boost { namespace property_tree
|
|
||||||
{
|
|
||||||
using xml_parser::read_xml;
|
|
||||||
using xml_parser::write_xml;
|
|
||||||
using xml_parser::xml_parser_error;
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -66,12 +66,12 @@ int main ( int argc , char** argv)
|
||||||
feature_type_style provpoly_style;
|
feature_type_style provpoly_style;
|
||||||
|
|
||||||
rule_type provpoly_rule_on;
|
rule_type provpoly_rule_on;
|
||||||
provpoly_rule_on.set_filter(create_filter("[NAME_EN] = 'Ontario'"));
|
provpoly_rule_on.set_filter(parse_expression("[NAME_EN] = 'Ontario'"));
|
||||||
provpoly_rule_on.append(polygon_symbolizer(color(250, 190, 183)));
|
provpoly_rule_on.append(polygon_symbolizer(color(250, 190, 183)));
|
||||||
provpoly_style.add_rule(provpoly_rule_on);
|
provpoly_style.add_rule(provpoly_rule_on);
|
||||||
|
|
||||||
rule_type provpoly_rule_qc;
|
rule_type provpoly_rule_qc;
|
||||||
provpoly_rule_qc.set_filter(create_filter("[NOM_FR] = 'Québec'"));
|
provpoly_rule_qc.set_filter(parse_expression("[NOM_FR] = 'Québec'"));
|
||||||
provpoly_rule_qc.append(polygon_symbolizer(color(217, 235, 203)));
|
provpoly_rule_qc.append(polygon_symbolizer(color(217, 235, 203)));
|
||||||
provpoly_style.add_rule(provpoly_rule_qc);
|
provpoly_style.add_rule(provpoly_rule_qc);
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ int main ( int argc , char** argv)
|
||||||
feature_type_style qcdrain_style;
|
feature_type_style qcdrain_style;
|
||||||
|
|
||||||
rule_type qcdrain_rule;
|
rule_type qcdrain_rule;
|
||||||
qcdrain_rule.set_filter(create_filter("[HYC] = 8"));
|
qcdrain_rule.set_filter(parse_expression("[HYC] = 8"));
|
||||||
qcdrain_rule.append(polygon_symbolizer(color(153, 204, 255)));
|
qcdrain_rule.append(polygon_symbolizer(color(153, 204, 255)));
|
||||||
qcdrain_style.add_rule(qcdrain_rule);
|
qcdrain_style.add_rule(qcdrain_rule);
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ int main ( int argc , char** argv)
|
||||||
// Roads 3 and 4 (The "grey" roads)
|
// Roads 3 and 4 (The "grey" roads)
|
||||||
feature_type_style roads34_style;
|
feature_type_style roads34_style;
|
||||||
rule_type roads34_rule;
|
rule_type roads34_rule;
|
||||||
roads34_rule.set_filter(create_filter("[CLASS] = 3 or [CLASS] = 4"));
|
roads34_rule.set_filter(parse_expression("[CLASS] = 3 or [CLASS] = 4"));
|
||||||
stroke roads34_rule_stk(color(171,158,137),2.0);
|
stroke roads34_rule_stk(color(171,158,137),2.0);
|
||||||
roads34_rule_stk.set_line_cap(ROUND_CAP);
|
roads34_rule_stk.set_line_cap(ROUND_CAP);
|
||||||
roads34_rule_stk.set_line_join(ROUND_JOIN);
|
roads34_rule_stk.set_line_join(ROUND_JOIN);
|
||||||
|
@ -117,7 +117,7 @@ int main ( int argc , char** argv)
|
||||||
// Roads 2 (The thin yellow ones)
|
// Roads 2 (The thin yellow ones)
|
||||||
feature_type_style roads2_style_1;
|
feature_type_style roads2_style_1;
|
||||||
rule_type roads2_rule_1;
|
rule_type roads2_rule_1;
|
||||||
roads2_rule_1.set_filter(create_filter("[CLASS] = 2"));
|
roads2_rule_1.set_filter(parse_expression("[CLASS] = 2"));
|
||||||
stroke roads2_rule_stk_1(color(171,158,137),4.0);
|
stroke roads2_rule_stk_1(color(171,158,137),4.0);
|
||||||
roads2_rule_stk_1.set_line_cap(ROUND_CAP);
|
roads2_rule_stk_1.set_line_cap(ROUND_CAP);
|
||||||
roads2_rule_stk_1.set_line_join(ROUND_JOIN);
|
roads2_rule_stk_1.set_line_join(ROUND_JOIN);
|
||||||
|
@ -128,7 +128,7 @@ int main ( int argc , char** argv)
|
||||||
|
|
||||||
feature_type_style roads2_style_2;
|
feature_type_style roads2_style_2;
|
||||||
rule_type roads2_rule_2;
|
rule_type roads2_rule_2;
|
||||||
roads2_rule_2.set_filter(create_filter("[CLASS] = 2"));
|
roads2_rule_2.set_filter(parse_expression("[CLASS] = 2"));
|
||||||
stroke roads2_rule_stk_2(color(255,250,115),2.0);
|
stroke roads2_rule_stk_2(color(255,250,115),2.0);
|
||||||
roads2_rule_stk_2.set_line_cap(ROUND_CAP);
|
roads2_rule_stk_2.set_line_cap(ROUND_CAP);
|
||||||
roads2_rule_stk_2.set_line_join(ROUND_JOIN);
|
roads2_rule_stk_2.set_line_join(ROUND_JOIN);
|
||||||
|
@ -140,7 +140,7 @@ int main ( int argc , char** argv)
|
||||||
// Roads 1 (The big orange ones, the highways)
|
// Roads 1 (The big orange ones, the highways)
|
||||||
feature_type_style roads1_style_1;
|
feature_type_style roads1_style_1;
|
||||||
rule_type roads1_rule_1;
|
rule_type roads1_rule_1;
|
||||||
roads1_rule_1.set_filter(create_filter("[CLASS] = 1"));
|
roads1_rule_1.set_filter(parse_expression("[CLASS] = 1"));
|
||||||
stroke roads1_rule_stk_1(color(188,149,28),7.0);
|
stroke roads1_rule_stk_1(color(188,149,28),7.0);
|
||||||
roads1_rule_stk_1.set_line_cap(ROUND_CAP);
|
roads1_rule_stk_1.set_line_cap(ROUND_CAP);
|
||||||
roads1_rule_stk_1.set_line_join(ROUND_JOIN);
|
roads1_rule_stk_1.set_line_join(ROUND_JOIN);
|
||||||
|
@ -150,7 +150,7 @@ int main ( int argc , char** argv)
|
||||||
|
|
||||||
feature_type_style roads1_style_2;
|
feature_type_style roads1_style_2;
|
||||||
rule_type roads1_rule_2;
|
rule_type roads1_rule_2;
|
||||||
roads1_rule_2.set_filter(create_filter("[CLASS] = 1"));
|
roads1_rule_2.set_filter(parse_expression("[CLASS] = 1"));
|
||||||
stroke roads1_rule_stk_2(color(242,191,36),5.0);
|
stroke roads1_rule_stk_2(color(242,191,36),5.0);
|
||||||
roads1_rule_stk_2.set_line_cap(ROUND_CAP);
|
roads1_rule_stk_2.set_line_cap(ROUND_CAP);
|
||||||
roads1_rule_stk_2.set_line_join(ROUND_JOIN);
|
roads1_rule_stk_2.set_line_join(ROUND_JOIN);
|
||||||
|
@ -170,14 +170,14 @@ int main ( int argc , char** argv)
|
||||||
|
|
||||||
m.insert_style("popplaces",popplaces_style );
|
m.insert_style("popplaces",popplaces_style );
|
||||||
|
|
||||||
// Layers
|
// layers
|
||||||
// Provincial polygons
|
// Provincial polygons
|
||||||
{
|
{
|
||||||
parameters p;
|
parameters p;
|
||||||
p["type"]="shape";
|
p["type"]="shape";
|
||||||
p["file"]="../data/boundaries";
|
p["file"]="../data/boundaries";
|
||||||
|
|
||||||
Layer lyr("Provinces");
|
layer lyr("Provinces");
|
||||||
lyr.set_datasource(datasource_cache::instance()->create(p));
|
lyr.set_datasource(datasource_cache::instance()->create(p));
|
||||||
lyr.add_style("provinces");
|
lyr.add_style("provinces");
|
||||||
m.addLayer(lyr);
|
m.addLayer(lyr);
|
||||||
|
@ -188,7 +188,7 @@ int main ( int argc , char** argv)
|
||||||
parameters p;
|
parameters p;
|
||||||
p["type"]="shape";
|
p["type"]="shape";
|
||||||
p["file"]="../data/qcdrainage";
|
p["file"]="../data/qcdrainage";
|
||||||
Layer lyr("Quebec Hydrography");
|
layer lyr("Quebec Hydrography");
|
||||||
lyr.set_datasource(datasource_cache::instance()->create(p));
|
lyr.set_datasource(datasource_cache::instance()->create(p));
|
||||||
lyr.add_style("drainage");
|
lyr.add_style("drainage");
|
||||||
m.addLayer(lyr);
|
m.addLayer(lyr);
|
||||||
|
@ -199,7 +199,7 @@ int main ( int argc , char** argv)
|
||||||
p["type"]="shape";
|
p["type"]="shape";
|
||||||
p["file"]="../data/ontdrainage";
|
p["file"]="../data/ontdrainage";
|
||||||
|
|
||||||
Layer lyr("Ontario Hydrography");
|
layer lyr("Ontario Hydrography");
|
||||||
lyr.set_datasource(datasource_cache::instance()->create(p));
|
lyr.set_datasource(datasource_cache::instance()->create(p));
|
||||||
lyr.add_style("drainage");
|
lyr.add_style("drainage");
|
||||||
m.addLayer(lyr);
|
m.addLayer(lyr);
|
||||||
|
@ -210,7 +210,7 @@ int main ( int argc , char** argv)
|
||||||
parameters p;
|
parameters p;
|
||||||
p["type"]="shape";
|
p["type"]="shape";
|
||||||
p["file"]="../data/boundaries_l";
|
p["file"]="../data/boundaries_l";
|
||||||
Layer lyr("Provincial borders");
|
layer lyr("Provincial borders");
|
||||||
lyr.set_datasource(datasource_cache::instance()->create(p));
|
lyr.set_datasource(datasource_cache::instance()->create(p));
|
||||||
lyr.add_style("provlines");
|
lyr.add_style("provlines");
|
||||||
m.addLayer(lyr);
|
m.addLayer(lyr);
|
||||||
|
@ -221,7 +221,7 @@ int main ( int argc , char** argv)
|
||||||
parameters p;
|
parameters p;
|
||||||
p["type"]="shape";
|
p["type"]="shape";
|
||||||
p["file"]="../data/roads";
|
p["file"]="../data/roads";
|
||||||
Layer lyr("Roads");
|
layer lyr("Roads");
|
||||||
lyr.set_datasource(datasource_cache::instance()->create(p));
|
lyr.set_datasource(datasource_cache::instance()->create(p));
|
||||||
lyr.add_style("smallroads");
|
lyr.add_style("smallroads");
|
||||||
lyr.add_style("road-border");
|
lyr.add_style("road-border");
|
||||||
|
@ -237,22 +237,22 @@ int main ( int argc , char** argv)
|
||||||
p["type"]="shape";
|
p["type"]="shape";
|
||||||
p["file"]="../data/popplaces";
|
p["file"]="../data/popplaces";
|
||||||
p["encoding"] = "latin1";
|
p["encoding"] = "latin1";
|
||||||
Layer lyr("Populated Places");
|
layer lyr("Populated Places");
|
||||||
lyr.set_datasource(datasource_cache::instance()->create(p));
|
lyr.set_datasource(datasource_cache::instance()->create(p));
|
||||||
lyr.add_style("popplaces");
|
lyr.add_style("popplaces");
|
||||||
m.addLayer(lyr);
|
m.addLayer(lyr);
|
||||||
}
|
}
|
||||||
|
|
||||||
m.zoomToBox(Envelope<double>(1405120.04127408,-247003.813399447,
|
m.zoomToBox(box2d<double>(1405120.04127408,-247003.813399447,
|
||||||
1706357.31328276,-25098.593149577));
|
1706357.31328276,-25098.593149577));
|
||||||
|
|
||||||
Image32 buf(m.getWidth(),m.getHeight());
|
image_32 buf(m.getWidth(),m.getHeight());
|
||||||
agg_renderer<Image32> ren(m,buf);
|
agg_renderer<image_32> ren(m,buf);
|
||||||
ren.apply();
|
ren.apply();
|
||||||
|
|
||||||
save_to_file<ImageData32>(buf.data(),"demo.jpg","jpeg");
|
save_to_file<image_data_32>(buf.data(),"demo.jpg","jpeg");
|
||||||
save_to_file<ImageData32>(buf.data(),"demo.png","png");
|
save_to_file<image_data_32>(buf.data(),"demo.png","png");
|
||||||
save_to_file<ImageData32>(buf.data(),"demo256.png","png256");
|
save_to_file<image_data_32>(buf.data(),"demo256.png","png256");
|
||||||
std::cout << "Three maps have been rendered using AGG in the current directory:\n"
|
std::cout << "Three maps have been rendered using AGG in the current directory:\n"
|
||||||
"- demo.jpg\n"
|
"- demo.jpg\n"
|
||||||
"- demo.png\n"
|
"- demo.png\n"
|
||||||
|
@ -267,7 +267,7 @@ int main ( int argc , char** argv)
|
||||||
png_render.apply();
|
png_render.apply();
|
||||||
image_surface->write_to_png("cairo-demo.png");
|
image_surface->write_to_png("cairo-demo.png");
|
||||||
|
|
||||||
Image32 im(image_surface);
|
image_32 im(image_surface);
|
||||||
save_to_file(im, "cairo-demo256.png","png256");
|
save_to_file(im, "cairo-demo256.png","png256");
|
||||||
|
|
||||||
Cairo::RefPtr<Cairo::Surface> surface;
|
Cairo::RefPtr<Cairo::Surface> surface;
|
||||||
|
|
|
@ -77,11 +77,11 @@ provpoly_style = mapnik.Style()
|
||||||
|
|
||||||
provpoly_rule_on = mapnik.Rule()
|
provpoly_rule_on = mapnik.Rule()
|
||||||
|
|
||||||
# A Filter() allows the selection of features to which the symbology will
|
# A Expression() allows the selection of features to which the symbology will
|
||||||
# be applied. More on Mapnik expressions can be found in Tutorial #2.
|
# be applied. More on Mapnik expressions can be found in Tutorial #2.
|
||||||
# A given feature can only match one filter per rule per style.
|
# A given feature can only match one filter per rule per style.
|
||||||
|
|
||||||
provpoly_rule_on.filter = mapnik.Filter("[NAME_EN] = 'Ontario'")
|
provpoly_rule_on.filter = mapnik.Expression("[NAME_EN] = 'Ontario'")
|
||||||
|
|
||||||
# Here a symbolizer is defined. Available are:
|
# Here a symbolizer is defined. Available are:
|
||||||
# - LineSymbolizer(Color(),<width>)
|
# - LineSymbolizer(Color(),<width>)
|
||||||
|
@ -99,7 +99,7 @@ provpoly_rule_on.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(250, 190,
|
||||||
provpoly_style.rules.append(provpoly_rule_on)
|
provpoly_style.rules.append(provpoly_rule_on)
|
||||||
|
|
||||||
provpoly_rule_qc = mapnik.Rule()
|
provpoly_rule_qc = mapnik.Rule()
|
||||||
provpoly_rule_qc.filter = mapnik.Filter("[NOM_FR] = 'Québec'")
|
provpoly_rule_qc.filter = mapnik.Expression("[NOM_FR] = 'Québec'")
|
||||||
provpoly_rule_qc.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(217, 235, 203)))
|
provpoly_rule_qc.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(217, 235, 203)))
|
||||||
provpoly_style.rules.append(provpoly_rule_qc)
|
provpoly_style.rules.append(provpoly_rule_qc)
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ qcdrain_lyr.datasource = mapnik.Shapefile(file='../data/qcdrainage')
|
||||||
|
|
||||||
qcdrain_style = mapnik.Style()
|
qcdrain_style = mapnik.Style()
|
||||||
qcdrain_rule = mapnik.Rule()
|
qcdrain_rule = mapnik.Rule()
|
||||||
qcdrain_rule.filter = mapnik.Filter('[HYC] = 8')
|
qcdrain_rule.filter = mapnik.Expression('[HYC] = 8')
|
||||||
qcdrain_rule.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(153, 204, 255)))
|
qcdrain_rule.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(153, 204, 255)))
|
||||||
qcdrain_style.rules.append(qcdrain_rule)
|
qcdrain_style.rules.append(qcdrain_rule)
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ roads34_lyr.datasource = mapnik.Shapefile(file='../data/roads')
|
||||||
|
|
||||||
roads34_style = mapnik.Style()
|
roads34_style = mapnik.Style()
|
||||||
roads34_rule = mapnik.Rule()
|
roads34_rule = mapnik.Rule()
|
||||||
roads34_rule.filter = mapnik.Filter('[CLASS] = 3 or [CLASS] = 4')
|
roads34_rule.filter = mapnik.Expression('([CLASS] = 3) or ([CLASS] = 4)')
|
||||||
|
|
||||||
# With lines of a certain width, you can control how the ends
|
# With lines of a certain width, you can control how the ends
|
||||||
# are closed off using line_cap as below.
|
# are closed off using line_cap as below.
|
||||||
|
@ -215,7 +215,7 @@ roads2_lyr.datasource = roads34_lyr.datasource
|
||||||
|
|
||||||
roads2_style_1 = mapnik.Style()
|
roads2_style_1 = mapnik.Style()
|
||||||
roads2_rule_1 = mapnik.Rule()
|
roads2_rule_1 = mapnik.Rule()
|
||||||
roads2_rule_1.filter = mapnik.Filter('[CLASS] = 2')
|
roads2_rule_1.filter = mapnik.Expression('[CLASS] = 2')
|
||||||
roads2_rule_stk_1 = mapnik.Stroke()
|
roads2_rule_stk_1 = mapnik.Stroke()
|
||||||
roads2_rule_stk_1.color = mapnik.Color(171,158,137)
|
roads2_rule_stk_1.color = mapnik.Color(171,158,137)
|
||||||
roads2_rule_stk_1.line_cap = mapnik.line_cap.ROUND_CAP
|
roads2_rule_stk_1.line_cap = mapnik.line_cap.ROUND_CAP
|
||||||
|
@ -227,7 +227,7 @@ m.append_style('road-border', roads2_style_1)
|
||||||
|
|
||||||
roads2_style_2 = mapnik.Style()
|
roads2_style_2 = mapnik.Style()
|
||||||
roads2_rule_2 = mapnik.Rule()
|
roads2_rule_2 = mapnik.Rule()
|
||||||
roads2_rule_2.filter = mapnik.Filter('[CLASS] = 2')
|
roads2_rule_2.filter = mapnik.Expression('[CLASS] = 2')
|
||||||
roads2_rule_stk_2 = mapnik.Stroke()
|
roads2_rule_stk_2 = mapnik.Stroke()
|
||||||
roads2_rule_stk_2.color = mapnik.Color(255,250,115)
|
roads2_rule_stk_2.color = mapnik.Color(255,250,115)
|
||||||
roads2_rule_stk_2.line_cap = mapnik.line_cap.ROUND_CAP
|
roads2_rule_stk_2.line_cap = mapnik.line_cap.ROUND_CAP
|
||||||
|
@ -250,7 +250,7 @@ roads1_lyr.datasource = roads34_lyr.datasource
|
||||||
|
|
||||||
roads1_style_1 = mapnik.Style()
|
roads1_style_1 = mapnik.Style()
|
||||||
roads1_rule_1 = mapnik.Rule()
|
roads1_rule_1 = mapnik.Rule()
|
||||||
roads1_rule_1.filter = mapnik.Filter('[CLASS] = 1')
|
roads1_rule_1.filter = mapnik.Expression('[CLASS] = 1')
|
||||||
roads1_rule_stk_1 = mapnik.Stroke()
|
roads1_rule_stk_1 = mapnik.Stroke()
|
||||||
roads1_rule_stk_1.color = mapnik.Color(188,149,28)
|
roads1_rule_stk_1.color = mapnik.Color(188,149,28)
|
||||||
roads1_rule_stk_1.line_cap = mapnik.line_cap.ROUND_CAP
|
roads1_rule_stk_1.line_cap = mapnik.line_cap.ROUND_CAP
|
||||||
|
@ -261,7 +261,7 @@ m.append_style('highway-border', roads1_style_1)
|
||||||
|
|
||||||
roads1_style_2 = mapnik.Style()
|
roads1_style_2 = mapnik.Style()
|
||||||
roads1_rule_2 = mapnik.Rule()
|
roads1_rule_2 = mapnik.Rule()
|
||||||
roads1_rule_2.filter = mapnik.Filter('[CLASS] = 1')
|
roads1_rule_2.filter = mapnik.Expression('[CLASS] = 1')
|
||||||
roads1_rule_stk_2 = mapnik.Stroke()
|
roads1_rule_stk_2 = mapnik.Stroke()
|
||||||
roads1_rule_stk_2.color = mapnik.Color(242,191,36)
|
roads1_rule_stk_2.color = mapnik.Color(242,191,36)
|
||||||
roads1_rule_stk_2.line_cap = mapnik.line_cap.ROUND_CAP
|
roads1_rule_stk_2.line_cap = mapnik.line_cap.ROUND_CAP
|
||||||
|
@ -289,7 +289,7 @@ popplaces_rule = mapnik.Rule()
|
||||||
# The first parameter is the name of the attribute to use as the source of the
|
# The first parameter is the name of the attribute to use as the source of the
|
||||||
# text to label with. Then there is font size in points (I think?), and colour.
|
# text to label with. Then there is font size in points (I think?), and colour.
|
||||||
|
|
||||||
popplaces_text_symbolizer = mapnik.TextSymbolizer('GEONAME',
|
popplaces_text_symbolizer = mapnik.TextSymbolizer(mapnik.Expression("[GEONAME]"),
|
||||||
'DejaVu Sans Book',
|
'DejaVu Sans Book',
|
||||||
10, mapnik.Color('black'))
|
10, mapnik.Color('black'))
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ m.layers.append(popplaces_lyr)
|
||||||
# Draw map
|
# Draw map
|
||||||
|
|
||||||
# Set the initial extent of the map in 'master' spherical Mercator projection
|
# Set the initial extent of the map in 'master' spherical Mercator projection
|
||||||
m.zoom_to_box(mapnik.Envelope(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855))
|
m.zoom_to_box(mapnik.Box2d(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855))
|
||||||
|
|
||||||
# Render two maps, two PNGs, one JPEG.
|
# Render two maps, two PNGs, one JPEG.
|
||||||
im = mapnik.Image(m.width,m.height)
|
im = mapnik.Image(m.width,m.height)
|
||||||
|
|
|
@ -69,7 +69,7 @@ m.layers.append(road_layer)
|
||||||
# Draw map
|
# Draw map
|
||||||
|
|
||||||
# Set the initial extent of the map.
|
# Set the initial extent of the map.
|
||||||
m.zoom_to_box(Envelope(0,0,14,-14))
|
m.zoom_to_box(Box2d(0,0,14,-14))
|
||||||
|
|
||||||
|
|
||||||
# Render
|
# Render
|
||||||
|
|
|
@ -70,7 +70,7 @@ m.layers.append(road_layer)
|
||||||
# Draw map
|
# Draw map
|
||||||
|
|
||||||
# Set the initial extent of the map.
|
# Set the initial extent of the map.
|
||||||
m.zoom_to_box(Envelope(0,0,14,-14))
|
m.zoom_to_box(Box2d(0,0,14,-14))
|
||||||
|
|
||||||
|
|
||||||
# Render
|
# Render
|
||||||
|
|
|
@ -71,7 +71,7 @@ m.layers.append(road_layer)
|
||||||
# Draw map
|
# Draw map
|
||||||
|
|
||||||
# Set the initial extent of the map.
|
# Set the initial extent of the map.
|
||||||
m.zoom_to_box(Envelope(0,0,14,-14))
|
m.zoom_to_box(Box2d(0,0,14,-14))
|
||||||
|
|
||||||
|
|
||||||
# Render
|
# Render
|
||||||
|
|
|
@ -69,7 +69,7 @@ m.layers.append(road_layer)
|
||||||
# Draw map
|
# Draw map
|
||||||
|
|
||||||
# Set the initial extent of the map.
|
# Set the initial extent of the map.
|
||||||
m.zoom_to_box(Envelope(0,0,14,-14))
|
m.zoom_to_box(Box2d(0,0,14,-14))
|
||||||
|
|
||||||
|
|
||||||
# Render
|
# Render
|
||||||
|
|
|
@ -90,7 +90,7 @@ bool LayerListModel::setData(const QModelIndex &index,
|
||||||
if (index.isValid() && role == Qt::CheckStateRole)
|
if (index.isValid() && role == Qt::CheckStateRole)
|
||||||
{
|
{
|
||||||
int status = value.toInt();
|
int status = value.toInt();
|
||||||
std::vector<mapnik::Layer> & layers = const_cast<std::vector<mapnik::Layer>& >(map_->layers());
|
std::vector<mapnik::layer> & layers = const_cast<std::vector<mapnik::layer>& >(map_->layers());
|
||||||
layers.at(index.row()).setActive(status);
|
layers.at(index.row()).setActive(status);
|
||||||
emit dataChanged(index, index);
|
emit dataChanged(index, index);
|
||||||
return true;
|
return true;
|
||||||
|
@ -107,15 +107,15 @@ Qt::ItemFlags LayerListModel::flags(QModelIndex const& index) const
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<mapnik::Layer&> LayerListModel::map_layer(int i)
|
boost::optional<mapnik::layer&> LayerListModel::map_layer(int i)
|
||||||
{
|
{
|
||||||
if (map_)
|
if (map_)
|
||||||
{
|
{
|
||||||
std::vector<mapnik::Layer> & layers = const_cast<std::vector<mapnik::Layer>& >(map_->layers());
|
std::vector<mapnik::layer> & layers = const_cast<std::vector<mapnik::layer>& >(map_->layers());
|
||||||
if (i < layers.size())
|
if (i < layers.size())
|
||||||
return boost::optional<mapnik::Layer&>(layers[i]);
|
return boost::optional<mapnik::layer&>(layers[i]);
|
||||||
}
|
}
|
||||||
return boost::optional<mapnik::Layer&>();
|
return boost::optional<mapnik::layer&>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class LayerListModel : public QAbstractListModel
|
||||||
bool setData(const QModelIndex &index, const QVariant &value,
|
bool setData(const QModelIndex &index, const QVariant &value,
|
||||||
int role = Qt::EditRole);
|
int role = Qt::EditRole);
|
||||||
Qt::ItemFlags flags(QModelIndex const& index) const;
|
Qt::ItemFlags flags(QModelIndex const& index) const;
|
||||||
boost::optional<mapnik::Layer&> map_layer(int i);
|
boost::optional<mapnik::layer&> map_layer(int i);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<mapnik::Map> map_;
|
boost::shared_ptr<mapnik::Map> map_;
|
||||||
|
|
|
@ -79,7 +79,7 @@ void LayerTab::layerInfo2(QModelIndex const& index)
|
||||||
QVector<QPair<QString,QString> > params;
|
QVector<QPair<QString,QString> > params;
|
||||||
unsigned i = index.row();
|
unsigned i = index.row();
|
||||||
LayerListModel * model = static_cast<LayerListModel*>(this->model());
|
LayerListModel * model = static_cast<LayerListModel*>(this->model());
|
||||||
boost::optional<mapnik::Layer&> layer = model->map_layer(i);
|
boost::optional<mapnik::layer&> layer = model->map_layer(i);
|
||||||
|
|
||||||
if (layer)
|
if (layer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,8 +41,8 @@ int main( int argc, char **argv )
|
||||||
// modify this prefix based on your install location
|
// modify this prefix based on your install location
|
||||||
std::string mapnik_dir = "/opt/mapnik";
|
std::string mapnik_dir = "/opt/mapnik";
|
||||||
|
|
||||||
datasource_cache::instance()->register_datasources(mapnik_dir + "/lib/mapnik/input");
|
datasource_cache::instance()->register_datasources(mapnik_dir + "/lib64/mapnik/input");
|
||||||
boost::filesystem::path path(mapnik_dir + "/lib/mapnik/fonts");
|
boost::filesystem::path path(mapnik_dir + "/lib64/mapnik/fonts");
|
||||||
boost::filesystem::directory_iterator end_itr;
|
boost::filesystem::directory_iterator end_itr;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ void MainWindow::reload()
|
||||||
{
|
{
|
||||||
if (!filename_.isEmpty())
|
if (!filename_.isEmpty())
|
||||||
{
|
{
|
||||||
mapnik::Envelope<double> bbox = mapWidget_->getMap()->getCurrentExtent();
|
mapnik::box2d<double> bbox = mapWidget_->getMap()->getCurrentExtent();
|
||||||
load_map_file(filename_);
|
load_map_file(filename_);
|
||||||
mapWidget_->zoomToBox(bbox);
|
mapWidget_->zoomToBox(bbox);
|
||||||
setWindowTitle(tr("%1 - *Reloaded*").arg(filename_));
|
setWindowTitle(tr("%1 - *Reloaded*").arg(filename_));
|
||||||
|
@ -382,7 +382,7 @@ void MainWindow::set_default_extent(double x0,double y0, double x1, double y1)
|
||||||
mapnik::projection prj(map_ptr->srs());
|
mapnik::projection prj(map_ptr->srs());
|
||||||
prj.forward(x0,y0);
|
prj.forward(x0,y0);
|
||||||
prj.forward(x1,y1);
|
prj.forward(x1,y1);
|
||||||
default_extent_=mapnik::Envelope<double>(x0,y0,x1,y1);
|
default_extent_=mapnik::box2d<double>(x0,y0,x1,y1);
|
||||||
mapWidget_->zoomToBox(default_extent_);
|
mapWidget_->zoomToBox(default_extent_);
|
||||||
std::cout << "SET DEFAULT EXT\n";
|
std::cout << "SET DEFAULT EXT\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ public slots:
|
||||||
QStatusBar *status;
|
QStatusBar *status;
|
||||||
QSlider * slider_;
|
QSlider * slider_;
|
||||||
|
|
||||||
mapnik::Envelope<double> default_extent_;
|
mapnik::box2d<double> default_extent_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,10 @@
|
||||||
#include "mapwidget.hpp"
|
#include "mapwidget.hpp"
|
||||||
#include "info_dialog.hpp"
|
#include "info_dialog.hpp"
|
||||||
|
|
||||||
using mapnik::Image32;
|
using mapnik::image_32;
|
||||||
using mapnik::Map;
|
using mapnik::Map;
|
||||||
using mapnik::Layer;
|
using mapnik::layer;
|
||||||
using mapnik::Envelope;
|
using mapnik::box2d;
|
||||||
using mapnik::coord2d;
|
using mapnik::coord2d;
|
||||||
using mapnik::feature_ptr;
|
using mapnik::feature_ptr;
|
||||||
using mapnik::geometry_ptr;
|
using mapnik::geometry_ptr;
|
||||||
|
@ -149,7 +149,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
|
||||||
{
|
{
|
||||||
if (int(index) != selectedLayer_) continue;
|
if (int(index) != selectedLayer_) continue;
|
||||||
|
|
||||||
Layer & layer = map_->layers()[index];
|
layer & layer = map_->layers()[index];
|
||||||
if (!layer.isVisible(scale_denom)) continue;
|
if (!layer.isVisible(scale_denom)) continue;
|
||||||
std::string name = layer.name();
|
std::string name = layer.name();
|
||||||
double x = e->x();
|
double x = e->x();
|
||||||
|
@ -187,7 +187,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
|
||||||
double x,y;
|
double x,y;
|
||||||
path.vertex(&x,&y);
|
path.vertex(&x,&y);
|
||||||
qpath.moveTo(x,y);
|
qpath.moveTo(x,y);
|
||||||
for (int j=1; j < geom.num_points(); ++j)
|
for (unsigned j = 1; j < geom.num_points(); ++j)
|
||||||
{
|
{
|
||||||
path.vertex(&x,&y);
|
path.vertex(&x,&y);
|
||||||
qpath.lineTo(x,y);
|
qpath.lineTo(x,y);
|
||||||
|
@ -216,7 +216,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
|
||||||
// remove annotation layer
|
// remove annotation layer
|
||||||
map_->layers().erase(remove_if(map_->layers().begin(),
|
map_->layers().erase(remove_if(map_->layers().begin(),
|
||||||
map_->layers().end(),
|
map_->layers().end(),
|
||||||
bind(&Layer::name,_1) == "*annotations*")
|
bind(&layer::name,_1) == "*annotations*")
|
||||||
, map_->layers().end());
|
, map_->layers().end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ void MapWidget::mouseReleaseEvent(QMouseEvent* e)
|
||||||
if (map_)
|
if (map_)
|
||||||
{
|
{
|
||||||
CoordTransform t(map_->getWidth(),map_->getHeight(),map_->getCurrentExtent());
|
CoordTransform t(map_->getWidth(),map_->getHeight(),map_->getCurrentExtent());
|
||||||
Envelope<double> box = t.backward(Envelope<double>(start_x_,start_y_,end_x_,end_y_));
|
box2d<double> box = t.backward(box2d<double>(start_x_,start_y_,end_x_,end_y_));
|
||||||
map_->zoomToBox(box);
|
map_->zoomToBox(box);
|
||||||
updateMap();
|
updateMap();
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ void MapWidget::mouseReleaseEvent(QMouseEvent* e)
|
||||||
|
|
||||||
void MapWidget::keyPressEvent(QKeyEvent *e)
|
void MapWidget::keyPressEvent(QKeyEvent *e)
|
||||||
{
|
{
|
||||||
std::cout << "key pressed:"<<e->key()<<"\n";
|
std::cout << "key pressed:"<< e->key()<<"\n";
|
||||||
switch (e->key()) {
|
switch (e->key()) {
|
||||||
case Qt::Key_Minus:
|
case Qt::Key_Minus:
|
||||||
zoomOut();
|
zoomOut();
|
||||||
|
@ -324,11 +324,14 @@ void MapWidget::keyPressEvent(QKeyEvent *e)
|
||||||
case 57:
|
case 57:
|
||||||
zoomToLevel(18);
|
zoomToLevel(18);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
QWidget::keyPressEvent(e);
|
||||||
}
|
}
|
||||||
QWidget::keyPressEvent(e);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWidget::zoomToBox(mapnik::Envelope<double> const& bbox)
|
void MapWidget::zoomToBox(mapnik::box2d<double> const& bbox)
|
||||||
{
|
{
|
||||||
if (map_)
|
if (map_)
|
||||||
{
|
{
|
||||||
|
@ -416,14 +419,14 @@ void MapWidget::zoomToLevel(int level)
|
||||||
{
|
{
|
||||||
double scale_denom = scales[level];
|
double scale_denom = scales[level];
|
||||||
std::cerr << "scale denominator = " << scale_denom << "\n";
|
std::cerr << "scale denominator = " << scale_denom << "\n";
|
||||||
mapnik::Envelope<double> ext = map_->getCurrentExtent();
|
mapnik::box2d<double> ext = map_->getCurrentExtent();
|
||||||
double width = static_cast<double>(map_->getWidth());
|
double width = static_cast<double>(map_->getWidth());
|
||||||
double height= static_cast<double>(map_->getHeight());
|
double height= static_cast<double>(map_->getHeight());
|
||||||
mapnik::coord2d pt = ext.center();
|
mapnik::coord2d pt = ext.center();
|
||||||
|
|
||||||
double res = scale_denom * 0.00028;
|
double res = scale_denom * 0.00028;
|
||||||
|
|
||||||
mapnik::Envelope<double> box(pt.x - 0.5 * width * res,
|
mapnik::box2d<double> box(pt.x - 0.5 * width * res,
|
||||||
pt.y - 0.5 * height*res,
|
pt.y - 0.5 * height*res,
|
||||||
pt.x + 0.5 * width * res,
|
pt.x + 0.5 * width * res,
|
||||||
pt.y + 0.5 * height*res);
|
pt.y + 0.5 * height*res);
|
||||||
|
@ -434,7 +437,7 @@ void MapWidget::zoomToLevel(int level)
|
||||||
|
|
||||||
void MapWidget::export_to_file(unsigned ,unsigned ,std::string const&,std::string const&)
|
void MapWidget::export_to_file(unsigned ,unsigned ,std::string const&,std::string const&)
|
||||||
{
|
{
|
||||||
//Image32 image(width,height);
|
//image_32 image(width,height);
|
||||||
//agg_renderer renderer(map,image);
|
//agg_renderer renderer(map,image);
|
||||||
//renderer.apply();
|
//renderer.apply();
|
||||||
//image.saveToFile(filename,type);
|
//image.saveToFile(filename,type);
|
||||||
|
@ -448,8 +451,8 @@ void MapWidget::updateMap()
|
||||||
unsigned width=map_->getWidth();
|
unsigned width=map_->getWidth();
|
||||||
unsigned height=map_->getHeight();
|
unsigned height=map_->getHeight();
|
||||||
|
|
||||||
Image32 buf(width,height);
|
image_32 buf(width,height);
|
||||||
mapnik::agg_renderer<Image32> ren(*map_,buf);
|
mapnik::agg_renderer<image_32> ren(*map_,buf);
|
||||||
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);
|
||||||
|
|
|
@ -48,7 +48,7 @@ class MapWidget : public QWidget
|
||||||
boost::shared_ptr<mapnik::Map> map_;
|
boost::shared_ptr<mapnik::Map> map_;
|
||||||
int selected_;
|
int selected_;
|
||||||
QPixmap pix_;
|
QPixmap pix_;
|
||||||
mapnik::Envelope<double> extent_;
|
mapnik::box2d<double> extent_;
|
||||||
eTool cur_tool_;
|
eTool cur_tool_;
|
||||||
int start_x_;
|
int start_x_;
|
||||||
int start_y_;
|
int start_y_;
|
||||||
|
@ -65,7 +65,7 @@ class MapWidget : public QWidget
|
||||||
inline QPixmap const& pixmap() const { return pix_;}
|
inline QPixmap const& pixmap() const { return pix_;}
|
||||||
void setMap(boost::shared_ptr<mapnik::Map> map);
|
void setMap(boost::shared_ptr<mapnik::Map> map);
|
||||||
void defaultView();
|
void defaultView();
|
||||||
void zoomToBox(mapnik::Envelope<double> const& box);
|
void zoomToBox(mapnik::box2d<double> const& box);
|
||||||
void zoomIn();
|
void zoomIn();
|
||||||
void zoomOut();
|
void zoomOut();
|
||||||
void panLeft();
|
void panLeft();
|
||||||
|
|
|
@ -182,13 +182,17 @@ struct symbolizer_icon : public boost::static_visitor<QIcon>
|
||||||
|
|
||||||
QIcon operator() (mapnik::point_symbolizer const& sym) const
|
QIcon operator() (mapnik::point_symbolizer const& sym) const
|
||||||
{
|
{
|
||||||
boost::shared_ptr<mapnik::ImageData32> symbol = sym.get_image();
|
// FIXME!
|
||||||
if (symbol)
|
/*
|
||||||
{
|
boost::shared_ptr<mapnik::image_data_32> symbol = sym.get_image();
|
||||||
QImage image(symbol->getBytes(),symbol->width(),symbol->height(),QImage::Format_ARGB32);
|
if (symbol)
|
||||||
|
{
|
||||||
|
QImage image(symbol->getBytes(),
|
||||||
|
symbol->width(),symbol->height(),QImage::Format_ARGB32);
|
||||||
QPixmap pix = QPixmap::fromImage(image.rgbSwapped());
|
QPixmap pix = QPixmap::fromImage(image.rgbSwapped());
|
||||||
return QIcon(pix);
|
return QIcon(pix);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return QIcon();
|
return QIcon();
|
||||||
}
|
}
|
||||||
QIcon operator() (mapnik::line_symbolizer const& sym) const
|
QIcon operator() (mapnik::line_symbolizer const& sym) const
|
||||||
|
@ -243,9 +247,9 @@ class rule_node
|
||||||
~rule_node() {}
|
~rule_node() {}
|
||||||
QString name() const
|
QString name() const
|
||||||
{
|
{
|
||||||
mapnik::filter_ptr filter = rule_.get_filter();
|
mapnik::expression_ptr filter = rule_.get_filter();
|
||||||
|
|
||||||
return QString(filter->to_string().c_str());
|
return QString("TODO!");//filter->to_string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon icon() const
|
QIcon icon() const
|
||||||
|
@ -319,7 +323,7 @@ StyleModel::StyleModel(boost::shared_ptr<mapnik::Map> map, QObject * parent)
|
||||||
for ( ; itr2 != rules.end();++itr2)
|
for ( ; itr2 != rules.end();++itr2)
|
||||||
{
|
{
|
||||||
node* rule_n = style_n->add_child(new node(rule_node(QString("Rule"),*itr2),style_n));
|
node* rule_n = style_n->add_child(new node(rule_node(QString("Rule"),*itr2),style_n));
|
||||||
mapnik::symbolizers::const_iterator itr3 = (*itr2).begin();
|
mapnik::rule_type::symbolizers::const_iterator itr3 = (*itr2).begin();
|
||||||
for ( ; itr3 !=itr2->end();++itr3)
|
for ( ; itr3 !=itr2->end();++itr3)
|
||||||
{
|
{
|
||||||
rule_n->add_child(new node(symbolizer_node(*itr3),rule_n));
|
rule_n->add_child(new node(symbolizer_node(*itr3),rule_n));
|
||||||
|
|
|
@ -5,14 +5,14 @@ CC = g++
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|
||||||
INCLUDEPATH += /opt/mapnik/include
|
INCLUDEPATH += /opt/mapnik/include
|
||||||
INCLUDEPATH += /opt/boost/include/boost-1_39
|
INCLUDEPATH += /opt/boost/include/
|
||||||
INCLUDEPATH += /usr/X11/include/
|
INCLUDEPATH += /usr/X11/include/
|
||||||
INCLUDEPATH += /usr/X11/include/freetype2
|
INCLUDEPATH += /usr/X11/include/freetype2
|
||||||
INCLUDEPATH += .
|
INCLUDEPATH += .
|
||||||
|
|
||||||
#QMAKE_CXXFLAGS +=' -DDARWIN'
|
QMAKE_CXXFLAGS +=' -DDARWIN -Wno-missing-field-initializers'
|
||||||
unix:LIBS = -L/opt/mapnik/lib -L/usr/X11/lib -lmapnik -lfreetype -L/usr/local/lib -licuuc
|
unix:LIBS = -L/opt/mapnik/lib64 -L/usr/X11/lib -lmapnik -lfreetype -L/usr/local/lib -licuuc
|
||||||
unix:LIBS += -lboost_system-xgcc40-mt -lboost_filesystem-xgcc40-mt -L/opt/boost/lib
|
unix:LIBS += -lboost_system -lboost_filesystem -lboost_regex -L/opt/boost/lib
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,8 @@ namespace mapnik {
|
||||||
~agg_renderer();
|
~agg_renderer();
|
||||||
void start_map_processing(Map const& map);
|
void start_map_processing(Map const& map);
|
||||||
void end_map_processing(Map const& map);
|
void end_map_processing(Map const& map);
|
||||||
void start_layer_processing(Layer const& lay);
|
void start_layer_processing(layer const& lay);
|
||||||
void end_layer_processing(Layer const& lay);
|
void end_layer_processing(layer const& lay);
|
||||||
void process(point_symbolizer const& sym,
|
void process(point_symbolizer const& sym,
|
||||||
Feature const& feature,
|
Feature const& feature,
|
||||||
proj_transform const& prj_trans);
|
proj_transform const& prj_trans);
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#ifndef ARROW_HPP
|
#ifndef ARROW_HPP
|
||||||
#define ARROW_HPP
|
#define ARROW_HPP
|
||||||
|
|
||||||
#include <mapnik/envelope.hpp>
|
#include <mapnik/box2d.hpp>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace mapnik {
|
||||||
arrow();
|
arrow();
|
||||||
void rewind(unsigned path_id);
|
void rewind(unsigned path_id);
|
||||||
unsigned vertex(double* x, double* y);
|
unsigned vertex(double* x, double* y);
|
||||||
Envelope<double> extent() const;
|
box2d<double> extent() const;
|
||||||
private:
|
private:
|
||||||
unsigned pos_;
|
unsigned pos_;
|
||||||
double x_[7];
|
double x_[7];
|
||||||
|
|
|
@ -1,222 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
//$Id: attribute.hpp 41 2005-04-13 20:21:56Z pavlenko $
|
|
||||||
|
|
||||||
#ifndef ATTRIBUTE_HPP
|
|
||||||
#define ATTRIBUTE_HPP
|
|
||||||
|
|
||||||
// boost
|
|
||||||
#include <boost/any.hpp>
|
|
||||||
// stl
|
|
||||||
#include <typeinfo>
|
|
||||||
#include <sstream>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace mapnik {
|
|
||||||
template <typename T>
|
|
||||||
struct attribute_traits
|
|
||||||
{
|
|
||||||
static std::string to_string(const T& value)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << value;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct attribute_traits<std::string>
|
|
||||||
{
|
|
||||||
static std::string to_string(const std::string& value)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MAPNIK_DECL attribute
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
attribute()
|
|
||||||
: base_(0) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
attribute(const T& value)
|
|
||||||
: base_(new attribute_impl<T>(value))
|
|
||||||
{}
|
|
||||||
|
|
||||||
attribute(const attribute& rhs)
|
|
||||||
: base_(rhs.base_ ? rhs.base_->clone() : 0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~attribute()
|
|
||||||
{
|
|
||||||
delete base_;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
attribute& operator=(const T& rhs)
|
|
||||||
{
|
|
||||||
attribute(rhs).swap(*this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
attribute& operator=(const attribute& rhs)
|
|
||||||
{
|
|
||||||
attribute(rhs).swap(*this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const
|
|
||||||
{
|
|
||||||
return !base_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::type_info & type() const
|
|
||||||
{
|
|
||||||
return base_ ? base_->type() : typeid(void);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string to_string() const
|
|
||||||
{
|
|
||||||
return base_ ? base_->to_string() : "";
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
attribute& swap(attribute& rhs)
|
|
||||||
{
|
|
||||||
std::swap(base_,rhs.base_);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
class attribute_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~attribute_base() {}
|
|
||||||
virtual attribute_base* clone() const=0;
|
|
||||||
virtual std::string to_string() const=0;
|
|
||||||
virtual const std::type_info& type() const=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T,typename ATraits=attribute_traits<T> >
|
|
||||||
class attribute_impl : public attribute_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef T value_type;
|
|
||||||
attribute_impl(const value_type& value)
|
|
||||||
: value_(value) {}
|
|
||||||
|
|
||||||
virtual std::string to_string() const
|
|
||||||
{
|
|
||||||
return ATraits::to_string(value_);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual attribute_base* clone() const
|
|
||||||
{
|
|
||||||
return new attribute_impl(value_);
|
|
||||||
}
|
|
||||||
virtual const std::type_info& type() const
|
|
||||||
{
|
|
||||||
return typeid(value_);
|
|
||||||
}
|
|
||||||
value_type value_;
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
template<typename value_type>
|
|
||||||
friend value_type* attribute_cast(attribute*);
|
|
||||||
attribute_base* base_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct bad_attribute_cast : public std::bad_cast
|
|
||||||
{
|
|
||||||
virtual const char* what() const throw()
|
|
||||||
{
|
|
||||||
return "attribute::failed conversion";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool is_type(const attribute& attr)
|
|
||||||
{
|
|
||||||
return attr.type()==typeid(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T* attribute_cast(attribute* attr)
|
|
||||||
{
|
|
||||||
return attr && attr->type() == typeid(T)
|
|
||||||
? &static_cast<attribute::attribute_impl<T>*>(attr->base_)->value_
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
const T* attribute_cast(const attribute* attr)
|
|
||||||
{
|
|
||||||
return attribute_cast<T>(const_cast<attribute*>(attr));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T attribute_cast(const attribute& attr)
|
|
||||||
{
|
|
||||||
using namespace boost;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
|
|
||||||
const nonref * result=attribute_cast<nonref>(&attr);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
throw bad_attribute_cast<T>();
|
|
||||||
}
|
|
||||||
return *result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T attribute_cast(attribute& attr)
|
|
||||||
{
|
|
||||||
using namespace boost;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
|
|
||||||
nonref * result=attribute_cast<nonref>(&attr);
|
|
||||||
if (!result)
|
|
||||||
throw bad_attribute_cast<T>();
|
|
||||||
return *result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
attribute attribute_from_string(const std::string& val)
|
|
||||||
{
|
|
||||||
std::istringstream is(val);
|
|
||||||
T t;
|
|
||||||
is >> t;
|
|
||||||
return attribute(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename charT, typename traits>
|
|
||||||
inline std::basic_ostream<charT,traits>&
|
|
||||||
operator << (std::basic_ostream<charT,traits>& out,
|
|
||||||
const attribute& attr)
|
|
||||||
{
|
|
||||||
out << attr.to_string();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //ATTRIBUTE_HPP
|
|
|
@ -26,77 +26,157 @@
|
||||||
#define ATTRIBUTE_COLLECTOR_HPP
|
#define ATTRIBUTE_COLLECTOR_HPP
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/filter.hpp>
|
|
||||||
#include <mapnik/expression.hpp>
|
|
||||||
#include <mapnik/feature_layer_desc.hpp>
|
#include <mapnik/feature_layer_desc.hpp>
|
||||||
#include <mapnik/rule.hpp>
|
#include <mapnik/rule.hpp>
|
||||||
|
#include <mapnik/path_expression_grammar.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
|
struct expression_attributes : boost::static_visitor<void>
|
||||||
|
{
|
||||||
|
explicit expression_attributes(std::set<std::string> & names)
|
||||||
|
: names_(names) {}
|
||||||
|
|
||||||
struct symbolizer_attributes : public boost::static_visitor<>
|
void operator() (value_type const& x) const
|
||||||
{
|
{
|
||||||
symbolizer_attributes(std::set<std::string>& names)
|
boost::ignore_unused_variable_warning(x);
|
||||||
: names_(names) {}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void operator() (attribute const& attr) const
|
||||||
void operator () (T const&) const {}
|
|
||||||
void operator () (text_symbolizer const& sym)
|
|
||||||
{
|
|
||||||
names_.insert(sym.get_name());
|
|
||||||
}
|
|
||||||
void operator () (shield_symbolizer const& sym)
|
|
||||||
{
|
|
||||||
names_.insert(sym.get_name());
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
std::set<std::string>& names_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
class attribute_collector : public filter_visitor<FeatureT>
|
|
||||||
{
|
{
|
||||||
private:
|
names_.insert(attr.name());
|
||||||
std::set<std::string>& names_;
|
}
|
||||||
public:
|
|
||||||
|
template <typename Tag>
|
||||||
attribute_collector(std::set<std::string>& names)
|
void operator() (binary_node<Tag> const& x) const
|
||||||
: names_(names) {}
|
{
|
||||||
|
boost::apply_visitor(expression_attributes(names_),x.left);
|
||||||
void visit(filter<FeatureT>& /*filter*/)
|
boost::apply_visitor(expression_attributes(names_),x.right);
|
||||||
{
|
|
||||||
//not interested
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void visit(expression<FeatureT>& exp)
|
|
||||||
{
|
|
||||||
property<FeatureT>* pf;
|
|
||||||
if ((pf = dynamic_cast<property<FeatureT>*>(&exp)))
|
|
||||||
{
|
|
||||||
names_.insert(pf->name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void visit(rule_type const& r)
|
|
||||||
{
|
|
||||||
const symbolizers& symbols = r.get_symbolizers();
|
|
||||||
symbolizers::const_iterator symIter=symbols.begin();
|
|
||||||
symbolizer_attributes attr(names_);
|
|
||||||
while (symIter != symbols.end())
|
|
||||||
{
|
|
||||||
boost::apply_visitor(attr,*symIter++);
|
|
||||||
}
|
|
||||||
filter_ptr const& filter = r.get_filter();
|
|
||||||
filter->accept(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~attribute_collector() {}
|
template <typename Tag>
|
||||||
private:
|
void operator() (unary_node<Tag> const& x) const
|
||||||
// no copying
|
{
|
||||||
attribute_collector(attribute_collector const&);
|
boost::apply_visitor(expression_attributes(names_),x.expr);
|
||||||
attribute_collector& operator=(attribute_collector const&);
|
}
|
||||||
};
|
|
||||||
}
|
void operator() (regex_match_node const& x) const
|
||||||
|
{
|
||||||
|
boost::apply_visitor(expression_attributes(names_),x.expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator() (regex_replace_node const& x) const
|
||||||
|
{
|
||||||
|
boost::apply_visitor(expression_attributes(names_),x.expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable std::set<std::string>& names_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct symbolizer_attributes : public boost::static_visitor<>
|
||||||
|
{
|
||||||
|
symbolizer_attributes(std::set<std::string>& names)
|
||||||
|
: names_(names) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void operator () (T const&) const {}
|
||||||
|
|
||||||
|
void operator () (text_symbolizer const& sym)
|
||||||
|
{
|
||||||
|
expression_ptr const& name_expr = sym.get_name();
|
||||||
|
if (name_expr)
|
||||||
|
{
|
||||||
|
expression_attributes f_attr(names_);
|
||||||
|
boost::apply_visitor(f_attr,*name_expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () (point_symbolizer const& sym)
|
||||||
|
{
|
||||||
|
path_expression_ptr const& filename_expr = sym.get_filename();
|
||||||
|
if (filename_expr)
|
||||||
|
{
|
||||||
|
path_processor_type::collect_attributes(*filename_expr,names_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () (line_pattern_symbolizer const& sym)
|
||||||
|
{
|
||||||
|
path_expression_ptr const& filename_expr = sym.get_filename();
|
||||||
|
if (filename_expr)
|
||||||
|
{
|
||||||
|
path_processor_type::collect_attributes(*filename_expr,names_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () (polygon_pattern_symbolizer const& sym)
|
||||||
|
{
|
||||||
|
path_expression_ptr const& filename_expr = sym.get_filename();
|
||||||
|
if (filename_expr)
|
||||||
|
{
|
||||||
|
path_processor_type::collect_attributes(*filename_expr,names_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () (shield_symbolizer const& sym)
|
||||||
|
{
|
||||||
|
expression_ptr const& name_expr = sym.get_name();
|
||||||
|
if (name_expr)
|
||||||
|
{
|
||||||
|
expression_attributes name_attr(names_);
|
||||||
|
boost::apply_visitor(name_attr,*name_expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
path_expression_ptr const& filename_expr = sym.get_filename();
|
||||||
|
if (filename_expr)
|
||||||
|
{
|
||||||
|
path_processor_type::collect_attributes(*filename_expr,names_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO - support remaining syms
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::set<std::string>& names_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class attribute_collector : public boost::noncopyable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::set<std::string>& names_;
|
||||||
|
public:
|
||||||
|
|
||||||
|
attribute_collector(std::set<std::string>& names)
|
||||||
|
: names_(names) {}
|
||||||
|
|
||||||
|
template <typename RuleType>
|
||||||
|
void operator() (RuleType const& r)
|
||||||
|
{
|
||||||
|
typename RuleType::symbolizers const& symbols = r.get_symbolizers();
|
||||||
|
typename RuleType::symbolizers::const_iterator symIter=symbols.begin();
|
||||||
|
symbolizer_attributes s_attr(names_);
|
||||||
|
while (symIter != symbols.end())
|
||||||
|
{
|
||||||
|
boost::apply_visitor(s_attr,*symIter++);
|
||||||
|
}
|
||||||
|
|
||||||
|
expression_ptr const& expr = r.get_filter();
|
||||||
|
expression_attributes f_attr(names_);
|
||||||
|
boost::apply_visitor(f_attr,*expr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mapnik
|
||||||
|
|
||||||
#endif //ATTRIBUTE_COLLECTOR_HPP
|
#endif //ATTRIBUTE_COLLECTOR_HPP
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2008 Tom Hughes
|
|
||||||
*
|
|
||||||
* 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$
|
|
||||||
|
|
||||||
#ifndef BOOLEAN_FILTER_HPP
|
|
||||||
#define BOOLEAN_FILTER_HPP
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/filter.hpp>
|
|
||||||
#include <mapnik/expression.hpp>
|
|
||||||
|
|
||||||
namespace mapnik
|
|
||||||
{
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct boolean_filter : public filter<FeatureT>
|
|
||||||
{
|
|
||||||
|
|
||||||
boolean_filter(expression<FeatureT> const& exp)
|
|
||||||
: filter<FeatureT>(),
|
|
||||||
exp_(exp.clone()) {}
|
|
||||||
|
|
||||||
boolean_filter(boolean_filter const& other)
|
|
||||||
: filter<FeatureT>(),
|
|
||||||
exp_(other.exp_->clone()) {}
|
|
||||||
|
|
||||||
bool pass(FeatureT const& feature) const
|
|
||||||
{
|
|
||||||
return exp_->get_value(feature).to_bool();
|
|
||||||
}
|
|
||||||
|
|
||||||
void accept(filter_visitor<FeatureT>& v)
|
|
||||||
{
|
|
||||||
exp_->accept(v);
|
|
||||||
v.visit(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
filter<FeatureT>* clone() const
|
|
||||||
{
|
|
||||||
return new boolean_filter(*this);
|
|
||||||
}
|
|
||||||
std::string to_string() const
|
|
||||||
{
|
|
||||||
return exp_->to_string();
|
|
||||||
}
|
|
||||||
~boolean_filter()
|
|
||||||
{
|
|
||||||
delete exp_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
expression<FeatureT>* exp_;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif //BOOLEAN_FILTER_HPP
|
|
|
@ -20,10 +20,10 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
//$Id: envelope.hpp 39 2005-04-10 20:39:53Z pavlenko $
|
//$Id: box2d.hpp 39 2005-04-10 20:39:53Z pavlenko $
|
||||||
|
|
||||||
#ifndef ENVELOPE_HPP
|
#ifndef MAPNIK_BOX2D_HPP
|
||||||
#define ENVELOPE_HPP
|
#define MAPNIK_BOX2D_HPP
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
|
@ -38,24 +38,24 @@ namespace mapnik {
|
||||||
/*!
|
/*!
|
||||||
* A spatial envelope (i.e. bounding box) which also defines some basic operators.
|
* A spatial envelope (i.e. bounding box) which also defines some basic operators.
|
||||||
*/
|
*/
|
||||||
template <typename T> class MAPNIK_DECL Envelope
|
template <typename T> class MAPNIK_DECL box2d
|
||||||
: boost::addable<Envelope<T>,
|
: boost::addable<box2d<T>,
|
||||||
boost::subtractable<Envelope<T>,
|
boost::subtractable<box2d<T>,
|
||||||
boost::dividable2<Envelope<T>, T,
|
boost::dividable2<box2d<T>, T,
|
||||||
boost::multipliable2<Envelope<T>, T > > > >
|
boost::multipliable2<box2d<T>, T > > > >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Envelope<T> EnvelopeType;
|
typedef box2d<T> box2d_type;
|
||||||
private:
|
private:
|
||||||
T minx_;
|
T minx_;
|
||||||
T miny_;
|
T miny_;
|
||||||
T maxx_;
|
T maxx_;
|
||||||
T maxy_;
|
T maxy_;
|
||||||
public:
|
public:
|
||||||
Envelope();
|
box2d();
|
||||||
Envelope(T minx,T miny,T maxx,T maxy);
|
box2d(T minx,T miny,T maxx,T maxy);
|
||||||
Envelope(const coord<T,2>& c0,const coord<T,2>& c1);
|
box2d(const coord<T,2>& c0,const coord<T,2>& c1);
|
||||||
Envelope(const EnvelopeType& rhs);
|
box2d(const box2d_type& rhs);
|
||||||
T minx() const;
|
T minx() const;
|
||||||
T miny() const;
|
T miny() const;
|
||||||
T maxx() const;
|
T maxx() const;
|
||||||
|
@ -67,34 +67,34 @@ namespace mapnik {
|
||||||
coord<T,2> center() const;
|
coord<T,2> center() const;
|
||||||
void expand_to_include(T x,T y);
|
void expand_to_include(T x,T y);
|
||||||
void expand_to_include(const coord<T,2>& c);
|
void expand_to_include(const coord<T,2>& c);
|
||||||
void expand_to_include(const EnvelopeType& other);
|
void expand_to_include(const box2d_type& other);
|
||||||
bool contains(const coord<T,2> &c) const;
|
bool contains(const coord<T,2> &c) const;
|
||||||
bool contains(T x,T y) const;
|
bool contains(T x,T y) const;
|
||||||
bool contains(const EnvelopeType &other) const;
|
bool contains(const box2d_type &other) const;
|
||||||
bool intersects(const coord<T,2> &c) const;
|
bool intersects(const coord<T,2> &c) const;
|
||||||
bool intersects(T x,T y) const;
|
bool intersects(T x,T y) const;
|
||||||
bool intersects(const EnvelopeType &other) const;
|
bool intersects(const box2d_type &other) const;
|
||||||
EnvelopeType intersect(const EnvelopeType& other) const;
|
box2d_type intersect(const box2d_type& other) const;
|
||||||
bool operator==(const EnvelopeType &other) const;
|
bool operator==(const box2d_type &other) const;
|
||||||
void re_center(T cx,T cy);
|
void re_center(T cx,T cy);
|
||||||
void init(T x0,T y0,T x1,T y1);
|
void init(T x0,T y0,T x1,T y1);
|
||||||
|
|
||||||
// define some operators
|
// define some operators
|
||||||
EnvelopeType& operator+=(EnvelopeType const& other);
|
box2d_type& operator+=(box2d_type const& other);
|
||||||
EnvelopeType& operator-=(EnvelopeType const& other);
|
box2d_type& operator-=(box2d_type const& other);
|
||||||
EnvelopeType& operator*=(T);
|
box2d_type& operator*=(T);
|
||||||
EnvelopeType& operator/=(T);
|
box2d_type& operator/=(T);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class charT,class traits,class T>
|
template <class charT,class traits,class T>
|
||||||
inline std::basic_ostream<charT,traits>&
|
inline std::basic_ostream<charT,traits>&
|
||||||
operator << (std::basic_ostream<charT,traits>& out,
|
operator << (std::basic_ostream<charT,traits>& out,
|
||||||
const Envelope<T>& e)
|
const box2d<T>& e)
|
||||||
{
|
{
|
||||||
std::basic_ostringstream<charT,traits> s;
|
std::basic_ostringstream<charT,traits> s;
|
||||||
s.copyfmt(out);
|
s.copyfmt(out);
|
||||||
s.width(0);
|
s.width(0);
|
||||||
s <<"Envelope(" << std::setprecision(16)
|
s <<"box2d(" << std::setprecision(16)
|
||||||
<< e.minx() << "," << e.miny() <<","
|
<< e.minx() << "," << e.miny() <<","
|
||||||
<< e.maxx() << "," << e.maxy() <<")";
|
<< e.maxx() << "," << e.maxy() <<")";
|
||||||
out << s.str();
|
out << s.str();
|
||||||
|
@ -102,4 +102,4 @@ namespace mapnik {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ENVELOPE_HPP
|
#endif // MAPNIK_BOX2D_HPP
|
|
@ -72,8 +72,8 @@ namespace mapnik {
|
||||||
public:
|
public:
|
||||||
~cairo_renderer_base();
|
~cairo_renderer_base();
|
||||||
void start_map_processing(Map const& map);
|
void start_map_processing(Map const& map);
|
||||||
void start_layer_processing(Layer const& lay);
|
void start_layer_processing(layer const& lay);
|
||||||
void end_layer_processing(Layer const& lay);
|
void end_layer_processing(layer const& lay);
|
||||||
void process(point_symbolizer const& sym,
|
void process(point_symbolizer const& sym,
|
||||||
Feature const& feature,
|
Feature const& feature,
|
||||||
proj_transform const& prj_trans);
|
proj_transform const& prj_trans);
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
|
|
||||||
//boost
|
//boost
|
||||||
#include <boost/format.hpp>
|
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
|
|
|
@ -22,46 +22,60 @@
|
||||||
|
|
||||||
//$Id$
|
//$Id$
|
||||||
|
|
||||||
#ifndef COLOR_FACTORY_HPP
|
#ifndef MAPNIK_COLOR_FACTORY_HPP
|
||||||
#define COLOR_FACTORY_HPP
|
#define MAPNIK_COLOR_FACTORY_HPP
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/color.hpp>
|
#include <mapnik/color.hpp>
|
||||||
#include <mapnik/css_color_parser.hpp>
|
|
||||||
#include <mapnik/config_error.hpp>
|
#include <mapnik/config_error.hpp>
|
||||||
|
#include <mapnik/css_color_grammar.hpp>
|
||||||
|
|
||||||
using namespace boost::spirit;
|
// boost
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
class MAPNIK_DECL color_factory
|
class MAPNIK_DECL color_factory : boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void init_from_string(color & c, char const* css_color)
|
static void init_from_string(color & c, char const* css_color)
|
||||||
{
|
{
|
||||||
actions<color> a(c);
|
|
||||||
css_color_grammar<actions<color> > grammar(a);
|
typedef std::string::const_iterator iterator_type;
|
||||||
parse_info<> info = parse(css_color, grammar, space_p);
|
typedef mapnik::css_color_grammar<iterator_type> css_color_grammar;
|
||||||
if ( ! info.full) {
|
std::string str(css_color);
|
||||||
throw config_error(std::string("Failed to parse color value: ") +
|
|
||||||
"Expected a color, but got '" + css_color + "'");
|
css_color_grammar g;
|
||||||
}
|
iterator_type first = str.begin();
|
||||||
}
|
iterator_type last = str.end();
|
||||||
|
mapnik::css css_;
|
||||||
static color from_string(char const* css_color)
|
bool result =
|
||||||
{
|
boost::spirit::qi::phrase_parse(first,
|
||||||
color c;
|
last,
|
||||||
init_from_string(c,css_color);
|
g,
|
||||||
return c;
|
boost::spirit::ascii::space,
|
||||||
}
|
css_);
|
||||||
|
if (!result)
|
||||||
private:
|
{
|
||||||
color_factory();
|
throw config_error(std::string("Failed to parse color value: ") +
|
||||||
color_factory(color_factory const&);
|
"Expected a color, but got '" + css_color + "'");
|
||||||
color_factory& operator=(color_factory const&);
|
}
|
||||||
};
|
// TODO: adapt mapnik::color into boost::fusion sequence
|
||||||
|
c.set_red(css_.r);
|
||||||
|
c.set_green(css_.g);
|
||||||
|
c.set_blue(css_.b);
|
||||||
|
c.set_alpha(css_.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static color from_string(char const* css_color)
|
||||||
|
{
|
||||||
|
color c;
|
||||||
|
init_from_string(c,css_color);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //COLOR_FACTORY_HPP
|
#endif //MAPNIK_COLOR_FACTORY_HPP
|
||||||
|
|
|
@ -1,149 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
//$Id$
|
|
||||||
|
|
||||||
#ifndef COMPARISON_HPP
|
|
||||||
#define COMPARISON_HPP
|
|
||||||
|
|
||||||
#include <mapnik/filter.hpp>
|
|
||||||
#include <mapnik/expression.hpp>
|
|
||||||
#include <mapnik/attribute.hpp>
|
|
||||||
|
|
||||||
namespace mapnik {
|
|
||||||
template <typename T>
|
|
||||||
struct greater_than
|
|
||||||
{
|
|
||||||
bool operator() (T const& left, T const& right) const
|
|
||||||
{
|
|
||||||
return left > right;
|
|
||||||
}
|
|
||||||
static std::string to_string()
|
|
||||||
{
|
|
||||||
return ">";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct greater_than_or_equal
|
|
||||||
{
|
|
||||||
bool operator() (T const& left, T const& right) const
|
|
||||||
{
|
|
||||||
return left >= right;
|
|
||||||
}
|
|
||||||
static std::string to_string()
|
|
||||||
{
|
|
||||||
return ">=";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <typename T>
|
|
||||||
struct less_than
|
|
||||||
{
|
|
||||||
bool operator() (T const& left, T const& right) const
|
|
||||||
{
|
|
||||||
return left < right;
|
|
||||||
}
|
|
||||||
static std::string to_string()
|
|
||||||
{
|
|
||||||
return "<";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <typename T>
|
|
||||||
struct less_than_or_equal
|
|
||||||
{
|
|
||||||
bool operator() (T const& left, T const& right) const
|
|
||||||
{
|
|
||||||
return left <= right;
|
|
||||||
}
|
|
||||||
static std::string to_string()
|
|
||||||
{
|
|
||||||
return "<=";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <typename T>
|
|
||||||
struct equals
|
|
||||||
{
|
|
||||||
bool operator() (T const& left, T const& right) const
|
|
||||||
{
|
|
||||||
return left == right;
|
|
||||||
}
|
|
||||||
static std::string to_string()
|
|
||||||
{
|
|
||||||
return "=";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct not_equals
|
|
||||||
{
|
|
||||||
bool operator() (T const& left, T const& right) const
|
|
||||||
{
|
|
||||||
return left != right;
|
|
||||||
}
|
|
||||||
static std::string to_string()
|
|
||||||
{
|
|
||||||
return "<>";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT,typename Op>
|
|
||||||
struct compare_filter : public filter<FeatureT>
|
|
||||||
{
|
|
||||||
compare_filter(expression<FeatureT> const& left,
|
|
||||||
expression<FeatureT> const& right)
|
|
||||||
: filter<FeatureT>(),
|
|
||||||
left_(left.clone()), right_(right.clone()) {}
|
|
||||||
|
|
||||||
compare_filter(compare_filter const& other)
|
|
||||||
: filter<FeatureT>(),
|
|
||||||
left_(other.left_->clone()),right_(other.right_->clone()) {}
|
|
||||||
|
|
||||||
bool pass(const FeatureT& feature) const
|
|
||||||
{
|
|
||||||
return Op()(left_->get_value(feature),right_->get_value(feature));
|
|
||||||
}
|
|
||||||
void accept(filter_visitor<FeatureT>& v)
|
|
||||||
{
|
|
||||||
left_->accept(v);
|
|
||||||
right_->accept(v);
|
|
||||||
v.visit(*this);
|
|
||||||
}
|
|
||||||
std::string to_string() const
|
|
||||||
{
|
|
||||||
return "("+left_->to_string()+Op::to_string()+right_->to_string()+")";
|
|
||||||
}
|
|
||||||
|
|
||||||
filter<FeatureT>* clone() const
|
|
||||||
{
|
|
||||||
return new compare_filter<FeatureT,Op>(*this);
|
|
||||||
}
|
|
||||||
virtual ~compare_filter()
|
|
||||||
{
|
|
||||||
delete left_;
|
|
||||||
delete right_;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
expression<FeatureT>* left_;
|
|
||||||
expression<FeatureT>* right_;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //COMPARISON_HPP
|
|
338
include/mapnik/css_color_grammar.hpp
Normal file
338
include/mapnik/css_color_grammar.hpp
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 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
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
#ifndef MAPNIK_CSS_COLOR_GRAMMAR_HPP
|
||||||
|
#define MAPNIK_CSS_COLOR_GRAMMAR_HPP
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/color.hpp>
|
||||||
|
// spirit2
|
||||||
|
#include <boost/config/warning_disable.hpp>
|
||||||
|
#include <boost/spirit/include/qi.hpp>
|
||||||
|
#include <boost/spirit/include/qi_action.hpp>
|
||||||
|
// phoenix
|
||||||
|
#include <boost/spirit/include/phoenix_core.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_fusion.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_function.hpp>
|
||||||
|
// fusion
|
||||||
|
#include <boost/fusion/include/adapt_struct.hpp>
|
||||||
|
|
||||||
|
// not in boost 1.41
|
||||||
|
//#include <boost/fusion/include/adapt_class.hpp>
|
||||||
|
|
||||||
|
// stl
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
//BOOST_FUSION_ADAPT_CLASS(
|
||||||
|
// mapnik::color,
|
||||||
|
// (unsigned, unsigned, obj.red(), obj.set_red(val))
|
||||||
|
// (unsigned, unsigned, obj.green(), obj.set_green(val))
|
||||||
|
// (unsigned, unsigned, obj.blue(), obj.set_blue(val))
|
||||||
|
// (unsigned, unsigned, obj.alpha(), obj.set_alpha(val))
|
||||||
|
// )
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
// temp workaround . TODO: adapt mapnik::color
|
||||||
|
struct css
|
||||||
|
{
|
||||||
|
css ()
|
||||||
|
: r(255),g(255),b(255),a(255) {}
|
||||||
|
css(unsigned r_,unsigned g_, unsigned b_,unsigned a_ = 0xff)
|
||||||
|
: r(r_),g(g_),b(b_),a(a_) {}
|
||||||
|
|
||||||
|
unsigned r;
|
||||||
|
unsigned g;
|
||||||
|
unsigned b;
|
||||||
|
unsigned a;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FUSION_ADAPT_STRUCT(
|
||||||
|
mapnik::css,
|
||||||
|
(unsigned, r)
|
||||||
|
(unsigned, g)
|
||||||
|
(unsigned, b)
|
||||||
|
(unsigned, a)
|
||||||
|
)
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace qi = boost::spirit::qi;
|
||||||
|
namespace phoenix = boost::phoenix;
|
||||||
|
|
||||||
|
typedef boost::spirit::ascii::space_type ascii_space_type;
|
||||||
|
|
||||||
|
struct named_colors_ : qi::symbols<char,mapnik::css>
|
||||||
|
{
|
||||||
|
named_colors_()
|
||||||
|
{
|
||||||
|
add
|
||||||
|
("aliceblue", mapnik::css(240, 248, 255))
|
||||||
|
("antiquewhite", mapnik::css(250, 235, 215))
|
||||||
|
("aqua", mapnik::css(0, 255, 255))
|
||||||
|
("aquamarine", mapnik::css(127, 255, 212))
|
||||||
|
("azure", mapnik::css(240, 255, 255))
|
||||||
|
("beige", mapnik::css(245, 245, 220))
|
||||||
|
("bisque", mapnik::css(255, 228, 196))
|
||||||
|
("black", mapnik::css(0, 0, 0))
|
||||||
|
("blanchedalmond", mapnik::css(255,235,205))
|
||||||
|
("blue", mapnik::css(0, 0, 255))
|
||||||
|
("blueviolet", mapnik::css(138, 43, 226))
|
||||||
|
("brown", mapnik::css(165, 42, 42))
|
||||||
|
("burlywood", mapnik::css(222, 184, 135))
|
||||||
|
("cadetblue", mapnik::css(95, 158, 160))
|
||||||
|
("chartreuse", mapnik::css(127, 255, 0))
|
||||||
|
("chocolate", mapnik::css(210, 105, 30))
|
||||||
|
("coral", mapnik::css(255, 127, 80))
|
||||||
|
("cornflowerblue", mapnik::css(100, 149, 237))
|
||||||
|
("cornsilk", mapnik::css(255, 248, 220))
|
||||||
|
("crimson", mapnik::css(220, 20, 60))
|
||||||
|
("cyan", mapnik::css(0, 255, 255))
|
||||||
|
("darkblue", mapnik::css(0, 0, 139))
|
||||||
|
("darkcyan", mapnik::css(0, 139, 139))
|
||||||
|
("darkgoldenrod", mapnik::css(184, 134, 11))
|
||||||
|
("darkgray", mapnik::css(169, 169, 169))
|
||||||
|
("darkgreen", mapnik::css(0, 100, 0))
|
||||||
|
("darkgrey", mapnik::css(169, 169, 169))
|
||||||
|
("darkkhaki", mapnik::css(189, 183, 107))
|
||||||
|
("darkmagenta", mapnik::css(139, 0, 139))
|
||||||
|
("darkolivegreen", mapnik::css(85, 107, 47))
|
||||||
|
("darkorange", mapnik::css(255, 140, 0))
|
||||||
|
("darkorchid", mapnik::css(153, 50, 204))
|
||||||
|
("darkred", mapnik::css(139, 0, 0))
|
||||||
|
("darksalmon", mapnik::css(233, 150, 122))
|
||||||
|
("darkseagreen", mapnik::css(143, 188, 143))
|
||||||
|
("darkslateblue", mapnik::css(72, 61, 139))
|
||||||
|
("darkslategrey", mapnik::css(47, 79, 79))
|
||||||
|
("darkturquoise", mapnik::css(0, 206, 209))
|
||||||
|
("darkviolet", mapnik::css(148, 0, 211))
|
||||||
|
("deeppink", mapnik::css(255, 20, 147))
|
||||||
|
("deepskyblue", mapnik::css(0, 191, 255))
|
||||||
|
("dimgray", mapnik::css(105, 105, 105))
|
||||||
|
("dimgrey", mapnik::css(105, 105, 105))
|
||||||
|
("dodgerblue", mapnik::css(30, 144, 255))
|
||||||
|
("firebrick", mapnik::css(178, 34, 34))
|
||||||
|
("floralwhite", mapnik::css(255, 250, 240))
|
||||||
|
("forestgreen", mapnik::css(34, 139, 34))
|
||||||
|
("fuchsia", mapnik::css(255, 0, 255))
|
||||||
|
("gainsboro", mapnik::css(220, 220, 220))
|
||||||
|
("ghostwhite", mapnik::css(248, 248, 255))
|
||||||
|
("gold", mapnik::css(255, 215, 0))
|
||||||
|
("goldenrod", mapnik::css(218, 165, 32))
|
||||||
|
("gray", mapnik::css(128, 128, 128))
|
||||||
|
("grey", mapnik::css(128, 128, 128))
|
||||||
|
("green", mapnik::css(0, 128, 0))
|
||||||
|
("greenyellow", mapnik::css(173, 255, 47))
|
||||||
|
("honeydew", mapnik::css(240, 255, 240))
|
||||||
|
("hotpink", mapnik::css(255, 105, 180))
|
||||||
|
("indianred", mapnik::css(205, 92, 92))
|
||||||
|
("indigo", mapnik::css(75, 0, 130))
|
||||||
|
("ivory", mapnik::css(255, 255, 240))
|
||||||
|
("khaki", mapnik::css(240, 230, 140))
|
||||||
|
("lavender", mapnik::css(230, 230, 250))
|
||||||
|
("lavenderblush", mapnik::css(255, 240, 245))
|
||||||
|
("lawngreen", mapnik::css(124, 252, 0))
|
||||||
|
("lemonchiffon", mapnik::css(255, 250, 205))
|
||||||
|
("lightblue", mapnik::css(173, 216, 230))
|
||||||
|
("lightcoral", mapnik::css(240, 128, 128))
|
||||||
|
("lightcyan", mapnik::css(224, 255, 255))
|
||||||
|
("lightgoldenrodyellow", mapnik::css(250, 250, 210))
|
||||||
|
("lightgray", mapnik::css(211, 211, 211))
|
||||||
|
("lightgreen", mapnik::css(144, 238, 144))
|
||||||
|
("lightgrey", mapnik::css(211, 211, 211))
|
||||||
|
("lightpink", mapnik::css(255, 182, 193))
|
||||||
|
("lightsalmon", mapnik::css(255, 160, 122))
|
||||||
|
("lightseagreen", mapnik::css(32, 178, 170))
|
||||||
|
("lightskyblue", mapnik::css(135, 206, 250))
|
||||||
|
("lightslategray", mapnik::css(119, 136, 153))
|
||||||
|
("lightslategrey", mapnik::css(119, 136, 153))
|
||||||
|
("lightsteelblue", mapnik::css(176, 196, 222))
|
||||||
|
("lightyellow", mapnik::css(255, 255, 224))
|
||||||
|
("lime", mapnik::css(0, 255, 0))
|
||||||
|
("limegreen", mapnik::css(50, 205, 50))
|
||||||
|
("linen", mapnik::css(250, 240, 230))
|
||||||
|
("magenta", mapnik::css(255, 0, 255))
|
||||||
|
("maroon", mapnik::css(128, 0, 0))
|
||||||
|
("mediumaquamarine", mapnik::css(102, 205, 170))
|
||||||
|
("mediumblue", mapnik::css(0, 0, 205))
|
||||||
|
("mediumorchid", mapnik::css(186, 85, 211))
|
||||||
|
("mediumpurple", mapnik::css(147, 112, 219))
|
||||||
|
("mediumseagreen", mapnik::css(60, 179, 113))
|
||||||
|
("mediumslateblue", mapnik::css(123, 104, 238))
|
||||||
|
("mediumspringgreen", mapnik::css(0, 250, 154))
|
||||||
|
("mediumturquoise", mapnik::css(72, 209, 204))
|
||||||
|
("mediumvioletred", mapnik::css(199, 21, 133))
|
||||||
|
("midnightblue", mapnik::css(25, 25, 112))
|
||||||
|
("mintcream", mapnik::css(245, 255, 250))
|
||||||
|
("mistyrose", mapnik::css(255, 228, 225))
|
||||||
|
("moccasin", mapnik::css(255, 228, 181))
|
||||||
|
("navajowhite", mapnik::css(255, 222, 173))
|
||||||
|
("navy", mapnik::css(0, 0, 128))
|
||||||
|
("oldlace", mapnik::css(253, 245, 230))
|
||||||
|
("olive", mapnik::css(128, 128, 0))
|
||||||
|
("olivedrab", mapnik::css(107, 142, 35))
|
||||||
|
("orange", mapnik::css(255, 165, 0))
|
||||||
|
("orangered", mapnik::css(255, 69, 0))
|
||||||
|
("orchid", mapnik::css(218, 112, 214))
|
||||||
|
("palegoldenrod", mapnik::css(238, 232, 170))
|
||||||
|
("palegreen", mapnik::css(152, 251, 152))
|
||||||
|
("paleturquoise", mapnik::css(175, 238, 238))
|
||||||
|
("palevioletred", mapnik::css(219, 112, 147))
|
||||||
|
("papayawhip", mapnik::css(255, 239, 213))
|
||||||
|
("peachpuff", mapnik::css(255, 218, 185))
|
||||||
|
("peru", mapnik::css(205, 133, 63))
|
||||||
|
("pink", mapnik::css(255, 192, 203))
|
||||||
|
("plum", mapnik::css(221, 160, 221))
|
||||||
|
("powderblue", mapnik::css(176, 224, 230))
|
||||||
|
("purple", mapnik::css(128, 0, 128))
|
||||||
|
("red", mapnik::css(255, 0, 0))
|
||||||
|
("rosybrown", mapnik::css(188, 143, 143))
|
||||||
|
("royalblue", mapnik::css(65, 105, 225))
|
||||||
|
("saddlebrown", mapnik::css(139, 69, 19))
|
||||||
|
("salmon", mapnik::css(250, 128, 114))
|
||||||
|
("sandybrown", mapnik::css(244, 164, 96))
|
||||||
|
("seagreen", mapnik::css(46, 139, 87))
|
||||||
|
("seashell", mapnik::css(255, 245, 238))
|
||||||
|
("sienna", mapnik::css(160, 82, 45))
|
||||||
|
("silver", mapnik::css(192, 192, 192))
|
||||||
|
("skyblue", mapnik::css(135, 206, 235))
|
||||||
|
("slateblue", mapnik::css(106, 90, 205))
|
||||||
|
("slategray", mapnik::css(112, 128, 144))
|
||||||
|
("slategrey", mapnik::css(112, 128, 144))
|
||||||
|
("snow", mapnik::css(255, 250, 250))
|
||||||
|
("springgreen", mapnik::css(0, 255, 127))
|
||||||
|
("steelblue", mapnik::css(70, 130, 180))
|
||||||
|
("tan", mapnik::css(210, 180, 140))
|
||||||
|
("teal", mapnik::css(0, 128, 128))
|
||||||
|
("thistle", mapnik::css(216, 191, 216))
|
||||||
|
("tomato", mapnik::css(255, 99, 71))
|
||||||
|
("turquoise", mapnik::css(64, 224, 208))
|
||||||
|
("violet", mapnik::css(238, 130, 238))
|
||||||
|
("wheat", mapnik::css(245, 222, 179))
|
||||||
|
("white", mapnik::css(255, 255, 255))
|
||||||
|
("whitesmoke", mapnik::css(245, 245, 245))
|
||||||
|
("yellow", mapnik::css(255, 255, 0))
|
||||||
|
("yellowgreen", mapnik::css(154, 205, 50))
|
||||||
|
("transparent", mapnik::css(0, 0, 0, 0))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
// clipper helper
|
||||||
|
|
||||||
|
template <int MIN,int MAX>
|
||||||
|
inline int clip_int(int val)
|
||||||
|
{
|
||||||
|
if (val < MIN ) return MIN;
|
||||||
|
if (val > MAX ) return MAX;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct percent_conv_impl
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
struct result
|
||||||
|
{
|
||||||
|
typedef unsigned type;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned operator() (double val) const
|
||||||
|
{
|
||||||
|
return clip_int<0,255>(int((255.0 * val)/100.0 + 0.5));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
struct css_color_grammar : qi::grammar<Iterator, mapnik::css(), ascii_space_type>
|
||||||
|
{
|
||||||
|
|
||||||
|
css_color_grammar()
|
||||||
|
: css_color_grammar::base_type(css_color)
|
||||||
|
|
||||||
|
{
|
||||||
|
using qi::lit;
|
||||||
|
using qi::_val;
|
||||||
|
using qi::double_;
|
||||||
|
using qi::_1;
|
||||||
|
using phoenix::at_c;
|
||||||
|
|
||||||
|
css_color %= rgba_color
|
||||||
|
| rgba_percent_color
|
||||||
|
| hex_color
|
||||||
|
| hex_color_small
|
||||||
|
| named;
|
||||||
|
|
||||||
|
hex_color %= lit('#')
|
||||||
|
>> hex2
|
||||||
|
>> hex2
|
||||||
|
>> hex2
|
||||||
|
>> -hex2
|
||||||
|
;
|
||||||
|
|
||||||
|
hex_color_small = lit('#')
|
||||||
|
>> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ]
|
||||||
|
>> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ]
|
||||||
|
>> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ]
|
||||||
|
>> -hex1[ at_c<3>(_val) = _1 | _1 << 4 ]
|
||||||
|
;
|
||||||
|
|
||||||
|
rgba_color %= lit("rgb") >> -lit('a')
|
||||||
|
>> lit('(')
|
||||||
|
>> dec3 >> ','
|
||||||
|
>> dec3 >> ','
|
||||||
|
>> dec3 >> -(','>> -dec3)
|
||||||
|
>> lit(')')
|
||||||
|
;
|
||||||
|
|
||||||
|
rgba_percent_color = lit("rgb") >> -lit('a')
|
||||||
|
>> lit('(')
|
||||||
|
>> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ','
|
||||||
|
>> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ','
|
||||||
|
>> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%'
|
||||||
|
>> -(','>> -double_ [at_c<3>(_val) = percent_converter(_1)] >> '%')
|
||||||
|
>> lit(')')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
qi::uint_parser< unsigned, 16, 2, 2 > hex2 ;
|
||||||
|
qi::uint_parser< unsigned, 16, 1, 1 > hex1 ;
|
||||||
|
qi::uint_parser< unsigned, 10, 1, 3 > dec3 ;
|
||||||
|
qi::rule<Iterator, mapnik::css(), ascii_space_type> rgba_color;
|
||||||
|
qi::rule<Iterator, mapnik::css(), ascii_space_type> rgba_percent_color;
|
||||||
|
qi::rule<Iterator, mapnik::css(), ascii_space_type> hex_color;
|
||||||
|
qi::rule<Iterator, mapnik::css(), ascii_space_type> hex_color_small;
|
||||||
|
qi::rule<Iterator, mapnik::css(), ascii_space_type> css_color;
|
||||||
|
named_colors_ named;
|
||||||
|
phoenix::function<percent_conv_impl> percent_converter;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //MAPNIK_CSS_COLOR_GRAMMAR_HPP
|
|
@ -1,442 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
//$Id$
|
|
||||||
|
|
||||||
#ifndef CSS_COLOR_PARSER_HPP
|
|
||||||
#define CSS_COLOR_PARSER_HPP
|
|
||||||
|
|
||||||
// boost
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
|
|
||||||
#if BOOST_VERSION < 103800
|
|
||||||
#include <boost/spirit/core.hpp>
|
|
||||||
#include <boost/spirit/symbols.hpp>
|
|
||||||
#else
|
|
||||||
#define BOOST_SPIRIT_USE_OLD_NAMESPACE
|
|
||||||
#include <boost/spirit/include/classic_core.hpp>
|
|
||||||
#include <boost/spirit/include/classic_symbols.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace boost::spirit;
|
|
||||||
|
|
||||||
namespace mapnik {
|
|
||||||
|
|
||||||
template <int MIN,int MAX>
|
|
||||||
inline int clip_int(int val)
|
|
||||||
{
|
|
||||||
if (val < MIN ) return MIN;
|
|
||||||
if (val > MAX ) return MAX;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct named_colors : public symbols<ColorT>
|
|
||||||
{
|
|
||||||
named_colors()
|
|
||||||
{
|
|
||||||
symbols<ColorT>::add
|
|
||||||
("aliceblue", ColorT(240, 248, 255))
|
|
||||||
("antiquewhite", ColorT(250, 235, 215))
|
|
||||||
("aqua", ColorT(0, 255, 255))
|
|
||||||
("aquamarine", ColorT(127, 255, 212))
|
|
||||||
("azure", ColorT(240, 255, 255))
|
|
||||||
("beige", ColorT(245, 245, 220))
|
|
||||||
("bisque", ColorT(255, 228, 196))
|
|
||||||
("black", ColorT(0, 0, 0))
|
|
||||||
("blanchedalmond", ColorT(255,235,205))
|
|
||||||
("blue", ColorT(0, 0, 255))
|
|
||||||
("blueviolet", ColorT(138, 43, 226))
|
|
||||||
("brown", ColorT(165, 42, 42))
|
|
||||||
("burlywood", ColorT(222, 184, 135))
|
|
||||||
("cadetblue", ColorT(95, 158, 160))
|
|
||||||
("chartreuse", ColorT(127, 255, 0))
|
|
||||||
("chocolate", ColorT(210, 105, 30))
|
|
||||||
("coral", ColorT(255, 127, 80))
|
|
||||||
("cornflowerblue", ColorT(100, 149, 237))
|
|
||||||
("cornsilk", ColorT(255, 248, 220))
|
|
||||||
("crimson", ColorT(220, 20, 60))
|
|
||||||
("cyan", ColorT(0, 255, 255))
|
|
||||||
("darkblue", ColorT(0, 0, 139))
|
|
||||||
("darkcyan", ColorT(0, 139, 139))
|
|
||||||
("darkgoldenrod", ColorT(184, 134, 11))
|
|
||||||
("darkgray", ColorT(169, 169, 169))
|
|
||||||
("darkgreen", ColorT(0, 100, 0))
|
|
||||||
("darkgrey", ColorT(169, 169, 169))
|
|
||||||
("darkkhaki", ColorT(189, 183, 107))
|
|
||||||
("darkmagenta", ColorT(139, 0, 139))
|
|
||||||
("darkolivegreen", ColorT(85, 107, 47))
|
|
||||||
("darkorange", ColorT(255, 140, 0))
|
|
||||||
("darkorchid", ColorT(153, 50, 204))
|
|
||||||
("darkred", ColorT(139, 0, 0))
|
|
||||||
("darksalmon", ColorT(233, 150, 122))
|
|
||||||
("darkseagreen", ColorT(143, 188, 143))
|
|
||||||
("darkslateblue", ColorT(72, 61, 139))
|
|
||||||
("darkslategrey", ColorT(47, 79, 79))
|
|
||||||
("darkturquoise", ColorT(0, 206, 209))
|
|
||||||
("darkviolet", ColorT(148, 0, 211))
|
|
||||||
("deeppink", ColorT(255, 20, 147))
|
|
||||||
("deepskyblue", ColorT(0, 191, 255))
|
|
||||||
("dimgray", ColorT(105, 105, 105))
|
|
||||||
("dimgrey", ColorT(105, 105, 105))
|
|
||||||
("dodgerblue", ColorT(30, 144, 255))
|
|
||||||
("firebrick", ColorT(178, 34, 34))
|
|
||||||
("floralwhite", ColorT(255, 250, 240))
|
|
||||||
("forestgreen", ColorT(34, 139, 34))
|
|
||||||
("fuchsia", ColorT(255, 0, 255))
|
|
||||||
("gainsboro", ColorT(220, 220, 220))
|
|
||||||
("ghostwhite", ColorT(248, 248, 255))
|
|
||||||
("gold", ColorT(255, 215, 0))
|
|
||||||
("goldenrod", ColorT(218, 165, 32))
|
|
||||||
("gray", ColorT(128, 128, 128))
|
|
||||||
("grey", ColorT(128, 128, 128))
|
|
||||||
("green", ColorT(0, 128, 0))
|
|
||||||
("greenyellow", ColorT(173, 255, 47))
|
|
||||||
("honeydew", ColorT(240, 255, 240))
|
|
||||||
("hotpink", ColorT(255, 105, 180))
|
|
||||||
("indianred", ColorT(205, 92, 92))
|
|
||||||
("indigo", ColorT(75, 0, 130))
|
|
||||||
("ivory", ColorT(255, 255, 240))
|
|
||||||
("khaki", ColorT(240, 230, 140))
|
|
||||||
("lavender", ColorT(230, 230, 250))
|
|
||||||
("lavenderblush", ColorT(255, 240, 245))
|
|
||||||
("lawngreen", ColorT(124, 252, 0))
|
|
||||||
("lemonchiffon", ColorT(255, 250, 205))
|
|
||||||
("lightblue", ColorT(173, 216, 230))
|
|
||||||
("lightcoral", ColorT(240, 128, 128))
|
|
||||||
("lightcyan", ColorT(224, 255, 255))
|
|
||||||
("lightgoldenrodyellow", ColorT(250, 250, 210))
|
|
||||||
("lightgray", ColorT(211, 211, 211))
|
|
||||||
("lightgreen", ColorT(144, 238, 144))
|
|
||||||
("lightgrey", ColorT(211, 211, 211))
|
|
||||||
("lightpink", ColorT(255, 182, 193))
|
|
||||||
("lightsalmon", ColorT(255, 160, 122))
|
|
||||||
("lightseagreen", ColorT(32, 178, 170))
|
|
||||||
("lightskyblue", ColorT(135, 206, 250))
|
|
||||||
("lightslategray", ColorT(119, 136, 153))
|
|
||||||
("lightslategrey", ColorT(119, 136, 153))
|
|
||||||
("lightsteelblue", ColorT(176, 196, 222))
|
|
||||||
("lightyellow", ColorT(255, 255, 224))
|
|
||||||
("lime", ColorT(0, 255, 0))
|
|
||||||
("limegreen", ColorT(50, 205, 50))
|
|
||||||
("linen", ColorT(250, 240, 230))
|
|
||||||
("magenta", ColorT(255, 0, 255))
|
|
||||||
("maroon", ColorT(128, 0, 0))
|
|
||||||
("mediumaquamarine", ColorT(102, 205, 170))
|
|
||||||
("mediumblue", ColorT(0, 0, 205))
|
|
||||||
("mediumorchid", ColorT(186, 85, 211))
|
|
||||||
("mediumpurple", ColorT(147, 112, 219))
|
|
||||||
("mediumseagreen", ColorT(60, 179, 113))
|
|
||||||
("mediumslateblue", ColorT(123, 104, 238))
|
|
||||||
("mediumspringgreen", ColorT(0, 250, 154))
|
|
||||||
("mediumturquoise", ColorT(72, 209, 204))
|
|
||||||
("mediumvioletred", ColorT(199, 21, 133))
|
|
||||||
("midnightblue", ColorT(25, 25, 112))
|
|
||||||
("mintcream", ColorT(245, 255, 250))
|
|
||||||
("mistyrose", ColorT(255, 228, 225))
|
|
||||||
("moccasin", ColorT(255, 228, 181))
|
|
||||||
("navajowhite", ColorT(255, 222, 173))
|
|
||||||
("navy", ColorT(0, 0, 128))
|
|
||||||
("oldlace", ColorT(253, 245, 230))
|
|
||||||
("olive", ColorT(128, 128, 0))
|
|
||||||
("olivedrab", ColorT(107, 142, 35))
|
|
||||||
("orange", ColorT(255, 165, 0))
|
|
||||||
("orangered", ColorT(255, 69, 0))
|
|
||||||
("orchid", ColorT(218, 112, 214))
|
|
||||||
("palegoldenrod", ColorT(238, 232, 170))
|
|
||||||
("palegreen", ColorT(152, 251, 152))
|
|
||||||
("paleturquoise", ColorT(175, 238, 238))
|
|
||||||
("palevioletred", ColorT(219, 112, 147))
|
|
||||||
("papayawhip", ColorT(255, 239, 213))
|
|
||||||
("peachpuff", ColorT(255, 218, 185))
|
|
||||||
("peru", ColorT(205, 133, 63))
|
|
||||||
("pink", ColorT(255, 192, 203))
|
|
||||||
("plum", ColorT(221, 160, 221))
|
|
||||||
("powderblue", ColorT(176, 224, 230))
|
|
||||||
("purple", ColorT(128, 0, 128))
|
|
||||||
("red", ColorT(255, 0, 0))
|
|
||||||
("rosybrown", ColorT(188, 143, 143))
|
|
||||||
("royalblue", ColorT(65, 105, 225))
|
|
||||||
("saddlebrown", ColorT(139, 69, 19))
|
|
||||||
("salmon", ColorT(250, 128, 114))
|
|
||||||
("sandybrown", ColorT(244, 164, 96))
|
|
||||||
("seagreen", ColorT(46, 139, 87))
|
|
||||||
("seashell", ColorT(255, 245, 238))
|
|
||||||
("sienna", ColorT(160, 82, 45))
|
|
||||||
("silver", ColorT(192, 192, 192))
|
|
||||||
("skyblue", ColorT(135, 206, 235))
|
|
||||||
("slateblue", ColorT(106, 90, 205))
|
|
||||||
("slategray", ColorT(112, 128, 144))
|
|
||||||
("slategrey", ColorT(112, 128, 144))
|
|
||||||
("snow", ColorT(255, 250, 250))
|
|
||||||
("springgreen", ColorT(0, 255, 127))
|
|
||||||
("steelblue", ColorT(70, 130, 180))
|
|
||||||
("tan", ColorT(210, 180, 140))
|
|
||||||
("teal", ColorT(0, 128, 128))
|
|
||||||
("thistle", ColorT(216, 191, 216))
|
|
||||||
("tomato", ColorT(255, 99, 71))
|
|
||||||
("turquoise", ColorT(64, 224, 208))
|
|
||||||
("violet", ColorT(238, 130, 238))
|
|
||||||
("wheat", ColorT(245, 222, 179))
|
|
||||||
("white", ColorT(255, 255, 255))
|
|
||||||
("whitesmoke", ColorT(245, 245, 245))
|
|
||||||
("yellow", ColorT(255, 255, 0))
|
|
||||||
("yellowgreen", ColorT(154, 205, 50))
|
|
||||||
("transparent", ColorT(0, 0, 0, 0))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ActionsT>
|
|
||||||
struct css_color_grammar : public grammar<css_color_grammar<ActionsT> >
|
|
||||||
{
|
|
||||||
css_color_grammar(ActionsT& actions_)
|
|
||||||
: actions(actions_) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct definition
|
|
||||||
{
|
|
||||||
definition(css_color_grammar const& self)
|
|
||||||
{
|
|
||||||
hex6 = ch_p('#') >> uint6x_p[self.actions.hex6_];
|
|
||||||
hex3 = ch_p('#') >> uint3x_p[self.actions.hex3_];
|
|
||||||
rgb = str_p("rgb") >> '(' >> int_p [self.actions.red_]
|
|
||||||
>> ',' >> int_p [self.actions.green_]
|
|
||||||
>> ',' >> int_p [self.actions.blue_]
|
|
||||||
>> ')';
|
|
||||||
rgba = str_p("rgba") >> '(' >> int_p [self.actions.red_]
|
|
||||||
>> ',' >> int_p [self.actions.green_]
|
|
||||||
>> ',' >> int_p [self.actions.blue_]
|
|
||||||
>> ',' >> real_p[self.actions.alpha_]
|
|
||||||
>> ')';
|
|
||||||
rgb_percent = str_p("rgb") >> '(' >> real_p[self.actions.red_p_] >> '%'
|
|
||||||
>> ',' >> real_p[self.actions.green_p_] >> '%'
|
|
||||||
>> ',' >> real_p[self.actions.blue_p_] >> '%'
|
|
||||||
>> ')';
|
|
||||||
rgba_percent = str_p("rgba") >> '(' >> real_p[self.actions.red_p_] >> '%'
|
|
||||||
>> ',' >> real_p[self.actions.green_p_] >> '%'
|
|
||||||
>> ',' >> real_p[self.actions.blue_p_] >> '%'
|
|
||||||
>> ',' >> real_p[self.actions.alpha_]
|
|
||||||
>> ')';
|
|
||||||
css_color = named_colors_p[self.actions.named_] | hex6 | hex3 | rgb_percent | rgba_percent | rgb | rgba;
|
|
||||||
}
|
|
||||||
boost::spirit::rule<ScannerT> rgb;
|
|
||||||
boost::spirit::rule<ScannerT> rgba;
|
|
||||||
boost::spirit::rule<ScannerT> rgb_percent;
|
|
||||||
boost::spirit::rule<ScannerT> rgba_percent;
|
|
||||||
boost::spirit::rule<ScannerT> hex6;
|
|
||||||
boost::spirit::rule<ScannerT> hex3;
|
|
||||||
boost::spirit::rule<ScannerT> css_color;
|
|
||||||
boost::spirit::rule<ScannerT> const& start() const
|
|
||||||
{
|
|
||||||
return css_color;
|
|
||||||
}
|
|
||||||
int_parser<int, 10, 1, -1> int_p;
|
|
||||||
uint_parser<unsigned, 16, 6, 6> uint6x_p;
|
|
||||||
uint_parser<unsigned, 16, 3, 3> uint3x_p;
|
|
||||||
real_parser<double, real_parser_policies<double> > real_p;
|
|
||||||
named_colors<typename ActionsT::color_type> named_colors_p;
|
|
||||||
|
|
||||||
};
|
|
||||||
ActionsT& actions;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct named_color_action
|
|
||||||
{
|
|
||||||
named_color_action(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator() (ColorT const&c) const
|
|
||||||
{
|
|
||||||
c_=c;
|
|
||||||
}
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct hex6_action
|
|
||||||
{
|
|
||||||
hex6_action(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator () (unsigned int hex) const
|
|
||||||
{
|
|
||||||
unsigned r = (hex >> 16) & 0xff;
|
|
||||||
unsigned g = (hex >> 8) & 0xff;
|
|
||||||
unsigned b = hex & 0xff;
|
|
||||||
c_.set_red(r);
|
|
||||||
c_.set_green(g);
|
|
||||||
c_.set_blue(b);
|
|
||||||
}
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct hex3_action
|
|
||||||
{
|
|
||||||
hex3_action(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator () (unsigned int hex) const
|
|
||||||
{
|
|
||||||
unsigned int r = (hex >> 8) & 0xf;
|
|
||||||
unsigned int g = (hex >> 4) & 0xf;
|
|
||||||
unsigned int b = hex & 0xf;
|
|
||||||
c_.set_red( r | r << 4);
|
|
||||||
c_.set_green(g | g << 4);
|
|
||||||
c_.set_blue(b | b << 4);
|
|
||||||
}
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct red_action
|
|
||||||
{
|
|
||||||
red_action(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator () (int r) const
|
|
||||||
{
|
|
||||||
c_.set_red(clip_int<0,255>(r));
|
|
||||||
}
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct green_action
|
|
||||||
{
|
|
||||||
green_action(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator () (int g) const
|
|
||||||
{
|
|
||||||
c_.set_green(clip_int<0,255>(g));
|
|
||||||
}
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct blue_action
|
|
||||||
{
|
|
||||||
blue_action(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator () (int b) const
|
|
||||||
{
|
|
||||||
c_.set_blue(clip_int<0,255>(b));
|
|
||||||
}
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct alpha_action
|
|
||||||
{
|
|
||||||
alpha_action(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator () (double a) const
|
|
||||||
{
|
|
||||||
if (a < 0.0) a = 0.0;
|
|
||||||
if (a > 1.0) a = 1.0;
|
|
||||||
c_.set_alpha(unsigned(a * 255.0 + 0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct red_action_p
|
|
||||||
{
|
|
||||||
red_action_p(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator () (double r) const
|
|
||||||
{
|
|
||||||
c_.set_red(clip_int<0,255>(int((255.0 * r)/100.0 + 0.5)));
|
|
||||||
}
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct green_action_p
|
|
||||||
{
|
|
||||||
green_action_p(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator () (double g) const
|
|
||||||
{
|
|
||||||
c_.set_green(clip_int<0,255>(int((255.0 * g)/100.0 + 0.5)));
|
|
||||||
}
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct blue_action_p
|
|
||||||
{
|
|
||||||
blue_action_p(ColorT& c)
|
|
||||||
: c_(c) {}
|
|
||||||
|
|
||||||
void operator () (double b) const
|
|
||||||
{
|
|
||||||
c_.set_blue(clip_int<0,255>(int((255.0 * b)/100.0 + 0.5)));
|
|
||||||
}
|
|
||||||
ColorT& c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ColorT>
|
|
||||||
struct actions
|
|
||||||
{
|
|
||||||
typedef ColorT color_type;
|
|
||||||
actions(ColorT& c)
|
|
||||||
:
|
|
||||||
named_(c),
|
|
||||||
hex6_(c),
|
|
||||||
hex3_(c),
|
|
||||||
red_(c),
|
|
||||||
green_(c),
|
|
||||||
blue_(c),
|
|
||||||
alpha_(c),
|
|
||||||
red_p_(c),
|
|
||||||
green_p_(c),
|
|
||||||
blue_p_(c)
|
|
||||||
{
|
|
||||||
c.set_alpha (255);
|
|
||||||
}
|
|
||||||
|
|
||||||
named_color_action<ColorT> named_;
|
|
||||||
hex6_action<ColorT> hex6_;
|
|
||||||
hex3_action<ColorT> hex3_;
|
|
||||||
red_action<ColorT> red_;
|
|
||||||
green_action<ColorT> green_;
|
|
||||||
blue_action<ColorT> blue_;
|
|
||||||
alpha_action<ColorT> alpha_;
|
|
||||||
red_action_p<ColorT> red_p_;
|
|
||||||
green_action_p<ColorT> green_p_;
|
|
||||||
blue_action_p<ColorT> blue_p_;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //CSS_COLOR_PARSER_HPP
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <mapnik/envelope.hpp>
|
#include <mapnik/box2d.hpp>
|
||||||
#include <mapnik/coord_array.hpp>
|
#include <mapnik/coord_array.hpp>
|
||||||
#include <mapnik/proj_transform.hpp>
|
#include <mapnik/proj_transform.hpp>
|
||||||
|
|
||||||
|
@ -130,11 +130,11 @@ namespace mapnik {
|
||||||
int height_;
|
int height_;
|
||||||
double sx_;
|
double sx_;
|
||||||
double sy_;
|
double sy_;
|
||||||
Envelope<double> extent_;
|
box2d<double> extent_;
|
||||||
double offset_x_;
|
double offset_x_;
|
||||||
double offset_y_;
|
double offset_y_;
|
||||||
public:
|
public:
|
||||||
CoordTransform(int width,int height,const Envelope<double>& extent,
|
CoordTransform(int width,int height,const box2d<double>& extent,
|
||||||
double offset_x = 0, double offset_y = 0)
|
double offset_x = 0, double offset_y = 0)
|
||||||
:width_(width),height_(height),extent_(extent),offset_x_(offset_x),offset_y_(offset_y)
|
:width_(width),height_(height),extent_(extent),offset_x_(offset_x),offset_y_(offset_y)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +186,7 @@ namespace mapnik {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Envelope<double> forward(const Envelope<double>& e) const
|
inline box2d<double> forward(const box2d<double>& e) const
|
||||||
{
|
{
|
||||||
double x0 = e.minx();
|
double x0 = e.minx();
|
||||||
double y0 = e.miny();
|
double y0 = e.miny();
|
||||||
|
@ -194,10 +194,10 @@ namespace mapnik {
|
||||||
double y1 = e.maxy();
|
double y1 = e.maxy();
|
||||||
forward(&x0,&y0);
|
forward(&x0,&y0);
|
||||||
forward(&x1,&y1);
|
forward(&x1,&y1);
|
||||||
return Envelope<double>(x0,y0,x1,y1);
|
return box2d<double>(x0,y0,x1,y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Envelope<double> backward(const Envelope<double>& e) const
|
inline box2d<double> backward(const box2d<double>& e) const
|
||||||
{
|
{
|
||||||
double x0 = e.minx();
|
double x0 = e.minx();
|
||||||
double y0 = e.miny();
|
double y0 = e.miny();
|
||||||
|
@ -205,7 +205,7 @@ namespace mapnik {
|
||||||
double y1 = e.maxy();
|
double y1 = e.maxy();
|
||||||
backward(&x0,&y0);
|
backward(&x0,&y0);
|
||||||
backward(&x1,&y1);
|
backward(&x1,&y1);
|
||||||
return Envelope<double>(x0,y0,x1,y1);
|
return box2d<double>(x0,y0,x1,y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CoordinateArray& forward(CoordinateArray& coords) const
|
inline CoordinateArray& forward(CoordinateArray& coords) const
|
||||||
|
@ -225,7 +225,7 @@ namespace mapnik {
|
||||||
}
|
}
|
||||||
return coords;
|
return coords;
|
||||||
}
|
}
|
||||||
inline Envelope<double> const& extent() const
|
inline box2d<double> const& extent() const
|
||||||
{
|
{
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace mapnik {
|
||||||
|
|
||||||
virtual featureset_ptr features(const query& q) const=0;
|
virtual featureset_ptr features(const query& q) const=0;
|
||||||
virtual featureset_ptr features_at_point(coord2d const& pt) const=0;
|
virtual featureset_ptr features_at_point(coord2d const& pt) const=0;
|
||||||
virtual Envelope<double> envelope() const=0;
|
virtual box2d<double> envelope() const=0;
|
||||||
virtual layer_descriptor get_descriptor() const=0;
|
virtual layer_descriptor get_descriptor() const=0;
|
||||||
virtual ~datasource() {};
|
virtual ~datasource() {};
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1,132 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
//$Id$
|
|
||||||
|
|
||||||
#ifndef EXPRESSION_HPP
|
|
||||||
#define EXPRESSION_HPP
|
|
||||||
|
|
||||||
#include <mapnik/value.hpp>
|
|
||||||
#include <mapnik/filter_visitor.hpp>
|
|
||||||
|
|
||||||
namespace mapnik {
|
|
||||||
template <typename FeatureT> class filter_visitor;
|
|
||||||
template <typename FeatureT>
|
|
||||||
class expression
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual value get_value(FeatureT const& feature) const=0;
|
|
||||||
virtual void accept(filter_visitor<FeatureT>& v)=0;
|
|
||||||
virtual expression<FeatureT>* clone() const=0;
|
|
||||||
virtual std::string to_string() const=0;
|
|
||||||
virtual ~expression() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
class literal : public expression<FeatureT>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
literal(bool val)
|
|
||||||
: expression<FeatureT>(),
|
|
||||||
value_(val) {}
|
|
||||||
literal(int val)
|
|
||||||
: expression<FeatureT>(),
|
|
||||||
value_(val) {}
|
|
||||||
literal(double val)
|
|
||||||
: expression<FeatureT>(),
|
|
||||||
value_(val) {}
|
|
||||||
literal(UnicodeString const& val)
|
|
||||||
: expression<FeatureT>(),
|
|
||||||
value_(val) {}
|
|
||||||
literal(literal const& other)
|
|
||||||
: expression<FeatureT>(),
|
|
||||||
value_(other.value_) {}
|
|
||||||
|
|
||||||
value get_value(FeatureT const& /*feature*/) const
|
|
||||||
{
|
|
||||||
return value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void accept(filter_visitor<FeatureT>& v)
|
|
||||||
{
|
|
||||||
v.visit(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
expression<FeatureT>* clone() const
|
|
||||||
{
|
|
||||||
return new literal(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string() const
|
|
||||||
{
|
|
||||||
return value_.to_expression_string();
|
|
||||||
}
|
|
||||||
~literal() {}
|
|
||||||
private:
|
|
||||||
value value_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
class property : public expression<FeatureT>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
property(std::string const& name)
|
|
||||||
: expression<FeatureT>(),
|
|
||||||
name_(name)
|
|
||||||
{}
|
|
||||||
|
|
||||||
property(property const& other)
|
|
||||||
: expression<FeatureT>(),
|
|
||||||
name_(other.name_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
value get_value(FeatureT const& feature) const
|
|
||||||
{
|
|
||||||
return feature[name_];
|
|
||||||
}
|
|
||||||
void accept(filter_visitor<FeatureT>& v)
|
|
||||||
{
|
|
||||||
v.visit(*this);
|
|
||||||
}
|
|
||||||
expression<FeatureT>* clone() const
|
|
||||||
{
|
|
||||||
return new property(*this);
|
|
||||||
}
|
|
||||||
std::string const& name() const
|
|
||||||
{
|
|
||||||
return name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string() const
|
|
||||||
{
|
|
||||||
return "["+name_+"]";
|
|
||||||
}
|
|
||||||
|
|
||||||
~property() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string name_;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //EXPRESSION_HPP
|
|
93
include/mapnik/expression_evaluator.hpp
Normal file
93
include/mapnik/expression_evaluator.hpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 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
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
#ifndef MAPNIK_EXPRESSION_EVALUATOR_HPP
|
||||||
|
#define MAPNIK_EXPRESSION_EVALUATOR_HPP
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
#include <boost/regex/icu.hpp>
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
template <typename T0, typename T1>
|
||||||
|
struct evaluate : boost::static_visitor<T1>
|
||||||
|
{
|
||||||
|
typedef T0 feature_type;
|
||||||
|
typedef T1 value_type;
|
||||||
|
|
||||||
|
explicit evaluate(feature_type const& f)
|
||||||
|
: feature_(f) {}
|
||||||
|
|
||||||
|
value_type operator() (value_type x) const { return x; }
|
||||||
|
value_type operator() (attribute const& attr) const
|
||||||
|
{
|
||||||
|
return attr.value<value_type,feature_type>(feature_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
value_type operator() (binary_node<tags::logical_and> const & x) const
|
||||||
|
{
|
||||||
|
return (boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.left).to_bool())
|
||||||
|
&& (boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.right).to_bool());
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type operator() (binary_node<tags::logical_or> const & x) const
|
||||||
|
{
|
||||||
|
return (boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.left).to_bool())
|
||||||
|
|| (boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.right).to_bool());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Tag>
|
||||||
|
value_type operator() (binary_node<Tag> const& x) const
|
||||||
|
{
|
||||||
|
typename make_op<Tag>::type operation;
|
||||||
|
return operation(boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.left),
|
||||||
|
boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.right));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Tag>
|
||||||
|
value_type operator() (unary_node<Tag> const& x) const
|
||||||
|
{
|
||||||
|
return ! (boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.expr).to_bool());
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type operator() (regex_match_node const& x) const
|
||||||
|
{
|
||||||
|
value_type v = boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.expr);
|
||||||
|
return boost::u32regex_match(v.to_unicode(),x.pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type operator() (regex_replace_node const& x) const
|
||||||
|
{
|
||||||
|
value_type v = boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.expr);
|
||||||
|
return boost::u32regex_replace(v.to_unicode(),x.pattern,x.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
feature_type const& feature_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //MAPNIK_EXPRESSION_EVALUATOR_HPP
|
244
include/mapnik/expression_grammar.hpp
Normal file
244
include/mapnik/expression_grammar.hpp
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 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
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_HPP
|
||||||
|
#define MAPNIK_EXPRESSIONS_GRAMMAR_HPP
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/value.hpp>
|
||||||
|
#include <mapnik/expression_node.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
//spirit2
|
||||||
|
#include <boost/spirit/include/qi.hpp>
|
||||||
|
#include <boost/spirit/include/qi_action.hpp>
|
||||||
|
//fusion
|
||||||
|
#include <boost/fusion/include/adapt_struct.hpp>
|
||||||
|
//phoenix
|
||||||
|
#include <boost/spirit/include/phoenix_core.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_object.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_function.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_stl.hpp>
|
||||||
|
#include <boost/spirit/home/phoenix/object/construct.hpp>
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace qi = boost::spirit::qi;
|
||||||
|
namespace standard_wide = boost::spirit::standard_wide;
|
||||||
|
using standard_wide::space_type;
|
||||||
|
|
||||||
|
struct unicode_impl
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
struct result
|
||||||
|
{
|
||||||
|
typedef UnicodeString type;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit unicode_impl(mapnik::transcoder const& tr)
|
||||||
|
: tr_(tr) {}
|
||||||
|
|
||||||
|
UnicodeString operator()(std::string const& str) const
|
||||||
|
{
|
||||||
|
return tr_.transcode(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::transcoder const& tr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct regex_match_impl
|
||||||
|
{
|
||||||
|
template <typename T0, typename T1>
|
||||||
|
struct result
|
||||||
|
{
|
||||||
|
typedef expr_node type;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit regex_match_impl(mapnik::transcoder const& tr)
|
||||||
|
: tr_(tr) {}
|
||||||
|
|
||||||
|
template <typename T0,typename T1>
|
||||||
|
expr_node operator() (T0 & node, T1 const& pattern) const
|
||||||
|
{
|
||||||
|
return regex_match_node(node,tr_.transcode(pattern.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::transcoder const& tr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct regex_replace_impl
|
||||||
|
{
|
||||||
|
template <typename T0, typename T1, typename T2>
|
||||||
|
struct result
|
||||||
|
{
|
||||||
|
typedef expr_node type;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit regex_replace_impl(mapnik::transcoder const& tr)
|
||||||
|
: tr_(tr) {}
|
||||||
|
|
||||||
|
template <typename T0,typename T1,typename T2>
|
||||||
|
expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const
|
||||||
|
{
|
||||||
|
return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::transcoder const& tr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
||||||
|
{
|
||||||
|
typedef qi::rule<Iterator, expr_node(), space_type> rule_type;
|
||||||
|
|
||||||
|
explicit expression_grammar(mapnik::transcoder const& tr)
|
||||||
|
: expression_grammar::base_type(expr),
|
||||||
|
unicode_(unicode_impl(tr)),
|
||||||
|
regex_match_(regex_match_impl(tr)),
|
||||||
|
regex_replace_(regex_replace_impl(tr))
|
||||||
|
{
|
||||||
|
using boost::phoenix::construct;
|
||||||
|
using qi::_1;
|
||||||
|
using qi::_a;
|
||||||
|
using qi::_b;
|
||||||
|
using qi::_r1;
|
||||||
|
using qi::lexeme;
|
||||||
|
using qi::_val;
|
||||||
|
using qi::lit;
|
||||||
|
using qi::int_;
|
||||||
|
using qi::double_;
|
||||||
|
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")) >> relational_expr [_val == _1])
|
||||||
|
| (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1])
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
regex_match_expr = lit(".match")
|
||||||
|
>> lit('(')
|
||||||
|
>> lit('\'')
|
||||||
|
>> ustring [_val = _1]
|
||||||
|
>> lit('\'')
|
||||||
|
>> lit(')')
|
||||||
|
;
|
||||||
|
|
||||||
|
regex_replace_expr =
|
||||||
|
lit(".replace")
|
||||||
|
>> lit('(')
|
||||||
|
>> lit('\'')
|
||||||
|
>> ustring [_a = _1]
|
||||||
|
>> lit('\'') >> lit(',')
|
||||||
|
>> lit('\'')
|
||||||
|
>> ustring [_b = _1]
|
||||||
|
>> lit('\'')
|
||||||
|
>> 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 = primary_expr [_val = _1]
|
||||||
|
>> *( '*' >> primary_expr [_val *= _1]
|
||||||
|
| '/' >> primary_expr [_val /= _1]
|
||||||
|
| '%' >> primary_expr [_val %= _1]
|
||||||
|
| regex_match_expr[_val = regex_match_(_val, _1)]
|
||||||
|
| regex_replace_expr(_val) [_val = _1]
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
primary_expr = strict_double [_val = _1]
|
||||||
|
| int_ [_val = _1]
|
||||||
|
| lit("true") [_val = true]
|
||||||
|
| lit("false") [_val = false]
|
||||||
|
| '\'' >> ustring [_val = unicode_(_1) ] >> '\''
|
||||||
|
| '[' >> attr [_val = construct<attribute>( _1 ) ] >> ']'
|
||||||
|
| '(' >> expr [_val = _1 ] >> ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
attr %= +(char_ - ']');
|
||||||
|
|
||||||
|
ustring %= lexeme[*(char_-'\'')];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
|
||||||
|
boost::phoenix::function<unicode_impl> unicode_;
|
||||||
|
boost::phoenix::function<regex_match_impl> regex_match_;
|
||||||
|
boost::phoenix::function<regex_replace_impl> regex_replace_;
|
||||||
|
//
|
||||||
|
rule_type expr;
|
||||||
|
rule_type equality_expr;
|
||||||
|
rule_type cond_expr;
|
||||||
|
rule_type relational_expr;
|
||||||
|
rule_type logical_expr;
|
||||||
|
rule_type additive_expr;
|
||||||
|
rule_type multiplicative_expr;
|
||||||
|
rule_type not_expr;
|
||||||
|
rule_type primary_expr;
|
||||||
|
qi::rule<Iterator, std::string() > regex_match_expr;
|
||||||
|
qi::rule<Iterator, expr_node(expr_node), qi::locals<std::string,std::string>, space_type> regex_replace_expr;
|
||||||
|
qi::rule<Iterator, std::string() , space_type> attr;
|
||||||
|
qi::rule<Iterator, std::string() > ustring;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAPNIK_EXPRESSIONS_GRAMMAR_HPP
|
353
include/mapnik/expression_node.hpp
Normal file
353
include/mapnik/expression_node.hpp
Normal file
|
@ -0,0 +1,353 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 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_EXPRESSION_NODE_HPP
|
||||||
|
#define MAPNIK_EXPRESSION_NODE_HPP
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/value.hpp>
|
||||||
|
// boost
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
#include <boost/regex/icu.hpp>
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
struct attribute
|
||||||
|
{
|
||||||
|
std::string name_;
|
||||||
|
explicit attribute(std::string const& name)
|
||||||
|
: name_(name) {}
|
||||||
|
|
||||||
|
template <typename V ,typename F>
|
||||||
|
V value(F const& f) const
|
||||||
|
{
|
||||||
|
return f[name_];
|
||||||
|
}
|
||||||
|
std::string const& name() const { return name_;}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace tags {
|
||||||
|
struct plus
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "+";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct minus
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mult
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "*";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct div
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct mod
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "%";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct less
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "<";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct less_equal
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "<=";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct greater
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return ">";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct greater_equal
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return ">=";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct equal_to
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "=";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct not_equal_to
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "!=";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct logical_not
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return "not ";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct logical_and
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return " and ";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct logical_or
|
||||||
|
{
|
||||||
|
static const char* str()
|
||||||
|
{
|
||||||
|
return " or ";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end operation tags
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Tag> struct binary_node;
|
||||||
|
template <typename Tag> struct unary_node;
|
||||||
|
struct regex_match_node;
|
||||||
|
struct regex_replace_node;
|
||||||
|
|
||||||
|
typedef mapnik::value value_type;
|
||||||
|
|
||||||
|
typedef boost::variant <
|
||||||
|
value_type,
|
||||||
|
attribute,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::plus> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::minus> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::mult> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::div> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::mod> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::less> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::less_equal> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::greater> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::greater_equal> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::equal_to> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::not_equal_to> >,
|
||||||
|
boost::recursive_wrapper<unary_node<tags::logical_not> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::logical_and> >,
|
||||||
|
boost::recursive_wrapper<binary_node<tags::logical_or> >,
|
||||||
|
boost::recursive_wrapper<regex_match_node>,
|
||||||
|
boost::recursive_wrapper<regex_replace_node>
|
||||||
|
> expr_node;
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<expr_node> expression_ptr;
|
||||||
|
|
||||||
|
template <typename Tag> struct make_op;
|
||||||
|
template <> struct make_op<tags::plus> { typedef std::plus<value_type> type;};
|
||||||
|
template <> struct make_op<tags::minus> { typedef std::minus<value_type> type;};
|
||||||
|
template <> struct make_op<tags::mult> { typedef std::multiplies<value_type> type;};
|
||||||
|
template <> struct make_op<tags::div> { typedef std::divides<value_type> type;};
|
||||||
|
template <> struct make_op<tags::mod> { typedef std::modulus<value_type> type;};
|
||||||
|
template <> struct make_op<tags::less> { typedef std::less<value_type> type;};
|
||||||
|
template <> struct make_op<tags::less_equal> { typedef std::less_equal<value_type> type;};
|
||||||
|
template <> struct make_op<tags::greater> { typedef std::greater<value_type> type;};
|
||||||
|
template <> struct make_op<tags::greater_equal> { typedef std::greater_equal<value_type> type;};
|
||||||
|
template <> struct make_op<tags::equal_to> { typedef std::equal_to<value_type> type;};
|
||||||
|
template <> struct make_op<tags::not_equal_to> { typedef std::not_equal_to<value_type> type;};
|
||||||
|
template <> struct make_op<tags::logical_not> { typedef std::logical_not<value_type> type;};
|
||||||
|
template <> struct make_op<tags::logical_and> { typedef std::logical_and<value_type> type;};
|
||||||
|
template <> struct make_op<tags::logical_or> { typedef std::logical_or<value_type> type;};
|
||||||
|
|
||||||
|
template <typename Tag>
|
||||||
|
struct unary_node
|
||||||
|
{
|
||||||
|
unary_node (expr_node const& a)
|
||||||
|
: expr(a) {}
|
||||||
|
|
||||||
|
static const char* type()
|
||||||
|
{
|
||||||
|
return Tag::str();
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_node expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tag>
|
||||||
|
struct binary_node
|
||||||
|
{
|
||||||
|
binary_node(expr_node const& a, expr_node const& b)
|
||||||
|
: left(a),
|
||||||
|
right(b) {}
|
||||||
|
|
||||||
|
static const char* type()
|
||||||
|
{
|
||||||
|
return Tag::str();
|
||||||
|
}
|
||||||
|
expr_node left,right;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct regex_match_node
|
||||||
|
{
|
||||||
|
regex_match_node (expr_node const& a, UnicodeString const& ustr)
|
||||||
|
: expr(a),
|
||||||
|
pattern(boost::make_u32regex(ustr)) {}
|
||||||
|
|
||||||
|
expr_node expr;
|
||||||
|
boost::u32regex pattern;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct regex_replace_node
|
||||||
|
{
|
||||||
|
regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f)
|
||||||
|
: expr(a),
|
||||||
|
pattern(boost::make_u32regex(ustr)),
|
||||||
|
format(f) {}
|
||||||
|
|
||||||
|
expr_node expr;
|
||||||
|
boost::u32regex pattern;
|
||||||
|
UnicodeString format;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct function_call
|
||||||
|
{
|
||||||
|
template<typename Fun>
|
||||||
|
explicit function_call (expr_node const a, Fun f)
|
||||||
|
: expr(a),
|
||||||
|
call_(f) {}
|
||||||
|
|
||||||
|
expr_node expr;
|
||||||
|
boost::function<value_type(value_type)> call_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ops
|
||||||
|
|
||||||
|
inline expr_node & operator += ( expr_node &left ,const expr_node &right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::plus>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator -= ( expr_node &left ,const expr_node &right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::minus>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator *= ( expr_node &left ,const expr_node &right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::mult>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator /= ( expr_node &left ,const expr_node &right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::div>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator %= ( expr_node &left ,const expr_node &right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::mod>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator < ( expr_node &left, expr_node const& right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::less>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator <= ( expr_node &left, expr_node const& right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::less_equal>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator > ( expr_node &left, expr_node const& right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::greater>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator >= ( expr_node &left, expr_node const& right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::greater_equal>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator == ( expr_node &left, expr_node const& right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::equal_to>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator != ( expr_node &left, expr_node const& right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::not_equal_to>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator ! (expr_node & expr)
|
||||||
|
{
|
||||||
|
return expr = unary_node<tags::logical_not>(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator && ( expr_node &left, expr_node const& right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::logical_and>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline expr_node & operator || ( expr_node &left, expr_node const& right)
|
||||||
|
{
|
||||||
|
return left = binary_node<tags::logical_or>(left,right);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MAPNIK_EXPRESSION_NODE_HPP
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Artem Pavlenko
|
* Copyright (C) 2009 Artem Pavlenko
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -22,27 +22,18 @@
|
||||||
|
|
||||||
//$Id$
|
//$Id$
|
||||||
|
|
||||||
#ifndef FILTER_VISITOR_HPP
|
#ifndef MAPNIK_EXPRESSION_STRING_HPP
|
||||||
#define FILTER_VISITOR_HPP
|
#define MAPNIK_EXPRESSION_STRING_HPP
|
||||||
|
|
||||||
#include <mapnik/filter.hpp>
|
// mapnik
|
||||||
#include <mapnik/expression.hpp>
|
#include <mapnik/config.hpp>
|
||||||
|
#include <mapnik/expression_node.hpp>
|
||||||
|
// stl
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
template <typename FeatureT> class filter;
|
MAPNIK_DECL std::string to_expression_string(expr_node const& );
|
||||||
template <typename FeatureT> class expression;
|
|
||||||
template <typename FeatureT> class expression;
|
|
||||||
template <typename Feature,template <typename> class Filter> class rule;
|
|
||||||
template <typename FeatureT>
|
|
||||||
class filter_visitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void visit(filter<FeatureT>& filter)=0;
|
|
||||||
virtual void visit(expression<FeatureT>&)=0;
|
|
||||||
virtual void visit(rule<FeatureT,filter> const& r)=0;
|
|
||||||
virtual ~filter_visitor() {}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //FILTER_VISITOR_HPP
|
#endif // MAPNIK_EXPRESSION_STRING_HPP
|
|
@ -43,130 +43,130 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
typedef boost::shared_ptr<raster> raster_ptr;
|
typedef boost::shared_ptr<raster> raster_ptr;
|
||||||
typedef boost::associative_property_map<
|
typedef boost::associative_property_map<
|
||||||
std::map<std::string,value
|
std::map<std::string,value
|
||||||
> > properties;
|
> > properties;
|
||||||
|
|
||||||
template <typename T1,typename T2>
|
template <typename T1,typename T2>
|
||||||
struct feature : public properties,
|
struct feature : public properties,
|
||||||
private boost::noncopyable
|
private boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef T1 geometry_type;
|
typedef T1 geometry_type;
|
||||||
typedef T2 raster_type;
|
typedef T2 raster_type;
|
||||||
typedef std::map<std::string,value>::value_type value_type;
|
typedef std::map<std::string,value>::value_type value_type;
|
||||||
typedef std::map<std::string,value>::size_type size_type;
|
typedef std::map<std::string,value>::size_type size_type;
|
||||||
|
typedef std::map<std::string,value>::difference_type difference_type;
|
||||||
private:
|
|
||||||
int id_;
|
private:
|
||||||
boost::ptr_vector<geometry_type> geom_cont_;
|
int id_;
|
||||||
raster_type raster_;
|
boost::ptr_vector<geometry_type> geom_cont_;
|
||||||
std::map<std::string,value> props_;
|
raster_type raster_;
|
||||||
public:
|
std::map<std::string,value> props_;
|
||||||
typedef std::map<std::string,value>::iterator iterator;
|
public:
|
||||||
explicit feature(int id)
|
typedef std::map<std::string,value>::iterator iterator;
|
||||||
: properties(props_),
|
explicit feature(int id)
|
||||||
id_(id),
|
: properties(props_),
|
||||||
geom_cont_(),
|
id_(id),
|
||||||
raster_() {}
|
geom_cont_(),
|
||||||
|
raster_() {}
|
||||||
//feature(int id,const geometry_type& geom)
|
|
||||||
// : properties(props_),
|
int id() const
|
||||||
// id_(id),
|
{
|
||||||
// geom_(geom),
|
return id_;
|
||||||
// raster_() {}
|
}
|
||||||
|
|
||||||
int id() const
|
void add_geometry(geometry_type * geom)
|
||||||
{
|
{
|
||||||
return id_;
|
geom_cont_.push_back(geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_geometry(geometry_type * geom)
|
unsigned num_geometries() const
|
||||||
{
|
{
|
||||||
geom_cont_.push_back(geom);
|
return geom_cont_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned num_geometries() const
|
geometry_type const& get_geometry(unsigned index) const
|
||||||
{
|
{
|
||||||
return geom_cont_.size();
|
return geom_cont_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
geometry_type const& get_geometry(unsigned index) const
|
geometry_type& get_geometry(unsigned index)
|
||||||
{
|
{
|
||||||
return geom_cont_[index];
|
return geom_cont_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
geometry_type& get_geometry(unsigned index)
|
box2d<double> envelope() const
|
||||||
{
|
{
|
||||||
return geom_cont_[index];
|
box2d<double> result;
|
||||||
}
|
for (unsigned i=0;i<num_geometries();++i)
|
||||||
|
{
|
||||||
Envelope<double> envelope() const
|
geometry2d const& geom = get_geometry(i);
|
||||||
{
|
if (i==0)
|
||||||
Envelope<double> result;
|
{
|
||||||
for (unsigned i=0;i<num_geometries();++i)
|
box2d<double> box = geom.envelope();
|
||||||
{
|
result.init(box.minx(),box.miny(),box.maxx(),box.maxy());
|
||||||
geometry2d const& geom = get_geometry(i);
|
}
|
||||||
if (i==0)
|
else
|
||||||
{
|
{
|
||||||
Envelope<double> box = geom.envelope();
|
result.expand_to_include(geom.envelope());
|
||||||
result.init(box.minx(),box.miny(),box.maxx(),box.maxy());
|
}
|
||||||
}
|
}
|
||||||
else
|
return result;
|
||||||
{
|
}
|
||||||
result.expand_to_include(geom.envelope());
|
|
||||||
}
|
const raster_type& get_raster() const
|
||||||
}
|
{
|
||||||
return result;
|
return raster_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const raster_type& get_raster() const
|
void set_raster(raster_type const& raster)
|
||||||
{
|
{
|
||||||
return raster_;
|
raster_=raster;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_raster(raster_type const& raster)
|
std::map<std::string,value> const& props() const
|
||||||
{
|
{
|
||||||
raster_=raster;
|
return props_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string,value> const& props() const
|
std::map<std::string,value>& props()
|
||||||
{
|
{
|
||||||
return props_;
|
return props_;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator begin() const
|
iterator begin()
|
||||||
{
|
{
|
||||||
return props_.begin();
|
return props_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end() const
|
iterator end()
|
||||||
{
|
{
|
||||||
return props_.end();
|
return props_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_string() const
|
std::string to_string() const
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "feature (" << std::endl;
|
ss << "feature (" << std::endl;
|
||||||
for (std::map<std::string,value>::const_iterator itr=props_.begin();
|
for (std::map<std::string,value>::const_iterator itr=props_.begin();
|
||||||
itr != props_.end();++itr)
|
itr != props_.end();++itr)
|
||||||
{
|
{
|
||||||
ss << " " << itr->first << ":" << itr->second << std::endl;
|
ss << " " << itr->first << ":" << itr->second << std::endl;
|
||||||
}
|
}
|
||||||
ss << ")" << std::endl;
|
ss << ")" << std::endl;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef feature<geometry2d,raster_ptr> Feature;
|
typedef feature<geometry2d,raster_ptr> Feature;
|
||||||
|
|
||||||
inline std::ostream& operator<< (std::ostream & out,Feature const& f)
|
inline std::ostream& operator<< (std::ostream & out,Feature const& f)
|
||||||
{
|
{
|
||||||
out << f.to_string();
|
out << f.to_string();
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //FEATURE_HPP
|
#endif //FEATURE_HPP
|
||||||
|
|
|
@ -26,234 +26,229 @@
|
||||||
#define FEATURE_STYLE_PROCESSOR_HPP
|
#define FEATURE_STYLE_PROCESSOR_HPP
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/envelope.hpp>
|
#include <mapnik/box2d.hpp>
|
||||||
#include <mapnik/datasource.hpp>
|
#include <mapnik/datasource.hpp>
|
||||||
#include <mapnik/layer.hpp>
|
#include <mapnik/layer.hpp>
|
||||||
#include <mapnik/map.hpp>
|
#include <mapnik/map.hpp>
|
||||||
#include <mapnik/attribute_collector.hpp>
|
#include <mapnik/attribute_collector.hpp>
|
||||||
|
#include <mapnik/expression_evaluator.hpp>
|
||||||
#include <mapnik/utils.hpp>
|
#include <mapnik/utils.hpp>
|
||||||
#include <mapnik/projection.hpp>
|
#include <mapnik/projection.hpp>
|
||||||
#include <mapnik/scale_denominator.hpp>
|
#include <mapnik/scale_denominator.hpp>
|
||||||
|
|
||||||
/*
|
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
#include <mapnik/wall_clock_timer.hpp>
|
//#include <mapnik/wall_clock_timer.hpp>
|
||||||
#endif
|
#endif
|
||||||
*/
|
|
||||||
|
|
||||||
//stl
|
//stl
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
template <typename Processor>
|
template <typename Processor>
|
||||||
class feature_style_processor
|
class feature_style_processor
|
||||||
{
|
{
|
||||||
struct symbol_dispatch : public boost::static_visitor<>
|
struct symbol_dispatch : public boost::static_visitor<>
|
||||||
{
|
{
|
||||||
symbol_dispatch (Processor & output,
|
symbol_dispatch (Processor & output,
|
||||||
Feature const& f,
|
Feature const& f,
|
||||||
proj_transform const& prj_trans)
|
proj_transform const& prj_trans)
|
||||||
: output_(output),
|
: output_(output),
|
||||||
f_(f),
|
f_(f),
|
||||||
prj_trans_(prj_trans) {}
|
prj_trans_(prj_trans) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator () (T const& sym) const
|
void operator () (T const& sym) const
|
||||||
{
|
{
|
||||||
output_.process(sym,f_,prj_trans_);
|
output_.process(sym,f_,prj_trans_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Processor & output_;
|
Processor & output_;
|
||||||
Feature const& f_;
|
Feature const& f_;
|
||||||
proj_transform const& prj_trans_;
|
proj_transform const& prj_trans_;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
feature_style_processor(Map const& m)
|
feature_style_processor(Map const& m)
|
||||||
: m_(m) {}
|
: m_(m) {}
|
||||||
|
|
||||||
void apply()
|
void apply()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
mapnik::wall_clock_progress_timer t(std::clog, "map rendering took: ");
|
//mapnik::wall_clock_progress_timer t(std::clog, "map rendering took: ");
|
||||||
#endif
|
#endif
|
||||||
*/
|
Processor & p = static_cast<Processor&>(*this);
|
||||||
Processor & p = static_cast<Processor&>(*this);
|
p.start_map_processing(m_);
|
||||||
p.start_map_processing(m_);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
projection proj(m_.srs()); // map projection
|
projection proj(m_.srs()); // map projection
|
||||||
double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
|
double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
std::clog << "scale denominator = " << scale_denom << "\n";
|
std::clog << "scale denominator = " << scale_denom << "\n";
|
||||||
#endif
|
#endif
|
||||||
std::vector<Layer>::const_iterator itr = m_.layers().begin();
|
std::vector<layer>::const_iterator itr = m_.layers().begin();
|
||||||
std::vector<Layer>::const_iterator end = m_.layers().end();
|
std::vector<layer>::const_iterator end = m_.layers().end();
|
||||||
|
|
||||||
while (itr != end)
|
while (itr != end)
|
||||||
{
|
{
|
||||||
if (itr->isVisible(scale_denom))
|
if (itr->isVisible(scale_denom))
|
||||||
{
|
{
|
||||||
apply_to_layer(*itr, p, proj, scale_denom);
|
apply_to_layer(*itr, p, proj, scale_denom);
|
||||||
}
|
}
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (proj_init_error& ex)
|
catch (proj_init_error& ex)
|
||||||
{
|
{
|
||||||
std::clog << "proj_init_error:" << ex.what() << "\n";
|
std::clog << "proj_init_error:" << ex.what() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
p.end_map_processing(m_);
|
p.end_map_processing(m_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void apply_to_layer(Layer const& lay, Processor & p,
|
void apply_to_layer(layer const& lay, Processor & p,
|
||||||
projection const& proj0,double scale_denom)
|
projection const& proj0,double scale_denom)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
wall_clock_progress_timer timer(clog, "end layer rendering: ");
|
//wall_clock_progress_timer timer(clog, "end layer rendering: ");
|
||||||
#endif
|
#endif
|
||||||
*/
|
p.start_layer_processing(lay);
|
||||||
p.start_layer_processing(lay);
|
boost::shared_ptr<datasource> ds=lay.datasource();
|
||||||
boost::shared_ptr<datasource> ds=lay.datasource();
|
if (ds)
|
||||||
if (ds)
|
{
|
||||||
{
|
box2d<double> ext = m_.get_buffered_extent();
|
||||||
Envelope<double> ext = m_.get_buffered_extent();
|
projection proj1(lay.srs());
|
||||||
projection proj1(lay.srs());
|
proj_transform prj_trans(proj0,proj1);
|
||||||
proj_transform prj_trans(proj0,proj1);
|
|
||||||
|
|
||||||
double mx0 = ext.minx();
|
double mx0 = ext.minx();
|
||||||
double my0 = ext.miny();
|
double my0 = ext.miny();
|
||||||
double mz0 = 0.0;
|
double mz0 = 0.0;
|
||||||
double mx1 = ext.maxx();
|
double mx1 = ext.maxx();
|
||||||
double my1 = ext.maxy();
|
double my1 = ext.maxy();
|
||||||
double mz1 = 0.0;
|
double mz1 = 0.0;
|
||||||
|
|
||||||
// project main map projection into layers extent
|
// project main map projection into layers extent
|
||||||
prj_trans.forward(mx0,my0,mz0);
|
prj_trans.forward(mx0,my0,mz0);
|
||||||
prj_trans.forward(mx1,my1,mz1);
|
prj_trans.forward(mx1,my1,mz1);
|
||||||
|
|
||||||
// if no intersection then nothing to do for layer
|
// if no intersection then nothing to do for layer
|
||||||
Envelope<double> layer_ext = lay.envelope();
|
box2d<double> layer_ext = lay.envelope();
|
||||||
if ( mx0 > layer_ext.maxx() || mx1 < layer_ext.minx() || my0 > layer_ext.maxy() || my1 < layer_ext.miny() )
|
if ( mx0 > layer_ext.maxx() || mx1 < layer_ext.minx() || my0 > layer_ext.maxy() || my1 < layer_ext.miny() )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip query bbox
|
// clip query bbox
|
||||||
mx0 = std::max(layer_ext.minx(),mx0);
|
mx0 = std::max(layer_ext.minx(),mx0);
|
||||||
my0 = std::max(layer_ext.miny(),my0);
|
my0 = std::max(layer_ext.miny(),my0);
|
||||||
mx1 = std::min(layer_ext.maxx(),mx1);
|
mx1 = std::min(layer_ext.maxx(),mx1);
|
||||||
my1 = std::min(layer_ext.maxy(),my1);
|
my1 = std::min(layer_ext.maxy(),my1);
|
||||||
|
|
||||||
Envelope<double> bbox(mx0,my0,mx1,my1);
|
box2d<double> bbox(mx0,my0,mx1,my1);
|
||||||
|
|
||||||
double resolution = m_.getWidth()/bbox.width();
|
double resolution = m_.getWidth()/bbox.width();
|
||||||
query q(bbox,resolution,scale_denom); //BBOX query
|
query q(bbox,resolution,scale_denom); //BBOX query
|
||||||
|
|
||||||
std::vector<std::string> const& style_names = lay.styles();
|
std::vector<std::string> const& style_names = lay.styles();
|
||||||
std::vector<std::string>::const_iterator stylesIter = style_names.begin();
|
std::vector<std::string>::const_iterator stylesIter = style_names.begin();
|
||||||
std::vector<std::string>::const_iterator stylesEnd = style_names.end();
|
std::vector<std::string>::const_iterator stylesEnd = style_names.end();
|
||||||
for (;stylesIter != stylesEnd; ++stylesIter)
|
for (;stylesIter != stylesEnd; ++stylesIter)
|
||||||
{
|
{
|
||||||
std::set<std::string> names;
|
std::set<std::string> names;
|
||||||
attribute_collector<Feature> collector(names);
|
attribute_collector collector(names);
|
||||||
std::vector<rule_type*> if_rules;
|
std::vector<rule_type*> if_rules;
|
||||||
std::vector<rule_type*> else_rules;
|
std::vector<rule_type*> else_rules;
|
||||||
|
|
||||||
bool active_rules=false;
|
bool active_rules=false;
|
||||||
|
|
||||||
boost::optional<feature_type_style const&> style=m_.find_style(*stylesIter);
|
boost::optional<feature_type_style const&> style=m_.find_style(*stylesIter);
|
||||||
if (!style) continue;
|
if (!style) continue;
|
||||||
|
|
||||||
const std::vector<rule_type>& rules=(*style).get_rules();
|
const std::vector<rule_type>& rules=(*style).get_rules();
|
||||||
std::vector<rule_type>::const_iterator ruleIter=rules.begin();
|
std::vector<rule_type>::const_iterator ruleIter=rules.begin();
|
||||||
std::vector<rule_type>::const_iterator ruleEnd=rules.end();
|
std::vector<rule_type>::const_iterator ruleEnd=rules.end();
|
||||||
|
|
||||||
for (;ruleIter!=ruleEnd;++ruleIter)
|
for (;ruleIter!=ruleEnd;++ruleIter)
|
||||||
{
|
{
|
||||||
if (ruleIter->active(scale_denom))
|
if (ruleIter->active(scale_denom))
|
||||||
{
|
{
|
||||||
active_rules=true;
|
active_rules=true;
|
||||||
ruleIter->accept(collector);
|
// collect unique attribute names
|
||||||
|
collector(*ruleIter);
|
||||||
if (ruleIter->has_else_filter())
|
if (ruleIter->has_else_filter())
|
||||||
{
|
{
|
||||||
else_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
|
else_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
|
if_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::set<std::string>::const_iterator namesIter=names.begin();
|
std::set<std::string>::const_iterator namesIter=names.begin();
|
||||||
std::set<std::string>::const_iterator namesEnd =names.end();
|
std::set<std::string>::const_iterator namesEnd =names.end();
|
||||||
|
|
||||||
// push all property names
|
// push all property names
|
||||||
for (;namesIter!=namesEnd;++namesIter)
|
for (;namesIter!=namesEnd;++namesIter)
|
||||||
{
|
{
|
||||||
q.add_property_name(*namesIter);
|
q.add_property_name(*namesIter);
|
||||||
}
|
}
|
||||||
if (active_rules)
|
if (active_rules)
|
||||||
{
|
{
|
||||||
featureset_ptr fs=ds->features(q);
|
featureset_ptr fs=ds->features(q);
|
||||||
if (fs)
|
if (fs)
|
||||||
{
|
{
|
||||||
feature_ptr feature;
|
feature_ptr feature;
|
||||||
while ((feature = fs->next()))
|
while ((feature = fs->next()))
|
||||||
{
|
{
|
||||||
bool do_else=true;
|
bool do_else=true;
|
||||||
std::vector<rule_type*>::const_iterator itr=if_rules.begin();
|
std::vector<rule_type*>::const_iterator itr=if_rules.begin();
|
||||||
std::vector<rule_type*>::const_iterator end=if_rules.end();
|
std::vector<rule_type*>::const_iterator end=if_rules.end();
|
||||||
for (;itr != end;++itr)
|
for (;itr != end;++itr)
|
||||||
{
|
{
|
||||||
filter_ptr const& filter=(*itr)->get_filter();
|
expression_ptr const& expr=(*itr)->get_filter();
|
||||||
if (filter->pass(*feature))
|
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
|
||||||
{
|
if (result.to_bool())
|
||||||
do_else=false;
|
{
|
||||||
const symbolizers& symbols = (*itr)->get_symbolizers();
|
do_else=false;
|
||||||
symbolizers::const_iterator symIter=symbols.begin();
|
const rule_type::symbolizers& symbols = (*itr)->get_symbolizers();
|
||||||
symbolizers::const_iterator symEnd =symbols.end();
|
rule_type::symbolizers::const_iterator symIter=symbols.begin();
|
||||||
for (;symIter != symEnd;++symIter)
|
rule_type::symbolizers::const_iterator symEnd =symbols.end();
|
||||||
{
|
for (;symIter != symEnd;++symIter)
|
||||||
boost::apply_visitor
|
{
|
||||||
(symbol_dispatch(p,*feature,prj_trans),*symIter);
|
boost::apply_visitor
|
||||||
}
|
(symbol_dispatch(p,*feature,prj_trans),*symIter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (do_else)
|
}
|
||||||
{
|
if (do_else)
|
||||||
//else filter
|
{
|
||||||
std::vector<rule_type*>::const_iterator itr=
|
//else filter
|
||||||
else_rules.begin();
|
std::vector<rule_type*>::const_iterator itr=
|
||||||
std::vector<rule_type*>::const_iterator end=
|
else_rules.begin();
|
||||||
else_rules.end();
|
std::vector<rule_type*>::const_iterator end=
|
||||||
for (;itr != end;++itr)
|
else_rules.end();
|
||||||
{
|
for (;itr != end;++itr)
|
||||||
const symbolizers& symbols = (*itr)->get_symbolizers();
|
{
|
||||||
symbolizers::const_iterator symIter= symbols.begin();
|
const rule_type::symbolizers& symbols = (*itr)->get_symbolizers();
|
||||||
symbolizers::const_iterator symEnd = symbols.end();
|
rule_type::symbolizers::const_iterator symIter= symbols.begin();
|
||||||
|
rule_type::symbolizers::const_iterator symEnd = symbols.end();
|
||||||
|
|
||||||
for (;symIter!=symEnd;++symIter)
|
for (;symIter!=symEnd;++symIter)
|
||||||
{
|
{
|
||||||
boost::apply_visitor
|
boost::apply_visitor
|
||||||
(symbol_dispatch(p,*feature,prj_trans),*symIter);
|
(symbol_dispatch(p,*feature,prj_trans),*symIter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.end_layer_processing(lay);
|
p.end_layer_processing(lay);
|
||||||
}
|
}
|
||||||
Map const& m_;
|
Map const& m_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //FEATURE_STYLE_PROCESSOR_HPP
|
#endif //FEATURE_STYLE_PROCESSOR_HPP
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
//$Id$
|
|
||||||
|
|
||||||
#ifndef FILTER_HPP
|
|
||||||
#define FILTER_HPP
|
|
||||||
|
|
||||||
#include <mapnik/config.hpp>
|
|
||||||
#include <mapnik/feature.hpp>
|
|
||||||
|
|
||||||
namespace mapnik
|
|
||||||
{
|
|
||||||
template <typename FeatureT> class filter_visitor;
|
|
||||||
template <typename FeatureT>
|
|
||||||
class MAPNIK_DECL filter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual bool pass(const FeatureT& feature) const=0;
|
|
||||||
virtual filter<FeatureT>* clone() const=0;
|
|
||||||
virtual void accept(filter_visitor<FeatureT>& v) = 0;
|
|
||||||
virtual std::string to_string() const=0;
|
|
||||||
virtual ~filter() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<filter<Feature> > filter_ptr;
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
class all_filter : public filter<FeatureT>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool pass (const FeatureT&) const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
filter<FeatureT>* clone() const
|
|
||||||
{
|
|
||||||
return new all_filter<FeatureT>;
|
|
||||||
}
|
|
||||||
std::string to_string() const
|
|
||||||
{
|
|
||||||
return "true";
|
|
||||||
}
|
|
||||||
void accept(filter_visitor<FeatureT>&) {}
|
|
||||||
virtual ~all_filter() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
class none_filter : public filter<FeatureT>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool pass (const FeatureT&) const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
filter<FeatureT>* clone() const
|
|
||||||
{
|
|
||||||
return new none_filter<FeatureT>;
|
|
||||||
}
|
|
||||||
std::string to_string() const
|
|
||||||
{
|
|
||||||
return "false";
|
|
||||||
}
|
|
||||||
void accept(filter_visitor<FeatureT>&) {}
|
|
||||||
virtual ~none_filter() {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //FILTER_HPP
|
|
|
@ -1,67 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
//$Id$
|
|
||||||
|
|
||||||
#ifndef FILTER_TO_STRING_HPP
|
|
||||||
#define FILTER_TO_STRING_HPP
|
|
||||||
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/filter.hpp>
|
|
||||||
#include <mapnik/expression.hpp>
|
|
||||||
// stl
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
namespace mapnik
|
|
||||||
{
|
|
||||||
template <typename FeatureT>
|
|
||||||
class filter_to_string : public filter_visitor<FeatureT>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string text_;
|
|
||||||
public:
|
|
||||||
filter_to_string() {}
|
|
||||||
void visit(filter<FeatureT>& /*filter*/)
|
|
||||||
{
|
|
||||||
//not interested
|
|
||||||
}
|
|
||||||
void visit(expression<FeatureT>& exp)
|
|
||||||
{
|
|
||||||
property<FeatureT>* pf;
|
|
||||||
if ((pf = dynamic_cast<property<FeatureT>*>(&exp)))
|
|
||||||
{
|
|
||||||
names_.insert(pf->name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string const& text() const
|
|
||||||
{
|
|
||||||
return text_;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~filter_to_string() {}
|
|
||||||
private:
|
|
||||||
filter_to_string(filter_to_string const&);
|
|
||||||
filter_to_string& operator=(filter_to_string const&);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //FILTER_TO_STRING
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Artem Pavlenko
|
* Copyright (C) 2006-2009 Artem Pavlenko
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -22,51 +22,18 @@
|
||||||
|
|
||||||
//$Id$
|
//$Id$
|
||||||
|
|
||||||
#ifndef FILTER_FACTORY_HPP
|
#ifndef MAPNIK_FILTER_FACTORY_HPP
|
||||||
#define FILTER_FACTORY_HPP
|
#define MAPNIK_FILTER_FACTORY_HPP
|
||||||
|
|
||||||
#include <mapnik/config_error.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/filter_parser.hpp>
|
#include <mapnik/expression_grammar.hpp>
|
||||||
#include <mapnik/unicode.hpp>
|
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
using std::string;
|
|
||||||
|
MAPNIK_DECL expression_ptr parse_expression (std::string const& wkt, std::string const& encoding);
|
||||||
template<typename FeatureT>
|
MAPNIK_DECL expression_ptr parse_expression (std::string const& wkt);
|
||||||
class MAPNIK_DECL filter_factory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static filter_ptr compile(string const& str,transcoder const& tr)
|
|
||||||
{
|
|
||||||
stack<shared_ptr<filter<FeatureT> > > filters;
|
|
||||||
stack<shared_ptr<expression<FeatureT> > > exps;
|
|
||||||
filter_grammar<FeatureT> grammar(filters,exps,tr);
|
|
||||||
parse_info<std::string::const_iterator> info = parse(str.begin(), str.end(), grammar, space_p);
|
|
||||||
if ( !info.full)
|
|
||||||
{
|
|
||||||
std::ostringstream os;
|
|
||||||
os << "Failed to parse filter expression:\n"
|
|
||||||
<< str << "\nParsing aborted at '" << *info.stop << "'";
|
|
||||||
|
|
||||||
throw config_error( os.str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! filters.empty())
|
|
||||||
{
|
|
||||||
return filters.top();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// XXX: do we ever get here? [DS]
|
|
||||||
return filter_ptr(new none_filter<FeatureT>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
MAPNIK_DECL filter_ptr create_filter (std::string const& wkt, std::string const& encoding);
|
|
||||||
MAPNIK_DECL filter_ptr create_filter (std::string const& wkt);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //FILTER_FACTORY_HPP
|
#endif //MAPNIK_FILTER_FACTORY_HPP
|
||||||
|
|
|
@ -1,548 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
//$Id$
|
|
||||||
|
|
||||||
#ifndef FILTER_PARSER_HPP
|
|
||||||
#define FILTER_PARSER_HPP
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/value.hpp>
|
|
||||||
#include <mapnik/unicode.hpp>
|
|
||||||
#include <mapnik/comparison.hpp>
|
|
||||||
#include <mapnik/math_expr.hpp>
|
|
||||||
#include <mapnik/expression.hpp>
|
|
||||||
#include <mapnik/filter.hpp>
|
|
||||||
#include <mapnik/regex_filter.hpp>
|
|
||||||
#include <mapnik/boolean_filter.hpp>
|
|
||||||
#include <mapnik/logical.hpp>
|
|
||||||
|
|
||||||
// boost
|
|
||||||
|
|
||||||
// XML Debugging output
|
|
||||||
#ifdef MAPNIK_XML_DEBUG
|
|
||||||
#define BOOST_SPIRIT_DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
|
|
||||||
#if BOOST_VERSION < 103800
|
|
||||||
#include <boost/spirit/core.hpp>
|
|
||||||
#include <boost/spirit/symbols.hpp>
|
|
||||||
#include <boost/spirit/utility/confix.hpp>
|
|
||||||
#include <boost/spirit/utility/escape_char.hpp>
|
|
||||||
#include <boost/spirit/utility/chset.hpp>
|
|
||||||
#else
|
|
||||||
#define BOOST_SPIRIT_USE_OLD_NAMESPACE
|
|
||||||
#include <boost/spirit/include/classic_core.hpp>
|
|
||||||
#include <boost/spirit/include/classic_symbols.hpp>
|
|
||||||
#include <boost/spirit/include/classic_confix.hpp>
|
|
||||||
#include <boost/spirit/include/classic_escape_char.hpp>
|
|
||||||
#include <boost/spirit/include/classic_chset.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// stl
|
|
||||||
#include <stack>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace boost::spirit;
|
|
||||||
using boost::shared_ptr;
|
|
||||||
|
|
||||||
namespace mapnik
|
|
||||||
{
|
|
||||||
using std::string;
|
|
||||||
using std::clog;
|
|
||||||
using std::stack;
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct push_boolean
|
|
||||||
{
|
|
||||||
push_boolean(stack<shared_ptr<expression<FeatureT> > >& exprs)
|
|
||||||
: exprs_(exprs) {}
|
|
||||||
|
|
||||||
void operator() (std::string const& val) const
|
|
||||||
{
|
|
||||||
if (val == "true")
|
|
||||||
exprs_.push(shared_ptr<expression<FeatureT> >
|
|
||||||
( new literal<FeatureT>(true)));
|
|
||||||
else if (val == "false")
|
|
||||||
exprs_.push(shared_ptr<expression<FeatureT> >
|
|
||||||
( new literal<FeatureT>(false)));
|
|
||||||
}
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct push_integer
|
|
||||||
{
|
|
||||||
push_integer(stack<shared_ptr<expression<FeatureT> > >& exprs)
|
|
||||||
: exprs_(exprs) {}
|
|
||||||
|
|
||||||
void operator() (int val) const
|
|
||||||
{
|
|
||||||
exprs_.push(shared_ptr<expression<FeatureT> >
|
|
||||||
( new literal<FeatureT>(val)));
|
|
||||||
}
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct push_real
|
|
||||||
{
|
|
||||||
push_real(stack<shared_ptr<expression<FeatureT> > >& exprs)
|
|
||||||
: exprs_(exprs) {}
|
|
||||||
void operator() (double val) const
|
|
||||||
{
|
|
||||||
exprs_.push(shared_ptr<expression<FeatureT> >(new literal<FeatureT>(val)));
|
|
||||||
}
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct push_string
|
|
||||||
{
|
|
||||||
push_string(stack<shared_ptr<expression<FeatureT> > >& exprs, transcoder const& tr)
|
|
||||||
: exprs_(exprs),
|
|
||||||
tr_(tr) {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
|
||||||
void operator() (Iter start,Iter end) const
|
|
||||||
{
|
|
||||||
UnicodeString unicode = tr_.transcode(std::string(start,end).c_str());
|
|
||||||
exprs_.push(shared_ptr<expression<FeatureT> >(new literal<FeatureT>(unicode)));
|
|
||||||
}
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_;
|
|
||||||
transcoder const& tr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct push_property
|
|
||||||
{
|
|
||||||
push_property(stack<shared_ptr<expression<FeatureT> > >& exprs)
|
|
||||||
: exprs_(exprs) {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
|
||||||
void operator() (Iter start,Iter end) const
|
|
||||||
{
|
|
||||||
string str(start,end);
|
|
||||||
exprs_.push(shared_ptr<expression<FeatureT> >(new property<FeatureT>(str)));
|
|
||||||
}
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT,typename Op>
|
|
||||||
struct compose_expression
|
|
||||||
{
|
|
||||||
compose_expression(stack<shared_ptr<expression<FeatureT> > >& exprs)
|
|
||||||
: exprs_(exprs) {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
|
||||||
void operator() (Iter,Iter) const
|
|
||||||
{
|
|
||||||
if (exprs_.size()>=2)
|
|
||||||
{
|
|
||||||
shared_ptr<expression<FeatureT> > right = exprs_.top();
|
|
||||||
exprs_.pop();
|
|
||||||
shared_ptr<expression<FeatureT> > left = exprs_.top();
|
|
||||||
exprs_.pop();
|
|
||||||
if (left && right)
|
|
||||||
{
|
|
||||||
exprs_.push(shared_ptr<expression<FeatureT> >
|
|
||||||
(new mapnik::math_expr_b<FeatureT,Op>(*left,*right)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct compose_regex
|
|
||||||
{
|
|
||||||
compose_regex(stack<shared_ptr<filter<FeatureT> > >& filters,
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs)
|
|
||||||
: filters_(filters),exprs_(exprs) {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
|
||||||
void operator() (Iter start,Iter end) const
|
|
||||||
{
|
|
||||||
if (exprs_.size()>=1)
|
|
||||||
{
|
|
||||||
shared_ptr<expression<FeatureT> > exp = exprs_.top();
|
|
||||||
exprs_.pop();
|
|
||||||
if (exp)
|
|
||||||
{
|
|
||||||
std::string pattern(start,end);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
filters_.push(shared_ptr<filter<FeatureT> >
|
|
||||||
(new regex_filter<FeatureT>(*exp,pattern)));
|
|
||||||
}
|
|
||||||
catch (...)//boost::regex_error& ex)
|
|
||||||
{
|
|
||||||
clog<<"error\n";//ex.what()<<"\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack<shared_ptr<filter<FeatureT> > >& filters_;
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename FeatureT,typename Op>
|
|
||||||
struct compose_filter
|
|
||||||
{
|
|
||||||
compose_filter(stack<shared_ptr<filter<FeatureT> > >& filters,
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs)
|
|
||||||
: filters_(filters),exprs_(exprs) {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
|
||||||
void operator() (Iter,Iter) const
|
|
||||||
{
|
|
||||||
if (exprs_.size()>=2)
|
|
||||||
{
|
|
||||||
shared_ptr<expression<FeatureT> > right = exprs_.top();
|
|
||||||
exprs_.pop();
|
|
||||||
shared_ptr<expression<FeatureT> > left = exprs_.top();
|
|
||||||
exprs_.pop();
|
|
||||||
if (left && right)
|
|
||||||
{
|
|
||||||
filters_.push(shared_ptr<filter<FeatureT> >(new compare_filter<FeatureT,Op>(*left,*right)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack<shared_ptr<filter<FeatureT> > >& filters_;
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct compose_boolean_filter
|
|
||||||
{
|
|
||||||
compose_boolean_filter(stack<shared_ptr<filter<FeatureT> > >& filters,
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs)
|
|
||||||
: filters_(filters),exprs_(exprs) {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
|
||||||
void operator() (Iter,Iter) const
|
|
||||||
{
|
|
||||||
if (exprs_.size()>=1)
|
|
||||||
{
|
|
||||||
shared_ptr<expression<FeatureT> > exp = exprs_.top();
|
|
||||||
exprs_.pop();
|
|
||||||
if (exp)
|
|
||||||
{
|
|
||||||
filters_.push(shared_ptr<filter<FeatureT> >(new boolean_filter<FeatureT>(*exp)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack<shared_ptr<filter<FeatureT> > >& filters_;
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct compose_and_filter
|
|
||||||
{
|
|
||||||
compose_and_filter(stack<shared_ptr<filter<FeatureT> > >& filters)
|
|
||||||
: filters_(filters) {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
|
||||||
void operator() (Iter,Iter) const
|
|
||||||
{
|
|
||||||
if (filters_.size()>=2)
|
|
||||||
{
|
|
||||||
shared_ptr<filter<FeatureT> > right = filters_.top();
|
|
||||||
filters_.pop();
|
|
||||||
shared_ptr<filter<FeatureT> > left = filters_.top();
|
|
||||||
filters_.pop();
|
|
||||||
if (left && right)
|
|
||||||
{
|
|
||||||
filters_.push(shared_ptr<filter<FeatureT> >
|
|
||||||
(new logical_and<FeatureT>(*left,*right)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack<shared_ptr<filter<FeatureT> > >& filters_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct compose_or_filter
|
|
||||||
{
|
|
||||||
compose_or_filter(stack<shared_ptr<filter<FeatureT> > >& filters)
|
|
||||||
: filters_(filters) {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
|
||||||
void operator() (Iter,Iter) const
|
|
||||||
{
|
|
||||||
if (filters_.size()>=2)
|
|
||||||
{
|
|
||||||
shared_ptr<filter<FeatureT> > right = filters_.top();
|
|
||||||
filters_.pop();
|
|
||||||
shared_ptr<filter<FeatureT> > left = filters_.top();
|
|
||||||
filters_.pop();
|
|
||||||
if (left && right)
|
|
||||||
{
|
|
||||||
filters_.push(shared_ptr<filter<FeatureT> >
|
|
||||||
(new logical_or<FeatureT>(*left,*right)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack<shared_ptr<filter<FeatureT> > >& filters_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct compose_not_filter
|
|
||||||
{
|
|
||||||
compose_not_filter(stack<shared_ptr<filter<FeatureT> > >& filters)
|
|
||||||
: filters_(filters) {}
|
|
||||||
|
|
||||||
template <typename Iter>
|
|
||||||
void operator() (Iter,Iter) const
|
|
||||||
{
|
|
||||||
if (filters_.size()>=1)
|
|
||||||
{
|
|
||||||
shared_ptr<filter<FeatureT> > filter_ = filters_.top();
|
|
||||||
filters_.pop();
|
|
||||||
if (filter_)
|
|
||||||
{
|
|
||||||
filters_.push(shared_ptr<filter<FeatureT> >(new logical_not<FeatureT>(*filter_)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack<shared_ptr<filter<FeatureT> > >& filters_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FeatureT>
|
|
||||||
struct filter_grammar : public grammar<filter_grammar<FeatureT> >
|
|
||||||
{
|
|
||||||
filter_grammar(stack<shared_ptr<filter<FeatureT> > >& filters_,
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs_,
|
|
||||||
transcoder const& tr_)
|
|
||||||
: filters(filters_),
|
|
||||||
exprs(exprs_),
|
|
||||||
tr(tr_) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct definition
|
|
||||||
{
|
|
||||||
definition(filter_grammar const& self)
|
|
||||||
{
|
|
||||||
typedef boost::spirit::chset<wchar_t> chset_t;
|
|
||||||
|
|
||||||
func1_op = "sqrt","sin","cos";
|
|
||||||
func2_op = "min","max";
|
|
||||||
spatial_op = "Equals","Disjoint","Touches","Within","Overlaps",
|
|
||||||
"Crosses","Intersects","Contains","DWithin","Beyond","BBOX";
|
|
||||||
boolean_const = "true","false";
|
|
||||||
|
|
||||||
chset_t BaseChar (L"\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF\x100-\x131\x134-\x13E"
|
|
||||||
L"\x141-\x148\x14A-\x17E\x180-\x1C3\x1CD-\x1F0\x1F4-\x1F5\x1FA-\x217"
|
|
||||||
L"\x250-\x2A8\x2BB-\x2C1\x386\x388-\x38A\x38C\x38E-\x3A1\x3A3-\x3CE"
|
|
||||||
L"\x3D0-\x3D6\x3DA\x3DC\x3DE\x3E0\x3E2-\x3F3\x401-\x40C\x40E-\x44F"
|
|
||||||
L"\x451-\x45C\x45E-\x481\x490-\x4C4\x4C7-\x4C8\x4CB-\x4CC\x4D0-\x4EB"
|
|
||||||
L"\x4EE-\x4F5\x4F8-\x4F9\x531-\x556\x559\x561-\x586\x5D0-\x5EA"
|
|
||||||
L"\x5F0-\x5F2\x621-\x63A\x641-\x64A\x671-\x6B7\x6BA-\x6BE\x6C0-\x6CE"
|
|
||||||
L"\x6D0-\x6D3\x6D5\x6E5-\x6E6\x905-\x939\x93D\x958-\x961\x985-\x98C"
|
|
||||||
L"\x98F-\x990\x993-\x9A8\x9AA-\x9B0\x9B2\x9B6-\x9B9\x9DC-\x9DD"
|
|
||||||
L"\x9DF-\x9E1\x9F0-\x9F1\xA05-\xA0A\xA0F-\xA10\xA13-\xA28\xA2A-\xA30"
|
|
||||||
L"\xA32-\xA33\xA35-\xA36\xA38-\xA39\xA59-\xA5C\xA5E\xA72-\xA74"
|
|
||||||
L"\xA85-\xA8B\xA8D\xA8F-\xA91\xA93-\xAA8\xAAA-\xAB0\xAB2-\xAB3"
|
|
||||||
L"\xAB5-\xAB9\xABD\xAE0\xB05-\xB0C\xB0F-\xB10\xB13-\xB28\xB2A-\xB30"
|
|
||||||
L"\xB32-\xB33\xB36-\xB39\xB3D\xB5C-\xB5D\xB5F-\xB61\xB85-\xB8A"
|
|
||||||
L"\xB8E-\xB90\xB92-\xB95\xB99-\xB9A\xB9C\xB9E-\xB9F\xBA3-\xBA4"
|
|
||||||
L"\xBA8-\xBAA\xBAE-\xBB5\xBB7-\xBB9\xC05-\xC0C\xC0E-\xC10\xC12-\xC28"
|
|
||||||
L"\xC2A-\xC33\xC35-\xC39\xC60-\xC61\xC85-\xC8C\xC8E-\xC90\xC92-\xCA8"
|
|
||||||
L"\xCAA-\xCB3\xCB5-\xCB9\xCDE\xCE0-\xCE1\xD05-\xD0C\xD0E-\xD10"
|
|
||||||
L"\xD12-\xD28\xD2A-\xD39\xD60-\xD61\xE01-\xE2E\xE30\xE32-\xE33"
|
|
||||||
L"\xE40-\xE45\xE81-\xE82\xE84\xE87-\xE88\xE8A\xE8D\xE94-\xE97"
|
|
||||||
L"\xE99-\xE9F\xEA1-\xEA3\xEA5\xEA7\xEAA-\xEAB\xEAD-\xEAE\xEB0"
|
|
||||||
L"\xEB2-\xEB3\xEBD\xEC0-\xEC4\xF40-\xF47\xF49-\xF69\x10A0-\x10C5"
|
|
||||||
L"\x10D0-\x10F6\x1100\x1102-\x1103\x1105-\x1107\x1109\x110B-\x110C"
|
|
||||||
L"\x110E-\x1112\x113C\x113E\x1140\x114C\x114E\x1150\x1154-\x1155"
|
|
||||||
L"\x1159\x115F-\x1161\x1163\x1165\x1167\x1169\x116D-\x116E"
|
|
||||||
L"\x1172-\x1173\x1175\x119E\x11A8\x11AB\x11AE-\x11AF\x11B7-\x11B8"
|
|
||||||
L"\x11BA\x11BC-\x11C2\x11EB\x11F0\x11F9\x1E00-\x1E9B\x1EA0-\x1EF9"
|
|
||||||
L"\x1F00-\x1F15\x1F18-\x1F1D\x1F20-\x1F45\x1F48-\x1F4D\x1F50-\x1F57"
|
|
||||||
L"\x1F59\x1F5B\x1F5D\x1F5F-\x1F7D\x1F80-\x1FB4\x1FB6-\x1FBC\x1FBE"
|
|
||||||
L"\x1FC2-\x1FC4\x1FC6-\x1FCC\x1FD0-\x1FD3\x1FD6-\x1FDB\x1FE0-\x1FEC"
|
|
||||||
L"\x1FF2-\x1FF4\x1FF6-\x1FFC\x2126\x212A-\x212B\x212E\x2180-\x2182"
|
|
||||||
L"\x3041-\x3094\x30A1-\x30FA\x3105-\x312C\xAC00-\xD7A3");
|
|
||||||
|
|
||||||
chset_t Ideographic(L"\x4E00-\x9FA5\x3007\x3021-\x3029");
|
|
||||||
chset_t Letter = BaseChar | Ideographic;
|
|
||||||
|
|
||||||
chset_t CombiningChar(L"\x0300-\x0345\x0360-\x0361\x0483-\x0486\x0591-\x05A1\x05A3-\x05B9"
|
|
||||||
L"\x05BB-\x05BD\x05BF\x05C1-\x05C2\x05C4\x064B-\x0652\x0670"
|
|
||||||
L"\x06D6-\x06DC\x06DD-\x06DF\x06E0-\x06E4\x06E7-\x06E8\x06EA-\x06ED"
|
|
||||||
L"\x0901-\x0903\x093C\x093E-\x094C\x094D\x0951-\x0954\x0962-\x0963"
|
|
||||||
L"\x0981-\x0983\x09BC\x09BE\x09BF\x09C0-\x09C4\x09C7-\x09C8"
|
|
||||||
L"\x09CB-\x09CD\x09D7\x09E2-\x09E3\x0A02\x0A3C\x0A3E\x0A3F"
|
|
||||||
L"\x0A40-\x0A42\x0A47-\x0A48\x0A4B-\x0A4D\x0A70-\x0A71\x0A81-\x0A83"
|
|
||||||
L"\x0ABC\x0ABE-\x0AC5\x0AC7-\x0AC9\x0ACB-\x0ACD\x0B01-\x0B03\x0B3C"
|
|
||||||
L"\x0B3E-\x0B43\x0B47-\x0B48\x0B4B-\x0B4D\x0B56-\x0B57\x0B82-\x0B83"
|
|
||||||
L"\x0BBE-\x0BC2\x0BC6-\x0BC8\x0BCA-\x0BCD\x0BD7\x0C01-\x0C03"
|
|
||||||
L"\x0C3E-\x0C44\x0C46-\x0C48\x0C4A-\x0C4D\x0C55-\x0C56\x0C82-\x0C83"
|
|
||||||
L"\x0CBE-\x0CC4\x0CC6-\x0CC8\x0CCA-\x0CCD\x0CD5-\x0CD6\x0D02-\x0D03"
|
|
||||||
L"\x0D3E-\x0D43\x0D46-\x0D48\x0D4A-\x0D4D\x0D57\x0E31\x0E34-\x0E3A"
|
|
||||||
L"\x0E47-\x0E4E\x0EB1\x0EB4-\x0EB9\x0EBB-\x0EBC\x0EC8-\x0ECD"
|
|
||||||
L"\x0F18-\x0F19\x0F35\x0F37\x0F39\x0F3E\x0F3F\x0F71-\x0F84"
|
|
||||||
L"\x0F86-\x0F8B\x0F90-\x0F95\x0F97\x0F99-\x0FAD\x0FB1-\x0FB7\x0FB9"
|
|
||||||
L"\x20D0-\x20DC\x20E1\x302A-\x302F\x3099\x309A");
|
|
||||||
|
|
||||||
chset_t Digit(L"\x0030-\x0039\x0660-\x0669\x06F0-\x06F9\x0966-\x096F\x09E6-\x09EF"
|
|
||||||
L"\x0A66-\x0A6F\x0AE6-\x0AEF\x0B66-\x0B6F\x0BE7-\x0BEF\x0C66-\x0C6F"
|
|
||||||
L"\x0CE6-\x0CEF\x0D66-\x0D6F\x0E50-\x0E59\x0ED0-\x0ED9\x0F20-\x0F29");
|
|
||||||
|
|
||||||
chset_t Extender(L"\x00B7\x02D0\x02D1\x0387\x0640\x0E46\x0EC6\x3005\x3031-\x3035"
|
|
||||||
L"\x309D-\x309E\x30FC-\x30FE");
|
|
||||||
|
|
||||||
chset_t NameChar =
|
|
||||||
Letter
|
|
||||||
| Digit
|
|
||||||
| L'.'
|
|
||||||
| L'-'
|
|
||||||
| L'_'
|
|
||||||
| L':'
|
|
||||||
| CombiningChar
|
|
||||||
| Extender;
|
|
||||||
|
|
||||||
boolean = boolean_const [push_boolean<FeatureT>(self.exprs)];
|
|
||||||
|
|
||||||
number = strict_real_p [push_real<FeatureT>(self.exprs)]
|
|
||||||
| int_p [push_integer<FeatureT>(self.exprs)];
|
|
||||||
|
|
||||||
string_ = confix_p(L'\'',(*lex_escape_ch_p)
|
|
||||||
[push_string<FeatureT>(self.exprs,self.tr)],
|
|
||||||
L'\'');
|
|
||||||
|
|
||||||
property = L'[' >> ( (Letter | Digit | L'_' | L':')
|
|
||||||
>> *NameChar )[push_property<FeatureT>(self.exprs)] >> L']';
|
|
||||||
|
|
||||||
literal = boolean | number | string_ | property;
|
|
||||||
|
|
||||||
function = literal | ( func1_op >> L'('>> literal >> L')') |
|
|
||||||
(func2_op >> L'(' >> literal >> L','>> literal >> L')');
|
|
||||||
|
|
||||||
factor = function
|
|
||||||
| L'(' >> or_expr >> L')'
|
|
||||||
| ( L'-' >> factor)
|
|
||||||
;
|
|
||||||
term = factor
|
|
||||||
>> *((L'*' >> factor) [compose_expression<FeatureT,mapnik::mult<value> >(self.exprs)]
|
|
||||||
| (L'/' >> factor) [compose_expression<FeatureT,mapnik::div<value> >(self.exprs)]
|
|
||||||
| (L'%' >> factor) [compose_expression<FeatureT,mapnik::mod<value> >(self.exprs)]);
|
|
||||||
|
|
||||||
expression = term >> *((L'+' >> term) [compose_expression<FeatureT,mapnik::add<value> >(self.exprs)]
|
|
||||||
| (L'-' >> term) [compose_expression<FeatureT,mapnik::sub<value> >(self.exprs)]);
|
|
||||||
|
|
||||||
regex = str_p(L".match")>>L'('>>confix_p(L'\'',(*lex_escape_ch_p)
|
|
||||||
[compose_regex<FeatureT>(self.filters,self.exprs)],
|
|
||||||
L'\'') >>L')';
|
|
||||||
|
|
||||||
relation = expression
|
|
||||||
>> *((L">=" >> expression)
|
|
||||||
[compose_filter<FeatureT,greater_than_or_equal<value> >(self.filters,self.exprs)]
|
|
||||||
| (L'>' >> expression)
|
|
||||||
[compose_filter<FeatureT,mapnik::greater_than<value> >(self.filters,self.exprs)]
|
|
||||||
| (L'<' >> expression)
|
|
||||||
[compose_filter<FeatureT,mapnik::less_than<value> >(self.filters,self.exprs)]
|
|
||||||
| (L"<=" >> expression)
|
|
||||||
[compose_filter<FeatureT,less_than_or_equal<value> >(self.filters,self.exprs)]
|
|
||||||
| regex );
|
|
||||||
|
|
||||||
equation = relation >> *( ( L'=' >> relation)
|
|
||||||
[compose_filter<FeatureT,mapnik::equals<value> >(self.filters,self.exprs)]
|
|
||||||
| ( L"<>" >> relation)
|
|
||||||
[compose_filter<FeatureT,not_equals<value> >(self.filters,self.exprs)]
|
|
||||||
| ( L"!=" >> relation)
|
|
||||||
[compose_filter<FeatureT,not_equals<value> >(self.filters,self.exprs)]);
|
|
||||||
|
|
||||||
cond_expr = equation | (expression)[compose_boolean_filter<FeatureT>(self.filters,self.exprs)];
|
|
||||||
|
|
||||||
not_expr = cond_expr | *(str_p(L"not") >> cond_expr)[compose_not_filter<FeatureT>(self.filters)];
|
|
||||||
|
|
||||||
and_expr = not_expr >> *(L"and" >> not_expr)[compose_and_filter<FeatureT>(self.filters)];
|
|
||||||
|
|
||||||
or_expr = and_expr >> *(L"or" >> and_expr)[compose_or_filter<FeatureT>(self.filters)];
|
|
||||||
|
|
||||||
filter_statement = or_expr >> *(space_p) >> end_p;
|
|
||||||
|
|
||||||
#ifdef BOOST_SPIRIT_DEBUG
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( factor );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( term );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( expression );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( relation );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( equation );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( cond_expr );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( not_expr );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( and_expr );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( or_expr );
|
|
||||||
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( filter_statement );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( literal );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( boolean );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( number );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( string_ );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( property );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( function );
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE( regex );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::spirit::rule<ScannerT> const& start() const
|
|
||||||
{
|
|
||||||
return filter_statement;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::spirit::rule<ScannerT> factor;
|
|
||||||
boost::spirit::rule<ScannerT> term;
|
|
||||||
boost::spirit::rule<ScannerT> expression;
|
|
||||||
boost::spirit::rule<ScannerT> relation;
|
|
||||||
boost::spirit::rule<ScannerT> equation;
|
|
||||||
boost::spirit::rule<ScannerT> cond_expr;
|
|
||||||
boost::spirit::rule<ScannerT> not_expr;
|
|
||||||
boost::spirit::rule<ScannerT> and_expr;
|
|
||||||
boost::spirit::rule<ScannerT> or_expr;
|
|
||||||
|
|
||||||
boost::spirit::rule<ScannerT> filter_statement;
|
|
||||||
boost::spirit::rule<ScannerT> literal;
|
|
||||||
boost::spirit::rule<ScannerT> boolean;
|
|
||||||
boost::spirit::rule<ScannerT> number;
|
|
||||||
boost::spirit::rule<ScannerT> string_;
|
|
||||||
boost::spirit::rule<ScannerT> property;
|
|
||||||
boost::spirit::rule<ScannerT> function;
|
|
||||||
boost::spirit::rule<ScannerT> regex;
|
|
||||||
symbols<string> func1_op;
|
|
||||||
symbols<string> func2_op;
|
|
||||||
symbols<string> spatial_op;
|
|
||||||
symbols<string> boolean_const;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
stack<shared_ptr<filter<FeatureT> > >& filters;
|
|
||||||
stack<shared_ptr<expression<FeatureT> > >& exprs;
|
|
||||||
transcoder const& tr;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //FILTER_PARSER_HPP
|
|
|
@ -358,9 +358,9 @@ namespace mapnik
|
||||||
return face_set;
|
return face_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
face_set_ptr get_face_set(FontSet const& fontset)
|
face_set_ptr get_face_set(font_set const& fset)
|
||||||
{
|
{
|
||||||
std::vector<std::string> const& names = fontset.get_face_names();
|
std::vector<std::string> const& names = fset.get_face_names();
|
||||||
face_set_ptr face_set(new font_face_set);
|
face_set_ptr face_set(new font_face_set);
|
||||||
for (std::vector<std::string>::const_iterator name = names.begin(); name != names.end(); ++name)
|
for (std::vector<std::string>::const_iterator name = names.begin(); name != names.end(); ++name)
|
||||||
{
|
{
|
||||||
|
@ -422,7 +422,7 @@ namespace mapnik
|
||||||
opacity_=opacity;
|
opacity_=opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
Envelope<double> prepare_glyphs(text_path *path)
|
box2d<double> prepare_glyphs(text_path *path)
|
||||||
{
|
{
|
||||||
//clear glyphs
|
//clear glyphs
|
||||||
glyphs_.clear();
|
glyphs_.clear();
|
||||||
|
@ -495,7 +495,7 @@ namespace mapnik
|
||||||
glyphs_.push_back(new glyph_t(image));
|
glyphs_.push_back(new glyph_t(image));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Envelope<double>(bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax);
|
return box2d<double>(bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(double x0, double y0)
|
void render(double x0, double y0)
|
||||||
|
|
|
@ -34,18 +34,18 @@
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
class MAPNIK_DECL FontSet
|
class MAPNIK_DECL font_set
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FontSet();
|
font_set();
|
||||||
FontSet(std::string const& name);
|
font_set(std::string const& name);
|
||||||
FontSet(FontSet const& rhs);
|
font_set(font_set const& rhs);
|
||||||
FontSet& operator=(FontSet const& rhs);
|
font_set& operator=(font_set const& rhs);
|
||||||
unsigned size() const;
|
unsigned size() const;
|
||||||
std::string const& get_name() const;
|
std::string const& get_name() const;
|
||||||
void add_face_name(std::string);
|
void add_face_name(std::string);
|
||||||
std::vector<std::string> const& get_face_names() const;
|
std::vector<std::string> const& get_face_names() const;
|
||||||
~FontSet();
|
~font_set();
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::vector<std::string> face_names_;
|
std::vector<std::string> face_names_;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#ifndef GEOM_UTIL_HPP
|
#ifndef GEOM_UTIL_HPP
|
||||||
#define GEOM_UTIL_HPP
|
#define GEOM_UTIL_HPP
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/envelope.hpp>
|
#include <mapnik/box2d.hpp>
|
||||||
#include <mapnik/vertex.hpp>
|
#include <mapnik/vertex.hpp>
|
||||||
// boost
|
// boost
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
@ -55,7 +55,7 @@ namespace mapnik
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T,typename Image>
|
template <typename T,typename Image>
|
||||||
bool clip_line(T& x0,T& y0,T& x1,T& y1,Envelope<T> const& box)
|
bool clip_line(T& x0,T& y0,T& x1,T& y1,box2d<T> const& box)
|
||||||
{
|
{
|
||||||
double tmin=0.0;
|
double tmin=0.0;
|
||||||
double tmax=1.0;
|
double tmax=1.0;
|
||||||
|
@ -195,11 +195,11 @@ namespace mapnik
|
||||||
// filters
|
// filters
|
||||||
struct filter_in_box
|
struct filter_in_box
|
||||||
{
|
{
|
||||||
Envelope<double> box_;
|
box2d<double> box_;
|
||||||
explicit filter_in_box(const Envelope<double>& box)
|
explicit filter_in_box(const box2d<double>& box)
|
||||||
: box_(box) {}
|
: box_(box) {}
|
||||||
|
|
||||||
bool pass(const Envelope<double>& extent) const
|
bool pass(const box2d<double>& extent) const
|
||||||
{
|
{
|
||||||
return extent.intersects(box_);
|
return extent.intersects(box_);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ namespace mapnik
|
||||||
coord2d pt_;
|
coord2d pt_;
|
||||||
explicit filter_at_point(const coord2d& pt)
|
explicit filter_at_point(const coord2d& pt)
|
||||||
: pt_(pt) {}
|
: pt_(pt) {}
|
||||||
bool pass(const Envelope<double>& extent) const
|
bool pass(const box2d<double>& extent) const
|
||||||
{
|
{
|
||||||
return extent.contains(pt_);
|
return extent.contains(pt_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,9 @@ namespace mapnik {
|
||||||
public:
|
public:
|
||||||
geometry () {}
|
geometry () {}
|
||||||
|
|
||||||
Envelope<double> envelope() const
|
box2d<double> envelope() const
|
||||||
{
|
{
|
||||||
Envelope<double> result;
|
box2d<double> result;
|
||||||
double x,y;
|
double x,y;
|
||||||
rewind(0);
|
rewind(0);
|
||||||
for (unsigned i=0;i<num_points();++i)
|
for (unsigned i=0;i<num_points();++i)
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <mapnik/color.hpp>
|
#include <mapnik/color.hpp>
|
||||||
#include <mapnik/gamma.hpp>
|
#include <mapnik/gamma.hpp>
|
||||||
#include <mapnik/image_data.hpp>
|
#include <mapnik/image_data.hpp>
|
||||||
#include <mapnik/envelope.hpp>
|
#include <mapnik/box2d.hpp>
|
||||||
#include <mapnik/image_view.hpp>
|
#include <mapnik/image_view.hpp>
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
|
|
||||||
|
@ -45,424 +45,424 @@
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Multiply
|
struct Multiply
|
||||||
{
|
{
|
||||||
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
||||||
unsigned &r1, unsigned &g1, unsigned &b1)
|
unsigned &r1, unsigned &g1, unsigned &b1)
|
||||||
{
|
|
||||||
r1 = r1*r0/255;
|
|
||||||
g1 = g1*g0/255;
|
|
||||||
b1 = b1*b0/255;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct Multiply2
|
|
||||||
{
|
|
||||||
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
|
||||||
unsigned &r1, unsigned &g1, unsigned &b1)
|
|
||||||
{
|
|
||||||
r1 = r1*r0/128;
|
|
||||||
if (r1>255) r1=255;
|
|
||||||
g1 = g1*g0/128;
|
|
||||||
if (g1>255) g1=255;
|
|
||||||
b1 = b1*b0/128;
|
|
||||||
if (b1>255) b1=255;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct Divide
|
|
||||||
{
|
|
||||||
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
|
||||||
unsigned &r1, unsigned &g1, unsigned &b1)
|
|
||||||
{
|
|
||||||
r1 = r0*256/(r1+1);
|
|
||||||
g1 = g0*256/(g1+1);
|
|
||||||
b1 = b0*256/(b1+1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct Divide2
|
|
||||||
{
|
|
||||||
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
|
||||||
unsigned &r1, unsigned &g1, unsigned &b1)
|
|
||||||
{
|
|
||||||
r1 = r0*128/(r1+1);
|
|
||||||
g1 = g0*128/(g1+1);
|
|
||||||
b1 = b0*128/(b1+1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct Screen
|
|
||||||
{
|
|
||||||
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
|
||||||
unsigned &r1, unsigned &g1, unsigned &b1)
|
|
||||||
{
|
|
||||||
r1 = 255 - (255-r0)*(255-r1)/255;
|
|
||||||
g1 = 255 - (255-g0)*(255-g1)/255;
|
|
||||||
b1 = 255 - (255-b0)*(255-b1)/255;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct HardLight
|
|
||||||
{
|
|
||||||
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
|
||||||
unsigned &r1, unsigned &g1, unsigned &b1)
|
|
||||||
{
|
|
||||||
r1 = (r1>128)?255-(255-r0)*(255-2*(r1-128))/256:r0*r1*2/256;
|
|
||||||
g1 = (g1>128)?255-(255-g0)*(255-2*(g1-128))/256:g0*g1*2/256;
|
|
||||||
b1 = (b1>128)?255-(255-b0)*(255-2*(b1-128))/256:b0*b1*2/256;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct MergeGrain
|
|
||||||
{
|
|
||||||
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
|
||||||
unsigned &r1, unsigned &g1, unsigned &b1)
|
|
||||||
{
|
|
||||||
r1 = (r1+r0>128)?r1+r0-128:0;
|
|
||||||
if (r1>255) r1=255;
|
|
||||||
g1 = (g1+g0>128)?g1+g0-128:0;
|
|
||||||
if (g1>255) g1=255;
|
|
||||||
b1 = (b1+b0>128)?b1+b0-128:0;
|
|
||||||
if (b1>255) b1=255;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct MergeGrain2
|
|
||||||
{
|
|
||||||
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
|
||||||
unsigned &r1, unsigned &g1, unsigned &b1)
|
|
||||||
{
|
|
||||||
r1 = (2*r1+r0>256)?2*r1+r0-256:0;
|
|
||||||
if (r1>255) r1=255;
|
|
||||||
g1 = (2*g1+g0>256)?2*g1+g0-256:0;
|
|
||||||
if (g1>255) g1=255;
|
|
||||||
b1 = (2*b1+b0>256)?2*b1+b0-256:0;
|
|
||||||
if (b1>255) b1=255;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MAPNIK_DECL Image32
|
|
||||||
{
|
{
|
||||||
private:
|
r1 = r1*r0/255;
|
||||||
unsigned width_;
|
g1 = g1*g0/255;
|
||||||
unsigned height_;
|
b1 = b1*b0/255;
|
||||||
color background_;
|
}
|
||||||
ImageData32 data_;
|
};
|
||||||
public:
|
struct Multiply2
|
||||||
Image32(int width,int height);
|
{
|
||||||
Image32(Image32 const& rhs);
|
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
||||||
|
unsigned &r1, unsigned &g1, unsigned &b1)
|
||||||
|
{
|
||||||
|
r1 = r1*r0/128;
|
||||||
|
if (r1>255) r1=255;
|
||||||
|
g1 = g1*g0/128;
|
||||||
|
if (g1>255) g1=255;
|
||||||
|
b1 = b1*b0/128;
|
||||||
|
if (b1>255) b1=255;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct Divide
|
||||||
|
{
|
||||||
|
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
||||||
|
unsigned &r1, unsigned &g1, unsigned &b1)
|
||||||
|
{
|
||||||
|
r1 = r0*256/(r1+1);
|
||||||
|
g1 = g0*256/(g1+1);
|
||||||
|
b1 = b0*256/(b1+1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct Divide2
|
||||||
|
{
|
||||||
|
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
||||||
|
unsigned &r1, unsigned &g1, unsigned &b1)
|
||||||
|
{
|
||||||
|
r1 = r0*128/(r1+1);
|
||||||
|
g1 = g0*128/(g1+1);
|
||||||
|
b1 = b0*128/(b1+1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct Screen
|
||||||
|
{
|
||||||
|
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
||||||
|
unsigned &r1, unsigned &g1, unsigned &b1)
|
||||||
|
{
|
||||||
|
r1 = 255 - (255-r0)*(255-r1)/255;
|
||||||
|
g1 = 255 - (255-g0)*(255-g1)/255;
|
||||||
|
b1 = 255 - (255-b0)*(255-b1)/255;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct HardLight
|
||||||
|
{
|
||||||
|
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
||||||
|
unsigned &r1, unsigned &g1, unsigned &b1)
|
||||||
|
{
|
||||||
|
r1 = (r1>128)?255-(255-r0)*(255-2*(r1-128))/256:r0*r1*2/256;
|
||||||
|
g1 = (g1>128)?255-(255-g0)*(255-2*(g1-128))/256:g0*g1*2/256;
|
||||||
|
b1 = (b1>128)?255-(255-b0)*(255-2*(b1-128))/256:b0*b1*2/256;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct MergeGrain
|
||||||
|
{
|
||||||
|
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
||||||
|
unsigned &r1, unsigned &g1, unsigned &b1)
|
||||||
|
{
|
||||||
|
r1 = (r1+r0>128)?r1+r0-128:0;
|
||||||
|
if (r1>255) r1=255;
|
||||||
|
g1 = (g1+g0>128)?g1+g0-128:0;
|
||||||
|
if (g1>255) g1=255;
|
||||||
|
b1 = (b1+b0>128)?b1+b0-128:0;
|
||||||
|
if (b1>255) b1=255;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct MergeGrain2
|
||||||
|
{
|
||||||
|
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
|
||||||
|
unsigned &r1, unsigned &g1, unsigned &b1)
|
||||||
|
{
|
||||||
|
r1 = (2*r1+r0>256)?2*r1+r0-256:0;
|
||||||
|
if (r1>255) r1=255;
|
||||||
|
g1 = (2*g1+g0>256)?2*g1+g0-256:0;
|
||||||
|
if (g1>255) g1=255;
|
||||||
|
b1 = (2*b1+b0>256)?2*b1+b0-256:0;
|
||||||
|
if (b1>255) b1=255;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MAPNIK_DECL image_32
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
unsigned width_;
|
||||||
|
unsigned height_;
|
||||||
|
color background_;
|
||||||
|
image_data_32 data_;
|
||||||
|
public:
|
||||||
|
image_32(int width,int height);
|
||||||
|
image_32(image_32 const& rhs);
|
||||||
#ifdef HAVE_CAIRO
|
#ifdef HAVE_CAIRO
|
||||||
Image32(Cairo::RefPtr<Cairo::ImageSurface> rhs);
|
image_32(Cairo::RefPtr<Cairo::ImageSurface> rhs);
|
||||||
#endif
|
#endif
|
||||||
~Image32();
|
~image_32();
|
||||||
void setBackground(color const& background);
|
void set_background(color const& background);
|
||||||
const color& getBackground() const;
|
const color& get_background() const;
|
||||||
const ImageData32& data() const;
|
const image_data_32& data() const;
|
||||||
|
|
||||||
inline ImageData32& data()
|
inline image_data_32& data()
|
||||||
{
|
{
|
||||||
return data_;
|
return data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const unsigned char* raw_data() const
|
inline const unsigned char* raw_data() const
|
||||||
{
|
{
|
||||||
return data_.getBytes();
|
return data_.getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned char* raw_data()
|
inline unsigned char* raw_data()
|
||||||
{
|
{
|
||||||
return data_.getBytes();
|
return data_.getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline image_view<ImageData32> get_view(unsigned x,unsigned y, unsigned w,unsigned h)
|
inline image_view<image_data_32> get_view(unsigned x,unsigned y, unsigned w,unsigned h)
|
||||||
{
|
{
|
||||||
return image_view<ImageData32>(x,y,w,h,data_);
|
return image_view<image_data_32>(x,y,w,h,data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
inline bool checkBounds(unsigned x, unsigned y) const
|
inline bool checkBounds(unsigned x, unsigned y) const
|
||||||
{
|
{
|
||||||
return (x < width_ && y < height_);
|
return (x < width_ && y < height_);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline void setPixel(int x,int y,unsigned int rgba)
|
inline void setPixel(int x,int y,unsigned int rgba)
|
||||||
{
|
{
|
||||||
if (checkBounds(x,y))
|
if (checkBounds(x,y))
|
||||||
{
|
{
|
||||||
data_(x,y)=rgba;
|
data_(x,y)=rgba;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline void blendPixel(int x,int y,unsigned int rgba1,int t)
|
inline void blendPixel(int x,int y,unsigned int rgba1,int t)
|
||||||
{
|
{
|
||||||
blendPixel2(x,y,rgba1,t,1.0); // do not change opacity
|
blendPixel2(x,y,rgba1,t,1.0); // do not change opacity
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void blendPixel2(int x,int y,unsigned int rgba1,int t,double opacity)
|
inline void blendPixel2(int x,int y,unsigned int rgba1,int t,double opacity)
|
||||||
{
|
{
|
||||||
if (checkBounds(x,y))
|
if (checkBounds(x,y))
|
||||||
{
|
{
|
||||||
unsigned rgba0 = data_(x,y);
|
unsigned rgba0 = data_(x,y);
|
||||||
#ifdef MAPNIK_BIG_ENDIAN
|
#ifdef MAPNIK_BIG_ENDIAN
|
||||||
unsigned a1 = (int)((rgba1 & 0xff) * opacity) & 0xff; // adjust for desired opacity
|
unsigned a1 = (int)((rgba1 & 0xff) * opacity) & 0xff; // adjust for desired opacity
|
||||||
a1 = (t*a1) / 255;
|
a1 = (t*a1) / 255;
|
||||||
if (a1 == 0) return;
|
if (a1 == 0) return;
|
||||||
unsigned r1 = (rgba1 >> 24) & 0xff;
|
unsigned r1 = (rgba1 >> 24) & 0xff;
|
||||||
unsigned g1 = (rgba1 >> 16 ) & 0xff;
|
unsigned g1 = (rgba1 >> 16 ) & 0xff;
|
||||||
unsigned b1 = (rgba1 >> 8) & 0xff;
|
unsigned b1 = (rgba1 >> 8) & 0xff;
|
||||||
|
|
||||||
unsigned a0 = (rgba0 & 0xff);
|
unsigned a0 = (rgba0 & 0xff);
|
||||||
unsigned r0 = ((rgba0 >> 24 ) & 0xff) * a0;
|
unsigned r0 = ((rgba0 >> 24 ) & 0xff) * a0;
|
||||||
unsigned g0 = ((rgba0 >> 16 ) & 0xff) * a0;
|
unsigned g0 = ((rgba0 >> 16 ) & 0xff) * a0;
|
||||||
unsigned b0 = ((rgba0 >> 8) & 0xff) * a0;
|
unsigned b0 = ((rgba0 >> 8) & 0xff) * a0;
|
||||||
|
|
||||||
a0 = ((a1 + a0) << 8) - a0*a1;
|
a0 = ((a1 + a0) << 8) - a0*a1;
|
||||||
|
|
||||||
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
||||||
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
||||||
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
||||||
a0 = a0 >> 8;
|
a0 = a0 >> 8;
|
||||||
data_(x,y)= (a0)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
|
data_(x,y)= (a0)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
|
||||||
#else
|
#else
|
||||||
unsigned a1 = (int)(((rgba1 >> 24) & 0xff) * opacity) & 0xff; // adjust for desired opacity
|
unsigned a1 = (int)(((rgba1 >> 24) & 0xff) * opacity) & 0xff; // adjust for desired opacity
|
||||||
a1 = (t*a1) / 255;
|
a1 = (t*a1) / 255;
|
||||||
if (a1 == 0) return;
|
if (a1 == 0) return;
|
||||||
unsigned r1 = rgba1 & 0xff;
|
unsigned r1 = rgba1 & 0xff;
|
||||||
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
||||||
unsigned b1 = (rgba1 >> 16) & 0xff;
|
unsigned b1 = (rgba1 >> 16) & 0xff;
|
||||||
|
|
||||||
unsigned a0 = (rgba0 >> 24) & 0xff;
|
unsigned a0 = (rgba0 >> 24) & 0xff;
|
||||||
unsigned r0 = (rgba0 & 0xff) * a0;
|
unsigned r0 = (rgba0 & 0xff) * a0;
|
||||||
unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
|
unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
|
||||||
unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
|
unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
|
||||||
|
|
||||||
a0 = ((a1 + a0) << 8) - a0*a1;
|
a0 = ((a1 + a0) << 8) - a0*a1;
|
||||||
|
|
||||||
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
||||||
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
||||||
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
||||||
a0 = a0 >> 8;
|
a0 = a0 >> 8;
|
||||||
data_(x,y)= (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
data_(x,y)= (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned width() const
|
inline unsigned width() const
|
||||||
{
|
{
|
||||||
return width_;
|
return width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned height() const
|
inline unsigned height() const
|
||||||
{
|
{
|
||||||
return height_;
|
return height_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_rectangle(int x0,int y0,ImageData32 const& data)
|
inline void set_rectangle(int x0,int y0,image_data_32 const& data)
|
||||||
{
|
{
|
||||||
Envelope<int> ext0(0,0,width_,height_);
|
box2d<int> ext0(0,0,width_,height_);
|
||||||
Envelope<int> ext1(x0,y0,x0+data.width(),y0+data.height());
|
box2d<int> ext1(x0,y0,x0+data.width(),y0+data.height());
|
||||||
|
|
||||||
if (ext0.intersects(ext1))
|
if (ext0.intersects(ext1))
|
||||||
{
|
{
|
||||||
Envelope<int> box = ext0.intersect(ext1);
|
box2d<int> box = ext0.intersect(ext1);
|
||||||
for (int y = box.miny(); y < box.maxy(); ++y)
|
for (int y = box.miny(); y < box.maxy(); ++y)
|
||||||
{
|
{
|
||||||
unsigned int* row_to = data_.getRow(y);
|
unsigned int* row_to = data_.getRow(y);
|
||||||
unsigned int const * row_from = data.getRow(y-y0);
|
unsigned int const * row_from = data.getRow(y-y0);
|
||||||
|
|
||||||
for (int x = box.minx(); x < box.maxx(); ++x)
|
for (int x = box.minx(); x < box.maxx(); ++x)
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_BIG_ENDIAN
|
#ifdef MAPNIK_BIG_ENDIAN
|
||||||
row_to[x] = row_from[x-x0];
|
row_to[x] = row_from[x-x0];
|
||||||
#else
|
#else
|
||||||
if (row_from[x-x0] & 0xff000000)
|
if (row_from[x-x0] & 0xff000000)
|
||||||
{
|
{
|
||||||
row_to[x] = row_from[x-x0];
|
row_to[x] = row_from[x-x0];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_rectangle_alpha(int x0,int y0,const ImageData32& data)
|
inline void set_rectangle_alpha(int x0,int y0,const image_data_32& data)
|
||||||
{
|
{
|
||||||
Envelope<int> ext0(0,0,width_,height_);
|
box2d<int> ext0(0,0,width_,height_);
|
||||||
Envelope<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
|
box2d<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
|
||||||
|
|
||||||
if (ext0.intersects(ext1))
|
if (ext0.intersects(ext1))
|
||||||
{
|
{
|
||||||
Envelope<int> box = ext0.intersect(ext1);
|
box2d<int> box = ext0.intersect(ext1);
|
||||||
for (int y = box.miny(); y < box.maxy(); ++y)
|
for (int y = box.miny(); y < box.maxy(); ++y)
|
||||||
{
|
{
|
||||||
unsigned int* row_to = data_.getRow(y);
|
unsigned int* row_to = data_.getRow(y);
|
||||||
unsigned int const * row_from = data.getRow(y-y0);
|
unsigned int const * row_from = data.getRow(y-y0);
|
||||||
for (int x = box.minx(); x < box.maxx(); ++x)
|
for (int x = box.minx(); x < box.maxx(); ++x)
|
||||||
{
|
{
|
||||||
unsigned rgba0 = row_to[x];
|
unsigned rgba0 = row_to[x];
|
||||||
unsigned rgba1 = row_from[x-x0];
|
unsigned rgba1 = row_from[x-x0];
|
||||||
|
|
||||||
#ifdef MAPNIK_BIG_ENDIAN
|
#ifdef MAPNIK_BIG_ENDIAN
|
||||||
unsigned a1 = rgba1 & 0xff;
|
unsigned a1 = rgba1 & 0xff;
|
||||||
if (a1 == 0) continue;
|
if (a1 == 0) continue;
|
||||||
unsigned r1 = (rgba1 >> 24) & 0xff;
|
unsigned r1 = (rgba1 >> 24) & 0xff;
|
||||||
unsigned g1 = (rgba1 >> 16 ) & 0xff;
|
unsigned g1 = (rgba1 >> 16 ) & 0xff;
|
||||||
unsigned b1 = (rgba1 >> 8) & 0xff;
|
unsigned b1 = (rgba1 >> 8) & 0xff;
|
||||||
|
|
||||||
unsigned a0 = rgba0 & 0xff;
|
unsigned a0 = rgba0 & 0xff;
|
||||||
unsigned r0 = ((rgba0 >> 24) & 0xff) * a0;
|
unsigned r0 = ((rgba0 >> 24) & 0xff) * a0;
|
||||||
unsigned g0 = ((rgba0 >> 16 ) & 0xff) * a0;
|
unsigned g0 = ((rgba0 >> 16 ) & 0xff) * a0;
|
||||||
unsigned b0 = ((rgba0 >> 8) & 0xff) * a0;
|
unsigned b0 = ((rgba0 >> 8) & 0xff) * a0;
|
||||||
|
|
||||||
a0 = ((a1 + a0) << 8) - a0*a1;
|
a0 = ((a1 + a0) << 8) - a0*a1;
|
||||||
|
|
||||||
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
||||||
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
||||||
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
||||||
a0 = a0 >> 8;
|
a0 = a0 >> 8;
|
||||||
row_to[x] = (a0) | (b0 << 8) | (g0 << 16) | (r0 << 24) ;
|
row_to[x] = (a0) | (b0 << 8) | (g0 << 16) | (r0 << 24) ;
|
||||||
#else
|
#else
|
||||||
unsigned a1 = (rgba1 >> 24) & 0xff;
|
unsigned a1 = (rgba1 >> 24) & 0xff;
|
||||||
if (a1 == 0) continue;
|
if (a1 == 0) continue;
|
||||||
unsigned r1 = rgba1 & 0xff;
|
unsigned r1 = rgba1 & 0xff;
|
||||||
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
||||||
unsigned b1 = (rgba1 >> 16) & 0xff;
|
unsigned b1 = (rgba1 >> 16) & 0xff;
|
||||||
|
|
||||||
unsigned a0 = (rgba0 >> 24) & 0xff;
|
unsigned a0 = (rgba0 >> 24) & 0xff;
|
||||||
unsigned r0 = (rgba0 & 0xff) * a0;
|
unsigned r0 = (rgba0 & 0xff) * a0;
|
||||||
unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
|
unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
|
||||||
unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
|
unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
|
||||||
|
|
||||||
a0 = ((a1 + a0) << 8) - a0*a1;
|
a0 = ((a1 + a0) << 8) - a0*a1;
|
||||||
|
|
||||||
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
||||||
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
||||||
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
||||||
a0 = a0 >> 8;
|
a0 = a0 >> 8;
|
||||||
row_to[x] = (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
row_to[x] = (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_rectangle_alpha2(ImageData32 const& data, unsigned x0, unsigned y0, float opacity)
|
inline void set_rectangle_alpha2(image_data_32 const& data, unsigned x0, unsigned y0, float opacity)
|
||||||
{
|
{
|
||||||
Envelope<int> ext0(0,0,width_,height_);
|
box2d<int> ext0(0,0,width_,height_);
|
||||||
Envelope<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
|
box2d<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
|
||||||
|
|
||||||
if (ext0.intersects(ext1))
|
if (ext0.intersects(ext1))
|
||||||
{
|
{
|
||||||
Envelope<int> box = ext0.intersect(ext1);
|
box2d<int> box = ext0.intersect(ext1);
|
||||||
for (int y = box.miny(); y < box.maxy(); ++y)
|
for (int y = box.miny(); y < box.maxy(); ++y)
|
||||||
{
|
{
|
||||||
unsigned int* row_to = data_.getRow(y);
|
unsigned int* row_to = data_.getRow(y);
|
||||||
unsigned int const * row_from = data.getRow(y-y0);
|
unsigned int const * row_from = data.getRow(y-y0);
|
||||||
for (int x = box.minx(); x < box.maxx(); ++x)
|
for (int x = box.minx(); x < box.maxx(); ++x)
|
||||||
{
|
{
|
||||||
unsigned rgba0 = row_to[x];
|
unsigned rgba0 = row_to[x];
|
||||||
unsigned rgba1 = row_from[x-x0];
|
unsigned rgba1 = row_from[x-x0];
|
||||||
#ifdef MAPNIK_BIG_ENDIAN
|
#ifdef MAPNIK_BIG_ENDIAN
|
||||||
unsigned a1 = int( (rgba1 & 0xff) * opacity );
|
unsigned a1 = int( (rgba1 & 0xff) * opacity );
|
||||||
if (a1 == 0) continue;
|
if (a1 == 0) continue;
|
||||||
unsigned r1 = (rgba1 >> 24) & 0xff;
|
unsigned r1 = (rgba1 >> 24) & 0xff;
|
||||||
unsigned g1 = (rgba1 >> 16 ) & 0xff;
|
unsigned g1 = (rgba1 >> 16 ) & 0xff;
|
||||||
unsigned b1 = (rgba1 >> 8) & 0xff;
|
unsigned b1 = (rgba1 >> 8) & 0xff;
|
||||||
|
|
||||||
unsigned a0 = rgba0 & 0xff;
|
unsigned a0 = rgba0 & 0xff;
|
||||||
unsigned r0 = (rgba0 >> 24) & 0xff ;
|
unsigned r0 = (rgba0 >> 24) & 0xff ;
|
||||||
unsigned g0 = (rgba0 >> 16 ) & 0xff;
|
unsigned g0 = (rgba0 >> 16 ) & 0xff;
|
||||||
unsigned b0 = (rgba0 >> 8) & 0xff;
|
unsigned b0 = (rgba0 >> 8) & 0xff;
|
||||||
|
|
||||||
r0 = uint8_t(((r1 - r0) * a1 + (r0 << 8)) >> 8);
|
r0 = uint8_t(((r1 - r0) * a1 + (r0 << 8)) >> 8);
|
||||||
g0 = uint8_t(((g1 - g0) * a1 + (g0 << 8)) >> 8);
|
g0 = uint8_t(((g1 - g0) * a1 + (g0 << 8)) >> 8);
|
||||||
b0 = uint8_t(((b1 - b0) * a1 + (b0 << 8)) >> 8);
|
b0 = uint8_t(((b1 - b0) * a1 + (b0 << 8)) >> 8);
|
||||||
a0 = uint8_t((a1 + a0) - ((a1 * a0 + 255) >> 8));
|
a0 = uint8_t((a1 + a0) - ((a1 * a0 + 255) >> 8));
|
||||||
|
|
||||||
row_to[x] = (a0)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
|
row_to[x] = (a0)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
|
||||||
#else
|
#else
|
||||||
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
|
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
|
||||||
if (a1 == 0) continue;
|
if (a1 == 0) continue;
|
||||||
unsigned r1 = rgba1 & 0xff;
|
unsigned r1 = rgba1 & 0xff;
|
||||||
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
||||||
unsigned b1 = (rgba1 >> 16) & 0xff;
|
unsigned b1 = (rgba1 >> 16) & 0xff;
|
||||||
|
|
||||||
unsigned a0 = (rgba0 >> 24) & 0xff;
|
unsigned a0 = (rgba0 >> 24) & 0xff;
|
||||||
unsigned r0 = rgba0 & 0xff ;
|
unsigned r0 = rgba0 & 0xff ;
|
||||||
unsigned g0 = (rgba0 >> 8 ) & 0xff;
|
unsigned g0 = (rgba0 >> 8 ) & 0xff;
|
||||||
unsigned b0 = (rgba0 >> 16) & 0xff;
|
unsigned b0 = (rgba0 >> 16) & 0xff;
|
||||||
|
|
||||||
r0 = uint8_t(((r1 - r0) * a1 + (r0 << 8)) >> 8);
|
r0 = uint8_t(((r1 - r0) * a1 + (r0 << 8)) >> 8);
|
||||||
g0 = uint8_t(((g1 - g0) * a1 + (g0 << 8)) >> 8);
|
g0 = uint8_t(((g1 - g0) * a1 + (g0 << 8)) >> 8);
|
||||||
b0 = uint8_t(((b1 - b0) * a1 + (b0 << 8)) >> 8);
|
b0 = uint8_t(((b1 - b0) * a1 + (b0 << 8)) >> 8);
|
||||||
a0 = uint8_t((a1 + a0) - ((a1 * a0 + 255) >> 8));
|
a0 = uint8_t((a1 + a0) - ((a1 * a0 + 255) >> 8));
|
||||||
|
|
||||||
row_to[x] = (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
row_to[x] = (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MergeMethod>
|
template <typename MergeMethod>
|
||||||
inline void merge_rectangle(ImageData32 const& data, unsigned x0, unsigned y0, float opacity)
|
inline void merge_rectangle(image_data_32 const& data, unsigned x0, unsigned y0, float opacity)
|
||||||
{
|
{
|
||||||
Envelope<int> ext0(0,0,width_,height_);
|
box2d<int> ext0(0,0,width_,height_);
|
||||||
Envelope<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
|
box2d<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
|
||||||
|
|
||||||
if (ext0.intersects(ext1))
|
if (ext0.intersects(ext1))
|
||||||
{
|
{
|
||||||
Envelope<int> box = ext0.intersect(ext1);
|
box2d<int> box = ext0.intersect(ext1);
|
||||||
for (int y = box.miny(); y < box.maxy(); ++y)
|
for (int y = box.miny(); y < box.maxy(); ++y)
|
||||||
{
|
{
|
||||||
unsigned int* row_to = data_.getRow(y);
|
unsigned int* row_to = data_.getRow(y);
|
||||||
unsigned int const * row_from = data.getRow(y-y0);
|
unsigned int const * row_from = data.getRow(y-y0);
|
||||||
for (int x = box.minx(); x < box.maxx(); ++x)
|
for (int x = box.minx(); x < box.maxx(); ++x)
|
||||||
{
|
{
|
||||||
unsigned rgba0 = row_to[x];
|
unsigned rgba0 = row_to[x];
|
||||||
unsigned rgba1 = row_from[x-x0];
|
unsigned rgba1 = row_from[x-x0];
|
||||||
#ifdef MAPNIK_BIG_ENDIAN
|
#ifdef MAPNIK_BIG_ENDIAN
|
||||||
unsigned a1 = int( (rgba1 & 0xff) * opacity );
|
unsigned a1 = int( (rgba1 & 0xff) * opacity );
|
||||||
if (a1 == 0) continue;
|
if (a1 == 0) continue;
|
||||||
unsigned r1 = (rgba1 >> 24)& 0xff;
|
unsigned r1 = (rgba1 >> 24)& 0xff;
|
||||||
unsigned g1 = (rgba1 >> 16 ) & 0xff;
|
unsigned g1 = (rgba1 >> 16 ) & 0xff;
|
||||||
unsigned b1 = (rgba1 >> 8) & 0xff;
|
unsigned b1 = (rgba1 >> 8) & 0xff;
|
||||||
|
|
||||||
unsigned a0 = rgba0 & 0xff;
|
unsigned a0 = rgba0 & 0xff;
|
||||||
unsigned r0 = (rgba0 >> 24) & 0xff ;
|
unsigned r0 = (rgba0 >> 24) & 0xff ;
|
||||||
unsigned g0 = (rgba0 >> 16 ) & 0xff;
|
unsigned g0 = (rgba0 >> 16 ) & 0xff;
|
||||||
unsigned b0 = (rgba0 >> 8) & 0xff;
|
unsigned b0 = (rgba0 >> 8) & 0xff;
|
||||||
|
|
||||||
unsigned a = (a1 * 255 + (255 - a1) * a0 + 127)/255;
|
unsigned a = (a1 * 255 + (255 - a1) * a0 + 127)/255;
|
||||||
|
|
||||||
MergeMethod::mergeRGB(r0,g0,b0,r1,g1,b1);
|
MergeMethod::mergeRGB(r0,g0,b0,r1,g1,b1);
|
||||||
|
|
||||||
r0 = (r1*a1 + (((255 - a1) * a0 + 127)/255) * r0 + 127)/a;
|
r0 = (r1*a1 + (((255 - a1) * a0 + 127)/255) * r0 + 127)/a;
|
||||||
g0 = (g1*a1 + (((255 - a1) * a0 + 127)/255) * g0 + 127)/a;
|
g0 = (g1*a1 + (((255 - a1) * a0 + 127)/255) * g0 + 127)/a;
|
||||||
b0 = (b1*a1 + (((255 - a1) * a0 + 127)/255) * b0 + 127)/a;
|
b0 = (b1*a1 + (((255 - a1) * a0 + 127)/255) * b0 + 127)/a;
|
||||||
|
|
||||||
row_to[x] = (a)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
|
row_to[x] = (a)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
|
||||||
#else
|
#else
|
||||||
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
|
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
|
||||||
if (a1 == 0) continue;
|
if (a1 == 0) continue;
|
||||||
unsigned r1 = rgba1 & 0xff;
|
unsigned r1 = rgba1 & 0xff;
|
||||||
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
||||||
unsigned b1 = (rgba1 >> 16) & 0xff;
|
unsigned b1 = (rgba1 >> 16) & 0xff;
|
||||||
|
|
||||||
unsigned a0 = (rgba0 >> 24) & 0xff;
|
unsigned a0 = (rgba0 >> 24) & 0xff;
|
||||||
unsigned r0 = rgba0 & 0xff ;
|
unsigned r0 = rgba0 & 0xff ;
|
||||||
unsigned g0 = (rgba0 >> 8 ) & 0xff;
|
unsigned g0 = (rgba0 >> 8 ) & 0xff;
|
||||||
unsigned b0 = (rgba0 >> 16) & 0xff;
|
unsigned b0 = (rgba0 >> 16) & 0xff;
|
||||||
|
|
||||||
unsigned a = (a1 * 255 + (255 - a1) * a0 + 127)/255;
|
unsigned a = (a1 * 255 + (255 - a1) * a0 + 127)/255;
|
||||||
|
|
||||||
MergeMethod::mergeRGB(r0,g0,b0,r1,g1,b1);
|
MergeMethod::mergeRGB(r0,g0,b0,r1,g1,b1);
|
||||||
|
|
||||||
r0 = (r1*a1 + (((255 - a1) * a0 + 127)/255) * r0 + 127)/a;
|
r0 = (r1*a1 + (((255 - a1) * a0 + 127)/255) * r0 + 127)/a;
|
||||||
g0 = (g1*a1 + (((255 - a1) * a0 + 127)/255) * g0 + 127)/a;
|
g0 = (g1*a1 + (((255 - a1) * a0 + 127)/255) * g0 + 127)/a;
|
||||||
b0 = (b1*a1 + (((255 - a1) * a0 + 127)/255) * b0 + 127)/a;
|
b0 = (b1*a1 + (((255 - a1) * a0 + 127)/255) * b0 + 127)/a;
|
||||||
|
|
||||||
row_to[x] = (a << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
row_to[x] = (a << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif //GRAPHICS_HPP
|
#endif //GRAPHICS_HPP
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
* Copyright (C) 2009 Artem Pavlenko
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -19,37 +19,41 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
//$Id$
|
//$Id$
|
||||||
|
|
||||||
#include <boost/python.hpp>
|
#ifndef MAPNIK_IMAGE_CACHE_HPP
|
||||||
|
#define MAPNIK_IMAGE_CACHE_HPP
|
||||||
|
|
||||||
#include <mapnik/spatial.hpp>
|
// mapnik
|
||||||
#include <mapnik/logical.hpp>
|
#include <mapnik/utils.hpp>
|
||||||
#include <mapnik/comparison.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/regex_filter.hpp>
|
#include <mapnik/image_data.hpp>
|
||||||
#include <mapnik/filter.hpp>
|
|
||||||
#include <mapnik/filter_factory.hpp>
|
|
||||||
|
|
||||||
using mapnik::filter;
|
// boost
|
||||||
using mapnik::filter_ptr;
|
#include <boost/utility.hpp>
|
||||||
using mapnik::filter_factory;
|
#include <boost/unordered_map.hpp>
|
||||||
using mapnik::Feature;
|
#include <boost/shared_ptr.hpp>
|
||||||
using mapnik::create_filter;
|
#include <boost/optional.hpp>
|
||||||
|
#include <boost/thread/mutex.hpp>
|
||||||
|
|
||||||
filter_ptr create_filter_(std::string const& wkt)
|
namespace mapnik
|
||||||
{
|
{
|
||||||
return create_filter(wkt,"utf8");
|
|
||||||
|
typedef boost::shared_ptr<image_data_32> image_ptr;
|
||||||
|
|
||||||
|
struct MAPNIK_DECL image_cache :
|
||||||
|
public singleton <image_cache, CreateStatic>,
|
||||||
|
private boost::noncopyable
|
||||||
|
{
|
||||||
|
|
||||||
|
friend class CreateStatic<image_cache>;
|
||||||
|
static boost::mutex mutex_;
|
||||||
|
static boost::unordered_map<std::string,image_ptr> cache_;
|
||||||
|
static bool insert(std::string const& key, image_ptr);
|
||||||
|
static boost::optional<image_ptr> find(std::string const& key, bool update_cache = false);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void export_filter()
|
#endif // MAPNIK_IMAGE_CACHE_HPP
|
||||||
{
|
|
||||||
using namespace boost::python;
|
|
||||||
class_<filter<Feature>,boost::noncopyable>("Filter",
|
|
||||||
"An expression which allows "
|
|
||||||
"to select features.",no_init)
|
|
||||||
.def("passes", &filter<Feature>::pass) // note: "pass" is a reserved word in Python
|
|
||||||
.def("__str__",&filter<Feature>::to_string);
|
|
||||||
;
|
|
||||||
|
|
||||||
def("Filter",&create_filter_);
|
|
||||||
}
|
|
|
@ -135,8 +135,8 @@ namespace mapnik
|
||||||
ImageData& operator=(const ImageData&);
|
ImageData& operator=(const ImageData&);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ImageData<unsigned> ImageData32;
|
typedef ImageData<unsigned> image_data_32;
|
||||||
typedef ImageData<byte> ImageData8;
|
typedef ImageData<byte> image_data_8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //IMAGE_DATA_HPP
|
#endif //IMAGE_DATA_HPP
|
||||||
|
|
|
@ -33,33 +33,33 @@
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
class ImageReaderException : public std::exception
|
class image_reader_exception : public std::exception
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string message_;
|
||||||
|
public:
|
||||||
|
image_reader_exception(const std::string& message)
|
||||||
|
: message_(message) {}
|
||||||
|
|
||||||
|
~image_reader_exception() throw() {}
|
||||||
|
|
||||||
|
virtual const char* what() const throw()
|
||||||
{
|
{
|
||||||
private:
|
return message_.c_str();
|
||||||
std::string message_;
|
}
|
||||||
public:
|
};
|
||||||
ImageReaderException(const std::string& message)
|
|
||||||
: message_(message) {}
|
|
||||||
|
|
||||||
~ImageReaderException() throw() {}
|
struct MAPNIK_DECL image_reader
|
||||||
|
{
|
||||||
|
virtual unsigned width() const=0;
|
||||||
|
virtual unsigned height() const=0;
|
||||||
|
virtual void read(unsigned x,unsigned y,image_data_32& image)=0;
|
||||||
|
virtual ~image_reader() {}
|
||||||
|
};
|
||||||
|
|
||||||
virtual const char* what() const throw()
|
bool register_image_reader(const std::string& type,image_reader* (*)(const std::string&));
|
||||||
{
|
MAPNIK_DECL image_reader* get_image_reader(const std::string& file,const std::string& type);
|
||||||
return message_.c_str();
|
MAPNIK_DECL image_reader* get_image_reader(const std::string& file);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MAPNIK_DECL ImageReader
|
|
||||||
{
|
|
||||||
virtual unsigned width() const=0;
|
|
||||||
virtual unsigned height() const=0;
|
|
||||||
virtual void read(unsigned x,unsigned y,ImageData32& image)=0;
|
|
||||||
virtual ~ImageReader() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool register_image_reader(const std::string& type,ImageReader* (*)(const std::string&));
|
|
||||||
MAPNIK_DECL ImageReader* get_image_reader(const std::string& file,const std::string& type);
|
|
||||||
MAPNIK_DECL ImageReader* get_image_reader(const std::string& file);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
// boost
|
// boost
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -92,16 +94,17 @@ namespace mapnik {
|
||||||
boost::algorithm::iends_with(filename,std::string(".tiff"));
|
boost::algorithm::iends_with(filename,std::string(".tiff"));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string type_from_filename(std::string const& filename)
|
inline boost::optional<std::string> type_from_filename(std::string const& filename)
|
||||||
{
|
{
|
||||||
if (is_png(filename)) return "png";
|
typedef boost::optional<std::string> result_type;
|
||||||
if (is_jpeg(filename)) return "jpeg";
|
if (is_png(filename)) return result_type("png");
|
||||||
if (is_tiff(filename)) return "tiff";
|
if (is_jpeg(filename)) return result_type("jpeg");
|
||||||
return "unknown";
|
if (is_tiff(filename)) return result_type("tiff");
|
||||||
}
|
return result_type();
|
||||||
|
}
|
||||||
|
|
||||||
inline std::string guess_type( const std::string & filename )
|
inline std::string guess_type( const std::string & filename )
|
||||||
{
|
{
|
||||||
std::string::size_type idx = filename.find_last_of(".");
|
std::string::size_type idx = filename.find_last_of(".");
|
||||||
if ( idx != std::string::npos ) {
|
if ( idx != std::string::npos ) {
|
||||||
return filename.substr( idx + 1 );
|
return filename.substr( idx + 1 );
|
||||||
|
@ -413,42 +416,42 @@ namespace mapnik {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MAPNIK_DECL void save_to_file (Image32 const& image,
|
inline MAPNIK_DECL void save_to_file (image_32 const& image,
|
||||||
std::string const& file,
|
std::string const& file,
|
||||||
std::string const& type)
|
std::string const& type)
|
||||||
{
|
{
|
||||||
save_to_file<ImageData32>(image.data(),file,type);
|
save_to_file<image_data_32>(image.data(),file,type);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MAPNIK_DECL void save_to_file(Image32 const& image,
|
inline MAPNIK_DECL void save_to_file(image_32 const& image,
|
||||||
std::string const& file)
|
std::string const& file)
|
||||||
{
|
{
|
||||||
save_to_file<ImageData32>(image.data(),file);
|
save_to_file<image_data_32>(image.data(),file);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MAPNIK_DECL std::string save_to_string(Image32 const& image,
|
inline MAPNIK_DECL std::string save_to_string(image_32 const& image,
|
||||||
std::string const& type)
|
std::string const& type)
|
||||||
{
|
{
|
||||||
return save_to_string<ImageData32>(image.data(),type);
|
return save_to_string<image_data_32>(image.data(),type);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
template MAPNIK_DECL void save_to_file<ImageData32>(ImageData32 const&,
|
template MAPNIK_DECL void save_to_file<image_data_32>(image_data_32 const&,
|
||||||
std::string const&,
|
std::string const&,
|
||||||
std::string const&);
|
std::string const&);
|
||||||
template MAPNIK_DECL void save_to_file<ImageData32>(ImageData32 const&,
|
template MAPNIK_DECL void save_to_file<image_data_32>(image_data_32 const&,
|
||||||
std::string const&);
|
std::string const&);
|
||||||
template MAPNIK_DECL std::string save_to_string<ImageData32>(ImageData32 const&,
|
template MAPNIK_DECL std::string save_to_string<image_data_32>(image_data_32 const&,
|
||||||
std::string const&);
|
std::string const&);
|
||||||
|
|
||||||
template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (image_view<ImageData32> const&,
|
template MAPNIK_DECL void save_to_file<image_view<image_data_32> > (image_view<image_data_32> const&,
|
||||||
std::string const&,
|
std::string const&,
|
||||||
std::string const&);
|
std::string const&);
|
||||||
|
|
||||||
template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (image_view<ImageData32> const&,
|
template MAPNIK_DECL void save_to_file<image_view<image_data_32> > (image_view<image_data_32> const&,
|
||||||
std::string const&);
|
std::string const&);
|
||||||
|
|
||||||
template MAPNIK_DECL std::string save_to_string<image_view<ImageData32> > (image_view<ImageData32> const&,
|
template MAPNIK_DECL std::string save_to_string<image_view<image_data_32> > (image_view<image_data_32> const&,
|
||||||
std::string const&);
|
std::string const&);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,9 @@ namespace mapnik
|
||||||
|
|
||||||
struct label_collision_detector
|
struct label_collision_detector
|
||||||
{
|
{
|
||||||
typedef std::vector<Envelope<double> > label_placements;
|
typedef std::vector<box2d<double> > label_placements;
|
||||||
|
|
||||||
bool has_plasement(Envelope<double> const& box)
|
bool has_plasement(box2d<double> const& box)
|
||||||
{
|
{
|
||||||
label_placements::const_iterator itr=labels_.begin();
|
label_placements::const_iterator itr=labels_.begin();
|
||||||
for( ; itr !=labels_.end();++itr)
|
for( ; itr !=labels_.end();++itr)
|
||||||
|
@ -66,14 +66,14 @@ namespace mapnik
|
||||||
// quad_tree based label collision detector
|
// quad_tree based label collision detector
|
||||||
class label_collision_detector2 : boost::noncopyable
|
class label_collision_detector2 : boost::noncopyable
|
||||||
{
|
{
|
||||||
typedef quad_tree<Envelope<double> > tree_t;
|
typedef quad_tree<box2d<double> > tree_t;
|
||||||
tree_t tree_;
|
tree_t tree_;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit label_collision_detector2(Envelope<double> const& extent)
|
explicit label_collision_detector2(box2d<double> const& extent)
|
||||||
: tree_(extent) {}
|
: tree_(extent) {}
|
||||||
|
|
||||||
bool has_placement(Envelope<double> const& box)
|
bool has_placement(box2d<double> const& box)
|
||||||
{
|
{
|
||||||
tree_t::query_iterator itr = tree_.query_in_box(box);
|
tree_t::query_iterator itr = tree_.query_in_box(box);
|
||||||
tree_t::query_iterator end = tree_.query_end();
|
tree_t::query_iterator end = tree_.query_end();
|
||||||
|
@ -100,14 +100,14 @@ namespace mapnik
|
||||||
// quad_tree based label collision detector with seperate check/insert
|
// quad_tree based label collision detector with seperate check/insert
|
||||||
class label_collision_detector3 : boost::noncopyable
|
class label_collision_detector3 : boost::noncopyable
|
||||||
{
|
{
|
||||||
typedef quad_tree< Envelope<double> > tree_t;
|
typedef quad_tree< box2d<double> > tree_t;
|
||||||
tree_t tree_;
|
tree_t tree_;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit label_collision_detector3(Envelope<double> const& extent)
|
explicit label_collision_detector3(box2d<double> const& extent)
|
||||||
: tree_(extent) {}
|
: tree_(extent) {}
|
||||||
|
|
||||||
bool has_placement(Envelope<double> const& box)
|
bool has_placement(box2d<double> const& box)
|
||||||
{
|
{
|
||||||
tree_t::query_iterator itr = tree_.query_in_box(box);
|
tree_t::query_iterator itr = tree_.query_in_box(box);
|
||||||
tree_t::query_iterator end = tree_.query_end();
|
tree_t::query_iterator end = tree_.query_end();
|
||||||
|
@ -123,7 +123,7 @@ namespace mapnik
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(Envelope<double> const& box)
|
void insert(box2d<double> const& box)
|
||||||
{
|
{
|
||||||
tree_.insert(box, box);
|
tree_.insert(box, box);
|
||||||
}
|
}
|
||||||
|
@ -140,24 +140,24 @@ namespace mapnik
|
||||||
{
|
{
|
||||||
struct label
|
struct label
|
||||||
{
|
{
|
||||||
label(Envelope<double> const& b) : box(b) {}
|
label(box2d<double> const& b) : box(b) {}
|
||||||
label(Envelope<double> const& b, UnicodeString const& t) : box(b), text(t) {}
|
label(box2d<double> const& b, UnicodeString const& t) : box(b), text(t) {}
|
||||||
|
|
||||||
Envelope<double> box;
|
box2d<double> box;
|
||||||
UnicodeString text;
|
UnicodeString text;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef quad_tree< label > tree_t;
|
typedef quad_tree< label > tree_t;
|
||||||
Envelope<double> extent_;
|
box2d<double> extent_;
|
||||||
tree_t tree_;
|
tree_t tree_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit label_collision_detector4(Envelope<double> const& extent)
|
explicit label_collision_detector4(box2d<double> const& extent)
|
||||||
: extent_(extent),
|
: extent_(extent),
|
||||||
tree_(extent) {}
|
tree_(extent) {}
|
||||||
|
|
||||||
bool has_placement(Envelope<double> const& box)
|
bool has_placement(box2d<double> const& box)
|
||||||
{
|
{
|
||||||
tree_t::query_iterator itr = tree_.query_in_box(box);
|
tree_t::query_iterator itr = tree_.query_in_box(box);
|
||||||
tree_t::query_iterator end = tree_.query_end();
|
tree_t::query_iterator end = tree_.query_end();
|
||||||
|
@ -173,9 +173,9 @@ namespace mapnik
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_placement(Envelope<double> const& box, UnicodeString const& text, double distance)
|
bool has_placement(box2d<double> const& box, UnicodeString const& text, double distance)
|
||||||
{
|
{
|
||||||
Envelope<double> bigger_box(box.minx() - distance, box.miny() - distance, box.maxx() + distance, box.maxy() + distance);
|
box2d<double> bigger_box(box.minx() - distance, box.miny() - distance, box.maxx() + distance, box.maxy() + distance);
|
||||||
tree_t::query_iterator itr = tree_.query_in_box(bigger_box);
|
tree_t::query_iterator itr = tree_.query_in_box(bigger_box);
|
||||||
tree_t::query_iterator end = tree_.query_end();
|
tree_t::query_iterator end = tree_.query_end();
|
||||||
|
|
||||||
|
@ -190,9 +190,9 @@ namespace mapnik
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_point_placement(Envelope<double> const& box, double distance)
|
bool has_point_placement(box2d<double> const& box, double distance)
|
||||||
{
|
{
|
||||||
Envelope<double> bigger_box(box.minx() - distance, box.miny() - distance, box.maxx() + distance, box.maxy() + distance);
|
box2d<double> bigger_box(box.minx() - distance, box.miny() - distance, box.maxx() + distance, box.maxy() + distance);
|
||||||
tree_t::query_iterator itr = tree_.query_in_box(bigger_box);
|
tree_t::query_iterator itr = tree_.query_in_box(bigger_box);
|
||||||
tree_t::query_iterator end = tree_.query_end();
|
tree_t::query_iterator end = tree_.query_end();
|
||||||
|
|
||||||
|
@ -207,12 +207,12 @@ namespace mapnik
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(Envelope<double> const& box)
|
void insert(box2d<double> const& box)
|
||||||
{
|
{
|
||||||
tree_.insert(label(box), box);
|
tree_.insert(label(box), box);
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(Envelope<double> const& box, UnicodeString const& text)
|
void insert(box2d<double> const& box, UnicodeString const& text)
|
||||||
{
|
{
|
||||||
tree_.insert(label(box, text), box);
|
tree_.insert(label(box, text), box);
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ namespace mapnik
|
||||||
tree_.clear();
|
tree_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Envelope<double> const& extent() const
|
box2d<double> const& extent() const
|
||||||
{
|
{
|
||||||
return extent_;
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue