mirror of
https://github.com/mapnik/mapnik.git
synced 2025-12-08 20:13:09 +00:00
Fixed a bug that caused half of the vertexes to disappear from the SVG path.
+ mapnik::geometry_iterator was replaced by mapnik::svg::path_iterator + svg::path_output_grammar was simplified + the container for this grammar is now coord_transform2, instead of geometry + added typedef size_type to coord_transform2 and removed it from geometry
This commit is contained in:
parent
aabdeb1265
commit
83a7b4710e
@ -60,6 +60,9 @@ private:
|
||||
template <typename Transform,typename Geometry>
|
||||
struct MAPNIK_DECL coord_transform2
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
typedef typename Geometry::value_type value_type;
|
||||
|
||||
coord_transform2(Transform const& t,
|
||||
Geometry const& geom,
|
||||
proj_transform const& prj_trans)
|
||||
|
||||
@ -48,7 +48,6 @@ class geometry
|
||||
{
|
||||
public:
|
||||
typedef T vertex_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef typename vertex_type::type value_type;
|
||||
typedef Container<vertex_type> container_type;
|
||||
private:
|
||||
|
||||
@ -25,9 +25,9 @@
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/vertex.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_iterator.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/svg/svg_path_iterator.hpp>
|
||||
#include <mapnik/svg/svg_output_attributes.hpp>
|
||||
|
||||
// boost
|
||||
@ -94,34 +94,36 @@ BOOST_FUSION_ADAPT_STRUCT(
|
||||
*/
|
||||
namespace boost { namespace spirit { namespace traits {
|
||||
|
||||
typedef mapnik::coord_transform2<mapnik::CoordTransform, mapnik::geometry_type> path_type;
|
||||
|
||||
template <>
|
||||
struct is_container<mapnik::geometry_type const>
|
||||
struct is_container<path_type const>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct container_iterator<mapnik::geometry_type const>
|
||||
struct container_iterator<path_type const>
|
||||
{
|
||||
typedef mapnik::geometry_iterator_type type;
|
||||
typedef mapnik::svg::path_iterator_type type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct begin_container<mapnik::geometry_type const>
|
||||
struct begin_container<path_type const>
|
||||
{
|
||||
static mapnik::geometry_iterator_type
|
||||
call(mapnik::geometry_type const& g)
|
||||
static mapnik::svg::path_iterator_type
|
||||
call(path_type const& path)
|
||||
{
|
||||
return mapnik::geometry_iterator_type(0, g);
|
||||
return mapnik::svg::path_iterator_type(0, path);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct end_container<mapnik::geometry_type const>
|
||||
struct end_container<path_type const>
|
||||
{
|
||||
static mapnik::geometry_iterator_type
|
||||
call(mapnik::geometry_type const& g)
|
||||
static mapnik::svg::path_iterator_type
|
||||
call(path_type const& path)
|
||||
{
|
||||
return mapnik::geometry_iterator_type(g);
|
||||
return mapnik::svg::path_iterator_type(path);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
@ -131,67 +133,17 @@ namespace mapnik { namespace svg {
|
||||
using namespace boost::spirit;
|
||||
using namespace boost::phoenix;
|
||||
|
||||
/*!
|
||||
* @brief Structure that performs the conversion from map to user coordinates.
|
||||
* It's methods and functions are meant to be used by svg_path_data_grammar as
|
||||
* semantic actions to convert the value of vertex coordinates inside the grammar.
|
||||
*
|
||||
* It (kind of) works like a state machine, setting the value of x and y and then
|
||||
* making the conversion just after y has been set.
|
||||
*/
|
||||
template <typename PathType>
|
||||
struct path_coordinate_transformer
|
||||
{
|
||||
explicit path_coordinate_transformer(PathType const& path_type)
|
||||
: path_type_(path_type),
|
||||
current_x_(0.0),
|
||||
current_y_(0.0)
|
||||
{}
|
||||
|
||||
void set_current_x(double& x)
|
||||
{
|
||||
current_x_ = x;
|
||||
}
|
||||
|
||||
void set_current_y(double& y)
|
||||
{
|
||||
current_y_ = y;
|
||||
path_type_.vertex(¤t_x_, ¤t_y_);
|
||||
}
|
||||
|
||||
void current_x(double& x) const
|
||||
{
|
||||
x = current_x_;
|
||||
}
|
||||
|
||||
void current_y(double& y) const
|
||||
{
|
||||
y = current_y_;
|
||||
}
|
||||
|
||||
PathType const& path_type_;
|
||||
double current_x_;
|
||||
double current_y_;
|
||||
};
|
||||
|
||||
template <typename OutputIterator, typename PathType>
|
||||
struct svg_path_data_grammar : karma::grammar<OutputIterator, mapnik::geometry_type&()>
|
||||
struct svg_path_data_grammar : karma::grammar<OutputIterator, PathType&()>
|
||||
{
|
||||
typedef path_coordinate_transformer<PathType> coordinate_transformer;
|
||||
typedef mapnik::geometry_iterator_type::value_type vertex_type;
|
||||
typedef mapnik::geometry_type::value_type& vertex_component_type;
|
||||
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),
|
||||
ct_(path_type)
|
||||
path_type_(path_type)
|
||||
{
|
||||
using karma::int_;
|
||||
using karma::double_;
|
||||
using karma::_1;
|
||||
using karma::_a;
|
||||
using karma::eol;
|
||||
using karma::omit;
|
||||
using repository::confix;
|
||||
|
||||
svg_path =
|
||||
@ -201,31 +153,18 @@ namespace mapnik { namespace svg {
|
||||
|
||||
path_vertex =
|
||||
path_vertex_command
|
||||
<< omit[path_vertex_component_x]
|
||||
<< omit[path_vertex_component_y]
|
||||
<< path_vertex_transformed_x
|
||||
<< double_
|
||||
<< lit(' ')
|
||||
<< path_vertex_transformed_y;
|
||||
<< double_;
|
||||
|
||||
path_vertex_command = &int_(1) << lit('M') | lit('L');
|
||||
|
||||
path_vertex_component_x = double_[_1 = _a][bind(&coordinate_transformer::set_current_x, &ct_, _a)][_a = _val];
|
||||
|
||||
path_vertex_component_y = double_[_1 = _a][bind(&coordinate_transformer::set_current_y, &ct_, _a)][_a = _val];
|
||||
|
||||
path_vertex_transformed_x = double_[_1 = _a][bind(&coordinate_transformer::current_x, &ct_, _a)];
|
||||
|
||||
path_vertex_transformed_y = double_[_1 = _a][bind(&coordinate_transformer::current_y, &ct_, _a)];
|
||||
}
|
||||
|
||||
karma::rule<OutputIterator, mapnik::geometry_type&()> svg_path;
|
||||
karma::rule<OutputIterator, PathType&()> svg_path;
|
||||
karma::rule<OutputIterator, vertex_type()> path_vertex;
|
||||
karma::rule<OutputIterator, int()> path_vertex_command;
|
||||
karma::rule<OutputIterator, vertex_component_type(), karma::locals<double> > path_vertex_component_x, path_vertex_component_y;
|
||||
karma::rule<OutputIterator, vertex_component_type(), karma::locals<double> > path_vertex_transformed_x, path_vertex_transformed_y;
|
||||
|
||||
PathType const& path_type_;
|
||||
coordinate_transformer ct_;
|
||||
};
|
||||
|
||||
template <typename OutputIterator>
|
||||
|
||||
@ -20,11 +20,12 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef GEOMETRY_ITERATOR_HPP
|
||||
#define GEOMETRY_ITERATOR_HPP
|
||||
#ifndef SVG_PATH_ITERATOR_HPP
|
||||
#define SVG_PATH_ITERATOR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
@ -32,6 +33,9 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
namespace svg {
|
||||
|
||||
using namespace mapnik;
|
||||
|
||||
/*
|
||||
* @brief Iterator class used to iterate over geometry vertexes.
|
||||
@ -47,9 +51,9 @@ namespace mapnik {
|
||||
* @tparam Value the type of sequence element dereferenced.
|
||||
* @tparam Container the sequence over which it iterates.
|
||||
*/
|
||||
template <typename Value, typename Container=geometry_type>
|
||||
class geometry_iterator
|
||||
: public boost::iterator_adaptor<geometry_iterator<Value, Container>,
|
||||
template <typename Value, typename Container>
|
||||
class path_iterator
|
||||
: public boost::iterator_adaptor<path_iterator<Value, Container>,
|
||||
Value*,
|
||||
boost::use_default,
|
||||
boost::forward_traversal_tag>
|
||||
@ -57,6 +61,7 @@ class geometry_iterator
|
||||
public:
|
||||
typedef Value value_type;
|
||||
typedef Container container_type;
|
||||
typedef typename Container::value_type value_component_type;
|
||||
|
||||
/*!
|
||||
* @brief Constructor that initializes the reference to the current element to null.
|
||||
@ -65,10 +70,10 @@ public:
|
||||
*
|
||||
* @param geometry the geometry that handles the vector of vertexes.
|
||||
*/
|
||||
geometry_iterator(Container const& geometry)
|
||||
: geometry_iterator::iterator_adaptor_(0),
|
||||
geometry_(geometry),
|
||||
first_value_(new Value(0,0,0,0,0))
|
||||
path_iterator(Container const& path)
|
||||
: path_iterator::iterator_adaptor_(0),
|
||||
path_(path),
|
||||
first_value_(new Value(0,0,0))
|
||||
{}
|
||||
|
||||
/*!
|
||||
@ -82,10 +87,10 @@ public:
|
||||
* @param p pointer to the first element of the sequence.
|
||||
* @param geometry the geometry that handles the vector of vertexes.
|
||||
*/
|
||||
explicit geometry_iterator(Value* first_element, Container const& geometry)
|
||||
: geometry_iterator::iterator_adaptor_(first_element),
|
||||
geometry_(geometry),
|
||||
first_value_(new Value(0,0,0,0,0))
|
||||
explicit path_iterator(Value* first_element, Container const& path)
|
||||
: path_iterator::iterator_adaptor_(first_element),
|
||||
path_(path),
|
||||
first_value_(new Value(0,0,0))
|
||||
{
|
||||
this->increment();
|
||||
}
|
||||
@ -97,10 +102,10 @@ public:
|
||||
* @sa http://www.boost.org/doc/libs/1_45_0/libs/iterator/doc/iterator_facade.html#interoperability
|
||||
*/
|
||||
template <typename OtherValue>
|
||||
geometry_iterator(geometry_iterator<OtherValue> const& other,
|
||||
path_iterator(path_iterator<OtherValue, Container> const& other,
|
||||
typename boost::enable_if<boost::is_convertible<OtherValue*, Value*>,
|
||||
enabler>::type = enabler())
|
||||
: geometry_iterator::iterator_adaptor_(other.base()) {}
|
||||
: path_iterator::iterator_adaptor_(other.base()) {}
|
||||
|
||||
private:
|
||||
|
||||
@ -117,7 +122,7 @@ private:
|
||||
geometry_type::value_type y;
|
||||
|
||||
// extract next vertex components.
|
||||
unsigned cmd = geometry_.vertex(&x, &y);
|
||||
unsigned cmd = path_.vertex(&x, &y);
|
||||
|
||||
if(cmd == SEG_END)
|
||||
{
|
||||
@ -137,13 +142,13 @@ private:
|
||||
// 'first_value_' is used as intermediate storage
|
||||
// because the compiler prohibits the assignment of the
|
||||
// address of a temporary object (&Value(...)).
|
||||
*first_value_ = Value(cmd, x, y, x, y);
|
||||
*first_value_ = Value(cmd, x, y);
|
||||
this->base_reference() = first_value_.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
// point the reference to the current element to the next.
|
||||
*(this->base_reference()) = Value(cmd, x, y, x, y);
|
||||
*(this->base_reference()) = Value(cmd, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,21 +158,23 @@ private:
|
||||
* @param other iterator to compare to current element.
|
||||
*/
|
||||
template <typename OtherValue>
|
||||
bool equal(geometry_iterator<OtherValue, Container> const& other) const
|
||||
bool equal(path_iterator<OtherValue, Container> const& other) const
|
||||
{
|
||||
return this->base_reference() == other.base();
|
||||
}
|
||||
|
||||
Container const& geometry_;
|
||||
Container const& path_;
|
||||
boost::shared_ptr<Value> first_value_;
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief Specialization of geometry_iterator, as needed by mapnik::svg::svg_path_data_grammar.
|
||||
* The Value type is a boost::tuple that holds 5 elements, the command and the x and y coordinate.
|
||||
* Each coordinate is stored twice to match the needs the grammar.
|
||||
* Each coordinate is stored twice to match the needs of the grammar.
|
||||
*/
|
||||
typedef geometry_iterator<boost::tuple<unsigned, geometry_type::value_type, geometry_type::value_type, geometry_type::value_type, geometry_type::value_type>, geometry_type> geometry_iterator_type;
|
||||
}
|
||||
typedef path_iterator<boost::tuple<unsigned, geometry_type::value_type, geometry_type::value_type>,
|
||||
coord_transform2<CoordTransform, geometry_type> > path_iterator_type;
|
||||
|
||||
#endif //GEOMETRY_ITERATOR_HPP
|
||||
}}
|
||||
|
||||
#endif //SVG_PATH_ITERATOR_HPP
|
||||
@ -73,7 +73,7 @@ namespace mapnik { namespace svg {
|
||||
path_attributes_grammar attributes_grammar;
|
||||
path_dash_array_grammar dash_array_grammar;
|
||||
|
||||
karma::generate(output_iterator_, lit("<path ") << data_grammar, path.geom());
|
||||
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);
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ void prepare_map(Map& m)
|
||||
lyr.add_style("provlines");
|
||||
m.addLayer(lyr);
|
||||
}
|
||||
|
||||
|
||||
// Roads
|
||||
{
|
||||
parameters p;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user