概述
今天测试提了一个自相交空间查询的bug,用自相交的多边形查询资源点查不到结果。但是用postgis是可以查询出来的,看了一下postgis的处理方式,wkt字符串转为geometry之后会调用makeValid方法,如果是一个自相交的多边形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被转成multiPolygonbn。但是这个是数据库处理的,后来想想geotools有没有对应的处理方法,网上搜索到一个高人写的方法:http://stackoverflow.com/questions/31473553/is-there-a-way-to-convert-a-self-intersecting-polygon-to-a-multipolygon-in-jts,很好的解决了这个问题。
/** * 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: return factory.createMultiPolygon(polygons.toArray(new Polygon[polygons.size()])); // multiple polygons - wrap them } }
最后
以上就是文静酒窝为你收集整理的多边形自相交处理-selfIntersection的全部内容,希望文章能够帮你解决多边形自相交处理-selfIntersection所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复