gpt4 book ai didi

java - 有没有办法在 JTS 中将自相交多边形转换为多多边形?

转载 作者:IT老高 更新时间:2023-10-28 20:33:38 27 4
gpt4 key购买 nike

取无效多边形POLYGON((0 100, 100 100, 0 0, 100 0, 0 100)) - 一个带有未声明交点的鸡蛋计时器形状

Invalid polygon

许多指令说 JTS 可以使用 buffer 方法创建一个有效的版本:

Geometry input = new WKTReader().read("POLYGON((0 100, 100 100, 0 0, 100 0, 0 100))");
Geometry output = geom.buffer(0);
return output;

但是,这会产生输出 POLYGON ((0 100, 100 100, 50 50, 0 100)),其中部分多边形丢失:

Part of the polygon was lost

有没有办法让 JTS 验证多边形,以便生成输出 MULTIPOLYGON(((0 100, 100 100, 50 50, 0 100)), ((0 0, 100 0, 50 50, 0 0))) 对于给定的输入?

Desired output

这似乎应该内置到 API 中(也许这种行为是一个错误)- 我错过了什么吗?

谢谢。

最佳答案

JTS 似乎提供了我需要的行为,尽管我必须在自己的代码中做一些跑腿工作。我编写的 validate 函数将多边形/多多边形分解为一组非自相交的线串,然后使用 Polygonizer 类从结果中构建多边形。我已经在以下(有限的)输入集上对其进行了测试,它的行为似乎符合我的要求:

    POLYGON((0 100, 100 100, 0 0, 100 0, 0 100))
POLYGON((0 0, 0 100, 100 100, 100 0, 0 0))
MULTIPOLYGON(((0 0, 0 100, 100 100, 100 0, 0 0)),((50 50, 50 150, 150 150, 150 50, 50 50)))
POLYGON((0 0, 50 50, 100 0, 150 0, 200 50, 250 0, 0 0))

代码:

/**
* Get / create a valid version of the geometry given. If the geometry is a polygon or multi polygon, self intersections /
* inconsistencies are fixed. Otherwise the geometry is returned.
*
* @param geom
* @return a geometry
*/
public static Geometry validate(Geometry geom){
if(geom instanceof Polygon){
if(geom.isValid()){
geom.normalize(); // validate does not pick up rings in the wrong order - this will fix that
return geom; // If the polygon is valid just return it
}
Polygonizer polygonizer = new Polygonizer();
addPolygon((Polygon)geom, polygonizer);
return toPolygonGeometry(polygonizer.getPolygons(), geom.getFactory());
}else if(geom instanceof MultiPolygon){
if(geom.isValid()){
geom.normalize(); // validate does not pick up rings in the wrong order - this will fix that
return geom; // If the multipolygon is valid just return it
}
Polygonizer polygonizer = new Polygonizer();
for(int n = geom.getNumGeometries(); n-- > 0;){
addPolygon((Polygon)geom.getGeometryN(n), polygonizer);
}
return toPolygonGeometry(polygonizer.getPolygons(), geom.getFactory());
}else{
return geom; // In my case, I only care about polygon / multipolygon geometries
}
}

/**
* Add all line strings from the polygon given to the polygonizer given
*
* @param polygon polygon from which to extract line strings
* @param polygonizer polygonizer
*/
static void addPolygon(Polygon polygon, Polygonizer polygonizer){
addLineString(polygon.getExteriorRing(), polygonizer);
for(int n = polygon.getNumInteriorRing(); n-- > 0;){
addLineString(polygon.getInteriorRingN(n), polygonizer);
}
}

/**
* Add the linestring given to the polygonizer
*
* @param linestring line string
* @param polygonizer polygonizer
*/
static void addLineString(LineString lineString, Polygonizer polygonizer){

if(lineString instanceof LinearRing){ // LinearRings are treated differently to line strings : we need a LineString NOT a LinearRing
lineString = lineString.getFactory().createLineString(lineString.getCoordinateSequence());
}

// unioning the linestring with the point makes any self intersections explicit.
Point point = lineString.getFactory().createPoint(lineString.getCoordinateN(0));
Geometry toAdd = lineString.union(point);

//Add result to polygonizer
polygonizer.add(toAdd);
}

/**
* Get a geometry from a collection of polygons.
*
* @param polygons collection
* @param factory factory to generate MultiPolygon if required
* @return null if there were no polygons, the polygon if there was only one, or a MultiPolygon containing all polygons otherwise
*/
static Geometry toPolygonGeometry(Collection<Polygon> polygons, GeometryFactory factory){
switch(polygons.size()){
case 0:
return null; // No valid polygons!
case 1:
return polygons.iterator().next(); // single polygon - no need to wrap
default:
//polygons may still overlap! Need to sym difference them
Iterator<Polygon> iter = polygons.iterator();
Geometry ret = iter.next();
while(iter.hasNext()){
ret = ret.symDifference(iter.next());
}
return ret;
}
}

关于java - 有没有办法在 JTS 中将自相交多边形转换为多多边形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31473553/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com