1

I am trying to do some geometry calculation (e.g distance from point to line) on 2D planar planes.

Currently investigating turfjs to calculate distance from point to line.


Code

distance.js:

// hello
var turf = require('@turf/turf')

init();

// init,
function init() {
    distance();
}

function distance() {
    // line
    let line = turf.lineString([
    [0, 0],
    [3, 4]
    ]);
    console.log(line);

    // point
    let point = turf.point([3, 0]);
    console.log(point);

    // calculate distance from point to line, using planar,
    let dis = turf.pointToLineDistance(point, line, {
    units: 'degrees',
    method: 'planar'
    });
    console.log("distance: %f", dis);
}

Output

distance: 2.398995395932417

If I change point to [30, 0] and line to [0, 0], [30, 40], then the output is:

distance: 25.741472914575986

The program is using degrees as unit, and planar as method.

The expected results are 2.4 and 24, but it's not.


Question

  • So, does that means those points are on a curved surface, instead of a flat plane?
  • Is it possible to define points & lines & polygons in flat plane, instead of the curved surface?
  • If not, then it there another similar tool to perform this task?
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Eric
  • 22,183
  • 20
  • 145
  • 196
  • But I don't see 'planar' option here: http://turfjs.org/docs#pointToLineDistance Why do you use geo-library for plain geometry? – MBo Jun 06 '18 at 09:54
  • @MBo You can find the options here: https://github.com/Turfjs/turf/tree/master/packages/turf-point-to-line-distance – Eric Jun 06 '18 at 10:34
  • @MBo I am looking for a proper library, just investigating turfjs, do you know any library that could be a better fit for this requirement? – Eric Jun 06 '18 at 10:35

2 Answers2

1

If you look at turf.js source code for point to line distance, you'll see that it calculates planar distances along a rhumb line, and that's not what you would expect in planar geometry.

To achieve what you want, you could implement the equation yourself, something like

function pointToLineDistance(line, p0) {
    var p1 = line[0],
        p2 = line[1];

    var x0 = p0[0], y0 = p0[1],
        x1 = p1[0], y1 = p1[1],
        x2 = p2[0], y2 = p2[1]


    return Math.abs(
        (y2 - y1) * x0
        - (x2 - x1) * y0
        + x2 * y1
        - y2 * x1
    ) 
    /
    Math.sqrt(
        (y2 - y1) * (y2 - y1)
        +
        (x2 - x1) * (x2 - x1)
    );
}

console.log(
    pointToLineDistance([[0, 0], [3, 4]], [3, 0]),
    pointToLineDistance([[0, 0], [30, 40]], [30, 0]),
);

Or if you prefer a library, something like flatten.js could help you :

let Flatten = require('flatten-js');

let {point, line} = Flatten;

let l = line(point(0, 0), point(3, 4));
let p = point(3, 0)
let d = p.distanceTo(l);

console.log(d[0]);
nikoshr
  • 32,926
  • 33
  • 91
  • 105
  • For this single operation this answer is great, but there are many other operations needed (e.g intersection of 2 polygons, area of a polygon), so I am still looking for a easy to use library to perform these operations, not limited to Javascript. – Eric Jun 06 '18 at 12:12
  • I am investigating flatten-js and some other tools, you might also be interested in Stefano's answer. – Eric Jun 09 '18 at 04:39
1

Turf.js is meant to be used on Mercator (web, 2D) maps but for calculations it's based on WSG84 (3D) standards, i.e. considers the Earth a spheroid. Some times though, particularly on wide areas, representations and operations on spherical features on a 2D map return unintuitive or unexpected results; in these cases we adopted Rhumb or even euclidean operations (hence the planar option for pointToLineDistance for example), which sometimes could result in reduced accuracy.

So, to answer to your first question, Turf considers your points on a curved surface and to answer the your second it is not possible to instruct Turf to work on a flat surface.

As for alternative libraries you might want to consider using more than one; in addition to the already suggested flatten.js you could take a look at jsts for operations like union and intersect.

If you are not limited to Javascript, you might want to take a look to Python Shapely, which in my understanding as a very powerful and reliable tool.

Both the above libraries are used in few Turf packages or used as reference for implementation and/or result. A note on jsts, it has shown some issues in Turf, but you might be fine with it depending on the complexity of your cases.

Stefano
  • 555
  • 1
  • 5
  • 18