使用JSTS缓冲区来识别自相交多边形 [英] Using JSTS buffer to identify a self-intersecting polygon
问题描述
我期望能够通过JSTS未能构造它们或者通过添加缓冲区来测试自相交多边形,并且在缓冲后测试它们是否是MultiPolygons,但是对于某种形状,这不起作用,并且已经远远超过了我几何能力grok
//一个自相交shapevar poly = [[0,3],[1,5],[3, 1],[5,5],[6,3],[0,3]]; var geomFactory = new jsts.geom.GeometryFactory(); var jstsCoordinates = poly.map(function(pt){return new jsts。 geom.Coordinate(pt [1]);}); var linearRing = ()); //这将是多边形,但我认为应该是MultiPolygonvar bufferedPoly =(jstsPolygon.shell.points.coordinates.map(function(pr){return [pr.x,pr.y]}))var svg = d3.select( 'svg'); //添加第一个形状(显示为maginified)svg.selectAll('。original')。data([poly])。enter()。append(polygon).attr(points,函数(d){return d.map(function(d){return [d [0] * 10 + 10,d [1] * 10] .join(,);})。join(); ()).attr(fill,yellow); //将缓冲形状添加到其下方的vg.selectAll('。buffered')。data([bufferedPoly])。enter()。append(polygon).attr (points,function(d){return d.map(function(d){return [d [0] * 10 + 10,d [1] * 10 + 40] .join(,);}) .join();}).attr(fill,yellow);
svg {background-color:blue}
< script src =https://cdnjs.cloudfla re.com/ajax/libs/d3/3.4.11/d3.min.js\"></script><script src =https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages /1.0.2/jsts.min.js\"></script><svg width = 200 height = 200> < svg>
让孩子们上床让我的大脑有足够的休息......
这里有两种解决方案(我认为 - 这种几何形状的东西超出了我的舒适程度区域)
我发现分裂自相交多边形只能在Python中很好地返回一个多边形并且是否有办法将自交多边形转换为JTS中的多边形?,它实际上包含jts,jsts和shapely的解决方案都是密切相关的。第一个是,构造了一个线性环(在这种情况下,它不是简单的),我可以调用 isSimple()
来接收 false
第二,我一直在调用 buffer(1)
来误解我给出的建议。解决方法是调用 buffer(0)
。
//自相交shapevar poly = [[0,3],[1,5],[3,1],[5,5],[6,3],[ 0,3]]; var geomFactory = new jsts.geom.GeometryFactory(); var jstsCoordinates = poly.map(function(pt){return new jsts.geom.Coordinate(pt [0],pt [1]);}} ); var linearRing = geomFactory.createLinearRing(jstsCoordinates); //事实证明,你可以问它是否简单...即没有任何自我交集.console.log(linearRing.isSimple()); //所以这是假的//啊!要分裂它,并找出它是否自相交使用缓冲区(0)var jstsPolygon = geomFactory.createPolygon(linearRing).buffer(0); console.log(jstsPolygon.getGeometryType()); // this this is MultiPolygonvar svg = d3.select('svg'); if(jstsPolygon.getGeometryType()!=='MultiPolygon'){var bufferedPoly =(jstsPolygon.shell.points.coordinates.map(function(pr ){return [pr.x,pr.y];})); //将缓冲形状添加到其下方的vg.selectAll('。buffered')。data([bufferedPoly])。enter()。append(polygon ).attr(points,function(d){return d.map(function(d){return [d [0] * 10 + 10,d [1] * 10 + 40] .join(,) ;})。join();}).attr(fill,yellow);} //添加第一个形状(放大显示)svg.selectAll('。original').data([poly ])。enter().append(polygon).attr(points,function(d){return d.map(function(d){return [d [0] * 10 + 10,d [1] * 10] .join(,);})。join();}).attr(fill,yellow);
svg {background-color:blue}
< script src =https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js>< / script> ;< script src =https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/1.0.2/jsts.min.js>< / script>< svg width = 200 height = 200 GT; < svg>
I was expecting to be able to test for self intersecting polygons either by JSTS failing to construct them or by adding a buffer and testing whether they were MultiPolygons after buffering but for a certain shape this isn't working and that's well past my geometry ability to grok
//a self-intersecting shape
var poly = [[0, 3], [1, 5], [3, 1], [5, 5], [6, 3], [0, 3]];
var geomFactory = new jsts.geom.GeometryFactory();
var jstsCoordinates = poly.map(function(pt) {
return new jsts.geom.Coordinate(pt[0], pt[1]);
});
var linearRing = geomFactory.createLinearRing(jstsCoordinates);
var jstsPolygon = geomFactory.createPolygon(linearRing).buffer(1);
console.log(jstsPolygon.getGeometryType()); //this will be polygon but I thought should be MultiPolygon
var bufferedPoly = (jstsPolygon.shell.points.coordinates.map(function(pr) {
return [pr.x, pr.y]
}))
var svg = d3.select('svg');
//add the first shape (maginified for display)
svg.selectAll('.original').data([poly]).enter().append("polygon")
.attr("points",function(d) {
return d.map(function(d) {
return [d[0] * 10 + 10, d[1]*10].join(",");
}).join(" ");
})
.attr("fill", "yellow");
//add the buffered shape below it
svg.selectAll('.buffered').data([bufferedPoly]).enter().append("polygon")
.attr("points",function(d) {
return d.map(function(d) {
return [d[0] * 10 + 10, d[1]*10 + 40].join(",");
}).join(" ");
})
.attr("fill", "yellow");
svg {background-color:blue}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/1.0.2/jsts.min.js"></script>
<svg width=200 height=200>
<svg>
And just getting the kids to bed gave my brain enough of a rest...
There are two solutions here (I think - this geometry stuff is way outside my comfort zone)
I found Splitting self-intersecting polygon only returned one polygon in shapely in Python and Is there a way to convert a self intersecting polygon to a multipolygon in JTS? which actually contain the solution(s) since jts, jsts, and shapely are all closely related.
The first is that, having constructed a linear ring (that in this case is not simple), I can call isSimple()
to receive false
and the second that I had been calling buffer(1)
having misunderstood the advice I'd been given. The solution there being to call buffer(0)
.
//a self-intersecting shape
var poly = [
[0, 3],
[1, 5],
[3, 1],
[5, 5],
[6, 3],
[0, 3]
];
var geomFactory = new jsts.geom.GeometryFactory();
var jstsCoordinates = poly.map(function(pt) {
return new jsts.geom.Coordinate(pt[0], pt[1]);
});
var linearRing = geomFactory.createLinearRing(jstsCoordinates);
// turns out you can just ask if it is simple... i.e. does not have any self intersections.
console.log(linearRing.isSimple()); //so this is false
//Ah! To split it and find out if it is self intersecting use buffer(0)
var jstsPolygon = geomFactory.createPolygon(linearRing).buffer(0);
console.log(jstsPolygon.getGeometryType()); //this will now be MultiPolygon
var svg = d3.select('svg');
if (jstsPolygon.getGeometryType() !== 'MultiPolygon') {
var bufferedPoly = (jstsPolygon.shell.points.coordinates.map(function(pr) {
return [pr.x, pr.y];
}));
//add the buffered shape below it
svg.selectAll('.buffered').data([bufferedPoly]).enter().append("polygon")
.attr("points",function(d) {
return d.map(function(d) {
return [d[0] * 10 + 10, d[1]*10 + 40].join(",");
}).join(" ");
})
.attr("fill", "yellow");
}
//add the first shape (magnified for display)
svg.selectAll('.original')
.data([poly]).enter()
.append("polygon")
.attr("points",function(d) {
return d.map(function(d) {
return [
d[0] * 10 + 10,
d[1]*10].join(",");
}).join(" ");
})
.attr("fill", "yellow");
svg {
background-color: blue
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/1.0.2/jsts.min.js"></script>
<svg width=200 height=200>
<svg>
这篇关于使用JSTS缓冲区来识别自相交多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!