question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Truncate and simplify generates Error: invalid polygon

See original GitHub issue

Latest turfjs version, location: /@turf/turf@6.5.0/turf.min.js

Code for reproducing:

const polygon =  {"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[12.56231543067888,55.71174271303183],[12.5622924993585,55.7117097183066],[12.56245909105533,55.71165693489258],[12.56248995363732,55.71168436284357],[12.56231543067888,55.71174271303183]]]}} 
turf.truncate(polygon)
turf.simplify(turf.truncate(polygon, { precision: 4 }))

Error generated:

turf.min.js:43 Uncaught Error: invalid polygon
    at en (turf.min.js:43)
    at turf.min.js:43
    at Array.forEach (<anonymous>)
    at tn (turf.min.js:43)
    at turf.min.js:88
    at turf.min.js:88
    at q (turf.min.js:1)
    at Object.t.simplify (turf.min.js:88)
    at <anonymous>:3:6

After debugging, it is the simplify function that removes duplicates, and thus ends up with a polygon that is not a polygon anymore.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6

github_iconTop GitHub Comments

1reaction
JamesLMilnercommented, Oct 19, 2021

Closing as there has been no follow up. Hope this helped!

1reaction
JamesLMilnercommented, Sep 26, 2021

Hey @kevinsimper, no problem at all. Appreciate you providing more details always helpful to gain context.

Here, I can totally appreciate that it is a surprise that truncate produces a Polygon which is invalid for the simplify function. However, here as the developer you are in control of the precision parameter passed to truncate. If we think about what truncate does, it cuts off the precision of the geometries coordinates to a given precision, in this case you have chosen 4. Here, a coordinate like:

[12.56231543067888, 55.71174271303183]

becomes:

[12.5623, 55.7117]

so the actual behaviour is exactly correct. This is to say, truncating the coordinates you have given as example to a precision of 4 produces exactly the right output (there is no bug in the behaviour). Think about it as per JavaScript’s toFixed number method, if you ran:

const float = 12.56231543067888;
const fixedPrecisionStr = float.toFixed(4);
// fixedPrecisionStr is 12.5623 here

It’s the same logic to truncate in this scenario.

As a developer you can control the precision to ensure that truncate does not produce an invalid Polygon input for the simplify function. For example, you can loop incrementing the precision until it produces a valid Polygon for your requirements.

In the interests of closing this, I’ve written a solution that should do the above:

let success = false;
let precision = 4;

while (!success) {
  let truncatedPolygon = truncate(polygon, { precision });
  try {
    let simplifiedPolygon = simplify(truncatedPolygon);
    success = true;
  } catch (error) {
    precision++;
    if (precision > 11) {
      throw Error("Could not make polygon valid");
    }
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

simplify fails to create a reasonable polygon in some cases
I tried simplifying directly with simplify-js and the issue doesn't occur with that. I'm not sure what kind of polygons triggers the issue....
Read more >
Fixing non-noded intersection problem using PostGIS
I'm using a PL/R function and PostGIS to generate voronoi polygons around a set ...
Read more >
Advanced geospatial analysis - Turf.js
Takes one or more features and calculates the centroid using the mean of all vertices. This lessens the effect of small islands and...
Read more >
Check Geometry (Data Management)—ArcGIS Pro
Geometry that is validated or repaired using the OGC option will be valid for the Esri option. To learn more about both methods,...
Read more >
Fix invalid polygon in Shapely - python - Stack Overflow
I found a solution that works for the specific case given: >>> pp2 = pp.buffer(0) >>> pp2.is_valid True >>> pp2.exterior.coords[:] [(0.0, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found