Search code examples
node.jsturfjs

Strange turfjs area calculation


I am new to using turf (v6.5.0) but I thought this would be an easy start.

I have the following script that is resulting in very strange area calculations;

const turf = require("@turf/turf");

var polygon1 = turf.polygon([
  [
    [499980.0, 3600000.0],
    [609780.0, 3600000.0],
    [609780.0, 3490200.0],
    [499980.0, 3490200.0],
    [499980.0, 3600000.0],
  ],
]);
var polygon2 = turf.polygon([
  [
    [499981.0, 3599999.0],
    [533365.5903128482, 3599999.0],
    [505696.0943201342, 3490201.0],
    [499981.0, 3490201.0],
    [499981.0, 3599999.0],
  ],
]);

console.log(turf.area(polygon1));
console.log(turf.area(polygon2));

Gives the output;

1026723.1868805697
484499828397451.25

I believe that the second area is way off what it should be and I can't figure out why. Coords are fine as here is a QGIS screen shot of what they look like;

enter image description here


Solution

  • As I suspected it was my bad. I didn't realise that turfjs assumed WGS84. The below code is my fix.

    const turf = require("@turf/turf");
    const proj4 = require("proj4");
    
    poly1 = [
      [
        [499980.0, 3600000.0],
        [609780.0, 3600000.0],
        [609780.0, 3490200.0],
        [499980.0, 3490200.0],
        [499980.0, 3600000.0],
      ],
    ];
    poly2 = [
      [
        [499981.0, 3599999.0],
        [533365.5903128482, 3599999.0],
        [505696.0943201342, 3490201.0],
        [499981.0, 3490201.0],
        [499981.0, 3599999.0],
      ],
    ];
    
    transf = (coords, zoneNum) =>
      coords.map((c) =>
        c.map((cc) =>
          proj4(
            `+proj=utm +zone=${zoneNum} +datum=WGS84 +units=m +no_defs +type=crs`,
            "EPSG:4326",
            cc
          )
        )
      );
    
    poly1_wgs84 = transf(poly1, 37);
    poly2_wgs84 = transf(poly2, 37);
    
    var polygon1 = turf.polygon(poly1_wgs84);
    var polygon2 = turf.polygon(poly2_wgs84);
    
    console.log(turf.area(polygon1));
    console.log(turf.area(polygon2));