Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

offset_converter rewrite, refs #927 #1269

merged 2 commits into from Jun 29, 2012


None yet
3 participants

lightmare commented Jun 25, 2012

I've rewritten the line-offset algorithm. First it traverses all input vertices, computes new vertices in the given distance (not caring for self-intersections) and stores them in a vector. For each bend it computes the end-point of the preceding segment's parallel, the start-point of the next segment's parallel, and connects them by either a straight line (inner turn) or a bulge made of several vertices along the arc (outer turn). This raw line can be seen in the image below marked with (*) (I also left a commented //break enabling this in the code). When vertex(&x,&y) is called, it checks whether the line segment from previous to current vertex intersects the rest of the line - if it does, the intersection point is returned instead, and all vertices preceding it on the line are skipped.

http://i48.tinypic.com/33pen1s.png (red: old algo, blue: postgis)
http://i48.tinypic.com/2ihtocz.png (red: new algo)
http://i49.tinypic.com/zjhs7k.png (red: new algo, simplified geom)

Sample pictures in several zoom levels. The black line is original geom, blue is PostGIS ST_OffsetCurve, red and green are mapnik line-offset with the new algorithm:
http://i47.tinypic.com/eze3qd.png - looks bad where separate linestrings meet, would need some preprocessing for this zoom
http://i50.tinypic.com/2z5ouio.png - there's a glitch with the upper green line, it's caused by how the algo works
http://i45.tinypic.com/2iubye.png - this one looks good, in the bottom left corner there's a little space between two separate linestrings
http://i45.tinypic.com/2cxizib.png (*) - the above picture with intersection detection turned off, showing how the algorithm works

From the silly sharpy line I added above the real-world geometry you can see that postgis (libgeos actually) cuts out the whole two-sided buffer around the line, splitting the offset line in pieces. Maybe it won't be difficult to do - we can compute both parallels at the beginning and check intersections with both - but that's twice as many computations, and we're satisfied with one-side checks for now.

I'd like to see how this works with other people's data, please post pictures if you find some quirks.


springmeyer commented Jun 25, 2012

Impressive work. My usecases have been largely just offsetting at high zooms where sharp spikes were rare, but intersections were messy - I'll look for a time to test later this week - this looks vastly better but it will be interesting to see much the more robust intersection tests impact for the simple cases.

@artemp artemp merged commit 9ccce2f into mapnik:master Jun 29, 2012

@talaj talaj deleted the mapycz:line-offset branch Sep 19, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment