finish bringing back to life the SVG_RENDERER - now outputs geometries again - closes #1438

This commit is contained in:
Dane Springmeyer 2012-11-28 17:45:05 -08:00
parent 1f7459d29d
commit 46f8ce3ce7
7 changed files with 94 additions and 118 deletions

View File

@ -100,6 +100,11 @@ struct MAPNIK_DECL coord_transform
geom_.rewind(pos);
}
unsigned type() const
{
return static_cast<unsigned>(geom_.type());
}
Geometry const& geom() const
{
return geom_;

View File

@ -27,6 +27,7 @@
#include <mapnik/ctrans.hpp>
#include <mapnik/color.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/util/geometry_svg_generator.hpp>
#include <mapnik/svg/output/svg_output_grammars.hpp>
#include <mapnik/svg/output/svg_output_attributes.hpp>
@ -44,11 +45,8 @@ namespace mapnik { namespace svg {
template <typename OutputIterator>
class svg_generator : private boost::noncopyable
{
typedef coord_transform<CoordTransform, geometry_type> path_type;
typedef svg::svg_root_attributes_grammar<OutputIterator> root_attributes_grammar;
typedef svg::svg_rect_attributes_grammar<OutputIterator> rect_attributes_grammar;
//typedef svg::svg_path_data_grammar<OutputIterator, path_type> path_data_grammar;
typedef svg::svg_path_attributes_grammar<OutputIterator> path_attributes_grammar;
typedef svg::svg_path_dash_array_grammar<OutputIterator> path_dash_array_grammar;
@ -60,7 +58,16 @@ namespace mapnik { namespace svg {
void generate_opening_root(root_output_attributes const& root_attributes);
void generate_closing_root();
void generate_rect(rect_output_attributes const& rect_attributes);
//void generate_path(path_type const& path, path_output_attributes const& path_attributes);
template <typename PathType>
void generate_path(PathType const& path, path_output_attributes const& path_attributes)
{
util::svg_generator<OutputIterator,PathType> svg_path_grammer;
karma::generate(output_iterator_, lit("<path ") << svg_path_grammer, path);
path_attributes_grammar attributes_grammar;
path_dash_array_grammar dash_array_grammar;
karma::generate(output_iterator_, lit(" ") << dash_array_grammar, path_attributes.stroke_dasharray());
karma::generate(output_iterator_, lit(" ") << attributes_grammar << lit("/>\n"), path_attributes);
}
private:
OutputIterator& output_iterator_;

View File

@ -87,88 +87,11 @@ BOOST_FUSION_ADAPT_STRUCT(
(std::string, svg_namespace_url_)
)
/*!
* mapnik::geometry_type is adapted to conform to the concepts
* required by Karma to be recognized as a container of
* attributes for output generation.
*/
/*
namespace boost { namespace spirit { namespace traits {
typedef mapnik::coord_transform<mapnik::CoordTransform, mapnik::geometry_type> path_type;
template <>
struct is_container<path_type const>
: mpl::true_ {};
template <>
struct container_iterator<path_type const>
{
typedef mapnik::svg::path_iterator_type type;
};
template <>
struct begin_container<path_type const>
{
static mapnik::svg::path_iterator_type
call(path_type const& path)
{
return mapnik::svg::path_iterator_type(0, path);
}
};
template <>
struct end_container<path_type const>
{
static mapnik::svg::path_iterator_type
call(path_type const& path)
{
return mapnik::svg::path_iterator_type(path);
}
};
}}}
*/
namespace mapnik { namespace svg {
using namespace boost::spirit;
using namespace boost::phoenix;
/*
template <typename OutputIterator, typename PathType>
struct svg_path_data_grammar : karma::grammar<OutputIterator, PathType&()>
{
typedef path_iterator_type::value_type vertex_type;
explicit svg_path_data_grammar(PathType const& path_type)
: svg_path_data_grammar::base_type(svg_path),
path_type_(path_type)
{
using karma::int_;
using karma::double_;
using repository::confix;
svg_path =
lit("d=")
<< confix('"', '"')[
-(path_vertex % lit(' '))];
path_vertex =
path_vertex_command
<< double_
<< lit(' ')
<< double_;
path_vertex_command = &int_(1) << lit('M') | lit('L');
}
karma::rule<OutputIterator, PathType&()> svg_path;
karma::rule<OutputIterator, vertex_type()> path_vertex;
karma::rule<OutputIterator, int()> path_vertex_command;
PathType const& path_type_;
};
*/
template <typename OutputIterator>
struct svg_path_attributes_grammar : karma::grammar<OutputIterator, mapnik::svg::path_output_attributes()>

View File

@ -25,7 +25,8 @@
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/geometry.hpp> // for container stuff
#include <mapnik/ctrans.hpp> // for container stuff
#include <mapnik/util/path_iterator.hpp>
#include <mapnik/util/container_adapter.hpp>
@ -38,35 +39,84 @@
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/home/phoenix/statement/if.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
#include <boost/type_traits/remove_pointer.hpp>
//#define BOOST_SPIRIT_USE_PHOENIX_V3 1
/*!
* adapted to conform to the concepts
* required by Karma to be recognized as a container of
* attributes for output generation.
*/
namespace boost { namespace spirit { namespace traits {
// TODO - this needs to be made generic to any path type
typedef mapnik::coord_transform<mapnik::CoordTransform, mapnik::geometry_type> path_type;
template <>
struct is_container<path_type const> : mpl::true_ {} ;
template <>
struct container_iterator<path_type const>
{
typedef mapnik::util::path_iterator<path_type> type;
};
template <>
struct begin_container<path_type const>
{
static mapnik::util::path_iterator<path_type>
call (path_type const& g)
{
return mapnik::util::path_iterator<path_type>(g);
}
};
template <>
struct end_container<path_type const>
{
static mapnik::util::path_iterator<path_type>
call (path_type const& g)
{
return mapnik::util::path_iterator<path_type>();
}
};
}}}
namespace mapnik { namespace util {
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
namespace svg_detail {
template <typename Geometry>
struct get_type
{
template <typename T>
struct result { typedef int type; };
int operator() (geometry_type const& geom) const
int operator() (Geometry const& geom) const
{
return (int)geom.type();
return static_cast<int>(geom.type());
}
};
template <typename T>
struct get_first
{
template <typename T>
struct result { typedef geometry_type::value_type const type; };
typedef T geometry_type;
geometry_type::value_type const operator() (geometry_type const& geom) const
template <typename U>
struct result { typedef typename geometry_type::value_type const type; };
typename geometry_type::value_type const operator() (geometry_type const& geom) const
{
geometry_type::value_type coord;
boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord));
typename geometry_type::value_type coord;
geom.rewind(0);
boost::get<0>(coord) = geom.vertex(&boost::get<1>(coord),&boost::get<2>(coord));
return coord;
}
};
@ -80,11 +130,14 @@ namespace mapnik { namespace util {
};
}
template <typename OutputIterator>
template <typename OutputIterator, typename Geometry>
struct svg_generator :
karma::grammar<OutputIterator, geometry_type const& ()>
karma::grammar<OutputIterator, Geometry const& ()>
{
typedef Geometry geometry_type;
typedef typename boost::remove_pointer<typename geometry_type::value_type>::type coord_type;
svg_generator()
: svg_generator::base_type(svg)
{
@ -102,22 +155,22 @@ namespace mapnik { namespace util {
;
svg_point = &uint_
<< lit("cx=\"") << coord_type
<< lit("\" cy=\"") << coord_type
<< lit("cx=\"") << coordinate
<< lit("\" cy=\"") << coordinate
<< lit('\"')
;
linestring = &uint_(mapnik::LineString)[_1 = _type(_val)]
<< svg_path
<< svg_path << lit('\"')
;
polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)]
<< svg_path
<< svg_path << lit('\"')
;
svg_path %= ((&uint_(mapnik::SEG_MOVETO) << lit('M')
svg_path %= ((&uint_(mapnik::SEG_MOVETO) << lit("d=\"") << lit('M')
| &uint_(mapnik::SEG_LINETO) [_a +=1] << karma::string [if_(_a == 1) [_1 = "L" ] ])
<< lit(' ') << coord_type << lit(' ') << coord_type) % lit(' ')
<< lit(' ') << coordinate << lit(' ') << coordinate) % lit(' ')
;
@ -129,14 +182,14 @@ namespace mapnik { namespace util {
karma::rule<OutputIterator, geometry_type const& ()> linestring;
karma::rule<OutputIterator, geometry_type const& ()> polygon;
karma::rule<OutputIterator, geometry_type::value_type ()> svg_point;
karma::rule<OutputIterator, coord_type ()> svg_point;
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> svg_path;
// phoenix functions
phoenix::function<svg_detail::get_type > _type;
phoenix::function<svg_detail::get_first> _first;
phoenix::function<svg_detail::get_type<geometry_type> > _type;
phoenix::function<svg_detail::get_first<geometry_type> > _first;
//
karma::real_generator<double, svg_detail::coordinate_policy<double> > coord_type;
karma::real_generator<double, svg_detail::coordinate_policy<double> > coordinate;
};

View File

@ -39,7 +39,7 @@ bool to_svg(std::string & svg, mapnik::geometry_type const& geom)
{
typedef std::back_insert_iterator<std::string> sink_type;
sink_type sink(svg);
svg_generator<sink_type> generator;
svg_generator<sink_type, mapnik::geometry_type> generator;
bool result = karma::generate(sink, generator, geom);
return result;
}

View File

@ -44,11 +44,11 @@ bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms,
// generate path output for each geometry of the current feature.
for(unsigned i=0; i<feature.num_geometries(); ++i)
{
geometry_type const& geom = feature.get_geometry(i);
if(geom.size() > 1)
geometry_type & geom = feature.get_geometry(i);
if(geom.size() > 0)
{
//path_type path(t_, geom, prj_trans);
//generator_.generate_path(path, path_attributes_);
path_type path(t_, geom, prj_trans);
generator_.generate_path(path, path_attributes_);
}
}

View File

@ -65,17 +65,5 @@ namespace mapnik { namespace svg {
karma::generate(output_iterator_, lit("<rect ") << attributes_grammar << lit("/>\n"), rect_attributes);
}
/*template <typename OutputIterator>
void svg_generator<OutputIterator>::generate_path(path_type const& path, path_output_attributes const& path_attributes)
{
path_data_grammar data_grammar(path);
path_attributes_grammar attributes_grammar;
path_dash_array_grammar dash_array_grammar;
karma::generate(output_iterator_, lit("<path ") << data_grammar, path);
karma::generate(output_iterator_, lit(" ") << dash_array_grammar, path_attributes.stroke_dasharray());
karma::generate(output_iterator_, lit(" ") << attributes_grammar << lit("/>\n"), path_attributes);
}*/
template class svg_generator<std::ostream_iterator<char> >;
}}