# Creating a circle in actual meters

How can I create a circle (or "buffer") around a point anywhere on the globe in modern Open Layers with a radius specified in actual meters?

"Actual" meters meaning that a geodetic measurement from the center of the circle to one of its points would return about the same distance as was used to create the buffer. "Fake" meters like in EPSG:3857 are what I am trying to escape.

OL has a Circle constructor that takes a radius parameter which is used in units of the projection. As there is no global projection that allows us to create nice circular buffers with actual meters, this cannot be used.

Using Geodesic Measurements for Circle Radii? is for an hugely outdated version of Openlayers.

• Divide the actual meters by the cosine of the latitude of the center and draw the circle with those fake meters. Jan 17, 2021 at 20:51
• That looks interesting thanks! A first try in QGIS looks good but shows errors of up to ~0.5% near the equator or towards the poles (995m instead of 1000m). Is there something more accurate? Jan 17, 2021 at 21:15
• Yes but hard, compute the coordinates of a geodesic problem for each vertex of the circle. Jan 17, 2021 at 21:22
• Instead of Circle geometry using circular openlayers.org/en/main/apidoc/…
– Mike
Jan 17, 2021 at 22:11
• The 0.5% error may be due to the difference between medium and real radius. Other choice can be draw it in ellipsoidal Mercator projection and transform. Jan 17, 2021 at 22:38

The following is only valid for differential elements of a direct Mercator projection on a unit sphere:

• In the direction of parallels, deformation modulus is constant. And a parallel circumference measures `2 π cos(φ)` on the sphere surface and `2 π` on the projected image.

• We know that it is conform, so we will save ourselves from calculating the deformation in the direction of the meridians, which respect the orthogonality with the parallels on both surfaces. (The projection is analytically conform, the transformation in the direction of the meridians is the one that fulfills that the deformation modulus in that direction is the same as in the parallels one.)

• So being conform, let's say the longitudinal Mercator modulus of deformation at a point is `1 / cos(φ)` in any direction.

Although this is not true for a Web Mercator projection of a non-spherical objective surface, it is nevertheless quite close.

So if the tolerance of your work allows it, one way to reach your goal is to divide the actual meters by the cosine of the latitude of the center of the circle, and use that measurement as the radius.

One option would be to create a circular polygon with the correct radius. The function below makes a 32 vertex circular polygon centered on a point:

``````function drawCircle(point, radius, dir) {
var d2r = Math.PI / 180;   // degrees to radians
var r2d = 180 / Math.PI;   // radians to degrees
var earthsradius = 6378137.0; // 6378137.0 is the radius of the earth in meters

var points = 32;

// find the raidus in lat/lon
var rlng = rlat / Math.cos(point * d2r);

var extp = new Array();
if (dir==1)  {var start=0;var end=points+1} // one extra here makes sure we connect the
else     {var start=points+1;var end=0}
for (var i=start; (dir==1 ? i < end : i > end); i=i+dir)
{
var theta = Math.PI * (i / (points/2));
ey = point + (rlng * Math.cos(theta)); // center a + radius x * cos(theta)
ex = point + (rlat * Math.sin(theta)); // center b + radius y * sin(theta)
extp.push([ey, ex]);
}
return extp;
}
``````

live example (red circle from the function, blue circle is the OpenLayers Circle)

• OpenLayers could do the red circle directly with `var polygon = ol.geom.Polygon.circular([parseFloat(response.lon), parseFloat(response.lat)], 4000);` instead of `var polygon = new ol.geom.Polygon([ring]);`
– Mike
Jan 18, 2021 at 20:25