I'm facing a strange behavior using buffers in Turf.js.
When trying to do a 50m buffer around a point, the result is actually closer to 35m.
On the screenshot below, the smaller circle is a turf.buffer() and the bigger one is a turf.circle() using the same radius/distance. This second one is correct.
Here's my code :
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.transform([5, 45], 'EPSG:4326', 'EPSG:3857'),
zoom: 17
})
});
var distance = 50
var center = turf.point([5, 45])
var bufferedWgs84 = turf.buffer(center, distance/1000, {units: 'kilometers'});
var circleWgs84 = turf.circle(center, distance/1000, {units: 'kilometers'});
var buffer = turf.toMercator(bufferedWgs84)
var circle = turf.toMercator(circleWgs84)
var layer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0)'
}),
stroke: new ol.style.Stroke({
color: '#737373',
width: 2
})
})
});
map.addLayer(layer);
layer.getSource().addFeature(new ol.format.GeoJSON().readFeature(buffer))
layer.getSource().addFeature(new ol.format.GeoJSON().readFeature(circle))
Fiddle : https://jsfiddle.net/fhkgzd2o/1/
Best Answer
Simple experiment show it's really question of projection. If you take coordinate [0, 0] as center of the circle and buffer, they match. If you calculate factor for diameter difference betwee buffer and circle at 45° of latitude, you get approximately 1.41, whch is exactly the value of Mercator projection length factor
1/Math.cos(latitude*Math.PI/180)
.This tells that
turf.circle
has real diameter andturf.buffer
method somehow behaves as having diameter at latitude 0° in projected CRS. To get the same result as withturf.circle
method, diameter has to be multiplied with Mercator projection length factor.EDIT (July 2022):
This problem was present with turf.js version 5.1.6. It is corrected now with version 6.5.0.