Skip to content

faster line-join and line-cap rendering #869

Open
artemp opened this Issue Oct 11, 2011 · 1 comment

2 participants

@artemp
Mapnik member
artemp commented Oct 11, 2011

agg supports setting the approximation_scale which can be used to optimize the drawing of line-joins when round is used (which is more expensive) and to a lesser extent line-caps when round.

A setting of 0.01 can almost double rendering times in a simple test of LineSymbolizer used on world borders shapefile with linejoin-round. In this case the rendering effect is to make lines appear crisper and better looking.

@springmeyer
Mapnik member
Index: bindings/python/mapnik_stroke.cpp
===================================================================
--- bindings/python/mapnik_stroke.cpp   (revision 3281)
+++ bindings/python/mapnik_stroke.cpp   (working copy)
@@ -68,17 +68,18 @@
                                          dashes,
                                          s.get_line_cap(),
                                          s.get_line_join(),
-                                         s.get_gamma());
+                                         s.get_gamma(),
+                                         s.get_approximation_scale());
     }

     static void
     setstate (stroke& s, boost::python::tuple state)
     {
         using namespace boost::python;
-        if (len(state) != 5)
+        if (len(state) != 6)
         {
             PyErr_SetObject(PyExc_ValueError,
-                            ("expected 5-item tuple in call to __setstate__; got %s"
+                            ("expected 6-item tuple in call to __setstate__; got %s"
                              % state).ptr()
                 );
             throw_error_already_set();
@@ -99,6 +100,7 @@
         s.set_line_cap(extract<line_cap_e>(state[2]));
         s.set_line_join(extract<line_join_e>(state[3]));
         s.set_gamma(extract<double>(state[4]));
+        s.set_approximation_scale(extract<double>(state[5]));

     }

@@ -151,6 +153,11 @@
                       &stroke::set_gamma, 
                       "Gets or sets the gamma of this stroke.\n"
                       "The value is a float between 0 and 1.\n")
+        .add_property("approximation_scale",
+                      &stroke::get_approximation_scale,
+                      &stroke::set_approximation_scale, 
+                      "Gets or sets the approximation-scale of this stroke.\n"
+                      "The value is a float between 0 and 1.\n")
         .add_property("line_cap",
                       &stroke::get_line_cap,
                       &stroke::set_line_cap,
Index: src/stroke.cpp
===================================================================
--- src/stroke.cpp  (revision 3281)
+++ src/stroke.cpp  (working copy)
@@ -54,6 +54,7 @@
       line_cap_(BUTT_CAP),
       line_join_(MITER_JOIN),
       gamma_(1.0),
+      approximation_scale_(1.0),
       dash_(),
       dash_offset_(0) {}

@@ -64,6 +65,7 @@
       line_cap_(BUTT_CAP),
       line_join_(MITER_JOIN),
       gamma_(1.0),
+      approximation_scale_(1.0),
       dash_(),
       dash_offset_(0.0) {}

@@ -74,6 +76,7 @@
       line_cap_(other.line_cap_),
       line_join_(other.line_join_),
       gamma_(other.gamma_),
+      approximation_scale_(other.approximation_scale_),
       dash_(other.dash_), 
       dash_offset_(other.dash_offset_) {}

@@ -145,6 +148,16 @@
     return gamma_;
 }

+void stroke::set_approximation_scale(double approximation_scale)
+{
+    approximation_scale_ = approximation_scale;
+}
+
+double stroke::get_approximation_scale() const
+{
+    return approximation_scale_;
+}
+
 void stroke::add_dash(double dash, double gap)
 {
     dash_.push_back(std::make_pair(dash,gap));
Index: src/load_map.cpp
===================================================================
--- src/load_map.cpp    (revision 3281)
+++ src/load_map.cpp    (working copy)
@@ -1735,6 +1735,10 @@
     if (gamma) strk.set_gamma(*gamma);

     // stroke-dash-offset
+    optional<double> approximation_scale = get_opt_attr<double>(sym, "stroke-approximation-scale");
+    if (approximation_scale) strk.set_approximation_scale(*approximation_scale);
+
+    // stroke-dash-offset
     optional<double> dash_offset = get_opt_attr<double>(sym, "stroke-dash-offset");
     if (dash_offset) strk.set_dash_offset(*dash_offset);

@@ -1784,6 +1788,7 @@
     std::stringstream s;
     s << "stroke,stroke-width,stroke-opacity,stroke-linejoin,"
       << "stroke-linecap,stroke-gamma,stroke-dash-offset,stroke-dasharray,"
+      << "stroke-approximation-scale,"
       << "meta-writer,meta-output";

     ensure_attrs(sym, "LineSymbolizer", s.str());
Index: src/agg/process_line_symbolizer.cpp
===================================================================
--- src/agg/process_line_symbolizer.cpp (revision 3281)
+++ src/agg/process_line_symbolizer.cpp (working copy)
@@ -139,6 +139,7 @@

                 stroke.generator().miter_limit(4.0);
                 stroke.generator().width(stroke_.get_width() * scale_factor_);
+                stroke.generator().approximation_scale(stroke_.get_approximation_scale());
                 ras_ptr->add_path(stroke);
                 if (writer.first) writer.first->add_line(path, feature, t_, writer.second);
             }
Index: src/save_map.cpp
===================================================================
--- src/save_map.cpp    (revision 3281)
+++ src/save_map.cpp    (working copy)
@@ -593,6 +593,10 @@
         {
             set_attr( node, "stroke-gamma", strk.get_gamma());
         }
+        if ( strk.get_approximation_scale() != dfl.get_approximation_scale() || explicit_defaults_ )
+        {
+            set_attr( node, "stroke-approximation-scale", strk.get_approximation_scale());
+        }
         if ( strk.dash_offset() != dfl.dash_offset() || explicit_defaults_ )
         {
             set_attr( node, "stroke-dash-offset", strk.dash_offset());
Index: include/mapnik/stroke.hpp
===================================================================
--- include/mapnik/stroke.hpp   (revision 3281)
+++ include/mapnik/stroke.hpp   (working copy)
@@ -68,6 +68,7 @@
     line_cap_e  line_cap_;
     line_join_e line_join_;
     double gamma_;
+    double approximation_scale_;
     dash_array dash_;
     double dash_offset_;
 public:
@@ -93,7 +94,10 @@

     void set_gamma(double gamma);
     double get_gamma() const;
-        
+
+    void set_approximation_scale(double approximation_scale);
+    double get_approximation_scale() const;
+
     void add_dash(double dash,double gap);
     bool has_dash() const;
@springmeyer springmeyer referenced this issue in mapbox/mapbox-gl-js Mar 13, 2013
Closed

Decisions #1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.