Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turf.js and PostGIS 'difference' function giving unexpected result

I have a polygon and a multipolygon. I want to create a geometry that is the area where the 2 geometries do not intersect. The result I get (red outline in the example) seems to have something like an extra point in the southmost and northmost part of the geometries and I don't understand why.

Can anyone help me figure out how I can get the result of having the red outline exactly around the purple area?

As a side note, I can get the result I'm looking for if I use PostGIS and do exactly ST_Difference(ST_SnapToGrid(poly1, 0.0000000001), ST_SnapToGrid(poly2, 0.0000000001)) from MYTABLE; however I don't comprehend why this works and it seems like it may be a brittle solution. Any decimal difference in 0.0000000001 doesn't work (0.000001 for example gives me the same result as the turfjs result).

var map = L.map("map").setView([19.42, -155], 9);

L.tileLayer('https://stamen-tiles.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

var poly1 = turf.polygon([[[-155.253325763,19.424193039],[-155.140558658,19.206650122],[-154.752533025,19.515649896],[-154.933670824,19.645287706],[-155.253325763,19.424193039]]]);
var poly2 = turf.multiPolygon([[[[-154.975609356,19.338005611],[-155.140558658,19.206650122],[-155.240053913,19.398589856],[-155.021104033,19.34867505],[-154.975609356,19.338005611]]],[[[-154.9542326,19.63106581],[-154.933670824,19.645287706],[-154.904729907,19.624575093],[-154.9542326,19.63106581]]]]);
var difference = turf.difference(poly1, poly2);

var myStyle = {weight: 0, fillOpacity: 0.3, fillColor: '#0000ff'};
L.geoJSON(poly1, {style: myStyle}).addTo(map);

myStyle.fillColor = '#00ff00';
L.geoJSON(poly2, {style: myStyle}).addTo(map);

myStyle = {weight: 1, opacity: 1, color: 'red', fillOpacity: 0.05, fillColor: '#ff0000'};
L.geoJSON(difference, {style: myStyle}).addTo(map);
#map {
  height: 200px;
}
<script src="https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<link href="https://unpkg.com/[email protected]/dist/leaflet.css" rel="stylesheet"/>
<div id="map"></div>
like image 803
A. Mort Avatar asked Oct 16 '25 02:10

A. Mort


1 Answers

Precision are a common problem when working with geometries. Have to use ST_SnapToGrid or other techniques to fix topological issues before use a geoprocess is no rare

So answering one of your questions, use ST_SnapToGrid is not a bad solution. For sure it will be better that the original data exactly match but that is not always possible.

Also, just a matter of taste, but usually I found more "understable" dump multi geometries to simple geometries and operate on that, that working directly with the multi. I find easy to debug problems when using simple versions.

To fix the precision issue in turf you can try to play with truncate

var options = {precision: 4};
var poly1 = turf.truncate(poly1, options);
var poly2 = turf.truncate(poly2, options);
like image 110
Francisco Puga Avatar answered Oct 18 '25 16:10

Francisco Puga



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!