]> granicus.if.org Git - postgis/commitdiff
Add lwgeom_delaunay_triangulation (#1215)
authorSandro Santilli <strk@keybit.net>
Wed, 27 Jun 2012 14:26:47 +0000 (14:26 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 27 Jun 2012 14:26:47 +0000 (14:26 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@9993 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/cunit/Makefile.in
liblwgeom/cunit/cu_tester.c
liblwgeom/cunit/cu_triangulate.c [new file with mode: 0644]
liblwgeom/liblwgeom.h.in
liblwgeom/lwgeom_geos.c

index 5bce1da038da9db504f25f17f641448495c62e36..fc3f399f9c081569bb9e7f5088c151d9e0208eae 100644 (file)
@@ -36,6 +36,7 @@ OBJS= \
        cu_libgeom.o \
        cu_split.o \
        cu_stringbuffer.o \
+       cu_triangulate.o \
        cu_homogenize.o \
        cu_out_wkt.o \
        cu_out_wkb.o \
index 9befc6c8856180eb95afa960a4c74b94e9cfa991..9e2998164652778e988a2896fad0ca4a0aa048e2 100644 (file)
@@ -34,6 +34,7 @@ extern CU_SuiteInfo split_suite;
 extern CU_SuiteInfo geodetic_suite;
 extern CU_SuiteInfo geos_suite;
 extern CU_SuiteInfo tree_suite;
+extern CU_SuiteInfo triangulate_suite;
 extern CU_SuiteInfo homogenize_suite;
 extern CU_SuiteInfo stringbuffer_suite;
 extern CU_SuiteInfo surface_suite;
@@ -70,6 +71,7 @@ int main(int argc, char *argv[])
                geodetic_suite,
                geos_suite,
                tree_suite,
+               triangulate_suite,
                stringbuffer_suite,
                surface_suite,
                homogenize_suite,
diff --git a/liblwgeom/cunit/cu_triangulate.c b/liblwgeom/cunit/cu_triangulate.c
new file mode 100644 (file)
index 0000000..2ee3372
--- /dev/null
@@ -0,0 +1,58 @@
+/**********************************************************************
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ *
+ * Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include "CUnit/Basic.h"
+#include "cu_tester.h"
+
+#include "liblwgeom.h"
+#include "liblwgeom_internal.h"
+
+static void test_lwgeom_delaunay_triangulation(void)
+{
+#if POSTGIS_GEOS_VERSION >= 34
+       LWGEOM *in, *tmp, *out;
+       char *wkt, *exp_wkt;
+
+       /* Because i don't trust that much prior tests...  ;) */
+       cu_error_msg_reset();
+
+       in = lwgeom_from_wkt("MULTIPOINT(10 0, 20 0, 5 5)", LW_PARSER_CHECK_NONE);
+
+       tmp = lwgeom_delaunay_triangulation(in, 0, 0);
+       lwgeom_free(in);
+       out = lwgeom_normalize(tmp); 
+       lwgeom_free(tmp);
+
+        wkt = lwgeom_to_ewkt(out);
+       lwgeom_free(out);
+
+       exp_wkt = "GEOMETRYCOLLECTION(POLYGON((5 5,20 0,10 0,5 5)))";
+        if ( strcmp(wkt, exp_wkt) )
+       {
+                fprintf(stderr, "\nExp:  %s\nObt:  %s\n", exp_wkt, wkt);
+       }
+       CU_ASSERT_STRING_EQUAL(wkt, exp_wkt);
+       lwfree(wkt);
+
+#endif /* POSTGIS_GEOS_VERSION >= 33 */
+}
+
+
+/*
+** Used by test harness to register the tests in this file.
+*/
+CU_TestInfo triangulate_tests[] =
+{
+       PG_TEST(test_lwgeom_delaunay_triangulation),
+       CU_TEST_INFO_NULL
+};
+CU_SuiteInfo triangulate_suite = {"triangulate",  NULL,  NULL, triangulate_tests};
index 325d40f04fd8b67fa9ac103b41908f8565c51f51..afb151a9253848fa035a4e5330c2a6f6e14c4977 100644 (file)
@@ -1915,5 +1915,16 @@ LWGEOM* lwgeom_split(const LWGEOM* lwgeom_in, const LWGEOM* blade_in);
  */
 LWGEOM* lwgeom_node(const LWGEOM* lwgeom_in);
 
+/**
+ * Take vertices of a geometry and build a delaunay
+ * triangulation on them.
+ *
+ * @param geom the input geometry
+ * @param tolerance an optional snapping tolerance for improved tolerance
+ * @param edgeOnly if non-zero the result will be a MULTILINESTRING,
+ *                 otherwise it'll be a COLLECTION of polygons.
+ */
+LWGEOM* lwgeom_delaunay_triangulation(const LWGEOM *geom, double tolerance, int edgeOnly);
+
 #endif /* !defined _LIBLWGEOM_H  */
 
index 74fe45e36681fe9a7589a84d5a9ffb2e4a6542bd..9e0c64e2e29a2eeb787d62c3cef79dddadbd5c53 100644 (file)
@@ -3,7 +3,7 @@
  * PostGIS - Spatial Types for PostgreSQL
  * http://postgis.refractions.net
  *
- * Copyright 2011 Sandro Santilli <strk@keybit.net>
+ * Copyright 2011-2012 Sandro Santilli <strk@keybit.net>
  *
  * This is free software; you can redistribute and/or modify it under
  * the terms of the GNU General Public Licence. See the COPYING file.
@@ -1299,3 +1299,49 @@ lwgeom_offsetcurve(const LWLINE *lwline, double size, int quadsegs, int joinStyl
        
 #endif /* POSTGIS_GEOS_VERSION < 32 */
 }
+
+LWGEOM*
+lwgeom_delaunay_triangulation(const LWGEOM *lwgeom_in, double tolerance, int edgeOnly)
+{
+#if POSTGIS_GEOS_VERSION < 34
+       lwerror("lwgeom_delaunay_triangulation: GEOS 3.4 or higher required");
+#else
+       GEOSGeometry *g1, *g3;
+       LWGEOM *lwgeom_result;
+
+       initGEOS(lwnotice, lwgeom_geos_error);
+
+       g1 = (GEOSGeometry *)LWGEOM2GEOS(lwgeom_in);
+       if ( ! g1 ) 
+       {
+               lwerror("lwgeom_delaunay_triangulation: Geometry could not be converted to GEOS: %s", lwgeom_geos_errmsg);
+               return NULL;
+       }
+
+       g3 = GEOSDelaunayTriangulation(g1, tolerance, edgeOnly);
+
+       /* Don't need input geometry anymore */
+       GEOSGeom_destroy(g1);
+
+       if (g3 == NULL)
+       {
+               lwerror("GEOSDelaunayTriangulation: %s", lwgeom_geos_errmsg);
+               return NULL;
+       }
+
+       /* LWDEBUGF(3, "result: %s", GEOSGeomToWKT(g3)); */
+
+       GEOSSetSRID(g3, lwgeom_get_srid(lwgeom_in));
+       lwgeom_result = GEOS2LWGEOM(g3, lwgeom_has_z(lwgeom_in));
+       GEOSGeom_destroy(g3);
+
+       if (lwgeom_result == NULL)
+       {
+               lwerror("lwgeom_delaunay_triangulation: GEOS2LWGEOM returned null");
+               return NULL;
+       }
+
+       return lwgeom_result;
+       
+#endif /* POSTGIS_GEOS_VERSION < 34 */
+}