[geos-commits] r2992 - in trunk: capi tests/unit tests/unit/capi

svn_geos at osgeo.org svn_geos at osgeo.org
Tue May 18 16:28:51 EDT 2010


Author: warmerdam
Date: 2010-05-18 16:28:50 -0400 (Tue, 18 May 2010)
New Revision: 2992

Added:
   trunk/tests/unit/capi/GEOSLineString_PointTest.cpp
Modified:
   trunk/capi/geos_c.cpp
   trunk/capi/geos_c.h.in
   trunk/capi/geos_ts_c.cpp
   trunk/tests/unit/Makefile.am
Log:
expose several new accessor functions on geometries (#345)

Modified: trunk/capi/geos_c.cpp
===================================================================
--- trunk/capi/geos_c.cpp	2010-05-18 20:07:01 UTC (rev 2991)
+++ trunk/capi/geos_c.cpp	2010-05-18 20:28:50 UTC (rev 2992)
@@ -467,8 +467,85 @@
     return GEOSGetGeometryN_r( handle, g1, n );
 }
 
+/*
+ * Call only on LINESTRING
+ * Returns NULL on exception
+ */
+Geometry *
+GEOSGeomGetPointN(const Geometry *g1, int n)
+{
+	return GEOSGeomGetPointN_r(handle, g1, n);
+}
 
 /*
+ * Call only on LINESTRING
+ */
+Geometry *
+GEOSGeomGetStartPoint(const Geometry *g1)
+{
+	return GEOSGeomGetStartPoint_r(handle, g1);
+}
+
+/*
+ * Call only on LINESTRING
+ */
+Geometry *
+GEOSGeomGetEndPoint(const Geometry *g1)
+{
+	return GEOSGeomGetEndPoint_r(handle, g1);
+}
+
+/*
+ * Call only on LINESTRING
+ * return 2 on exception, 1 on true, 0 on false
+ */
+char
+GEOSisClosed(const Geometry *g1)
+{
+	return GEOSisClosed_r(handle, g1);
+}
+
+/*
+ * Call only on LINESTRING
+ * returns 0 on exception, otherwise 1
+ */
+int
+GEOSGeomGetLength(const Geometry *g1, double *length)
+{
+	return GEOSGeomGetLength_r(handle, g1, length);
+}
+
+/*
+ * Call only on LINESTRING
+ * returns -1 on exception
+ */
+int
+GEOSGeomGetNumPoints(const Geometry *g1)
+{
+	return GEOSGeomGetNumPoints_r(handle, g1);
+}
+
+/*
+ * For POINT
+ * returns 0 on exception, otherwise 1
+ */
+int
+GEOSGeomGetX(const Geometry *g1, double *x)
+{
+	return GEOSGeomGetX_r(handle, g1, x);
+}
+
+/*
+ * For POINT
+ * returns 0 on exception, otherwise 1
+ */
+int
+GEOSGeomGetY(const Geometry *g1, double *y)
+{
+	return GEOSGeomGetY_r(handle, g1, y);
+}
+
+/*
  * Call only on polygon
  * Return a copy of the internal Geometry.
  */

Modified: trunk/capi/geos_c.h.in
===================================================================
--- trunk/capi/geos_c.h.in	2010-05-18 20:07:01 UTC (rev 2991)
+++ trunk/capi/geos_c.h.in	2010-05-18 20:28:50 UTC (rev 2992)
@@ -752,6 +752,7 @@
 extern char GEOS_DLL GEOSisSimple(const GEOSGeometry* g1);
 extern char GEOS_DLL GEOSisRing(const GEOSGeometry* g1);
 extern char GEOS_DLL GEOSHasZ(const GEOSGeometry* g1);
+extern char GEOS_DLL GEOSisClosed(const GEOSGeometry *g1);
 
 extern char GEOS_DLL GEOSisEmpty_r(GEOSContextHandle_t handle,
                                    const GEOSGeometry* g1);
@@ -770,6 +771,8 @@
                                   const GEOSGeometry* g1);
 extern char GEOS_DLL GEOSHasZ_r(GEOSContextHandle_t handle,
                                 const GEOSGeometry* g1);
+extern char GEOS_DLL GEOSisClosed_r(GEOSContextHandle_t handle,
+                                const GEOSGeometry *g1);
 
 /************************************************************************
  *
@@ -835,6 +838,19 @@
 extern int GEOS_DLL GEOSGetNumInteriorRings_r(GEOSContextHandle_t handle,
                                               const GEOSGeometry* g1);
 
+/* Return -1 on exception, Geometry must be a LineString. */
+extern int GEOS_DLL GEOSGeomGetNumPoints(const GEOSGeometry* g1);
+
+extern int GEOS_DLL GEOSGeomGetNumPoints_r(GEOSContextHandle_t handle,
+                                       const GEOSGeometry* g1);
+
+/* Return -1 on exception, Geometry must be a Point. */
+extern int GEOS_DLL GEOSGeomGetX(const GEOSGeometry *g1, double *x);
+extern int GEOS_DLL GEOSGeomGetY(const GEOSGeometry *g1, double *y);
+
+extern int GEOS_DLL GEOSGeomGetX_r(GEOSContextHandle_t handle, const GEOSGeometry *g1, double *x);
+extern int GEOS_DLL GEOSGeomGetY_r(GEOSContextHandle_t handle, const GEOSGeometry *g1, double *y);
+
 /*
  * Return NULL on exception, Geometry must be a Polygon.
  * Returned object is a pointer to internal storage:
@@ -882,6 +898,18 @@
 extern int GEOS_DLL GEOSGeom_getDimensions_r(GEOSContextHandle_t handle,
                                              const GEOSGeometry* g);
 
+/*
+ * Return NULL on exception.
+ * Must be LineString and must be freed by called.
+ */
+extern GEOSGeometry GEOS_DLL *GEOSGeomGetPointN(const GEOSGeometry *g1, int n);
+extern GEOSGeometry GEOS_DLL *GEOSGeomGetStartPoint(const GEOSGeometry *g1);
+extern GEOSGeometry GEOS_DLL *GEOSGeomGetEndPoint(const GEOSGeometry *g1);
+
+extern GEOSGeometry GEOS_DLL *GEOSGeomGetPointN_r(GEOSContextHandle_t handle, const GEOSGeometry *g1, int n);
+extern GEOSGeometry GEOS_DLL *GEOSGeomGetStartPoint_r(GEOSContextHandle_t handle, const GEOSGeometry *g1);
+extern GEOSGeometry GEOS_DLL *GEOSGeomGetEndPoint_r(GEOSContextHandle_t handle, const GEOSGeometry *g1);
+
 /************************************************************************
  *
  *  Misc functions 
@@ -897,6 +925,7 @@
         const GEOSGeometry *g2, double *dist);
 extern int GEOS_DLL GEOSHausdorffDistanceDensify(const GEOSGeometry *g1,
         const GEOSGeometry *g2, double densifyFrac, double *dist);
+extern int GEOS_DLL GEOSGeomGetLength(const GEOSGeometry *g1, double *length);       
 extern int GEOS_DLL GEOSArea_r(GEOSContextHandle_t handle,
                                const GEOSGeometry* g1, double *area);
 extern int GEOS_DLL GEOSLength_r(GEOSContextHandle_t handle,
@@ -912,6 +941,8 @@
                                    const GEOSGeometry *g1,
                                    const GEOSGeometry *g2,
                                    double densifyFrac, double *dist);
+extern int GEOS_DLL GEOSGeomGetLength_r(GEOSContextHandle_t handle,
+                                   const GEOSGeometry *g1, double *length);
 
 /************************************************************************
  *

Modified: trunk/capi/geos_ts_c.cpp
===================================================================
--- trunk/capi/geos_ts_c.cpp	2010-05-18 20:07:01 UTC (rev 2991)
+++ trunk/capi/geos_ts_c.cpp	2010-05-18 20:28:50 UTC (rev 2992)
@@ -2075,8 +2075,343 @@
     return NULL;
 }
 
+/*
+ * Call only on LINESTRING
+ * Returns NULL on exception
+ */
+Geometry *
+GEOSGeomGetPointN_r(GEOSContextHandle_t extHandle, const Geometry *g1, int n)
+{
+    if ( 0 == extHandle )
+    {
+        return NULL;
+    }
 
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return NULL;
+    }
+
+    try
+    {
+    	using geos::geom::LineString;
+    	const LineString *ls = dynamic_cast<const LineString *>(g1);
+    	if ( ! ls )
+    	{
+    		handle->ERROR_MESSAGE("Argument is not a LineString");
+    		return NULL;
+    	}
+    	return ls->getPointN(n);
+    }
+    catch (const std::exception &e)
+    {
+        handle->ERROR_MESSAGE("%s", e.what());
+    }
+    catch (...)
+    {
+        handle->ERROR_MESSAGE("Unknown exception thrown");
+    }
+
+    return NULL;
+}
+
 /*
+ * Call only on LINESTRING
+ */
+Geometry *
+GEOSGeomGetStartPoint_r(GEOSContextHandle_t extHandle, const Geometry *g1)
+{
+    if ( 0 == extHandle )
+    {
+        return NULL;
+    }
+
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return NULL;
+    }
+
+    try
+    {
+    	using geos::geom::LineString;
+    	const LineString *ls = dynamic_cast<const LineString *>(g1);
+    	if ( ! ls )
+    	{
+    		handle->ERROR_MESSAGE("Argument is not a LineString");
+    		return NULL;
+    	}
+    	return ls->getStartPoint();
+    }
+    catch (const std::exception &e)
+    {
+        handle->ERROR_MESSAGE("%s", e.what());
+    }
+    catch (...)
+    {
+        handle->ERROR_MESSAGE("Unknown exception thrown");
+    }
+
+    return NULL;
+}
+
+/*
+ * Call only on LINESTRING
+ */
+Geometry *
+GEOSGeomGetEndPoint_r(GEOSContextHandle_t extHandle, const Geometry *g1)
+{
+    if ( 0 == extHandle )
+    {
+        return NULL;
+    }
+
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return NULL;
+    }
+
+    try
+    {
+    	using geos::geom::LineString;
+    	const LineString *ls = dynamic_cast<const LineString *>(g1);
+    	if ( ! ls )
+    	{
+    		handle->ERROR_MESSAGE("Argument is not a LineString");
+    		return NULL;
+    	}
+    	return ls->getEndPoint();
+    }
+    catch (const std::exception &e)
+    {
+        handle->ERROR_MESSAGE("%s", e.what());
+    }
+    catch (...)
+    {
+        handle->ERROR_MESSAGE("Unknown exception thrown");
+    }
+
+    return NULL;
+}
+
+/*
+ * Call only on LINESTRING
+ * return 2 on exception, 1 on true, 0 on false
+ */
+char
+GEOSisClosed_r(GEOSContextHandle_t extHandle, const Geometry *g1)
+{
+    if ( 0 == extHandle )
+    {
+        return 2;
+    }
+
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return 2;
+    }
+
+    try
+    {
+    	using geos::geom::LineString;
+    	const LineString *ls = dynamic_cast<const LineString *>(g1);
+    	if ( ! ls )
+    	{
+    		handle->ERROR_MESSAGE("Argument is not a LineString");
+    		return 2;
+    	}
+    	return ls->isClosed();
+    }
+    catch (const std::exception &e)
+    {
+        handle->ERROR_MESSAGE("%s", e.what());
+    }
+    catch (...)
+    {
+        handle->ERROR_MESSAGE("Unknown exception thrown");
+    }
+
+    return 2;
+}
+
+/*
+ * Call only on LINESTRING
+ * return 0 on exception, otherwise 1
+ */
+int
+GEOSGeomGetLength_r(GEOSContextHandle_t extHandle, const Geometry *g1, double *length)
+{
+    if ( 0 == extHandle )
+    {
+        return 0;
+    }
+
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return 0;
+    }
+
+    try
+    {
+    	using geos::geom::LineString;
+    	const LineString *ls = dynamic_cast<const LineString *>(g1);
+    	if ( ! ls )
+    	{
+    		handle->ERROR_MESSAGE("Argument is not a LineString");
+    		return 0;
+    	}
+    	*length = ls->getLength();
+    	return 1;
+    }
+    catch (const std::exception &e)
+    {
+        handle->ERROR_MESSAGE("%s", e.what());
+    }
+    catch (...)
+    {
+        handle->ERROR_MESSAGE("Unknown exception thrown");
+    }
+
+    return 0;
+}
+
+/*
+ * Call only on LINESTRING
+ */
+int
+GEOSGeomGetNumPoints_r(GEOSContextHandle_t extHandle, const Geometry *g1)
+{
+    if ( 0 == extHandle )
+    {
+        return -1;
+    }
+
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return -1;
+    }
+
+    try
+    {
+    	using geos::geom::LineString;
+		const LineString *ls = dynamic_cast<const LineString *>(g1);
+		if ( ! ls )
+		{
+			handle->ERROR_MESSAGE("Argument is not a LineString");
+			return -1;
+		}
+		return ls->getNumPoints();
+    }
+    catch (const std::exception &e)
+    {
+        handle->ERROR_MESSAGE("%s", e.what());
+    }
+    catch (...)
+    {
+        handle->ERROR_MESSAGE("Unknown exception thrown");
+    }
+
+    return -1;
+}
+
+/*
+ * For POINT
+ * returns 0 on exception, otherwise 1
+ */
+int
+GEOSGeomGetX_r(GEOSContextHandle_t extHandle, const Geometry *g1, double *x)
+{
+    if ( 0 == extHandle )
+    {
+        return 0;
+    }
+
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return 0;
+    }
+
+    try
+    {
+    	using geos::geom::Point;
+    	const Point *po = dynamic_cast<const Point *>(g1);
+    	if ( ! po )
+    	{
+    		handle->ERROR_MESSAGE("Argument is not a Point");
+    		return 0;
+    	}
+    	*x = po->getX();
+    	return 1;
+    }
+    catch (const std::exception &e)
+    {
+        handle->ERROR_MESSAGE("%s", e.what());
+    }
+    catch (...)
+    {
+        handle->ERROR_MESSAGE("Unknown exception thrown");
+    }
+
+    return 0;
+}
+
+/*
+ * For POINT
+ * returns 0 on exception, otherwise 1
+ */
+int
+GEOSGeomGetY_r(GEOSContextHandle_t extHandle, const Geometry *g1, double *y)
+{
+    if ( 0 == extHandle )
+    {
+        return 0;
+    }
+
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return 0;
+    }
+
+    try
+    {
+    	using geos::geom::Point;
+    	const Point *po = dynamic_cast<const Point *>(g1);
+    	if ( ! po )
+    	{
+    		handle->ERROR_MESSAGE("Argument is not a Point");
+    		return 0;
+    	}
+    	*y = po->getY();
+    	return 1;
+    }
+    catch (const std::exception &e)
+    {
+        handle->ERROR_MESSAGE("%s", e.what());
+    }
+    catch (...)
+    {
+        handle->ERROR_MESSAGE("Unknown exception thrown");
+    }
+
+    return 0;
+}
+
+/*
  * Call only on polygon
  * Return a copy of the internal Geometry.
  */

Modified: trunk/tests/unit/Makefile.am
===================================================================
--- trunk/tests/unit/Makefile.am	2010-05-18 20:07:01 UTC (rev 2991)
+++ trunk/tests/unit/Makefile.am	2010-05-18 20:28:50 UTC (rev 2992)
@@ -94,7 +94,8 @@
 	capi/GEOSBufferTest.cpp \
 	capi/GEOSGeom_create.cpp \
 	capi/GEOSGeom_extractUniquePointsTest.cpp \
-	capi/GEOSOrientationIndex.cpp
+	capi/GEOSOrientationIndex.cpp \
+	capi/GEOSLineString_PointTest.cpp
 
 noinst_HEADERS = \
 	utility.h

Added: trunk/tests/unit/capi/GEOSLineString_PointTest.cpp
===================================================================
--- trunk/tests/unit/capi/GEOSLineString_PointTest.cpp	                        (rev 0)
+++ trunk/tests/unit/capi/GEOSLineString_PointTest.cpp	2010-05-18 20:28:50 UTC (rev 2992)
@@ -0,0 +1,122 @@
+// Test Suite for C-API LineString and Point functions
+
+#include <tut.hpp>
+// geos
+#include <geos_c.h>
+// std
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+
+namespace tut
+{
+    //
+    // Test Group
+    //
+
+    // Common data used in test cases.
+    struct test_capilinestringpoint_data
+    {
+        GEOSGeometry* geom1_;
+
+        static void notice(const char *fmt, ...)
+        {
+            std::fprintf( stdout, "NOTICE: ");
+
+            va_list ap;
+            va_start(ap, fmt);
+            std::vfprintf(stdout, fmt, ap);
+            va_end(ap);
+
+            std::fprintf(stdout, "\n");
+        }
+
+        test_capilinestringpoint_data()
+            : geom1_(0)
+        {
+            initGEOS(notice, notice);
+        }
+
+        ~test_capilinestringpoint_data()
+        {
+            GEOSGeom_destroy(geom1_);
+            geom1_ = 0;
+            finishGEOS();
+        }
+
+    };
+
+    typedef test_group<test_capilinestringpoint_data> group;
+    typedef group::object object;
+
+    group test_capilinestringpoint_group("capi::GEOSLineStringPoint");
+
+    //
+    // Test Cases
+    //
+
+    template<>
+    template<>
+    void object::test<1>()
+    {
+        geom1_ = GEOSGeomFromWKT("LINESTRING(0 0, 5 5, 10 10)");
+        GEOSGeometry *geom2;
+        double x, y;
+        ensure( 0 != geom1_ );
+
+        char const r1 = GEOSisClosed(geom1_);
+
+        ensure_equals(r1, 0);
+
+        geom2 = GEOSGeomGetPointN(geom1_, 0);
+        GEOSGeomGetX(geom2, &x);
+        GEOSGeomGetY(geom2, &y);
+
+        ensure_equals(x, 0);
+        ensure_equals(y, 0);
+
+        GEOSGeom_destroy(geom2);
+
+        geom2 = GEOSGeomGetStartPoint(geom1_);
+        GEOSGeomGetX(geom2, &x);
+        GEOSGeomGetY(geom2, &y);
+
+        ensure_equals(x, 0);
+        ensure_equals(y, 0);
+
+        GEOSGeom_destroy(geom2);
+
+        geom2 = GEOSGeomGetEndPoint(geom1_);
+        GEOSGeomGetX(geom2, &x);
+        GEOSGeomGetY(geom2, &y);
+
+        ensure_equals(x, 10);
+        ensure_equals(y, 10);
+
+        GEOSGeom_destroy(geom2);
+    }
+
+    template<>
+    template<>
+    void object::test<2>()
+    {
+        geom1_ = GEOSGeomFromWKT("LINESTRING(0 0, 5 5, 10 10)");
+        double length;
+        ensure( 0 != geom1_ );
+
+        GEOSGeomGetLength(geom1_, &length);
+        ensure(length != 0.0);
+    }
+
+    template<>
+    template<>
+    void object::test<3>()
+    {
+        geom1_ = GEOSGeomFromWKT("LINESTRING(0 0, 5 5, 10 10)");
+        int points;
+        ensure( 0 != geom1_ );
+
+        points = GEOSGeomGetNumPoints(geom1_);
+        ensure_equals(points, 3);
+    }
+} // namespace tut



More information about the geos-commits mailing list