Geographic Information Systems Asked by bugmenot123 on February 18, 2021
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.
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.
Answered by Gabriel De Luca on February 18, 2021
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)
Answered by geocodezip on February 18, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP