Tuesday, June 5, 2012

Split OpenLayers Polygons with JSTS

Update: I've put several months of development into our app since this post was first published, with probably a couple weeks' extra work into the SplitPolygon tool.  Our tool is now production quality, but I won't post it here until I get word from our legal department on an OpenLayers CLA.  I'm leaving the old code up, but be warned that it's more like demo quality.  In particular, note that because this version doesn't split edges of "unaffected" polygons adjacent to affected polygons, split polygons may not merge cleanly back with their neighbors.  Also, because Mobile Safari likes to terminate long-running tasks without warning, I did significant rework to break tasks into the smallest pieces I could without modifying JSTS itself, and running the pieces on timers.  This was nice for other reasons, as it allowed me to display progress updates, etc.  Anyway, hopefully I'll get the real version posted... someday.

So I've got a half-baked SplitPolygon control for OpenLayers that's good enough for our use in a project here at work but not ready for submission back to OpenLayers (if they'd even accept a control with an external dependency), and I thought I should find some way to share it for others trying to do the same thing.  It seems like the typical route is one's personal "code blog."  So I made this lovely personal code blog, where I will share such thing(s).

Here's the SplitPolygon code.  It's just the OpenLayers Split Control, slightly mangled to handle polygons instead of polylines.  The Split control will technically handle any OpenLayers.Geometry with a "split" method, but as of OpenLayers 2.12, only polylines have this method.

It depends on the excellent JSTS, a JavaScript port of Martin Davis's JTS Topology Suite by the illustrious Bj√∂rn Harrtell, who (through his employer, SWECO Position AB), for a very reasonable fee, ported the critical Polygonizer.  The logic in the considerSplit function is ripped from a desktop application we wrote for the USDA.

The tool works through the supplied layer and splits all eligible features with the provided polyline.  The polyline can be arbitrarily complex, with self-intersections and other goodness.   It can split a single polygon into several pieces.  I put some code in to limit the splits to visible features because that was a requirement for our app.

Because we're using it on touch devices, which can't use CTRL-Z and ESC for undo and cancel, it adds two links to the map (one for undo and one for cancel).

I commented out some code we weren't using, and I mostly ignored parts of it that I didn't understand.  So this might serve as a base for your own tool but probably shouldn't be taken as-is.

Hope this helps!

No comments:

Post a Comment