I was wondering if there was a way to create a buffer around a polyline feature in OpenLayers 2. I have created a tool that allows the user to draw a circle buffer zone of whatever size and style they want around a single point (using this handy walkthough ), but was just wondering if I could do the same with Polylines. The user would define the size of their buffer zone and then draw their polyline on to the map. Once finished drawing the buffer would be added to the map, like the example I made in MapInfo below.
OpenLayers – Creating Polyline Buffer in OpenLayers 2
bufferopenlayers-2
Related Solutions
If you're home-brewing in the browser, you can get a "circle" (it will not be round on the screen due to your projection; rather approximated by a polygon w/ as many points as you care to draw), use a the direct form of geodesic calculations: given a point, a direction (azimuth), and a distance it gives you the resulting point. Gory details: http://en.wikipedia.org/wiki/Vincenty%27s_formulae#Direct_Method
Looks like someone has done a translation to JavaScript already: http://www.movable-type.co.uk/scripts/latlong-vincenty-direct.html. Lucky you!
To finish things off:
- Decide how chunky (# of vertices, call it n) you are willing to have the end result be.
- Divide 360 degrees into n pieces.
- Build a polygon by (for i in range(n): polygon.add(vincenty_direct(start_point, i * 360/n, distance)))
- After-the-fact, possibly fix up some projection and planarisation irritations:
- If you're using the typical web map projection, which you almost certainly are, the resulting polygon will be hugely stretched vertically if it nears a pole.
- Similarly, if the result polygon crosses the international date line, it'll be really borked.
Here's an example of creating two layers like you said, one polygon layer and one circle layer.
It first creates the polygon from the coords you provided above and then creates a 3 kilometer radius circle from the centroid of that feature.
Update per comment:
/*
* APIMethod: createGeodesicPolygon
* Create a regular polygon around a radius. Useful for creating circles
* and the like.
*
* Parameters:
* origin - {<OpenLayers.Geometry.Point>} center of polygon.
* radius - {Float} distance to vertex, in map units.
* sides - {Integer} Number of sides. 20 approximates a circle.
* rotation - {Float} original angle of rotation, in degrees.
* projection - {<OpenLayers.Projection>} the map's projection
*/
Update #2 Per Comment:
So if you'd like to style all the features in the layer the same you could add the style at the layer level:
var vectorLayer = new OpenLayers.Layer.Vector("myPolygonLayer", {
styleMap: new OpenLayers.StyleMap({
"default": new OpenLayers.Style({
fillColor: "#33CC00",
strokeColor: "#000000",
strokeWidth: 1
})
})
});
Or you can style it at the individual feature level:
var style_Green_Box = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
style_Green_Box.strokeColor = "#000000";
style_Green_Box.fillColor = "#33CC00";
style_Green_Box.strokeWidth = 1;
circleFeature.style = style_Green_Box;
Here's the DEMO Update which shows this.
Best Answer
There are 2 ways you could approach this; server side or client side. The approach you take will depend on whether you want the processing overhead on the client or on the server (or even if you have access to a backend server like GeoServer).
Method 1: Client Side
There is a pure JavaScript port of the Java Topology Suite called JSTS which contains (amongst many other things) a buffer operation. There is an example of doing a buffer operation with OpenLayers which you could adapt to your own needs.
Method 2: Server Side
If you have access to GeoServer then you can achieve what you need through the WPS extension of GeoServer (Web Processing Service).
The default installation of GeoServer's WPS extension contains a number of different processes that can be run including several for buffering:
In my opinion the
JTS:buffer
process is most like what you have mocked up using MapInfo. TheJTS:buffer
process takes the following parameters:The output from the process is the generated buffer geometry and that can be requested in a number of formats, all of which can be read by OpenLayers. So, the process I would follow is:
An example XML request could be:
The result from this request would be a WKT encoding of a polygon that is the 50m buffer of the input polyline.
Note that this approach will work with any backend map server that supports the OGC WPS specification.