Skip to content
This repository
Browse code

add facilities to choose the simplification algorithm

  • Loading branch information...
commit 22150f908f2c2a80eb67ed2db8f6b0a8acd4509f 1 parent eace6ee
Konstantin Käfer kkaefer authored
4 bindings/python/mapnik_line_symbolizer.cpp
@@ -63,6 +63,10 @@ void export_line_symbolizer()
63 63 &line_symbolizer::smooth,
64 64 &line_symbolizer::set_smooth,
65 65 "smooth value (0..1.0)")
  66 + .add_property("simplify_algorithm",
  67 + &line_symbolizer::simplify_algorithm,
  68 + &line_symbolizer::set_simplify_algorithm,
  69 + "simplfication algorithm")
66 70 .add_property("simplify_tolerance",
67 71 &line_symbolizer::simplify_tolerance,
68 72 &line_symbolizer::set_simplify_tolerance,
4 bindings/python/mapnik_polygon_symbolizer.cpp
@@ -88,6 +88,10 @@ void export_polygon_symbolizer()
88 88 &polygon_symbolizer::smooth,
89 89 &polygon_symbolizer::set_smooth,
90 90 "smooth value (0..1.0)")
  91 + .add_property("simplify_algorithm",
  92 + &polygon_symbolizer::simplify_algorithm,
  93 + &polygon_symbolizer::set_simplify_algorithm,
  94 + "simplfication algorithm")
91 95 .add_property("simplify_tolerance",
92 96 &polygon_symbolizer::simplify_tolerance,
93 97 &polygon_symbolizer::set_simplify_tolerance,
25 include/mapnik/simplify.hpp
... ... @@ -0,0 +1,25 @@
  1 +#ifndef MAPNIK_SIMPLIFY_HPP
  2 +#define MAPNIK_SIMPLIFY_HPP
  3 +
  4 +#include <mapnik/debug.hpp>
  5 +
  6 +// Boost
  7 +#include <boost/optional.hpp>
  8 +
  9 +namespace mapnik
  10 +{
  11 +
  12 +enum simplify_algorithm_e
  13 +{
  14 + radial_distance = 0,
  15 + douglas_peucker,
  16 + visvalingam_whyatt,
  17 + zhao_saalfeld
  18 +};
  19 +
  20 +MAPNIK_DECL boost::optional<simplify_algorithm_e> simplify_algorithm_from_string(std::string const& name);
  21 +MAPNIK_DECL boost::optional<std::string> simplify_algorithm_to_string(simplify_algorithm_e algorithm);
  22 +
  23 +}
  24 +
  25 +#endif // MAPNIK_SIMPLIFY_HPP
50 include/mapnik/simplify_converter.hpp
@@ -4,14 +4,17 @@
4 4 #include <mapnik/debug.hpp>
5 5 #include <mapnik/box2d.hpp>
6 6 #include <mapnik/vertex.hpp>
  7 +#include <mapnik/simplify.hpp>
7 8
8 9 // STL
9 10 #include <limits>
10 11
  12 +// Boost
  13 +#include <boost/optional.hpp>
  14 +
11 15 namespace mapnik
12 16 {
13 17
14   -
15 18 struct weighted_vertex : private boost::noncopyable {
16 19 vertex2d coord;
17 20 double weight;
@@ -49,6 +52,7 @@ struct MAPNIK_DECL simplify_converter
49 52 : geom_(geom)
50 53 , tolerance_(0.0)
51 54 , status_(initial)
  55 + , algorithm_(radial_distance)
52 56 {
53 57 }
54 58
@@ -59,6 +63,18 @@ struct MAPNIK_DECL simplify_converter
59 63 end
60 64 };
61 65
  66 + simplify_algorithm_e get_simplify_algorithm()
  67 + {
  68 + return algorithm_;
  69 + }
  70 +
  71 + void set_simplify_algorithm(simplify_algorithm_e value) {
  72 + if (algorithm_ != value) {
  73 + algorithm_ = value;
  74 + reset();
  75 + }
  76 + }
  77 +
62 78 double get_simplify_tolerance()
63 79 {
64 80 return tolerance_;
@@ -93,6 +109,25 @@ struct MAPNIK_DECL simplify_converter
93 109 if (status_ == initial)
94 110 init_vertices();
95 111
  112 + return output_vertex(x, y);
  113 + }
  114 +
  115 +
  116 +
  117 +private:
  118 + unsigned output_vertex(double* x, double* y)
  119 + {
  120 + switch (algorithm_) {
  121 + case visvalingam_whyatt:
  122 + return output_vertex_cached(x, y);
  123 + default:
  124 + throw std::runtime_error("simplification algorithm not yet implemented");
  125 + }
  126 +
  127 + return SEG_END;
  128 + }
  129 +
  130 + unsigned output_vertex_cached(double* x, double* y) {
96 131 if (pos_ >= vertices_.size())
97 132 return SEG_END;
98 133
@@ -103,7 +138,6 @@ struct MAPNIK_DECL simplify_converter
103 138 return vtx.cmd;
104 139 }
105 140
106   -private:
107 141 status init_vertices()
108 142 {
109 143 if (status_ != initial) // already initialized
@@ -111,6 +145,15 @@ struct MAPNIK_DECL simplify_converter
111 145
112 146 reset();
113 147
  148 + switch (algorithm_) {
  149 + case visvalingam_whyatt:
  150 + return init_vertices_visvalingam_whyatt();
  151 + default:
  152 + throw std::runtime_error("simplification algorithm not yet implemented");
  153 + }
  154 + }
  155 +
  156 + status init_vertices_visvalingam_whyatt() {
114 157 typedef std::vector<weighted_vertex *> WeightedVertices;
115 158
116 159 WeightedVertices v;
@@ -171,13 +214,14 @@ struct MAPNIK_DECL simplify_converter
171 214 delete removed;
172 215 }
173 216
174   - // initialization finished
  217 + // Initialization finished.
175 218 return status_ = process;
176 219 }
177 220
178 221 Geometry& geom_;
179 222 double tolerance_;
180 223 status status_;
  224 + simplify_algorithm_e algorithm_;
181 225 size_t pos_;
182 226 std::vector<vertex2d> vertices_;
183 227
4 include/mapnik/symbolizer.hpp
@@ -29,6 +29,7 @@
29 29 #include <mapnik/metawriter.hpp>
30 30 #include <mapnik/image_compositing.hpp>
31 31 #include <mapnik/transform_expression.hpp>
  32 +#include <mapnik/simplify.hpp>
32 33
33 34 // boost
34 35 #include <boost/array.hpp>
@@ -90,6 +91,8 @@ class MAPNIK_DECL symbolizer_base
90 91 std::string get_transform_string() const;
91 92 void set_clip(bool clip);
92 93 bool clip() const;
  94 + void set_simplify_algorithm(simplify_algorithm_e algorithm);
  95 + simplify_algorithm_e simplify_algorithm() const;
93 96 void set_simplify_tolerance(double simplify_tolerance);
94 97 double simplify_tolerance() const;
95 98 void set_smooth(double smooth);
@@ -102,6 +105,7 @@ class MAPNIK_DECL symbolizer_base
102 105 composite_mode_e comp_op_;
103 106 transform_type affine_transform_;
104 107 bool clip_;
  108 + simplify_algorithm_e simplify_algorithm_value_;
105 109 double simplify_tolerance_value_;
106 110 double smooth_value_;
107 111 };
1  src/build.py
@@ -151,6 +151,7 @@ def ldconfig(*args,**kwargs):
151 151 proj_transform.cpp
152 152 distance.cpp
153 153 scale_denominator.cpp
  154 + simplify.cpp
154 155 memory_datasource.cpp
155 156 stroke.cpp
156 157 symbolizer.cpp
15 src/load_map.cpp
@@ -882,6 +882,21 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt)
882 882 optional<boolean> clip = pt.get_opt_attr<boolean>("clip");
883 883 if (clip) sym.set_clip(*clip);
884 884
  885 + // simplify algorithm
  886 + optional<std::string> simplify_algorithm_name = pt.get_opt_attr<std::string>("simlify-op");
  887 + if (simplify_algorithm_name)
  888 + {
  889 + optional<simplify_algorithm_e> simplify_algorithm = simplify_algorithm_from_string(*simplify_algorithm_name);
  890 + if (simplify_algorithm)
  891 + {
  892 + sym.set_simplify_algorithm(*simplify_algorithm);
  893 + }
  894 + else
  895 + {
  896 + throw config_error("failed to parse simplify-algorithm: '" + *simplify_algorithm_name + "'");
  897 + }
  898 + }
  899 +
885 900 // simplify value
886 901 optional<double> simplify_tolerance = pt.get_opt_attr<double>("simplify-tolerance");
887 902 if (simplify_tolerance) sym.set_simplify_tolerance(*simplify_tolerance);
4 src/save_map.cpp
@@ -357,6 +357,10 @@ class serialize_symbolizer : public boost::static_visitor<>
357 357 {
358 358 set_attr( node, "clip", sym.clip() );
359 359 }
  360 + if (sym.simplify_algorithm() != dfl.simplify_algorithm() || explicit_defaults_)
  361 + {
  362 + set_attr( node, "simplify-algorithm", *simplify_algorithm_to_string(sym.simplify_algorithm()) );
  363 + }
360 364 if (sym.simplify_tolerance() != dfl.simplify_tolerance() || explicit_defaults_)
361 365 {
362 366 set_attr( node, "simplify-tolerance", sym.simplify_tolerance() );
41 src/simplify.cpp
... ... @@ -0,0 +1,41 @@
  1 +// mapnik
  2 +#include <mapnik/simplify.hpp>
  3 +
  4 +// boost
  5 +#include <boost/assign/list_of.hpp>
  6 +#include <boost/bimap.hpp>
  7 +
  8 +namespace mapnik
  9 +{
  10 +
  11 +typedef boost::bimap<simplify_algorithm_e, std::string> simplify_algorithm_lookup_type;
  12 +static const simplify_algorithm_lookup_type simplify_lookup = boost::assign::list_of<simplify_algorithm_lookup_type::relation>
  13 + (radial_distance,"radial-distance")
  14 + (douglas_peucker,"douglas-peucker")
  15 + (visvalingam_whyatt,"visvalingam-whyatt")
  16 + (zhao_saalfeld,"zhao-saalfeld")
  17 + ;
  18 +
  19 +boost::optional<simplify_algorithm_e> simplify_algorithm_from_string(std::string const& name)
  20 +{
  21 + boost::optional<simplify_algorithm_e> algo;
  22 + simplify_algorithm_lookup_type::right_const_iterator right_iter = simplify_lookup.right.find(name);
  23 + if (right_iter != simplify_lookup.right.end())
  24 + {
  25 + algo.reset(right_iter->second);
  26 + }
  27 + return algo;
  28 +}
  29 +
  30 +boost::optional<std::string> simplify_algorithm_to_string(simplify_algorithm_e value)
  31 +{
  32 + boost::optional<std::string> algo;
  33 + simplify_algorithm_lookup_type::left_const_iterator left_iter = simplify_lookup.left.find(value);
  34 + if (left_iter != simplify_lookup.left.end())
  35 + {
  36 + algo.reset(left_iter->second);
  37 + }
  38 + return algo;
  39 +}
  40 +
  41 +}
11 src/symbolizer.cpp
@@ -51,6 +51,7 @@ symbolizer_base::symbolizer_base()
51 51 writer_ptr_(),
52 52 comp_op_(src_over),
53 53 clip_(true),
  54 + simplify_algorithm_value_(radial_distance),
54 55 simplify_tolerance_value_(0.0),
55 56 smooth_value_(0.0)
56 57 {
@@ -152,6 +153,16 @@ bool symbolizer_base::clip() const
152 153 return clip_;
153 154 }
154 155
  156 +void symbolizer_base::set_simplify_algorithm(simplify_algorithm_e algo)
  157 +{
  158 + simplify_algorithm_value_ = algo;
  159 +}
  160 +
  161 +simplify_algorithm_e symbolizer_base::simplify_algorithm() const
  162 +{
  163 + return simplify_algorithm_value_;
  164 +}
  165 +
155 166 void symbolizer_base::set_simplify_tolerance(double simplify_tolerance)
156 167 {
157 168 simplify_tolerance_value_ = simplify_tolerance;

0 comments on commit 22150f9

Please sign in to comment.
Something went wrong with that request. Please try again.