Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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.

share|improve this question
    
How exactly are you constructing your polygons? Through the OpenLayers tools or in code with distances? –  geographika Nov 30 '11 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))"); –  CaptDragon Nov 30 '11 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. –  CaptDragon Nov 30 '11 at 21:50

2 Answers 2

up vote 4 down vote accepted

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) *
                    (2 + Math.sin(OpenLayers.Util.rad(p1.y)) +
                    Math.sin(OpenLayers.Util.rad(p2.y)));
        }
        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.

share|improve this answer
    
Thanks man i really appreciate your help. (+1) –  CaptDragon Dec 1 '11 at 14:19

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).

share|improve this answer
    
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 '12 at 19:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.