artemp/mapnik — Issue #635: Geometry Simplification
Author: artemp
Created: 2011-10-11 16:30:14+00:00
State: open
Labels: Core_Library

I've been playing around with patches against ctrans for both naive and more sophisticated simplification at render time.

The combo of the time it takes to recompile after changes to ctrans.hpp and the trickyness of working with path type geometries have kept me from getting fully baked patches. But I'm attaching now a few in-progress tinkerings to flag this issue.

The idea is to be able to speed up rendering by throwing away geometries, but so far I've not been able to get noticeable speed bumps.

Here is the naive one:

to be used in a renderer like:

{{{
path_type path(t_,geom,prj_trans,0.5);
}}}

{{{
#!diff
Index: include/mapnik/ctrans.hpp
===================================================================
--- include/mapnik/ctrans.hpp	(revision 2242)
+++ include/mapnik/ctrans.hpp	(working copy)
@@ -30,7 +30,10 @@
#include
#include
#include
+#include

+#include "agg_math.h"
+
namespace mapnik {
typedef coord_array CoordinateArray;

@@ -91,6 +94,94 @@
Geometry const& geom_;
proj_transform const& prj_trans_;
};
+
+template
+struct MAPNIK_DECL coord_transform2a
+{
+ coord_transform2a(Transform const& t,
+ Geometry const& geom,
+ proj_transform const& prj_trans,
+ float tolerance)
+ : t_(t),
+ geom_(geom),
+ prj_trans_(prj_trans),
+ tol_(tolerance),
+ lx(0.0),
+ ly(0.0),
+ m_status(initial) {}
+
+ enum status
+ {
+ initial,
+ process,
+ last,
+ end
+ };
+
+ unsigned vertex(double * x , double * y)
+ {
+ if (tol_ == 0.0){
+ unsigned command = geom_.vertex(x,y);
+ double z=0;
+ prj_trans_.backward(*x,*y,z);
+ t_.forward(x,y);
+ return command;
+ }
+ else
+ {
+ double z=0;
+ while(true)
+ {
+ switch(m_status)
+ {
+ case end:
+ return SEG_END;
+ break;
+ case initial:
+ command = geom_.vertex(x,y);
+ prj_trans_.backward(*x,*y,z);
+ t_.forward(x,y);
+ lx = *x;
+ ly = *y;
+ m_status = (command!=SEG_END)?process:end;
+ return command;
+ case process:
+ command = geom_.vertex(x,y);
+ prj_trans_.backward(*x,*y,z);
+ t_.forward(x,y);
+ bool ret = (agg::calc_distance(lx, ly, *x, *y) > tol_);
+ if (ret)
+ {
+ lx = *x;
+ ly = *y;
+ m_status = (command!=SEG_END)?process:end;
+ return command;
+ }
+ }
+ }
+ }
+ }
+
+ void rewind (unsigned pos)
+ {
+ geom_.rewind(pos);
+ }
+
+ Geometry const& geom() const
+ {
+	return geom_;
+ }
+
+private:
+ Transform const& t_;
+ Geometry const& geom_;
+ proj_transform const& prj_trans_;
+ float tol_;
+ status m_status;
+ unsigned command;
+ double lx;
+ double ly;
+};

template
struct MAPNIK_DECL coord_transform3
}}}