[GIS] Using meters to buffer with JSTS

bufferjstsopenlayers

I'm trying to create a buffer using OpenLayers with JSTS library.

However, even after transforming geometry from EPSG:4326 to EPSG:3857, the buffer method doesn't create distance in meters as expected.

Take this code snippet, which runs on an OpenLayers Map with view with projection EPSG:3857:

const geoInput = {
    type: 'Point',
    coordinates: [
        14.432940,
        50.077371
    ]
};
const geoJsonFormat = new GeoJSON();
const features = geoJsonFormat.readFeatures(geoInput, {
    dataProjection: 'EPSG:4326',
    featureProjection: 'EPSG:4326'
});
const parser = new jsts.io.OL3Parser();
parser.inject(Point, LineString, LinearRing, Polygon, MultiPoint, MultiLineString, MultiPolygon, Circle);
const originalFeatures = [];
const bufferedFeatures = [];

for(let i = 0; i < features.length; i++) {
    const featGeom = features[i].getGeometry().clone();
    featGeom.transform('EPSG:4326', 'EPSG:3857');
    const bufferedJsts = parser.read(featGeom).buffer(251300); // in km ?
    const buffered = parser.write(bufferedJsts);
    originalFeatures.push(new Feature(featGeom));
    bufferedFeatures.push(new Feature(buffered));
}
const source = new VectorSource();
source.addFeatures(originalFeatures);
source.addFeatures(bufferedFeatures);
const vectorLayer = new VectorLayer({source});

This code snippet tries to put a circle from Prague with a distance of 251 km.
The circle obviously doesn't have radius of 251 km, as that's the distance between Prague and Vienna (according to Google Maps) and the buffer doesn't match that.

enter image description here

Even the official example in OpenLayers page doesn't seem like producing correct buffer – https://openlayers.org/en/latest/examples/jsts.html
enter image description here

Am I missing something out, or is it a problem report for JSTS library?

Best Answer

As it turns out, using Turf library instead of JSTS is simpler and works with meters:

const format = new GeoJSON();
const features = format.readFeatures(geoInput, {
    featureProjection: 'EPSG:3857'
});
const buffered = turf.buffer(geoInput, 251300, {
    units: 'meters'
});
Related Question