Hi all, I help maintain https://github.com/GEOSwift/GEOSwift
I'm testing out 3.9.0beta1 and have run into a couple things to share. If you want to try any of these out directly with GEOSwift, I recommend using the Swift Package Manager. You can clone https://github.com/GEOSwift/GEOSwift.git and check out branch geos-3.9.0-testing. Then run `$ swift test` to build and run the tests. I'm using Swift 5.3.1. One way to get Swift is to use the Docker image: https://hub.docker.com/_/swift 1) GeometryConvertible_GEOSTests.testMakeValidWhenItIsAPolygon() This test is checking that makeValid() (a wrapper around the CAPI's GEOSMakeValid_r) produces an expected result given some pre-defined geometry. Here's what happened: Input: Polygon( exterior: LinearRing( points: [ Point(x: 0, y: 0), Point(x: 2, y: 0), Point(x: 1, y: 1), Point(x: 0, y: 2), Point(x: 2, y: 2), Point(x: 1, y: 1), Point(x: 0, y: 0) ] ) ) Actual (wrapped in a multipolygon) Polygon( exterior: LinearRing( points: [ Point(x: 0, y: 2), Point(x: 2, y: 2), Point(x: 1, y: 1), Point(x: 0, y: 2) ] ) ) Polygon( exterior: LinearRing( points: [ Point(x: 2, y: 0), Point(x: 0, y: 0), Point(x: 1, y: 1), Point(x: 2, y: 0) ] ) ) Expected (wrapped in any order in a multipolygon) Polygon( exterior: LinearRing( points: [ Point(x: 1, y: 1), Point(x: 2, y: 0), Point(x: 0, y: 0), Point(x: 1, y: 1) ] ) ) Polygon( exterior: LinearRing( points: [ Point(x: 1, y: 1), Point(x: 0, y: 2), Point(x: 2, y: 2), Point(x: 1, y: 1) ] ) ) Since these are topologically equivalent, I've just updated the test to check for that instead of exact equality (see GEOSwift commit 6c4b191646623159528433fbd112c11ddce7c5ea on the aforementioned branch), but I thought I'd share here just in case this behavior is unexpected. 2) GeometryConvertible_GEOSTests.testBufferAllTypes() This test is intended to be a sort of stress-test to make sure that all the types of geometry on which GEOSwift allows you to invoke buffer(by:) (wrapper around the CAPI's GEOSBuffer_r) can actually be buffered. In geos 3.8.1, all the sample geometries were able to be buffered without any issues. Here's what we get for one of the test cases with 3.9.0beta1: Input: GeometryCollection( geometries: [ GeometryCollection( geometries: [ Point(x: 1.0, y: 2.0), MultiPoint( points: [ Point(x: 1.0, y: 2.0), Point(x: 3.0, y: 4.0) ] ), LineString( points: [ Point(x: 1.0, y: 2.0), Point(x: 3.0, y: 4.0) ] ), MultiLineString( lineStrings: [ LineString( points: [ Point(x: 1.0, y: 2.0), Point(x: 3.0, y: 4.0) ] ), LineString( points: [ Point(x: 5.0, y: 6.0), Point(x: 7.0, y: 8.0) ] ) ] ), Polygon( exterior: LinearRing( points: [ Point(x: 2.0, y: 2.0), Point(x: -2.0, y: 2.0), Point(x: -2.0, y: -2.0), Point(x: 2.0, y: -2.0), Point(x: 2.0, y: 2.0) ] ), holes: [ LinearRing( points: [ Point(x: 1.0, y: 1.0), Point(x: 1.0, y: -1.0), Point(x: -1.0, y: -1.0), Point(x: -1.0, y: 1.0), Point(x: 1.0, y: 1.0) ] ) ] ), MultiPolygon( polygons: [ Polygon( exterior: LinearRing( points: [ Point(x: 2.0, y: 2.0), Point(x: -2.0, y: 2.0), Point(x: -2.0, y: -2.0), Point(x: 2.0, y: -2.0), Point(x: 2.0, y: 2.0) ] ), holes: [ LinearRing( points: [ Point(x: 1.0, y: 1.0), Point(x: 1.0, y: -1.0), Point(x: -1.0, y: -1.0), Point(x: -1.0, y: 1.0), Point(x: 1.0, y: 1.0) ] ) ] ), Polygon( exterior: LinearRing( points: [ Point(x: 7.0, y: 2.0), Point(x: 3.0, y: 2.0), Point(x: 3.0, y: -2.0), Point(x: 7.0, y: -2.0), Point(x: 7.0, y: 2.0) ] ), holes: [] ) ] ) ] ) ] ) buffer(by: 0.5) errorMessage: "IllegalArgumentException: Overlay input is mixed-dimension" The exception is being thrown from EdgeNodingBuilder.cpp:195. In frame #2, i = 0 In frame #0, i = 0 This suggests to me that it's checking the dimension of the Point inside of the child GeometryCollection inside of the parent GeometryCollection. g->getDimension() is returning 0 (geos::geom::Dimension::DimensionType P) and expectedDim is 2. Here's a relevant stack trace: #0 geos::operation::overlayng::EdgeNodingBuilder::addGeometryCollection(geos::geom::GeometryCollection const*, int, int) at geos/src/operation/overlayng/EdgeNodingBuilder.cpp:195 #1 geos::operation::overlayng::EdgeNodingBuilder::add(geos::geom::Geometry const*, int) at geos/src/operation/overlayng/EdgeNodingBuilder.cpp:169 #2 geos::operation::overlayng::EdgeNodingBuilder::addGeometryCollection(geos::geom::GeometryCollection const*, int, int) at geos/src/operation/overlayng/EdgeNodingBuilder.cpp:197 #3 geos::operation::overlayng::EdgeNodingBuilder::add(geos::geom::Geometry const*, int) at geos/src/operation/overlayng/EdgeNodingBuilder.cpp:169 #4 geos::operation::overlayng::EdgeNodingBuilder::build(geos::geom::Geometry const*, geos::geom::Geometry const*) at geos/src/operation/overlayng/EdgeNodingBuilder.cpp:82 #5 geos::operation::overlayng::OverlayNG::computeEdgeOverlay() at geos/src/operation/overlayng/OverlayNG.cpp:222 #6 geos::operation::overlayng::OverlayNG::getResult() at geos/src/operation/overlayng/OverlayNG.cpp:179 #7 geos::operation::overlayng::PrecisionReducer::reducePrecision(geos::geom::Geometry const*, geos::geom::PrecisionModel const*, bool) at geos/src/operation/overlayng/PrecisionReducer.cpp:46 #8 geos::precision::GeometryPrecisionReducer::reduce(geos::geom::Geometry const&) at geos/src/precision/GeometryPrecisionReducer.cpp:60 #9 geos::precision::GeometryPrecisionReducer::reduce(geos::geom::Geometry const&, geos::geom::PrecisionModel const&) at geos/include/geos/precision/GeometryPrecisionReducer.h:102 #10 geos::operation::buffer::BufferOp::bufferFixedPrecision(geos::geom::PrecisionModel const&) at geos/src/operation/buffer/BufferOp.cpp:263 #11 geos::operation::buffer::BufferOp::bufferReducedPrecision(int) at geos/src/operation/buffer/BufferOp.cpp:218 #12 geos::operation::buffer::BufferOp::bufferReducedPrecision() at geos/src/operation/buffer/BufferOp.cpp:168 #13 geos::operation::buffer::BufferOp::computeGeometry() at geos/src/operation/buffer/BufferOp.cpp:150 #14 geos::operation::buffer::BufferOp::getResultGeometry(double) at geos/src/operation/buffer/BufferOp.cpp:122 #15 geos::operation::buffer::BufferOp::bufferOp(geos::geom::Geometry const*, double, int, int) at geos/src/operation/buffer/BufferOp.cpp:114 #16 geos::geom::Geometry::buffer(double, int) const at geos/src/geom/Geometry.cpp:509 #17 GEOSBuffer_r::$_41::operator()() const at geos/capi/geos_ts_c.cpp:1078 #18 _Z7executeIZ12GEOSBuffer_rE4$_41LDn0EEDTclfp0_EEP20GEOSContextHandle_HSOT_ at geos/capi/geos_ts_c.cpp:388 #19 ::GEOSBuffer_r(GEOSContextHandle_t, const geos::geom::Geometry *, double, int) at geos/capi/geos_ts_c.cpp:1077 #20 GeometryConvertible.buffer(by:) at GEOSwift/GEOSwift/GEOS/GeometryConvertible+GEOS.swift:348 #21 GeometryConvertible_GEOSTests.testBufferAllTypes() at GEOSwift/GEOSwiftTests/GEOS/GeometryConvertible+GEOSTests.swift:856 Let me know what other info I can provide. -- Andrew
_______________________________________________ geos-devel mailing list geos-devel@lists.osgeo.org https://lists.osgeo.org/mailman/listinfo/geos-devel