[geos-devel] Patch to expose more methods in the CAPI
Alex Trofast
alex.trofast at ingres.com
Wed Jan 6 11:27:14 EST 2010
Greetings GEOS-devel
I've attached a patch that exposes these C++ class methods as CAPI
functions:
LineString::getPointN -> GEOSGetPointN
LineString::getStartPoint -> GEOSGetStartPoint
LineString::getEndPoint -> GEOSGetEndPoint
LineString::isClosed -> GEOSisClosed
LineString::getLength -> GEOSGetLength
LineString::getNumPoints -> GEOSGetNumPoints
Point::getX -> GEOSGetX
Point::getY -> GEOSGetY
Additionally I wrote a small test case for the new functions. Any
feedback is greatly appreciated.
Thank you,
Alex Trofast
Software Engineer
Ingres
-------------- next part --------------
Index: tests/unit/Makefile.am
===================================================================
--- tests/unit/Makefile.am (revision 2835)
+++ tests/unit/Makefile.am (working copy)
@@ -90,7 +90,8 @@
capi/GEOSSimplifyTest.cpp \
capi/GEOSPreparedGeometryTest.cpp \
capi/GEOSPolygonizer_getCutEdgesTest.cpp \
- capi/GEOSBufferTest.cpp
+ capi/GEOSBufferTest.cpp \
+ capi/GEOSLineString_PointTest.cpp
noinst_HEADERS = \
utility.h
Index: tests/unit/capi/GEOSLineString_PointTest.cpp
===================================================================
--- tests/unit/capi/GEOSLineString_PointTest.cpp (revision 0)
+++ tests/unit/capi/GEOSLineString_PointTest.cpp (revision 0)
@@ -0,0 +1,123 @@
+// 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 = GEOSGetPointN(geom1_, 0);
+ GEOSGetX(geom2, &x);
+ GEOSGetY(geom2, &y);
+
+ ensure_equals(x, 0);
+ ensure_equals(y, 0);
+
+ GEOSGeom_destroy(geom2);
+
+ geom2 = GEOSGetStartPoint(geom1_);
+ GEOSGetX(geom2, &x);
+ GEOSGetY(geom2, &y);
+
+ ensure_equals(x, 0);
+ ensure_equals(y, 0);
+
+ GEOSGeom_destroy(geom2);
+
+ geom2 = GEOSGetEndPoint(geom1_);
+ GEOSGetX(geom2, &x);
+ GEOSGetY(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_ );
+
+ GEOSGetLength(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 = GEOSGetNumPoints(geom1_);
+ ensure_equals(points, 3);
+ }
+} // namespace tut
+
Index: capi/geos_c.cpp
===================================================================
--- capi/geos_c.cpp (revision 2835)
+++ capi/geos_c.cpp (working copy)
@@ -452,8 +452,85 @@
return GEOSGetGeometryN_r( handle, g1, n );
}
+/*
+ * Call only on LINESTRING
+ * Returns NULL on exception
+ */
+Geometry *
+GEOSGetPointN(const Geometry *g1, int n)
+{
+ return GEOSGetPointN_r(handle, g1, n);
+}
/*
+ * Call only on LINESTRING
+ */
+Geometry *
+GEOSGetStartPoint(const Geometry *g1)
+{
+ return GEOSGetStartPoint_r(handle, g1);
+}
+
+/*
+ * Call only on LINESTRING
+ */
+Geometry *
+GEOSGetEndPoint(const Geometry *g1)
+{
+ return GEOSGetEndPoint_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
+GEOSGetLength(const Geometry *g1, double *length)
+{
+ return GEOSGetLength_r(handle, g1, length);
+}
+
+/*
+ * Call only on LINESTRING
+ * returns -1 on exception
+ */
+int
+GEOSGetNumPoints(const Geometry *g1)
+{
+ return GEOSGetNumPoints_r(handle, g1);
+}
+
+/*
+ * For POINT
+ * returns 0 on exception, otherwise 1
+ */
+int
+GEOSGetX(const Geometry *g1, double *x)
+{
+ return GEOSGetX_r(handle, g1, x);
+}
+
+/*
+ * For POINT
+ * returns 0 on exception, otherwise 1
+ */
+int
+GEOSGetY(const Geometry *g1, double *y)
+{
+ return GEOSGetY_r(handle, g1, y);
+}
+
+/*
* Call only on polygon
* Return a copy of the internal Geometry.
*/
Index: capi/geos_ts_c.cpp
===================================================================
--- capi/geos_ts_c.cpp (revision 2835)
+++ capi/geos_ts_c.cpp (working copy)
@@ -1991,8 +1991,343 @@
return NULL;
}
+/*
+ * Call only on LINESTRING
+ * Returns NULL on exception
+ */
+Geometry *
+GEOSGetPointN_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 *
+GEOSGetStartPoint_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 *
+GEOSGetEndPoint_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
+GEOSGetLength_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
+GEOSGetNumPoints_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
+GEOSGetX_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
+GEOSGetY_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.
*/
Index: capi/geos_c.h.in
===================================================================
--- capi/geos_c.h.in (revision 2835)
+++ capi/geos_c.h.in (working copy)
@@ -687,6 +687,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);
@@ -700,6 +701,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);
/************************************************************************
*
@@ -762,6 +765,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 GEOSGetNumPoints(const GEOSGeometry* g1);
+
+extern int GEOS_DLL GEOSGetNumPoints_r(GEOSContextHandle_t handle,
+ const GEOSGeometry* g1);
+
+/* Return -1 on exception, Geometry must be a Point. */
+extern int GEOS_DLL GEOSGetX(const GEOSGeometry *g1, double *x);
+extern int GEOS_DLL GEOSGetY(const GEOSGeometry *g1, double *y);
+
+extern int GEOS_DLL GEOSGetX_r(GEOSContextHandle_t handle, const GEOSGeometry *g1, double *x);
+extern int GEOS_DLL GEOSGetY_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:
@@ -809,6 +825,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 *GEOSGetPointN(const GEOSGeometry *g1, int n);
+extern GEOSGeometry GEOS_DLL *GEOSGetStartPoint(const GEOSGeometry *g1);
+extern GEOSGeometry GEOS_DLL *GEOSGetEndPoint(const GEOSGeometry *g1);
+
+extern GEOSGeometry GEOS_DLL *GEOSGetPointN_r(GEOSContextHandle_t handle, const GEOSGeometry *g1, int n);
+extern GEOSGeometry GEOS_DLL *GEOSGetStartPoint_r(GEOSContextHandle_t handle, const GEOSGeometry *g1);
+extern GEOSGeometry GEOS_DLL *GEOSGetEndPoint_r(GEOSContextHandle_t handle, const GEOSGeometry *g1);
+
/************************************************************************
*
* Misc functions
@@ -824,6 +852,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 GEOSGetLength(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,
@@ -839,6 +868,8 @@
const GEOSGeometry *g1,
const GEOSGeometry *g2,
double densifyFrac, double *dist);
+extern int GEOS_DLL GEOSGetLength_r(GEOSContextHandle_t handle,
+ const GEOSGeometry *g1, double *length);
/************************************************************************
More information about the geos-devel
mailing list