Turfjs / turf

A modular geospatial engine written in JavaScript and TypeScript
https://turfjs.org/
MIT License
9.01k stars 927 forks source link

lineSplit does not split horizontal lines that have more than 7 decimals in latitude #2040

Open ChristopherChudzicki opened 3 years ago

ChristopherChudzicki commented 3 years ago

Turf Version: 6.3.0

lineSplit does not split horizontal lines whose latitudes have more than 7 decimal places.

For example, the test below fails

test("turf-line-split -- splitting horizontal lines with more than 7 lat decimals", (t) => {
  const x1 = 0
  const x2 = 10;
  const y = 0.12345678;

  const xMid = (x1 + x2)/2;

  const line = lineString([[x1, y], [x2, y]]);
  const splitter = point([xMid, y]);

  const { features } = lineSplit(line, splitter);

  // these fail; real result is an un-split line: lineString([ [ x1, y ], [ x2, y] ])
  t.isEqual(features.length, 2)
  t.deepEquals(features[0], lineString([[x1, y], [xMid, y]]));
  t.deepEquals(features[1], lineString([[xMid, y], [x2, y]]));

  t.end();
})
ChristopherChudzicki commented 3 years ago

I looked into the cause a bit. As best I can tell, what's happening is:

This seems like it could be an issue with very slightly sloped lines, too.

One idea for fixing : Just truncate the line segments that are loaded into rbush. One potential downside to this is that currently the LineString vertices returned by lineSplit exactly match the original geometry except at the split points. Truncating the segments into rbush might mean the new vertices are not exactly equal to the old vertices. I dunno how big a deal that is. My understanding is that GeoJSON does not specify a standard precision, but recommends 6 decimals. So maybe it's ok.