views:

153

answers:

4

I'm searching for algorithms to reduce the LOD of polylines, lines (looped or not) of nodes. In simple words, I want to take hi-resolution coastline data and be able to reduce its LOD hundred- or thousandfold to render it in small-scale.

I found polygon reduction algorithms (but they require triangles) and Laplacian smoothing, but that doesn't seem exactly what I need.

+1  A: 

I developed a very simple algorithm, using the distance of a given point to the following points to decide whether it makes sense to include them in the rendering. Depending on current scale you could associate a minimum distance between points required for a transformed model.

stacker
I thought of this too. Did you consider averaging several near points into one?
culebrón
@culebrón no I just skipped all points which are too close to the starting point and use the selected point as the next starting point.
stacker
+2  A: 

When I was looking at turning a Bezier curve into straight line segments, what I ended up doing was defining a maximum distance between the curve and a straight line between two points of the curve. Start with one point being one end-point, slide the other end along the curve, until sliding it any further would exceed the maximum distance. Then do it again, using the second (and so on) point, until you've covered the whole curve.

You should be able to generate multiple LODs by simply increasing the distance allowed between the line segments and your poly-line.

Vatine
+5  A: 

The solution that I've found and quite probably will use, is Ramer-Douglas-Peucker algorithm. It's used in PostGIS

Add: I've published my own implementation in Python

culebrón
+1  A: 

I'm a fan of sorting the points based on the angle that the segments make on either side of the point, then removing the points with the shallowest angle iteratively until you hit some threshold. O(n log(n)) I think, versus the RDP method's O(n^2), and with smaller constants to boot. :)

The angle can even be scaled by the segment lengths (indeed it's easier to compute it this way) if you want to give more weight (desirability) to longer segments.

Given p0, p1, p2, p1's weight would be ((p0 - p1) dot (p2 - p1)), normalize the differences if you don't want to weight by length. (Contrast this to distance-to-line, it is much cheaper, and the results may be identical.)

dash-tom-bang
Actually- this could even be a O(n) solution, if you just march front to back and remove points that don't meet your angle criteria; just look one or two ahead of where you might be removing points to make sure that better-to-remove points aren't coming up.
dash-tom-bang
I see a weak spot in this algorithm: if you have a rectangle with a very small but bushy "star" at one of the corners (that has sharp corners), this algorithm will wipe out the rectangle first.
culebrón
You may need to tweak your weighting, e.g. so that a vertex with two "long" edges would be seen as less desirable to remove. The single-pass take on this algorithm would be less useful in cases like this. However, my last paragraph in the original post should nudge in a decent direction.
dash-tom-bang