2

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.

6
  • 4
    Divide the actual meters by the cosine of the latitude of the center and draw the circle with those fake meters. – Gabriel De Luca Jan 17 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? – bugmenot123 Jan 17 at 21:15
  • Yes but hard, compute the coordinates of a geodesic problem for each vertex of the circle. – Gabriel De Luca Jan 17 at 21:22
  • 3
    Instead of Circle geometry using circular openlayers.org/en/main/apidoc/… – Mike Jan 17 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. – Gabriel De Luca Jan 17 at 22:38
4

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.

0

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 rlat = (radius / earthsradius) * r2d; 
  var rlng = rlat / Math.cos(point[1] * 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[0] + (rlng * Math.cos(theta)); // center a + radius x * cos(theta) 
    ex = point[1] + (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)

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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