[geos-commits] [SCM] GEOS branch main updated. b18c7aa44b9c46dd04b60071962bd369b36c787e

git at osgeo.org git at osgeo.org
Wed May 17 16:43:41 PDT 2023


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, main has been updated
       via  b18c7aa44b9c46dd04b60071962bd369b36c787e (commit)
       via  0e6d68edaa2e66946570b2ae86a4a5bc92121f2d (commit)
       via  cb84b4e035ca86bf1fa1628a4d818a0f2a0114e9 (commit)
      from  fb79eb2bc785e21f68e36af2f1c89f93a19e902e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit b18c7aa44b9c46dd04b60071962bd369b36c787e
Author: Sandro Santilli <strk at kbt.io>
Date:   Wed May 17 16:18:22 2023 +0200

    Fix single-sided buffer of multigeoms (#912)
    
    References GH-665

diff --git a/src/operation/buffer/BufferBuilder.cpp b/src/operation/buffer/BufferBuilder.cpp
index 8ebe484ff..e7de6f69d 100644
--- a/src/operation/buffer/BufferBuilder.cpp
+++ b/src/operation/buffer/BufferBuilder.cpp
@@ -36,6 +36,7 @@
 #include <geos/operation/overlay/PolygonBuilder.h>
 #include <geos/operation/overlay/OverlayNodeFactory.h>
 #include <geos/operation/polygonize/Polygonizer.h>
+#include <geos/operation/union/UnaryUnionOp.h>
 #include <geos/operation/valid/RepeatedPointRemover.h>
 #include <geos/operation/linemerge/LineMerger.h>
 #include <geos/algorithm/LineIntersector.h>
@@ -368,6 +369,27 @@ std::unique_ptr<Geometry>
 BufferBuilder::buffer(const Geometry* g, double distance)
 // throw(GEOSException *)
 {
+    // Single-sided buffer only works on single geometries
+    // so we'll need to do it individually and then union
+    // the result
+    if ( bufParams.isSingleSided() && g->getNumGeometries() > 1 )
+    {
+        std::vector< std::unique_ptr<Geometry> > geoms_to_delete;
+        for ( size_t i=0, n=g->getNumGeometries(); i<n; ++i )
+        {
+            // BufferBuilder class cannot be re-used, so
+            // we create a new one for each subgeom
+            BufferBuilder subbuilder(bufParams);
+            const Geometry *subgeom = g->getGeometryN(i);
+            std::unique_ptr<Geometry> subbuf = subbuilder.buffer(subgeom, distance);
+            geoms_to_delete.push_back( std::move(subbuf) );
+        }
+        std::vector< Geometry* > geoms;
+        for ( size_t i=0, n=geoms_to_delete.size(); i<n; ++i )
+            geoms.push_back( geoms_to_delete[i].get() );
+        return operation::geounion::UnaryUnionOp::Union(geoms);
+    }
+
     const PrecisionModel* precisionModel = workingPrecisionModel;
     if(precisionModel == nullptr) {
         precisionModel = g->getPrecisionModel();
diff --git a/tests/unit/operation/buffer/BufferOpTest.cpp b/tests/unit/operation/buffer/BufferOpTest.cpp
index a1ff2e557..4d4c693d9 100644
--- a/tests/unit/operation/buffer/BufferOpTest.cpp
+++ b/tests/unit/operation/buffer/BufferOpTest.cpp
@@ -570,4 +570,26 @@ void object::test<21>
     ensure_equals(int(result->getArea()), 5055);
 }
 
+// Another test for single-sided buffer
+// See https://github.com/libgeos/geos/issues/665
+template<>
+template<>
+void object::test<22>
+()
+{
+    using geos::operation::buffer::BufferOp;
+    using geos::operation::buffer::BufferParameters;
+
+    std::string wkt("MULTILINESTRING((0 0,10 0),(20 0,30 0))");
+    GeomPtr geom(wktreader.read(wkt));
+
+    geos::operation::buffer::BufferParameters bp;
+    bp.setSingleSided(true);
+    geos::operation::buffer::BufferOp op(geom.get(), bp);
+
+    std::unique_ptr<Geometry> result = op.getResultGeometry(-10);
+    ensure_equals(result->getNumGeometries(), 2u);
+    ensure_equals(result->getArea(), 200);
+}
+
 } // namespace tut

commit 0e6d68edaa2e66946570b2ae86a4a5bc92121f2d
Author: Mike Taves <mwtoews at gmail.com>
Date:   Wed May 17 13:20:21 2023 +1200

    Improve util/geosop/README.md

diff --git a/util/geosop/README.md b/util/geosop/README.md
index 109bb20a3..34741d3bc 100644
--- a/util/geosop/README.md
+++ b/util/geosop/README.md
@@ -4,8 +4,7 @@
 It can be used to:
 
 * Run GEOS operations on one or many geometries
-* Output geometry resuls in various formats (WKT and WKB)
-* Convert between WKT and WKB
+* Output geometry results in various formats (WKT, WKB and GeoJSON)
 * Time the performance of operations
 * Check for memory leaks in operations
 * Check the semantics of GEOS operations
@@ -28,14 +27,17 @@ It can be used to:
 ```
   geosop [OPTION...] opName opArg
 
-  -a arg               source for A geometries (WKT, WKB, file, stdin, stdin.wkb)
-  -b arg               source for B geometries (WKT, WKB, file, stdin, stdin.wkb)
+  -a arg               source for A geometries (WKT, WKB, file, stdin,
+                       stdin.wkb)
+  -b arg               source for B geometries (WKT, WKB, file, stdin,
+                       stdin.wkb)
   -l, --limita arg     Limit number of A geometries read
   -o, --offseta arg    Skip reading first N geometries of A
-  -c, --collect        Collect input into single geometry
+  -c, --collect        Collect input into single geometry (automatic for AGG
+                       ops)
   -e, --explode        Explode results into component geometries
-  -f, --format arg     Output format (wkt, wkb or txt)
-  -p, --precision arg  Sets number of decimal places in output coordinates
+  -f, --format arg     Output format (wkt, wkb, txt or geojson)
+  -p, --precision arg  Set number of decimal places in output coordinates
   -q, --quiet          Disable result output
   -r, --repeat arg     Repeat operation N times
   -t, --time           Print execution time
@@ -82,9 +84,9 @@ It can be used to:
 
     `geosop -a geoms.wkt -f wkb unaryUnion`
 
-* Compute the buffer of a WKB literal and output as WKT
+* Compute the buffer of a WKB literal and output as GeoJSON
 
-    `geosop -a 000000000140240000000000004024000000000000 buffer 10`
+    `geosop -a 000000000140240000000000004024000000000000 -f geojson buffer 10`
 
 * Polygonize lines and output the individual result polygons as WKT
 

commit cb84b4e035ca86bf1fa1628a4d818a0f2a0114e9
Author: Mike Taves <mwtoews at gmail.com>
Date:   Wed May 17 13:05:06 2023 +1200

    geosop: add option to output GeoJSON (#911)

diff --git a/util/geosop/GeosOp.cpp b/util/geosop/GeosOp.cpp
index 2e41e3268..1f974c32d 100644
--- a/util/geosop/GeosOp.cpp
+++ b/util/geosop/GeosOp.cpp
@@ -18,6 +18,7 @@
 #include <geos/geom/Point.h>
 #include <geos/geom/GeometryFactory.h>
 #include <geos/operation/valid/MakeValid.h>
+#include <geos/io/GeoJSONWriter.h>
 #include <geos/io/WKTReader.h>
 #include <geos/io/WKTStreamReader.h>
 #include <geos/io/WKTWriter.h>
@@ -84,7 +85,7 @@ int main(int argc, char** argv) {
         ("o,offseta", "Skip reading first N geometries of A", cxxopts::value<int>( cmdArgs.offsetA ) )
         ("c,collect", "Collect input into single geometry (automatic for AGG ops)", cxxopts::value<bool>( cmdArgs.isCollect ))
         ("e,explode", "Explode results into component geometries", cxxopts::value<bool>( cmdArgs.isExplode))
-        ("f,format", "Output format (wkt, wkb or txt)", cxxopts::value<std::string>( ))
+        ("f,format", "Output format (wkt, wkb, txt or geojson)", cxxopts::value<std::string>( ))
         ("p,precision", "Set number of decimal places in output coordinates", cxxopts::value<int>( cmdArgs.precision ) )
         ("q,quiet", "Disable result output", cxxopts::value<bool>( cmdArgs.isQuiet ) )
         ("r,repeat", "Repeat operation N times", cxxopts::value<int>( cmdArgs.repeatNum ) )
@@ -127,12 +128,18 @@ int main(int argc, char** argv) {
 
     if (result.count("format")) {
         auto fmt = result["format"].as<std::string>();
+        // Use lowercase matching
+        std::transform(fmt.begin(), fmt.end(), fmt.begin(),
+            [](unsigned char c){ return std::tolower(c); });
         if (fmt == "txt" || fmt == "wkt" ) {
             cmdArgs.format = GeosOpArgs::fmtText;
         }
         else if (fmt == "wkb") {
             cmdArgs.format = GeosOpArgs::fmtWKB;
         }
+        else if (fmt == "geojson" || fmt == "json") {
+            cmdArgs.format = GeosOpArgs::fmtGeoJSON;
+        }
         else {
             std::cerr << "Invalid format value: " << fmt << std::endl;
             exit(1);
@@ -542,6 +549,12 @@ void GeosOp::outputGeometry(const Geometry * geom) {
         writer.writeHEX(*geom, std::cout);
         std::cout << std::endl;
     }
+    else if (args.format == GeosOpArgs::fmtGeoJSON ) {
+        // output as GeoJSON
+        // TODO: enable args.precision to output
+        geos::io::GeoJSONWriter geojsonwriter;
+        std::cout << geojsonwriter.write(geom) << std::endl;
+    }
     else {
         // output as text/WKT
         WKTWriter writer;
diff --git a/util/geosop/GeosOp.h b/util/geosop/GeosOp.h
index b5ded9f18..3fe373700 100644
--- a/util/geosop/GeosOp.h
+++ b/util/geosop/GeosOp.h
@@ -31,7 +31,10 @@ class GeosOpArgs {
 
 public:
     enum {
-        fmtNone, fmtText, fmtWKB
+        fmtNone,
+        fmtText,
+        fmtWKB,
+        fmtGeoJSON,
     } format = fmtText;
 
     bool isShowTime = false;

-----------------------------------------------------------------------

Summary of changes:
 src/operation/buffer/BufferBuilder.cpp       | 22 ++++++++++++++++++++++
 tests/unit/operation/buffer/BufferOpTest.cpp | 22 ++++++++++++++++++++++
 util/geosop/GeosOp.cpp                       | 15 ++++++++++++++-
 util/geosop/GeosOp.h                         |  5 ++++-
 util/geosop/README.md                        | 20 +++++++++++---------
 5 files changed, 73 insertions(+), 11 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list