Stay Connected with the Boundless Blog

GeoServer Geospatial Software Split Polygon WPS Process Part II

In a previous entry, Martin explains the creation of a GeoServer WPS process for splitting polygons. In this follow-up, we’ll describe how a web client can take advantage of this process to split polygons using sketches drawn in the browser.

First, let’s see it in action:

The above example makes use of utilities in OpenLayers to draw vector features and execute WPS processes. Stitching it all together involves four basic steps.

Creating the map

In a real application that takes advantage of a polygon splitting process, you’d likely be allowing users to digitize features over some base layer and persisting changes to the server (via a WFS transaction for example). To keep things simple for this example, we’ve just created a map with a single base layer using tiles from MapQuest and a single vector layer to render the geometry sketches.

Adding drawing controls

This simple demo application allows the user to draw one or more polygons (with optional holes), draw “splitter” lines to split any intersecting polygons, and then drag the pieces apart to verify that the splits worked. To accomplish this, we’ve added three additional controls to the map (named drawPoly, drawLine, and dragPoly). These controls are activated and deactivated by the user with three radio buttons.

When the drawPoly control is active, the user can digitize any number of polygons – using the shift key to enable freehand drawing and the alt/option key to digitize holes in existing polygons.

With the splitPoly control active, the user can draw a linestring. To engage the splitting process, we wait for the sketchcomplete event by adding a listener to the vector layer. This listener will be called before any digitized feature is added to the layer. If the sketched feature has a linestring geometry, we want to consider splitting any intersecting polygons. For every intersecting polygon, the listener removes the original feature and calls a method (named executeSplit) to execute the split process.

Issuing the request to execute the process

The gs:SplitPolygon process accepts geometry inputs named polygon and line and returns the result of a split with the name result. GeoServer will accept GML (2.1.2 or 3.1.1) or WKT for the input geometries and can produce the same for the result. Our client uses WKT for inputs and outputs. When the executeSplit method is called, it creates a data structure with the required inputs and desired output. OpenLayers serializes this data structure as a WPS Execute request and POSTs it to the /geoserver/wps endpoint for execution.

Handling the results of the split

When GeoServer returns the results from the gs:SplitPolygon process, our client code parses the result (expecting a WKT GEOMETRYCOLLECTION). Since we previously removed each of the target polygons before splitting, if the response includes multiple geometries (a successful split), we add a feature for each new polygon geometry to the layer.

If the response doesn’t include any geometries (for example, if the line crosses the exterior of a polygon only once), we add the original target feature back. Because the handler for the posted request is defined in the executeSplit closure, we aren’t concerned about the order of returned responses. Any number of requests can be executed and returned in any order, and we always have access to the original polygon in case the process didn’t result in a split.

Finally, when the dragPoly control is active, the user can drag existing polygon features around the map to confirm that the split process works as advertised.

Running the Demo at Home

The gs:SplitPolygon process should be included the upcoming OpenGeo Suite 3.0 release. If you’d like to try it out before, download the splitpoly.jar archive and drop it in your GeoServer WEB-INF/lib directory. Restart GeoServer and issue a DescribeProcess request to verify that the process is there.

Find the client side of the demo application on GitHub (see examples/split-poly.js). You’ll need to serve up the client side of the application on the same origin as GeoSever. The readme in the repository describes how you can proxy GeoServer on port 80 if you’re serving the client-side resources with Apache.