[geos-commits] [SCM] GEOS branch master updated. 841135eed82c7bfc1653a7ba77af5b8c82d9eaa7

git at osgeo.org git at osgeo.org
Fri Jan 22 15:24:13 PST 2021


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, master has been updated
       via  841135eed82c7bfc1653a7ba77af5b8c82d9eaa7 (commit)
      from  2c0c59b2cb89ace31b78f34ce09118701e2ebaad (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 841135eed82c7bfc1653a7ba77af5b8c82d9eaa7
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Fri Jan 22 15:23:28 2021 -0800

    Add filled-in simple examples with comments, and a few changes
    to the CAPI doco

diff --git a/capi/geos_c.h.in b/capi/geos_c.h.in
index e5e478b..d0c0e90 100644
--- a/capi/geos_c.h.in
+++ b/capi/geos_c.h.in
@@ -124,26 +124,48 @@ typedef void (*GEOSMessageHandler_r)(const char *message, void *userdata);
 * those clients don't have access to the original C++ headers, by design.
 */
 #ifndef GEOSGeometry
+
 /**
-Geometry generic type. Geometry can be a point, linestring, polygon,
-multipoint, multilinestring, multipolygon, or geometrycollection.
-Geometry type can be read with \ref GEOSGeomTypeId. Most functions
-in GEOS either have GEOSGeometry* as a parameter or a return type.
-\see GEOSGeom_createPoint
-\see GEOSGeom_createLineString
-\see GEOSGeom_createPolygon
-\see GEOSGeom_createCollection
-\see GEOSGeom_destroy
+* Geometry generic type. Geometry can be a point, linestring, polygon,
+* multipoint, multilinestring, multipolygon, or geometrycollection.
+* Geometry type can be read with \ref GEOSGeomTypeId. Most functions
+* in GEOS either have GEOSGeometry* as a parameter or a return type.
+* \see GEOSGeom_createPoint
+* \see GEOSGeom_createLineString
+* \see GEOSGeom_createPolygon
+* \see GEOSGeom_createCollection
+* \see GEOSGeom_destroy
 */
 typedef struct GEOSGeom_t GEOSGeometry;
-/** Prepared geometry type. \see GEOSPrepare */
+
+/**
+* Prepared geometry type.
+* \see GEOSPrepare()
+* \see GEOSPreparedGeom_destroy()
+*/
 typedef struct GEOSPrepGeom_t GEOSPreparedGeometry;
-/** Coordinate sequence. \see GEOSCoordSeq_create */
+
+/**
+* Coordinate sequence.
+* \see GEOSCoordSeq_create()
+* \see GEOSCoordSeq_destroy()
+*/
 typedef struct GEOSCoordSeq_t GEOSCoordSequence;
-/** STRTree index. \see GEOSSTRtree_create */
+
+/**
+* STRTree index.
+* \see GEOSSTRtree_create()
+* \see GEOSSTRtree_destroy()
+*/
 typedef struct GEOSSTRtree_t GEOSSTRtree;
-/** Paramter object for buffering. \see GEOSBufferParams_create */
+
+/**
+* Paramter object for buffering.
+* \see GEOSBufferParams_create()
+* \see GEOSBufferParams_destroy()
+*/
 typedef struct GEOSBufParams_t GEOSBufferParams;
+
 #endif
 
 /** \cond */
@@ -1440,14 +1462,35 @@ extern int GEOS_DLL GEOSOrientationIndex_r(
 /* ========== Reader and Writer APIs ========== */
 
 #ifndef GEOSWKTReader
-/** Reader object to read Well-Known Text (WKT) format and construct Geometry. */
+
+/**
+* Reader object to read Well-Known Text (WKT) format and construct Geometry.
+* \see GEOSWKTReader_create
+* \see GEOSWKTReader_create_r
+*/
 typedef struct GEOSWKTReader_t GEOSWKTReader;
-/** Writer object to turn Geometry into Well-Known Text (WKT). */
+
+/**
+* Writer object to turn Geometry into Well-Known Text (WKT).
+* \see GEOSWKTWriter_create
+* \see GEOSWKTWriter_create_r
+*/
 typedef struct GEOSWKTWriter_t GEOSWKTWriter;
-/** Reader object to read Well-Known Binary (WKB) format and construct Geometry. */
+
+/**
+* Reader object to read Well-Known Binary (WKB) format and construct Geometry.
+* \see GEOSWKBReader_create
+* \see GEOSWKBReader_create_r
+*/
 typedef struct GEOSWKBReader_t GEOSWKBReader;
-/** Writer object to turn Geometry into Well-Known Binary (WKB). */
+
+/**
+* Writer object to turn Geometry into Well-Known Binary (WKB).
+* \see GEOSWKBWriter_create
+* \see GEOSWKBWriter_create_r
+*/
 typedef struct GEOSWKBWriter_t GEOSWKBWriter;
+
 #endif
 
 /* ========== WKT Reader ========== */
diff --git a/examples/client/CMakeLists.txt b/examples/CMakeLists.txt
similarity index 56%
rename from examples/client/CMakeLists.txt
rename to examples/CMakeLists.txt
index b6106c6..c72e8c5 100644
--- a/examples/client/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -11,10 +11,16 @@
 cmake_minimum_required(VERSION 3.12)
 
 project(GEOS VERSION 1.0.0 LANGUAGES C CXX)
-find_package(GEOS 3.8 REQUIRED)
+find_package(GEOS 3.9 REQUIRED)
 
-add_executable(geos_client geos_client.cpp)
-target_link_libraries(geos_client PRIVATE GEOS::geos)
+add_executable(cpp_read cpp_read.cpp)
+target_link_libraries(cpp_read PRIVATE GEOS::geos)
 
-add_executable(geos_c_client geos_c_client.cpp)
-target_link_libraries(geos_c_client PRIVATE GEOS::geos_c)
+add_executable(capi_read capi_read.cpp)
+target_link_libraries(capi_read PRIVATE GEOS::geos_c)
+
+add_executable(capi_prepared capi_prepared.cpp)
+target_link_libraries(capi_prepared PRIVATE GEOS::geos_c)
+
+add_executable(capi_read_ts capi_read_ts.cpp)
+target_link_libraries(capi_read_ts PRIVATE GEOS::geos_c)
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..ddfbe48
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,15 @@
+# GEOS Example Programs
+
+* `capi_read` uses the standard C API to read two WKT geometries, calculate the intersection and print the result
+* `capi_read_ts` uses the "re-entrant" C API (threadsafe) to read two WKT geometries, calculate the intersection and print the result
+* `cpp_read` uses the C++ API to read two WKT geometries, calculate the intersection and print the result
+* `capi_prepared` uses the standard C API to read one WKT geometry, and fill it with a point grid, applying a high performance "prepared" geometry to speed up intersection testing
+
+## Build
+
+```
+mkdir _build
+cd _build
+cmake ..
+make
+```
diff --git a/examples/capi_prepared.cpp b/examples/capi_prepared.cpp
new file mode 100644
index 0000000..a1ffd12
--- /dev/null
+++ b/examples/capi_prepared.cpp
@@ -0,0 +1,137 @@
+/*
+* # GEOS C API example 2
+*
+* Reads one geometry and does a high-performance
+* prepared geometry operations to place random
+* points inside it.
+*/
+
+/* To print to stdout */
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* Only the CAPI header is required */
+#include <geos_c.h>
+
+/*
+* GEOS requires two message handlers to return
+* error and notice message to the calling program.
+*
+*   typedef void(* GEOSMessageHandler) (const char *fmt,...)
+*
+* Here we stub out an example that just prints the
+* messages to stdout.
+*/
+static void
+geos_message_handler(const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vprintf (fmt, ap);
+    va_end(ap);
+}
+
+
+int main()
+{
+    /* Send notice and error messages to our stdout handler */
+    initGEOS(geos_message_handler, geos_message_handler);
+
+    /* One concave polygon */
+    const char* wkt = "POLYGON ((189 115, 200 170, 130 170, 35 242, 156 215, 210 290, 274 256, 360 190, 267 215, 300 50, 200 60, 189 115))";
+
+    /* Read the WKT into geometry objects */
+    GEOSWKTReader* reader = GEOSWKTReader_create();
+    GEOSGeometry* geom = GEOSWKTReader_read(reader, wkt);
+    GEOSWKTReader_destroy(reader);
+
+    /* Check for parse success */
+    if (!geom) {
+        finishGEOS();
+        return 1;
+    }
+
+    /* Prepare the geometry */
+    const GEOSPreparedGeometry* prep_geom = GEOSPrepare(geom);
+
+    /* Read bounds of geometry */
+    double xmin, xmax, ymin, ymax;
+    GEOSGeom_getXMin(geom, &xmin);
+    GEOSGeom_getXMax(geom, &xmax);
+    GEOSGeom_getYMin(geom, &ymin);
+    GEOSGeom_getYMax(geom, &ymax);
+
+    /*
+    * Set up the point generator
+    * Generate all the points in the bounding box
+    * of the input polygon.
+    */
+    const int steps = 10;
+    double xstep = (xmax - xmin) / steps;
+    double ystep = (ymax - ymin) / steps;
+
+    /* Place to hold points to output */
+    GEOSGeometry** geoms = (GEOSGeometry**)malloc(steps*steps*sizeof(GEOSGeometry*));
+    size_t ngeoms = 0;
+
+    /*
+    * Test all the points in the polygon bounding box
+    * and only keep those that intersect the actual polygon
+    */
+    int i, j;
+    for (i = 0; i < steps; i++) {
+        for (j = 0; j < steps; j++) {
+            /* Make a point in the point grid */
+            GEOSGeometry* pt = GEOSGeom_createPointFromXY(
+                                    xmin + xstep*i,
+                                    ymin + ystep*j);
+            /* Check if the point and polygon intersect */
+            if (GEOSPreparedIntersects(prep_geom, pt)) {
+                /* Save the ones that do */
+                geoms[ngeoms++] = pt;
+            }
+            else {
+                /* Clean up the ones that don't */
+                GEOSGeom_destroy(pt);
+            }
+
+        }
+    }
+
+    /* Put the successful geoms inside a geometry for WKT output */
+    GEOSGeometry* result = GEOSGeom_createCollection(GEOS_MULTIPOINT, geoms, ngeoms);
+
+    /*
+    * The GEOSGeom_createCollection() only takes ownership of the
+    * geometries, not the array container, so we can free the container
+    * now
+    */
+    free(geoms);
+
+    /* Convert result to WKT */
+    GEOSWKTWriter* writer = GEOSWKTWriter_create();
+    /* Trim trailing zeros off output */
+    GEOSWKTWriter_setTrim(writer, 1);
+    GEOSWKTWriter_setRoundingPrecision(writer, 3);
+    char* wkt_result = GEOSWKTWriter_write(writer, result);
+    GEOSWKTWriter_destroy(writer);
+
+    /* Print answer */
+    printf("Input Polygon:\n");
+    printf("%s\n\n", wkt);
+    printf("Output Points:\n");
+    printf("%s\n\n", wkt_result);
+
+    /* Clean up everything we allocated */
+    GEOSPreparedGeom_destroy(prep_geom);
+    GEOSGeom_destroy(geom);
+    GEOSGeom_destroy(result);
+    GEOSFree(wkt_result);
+
+    /* Clean up the global context */
+    finishGEOS();
+
+    /* Done */
+    return 0;
+}
diff --git a/examples/capi_read.cpp b/examples/capi_read.cpp
new file mode 100644
index 0000000..691dd9b
--- /dev/null
+++ b/examples/capi_read.cpp
@@ -0,0 +1,75 @@
+/*
+* # GEOS C API example 1
+*
+* Reads two WKT representations and calculates the
+* intersection, prints it out, and cleans up.
+*/
+
+/* To print to stdout */
+#include <stdio.h>
+#include <stdarg.h>
+
+/* Only the CAPI header is required */
+#include <geos_c.h>
+
+/*
+* GEOS requires two message handlers to return
+* error and notice message to the calling program.
+*
+*   typedef void(* GEOSMessageHandler) (const char *fmt,...)
+*
+* Here we stub out an example that just prints the
+* messages to stdout.
+*/
+static void
+geos_message_handler(const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vprintf (fmt, ap);
+    va_end(ap);
+}
+
+
+int main()
+{
+    /* Send notice and error messages to our stdout handler */
+    initGEOS(geos_message_handler, geos_message_handler);
+
+    /* Two squares that overlap */
+    const char* wkt_a = "POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))";
+    const char* wkt_b = "POLYGON((5 5, 15 5, 15 15, 5 15, 5 5))";
+
+    /* Read the WKT into geometry objects */
+    GEOSWKTReader* reader = GEOSWKTReader_create();
+    GEOSGeometry* geom_a = GEOSWKTReader_read(reader, wkt_a);
+    GEOSGeometry* geom_b = GEOSWKTReader_read(reader, wkt_b);
+
+    /* Calculate the intersection */
+    GEOSGeometry* inter = GEOSIntersection(geom_a, geom_b);
+
+    /* Convert result to WKT */
+    GEOSWKTWriter* writer = GEOSWKTWriter_create();
+    /* Trim trailing zeros off output */
+    GEOSWKTWriter_setTrim(writer, 1);
+    char* wkt_inter = GEOSWKTWriter_write(writer, inter);
+
+    /* Print answer */
+    printf("Geometry A:         %s\n", wkt_a);
+    printf("Geometry B:         %s\n", wkt_b);
+    printf("Intersection(A, B): %s\n", wkt_inter);
+
+    /* Clean up everything we allocated */
+    GEOSWKTReader_destroy(reader);
+    GEOSWKTWriter_destroy(writer);
+    GEOSGeom_destroy(geom_a);
+    GEOSGeom_destroy(geom_b);
+    GEOSGeom_destroy(inter);
+    GEOSFree(wkt_inter);
+
+    /* Clean up the global context */
+    finishGEOS();
+
+    /* Done */
+    return 0;
+}
diff --git a/examples/capi_read_ts.cpp b/examples/capi_read_ts.cpp
new file mode 100644
index 0000000..b351159
--- /dev/null
+++ b/examples/capi_read_ts.cpp
@@ -0,0 +1,86 @@
+/*
+* # GEOS C API example 2
+*
+* Thread-safe version of example 1. Uses the
+* re-entrant API.
+* Reads two WKT representations and calculates the
+* intersection, prints it out, and cleans up.
+*/
+
+/* To print to stdout */
+#include <stdio.h>
+#include <stdarg.h>
+
+/* Only the CAPI header is required */
+#include <geos_c.h>
+
+/*
+* GEOS requires two message handlers to return
+* error and notice message to the calling program.
+*
+*   typedef void(* GEOSMessageHandler) (const char *fmt,...)
+*
+* Here we stub out an example that just prints the
+* messages to stdout.
+*/
+static void
+geos_message_handler(const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vprintf (fmt, ap);
+    va_end(ap);
+}
+
+
+int main()
+{
+    /*
+    * Each thread using the re-entrant API must get its
+    * own context handle
+    */
+    GEOSContextHandle_t context = GEOS_init_r();
+    /*
+    * The notice/error handlers route message back to the calling
+    * application. Here they just print to stdout.
+    */
+    GEOSContext_setNoticeHandler_r(context, geos_message_handler);
+    GEOSContext_setErrorHandler_r(context, geos_message_handler);
+
+    /* Two squares that overlap */
+    const char* wkt_a = "POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))";
+    const char* wkt_b = "POLYGON((5 5, 15 5, 15 15, 5 15, 5 5))";
+
+    /* Read the WKT into geometry objects */
+    GEOSWKTReader* reader = GEOSWKTReader_create_r(context);
+    GEOSGeometry* geom_a = GEOSWKTReader_read_r(context, reader, wkt_a);
+    GEOSGeometry* geom_b = GEOSWKTReader_read_r(context, reader, wkt_b);
+
+    /* Calculate the intersection */
+    GEOSGeometry* inter = GEOSIntersection_r(context, geom_a, geom_b);
+
+    /* Convert result to WKT */
+    GEOSWKTWriter* writer = GEOSWKTWriter_create_r(context);
+    /* Trim trailing zeros off output */
+    GEOSWKTWriter_setTrim(writer, 1);
+    char* wkt_inter = GEOSWKTWriter_write_r(context, writer, inter);
+
+    /* Print answer */
+    printf("Geometry A:         %s\n", wkt_a);
+    printf("Geometry B:         %s\n", wkt_b);
+    printf("Intersection(A, B): %s\n", wkt_inter);
+
+    /* Clean up everything we allocated */
+    GEOSWKTReader_destroy_r(context, reader);
+    GEOSWKTWriter_destroy_r(context, writer);
+    GEOSGeom_destroy_r(context, geom_a);
+    GEOSGeom_destroy_r(context, geom_b);
+    GEOSGeom_destroy_r(context, inter);
+    GEOSFree_r(context, wkt_inter);
+
+    /* Clean up the global context */
+    GEOS_finish_r(context);
+
+    /* Done */
+    return 0;
+}
diff --git a/examples/client/geos_c_client.cpp b/examples/client/geos_c_client.cpp
deleted file mode 100644
index 7b1be59..0000000
--- a/examples/client/geos_c_client.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <geos_c.h>
-
-int main()
-{
-    finishGEOS();
-}
\ No newline at end of file
diff --git a/examples/client/geos_client.cpp b/examples/client/geos_client.cpp
deleted file mode 100644
index d880ee0..0000000
--- a/examples/client/geos_client.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <geos/geom/GeometryFactory.h>
-using namespace geos::geom;
-
-int main()
-{
-    GeometryFactory::Ptr factory = GeometryFactory::create();
-    (void)factory;
-}
\ No newline at end of file
diff --git a/examples/cpp_read.cpp b/examples/cpp_read.cpp
new file mode 100644
index 0000000..ec31a4c
--- /dev/null
+++ b/examples/cpp_read.cpp
@@ -0,0 +1,60 @@
+/*
+* # GEOS C++ example 1
+*
+* Reads two WKT representations and calculates the
+* intersection, prints it out, and cleans up.
+*
+* In general, to avoid API changes, stick to operations
+* on Geometry. The more esoteric APIs are more likely
+* to change between versions.
+*/
+
+#include <iostream>
+
+/* For geometry operations */
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/Geometry.h>
+
+/* For WKT read/write */
+#include <geos/io/WKTReader.h>
+#include <geos/io/WKTWriter.h>
+
+/* Geometry/GeometryFactory */
+using namespace geos::geom;
+
+/* WKTReader/WKTWriter */
+using namespace geos::io;
+
+int main()
+{
+    /* New factory with default (float) precision model */
+    GeometryFactory::Ptr factory = GeometryFactory::create();
+
+    /*
+    * Reader requires a factory to bind the geometry to
+    * for shared resources like the PrecisionModel
+    */
+    WKTReader reader(*factory);
+
+    /* Input WKT strings */
+    std::string wkt_a("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))");
+    std::string wkt_b("POLYGON((5 5, 15 5, 15 15, 5 15, 5 5))");
+
+    /* Convert WKT to Geometry */
+    std::unique_ptr<Geometry> geom_a(reader.read(wkt_a));
+    std::unique_ptr<Geometry> geom_b(reader.read(wkt_b));
+
+    /* Calculate intersection */
+    std::unique_ptr<Geometry> inter = geom_a->intersection(geom_b.get());
+
+    /* Convert Geometry to WKT */
+    WKTWriter writer;
+    writer.setTrim(true);
+    std::string inter_wkt = writer.write(inter.get());
+
+    /* Print out results */
+    std::cout << "Geometry A:         " << wkt_a << std::endl;
+    std::cout << "Geometry B:         " << wkt_b << std::endl;
+    std::cout << "Intersection(A, B): " << inter_wkt << std::endl;
+
+}

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

Summary of changes:
 capi/geos_c.h.in                     |  77 +++++++++++++++-----
 examples/{client => }/CMakeLists.txt |  16 ++--
 examples/README.md                   |  15 ++++
 examples/capi_prepared.cpp           | 137 +++++++++++++++++++++++++++++++++++
 examples/capi_read.cpp               |  75 +++++++++++++++++++
 examples/capi_read_ts.cpp            |  86 ++++++++++++++++++++++
 examples/client/geos_c_client.cpp    |   6 --
 examples/client/geos_client.cpp      |   8 --
 examples/cpp_read.cpp                |  60 +++++++++++++++
 9 files changed, 444 insertions(+), 36 deletions(-)
 rename examples/{client => }/CMakeLists.txt (56%)
 create mode 100644 examples/README.md
 create mode 100644 examples/capi_prepared.cpp
 create mode 100644 examples/capi_read.cpp
 create mode 100644 examples/capi_read_ts.cpp
 delete mode 100644 examples/client/geos_c_client.cpp
 delete mode 100644 examples/client/geos_client.cpp
 create mode 100644 examples/cpp_read.cpp


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list