# How to create Geodesic Polygons in OpenLayers?

I would like to create geodesic polygons in openlayers. This is not the same as this question although VERY similar.

Geographika was able to do it but his solution is based on a circle. I'm interested in creating polygons that aren't necessarily circles, such as squares. Or maybe even a line.

Anyone know of any javascript snippet that might convert my geometric openlayers polygons to geodesic ones?

Google Maps has the Geodesic:true property for its shapes. OpenLayers should definitely have it.

• How exactly are you constructing your polygons? Through the OpenLayers tools or in code with distances? Nov 30, 2011 at 13:10
• @geographika: I'm constructing them mostly using OpenLayers.Format.WKT `var myFeature = format.read("POLYGON((-102.65625 5.2734375, -109.6875 -42.5390625, 97.03125 -39.7265625, 99.140625 6.6796875, -102.65625 5.2734375))");` Nov 30, 2011 at 13:55
• Actually the user has the option of drawing a polygon on the map with the OpenLayers tools as well. But for simplicity sake, let's just suppose i'm using the Format.WKT. Nov 30, 2011 at 21:50

If you only have two points on a line you may have to create more vertices and then reproject these to EPSG:4326 and back again to create something similar to the Google example.

There is an OpenLayers example of Great Circle lines here. The source code for the algorithms is also online.

There is a getGeodesicArea function on OpenLayer polygons, and geometry collections. There is also a getGeodesicLength function. These algorithms are implemented based on the following (according to the docs):

Robert. G. Chamberlain and William H. Duquette, “Some Algorithms for Polygons on a Sphere”, JPL Publication 07-03, Jet Propulsion Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409

Looking at the sourcecode it reprojects points to 4326, and then uses the OpenLayers.Util.distVincenty function to calculate the distance between points on the surface of an ellipsoid (the earth).

``````getGeodesicLength: function(projection) {
var geom = this; // so we can work with a clone if needed
if(projection) {
var gg = new OpenLayers.Projection("EPSG:4326");
if(!gg.equals(projection)) {
geom = this.clone().transform(projection, gg);
}
}
var length = 0.0;
if(geom.components && (geom.components.length > 1)) {
var p1, p2;
for(var i=1, len=geom.components.length; i<len; i++) {
p1 = geom.components[i-1];
p2 = geom.components[i];
// this returns km and requires lon/lat properties
length += OpenLayers.Util.distVincenty(
{lon: p1.x, lat: p1.y}, {lon: p2.x, lat: p2.y}
);
}
}
// convert to m
return length * 1000;
}
``````

For polygons areas, the algorithm is in the LinearRing source, and uses the earth's radius of 6378137 and geometry to calculate the geodesic area.

``````getGeodesicArea: function(projection) {
var ring = this; // so we can work with a clone if needed
if(projection) {
var gg = new OpenLayers.Projection("EPSG:4326");
if(!gg.equals(projection)) {
ring = this.clone().transform(projection, gg);
}
}
var area = 0.0;
var len = ring.components && ring.components.length;
if(len > 2) {
var p1, p2;
for(var i=0; i<len-1; i++) {
p1 = ring.components[i];
p2 = ring.components[i+1];
area += OpenLayers.Util.rad(p2.x - p1.x) *
}
area = area * 6378137.0 * 6378137.0 / 2.0;
}
return area;
},
``````

The main problem I had with the circle was that I only had one reference coordinate, and there was no inbuilt way in OpenLayers to create a circle around this point apart from on a Cartesian plane. However with the OpenLayers.Util.distVincenty function it was relatively easy to calculate these.

This patch to OpenLayers,

http://trac.osgeo.org/openlayers/ticket/3426

provides accurate geodesic calculations including the ability to compute the area of a geodesic polygon accurately.

http://geographiclib.sourceforge.net/scripts/geod-calc.html

previews some of the capabilities (including giving the area of the polygon).

• See also this paper: C. F. F. Karney, Algorithms for Geodesics, J. Geod, DOI: dx.doi.org/10.1007/s00190-012-0578-z
– cffk
Sep 1, 2012 at 19:09