+ merge mapnik2 to trunk

This commit is contained in:
Artem Pavlenko 2009-12-16 20:02:06 +00:00
parent 0ccdac028e
commit 47dc1e197b
220 changed files with 6656 additions and 11603 deletions

View file

@ -17,6 +17,8 @@ Mapnik 0.7.0 Release
- 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
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

View file

@ -93,6 +93,7 @@ PLUGINS = { # plugins with external dependencies
'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++'},
'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...
# 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('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('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
BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'),
@ -698,11 +701,11 @@ if not preconfigured:
BOOST_LIBSHEADERS.append(['thread', 'boost/thread/mutex.hpp', True])
# if the user is not setting custom boost configuration
# enforce boost version greater than or equal to 1.34
if not conf.CheckBoost('1.34'):
color_print (1,'Boost version 1.34 or greater is requred')
# enforce boost version greater than or equal to 1.41
if not conf.CheckBoost('1.41'):
color_print (1,'Boost version 1.41 or greater is requred')
if not env['BOOST_VERSION']:
env['MISSING_DEPS'].append('boost version >=1.34')
env['MISSING_DEPS'].append('boost version >=1.41')
else:
color_print (4,'Found boost lib version... %s' % boost_lib_version_from_header )
@ -783,7 +786,7 @@ if not preconfigured:
if 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," 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," $ sudo python scons/scons.py install")
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)
else:
# 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']:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags)

View file

@ -137,12 +137,12 @@ class _Coord(Coord,_injector):
"""
return inverse_(self, projection)
class _Envelope(Envelope,_injector):
class _Box2d(Box2d,_injector):
"""
Represents a spatial envelope (i.e. bounding box).
Following operators are defined for Envelope:
Following operators are defined for Box2d:
Addition:
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.
"""
def __repr__(self):
return 'Envelope(%s,%s,%s,%s)' % \
return 'Box2d(%s,%s,%s,%s)' % \
(self.minx,self.miny,self.maxx,self.maxy)
def forward(self, projection):
"""
@ -193,21 +193,21 @@ class _Projection(Projection,_injector):
return "Projection('%s')" % self.params()
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.
See also:
Envelope.forward(self, projection),
Box2d.forward(self, projection),
Coord.forward(self, projection).
"""
return forward_(obj,self)
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.
See also:
Envelope.inverse(self, projection),
Box2d.inverse(self, projection),
Coord.inverse(self, projection).
"""
return inverse_(obj,self)
@ -337,7 +337,7 @@ def Raster(**keywords):
hix -- highest (max) x/longitude 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:
base -- path prefix (default None)
@ -450,6 +450,26 @@ def SQLite(**keywords):
keywords['type'] = 'sqlite'
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):
"""Create a Osm Datasource.
@ -524,7 +544,7 @@ __all__ = [
# classes
'Color', 'Coord',
'DatasourceCache',
'Envelope',
'Box2d',
'Feature', 'Featureset', 'FontEngine',
'Geometry2d',
'Image', 'ImageView',
@ -537,7 +557,6 @@ __all__ = [
'PolygonPatternSymbolizer', 'PolygonSymbolizer',
'ProjTransform',
'Projection',
'Properties',
'Query',
'RasterSymbolizer',
'Rule', 'Rules',
@ -562,7 +581,8 @@ __all__ = [
'mapnik_version_string', 'mapnik_version', 'mapnik_svn_revision',
'has_cairo', 'has_pycairo',
# factory methods
'Filter',
'Expression',
'PathExpression',
# load/save/render
'load_map', 'load_map_from_string', 'save_map', 'save_map_to_string',
'render', 'render_tile_to_file', 'render_to_file',

View file

@ -22,7 +22,7 @@
"""Core OGCServer classes and functions."""
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.ImageDraw import Draw
from StringIO import StringIO
@ -409,7 +409,7 @@ class WMSBaseServiceHandler(BaseServiceHandler):
else:
raise ServerConfigurationError('Layer "%s" refers to non-existent style "%s".' % (layername, stylename))
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
class BaseExceptionHandler:

View file

@ -23,7 +23,7 @@
from common import ParameterDefinition, Response, Version, ListFactory, \
ColorFactory, CRSFactory, CRS, WMSBaseServiceHandler, \
BaseExceptionHandler, Projection, Envelope
BaseExceptionHandler, Projection, Box2d
from exceptions import OGCException, ServerConfigurationError
from mapnik import Coord
@ -238,7 +238,7 @@ class ServiceHandler(WMSBaseServiceHandler):
m = WMSBaseServiceHandler._buildMap(self, params)
# for range of epsg codes reverse axis
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
class ExceptionHandler(BaseExceptionHandler):

View file

@ -28,7 +28,7 @@
#include <vector>
// mapnik
#include <mapnik/envelope.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/feature_layer_desc.hpp>

View file

@ -25,15 +25,15 @@
#include <boost/python.hpp>
// mapnik
#include <mapnik/envelope.hpp>
#include <mapnik/box2d.hpp>
using mapnik::coord;
using mapnik::Envelope;
using mapnik::box2d;
struct envelope_pickle_suite : boost::python::pickle_suite
{
static boost::python::tuple
getinitargs(const Envelope<double>& e)
getinitargs(const box2d<double>& e)
{
using namespace boost::python;
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
void (Envelope<double>::*width_p1)(double) = &Envelope<double>::width;
double (Envelope<double>::*width_p2)() const = &Envelope<double>::width;
void (box2d<double>::*width_p1)(double) = &box2d<double>::width;
double (box2d<double>::*width_p2)() const = &box2d<double>::width;
void (Envelope<double>::*height_p1)(double) = &Envelope<double>::height;
double (Envelope<double>::*height_p2)() const = &Envelope<double>::height;
void (box2d<double>::*height_p1)(double) = &box2d<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 (Envelope<double>::*expand_to_include_p2)(coord<double,2> const& ) = &Envelope<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_p1)(double,double) = &box2d<double>::expand_to_include;
void (box2d<double>::*expand_to_include_p2)(coord<double,2> const& ) = &box2d<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 (Envelope<double>::*contains_p2)(coord<double,2> const&) const = &Envelope<double>::contains;
bool (Envelope<double>::*contains_p3)(Envelope<double> const&) const = &Envelope<double>::contains;
bool (box2d<double>::*contains_p1)(double,double) const = &box2d<double>::contains;
bool (box2d<double>::*contains_p2)(coord<double,2> const&) const = &box2d<double>::contains;
bool (box2d<double>::*contains_p3)(box2d<double> const&) const = &box2d<double>::contains;
//intersects
bool (Envelope<double>::*intersects_p1)(double,double) const = &Envelope<double>::intersects;
bool (Envelope<double>::*intersects_p2)(coord<double,2> const&) const = &Envelope<double>::intersects;
bool (Envelope<double>::*intersects_p3)(Envelope<double> const&) const = &Envelope<double>::intersects;
bool (box2d<double>::*intersects_p1)(double,double) const = &box2d<double>::intersects;
bool (box2d<double>::*intersects_p2)(coord<double,2> const&) const = &box2d<double>::intersects;
bool (box2d<double>::*intersects_p3)(box2d<double> const&) const = &box2d<double>::intersects;
// 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()
{
using namespace boost::python;
class_<Envelope<double> >("Envelope",
// class docstring is in mapnik/__init__.py, class _Coord
init<double,double,double,double>(
class_<box2d<double> >("Box2d",
// class docstring is in mapnik/__init__.py, class _Coord
init<double,double,double,double>(
(arg("minx"),arg("miny"),arg("maxx"),arg("maxy")),
"Constructs a new envelope from the coordinates\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>&>(
(arg("ll"),arg("ur")),
"Equivalent to Envelope(ll.x, ll.y, ur.x, ur.y).\n"))
.add_property("minx", &Envelope<double>::minx,
(arg("ll"),arg("ur")),
"Equivalent to box2d(ll.x, ll.y, ur.x, ur.y).\n"))
.add_property("minx", &box2d<double>::minx,
"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")
.add_property("maxx", &Envelope<double>::maxx,
.add_property("maxx", &box2d<double>::maxx,
"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")
.def("center", &Envelope<double>::center,
.def("center", &box2d<double>::center,
"Returns the coordinates of the center of the bounding box.\n"
"\n"
"Example:\n"
">>> e = Envelope(0, 0, 100, 100)\n"
">>> e = box2d(0, 0, 100, 100)\n"
">>> e.center()\n"
"Coord(50, 50)\n")
.def("center", &Envelope<double>::re_center,
.def("center", &box2d<double>::re_center,
(arg("x"), arg("y")),
"Moves the envelope so that the given coordinates become its new center.\n"
"The width and the height are preserved.\n"
"\n "
"Example:\n"
">>> e = Envelope(0, 0, 100, 100)\n"
">>> e = box2d(0, 0, 100, 100)\n"
">>> e.center(60, 60)\n"
">>> e.center()\n"
"Coord(60.0,60.0)\n"
">>> (e.width(), e.height())\n"
"(100.0, 100.0)\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,
(arg("new_width")),
"Sets the width to new_width of the envelope preserving its center.\n"
"\n "
"Example:\n"
">>> e = Envelope(0, 0, 100, 100)\n"
">>> e = box2d(0, 0, 100, 100)\n"
">>> e.width(120)\n"
">>> e.center()\n"
"Coord(50.0,50.0)\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,
"Returns the width of this envelope.\n"
)
)
.def("height", height_p1,
(arg("new_height")),
"Sets the height to new_height of the envelope preserving its center.\n"
"\n "
"Example:\n"
">>> e = Envelope(0, 0, 100, 100)\n"
">>> e = box2d(0, 0, 100, 100)\n"
">>> e.height(120)\n"
">>> e.center()\n"
"Coord(50.0,50.0)\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,
"Returns the height of this envelope.\n"
)
)
.def("expand_to_include",expand_to_include_p1,
(arg("x"),arg("y")),
"Expands this envelope to include the point given by x and y.\n"
"\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\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,
(arg("p")),
"Equivalent to expand_to_include(p.x, p.y)\n"
)
)
.def("expand_to_include",expand_to_include_p3,
(arg("other")),
"Equivalent to:\n"
" expand_to_include(other.minx, other.miny)\n"
" expand_to_include(other.maxx, other.maxy)\n"
)
)
.def("contains",contains_p1,
(arg("x"),arg("y")),
"Returns True iff this envelope contains the point\n"
"given by x and y.\n"
)
)
.def("contains",contains_p2,
(arg("p")),
"Equivalent to contains(p.x, p.y)\n"
)
)
.def("contains",contains_p3,
(arg("other")),
"Equivalent to:\n"
" contains(other.minx, other.miny) and contains(other.maxx, other.maxy)\n"
)
)
.def("intersects",intersects_p1,
(arg("x"),arg("y")),
"Returns True iff this envelope intersects the point\n"
@ -178,7 +178,7 @@ void export_envelope()
"Note: For points, intersection is equivalent\n"
"to containment, i.e. the following holds:\n"
" e.contains(x, y) == e.intersects(x, y)\n"
)
)
.def("intersects",intersects_p2,
(arg("p")),
"Equivalent to contains(p.x, p.y)\n")
@ -188,24 +188,24 @@ void export_envelope()
"This relationship is symmetric."
"\n"
"Example:\n"
">>> e1 = Envelope(0, 0, 100, 100)\n"
">>> e2 = Envelope(50, 50, 150, 150)\n"
">>> e1 = box2d(0, 0, 100, 100)\n"
">>> e2 = box2d(50, 50, 150, 150)\n"
">>> e1.intersects(e2)\n"
"True\n"
">>> e1.contains(e2)\n"
"False\n"
)
)
.def("intersect",intersect,
(arg("other")),
"Returns the overlap of this envelope and the other envelope\n"
"as a new envelope.\n"
"\n"
"Example:\n"
">>> e1 = Envelope(0, 0, 100, 100)\n"
">>> e2 = Envelope(50, 50, 150, 150)\n"
">>> e1 = box2d(0, 0, 100, 100)\n"
">>> e2 = box2d(50, 50, 150, 150)\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) // __add__
.def(self - self) // __sub__

View 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_);
}

View file

@ -30,197 +30,246 @@
#include <boost/scoped_array.hpp>
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
mapnik::geometry2d & (mapnik::Feature::*get_geom1)(unsigned) = &mapnik::Feature::get_geometry;
namespace boost { namespace python {
struct value_converter : public boost::static_visitor<PyObject*>
{
PyObject * operator() (int val) const
{
return ::PyInt_FromLong(val);
}
struct value_converter : public boost::static_visitor<PyObject*>
{
PyObject * operator() (int val) const
{
return ::PyInt_FromLong(val);
}
PyObject * operator() (double val) const
{
return ::PyFloat_FromDouble(val);
}
PyObject * operator() (double val) const
{
return ::PyFloat_FromDouble(val);
}
PyObject * operator() (UnicodeString const& s) const
{
std::string buffer;
mapnik::to_utf8(s,buffer);
PyObject *obj = Py_None;
obj = ::PyUnicode_DecodeUTF8(buffer.c_str(),implicit_cast<ssize_t>(buffer.length()),0);
return obj;
}
PyObject * operator() (UnicodeString const& s) const
{
std::string buffer;
mapnik::to_utf8(s,buffer);
PyObject *obj = Py_None;
obj = ::PyUnicode_DecodeUTF8(buffer.c_str(),implicit_cast<ssize_t>(buffer.length()),0);
return obj;
}
PyObject * operator() (mapnik::value_null const& s) const
{
return NULL;
}
};
PyObject * operator() (mapnik::value_null const& s) const
{
return NULL;
}
};
struct mapnik_value_to_python
{
static PyObject* convert(mapnik::value const& v)
{
return boost::apply_visitor(value_converter(),v.base());
}
};
struct mapnik_value_to_python
{
static PyObject* convert(mapnik::value const& v)
{
return boost::apply_visitor(value_converter(),v.base());
}
};
// Forward declaration
template <class Container, bool NoProxy, class DerivedPolicies>
class map_indexing_suite2;
// Forward declaration
template <class Container, bool NoProxy, class DerivedPolicies>
class map_indexing_suite2;
namespace detail
{
template <class Container, bool NoProxy>
class final_map_derived_policies
: public map_indexing_suite2<Container,
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> >();
}
};
}
namespace detail
{
template <class Container, bool NoProxy>
class final_map_derived_policies
: public map_indexing_suite2<Container,
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.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()
{
using namespace boost::python;
using mapnik::Feature;
using namespace boost::python;
using mapnik::Feature;
std_pair_to_python_converter<std::string const,mapnik::value>();
to_python_converter<mapnik::value,mapnik_value_to_python>();
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)
;
implicitly_convertible<int,mapnik::value>();
implicitly_convertible<double,mapnik::value>();
implicitly_convertible<UnicodeString,mapnik::value>();
implicitly_convertible<bool,mapnik::value>();
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> > ())
;
std_pair_to_python_converter<std::string const,mapnik::value>();
to_python_converter<mapnik::value,mapnik_value_to_python>();
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> > ())
// ;
}

View file

@ -43,52 +43,57 @@ extern "C"
#include <pycairo.h>
#endif
using mapnik::Image32;
using mapnik::ImageReader;
using mapnik::image_32;
using mapnik::image_reader;
using mapnik::get_image_reader;
using mapnik::type_from_filename;
using namespace boost::python;
using mapnik::save_to_file;
// output 'raw' pixels
PyObject* tostring1( Image32 const& im)
PyObject* tostring1( image_32 const& im)
{
int size = im.width() * im.height() * 4;
return ::PyString_FromStringAndSize((const char*)im.raw_data(),size);
}
// 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);
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_file2)( mapnik::Image32 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::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)));
if (reader.get())
{
boost::shared_ptr<Image32> image_ptr(new Image32(reader->width(),reader->height()));
reader->read(0,0,image_ptr->data());
return image_ptr;
}
throw mapnik::ImageReaderException("FIXME: " + filename);
boost::optional<std::string> type = type_from_filename(filename);
if (type)
{
std::auto_ptr<image_reader> reader(get_image_reader(filename,*type));
if (reader.get())
{
boost::shared_ptr<image_32> image_ptr(new image_32(reader->width(),reader->height()));
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);
}
#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));
boost::shared_ptr<Image32> image_ptr(new Image32(s));
boost::shared_ptr<image_32> image_ptr(new image_32(s));
return image_ptr;
}
#endif
@ -96,13 +101,13 @@ boost::shared_ptr<Image32> from_cairo(PycairoSurface* surface)
void export_image()
{
using namespace boost::python;
class_<Image32,boost::shared_ptr<Image32> >("Image","This class represents a 32 bit RGBA image.",init<int,int>())
.def("width",&Image32::width)
.def("height",&Image32::height)
.def("view",&Image32::get_view)
class_<image_32,boost::shared_ptr<image_32> >("Image","This class represents a 32 bit RGBA image.",init<int,int>())
.def("width",&image_32::width)
.def("height",&image_32::height)
.def("view",&image_32::get_view)
.add_property("background",make_function
(&Image32::getBackground,return_value_policy<copy_const_reference>()),
&Image32::setBackground, "The background color of the image.")
(&image_32::get_background,return_value_policy<copy_const_reference>()),
&image_32::set_background, "The background color of the image.")
.def("blend",&blend)
.def("tostring",&tostring1)
.def("tostring",&tostring2)

View file

@ -33,38 +33,38 @@ extern "C"
#include <mapnik/png_io.hpp>
#include <sstream>
using mapnik::ImageData32;
using mapnik::image_data_32;
using mapnik::image_view;
using mapnik::save_to_file;
// 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);
for (unsigned i=0;i<view.height();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());
}
// 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);
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_view2)(image_view<ImageData32> 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<image_data_32> const&, std::string const&) = mapnik::save_to_file;
void export_image_view()
{
using namespace boost::python;
class_<image_view<ImageData32> >("ImageView","A view into an image.",no_init)
.def("width",&image_view<ImageData32>::width)
.def("height",&image_view<ImageData32>::height)
class_<image_view<image_data_32> >("ImageView","A view into an image.",no_init)
.def("width",&image_view<image_data_32>::width)
.def("height",&image_view<image_data_32>::height)
.def("tostring",&view_tostring1)
.def("tostring",&view_tostring2)
.def("save",save_view1)

View file

@ -32,7 +32,7 @@
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
using mapnik::Layer;
using mapnik::layer;
using mapnik::parameters;
using mapnik::datasource_cache;
@ -40,13 +40,13 @@ using mapnik::datasource_cache;
struct layer_pickle_suite : boost::python::pickle_suite
{
static boost::python::tuple
getinitargs(const Layer& l)
getinitargs(const layer& l)
{
return boost::python::make_tuple(l.name(),l.srs());
}
static boost::python::tuple
getstate(const Layer& l)
getstate(const layer& l)
{
boost::python::list s;
std::vector<std::string> const& style_names = l.styles();
@ -58,7 +58,7 @@ struct layer_pickle_suite : boost::python::pickle_suite
}
static void
setstate (Layer& l, boost::python::tuple state)
setstate (layer& l, boost::python::tuple state)
{
using namespace boost::python;
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()
{
@ -123,7 +123,7 @@ void export_layer()
.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"
"\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("envelope",&Layer::envelope,
.def("envelope",&layer::envelope,
"Return the geographic envelope/bounding box."
"\n"
"Determined based on the layer datasource.\n"
@ -148,10 +148,10 @@ void export_layer()
">>> from mapnik import Layer\n"
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\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"
"\n"
"Otherwise returns False.\n"
@ -172,8 +172,8 @@ void export_layer()
)
.add_property("abstract",
make_function(&Layer::abstract,return_value_policy<copy_const_reference>()),
&Layer::set_abstract,
make_function(&layer::abstract,return_value_policy<copy_const_reference>()),
&layer::set_abstract,
"Get/Set the abstract of the layer.\n"
"\n"
"Usage:\n"
@ -187,8 +187,8 @@ void export_layer()
)
.add_property("active",
&Layer::isActive,
&Layer::setActive,
&layer::isActive,
&layer::setActive,
"Get/Set whether this layer is active and will be rendered.\n"
"\n"
"Usage:\n"
@ -202,8 +202,8 @@ void export_layer()
)
.add_property("clear_label_cache",
&Layer::clear_label_cache,
&Layer::set_clear_label_cache,
&layer::clear_label_cache,
&layer::set_clear_label_cache,
"Get/Set whether this layer's labels are cached.\n"
"\n"
"Usage:\n"
@ -211,8 +211,8 @@ void export_layer()
)
.add_property("datasource",
&Layer::datasource,
&Layer::set_datasource,
&layer::datasource,
&layer::set_datasource,
"The datasource attached to this layer.\n"
"\n"
"Usage:\n"
@ -224,8 +224,8 @@ void export_layer()
)
.add_property("maxzoom",
&Layer::getMaxZoom,
&Layer::setMaxZoom,
&layer::getMaxZoom,
&layer::setMaxZoom,
"Get/Set the maximum zoom lever of the layer.\n"
"\n"
"Usage:\n"
@ -239,8 +239,8 @@ void export_layer()
)
.add_property("minzoom",
&Layer::getMinZoom,
&Layer::setMinZoom,
&layer::getMinZoom,
&layer::setMinZoom,
"Get/Set the minimum zoom lever of the layer.\n"
"\n"
"Usage:\n"
@ -254,8 +254,8 @@ void export_layer()
)
.add_property("name",
make_function(&Layer::name, return_value_policy<copy_const_reference>()),
&Layer::set_name,
make_function(&layer::name, return_value_policy<copy_const_reference>()),
&layer::set_name,
"Get/Set the name of the layer.\n"
"\n"
"Usage:\n"
@ -269,13 +269,13 @@ void export_layer()
)
.add_property("queryable",
&Layer::isQueryable,
&Layer::setQueryable,
&layer::isQueryable,
&layer::setQueryable,
"Get/Set whether this layer is queryable.\n"
"\n"
"Usage:\n"
">>> from mapnik import Layer\n"
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
">>> from mapnik import layer\n"
">>> lyr = layer('My layer','+proj=latlong +datum=WGS84')\n"
">>> lyr.queryable\n"
"False # Not queryable by default\n"
">>> lyr.queryable = True\n"
@ -284,13 +284,13 @@ void export_layer()
)
.add_property("srs",
make_function(&Layer::srs,return_value_policy<copy_const_reference>()),
&Layer::set_srs,
make_function(&layer::srs,return_value_policy<copy_const_reference>()),
&layer::set_srs,
"Get/Set the SRS of the layer.\n"
"\n"
"Usage:\n"
">>> from mapnik import Layer\n"
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
">>> from mapnik import layer\n"
">>> lyr = layer('My layer','+proj=latlong +datum=WGS84')\n"
">>> lyr.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"
@ -303,8 +303,8 @@ void export_layer()
"The styles list attached to this layer.\n"
"\n"
"Usage:\n"
">>> from mapnik import Layer\n"
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
">>> from mapnik import layer\n"
">>> lyr = layer('My layer','+proj=latlong +datum=WGS84')\n"
">>> lyr.styles\n"
"<mapnik._mapnik.Names object at 0x6d3e8>\n"
">>> len(lyr.styles)\n"
@ -317,13 +317,13 @@ void export_layer()
)
.add_property("title",
make_function(&Layer::title, return_value_policy<copy_const_reference>()),
&Layer::set_title,
make_function(&layer::title, return_value_policy<copy_const_reference>()),
&layer::set_title,
"Get/Set the title of the layer.\n"
"\n"
"Usage:\n"
">>> from mapnik import Layer\n"
">>> lyr = Layer('My Layer','+proj=latlong +datum=WGS84')\n"
">>> from mapnik import layer\n"
">>> lyr = layer('My layer','+proj=latlong +datum=WGS84')\n"
">>> lyr.title\n"
"''\n"
">>> lyr.title = 'My first layer'\n"

View file

@ -22,19 +22,25 @@
//$Id$
#include <boost/python.hpp>
#include <mapnik/image_util.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::path_processor_type;
using mapnik::path_expression_ptr;
using mapnik::guess_type;
struct line_pattern_symbolizer_pickle_suite : boost::python::pickle_suite
{
static boost::python::tuple
getinitargs(const line_pattern_symbolizer& l)
{
boost::shared_ptr<mapnik::ImageData32> img = l.get_image();
const std::string & filename = l.get_filename();
return boost::python::make_tuple(filename,mapnik::guess_type(filename),img->width(),img->height());
std::string filename = path_processor_type::to_string(*l.get_filename());
// FIXME : Do we need "type" parameter at all ?
return boost::python::make_tuple(filename, guess_type(filename));
}
};
@ -43,8 +49,8 @@ void export_line_pattern_symbolizer()
using namespace boost::python;
class_<line_pattern_symbolizer>("LinePatternSymbolizer",
init<std::string const&,
std::string const&,unsigned,unsigned>("TODO"))
.def_pickle(line_pattern_symbolizer_pickle_suite())
init<path_expression_ptr>
("<image file expression>"))
//.def_pickle(line_pattern_symbolizer_pickle_suite())
;
}

View file

@ -36,8 +36,8 @@
using mapnik::color;
using mapnik::coord;
using mapnik::Envelope;
using mapnik::Layer;
using mapnik::box2d;
using mapnik::layer;
using mapnik::Map;
struct map_pickle_suite : boost::python::pickle_suite
@ -84,7 +84,7 @@ struct map_pickle_suite : boost::python::pickle_suite
throw_error_already_set();
}
Envelope<double> ext = extract<Envelope<double> >(state[0]);
box2d<double> ext = extract<box2d<double> >(state[0]);
m.zoomToBox(ext);
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]);
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]);
@ -109,8 +109,8 @@ struct map_pickle_suite : boost::python::pickle_suite
}
};
std::vector<Layer>& (Map::*layers_nonconst)() = &Map::layers;
std::vector<Layer> const& (Map::*layers_const)() const = &Map::layers;
std::vector<layer>& (Map::*layers_nonconst)() = &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)
@ -141,8 +141,8 @@ void export_map()
;
python_optional<mapnik::color> ();
class_<std::vector<Layer> >("Layers")
.def(vector_indexing_suite<std::vector<Layer> >())
class_<std::vector<layer> >("Layers")
.def(vector_indexing_suite<std::vector<layer> >())
;
class_<Map>("Map","The map object.",init<int,int,optional<std::string const&> >(
@ -178,30 +178,30 @@ void export_map()
.def("buffered_envelope",
&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"
"\n"
"Usage:\n"
">>> m = Map(600,400)\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"
"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.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",
make_function(&Map::getCurrentExtent,
return_value_policy<copy_const_reference>()),
"Return the Map Envelope object\n"
"Return the Map box2d object\n"
"and print the string representation\n"
"of the current extent of the map.\n"
"\n"
"Usage:\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"
"...'center', 'contains', 'expand_to_include', 'forward',\n"
"...'height', 'intersect', 'intersects', 'inverse', 'maxx',\n"
@ -285,7 +285,7 @@ void export_map()
)
.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"
"Usage:\n"
">>> m.remove_all()\n"
@ -343,10 +343,10 @@ void export_map()
.def("zoom_to_box",&Map::zoomToBox,
"Set the geographical extent of the map\n"
"by specifying a Mapnik Envelope.\n"
"by specifying a Mapnik box2d.\n"
"\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"
)
@ -401,9 +401,9 @@ void export_map()
"\n"
"Usage:\n"
">>> m.layers\n"
"<mapnik._mapnik.Layers object at 0x6d458>"
"<mapnik._mapnik.layers object at 0x6d458>"
">>> m.layers[0]\n"
"<mapnik._mapnik.Layer object at 0x5fe130>\n"
"<mapnik._mapnik.layer object at 0x5fe130>\n"
)
.add_property("srs",

View file

@ -25,25 +25,19 @@
#include <mapnik/graphics.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/point_symbolizer.hpp>
#include <mapnik/path_expression_grammar.hpp>
using mapnik::point_symbolizer;
using mapnik::symbolizer_with_image;
using mapnik::path_processor_type;
struct point_symbolizer_pickle_suite : boost::python::pickle_suite
{
static boost::python::tuple
getinitargs(const point_symbolizer& p)
{
boost::shared_ptr<mapnik::ImageData32> img = p.get_image();
const std::string & filename = p.get_filename();
if ( ! filename.empty() ) {
return boost::python::make_tuple(filename,mapnik::guess_type(filename),img->width(),img->height());
} else {
return boost::python::make_tuple();
}
std::string filename = path_processor_type::to_string(*p.get_filename());
return boost::python::make_tuple(filename,mapnik::guess_type(filename));
}
static boost::python::tuple
@ -74,12 +68,12 @@ struct point_symbolizer_pickle_suite : boost::python::pickle_suite
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()
@ -88,9 +82,8 @@ void export_point_symbolizer()
class_<point_symbolizer>("PointSymbolizer",
init<>("Default Point Symbolizer - 4x4 black square"))
.def (init<std::string const&,
std::string const&,unsigned,unsigned>("TODO"))
.def_pickle(point_symbolizer_pickle_suite())
.def (init<mapnik::path_expression_ptr>("<path expression ptr>"))
//.def_pickle(point_symbolizer_pickle_suite())
.add_property("filename",
// 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>()),

View file

@ -24,17 +24,20 @@
#include <boost/python.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/polygon_pattern_symbolizer.hpp>
#include <mapnik/path_expression_grammar.hpp>
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
{
static boost::python::tuple
getinitargs(const polygon_pattern_symbolizer& p)
{
boost::shared_ptr<mapnik::ImageData32> img = p.get_image();
const std::string & filename = p.get_filename();
return boost::python::make_tuple(filename,mapnik::guess_type(filename),img->width(),img->height());
{
std::string filename = path_processor_type::to_string(*p.get_filename());
return boost::python::make_tuple(filename,guess_type(filename));
}
};
@ -43,8 +46,6 @@ void export_polygon_pattern_symbolizer()
using namespace boost::python;
class_<polygon_pattern_symbolizer>("PolygonPatternSymbolizer",
init<std::string const&,
std::string const&,
unsigned,unsigned>("TODO"))
init<path_expression_ptr>("<path_expression_ptr>"))
.def_pickle(polygon_pattern_symbolizer_pickle_suite()) ;
}

View file

@ -59,7 +59,7 @@ namespace {
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 miny = box.miny();
@ -68,10 +68,10 @@ namespace {
double z = 0.0;
t.forward(minx,miny,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 miny = box.miny();
@ -80,7 +80,7 @@ namespace {
double z = 0.0;
t.backward(minx,miny,z);
t.backward(maxx,maxy,z);
return mapnik::Envelope<double>(minx,miny,maxx,maxy);
return mapnik::box2d<double>(minx,miny,maxx,maxy);
}
}

View file

@ -59,7 +59,7 @@ namespace {
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)
{
double minx = box.minx();
@ -68,10 +68,10 @@ namespace {
double maxy = box.maxy();
prj.forward(minx,miny);
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)
{
double minx = box.minx();
@ -80,7 +80,7 @@ namespace {
double maxy = box.maxy();
prj.inverse(minx,miny);
prj.inverse(maxx,maxy);
return mapnik::Envelope<double>(minx,miny,maxx,maxy);
return mapnik::box2d<double>(minx,miny,maxx,maxy);
}
}

View file

@ -38,7 +38,7 @@ void export_image();
void export_image_view();
void export_map();
void export_python();
void export_filter();
void export_expression();
void export_rule();
void export_style();
void export_stroke();
@ -77,12 +77,12 @@ void export_view_transform();
static Pycairo_CAPI_t *Pycairo_CAPI;
#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
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();
}
catch (...)
@ -93,12 +93,12 @@ void render(const mapnik::Map& map,mapnik::Image32& image, unsigned offset_x = 0
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
try
{
mapnik::agg_renderer<mapnik::Image32> ren(map,image);
mapnik::agg_renderer<mapnik::image_32> ren(map,image);
ren.apply();
}
catch (...)
@ -187,7 +187,7 @@ void render_tile_to_file(const mapnik::Map& map,
const std::string& file,
const std::string& format)
{
mapnik::Image32 image(width,height);
mapnik::image_32 image(width,height);
render(map,image,offset_x, offset_y);
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& format)
{
mapnik::Image32 image(map.getWidth(),map.getHeight());
mapnik::image_32 image(map.getWidth(),map.getHeight());
render(map,image,0,0);
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,
const std::string& filename)
{
mapnik::Image32 image(map.getWidth(),map.getHeight());
mapnik::image_32 image(map.getWidth(),map.getHeight());
render(map,image,0,0);
mapnik::save_to_file(image,filename);
}
@ -289,7 +289,7 @@ BOOST_PYTHON_MODULE(_mapnik)
export_envelope();
export_image();
export_image_view();
export_filter();
export_expression();
export_rule();
export_style();
export_layer();
@ -350,7 +350,7 @@ BOOST_PYTHON_MODULE(_mapnik)
def("render",&render,
"\n"
"Render Map to an AGG Image32 using offsets\n"
"Render Map to an AGG image_32 using offsets\n"
"\n"
"Usage:\n"
">>> from mapnik import Map, Image, render, load_map\n"
@ -363,7 +363,7 @@ BOOST_PYTHON_MODULE(_mapnik)
def("render",&render2,
"\n"
"Render Map to an AGG Image32\n"
"Render Map to an AGG image_32\n"
"\n"
"Usage:\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_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>();
}

View file

@ -23,9 +23,9 @@
#include <boost/python.hpp>
#include <mapnik/query.hpp>
#include <mapnik/envelope.hpp>
#include <mapnik/box2d.hpp>
using mapnik::query;
using mapnik::Envelope;
using mapnik::box2d;
struct query_pickle_suite : boost::python::pickle_suite
{
@ -41,7 +41,7 @@ void export_query()
using namespace boost::python;
class_<query>("Query", "a spatial query data object",
init<Envelope<double>,double>() )
init<box2d<double>,double>() )
.def_pickle(query_pickle_suite())
.add_property("resolution", &query::resolution)
.add_property("bbox", make_function(&query::get_bbox,

View file

@ -28,11 +28,11 @@
#include <mapnik/rule.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/expression_string.hpp>
using mapnik::rule_type;
using mapnik::filter;
using mapnik::filter_ptr;
using mapnik::filter_factory;
using mapnik::expr_node;
using mapnik::expression_ptr;
using mapnik::Feature;
using mapnik::point_symbolizer;
using mapnik::line_symbolizer;
@ -45,7 +45,7 @@ using mapnik::text_symbolizer;
using mapnik::building_symbolizer;
using mapnik::markers_symbolizer;
using mapnik::symbolizer;
using mapnik::symbolizers;
using mapnik::to_expression_string;
struct pickle_symbolizer : public boost::static_visitor<>
{
@ -93,14 +93,14 @@ struct rule_pickle_suite : boost::python::pickle_suite
{
boost::python::list syms;
symbolizers::const_iterator begin = r.get_symbolizers().begin();
symbolizers::const_iterator end = r.get_symbolizers().end();
rule_type::symbolizers::const_iterator begin = r.get_symbolizers().begin();
rule_type::symbolizers::const_iterator end = r.get_symbolizers().end();
pickle_symbolizer serializer( syms );
std::for_each( begin, end , boost::apply_visitor( serializer ));
// Here the filter string is used rather than the actual Filter object
// Need to look into how to get the Filter object
std::string filter_expr = r.get_filter()->to_string();
// We serialize filter expressions AST as strings
std::string filter_expr = to_expression_string(*r.get_filter());
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;
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)
{
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<text_symbolizer,symbolizer>();
class_<symbolizers>("Symbolizers",init<>("TODO"))
.def(vector_indexing_suite<symbolizers>())
class_<rule_type::symbolizers>("Symbolizers",init<>("TODO"))
.def(vector_indexing_suite<rule_type::symbolizers>())
;
class_<rule_type>("Rule",init<>("default constructor"))

View file

@ -25,22 +25,26 @@
#include <boost/python.hpp>
#include <mapnik/shield_symbolizer.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/path_expression_grammar.hpp>
using mapnik::color;
using mapnik::shield_symbolizer;
using mapnik::text_symbolizer;
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
{
static boost::python::tuple
getinitargs(const shield_symbolizer& s)
{
boost::shared_ptr<mapnik::ImageData32> img = s.get_image();
const std::string & filename = s.get_filename();
//(name, font name, font size, font color, image file, image type, width, height)
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());
std::string filename = path_processor_type::to_string(*s.get_filename());
//(name, font name, font size, font color, image file, image type, width, height)
return boost::python::make_tuple( "TODO",//s.get_name(),
s.get_face_name(),s.get_text_size(),s.get_fill(),filename,guess_type(filename));
}
@ -75,9 +79,9 @@ void export_shield_symbolizer()
{
using namespace boost::python;
class_< shield_symbolizer, bases<text_symbolizer> >("ShieldSymbolizer",
init< std::string const&, std::string const&, unsigned, mapnik::color const&,
std::string const&, std::string const&,unsigned,unsigned>("TODO"))
.def_pickle(shield_symbolizer_pickle_suite())
init<expression_ptr, std::string const&, unsigned, mapnik::color const&,
path_expression_ptr>("TODO"))
//.def_pickle(shield_symbolizer_pickle_suite())
;
}

View file

@ -62,7 +62,8 @@ struct text_symbolizer_pickle_suite : boost::python::pickle_suite
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());
}
@ -164,8 +165,8 @@ using namespace boost::python;
.value("TOLOWER",TOLOWER)
;
class_<text_symbolizer>("TextSymbolizer",init<std::string const&,std::string const&, unsigned,color const&>())
.def_pickle(text_symbolizer_pickle_suite())
class_<text_symbolizer>("TextSymbolizer",init<expression_ptr,std::string const&, unsigned,color const&>())
//.def_pickle(text_symbolizer_pickle_suite())
.def("anchor",&text_symbolizer::set_anchor)
.def("displacement",&text_symbolizer::set_displacement)
.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",
&text_symbolizer::get_minimum_distance,
&text_symbolizer::set_minimum_distance)
.add_property("name",
make_function(&text_symbolizer::get_name,return_value_policy<copy_const_reference>()),
&text_symbolizer::set_name)
//.add_property("name",
// make_function(&text_symbolizer::get_name,return_value_policy<copy_const_reference>()),
// &text_symbolizer::set_name)
.add_property("text_convert",
&text_symbolizer::get_text_convert,
&text_symbolizer::set_text_convert,

View file

@ -55,12 +55,12 @@ namespace {
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);
}
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);
}
@ -69,10 +69,10 @@ namespace {
void export_view_transform()
{
using namespace boost::python;
using mapnik::Envelope;
using mapnik::box2d;
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"))
.def_pickle(view_transform_pickle_suite())
.def("forward", forward_point)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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>("&lt;"); break;
case Ch('>'): r += detail::widen<Ch>("&gt;"); break;
case Ch('&'): r += detail::widen<Ch>("&amp;"); 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -66,12 +66,12 @@ int main ( int argc , char** argv)
feature_type_style provpoly_style;
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_style.add_rule(provpoly_rule_on);
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_style.add_rule(provpoly_rule_qc);
@ -95,7 +95,7 @@ int main ( int argc , char** argv)
feature_type_style qcdrain_style;
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_style.add_rule(qcdrain_rule);
@ -104,7 +104,7 @@ int main ( int argc , char** argv)
// Roads 3 and 4 (The "grey" roads)
feature_type_style roads34_style;
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);
roads34_rule_stk.set_line_cap(ROUND_CAP);
roads34_rule_stk.set_line_join(ROUND_JOIN);
@ -117,7 +117,7 @@ int main ( int argc , char** argv)
// Roads 2 (The thin yellow ones)
feature_type_style roads2_style_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);
roads2_rule_stk_1.set_line_cap(ROUND_CAP);
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;
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);
roads2_rule_stk_2.set_line_cap(ROUND_CAP);
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)
feature_type_style roads1_style_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);
roads1_rule_stk_1.set_line_cap(ROUND_CAP);
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;
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);
roads1_rule_stk_2.set_line_cap(ROUND_CAP);
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 );
// Layers
// layers
// Provincial polygons
{
parameters p;
p["type"]="shape";
p["file"]="../data/boundaries";
Layer lyr("Provinces");
layer lyr("Provinces");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("provinces");
m.addLayer(lyr);
@ -188,7 +188,7 @@ int main ( int argc , char** argv)
parameters p;
p["type"]="shape";
p["file"]="../data/qcdrainage";
Layer lyr("Quebec Hydrography");
layer lyr("Quebec Hydrography");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("drainage");
m.addLayer(lyr);
@ -199,7 +199,7 @@ int main ( int argc , char** argv)
p["type"]="shape";
p["file"]="../data/ontdrainage";
Layer lyr("Ontario Hydrography");
layer lyr("Ontario Hydrography");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("drainage");
m.addLayer(lyr);
@ -210,7 +210,7 @@ int main ( int argc , char** argv)
parameters p;
p["type"]="shape";
p["file"]="../data/boundaries_l";
Layer lyr("Provincial borders");
layer lyr("Provincial borders");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("provlines");
m.addLayer(lyr);
@ -221,7 +221,7 @@ int main ( int argc , char** argv)
parameters p;
p["type"]="shape";
p["file"]="../data/roads";
Layer lyr("Roads");
layer lyr("Roads");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("smallroads");
lyr.add_style("road-border");
@ -237,22 +237,22 @@ int main ( int argc , char** argv)
p["type"]="shape";
p["file"]="../data/popplaces";
p["encoding"] = "latin1";
Layer lyr("Populated Places");
layer lyr("Populated Places");
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.add_style("popplaces");
m.addLayer(lyr);
}
m.zoomToBox(Envelope<double>(1405120.04127408,-247003.813399447,
m.zoomToBox(box2d<double>(1405120.04127408,-247003.813399447,
1706357.31328276,-25098.593149577));
Image32 buf(m.getWidth(),m.getHeight());
agg_renderer<Image32> ren(m,buf);
image_32 buf(m.getWidth(),m.getHeight());
agg_renderer<image_32> ren(m,buf);
ren.apply();
save_to_file<ImageData32>(buf.data(),"demo.jpg","jpeg");
save_to_file<ImageData32>(buf.data(),"demo.png","png");
save_to_file<ImageData32>(buf.data(),"demo256.png","png256");
save_to_file<image_data_32>(buf.data(),"demo.jpg","jpeg");
save_to_file<image_data_32>(buf.data(),"demo.png","png");
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"
"- demo.jpg\n"
"- demo.png\n"
@ -267,7 +267,7 @@ int main ( int argc , char** argv)
png_render.apply();
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");
Cairo::RefPtr<Cairo::Surface> surface;

View file

@ -77,11 +77,11 @@ provpoly_style = mapnik.Style()
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.
# 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:
# - 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_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_style.rules.append(provpoly_rule_qc)
@ -129,7 +129,7 @@ qcdrain_lyr.datasource = mapnik.Shapefile(file='../data/qcdrainage')
qcdrain_style = mapnik.Style()
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_style.rules.append(qcdrain_rule)
@ -182,7 +182,7 @@ roads34_lyr.datasource = mapnik.Shapefile(file='../data/roads')
roads34_style = mapnik.Style()
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
# are closed off using line_cap as below.
@ -215,7 +215,7 @@ roads2_lyr.datasource = roads34_lyr.datasource
roads2_style_1 = mapnik.Style()
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.color = mapnik.Color(171,158,137)
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_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.color = mapnik.Color(255,250,115)
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_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.color = mapnik.Color(188,149,28)
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_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.color = mapnik.Color(242,191,36)
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
# 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',
10, mapnik.Color('black'))
@ -310,7 +310,7 @@ m.layers.append(popplaces_lyr)
# Draw map
# 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.
im = mapnik.Image(m.width,m.height)

View file

@ -69,7 +69,7 @@ m.layers.append(road_layer)
# Draw 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

View file

@ -70,7 +70,7 @@ m.layers.append(road_layer)
# Draw 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

View file

@ -71,7 +71,7 @@ m.layers.append(road_layer)
# Draw 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

View file

@ -69,7 +69,7 @@ m.layers.append(road_layer)
# Draw 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

View file

@ -90,7 +90,7 @@ bool LayerListModel::setData(const QModelIndex &index,
if (index.isValid() && role == Qt::CheckStateRole)
{
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);
emit dataChanged(index, index);
return true;
@ -107,15 +107,15 @@ Qt::ItemFlags LayerListModel::flags(QModelIndex const& index) const
return flags;
}
boost::optional<mapnik::Layer&> LayerListModel::map_layer(int i)
boost::optional<mapnik::layer&> LayerListModel::map_layer(int i)
{
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())
return boost::optional<mapnik::Layer&>(layers[i]);
return boost::optional<mapnik::layer&>(layers[i]);
}
return boost::optional<mapnik::Layer&>();
return boost::optional<mapnik::layer&>();
}

View file

@ -40,7 +40,7 @@ class LayerListModel : public QAbstractListModel
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole);
Qt::ItemFlags flags(QModelIndex const& index) const;
boost::optional<mapnik::Layer&> map_layer(int i);
boost::optional<mapnik::layer&> map_layer(int i);
private:
boost::shared_ptr<mapnik::Map> map_;

View file

@ -79,7 +79,7 @@ void LayerTab::layerInfo2(QModelIndex const& index)
QVector<QPair<QString,QString> > params;
unsigned i = index.row();
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)
{

View file

@ -41,8 +41,8 @@ int main( int argc, char **argv )
// modify this prefix based on your install location
std::string mapnik_dir = "/opt/mapnik";
datasource_cache::instance()->register_datasources(mapnik_dir + "/lib/mapnik/input");
boost::filesystem::path path(mapnik_dir + "/lib/mapnik/fonts");
datasource_cache::instance()->register_datasources(mapnik_dir + "/lib64/mapnik/input");
boost::filesystem::path path(mapnik_dir + "/lib64/mapnik/fonts");
boost::filesystem::directory_iterator end_itr;

View file

@ -140,7 +140,7 @@ void MainWindow::reload()
{
if (!filename_.isEmpty())
{
mapnik::Envelope<double> bbox = mapWidget_->getMap()->getCurrentExtent();
mapnik::box2d<double> bbox = mapWidget_->getMap()->getCurrentExtent();
load_map_file(filename_);
mapWidget_->zoomToBox(bbox);
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());
prj.forward(x0,y0);
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_);
std::cout << "SET DEFAULT EXT\n";
}

View file

@ -105,7 +105,7 @@ public slots:
QStatusBar *status;
QSlider * slider_;
mapnik::Envelope<double> default_extent_;
mapnik::box2d<double> default_extent_;
};

View file

@ -30,10 +30,10 @@
#include "mapwidget.hpp"
#include "info_dialog.hpp"
using mapnik::Image32;
using mapnik::image_32;
using mapnik::Map;
using mapnik::Layer;
using mapnik::Envelope;
using mapnik::layer;
using mapnik::box2d;
using mapnik::coord2d;
using mapnik::feature_ptr;
using mapnik::geometry_ptr;
@ -149,7 +149,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
{
if (int(index) != selectedLayer_) continue;
Layer & layer = map_->layers()[index];
layer & layer = map_->layers()[index];
if (!layer.isVisible(scale_denom)) continue;
std::string name = layer.name();
double x = e->x();
@ -187,7 +187,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
double x,y;
path.vertex(&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);
qpath.lineTo(x,y);
@ -216,7 +216,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
// remove annotation layer
map_->layers().erase(remove_if(map_->layers().begin(),
map_->layers().end(),
bind(&Layer::name,_1) == "*annotations*")
bind(&layer::name,_1) == "*annotations*")
, map_->layers().end());
}
}
@ -249,7 +249,7 @@ void MapWidget::mouseReleaseEvent(QMouseEvent* e)
if (map_)
{
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);
updateMap();
}
@ -273,7 +273,7 @@ void MapWidget::mouseReleaseEvent(QMouseEvent* e)
void MapWidget::keyPressEvent(QKeyEvent *e)
{
std::cout << "key pressed:"<<e->key()<<"\n";
std::cout << "key pressed:"<< e->key()<<"\n";
switch (e->key()) {
case Qt::Key_Minus:
zoomOut();
@ -324,11 +324,14 @@ void MapWidget::keyPressEvent(QKeyEvent *e)
case 57:
zoomToLevel(18);
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_)
{
@ -416,14 +419,14 @@ void MapWidget::zoomToLevel(int level)
{
double scale_denom = scales[level];
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 height= static_cast<double>(map_->getHeight());
mapnik::coord2d pt = ext.center();
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.x + 0.5 * width * 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&)
{
//Image32 image(width,height);
//image_32 image(width,height);
//agg_renderer renderer(map,image);
//renderer.apply();
//image.saveToFile(filename,type);
@ -448,8 +451,8 @@ void MapWidget::updateMap()
unsigned width=map_->getWidth();
unsigned height=map_->getHeight();
Image32 buf(width,height);
mapnik::agg_renderer<Image32> ren(*map_,buf);
image_32 buf(width,height);
mapnik::agg_renderer<image_32> ren(*map_,buf);
ren.apply();
QImage image((uchar*)buf.raw_data(),width,height,QImage::Format_ARGB32);

View file

@ -48,7 +48,7 @@ class MapWidget : public QWidget
boost::shared_ptr<mapnik::Map> map_;
int selected_;
QPixmap pix_;
mapnik::Envelope<double> extent_;
mapnik::box2d<double> extent_;
eTool cur_tool_;
int start_x_;
int start_y_;
@ -65,7 +65,7 @@ class MapWidget : public QWidget
inline QPixmap const& pixmap() const { return pix_;}
void setMap(boost::shared_ptr<mapnik::Map> map);
void defaultView();
void zoomToBox(mapnik::Envelope<double> const& box);
void zoomToBox(mapnik::box2d<double> const& box);
void zoomIn();
void zoomOut();
void panLeft();

View file

@ -182,13 +182,17 @@ struct symbolizer_icon : public boost::static_visitor<QIcon>
QIcon operator() (mapnik::point_symbolizer const& sym) const
{
boost::shared_ptr<mapnik::ImageData32> symbol = sym.get_image();
if (symbol)
{
QImage image(symbol->getBytes(),symbol->width(),symbol->height(),QImage::Format_ARGB32);
// FIXME!
/*
boost::shared_ptr<mapnik::image_data_32> symbol = sym.get_image();
if (symbol)
{
QImage image(symbol->getBytes(),
symbol->width(),symbol->height(),QImage::Format_ARGB32);
QPixmap pix = QPixmap::fromImage(image.rgbSwapped());
return QIcon(pix);
}
*/
return QIcon();
}
QIcon operator() (mapnik::line_symbolizer const& sym) const
@ -243,9 +247,9 @@ class rule_node
~rule_node() {}
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
@ -319,7 +323,7 @@ StyleModel::StyleModel(boost::shared_ptr<mapnik::Map> map, QObject * parent)
for ( ; itr2 != rules.end();++itr2)
{
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)
{
rule_n->add_child(new node(symbolizer_node(*itr3),rule_n));

View file

@ -5,14 +5,14 @@ CC = g++
TEMPLATE = app
INCLUDEPATH += /opt/mapnik/include
INCLUDEPATH += /opt/boost/include/boost-1_39
INCLUDEPATH += /opt/boost/include/
INCLUDEPATH += /usr/X11/include/
INCLUDEPATH += /usr/X11/include/freetype2
INCLUDEPATH += .
#QMAKE_CXXFLAGS +=' -DDARWIN'
unix:LIBS = -L/opt/mapnik/lib -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
QMAKE_CXXFLAGS +=' -DDARWIN -Wno-missing-field-initializers'
unix:LIBS = -L/opt/mapnik/lib64 -L/usr/X11/lib -lmapnik -lfreetype -L/usr/local/lib -licuuc
unix:LIBS += -lboost_system -lboost_filesystem -lboost_regex -L/opt/boost/lib
# Input

View file

@ -51,8 +51,8 @@ namespace mapnik {
~agg_renderer();
void start_map_processing(Map const& map);
void end_map_processing(Map const& map);
void start_layer_processing(Layer const& lay);
void end_layer_processing(Layer const& lay);
void start_layer_processing(layer const& lay);
void end_layer_processing(layer const& lay);
void process(point_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);

View file

@ -25,7 +25,7 @@
#ifndef ARROW_HPP
#define ARROW_HPP
#include <mapnik/envelope.hpp>
#include <mapnik/box2d.hpp>
namespace mapnik {
@ -35,7 +35,7 @@ namespace mapnik {
arrow();
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
Envelope<double> extent() const;
box2d<double> extent() const;
private:
unsigned pos_;
double x_[7];

View file

@ -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

View file

@ -26,77 +26,157 @@
#define ATTRIBUTE_COLLECTOR_HPP
// mapnik
#include <mapnik/filter.hpp>
#include <mapnik/expression.hpp>
#include <mapnik/feature_layer_desc.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
#include <set>
#include <iostream>
namespace mapnik {
struct symbolizer_attributes : public boost::static_visitor<>
struct expression_attributes : boost::static_visitor<void>
{
explicit expression_attributes(std::set<std::string> & names)
: names_(names) {}
void operator() (value_type const& x) const
{
symbolizer_attributes(std::set<std::string>& names)
: names_(names) {}
boost::ignore_unused_variable_warning(x);
}
template <typename T>
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>
void operator() (attribute const& attr) const
{
private:
std::set<std::string>& names_;
public:
names_.insert(attr.name());
}
attribute_collector(std::set<std::string>& names)
: names_(names) {}
template <typename Tag>
void operator() (binary_node<Tag> const& x) const
{
boost::apply_visitor(expression_attributes(names_),x.left);
boost::apply_visitor(expression_attributes(names_),x.right);
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());
}
}
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);
}
template <typename Tag>
void operator() (unary_node<Tag> const& x) const
{
boost::apply_visitor(expression_attributes(names_),x.expr);
}
virtual ~attribute_collector() {}
private:
// no copying
attribute_collector(attribute_collector const&);
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

View file

@ -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

View file

@ -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
#define ENVELOPE_HPP
#ifndef MAPNIK_BOX2D_HPP
#define MAPNIK_BOX2D_HPP
// mapnik
#include <mapnik/config.hpp>
@ -38,24 +38,24 @@ namespace mapnik {
/*!
* A spatial envelope (i.e. bounding box) which also defines some basic operators.
*/
template <typename T> class MAPNIK_DECL Envelope
: boost::addable<Envelope<T>,
boost::subtractable<Envelope<T>,
boost::dividable2<Envelope<T>, T,
boost::multipliable2<Envelope<T>, T > > > >
template <typename T> class MAPNIK_DECL box2d
: boost::addable<box2d<T>,
boost::subtractable<box2d<T>,
boost::dividable2<box2d<T>, T,
boost::multipliable2<box2d<T>, T > > > >
{
public:
typedef Envelope<T> EnvelopeType;
typedef box2d<T> box2d_type;
private:
T minx_;
T miny_;
T maxx_;
T maxy_;
public:
Envelope();
Envelope(T minx,T miny,T maxx,T maxy);
Envelope(const coord<T,2>& c0,const coord<T,2>& c1);
Envelope(const EnvelopeType& rhs);
box2d();
box2d(T minx,T miny,T maxx,T maxy);
box2d(const coord<T,2>& c0,const coord<T,2>& c1);
box2d(const box2d_type& rhs);
T minx() const;
T miny() const;
T maxx() const;
@ -67,34 +67,34 @@ namespace mapnik {
coord<T,2> center() const;
void expand_to_include(T x,T y);
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(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(T x,T y) const;
bool intersects(const EnvelopeType &other) const;
EnvelopeType intersect(const EnvelopeType& other) const;
bool operator==(const EnvelopeType &other) const;
bool intersects(const box2d_type &other) const;
box2d_type intersect(const box2d_type& other) const;
bool operator==(const box2d_type &other) const;
void re_center(T cx,T cy);
void init(T x0,T y0,T x1,T y1);
// define some operators
EnvelopeType& operator+=(EnvelopeType const& other);
EnvelopeType& operator-=(EnvelopeType const& other);
EnvelopeType& operator*=(T);
EnvelopeType& operator/=(T);
box2d_type& operator+=(box2d_type const& other);
box2d_type& operator-=(box2d_type const& other);
box2d_type& operator*=(T);
box2d_type& operator/=(T);
};
template <class charT,class traits,class T>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
const Envelope<T>& e)
const box2d<T>& e)
{
std::basic_ostringstream<charT,traits> s;
s.copyfmt(out);
s.width(0);
s <<"Envelope(" << std::setprecision(16)
s <<"box2d(" << std::setprecision(16)
<< e.minx() << "," << e.miny() <<","
<< e.maxx() << "," << e.maxy() <<")";
out << s.str();
@ -102,4 +102,4 @@ namespace mapnik {
}
}
#endif // ENVELOPE_HPP
#endif // MAPNIK_BOX2D_HPP

View file

@ -72,8 +72,8 @@ namespace mapnik {
public:
~cairo_renderer_base();
void start_map_processing(Map const& map);
void start_layer_processing(Layer const& lay);
void end_layer_processing(Layer const& lay);
void start_layer_processing(layer const& lay);
void end_layer_processing(layer const& lay);
void process(point_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);

View file

@ -30,7 +30,6 @@
#include <mapnik/global.hpp>
//boost
#include <boost/format.hpp>
#include <boost/cstdint.hpp>
// stl

View file

@ -22,46 +22,60 @@
//$Id$
#ifndef COLOR_FACTORY_HPP
#define COLOR_FACTORY_HPP
#ifndef MAPNIK_COLOR_FACTORY_HPP
#define MAPNIK_COLOR_FACTORY_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/color.hpp>
#include <mapnik/css_color_parser.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/css_color_grammar.hpp>
using namespace boost::spirit;
// boost
#include <boost/utility.hpp>
namespace mapnik {
class MAPNIK_DECL color_factory
class MAPNIK_DECL color_factory : boost::noncopyable
{
public:
static void init_from_string(color & c, char const* css_color)
{
public:
static void init_from_string(color & c, char const* css_color)
{
actions<color> a(c);
css_color_grammar<actions<color> > grammar(a);
parse_info<> info = parse(css_color, grammar, space_p);
if ( ! info.full) {
throw config_error(std::string("Failed to parse color value: ") +
"Expected a color, but got '" + css_color + "'");
}
}
typedef std::string::const_iterator iterator_type;
typedef mapnik::css_color_grammar<iterator_type> css_color_grammar;
std::string str(css_color);
static color from_string(char const* css_color)
{
color c;
init_from_string(c,css_color);
return c;
}
css_color_grammar g;
iterator_type first = str.begin();
iterator_type last = str.end();
mapnik::css css_;
bool result =
boost::spirit::qi::phrase_parse(first,
last,
g,
boost::spirit::ascii::space,
css_);
if (!result)
{
throw config_error(std::string("Failed to parse color value: ") +
"Expected a color, but got '" + css_color + "'");
}
// 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);
}
private:
color_factory();
color_factory(color_factory const&);
color_factory& operator=(color_factory const&);
};
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

View file

@ -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

View 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

View file

@ -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

View file

@ -27,7 +27,7 @@
#include <algorithm>
#include <mapnik/envelope.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord_array.hpp>
#include <mapnik/proj_transform.hpp>
@ -130,11 +130,11 @@ namespace mapnik {
int height_;
double sx_;
double sy_;
Envelope<double> extent_;
box2d<double> extent_;
double offset_x_;
double offset_y_;
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)
:width_(width),height_(height),extent_(extent),offset_x_(offset_x),offset_y_(offset_y)
{
@ -186,7 +186,7 @@ namespace mapnik {
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 y0 = e.miny();
@ -194,10 +194,10 @@ namespace mapnik {
double y1 = e.maxy();
forward(&x0,&y0);
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 y0 = e.miny();
@ -205,7 +205,7 @@ namespace mapnik {
double y1 = e.maxy();
backward(&x0,&y0);
backward(&x1,&y1);
return Envelope<double>(x0,y0,x1,y1);
return box2d<double>(x0,y0,x1,y1);
}
inline CoordinateArray& forward(CoordinateArray& coords) const
@ -225,7 +225,7 @@ namespace mapnik {
}
return coords;
}
inline Envelope<double> const& extent() const
inline box2d<double> const& extent() const
{
return extent_;
}

View file

@ -95,7 +95,7 @@ namespace mapnik {
virtual featureset_ptr features(const query& q) 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 ~datasource() {};
protected:

View file

@ -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

View 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

View 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

View 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

View file

@ -2,7 +2,7 @@
*
* 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
* modify it under the terms of the GNU Lesser General Public
@ -22,27 +22,18 @@
//$Id$
#ifndef FILTER_VISITOR_HPP
#define FILTER_VISITOR_HPP
#ifndef MAPNIK_EXPRESSION_STRING_HPP
#define MAPNIK_EXPRESSION_STRING_HPP
#include <mapnik/filter.hpp>
#include <mapnik/expression.hpp>
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/expression_node.hpp>
// stl
#include <string>
namespace mapnik
{
template <typename FeatureT> class filter;
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() {}
};
MAPNIK_DECL std::string to_expression_string(expr_node const& );
}
#endif //FILTER_VISITOR_HPP
#endif // MAPNIK_EXPRESSION_STRING_HPP

View file

@ -43,130 +43,130 @@
#include <map>
namespace mapnik {
typedef boost::shared_ptr<raster> raster_ptr;
typedef boost::associative_property_map<
std::map<std::string,value
> > properties;
typedef boost::shared_ptr<raster> raster_ptr;
typedef boost::associative_property_map<
std::map<std::string,value
> > properties;
template <typename T1,typename T2>
struct feature : public properties,
private boost::noncopyable
{
public:
typedef T1 geometry_type;
typedef T2 raster_type;
typedef std::map<std::string,value>::value_type value_type;
typedef std::map<std::string,value>::size_type size_type;
template <typename T1,typename T2>
struct feature : public properties,
private boost::noncopyable
{
public:
typedef T1 geometry_type;
typedef T2 raster_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>::difference_type difference_type;
private:
int id_;
boost::ptr_vector<geometry_type> geom_cont_;
raster_type raster_;
std::map<std::string,value> props_;
public:
typedef std::map<std::string,value>::iterator iterator;
explicit feature(int id)
: properties(props_),
id_(id),
geom_cont_(),
raster_() {}
private:
int id_;
boost::ptr_vector<geometry_type> geom_cont_;
raster_type raster_;
std::map<std::string,value> props_;
public:
typedef std::map<std::string,value>::iterator iterator;
explicit feature(int id)
: properties(props_),
id_(id),
geom_cont_(),
raster_() {}
//feature(int id,const geometry_type& geom)
// : properties(props_),
// id_(id),
// geom_(geom),
// raster_() {}
int id() const
{
return id_;
}
int id() const
{
return id_;
}
void add_geometry(geometry_type * geom)
{
geom_cont_.push_back(geom);
}
void add_geometry(geometry_type * geom)
{
geom_cont_.push_back(geom);
}
unsigned num_geometries() const
{
return geom_cont_.size();
}
unsigned num_geometries() const
{
return geom_cont_.size();
}
geometry_type const& get_geometry(unsigned index) const
{
return geom_cont_[index];
}
geometry_type const& get_geometry(unsigned index) const
{
return geom_cont_[index];
}
geometry_type& get_geometry(unsigned index)
{
return geom_cont_[index];
}
geometry_type& get_geometry(unsigned index)
{
return geom_cont_[index];
}
box2d<double> envelope() const
{
box2d<double> result;
for (unsigned i=0;i<num_geometries();++i)
{
geometry2d const& geom = get_geometry(i);
if (i==0)
{
box2d<double> box = geom.envelope();
result.init(box.minx(),box.miny(),box.maxx(),box.maxy());
}
else
{
result.expand_to_include(geom.envelope());
}
}
return result;
}
Envelope<double> envelope() const
{
Envelope<double> result;
for (unsigned i=0;i<num_geometries();++i)
{
geometry2d const& geom = get_geometry(i);
if (i==0)
{
Envelope<double> box = geom.envelope();
result.init(box.minx(),box.miny(),box.maxx(),box.maxy());
}
else
{
result.expand_to_include(geom.envelope());
}
}
return result;
}
const raster_type& get_raster() const
{
return raster_;
}
const raster_type& get_raster() const
{
return raster_;
}
void set_raster(raster_type const& raster)
{
raster_=raster;
}
void set_raster(raster_type const& raster)
{
raster_=raster;
}
std::map<std::string,value> const& props() const
{
return props_;
}
std::map<std::string,value> const& props() const
{
return props_;
}
std::map<std::string,value>& props()
{
return props_;
}
iterator begin() const
{
return props_.begin();
}
iterator begin()
{
return props_.begin();
}
iterator end() const
{
return props_.end();
}
iterator end()
{
return props_.end();
}
std::string to_string() const
{
std::stringstream ss;
ss << "feature (" << std::endl;
for (std::map<std::string,value>::const_iterator itr=props_.begin();
itr != props_.end();++itr)
{
ss << " " << itr->first << ":" << itr->second << std::endl;
}
ss << ")" << std::endl;
return ss.str();
}
};
std::string to_string() const
{
std::stringstream ss;
ss << "feature (" << std::endl;
for (std::map<std::string,value>::const_iterator itr=props_.begin();
itr != props_.end();++itr)
{
ss << " " << itr->first << ":" << itr->second << std::endl;
}
ss << ")" << std::endl;
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)
{
out << f.to_string();
return out;
}
inline std::ostream& operator<< (std::ostream & out,Feature const& f)
{
out << f.to_string();
return out;
}
}
#endif //FEATURE_HPP

View file

@ -26,234 +26,229 @@
#define FEATURE_STYLE_PROCESSOR_HPP
// mapnik
#include <mapnik/envelope.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/scale_denominator.hpp>
/*
#ifdef MAPNIK_DEBUG
#include <mapnik/wall_clock_timer.hpp>
//#include <mapnik/wall_clock_timer.hpp>
#endif
*/
//stl
#include <vector>
namespace mapnik
{
template <typename Processor>
class feature_style_processor
{
struct symbol_dispatch : public boost::static_visitor<>
{
symbol_dispatch (Processor & output,
Feature const& f,
proj_transform const& prj_trans)
: output_(output),
f_(f),
prj_trans_(prj_trans) {}
template <typename Processor>
class feature_style_processor
{
struct symbol_dispatch : public boost::static_visitor<>
{
symbol_dispatch (Processor & output,
Feature const& f,
proj_transform const& prj_trans)
: output_(output),
f_(f),
prj_trans_(prj_trans) {}
template <typename T>
void operator () (T const& sym) const
{
output_.process(sym,f_,prj_trans_);
}
template <typename T>
void operator () (T const& sym) const
{
output_.process(sym,f_,prj_trans_);
}
Processor & output_;
Feature const& f_;
proj_transform const& prj_trans_;
};
public:
feature_style_processor(Map const& m)
: m_(m) {}
Processor & output_;
Feature const& f_;
proj_transform const& prj_trans_;
};
public:
feature_style_processor(Map const& m)
: m_(m) {}
void apply()
{
/*
void apply()
{
#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
*/
Processor & p = static_cast<Processor&>(*this);
p.start_map_processing(m_);
Processor & p = static_cast<Processor&>(*this);
p.start_map_processing(m_);
try
{
projection proj(m_.srs()); // map projection
double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
try
{
projection proj(m_.srs()); // map projection
double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
#ifdef MAPNIK_DEBUG
std::clog << "scale denominator = " << scale_denom << "\n";
std::clog << "scale denominator = " << scale_denom << "\n";
#endif
std::vector<Layer>::const_iterator itr = m_.layers().begin();
std::vector<Layer>::const_iterator end = m_.layers().end();
std::vector<layer>::const_iterator itr = m_.layers().begin();
std::vector<layer>::const_iterator end = m_.layers().end();
while (itr != end)
{
if (itr->isVisible(scale_denom))
{
apply_to_layer(*itr, p, proj, scale_denom);
}
++itr;
}
}
catch (proj_init_error& ex)
{
std::clog << "proj_init_error:" << ex.what() << "\n";
}
while (itr != end)
{
if (itr->isVisible(scale_denom))
{
apply_to_layer(*itr, p, proj, scale_denom);
}
++itr;
}
}
catch (proj_init_error& ex)
{
std::clog << "proj_init_error:" << ex.what() << "\n";
}
p.end_map_processing(m_);
}
private:
void apply_to_layer(Layer const& lay, Processor & p,
projection const& proj0,double scale_denom)
{
/*
p.end_map_processing(m_);
}
private:
void apply_to_layer(layer const& lay, Processor & p,
projection const& proj0,double scale_denom)
{
#ifdef MAPNIK_DEBUG
wall_clock_progress_timer timer(clog, "end layer rendering: ");
//wall_clock_progress_timer timer(clog, "end layer rendering: ");
#endif
*/
p.start_layer_processing(lay);
boost::shared_ptr<datasource> ds=lay.datasource();
if (ds)
{
Envelope<double> ext = m_.get_buffered_extent();
projection proj1(lay.srs());
proj_transform prj_trans(proj0,proj1);
p.start_layer_processing(lay);
boost::shared_ptr<datasource> ds=lay.datasource();
if (ds)
{
box2d<double> ext = m_.get_buffered_extent();
projection proj1(lay.srs());
proj_transform prj_trans(proj0,proj1);
double mx0 = ext.minx();
double my0 = ext.miny();
double mz0 = 0.0;
double mx1 = ext.maxx();
double my1 = ext.maxy();
double mz1 = 0.0;
double mx0 = ext.minx();
double my0 = ext.miny();
double mz0 = 0.0;
double mx1 = ext.maxx();
double my1 = ext.maxy();
double mz1 = 0.0;
// project main map projection into layers extent
prj_trans.forward(mx0,my0,mz0);
prj_trans.forward(mx1,my1,mz1);
// project main map projection into layers extent
prj_trans.forward(mx0,my0,mz0);
prj_trans.forward(mx1,my1,mz1);
// if no intersection then nothing to do for layer
Envelope<double> layer_ext = lay.envelope();
if ( mx0 > layer_ext.maxx() || mx1 < layer_ext.minx() || my0 > layer_ext.maxy() || my1 < layer_ext.miny() )
{
return;
}
// if no intersection then nothing to do for layer
box2d<double> layer_ext = lay.envelope();
if ( mx0 > layer_ext.maxx() || mx1 < layer_ext.minx() || my0 > layer_ext.maxy() || my1 < layer_ext.miny() )
{
return;
}
// clip query bbox
mx0 = std::max(layer_ext.minx(),mx0);
my0 = std::max(layer_ext.miny(),my0);
mx1 = std::min(layer_ext.maxx(),mx1);
my1 = std::min(layer_ext.maxy(),my1);
// clip query bbox
mx0 = std::max(layer_ext.minx(),mx0);
my0 = std::max(layer_ext.miny(),my0);
mx1 = std::min(layer_ext.maxx(),mx1);
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();
query q(bbox,resolution,scale_denom); //BBOX query
double resolution = m_.getWidth()/bbox.width();
query q(bbox,resolution,scale_denom); //BBOX query
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 stylesEnd = style_names.end();
for (;stylesIter != stylesEnd; ++stylesIter)
{
std::set<std::string> names;
attribute_collector<Feature> collector(names);
std::vector<rule_type*> if_rules;
std::vector<rule_type*> else_rules;
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 stylesEnd = style_names.end();
for (;stylesIter != stylesEnd; ++stylesIter)
{
std::set<std::string> names;
attribute_collector collector(names);
std::vector<rule_type*> if_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);
if (!style) continue;
boost::optional<feature_type_style const&> style=m_.find_style(*stylesIter);
if (!style) continue;
const std::vector<rule_type>& rules=(*style).get_rules();
std::vector<rule_type>::const_iterator ruleIter=rules.begin();
std::vector<rule_type>::const_iterator ruleEnd=rules.end();
const std::vector<rule_type>& rules=(*style).get_rules();
std::vector<rule_type>::const_iterator ruleIter=rules.begin();
std::vector<rule_type>::const_iterator ruleEnd=rules.end();
for (;ruleIter!=ruleEnd;++ruleIter)
{
if (ruleIter->active(scale_denom))
{
for (;ruleIter!=ruleEnd;++ruleIter)
{
if (ruleIter->active(scale_denom))
{
active_rules=true;
ruleIter->accept(collector);
if (ruleIter->has_else_filter())
// collect unique attribute names
collector(*ruleIter);
if (ruleIter->has_else_filter())
{
else_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
else_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
}
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 namesEnd =names.end();
}
}
std::set<std::string>::const_iterator namesIter=names.begin();
std::set<std::string>::const_iterator namesEnd =names.end();
// push all property names
for (;namesIter!=namesEnd;++namesIter)
{
q.add_property_name(*namesIter);
}
if (active_rules)
{
featureset_ptr fs=ds->features(q);
if (fs)
{
// push all property names
for (;namesIter!=namesEnd;++namesIter)
{
q.add_property_name(*namesIter);
}
if (active_rules)
{
featureset_ptr fs=ds->features(q);
if (fs)
{
feature_ptr feature;
while ((feature = fs->next()))
{
bool do_else=true;
std::vector<rule_type*>::const_iterator itr=if_rules.begin();
std::vector<rule_type*>::const_iterator end=if_rules.end();
for (;itr != end;++itr)
{
filter_ptr const& filter=(*itr)->get_filter();
if (filter->pass(*feature))
{
do_else=false;
const symbolizers& symbols = (*itr)->get_symbolizers();
symbolizers::const_iterator symIter=symbols.begin();
symbolizers::const_iterator symEnd =symbols.end();
for (;symIter != symEnd;++symIter)
{
boost::apply_visitor
(symbol_dispatch(p,*feature,prj_trans),*symIter);
}
}
}
if (do_else)
{
//else filter
std::vector<rule_type*>::const_iterator itr=
else_rules.begin();
std::vector<rule_type*>::const_iterator end=
else_rules.end();
for (;itr != end;++itr)
{
const symbolizers& symbols = (*itr)->get_symbolizers();
symbolizers::const_iterator symIter= symbols.begin();
symbolizers::const_iterator symEnd = symbols.end();
bool do_else=true;
std::vector<rule_type*>::const_iterator itr=if_rules.begin();
std::vector<rule_type*>::const_iterator end=if_rules.end();
for (;itr != end;++itr)
{
expression_ptr const& expr=(*itr)->get_filter();
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
if (result.to_bool())
{
do_else=false;
const rule_type::symbolizers& symbols = (*itr)->get_symbolizers();
rule_type::symbolizers::const_iterator symIter=symbols.begin();
rule_type::symbolizers::const_iterator symEnd =symbols.end();
for (;symIter != symEnd;++symIter)
{
boost::apply_visitor
(symbol_dispatch(p,*feature,prj_trans),*symIter);
}
}
}
if (do_else)
{
//else filter
std::vector<rule_type*>::const_iterator itr=
else_rules.begin();
std::vector<rule_type*>::const_iterator end=
else_rules.end();
for (;itr != end;++itr)
{
const rule_type::symbolizers& symbols = (*itr)->get_symbolizers();
rule_type::symbolizers::const_iterator symIter= symbols.begin();
rule_type::symbolizers::const_iterator symEnd = symbols.end();
for (;symIter!=symEnd;++symIter)
{
boost::apply_visitor
(symbol_dispatch(p,*feature,prj_trans),*symIter);
}
}
}
for (;symIter!=symEnd;++symIter)
{
boost::apply_visitor
(symbol_dispatch(p,*feature,prj_trans),*symIter);
}
}
}
}
}
}
}
}
p.end_layer_processing(lay);
}
Map const& m_;
};
}
}
}
}
p.end_layer_processing(lay);
}
Map const& m_;
};
}
#endif //FEATURE_STYLE_PROCESSOR_HPP

View file

@ -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

View file

@ -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

View file

@ -2,7 +2,7 @@
*
* 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
* modify it under the terms of the GNU Lesser General Public
@ -22,51 +22,18 @@
//$Id$
#ifndef FILTER_FACTORY_HPP
#define FILTER_FACTORY_HPP
#ifndef MAPNIK_FILTER_FACTORY_HPP
#define MAPNIK_FILTER_FACTORY_HPP
#include <mapnik/config_error.hpp>
#include <mapnik/filter_parser.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/config.hpp>
#include <mapnik/expression_grammar.hpp>
namespace mapnik
{
using std::string;
template<typename FeatureT>
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);
MAPNIK_DECL expression_ptr parse_expression (std::string const& wkt, std::string const& encoding);
MAPNIK_DECL expression_ptr parse_expression (std::string const& wkt);
}
#endif //FILTER_FACTORY_HPP
#endif //MAPNIK_FILTER_FACTORY_HPP

View file

@ -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

View file

@ -358,9 +358,9 @@ namespace mapnik
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);
for (std::vector<std::string>::const_iterator name = names.begin(); name != names.end(); ++name)
{
@ -422,7 +422,7 @@ namespace mapnik
opacity_=opacity;
}
Envelope<double> prepare_glyphs(text_path *path)
box2d<double> prepare_glyphs(text_path *path)
{
//clear glyphs
glyphs_.clear();
@ -495,7 +495,7 @@ namespace mapnik
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)

View file

@ -34,18 +34,18 @@
namespace mapnik
{
class MAPNIK_DECL FontSet
class MAPNIK_DECL font_set
{
public:
FontSet();
FontSet(std::string const& name);
FontSet(FontSet const& rhs);
FontSet& operator=(FontSet const& rhs);
font_set();
font_set(std::string const& name);
font_set(font_set const& rhs);
font_set& operator=(font_set const& rhs);
unsigned size() const;
std::string const& get_name() const;
void add_face_name(std::string);
std::vector<std::string> const& get_face_names() const;
~FontSet();
~font_set();
private:
std::string name_;
std::vector<std::string> face_names_;

View file

@ -25,7 +25,7 @@
#ifndef GEOM_UTIL_HPP
#define GEOM_UTIL_HPP
// mapnik
#include <mapnik/envelope.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/vertex.hpp>
// boost
#include <boost/tuple/tuple.hpp>
@ -55,7 +55,7 @@ namespace mapnik
}
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 tmax=1.0;
@ -195,11 +195,11 @@ namespace mapnik
// filters
struct filter_in_box
{
Envelope<double> box_;
explicit filter_in_box(const Envelope<double>& box)
box2d<double> box_;
explicit filter_in_box(const box2d<double>& box)
: box_(box) {}
bool pass(const Envelope<double>& extent) const
bool pass(const box2d<double>& extent) const
{
return extent.intersects(box_);
}
@ -210,7 +210,7 @@ namespace mapnik
coord2d pt_;
explicit filter_at_point(const coord2d& pt)
: pt_(pt) {}
bool pass(const Envelope<double>& extent) const
bool pass(const box2d<double>& extent) const
{
return extent.contains(pt_);
}

View file

@ -51,9 +51,9 @@ namespace mapnik {
public:
geometry () {}
Envelope<double> envelope() const
box2d<double> envelope() const
{
Envelope<double> result;
box2d<double> result;
double x,y;
rewind(0);
for (unsigned i=0;i<num_points();++i)

View file

@ -28,7 +28,7 @@
#include <mapnik/color.hpp>
#include <mapnik/gamma.hpp>
#include <mapnik/image_data.hpp>
#include <mapnik/envelope.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/image_view.hpp>
#include <mapnik/global.hpp>
@ -45,424 +45,424 @@
namespace mapnik
{
struct Multiply
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
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
struct Multiply
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
private:
unsigned width_;
unsigned height_;
color background_;
ImageData32 data_;
public:
Image32(int width,int height);
Image32(Image32 const& rhs);
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 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
Image32(Cairo::RefPtr<Cairo::ImageSurface> rhs);
image_32(Cairo::RefPtr<Cairo::ImageSurface> rhs);
#endif
~Image32();
void setBackground(color const& background);
const color& getBackground() const;
const ImageData32& data() const;
~image_32();
void set_background(color const& background);
const color& get_background() const;
const image_data_32& data() const;
inline ImageData32& data()
{
return data_;
}
inline image_data_32& data()
{
return data_;
}
inline const unsigned char* raw_data() const
{
return data_.getBytes();
}
inline const unsigned char* raw_data() const
{
return data_.getBytes();
}
inline unsigned char* raw_data()
{
return data_.getBytes();
}
inline unsigned char* raw_data()
{
return data_.getBytes();
}
inline image_view<ImageData32> get_view(unsigned x,unsigned y, unsigned w,unsigned h)
{
return image_view<ImageData32>(x,y,w,h,data_);
}
inline image_view<image_data_32> get_view(unsigned x,unsigned y, unsigned w,unsigned h)
{
return image_view<image_data_32>(x,y,w,h,data_);
}
private:
private:
inline bool checkBounds(unsigned x, unsigned y) const
{
return (x < width_ && y < height_);
}
inline bool checkBounds(unsigned x, unsigned y) const
{
return (x < width_ && y < height_);
}
public:
inline void setPixel(int x,int y,unsigned int rgba)
{
if (checkBounds(x,y))
{
data_(x,y)=rgba;
}
}
inline void blendPixel(int x,int y,unsigned int rgba1,int t)
{
blendPixel2(x,y,rgba1,t,1.0); // do not change opacity
}
public:
inline void setPixel(int x,int y,unsigned int rgba)
{
if (checkBounds(x,y))
{
data_(x,y)=rgba;
}
}
inline void blendPixel(int x,int y,unsigned int rgba1,int t)
{
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)
{
if (checkBounds(x,y))
{
unsigned rgba0 = data_(x,y);
inline void blendPixel2(int x,int y,unsigned int rgba1,int t,double opacity)
{
if (checkBounds(x,y))
{
unsigned rgba0 = data_(x,y);
#ifdef MAPNIK_BIG_ENDIAN
unsigned a1 = (int)((rgba1 & 0xff) * opacity) & 0xff; // adjust for desired opacity
a1 = (t*a1) / 255;
if (a1 == 0) return;
unsigned r1 = (rgba1 >> 24) & 0xff;
unsigned g1 = (rgba1 >> 16 ) & 0xff;
unsigned b1 = (rgba1 >> 8) & 0xff;
unsigned a1 = (int)((rgba1 & 0xff) * opacity) & 0xff; // adjust for desired opacity
a1 = (t*a1) / 255;
if (a1 == 0) return;
unsigned r1 = (rgba1 >> 24) & 0xff;
unsigned g1 = (rgba1 >> 16 ) & 0xff;
unsigned b1 = (rgba1 >> 8) & 0xff;
unsigned a0 = (rgba0 & 0xff);
unsigned r0 = ((rgba0 >> 24 ) & 0xff) * a0;
unsigned g0 = ((rgba0 >> 16 ) & 0xff) * a0;
unsigned b0 = ((rgba0 >> 8) & 0xff) * a0;
unsigned a0 = (rgba0 & 0xff);
unsigned r0 = ((rgba0 >> 24 ) & 0xff) * a0;
unsigned g0 = ((rgba0 >> 16 ) & 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);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
data_(x,y)= (a0)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
data_(x,y)= (a0)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
#else
unsigned a1 = (int)(((rgba1 >> 24) & 0xff) * opacity) & 0xff; // adjust for desired opacity
a1 = (t*a1) / 255;
if (a1 == 0) return;
unsigned r1 = rgba1 & 0xff;
unsigned g1 = (rgba1 >> 8 ) & 0xff;
unsigned b1 = (rgba1 >> 16) & 0xff;
unsigned a1 = (int)(((rgba1 >> 24) & 0xff) * opacity) & 0xff; // adjust for desired opacity
a1 = (t*a1) / 255;
if (a1 == 0) return;
unsigned r1 = rgba1 & 0xff;
unsigned g1 = (rgba1 >> 8 ) & 0xff;
unsigned b1 = (rgba1 >> 16) & 0xff;
unsigned a0 = (rgba0 >> 24) & 0xff;
unsigned r0 = (rgba0 & 0xff) * a0;
unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
unsigned a0 = (rgba0 >> 24) & 0xff;
unsigned r0 = (rgba0 & 0xff) * a0;
unsigned g0 = ((rgba0 >> 8 ) & 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);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
data_(x,y)= (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
data_(x,y)= (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
#endif
}
}
}
}
inline unsigned width() const
{
return width_;
}
inline unsigned width() const
{
return width_;
}
inline unsigned height() const
{
return height_;
}
inline unsigned height() const
{
return height_;
}
inline void set_rectangle(int x0,int y0,ImageData32 const& data)
{
Envelope<int> ext0(0,0,width_,height_);
Envelope<int> ext1(x0,y0,x0+data.width(),y0+data.height());
inline void set_rectangle(int x0,int y0,image_data_32 const& data)
{
box2d<int> ext0(0,0,width_,height_);
box2d<int> ext1(x0,y0,x0+data.width(),y0+data.height());
if (ext0.intersects(ext1))
{
Envelope<int> box = ext0.intersect(ext1);
for (int y = box.miny(); y < box.maxy(); ++y)
{
unsigned int* row_to = data_.getRow(y);
unsigned int const * row_from = data.getRow(y-y0);
if (ext0.intersects(ext1))
{
box2d<int> box = ext0.intersect(ext1);
for (int y = box.miny(); y < box.maxy(); ++y)
{
unsigned int* row_to = data_.getRow(y);
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
row_to[x] = row_from[x-x0];
row_to[x] = row_from[x-x0];
#else
if (row_from[x-x0] & 0xff000000)
{
if (row_from[x-x0] & 0xff000000)
{
row_to[x] = row_from[x-x0];
}
}
#endif
}
}
}
}
}
}
}
}
inline void set_rectangle_alpha(int x0,int y0,const ImageData32& data)
{
Envelope<int> ext0(0,0,width_,height_);
Envelope<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
inline void set_rectangle_alpha(int x0,int y0,const image_data_32& data)
{
box2d<int> ext0(0,0,width_,height_);
box2d<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
if (ext0.intersects(ext1))
{
Envelope<int> box = ext0.intersect(ext1);
for (int y = box.miny(); y < box.maxy(); ++y)
{
unsigned int* row_to = data_.getRow(y);
unsigned int const * row_from = data.getRow(y-y0);
for (int x = box.minx(); x < box.maxx(); ++x)
{
unsigned rgba0 = row_to[x];
unsigned rgba1 = row_from[x-x0];
if (ext0.intersects(ext1))
{
box2d<int> box = ext0.intersect(ext1);
for (int y = box.miny(); y < box.maxy(); ++y)
{
unsigned int* row_to = data_.getRow(y);
unsigned int const * row_from = data.getRow(y-y0);
for (int x = box.minx(); x < box.maxx(); ++x)
{
unsigned rgba0 = row_to[x];
unsigned rgba1 = row_from[x-x0];
#ifdef MAPNIK_BIG_ENDIAN
unsigned a1 = rgba1 & 0xff;
if (a1 == 0) continue;
unsigned r1 = (rgba1 >> 24) & 0xff;
unsigned g1 = (rgba1 >> 16 ) & 0xff;
unsigned b1 = (rgba1 >> 8) & 0xff;
unsigned a1 = rgba1 & 0xff;
if (a1 == 0) continue;
unsigned r1 = (rgba1 >> 24) & 0xff;
unsigned g1 = (rgba1 >> 16 ) & 0xff;
unsigned b1 = (rgba1 >> 8) & 0xff;
unsigned a0 = rgba0 & 0xff;
unsigned r0 = ((rgba0 >> 24) & 0xff) * a0;
unsigned g0 = ((rgba0 >> 16 ) & 0xff) * a0;
unsigned b0 = ((rgba0 >> 8) & 0xff) * a0;
unsigned a0 = rgba0 & 0xff;
unsigned r0 = ((rgba0 >> 24) & 0xff) * a0;
unsigned g0 = ((rgba0 >> 16 ) & 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);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
row_to[x] = (a0) | (b0 << 8) | (g0 << 16) | (r0 << 24) ;
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
row_to[x] = (a0) | (b0 << 8) | (g0 << 16) | (r0 << 24) ;
#else
unsigned a1 = (rgba1 >> 24) & 0xff;
if (a1 == 0) continue;
unsigned r1 = rgba1 & 0xff;
unsigned g1 = (rgba1 >> 8 ) & 0xff;
unsigned b1 = (rgba1 >> 16) & 0xff;
unsigned a1 = (rgba1 >> 24) & 0xff;
if (a1 == 0) continue;
unsigned r1 = rgba1 & 0xff;
unsigned g1 = (rgba1 >> 8 ) & 0xff;
unsigned b1 = (rgba1 >> 16) & 0xff;
unsigned a0 = (rgba0 >> 24) & 0xff;
unsigned r0 = (rgba0 & 0xff) * a0;
unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
unsigned a0 = (rgba0 >> 24) & 0xff;
unsigned r0 = (rgba0 & 0xff) * a0;
unsigned g0 = ((rgba0 >> 8 ) & 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);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
row_to[x] = (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
row_to[x] = (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
#endif
}
}
}
}
}
}
}
}
inline void set_rectangle_alpha2(ImageData32 const& data, unsigned x0, unsigned y0, float opacity)
{
Envelope<int> ext0(0,0,width_,height_);
Envelope<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
inline void set_rectangle_alpha2(image_data_32 const& data, unsigned x0, unsigned y0, float opacity)
{
box2d<int> ext0(0,0,width_,height_);
box2d<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
if (ext0.intersects(ext1))
{
Envelope<int> box = ext0.intersect(ext1);
for (int y = box.miny(); y < box.maxy(); ++y)
{
unsigned int* row_to = data_.getRow(y);
unsigned int const * row_from = data.getRow(y-y0);
for (int x = box.minx(); x < box.maxx(); ++x)
{
unsigned rgba0 = row_to[x];
unsigned rgba1 = row_from[x-x0];
if (ext0.intersects(ext1))
{
box2d<int> box = ext0.intersect(ext1);
for (int y = box.miny(); y < box.maxy(); ++y)
{
unsigned int* row_to = data_.getRow(y);
unsigned int const * row_from = data.getRow(y-y0);
for (int x = box.minx(); x < box.maxx(); ++x)
{
unsigned rgba0 = row_to[x];
unsigned rgba1 = row_from[x-x0];
#ifdef MAPNIK_BIG_ENDIAN
unsigned a1 = int( (rgba1 & 0xff) * opacity );
if (a1 == 0) continue;
unsigned r1 = (rgba1 >> 24) & 0xff;
unsigned g1 = (rgba1 >> 16 ) & 0xff;
unsigned b1 = (rgba1 >> 8) & 0xff;
unsigned a1 = int( (rgba1 & 0xff) * opacity );
if (a1 == 0) continue;
unsigned r1 = (rgba1 >> 24) & 0xff;
unsigned g1 = (rgba1 >> 16 ) & 0xff;
unsigned b1 = (rgba1 >> 8) & 0xff;
unsigned a0 = rgba0 & 0xff;
unsigned r0 = (rgba0 >> 24) & 0xff ;
unsigned g0 = (rgba0 >> 16 ) & 0xff;
unsigned b0 = (rgba0 >> 8) & 0xff;
unsigned a0 = rgba0 & 0xff;
unsigned r0 = (rgba0 >> 24) & 0xff ;
unsigned g0 = (rgba0 >> 16 ) & 0xff;
unsigned b0 = (rgba0 >> 8) & 0xff;
r0 = uint8_t(((r1 - r0) * a1 + (r0 << 8)) >> 8);
g0 = uint8_t(((g1 - g0) * a1 + (g0 << 8)) >> 8);
b0 = uint8_t(((b1 - b0) * a1 + (b0 << 8)) >> 8);
a0 = uint8_t((a1 + a0) - ((a1 * a0 + 255) >> 8));
r0 = uint8_t(((r1 - r0) * a1 + (r0 << 8)) >> 8);
g0 = uint8_t(((g1 - g0) * a1 + (g0 << 8)) >> 8);
b0 = uint8_t(((b1 - b0) * a1 + (b0 << 8)) >> 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
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
if (a1 == 0) continue;
unsigned r1 = rgba1 & 0xff;
unsigned g1 = (rgba1 >> 8 ) & 0xff;
unsigned b1 = (rgba1 >> 16) & 0xff;
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
if (a1 == 0) continue;
unsigned r1 = rgba1 & 0xff;
unsigned g1 = (rgba1 >> 8 ) & 0xff;
unsigned b1 = (rgba1 >> 16) & 0xff;
unsigned a0 = (rgba0 >> 24) & 0xff;
unsigned r0 = rgba0 & 0xff ;
unsigned g0 = (rgba0 >> 8 ) & 0xff;
unsigned b0 = (rgba0 >> 16) & 0xff;
unsigned a0 = (rgba0 >> 24) & 0xff;
unsigned r0 = rgba0 & 0xff ;
unsigned g0 = (rgba0 >> 8 ) & 0xff;
unsigned b0 = (rgba0 >> 16) & 0xff;
r0 = uint8_t(((r1 - r0) * a1 + (r0 << 8)) >> 8);
g0 = uint8_t(((g1 - g0) * a1 + (g0 << 8)) >> 8);
b0 = uint8_t(((b1 - b0) * a1 + (b0 << 8)) >> 8);
a0 = uint8_t((a1 + a0) - ((a1 * a0 + 255) >> 8));
r0 = uint8_t(((r1 - r0) * a1 + (r0 << 8)) >> 8);
g0 = uint8_t(((g1 - g0) * a1 + (g0 << 8)) >> 8);
b0 = uint8_t(((b1 - b0) * a1 + (b0 << 8)) >> 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
}
}
}
}
}
}
}
}
template <typename MergeMethod>
inline void merge_rectangle(ImageData32 const& data, unsigned x0, unsigned y0, float opacity)
{
Envelope<int> ext0(0,0,width_,height_);
Envelope<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
template <typename MergeMethod>
inline void merge_rectangle(image_data_32 const& data, unsigned x0, unsigned y0, float opacity)
{
box2d<int> ext0(0,0,width_,height_);
box2d<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
if (ext0.intersects(ext1))
{
Envelope<int> box = ext0.intersect(ext1);
for (int y = box.miny(); y < box.maxy(); ++y)
{
unsigned int* row_to = data_.getRow(y);
unsigned int const * row_from = data.getRow(y-y0);
for (int x = box.minx(); x < box.maxx(); ++x)
{
unsigned rgba0 = row_to[x];
unsigned rgba1 = row_from[x-x0];
if (ext0.intersects(ext1))
{
box2d<int> box = ext0.intersect(ext1);
for (int y = box.miny(); y < box.maxy(); ++y)
{
unsigned int* row_to = data_.getRow(y);
unsigned int const * row_from = data.getRow(y-y0);
for (int x = box.minx(); x < box.maxx(); ++x)
{
unsigned rgba0 = row_to[x];
unsigned rgba1 = row_from[x-x0];
#ifdef MAPNIK_BIG_ENDIAN
unsigned a1 = int( (rgba1 & 0xff) * opacity );
if (a1 == 0) continue;
unsigned r1 = (rgba1 >> 24)& 0xff;
unsigned g1 = (rgba1 >> 16 ) & 0xff;
unsigned b1 = (rgba1 >> 8) & 0xff;
unsigned a1 = int( (rgba1 & 0xff) * opacity );
if (a1 == 0) continue;
unsigned r1 = (rgba1 >> 24)& 0xff;
unsigned g1 = (rgba1 >> 16 ) & 0xff;
unsigned b1 = (rgba1 >> 8) & 0xff;
unsigned a0 = rgba0 & 0xff;
unsigned r0 = (rgba0 >> 24) & 0xff ;
unsigned g0 = (rgba0 >> 16 ) & 0xff;
unsigned b0 = (rgba0 >> 8) & 0xff;
unsigned a0 = rgba0 & 0xff;
unsigned r0 = (rgba0 >> 24) & 0xff ;
unsigned g0 = (rgba0 >> 16 ) & 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;
g0 = (g1*a1 + (((255 - a1) * a0 + 127)/255) * g0 + 127)/a;
b0 = (b1*a1 + (((255 - a1) * a0 + 127)/255) * b0 + 127)/a;
r0 = (r1*a1 + (((255 - a1) * a0 + 127)/255) * r0 + 127)/a;
g0 = (g1*a1 + (((255 - a1) * a0 + 127)/255) * g0 + 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
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
if (a1 == 0) continue;
unsigned r1 = rgba1 & 0xff;
unsigned g1 = (rgba1 >> 8 ) & 0xff;
unsigned b1 = (rgba1 >> 16) & 0xff;
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
if (a1 == 0) continue;
unsigned r1 = rgba1 & 0xff;
unsigned g1 = (rgba1 >> 8 ) & 0xff;
unsigned b1 = (rgba1 >> 16) & 0xff;
unsigned a0 = (rgba0 >> 24) & 0xff;
unsigned r0 = rgba0 & 0xff ;
unsigned g0 = (rgba0 >> 8 ) & 0xff;
unsigned b0 = (rgba0 >> 16) & 0xff;
unsigned a0 = (rgba0 >> 24) & 0xff;
unsigned r0 = rgba0 & 0xff ;
unsigned g0 = (rgba0 >> 8 ) & 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;
g0 = (g1*a1 + (((255 - a1) * a0 + 127)/255) * g0 + 127)/a;
b0 = (b1*a1 + (((255 - a1) * a0 + 127)/255) * b0 + 127)/a;
r0 = (r1*a1 + (((255 - a1) * a0 + 127)/255) * r0 + 127)/a;
g0 = (g1*a1 + (((255 - a1) * a0 + 127)/255) * g0 + 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 //GRAPHICS_HPP

View file

@ -2,7 +2,7 @@
*
* 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
* 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
*
*****************************************************************************/
//$Id$
#include <boost/python.hpp>
#ifndef MAPNIK_IMAGE_CACHE_HPP
#define MAPNIK_IMAGE_CACHE_HPP
#include <mapnik/spatial.hpp>
#include <mapnik/logical.hpp>
#include <mapnik/comparison.hpp>
#include <mapnik/regex_filter.hpp>
#include <mapnik/filter.hpp>
#include <mapnik/filter_factory.hpp>
// mapnik
#include <mapnik/utils.hpp>
#include <mapnik/config.hpp>
#include <mapnik/image_data.hpp>
using mapnik::filter;
using mapnik::filter_ptr;
using mapnik::filter_factory;
using mapnik::Feature;
using mapnik::create_filter;
// boost
#include <boost/utility.hpp>
#include <boost/unordered_map.hpp>
#include <boost/shared_ptr.hpp>
#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()
{
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_);
}
#endif // MAPNIK_IMAGE_CACHE_HPP

View file

@ -135,8 +135,8 @@ namespace mapnik
ImageData& operator=(const ImageData&);
};
typedef ImageData<unsigned> ImageData32;
typedef ImageData<byte> ImageData8;
typedef ImageData<unsigned> image_data_32;
typedef ImageData<byte> image_data_8;
}
#endif //IMAGE_DATA_HPP

View file

@ -33,33 +33,33 @@
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:
std::string message_;
public:
ImageReaderException(const std::string& message)
: message_(message) {}
return message_.c_str();
}
};
~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()
{
return message_.c_str();
}
};
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);
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);
MAPNIK_DECL image_reader* get_image_reader(const std::string& file);
}

View file

@ -32,6 +32,8 @@
// boost
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
// stl
#include <string>
@ -92,16 +94,17 @@ namespace mapnik {
boost::algorithm::iends_with(filename,std::string(".tiff"));
}
inline std::string type_from_filename(std::string const& filename)
{
if (is_png(filename)) return "png";
if (is_jpeg(filename)) return "jpeg";
if (is_tiff(filename)) return "tiff";
return "unknown";
}
inline boost::optional<std::string> type_from_filename(std::string const& filename)
{
typedef boost::optional<std::string> result_type;
if (is_png(filename)) return result_type("png");
if (is_jpeg(filename)) return result_type("jpeg");
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(".");
if ( idx != std::string::npos ) {
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& 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)
{
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)
{
return save_to_string<ImageData32>(image.data(),type);
return save_to_string<image_data_32>(image.data(),type);
}
#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&);
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&);
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&);
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 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&);
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&);
#endif

View file

@ -38,9 +38,9 @@ namespace mapnik
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();
for( ; itr !=labels_.end();++itr)
@ -66,14 +66,14 @@ namespace mapnik
// quad_tree based label collision detector
class label_collision_detector2 : boost::noncopyable
{
typedef quad_tree<Envelope<double> > tree_t;
typedef quad_tree<box2d<double> > tree_t;
tree_t tree_;
public:
explicit label_collision_detector2(Envelope<double> const& extent)
explicit label_collision_detector2(box2d<double> const& 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 end = tree_.query_end();
@ -100,14 +100,14 @@ namespace mapnik
// quad_tree based label collision detector with seperate check/insert
class label_collision_detector3 : boost::noncopyable
{
typedef quad_tree< Envelope<double> > tree_t;
typedef quad_tree< box2d<double> > tree_t;
tree_t tree_;
public:
explicit label_collision_detector3(Envelope<double> const& extent)
explicit label_collision_detector3(box2d<double> const& 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 end = tree_.query_end();
@ -123,7 +123,7 @@ namespace mapnik
return true;
}
void insert(Envelope<double> const& box)
void insert(box2d<double> const& box)
{
tree_.insert(box, box);
}
@ -140,24 +140,24 @@ namespace mapnik
{
struct label
{
label(Envelope<double> const& b) : box(b) {}
label(Envelope<double> const& b, UnicodeString const& t) : box(b), text(t) {}
label(box2d<double> const& b) : box(b) {}
label(box2d<double> const& b, UnicodeString const& t) : box(b), text(t) {}
Envelope<double> box;
box2d<double> box;
UnicodeString text;
};
typedef quad_tree< label > tree_t;
Envelope<double> extent_;
box2d<double> extent_;
tree_t tree_;
public:
explicit label_collision_detector4(Envelope<double> const& extent)
explicit label_collision_detector4(box2d<double> const& extent)
: extent_(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 end = tree_.query_end();
@ -173,9 +173,9 @@ namespace mapnik
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 end = tree_.query_end();
@ -190,9 +190,9 @@ namespace mapnik
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 end = tree_.query_end();
@ -207,12 +207,12 @@ namespace mapnik
return true;
}
void insert(Envelope<double> const& box)
void insert(box2d<double> const& 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);
}
@ -222,7 +222,7 @@ namespace mapnik
tree_.clear();
}
Envelope<double> const& extent() const
box2d<double> const& extent() const
{
return extent_;
}

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