[GIS] How to draw a circle in OpenLayers 2 and measure its radius dynamically

dynamicgeodesicMeasurementsopenlayers-2

With OpenLayers 2.13, I want to draw a circle and obtain its radius at each mousemove. The radius would then be returned as arguments of a callback function, for example. But of course, this is not the problem here.

I have tried several ways but none of the worked the way I want:

METHOD A

I tried to change the "move" method in OpenLayers.Handler.RegularPolygon, adding a custom event in the control of the handler. It worked but, it does not fit my needs, because:

  • I can only calculate the "normal" length, and not the "geodesic" length. So, I never get a correct radius.
  • By the way, changing the core of OpenLayers doesn't seem very clean to me, nor safe!

METHOD B

Using OpenLayers.Control.Measure together with OpenLayers.Control.DrawFeatiure, seemed to be the best option to me. I registered an event for "measurepartial", but it didn't return anything. The "measurepartial" event is not triggered when drawing a circle (RegularPolygon) because there is no point being added (I suppose this is the reason).

SOURCES

  • In this question, it is asked something very similar to what I ask, bt there was no good answer for y case, so I tried to investigate it and post my own question.
  • In this question, I found the exact same problem as mine, and it is based on this that I applied METHOD A.

CONCLUSION

I would rather use something like METHOD B, but I don't know how. The "measurepartial" event is not triggered when using RegularPolygon.

I didn't post code, because it is work-related. And by the way, I think I explained everything that needed to be told.

Best Answer

You could try to use the move callback:

var my_polygonhandler = OpenLayers.Handler.RegularPolygon;

var polygonControl = new OpenLayers.Control.DrawFeature(circles,
my_polygonhandler, {
    handlerOptions: {
        sides: 40
    }
});

polygonControl.handler.callbacks.move = function (e) {

    var linearRing = new OpenLayers.Geometry.LinearRing(e.components[0].components);
    var geometry = new OpenLayers.Geometry.Polygon([linearRing]);
    var polygonFeature = new OpenLayers.Feature.Vector(geometry, null);
    var polybounds = polygonFeature.geometry.getBounds();

    var minX = polybounds.left;
    var minY = polybounds.bottom;
    var maxX = polybounds.right;
    var maxY = polybounds.top;

    //calculate the center coordinates

    var startX = (minX + maxX) / 2;
    var startY = (minY + maxY) / 2;

    //make two points at center and at the edge
    var startPoint = new OpenLayers.Geometry.Point(startX, startY);
    var endPoint = new OpenLayers.Geometry.Point(maxX, startY);
    var radius = new OpenLayers.Geometry.LineString([startPoint, endPoint]);
    var len = Math.round(radius.getLength()).toString();

    document.getElementById("radius").innerHTML = len;


}

I just set up a jsfiddle to demonstrate how to use it:

http://jsfiddle.net/expedio/L529bqb5/

If you want to calculate geodesic length you can use the method "getGeodesicLength" of your linestring.