Turf.js和Postgis'差异'功能给出意外结果

发布于 2025-02-07 02:47:45 字数 2411 浏览 2 评论 0原文

我有一个多边形和一个多角形。我想创建一个几何形状,该几何形状是2个几何形状不相交的区域。我得到的结果(示例中的红色轮廓)似乎在几何的最南端和最北部的部分中都有一个额外的点,我不明白为什么。

谁能帮助我弄清楚如何获得紫色区域周围的红色轮廓的结果?

附带说明,如果我使用postgis并准确地做st_difference(st_snaptogrid(poly1,0.0000000001),st_snaptogrid(poly2,0.0000000001)),我可以找到我要寻找的结果。 不理解为什么这起作用,似乎这可能是一个脆弱的解决方案。 0.0000000001中的任何小数差都不起作用(例如,0.000001给我与TurfJ的结果相同的结果)。

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>

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: '© <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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南街九尾狐 2025-02-14 02:47:45

当使用几何形状时,精度是一个常见的问题。必须使用ST_SNAPTGRID或其他技术来解决拓扑问题,然后再使用地理程序并不是很少见,

因此回答您的一个问题,使用ST_SNAPTGRID并不是一个不好的解决方案。可以肯定的是,原始数据可以完全匹配,但这并不总是可能。

另外,只是一个品味问题,但通常我发现更多的“可低估”的垃圾场多几何形状到简单的几何形状并在此上进行操作,该几何形状直接与多型合作。使用简单版本时,我发现易于调试问题。

要解决草皮中的精确问题,您可以尝试使用 truncate

var options = {precision: 4};
var poly1 = turf.truncate(poly1, options);
var poly2 = turf.truncate(poly2, options);

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文