# How to perform spatial computation in a Mercator projection in turf?

TL;DR: Spatial computation with turfjs does not work well in a EPSG:3857 map.

In a OpenLayers map, I use turf for transforming a line into a polygon by computing the offset line (aka side-buffer for instance in PostGIS).

Here's the process:

1. Draw a line using OpenLayers
2. Compute an offset line by a given distance `offsetDistance` using turf.lineOffset()
3. Gather all points and convert to a polygon.

And here's the code

``````const offsetLine = turf.lineOffset(line, offsetDistance / 1000);
const line2polygon = turf.lineString([
...turf.getCoords(line),
...turf.getCoords(offsetLine).reverse()
]);
const polygon = turf.lineToPolygon(line2polygon);
``````

The process works well except that there is a projection issue. In the image below I drew a line along the soccer pitch and I enter an offset distance of 53m, which is the width of the pitch. The problem is that the offset line is computed in the WGS84 coordinate system so the distance is actually too small (it is 53 m * cos(latitude)) and it does not result in a square polygon. The OpenLayers map is in EPSG:3857 and I would not like to change that.

I manage to do something OK by converting first the line to Mercator and by multiplying the offset distance by a scale factor (1.783 * 100000) that I got by trial-error:

``````const offsetLine = turf.lineOffset(turf.toMercator(line), offsetDistance / 1000 * 100000 * 1.783);
const line2polygon = turf.lineString([
...turf.getCoords(line),
...turf.getCoords(turf.toWgs84(offsetLine)).reverse()
]);

const polygon = turf.lineToPolygon(line2polygon);
``````

And I got this:

So the result is OK but is there a better way to do it? And how can I compute my scale factor properly (I guess it is dependent on the latitude but I could not find the formula)? Surprisingly, my scale factor is not equal to `cos(latitude)`.

• Does this help: gis.stackexchange.com/questions/347548/… Apr 25, 2020 at 9:46
• Yes, this is completely related. But my scale factor is not exactly equal to cos(latitude) and I don't figure out why. And I wonder if there is a proper way to do computation without resorting to multiplying by a scale factor. Apr 25, 2020 at 10:33

I don't think Turf can deal with Mercator projection in it's functions. Instead of trying to find out the algorithm for the right factor, it's possible to get the correct offset line with Turf's `turf.bearing` and `turf.destination` methods.

If the line goes down, the code below will calculate polygon with offset 65m to the right of the line:

``````var linePoints = turf.getCoords(line);
var bearing = turf.bearing(turf.point(linePoints[0]), turf.point(linePoints[1]));
var destPoint4 = turf.destination(turf.point(linePoints[0]), 0.065, bearing - 90);
var destPoint3 = turf.destination(turf.point(linePoints[1]), 0.065, bearing - 90);
var point4 = turf.getCoords(destPoint4);
var point3 = turf.getCoords(destPoint3);
var polygon = turf.polygon([[linePoints[0], linePoints[1], point3, point4, linePoints[0]]]);
``````

I was able to find very similar plot in our country, here is the result when the initial line goes top down on the left side of the field:

• Thank you. This is a correct answer for a line with 2 points but I need a solution for any lines with >= 2 points. This could be the basis however for an algorithm for any lines >= 2 points. Apr 27, 2020 at 11:27
• I think I got the algo for n-lines: Apr 27, 2020 at 12:12