Permalink
Browse files

add facilities to choose the simplification algorithm

  • Loading branch information...
1 parent eace6ee commit 22150f908f2c2a80eb67ed2db8f6b0a8acd4509f @kkaefer kkaefer committed Aug 16, 2012
View
4 bindings/python/mapnik_line_symbolizer.cpp
@@ -63,6 +63,10 @@ void export_line_symbolizer()
&line_symbolizer::smooth,
&line_symbolizer::set_smooth,
"smooth value (0..1.0)")
+ .add_property("simplify_algorithm",
+ &line_symbolizer::simplify_algorithm,
+ &line_symbolizer::set_simplify_algorithm,
+ "simplfication algorithm")
.add_property("simplify_tolerance",
&line_symbolizer::simplify_tolerance,
&line_symbolizer::set_simplify_tolerance,
View
4 bindings/python/mapnik_polygon_symbolizer.cpp
@@ -88,6 +88,10 @@ void export_polygon_symbolizer()
&polygon_symbolizer::smooth,
&polygon_symbolizer::set_smooth,
"smooth value (0..1.0)")
+ .add_property("simplify_algorithm",
+ &polygon_symbolizer::simplify_algorithm,
+ &polygon_symbolizer::set_simplify_algorithm,
+ "simplfication algorithm")
.add_property("simplify_tolerance",
&polygon_symbolizer::simplify_tolerance,
&polygon_symbolizer::set_simplify_tolerance,
View
25 include/mapnik/simplify.hpp
@@ -0,0 +1,25 @@
+#ifndef MAPNIK_SIMPLIFY_HPP
+#define MAPNIK_SIMPLIFY_HPP
+
+#include <mapnik/debug.hpp>
+
+// Boost
+#include <boost/optional.hpp>
+
+namespace mapnik
+{
+
+enum simplify_algorithm_e
+{
+ radial_distance = 0,
+ douglas_peucker,
+ visvalingam_whyatt,
+ zhao_saalfeld
+};
+
+MAPNIK_DECL boost::optional<simplify_algorithm_e> simplify_algorithm_from_string(std::string const& name);
+MAPNIK_DECL boost::optional<std::string> simplify_algorithm_to_string(simplify_algorithm_e algorithm);
+
+}
+
+#endif // MAPNIK_SIMPLIFY_HPP
View
50 include/mapnik/simplify_converter.hpp
@@ -4,14 +4,17 @@
#include <mapnik/debug.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/vertex.hpp>
+#include <mapnik/simplify.hpp>
// STL
#include <limits>
+// Boost
+#include <boost/optional.hpp>
+
namespace mapnik
{
-
struct weighted_vertex : private boost::noncopyable {
vertex2d coord;
double weight;
@@ -49,6 +52,7 @@ struct MAPNIK_DECL simplify_converter
: geom_(geom)
, tolerance_(0.0)
, status_(initial)
+ , algorithm_(radial_distance)
{
}
@@ -59,6 +63,18 @@ struct MAPNIK_DECL simplify_converter
end
};
+ simplify_algorithm_e get_simplify_algorithm()
+ {
+ return algorithm_;
+ }
+
+ void set_simplify_algorithm(simplify_algorithm_e value) {
+ if (algorithm_ != value) {
+ algorithm_ = value;
+ reset();
+ }
+ }
+
double get_simplify_tolerance()
{
return tolerance_;
@@ -93,6 +109,25 @@ struct MAPNIK_DECL simplify_converter
if (status_ == initial)
init_vertices();
+ return output_vertex(x, y);
+ }
+
+
+
+private:
+ unsigned output_vertex(double* x, double* y)
+ {
+ switch (algorithm_) {
+ case visvalingam_whyatt:
+ return output_vertex_cached(x, y);
+ default:
+ throw std::runtime_error("simplification algorithm not yet implemented");
+ }
+
+ return SEG_END;
+ }
+
+ unsigned output_vertex_cached(double* x, double* y) {
if (pos_ >= vertices_.size())
return SEG_END;
@@ -103,14 +138,22 @@ struct MAPNIK_DECL simplify_converter
return vtx.cmd;
}
-private:
status init_vertices()
{
if (status_ != initial) // already initialized
return status_;
reset();
+ switch (algorithm_) {
+ case visvalingam_whyatt:
+ return init_vertices_visvalingam_whyatt();
+ default:
+ throw std::runtime_error("simplification algorithm not yet implemented");
+ }
+ }
+
+ status init_vertices_visvalingam_whyatt() {
typedef std::vector<weighted_vertex *> WeightedVertices;
WeightedVertices v;
@@ -171,13 +214,14 @@ struct MAPNIK_DECL simplify_converter
delete removed;
}
- // initialization finished
+ // Initialization finished.
return status_ = process;
}
Geometry& geom_;
double tolerance_;
status status_;
+ simplify_algorithm_e algorithm_;
size_t pos_;
std::vector<vertex2d> vertices_;
View
4 include/mapnik/symbolizer.hpp
@@ -29,6 +29,7 @@
#include <mapnik/metawriter.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/transform_expression.hpp>
+#include <mapnik/simplify.hpp>
// boost
#include <boost/array.hpp>
@@ -90,6 +91,8 @@ class MAPNIK_DECL symbolizer_base
std::string get_transform_string() const;
void set_clip(bool clip);
bool clip() const;
+ void set_simplify_algorithm(simplify_algorithm_e algorithm);
+ simplify_algorithm_e simplify_algorithm() const;
void set_simplify_tolerance(double simplify_tolerance);
double simplify_tolerance() const;
void set_smooth(double smooth);
@@ -102,6 +105,7 @@ class MAPNIK_DECL symbolizer_base
composite_mode_e comp_op_;
transform_type affine_transform_;
bool clip_;
+ simplify_algorithm_e simplify_algorithm_value_;
double simplify_tolerance_value_;
double smooth_value_;
};
View
1 src/build.py
@@ -151,6 +151,7 @@ def ldconfig(*args,**kwargs):
proj_transform.cpp
distance.cpp
scale_denominator.cpp
+ simplify.cpp
memory_datasource.cpp
stroke.cpp
symbolizer.cpp
View
15 src/load_map.cpp
@@ -882,6 +882,21 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt)
optional<boolean> clip = pt.get_opt_attr<boolean>("clip");
if (clip) sym.set_clip(*clip);
+ // simplify algorithm
+ optional<std::string> simplify_algorithm_name = pt.get_opt_attr<std::string>("simlify-op");
+ if (simplify_algorithm_name)
+ {
+ optional<simplify_algorithm_e> simplify_algorithm = simplify_algorithm_from_string(*simplify_algorithm_name);
+ if (simplify_algorithm)
+ {
+ sym.set_simplify_algorithm(*simplify_algorithm);
+ }
+ else
+ {
+ throw config_error("failed to parse simplify-algorithm: '" + *simplify_algorithm_name + "'");
+ }
+ }
+
// simplify value
optional<double> simplify_tolerance = pt.get_opt_attr<double>("simplify-tolerance");
if (simplify_tolerance) sym.set_simplify_tolerance(*simplify_tolerance);
View
4 src/save_map.cpp
@@ -357,6 +357,10 @@ class serialize_symbolizer : public boost::static_visitor<>
{
set_attr( node, "clip", sym.clip() );
}
+ if (sym.simplify_algorithm() != dfl.simplify_algorithm() || explicit_defaults_)
+ {
+ set_attr( node, "simplify-algorithm", *simplify_algorithm_to_string(sym.simplify_algorithm()) );
+ }
if (sym.simplify_tolerance() != dfl.simplify_tolerance() || explicit_defaults_)
{
set_attr( node, "simplify-tolerance", sym.simplify_tolerance() );
View
41 src/simplify.cpp
@@ -0,0 +1,41 @@
+// mapnik
+#include <mapnik/simplify.hpp>
+
+// boost
+#include <boost/assign/list_of.hpp>
+#include <boost/bimap.hpp>
+
+namespace mapnik
+{
+
+typedef boost::bimap<simplify_algorithm_e, std::string> simplify_algorithm_lookup_type;
+static const simplify_algorithm_lookup_type simplify_lookup = boost::assign::list_of<simplify_algorithm_lookup_type::relation>
+ (radial_distance,"radial-distance")
+ (douglas_peucker,"douglas-peucker")
+ (visvalingam_whyatt,"visvalingam-whyatt")
+ (zhao_saalfeld,"zhao-saalfeld")
+ ;
+
+boost::optional<simplify_algorithm_e> simplify_algorithm_from_string(std::string const& name)
+{
+ boost::optional<simplify_algorithm_e> algo;
+ simplify_algorithm_lookup_type::right_const_iterator right_iter = simplify_lookup.right.find(name);
+ if (right_iter != simplify_lookup.right.end())
+ {
+ algo.reset(right_iter->second);
+ }
+ return algo;
+}
+
+boost::optional<std::string> simplify_algorithm_to_string(simplify_algorithm_e value)
+{
+ boost::optional<std::string> algo;
+ simplify_algorithm_lookup_type::left_const_iterator left_iter = simplify_lookup.left.find(value);
+ if (left_iter != simplify_lookup.left.end())
+ {
+ algo.reset(left_iter->second);
+ }
+ return algo;
+}
+
+}
View
11 src/symbolizer.cpp
@@ -51,6 +51,7 @@ symbolizer_base::symbolizer_base()
writer_ptr_(),
comp_op_(src_over),
clip_(true),
+ simplify_algorithm_value_(radial_distance),
simplify_tolerance_value_(0.0),
smooth_value_(0.0)
{
@@ -152,6 +153,16 @@ bool symbolizer_base::clip() const
return clip_;
}
+void symbolizer_base::set_simplify_algorithm(simplify_algorithm_e algo)
+{
+ simplify_algorithm_value_ = algo;
+}
+
+simplify_algorithm_e symbolizer_base::simplify_algorithm() const
+{
+ return simplify_algorithm_value_;
+}
+
void symbolizer_base::set_simplify_tolerance(double simplify_tolerance)
{
simplify_tolerance_value_ = simplify_tolerance;

0 comments on commit 22150f9

Please sign in to comment.