[postgis-tickets] r16639 - Improve lwgeom_geos clarity

Daniel Baston dbaston at gmail.com
Tue Jul 10 06:42:23 PDT 2018


Author: dbaston
Date: 2018-07-10 06:42:23 -0700 (Tue, 10 Jul 2018)
New Revision: 16639

Modified:
   trunk/NEWS
   trunk/liblwgeom/lwgeom_geos.c
Log:
Improve lwgeom_geos clarity

References #4027
Closes https://github.com/postgis/postgis/pull/264



Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2018-07-06 14:49:32 UTC (rev 16638)
+++ trunk/NEWS	2018-07-10 13:42:23 UTC (rev 16639)
@@ -101,6 +101,8 @@
   - #4060, #4094, PostgreSQL JIT support (Raúl Marín, Laurenz Albe)
   - #3960, ST_Centroid now uses lwgeom_centroid (Darafei Praliaskouski)
   - #4103, ST_PointOnSurface can handle invalid (Darafei Praliaskouski)
+  - #4027, Remove duplicated code in lwgeom_geos (Darafei Praliaskouski,
+           Daniel Baston)
 
 PostGIS 2.4.4
 2018/04/08

Modified: trunk/liblwgeom/lwgeom_geos.c
===================================================================
--- trunk/liblwgeom/lwgeom_geos.c	2018-07-06 14:49:32 UTC (rev 16638)
+++ trunk/liblwgeom/lwgeom_geos.c	2018-07-10 13:42:23 UTC (rev 16639)
@@ -19,6 +19,7 @@
  **********************************************************************
  *
  * Copyright 2011-2014 Sandro Santilli <strk at kbt.io>
+ * Copyright 2015-2018 Daniel Baston <dbaston at gmail.com>
  * Copyright 2017-2018 Darafei Praliaskouski <me at komzpa.net>
  *
  **********************************************************************/
@@ -28,11 +29,13 @@
 #include "liblwgeom_internal.h"
 #include "lwgeom_log.h"
 
+#include <stdarg.h>
 #include <stdlib.h>
 #include <time.h>
 
 LWTIN* lwtin_from_geos(const GEOSGeometry* geom, uint8_t want3d);
 
+#define AUTOFIX LW_TRUE
 #define LWGEOM_GEOS_ERRMSG_MAXSIZE 256
 char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE];
 
@@ -49,6 +52,45 @@
 	va_end(ap);
 }
 
+/* Destroy any non-null GEOSGeometry* pointers passed as arguments */
+#define GEOS_FREE(...) \
+do { \
+	geos_destroy((sizeof((void*[]){__VA_ARGS__})/sizeof(void*)), __VA_ARGS__); \
+} while (0)
+
+/* Pass the latest GEOS error to lwerror, then return NULL */
+#define GEOS_FAIL() \
+do { \
+	lwerror("%s: GEOS Error: %s", __func__, lwgeom_geos_errmsg); \
+	return NULL; \
+} while (0)
+
+#define GEOS_FREE_AND_FAIL(...) \
+do { \
+	GEOS_FREE(__VA_ARGS__); \
+	GEOS_FAIL(); \
+} while (0)
+
+/* Return the consistent SRID of all inputs, or call lwerror
+ * in case of SRID mismatch. */
+#define RESULT_SRID(...) \
+	(get_result_srid((sizeof((const void*[]){__VA_ARGS__})/sizeof(void*)), __func__,  __VA_ARGS__))
+
+/* Free any non-null GEOSGeometry* pointers passed as arguments *
+ * Called by GEOS_FREE, which populates 'count' */
+static void geos_destroy(size_t count, ...) {
+	va_list ap;
+	va_start(ap, count);
+	while (count--)
+	{
+		GEOSGeometry* g = va_arg(ap, GEOSGeometry*);
+		if (g)
+		{
+			GEOSGeom_destroy(g);
+		}
+	}
+}
+
 /*
 **  GEOS <==> PostGIS conversion functions
 **
@@ -495,80 +537,44 @@
 	return ver;
 }
 
-inline static int32_t
-get_result_srid(const LWGEOM* geom1, const LWGEOM* geom2, const char* funcname)
+/* Return the consistent SRID of all input.
+ * Intended to be called from RESULT_SRID macro */
+static int32_t
+get_result_srid(size_t count, const char* funcname, ...)
 {
-	if (!geom1)
+	va_list ap;
+	va_start(ap, funcname);
+	int32_t srid = SRID_INVALID;
+	size_t i;
+	for(i = 0; i < count; i++)
 	{
-		lwerror("%s: First argument is null pointer", funcname);
-		return SRID_INVALID;
+		LWGEOM* g = va_arg(ap, LWGEOM*);
+		if (!g)
+		{
+			lwerror("%s: Geometry is null", funcname);
+			return SRID_INVALID;
+		}
+		if (i == 0)
+		{
+			srid = g->srid;
+		}
+		else
+		{
+			if (g->srid != srid)
+			{
+				lwerror("%s: Operation on mixed SRID geometries (%d != %d)", funcname, srid, g->srid);
+				return SRID_INVALID;
+			}
+		}
 	}
-	if (geom2 && (geom1->srid != geom2->srid))
-	{
-		lwerror("%s: Operation on mixed SRID geometries (%d != %d)", funcname, geom1->srid, geom2->srid);
-		return SRID_INVALID;
-	}
-	if (geom1->srid > SRID_MAXIMUM)
-	{
-		lwerror("%s: SRID is more than maximum (%d > %d)", funcname, geom1->srid, SRID_USER_MAXIMUM);
-		return SRID_INVALID;
-	}
-	return geom1->srid;
+	return srid;
 }
 
-/* Input decoder and sanity checker for GEOS wrappers */
-inline static uint8_t
-input_lwgeom_to_geos(GEOSGeometry** g, const LWGEOM* geom, const char* funcname)
-{
-	*g = LWGEOM2GEOS(geom, 1);
-	if (!*g)
-	{
-		lwerror("%s: argument geometry could not be converted to GEOS: %s", funcname, lwgeom_geos_errmsg);
-		return LW_FALSE;
-	}
-	return LW_TRUE;
-}
-
-/* Output encoder and sanity checker for GEOS wrappers */
-inline static uint8_t
-output_geos_as_lwgeom(GEOSGeometry** g, LWGEOM** geom, const int32_t srid, const uint8_t is3d, const char* funcname)
-{
-	GEOSSetSRID(*g, srid);
-	*geom = GEOS2LWGEOM(*g, is3d);
-	if (!*geom)
-	{
-		lwerror("%s: result geometry could not be converted from GEOS: %s", funcname, lwgeom_geos_errmsg);
-		return LW_FALSE;
-	}
-	return LW_TRUE;
-}
-
-/* Clean up and return NULL */
-inline static LWGEOM*
-geos_clean_and_fail(GEOSGeometry* g1, GEOSGeometry* g2, GEOSGeometry* g3, const char* funcname)
-{
-	if (g1) GEOSGeom_destroy(g1);
-	if (g2) GEOSGeom_destroy(g2);
-	if (g3) GEOSGeom_destroy(g3);
-	lwerror("%s: GEOS Error: %s", funcname, lwgeom_geos_errmsg);
-	return NULL;
-}
-
-/* Clean up */
-inline static void
-geos_clean(GEOSGeometry* g1, GEOSGeometry* g2, GEOSGeometry* g3)
-{
-	if (g1) GEOSGeom_destroy(g1);
-	if (g2) GEOSGeom_destroy(g2);
-	if (g3) GEOSGeom_destroy(g3);
-	return;
-}
-
 LWGEOM*
 lwgeom_normalize(const LWGEOM* geom)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(geom->flags);
 	GEOSGeometry* g;
 
@@ -576,11 +582,13 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g, geom, __func__)) return NULL;
+	if (!(g = LWGEOM2GEOS(geom, AUTOFIX))) GEOS_FAIL();
 
-	if (GEOSNormalize(g) == -1) return geos_clean_and_fail(g, NULL, NULL, __func__);
+	if (GEOSNormalize(g) == -1) GEOS_FREE_AND_FAIL(g);
+	GEOSSetSRID(g, srid);
 
-	output_geos_as_lwgeom(&g, &result, srid, is3d, __func__);
+	if (!(result = GEOS2LWGEOM(g, is3d))) GEOS_FREE_AND_FAIL(g);
+
 	GEOSGeom_destroy(g);
 	return result;
 }
@@ -589,7 +597,7 @@
 lwgeom_intersection(const LWGEOM* geom1, const LWGEOM* geom2)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom1, geom2, __func__);
+	int32_t srid = RESULT_SRID(geom1, geom2);
 	uint8_t is3d = (FLAGS_GET_Z(geom1->flags) || FLAGS_GET_Z(geom2->flags));
 	GEOSGeometry* g1;
 	GEOSGeometry* g2;
@@ -605,8 +613,8 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom1, __func__)) return NULL;
-	if (!input_lwgeom_to_geos(&g2, geom2, __func__)) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!(g1 = LWGEOM2GEOS(geom1, AUTOFIX))) GEOS_FAIL();
+	if (!(g2 = LWGEOM2GEOS(geom2, AUTOFIX))) GEOS_FREE_AND_FAIL(g1);
 
 	g3 = GEOSIntersection(g1, g2);
 
@@ -624,16 +632,16 @@
 			g1v = LWGEOM_GEOS_makeValid(g1);
 			g2v = LWGEOM_GEOS_makeValid(g2);
 			g3 = GEOSIntersection(g1v, g2v);
-			geos_clean(g1v, g2v, NULL);
+			GEOS_FREE(g1v, g2v);
 		}
 	}
 
-	if (!g3) return geos_clean_and_fail(g1, g2, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, g2, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d))) GEOS_FREE_AND_FAIL(g1, g2, g3);
 
-	geos_clean(g1, g2, g3);
+	GEOS_FREE(g1, g2, g3);
 	return result;
 }
 
@@ -641,7 +649,7 @@
 lwgeom_linemerge(const LWGEOM* geom)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(geom->flags);
 	GEOSGeometry* g1;
 	GEOSGeometry* g3;
@@ -653,16 +661,17 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom, __func__)) return NULL;
+	if (!(g1 = LWGEOM2GEOS(geom, AUTOFIX))) GEOS_FAIL();
 
 	g3 = GEOSLineMerge(g1);
 
-	if (!g3) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, NULL, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g3);
 
-	geos_clean(g1, NULL, g3);
+	GEOS_FREE(g1, g3);
 
 	return result;
 }
@@ -671,7 +680,7 @@
 lwgeom_unaryunion(const LWGEOM* geom)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(geom->flags);
 	GEOSGeometry* g1;
 	GEOSGeometry* g3;
@@ -683,16 +692,17 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom, __func__)) return NULL;
+	if (!(g1 = LWGEOM2GEOS(geom, AUTOFIX))) GEOS_FAIL();
 
 	g3 = GEOSUnaryUnion(g1);
 
-	if (!g3) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, NULL, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g3);
 
-	geos_clean(g1, NULL, g3);
+	GEOS_FREE(g1, g3);
 
 	return result;
 }
@@ -701,7 +711,7 @@
 lwgeom_difference(const LWGEOM* geom1, const LWGEOM* geom2)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom1, geom2, __func__);
+	int32_t srid = RESULT_SRID(geom1, geom2);
 	uint8_t is3d = (FLAGS_GET_Z(geom1->flags) || FLAGS_GET_Z(geom2->flags));
 	GEOSGeometry *g1, *g2, *g3;
 
@@ -715,8 +725,8 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom1, __func__)) return NULL;
-	if (!input_lwgeom_to_geos(&g2, geom2, __func__)) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!(g1 = LWGEOM2GEOS(geom1, AUTOFIX))) GEOS_FAIL();
+	if (!(g2 = LWGEOM2GEOS(geom2, AUTOFIX))) GEOS_FREE_AND_FAIL(g1);
 
 	g3 = GEOSDifference(g1, g2);
 
@@ -734,16 +744,17 @@
 			g1v = LWGEOM_GEOS_makeValid(g1);
 			g2v = LWGEOM_GEOS_makeValid(g2);
 			g3 = GEOSDifference(g1v, g2v);
-			geos_clean(g1v, g2v, NULL);
+			GEOS_FREE(g1v, g2v);
 		}
 	}
 
-	if (!g3) return geos_clean_and_fail(g1, g2, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1, g2);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, g2, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g2, g3);
 
-	geos_clean(g1, g2, g3);
+	GEOS_FREE(g1, g2, g3);
 	return result;
 }
 
@@ -751,7 +762,7 @@
 lwgeom_symdifference(const LWGEOM* geom1, const LWGEOM* geom2)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom1, geom2, __func__);
+	int32_t srid = RESULT_SRID(geom1, geom2);
 	uint8_t is3d = (FLAGS_GET_Z(geom1->flags) || FLAGS_GET_Z(geom2->flags));
 	GEOSGeometry *g1, *g2, *g3;
 
@@ -765,8 +776,8 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom1, __func__)) return NULL;
-	if (!input_lwgeom_to_geos(&g2, geom2, __func__)) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!(g1 = LWGEOM2GEOS(geom1, AUTOFIX))) GEOS_FAIL();
+	if (!(g2 = LWGEOM2GEOS(geom2, AUTOFIX))) GEOS_FREE_AND_FAIL(g1);
 
 	g3 = GEOSSymDifference(g1, g2);
 
@@ -784,16 +795,17 @@
 			g1v = LWGEOM_GEOS_makeValid(g1);
 			g2v = LWGEOM_GEOS_makeValid(g2);
 			g3 = GEOSSymDifference(g1v, g2v);
-			geos_clean(g1v, g2v, NULL);
+			GEOS_FREE(g1v, g2v);
 		}
 	}
 
-	if (!g3) return geos_clean_and_fail(g1, g2, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1, g2);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, g2, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g2, g3);
 
-	geos_clean(g1, g2, g3);
+	GEOS_FREE(g1, g2, g3);
 	return result;
 }
 
@@ -801,7 +813,7 @@
 lwgeom_centroid(const LWGEOM* geom)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(geom->flags);
 	GEOSGeometry *g1, *g3;
 
@@ -815,16 +827,17 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom, __func__)) return NULL;
+	if (!(g1 = LWGEOM2GEOS(geom, AUTOFIX))) GEOS_FAIL();
 
 	g3 = GEOSGetCentroid(g1);
 
-	if (!g3) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, NULL, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1);
 
-	geos_clean(g1, NULL, g3);
+	GEOS_FREE(g1, g3);
 
 	return result;
 }
@@ -833,7 +846,7 @@
 lwgeom_pointonsurface(const LWGEOM *geom)
 {
 	LWGEOM *result;
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(geom->flags);
 	GEOSGeometry *g1, *g3;
 
@@ -847,7 +860,7 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom, __func__)) return NULL;
+	if (!(g1 = LWGEOM2GEOS(geom, AUTOFIX))) GEOS_FAIL();
 
 	g3 = GEOSPointOnSurface(g1);
 
@@ -864,16 +877,17 @@
 			    "Retrying GEOS operation with ST_MakeValid of your input.");
 			g1v = LWGEOM_GEOS_makeValid(g1);
 			g3 = GEOSPointOnSurface(g1v);
-			geos_clean(g1v, NULL, NULL);
+			GEOS_FREE(g1v);
 		}
 	}
 
-	if (!g3) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, NULL, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g3);
 
-	geos_clean(g1, NULL, g3);
+	GEOS_FREE(g1, g3);
 
 	return result;
 }
@@ -882,7 +896,7 @@
 lwgeom_union(const LWGEOM* geom1, const LWGEOM* geom2)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom1, geom2, __func__);
+	int32_t srid = RESULT_SRID(geom1, geom2);
 	uint8_t is3d = (FLAGS_GET_Z(geom1->flags) || FLAGS_GET_Z(geom2->flags));
 	GEOSGeometry *g1, *g2, *g3;
 
@@ -896,8 +910,8 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom1, __func__)) return NULL;
-	if (!input_lwgeom_to_geos(&g2, geom2, __func__)) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!(g1 = LWGEOM2GEOS(geom1, AUTOFIX))) GEOS_FAIL();
+	if (!(g2 = LWGEOM2GEOS(geom2, AUTOFIX))) GEOS_FREE_AND_FAIL(g1);
 
 	g3 = GEOSUnion(g1, g2);
 
@@ -915,16 +929,17 @@
 			g1v = LWGEOM_GEOS_makeValid(g1);
 			g2v = LWGEOM_GEOS_makeValid(g2);
 			g3 = GEOSUnion(g1v, g2v);
-			geos_clean(g1v, g2v, NULL);
+			GEOS_FREE(g1v, g2v);
 		}
 	}
 
-	if (!g3) return geos_clean_and_fail(g1, g2, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1, g2);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, g2, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g2, g3);
 
-	geos_clean(g1, g2, g3);
+	GEOS_FREE(g1, g2, g3);
 	return result;
 }
 
@@ -1217,7 +1232,7 @@
 lwgeom_buildarea(const LWGEOM* geom)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(geom->flags);
 	GEOSGeometry *g1, *g3;
 
@@ -1228,19 +1243,24 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom, __func__)) return NULL;
+	if (!(g1 = LWGEOM2GEOS(geom, AUTOFIX))) GEOS_FAIL();
 
 	g3 = LWGEOM_GEOS_buildArea(g1);
 
-	if (!g3) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1);
+	GEOSSetSRID(g3, srid);
 
 	/* If no geometries are in result collection, return NULL */
-	if (GEOSGetNumGeometries(g3) == 0) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (GEOSGetNumGeometries(g3) == 0)
+	{
+		GEOS_FREE(g1);
+		return NULL;
+	}
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, NULL, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g3);
 
-	geos_clean(g1, NULL, g3);
+	GEOS_FREE(g1, g3);
 
 	return result;
 }
@@ -1258,7 +1278,7 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g, geom, __func__)) return -1;
+	if (!(g = LWGEOM2GEOS(geom, AUTOFIX))) return -1;
 
 	simple = GEOSisSimple(g);
 	GEOSGeom_destroy(g);
@@ -1276,7 +1296,7 @@
 lwgeom_geos_noop(const LWGEOM* geom)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(geom->flags);
 	GEOSGeometry* g;
 
@@ -1284,14 +1304,15 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g, geom, __func__)) return NULL;
+	if (!(g = LWGEOM2GEOS(geom, AUTOFIX))) GEOS_FAIL();
 
-	if (!g) return geos_clean_and_fail(g, NULL, NULL, __func__);
+	if (!g) GEOS_FREE_AND_FAIL(g);
+	GEOSSetSRID(g, srid);
 
-	if (!output_geos_as_lwgeom(&g, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g, NULL, NULL, __func__);
+	if (!(result = GEOS2LWGEOM(g, is3d)))
+		GEOS_FREE_AND_FAIL(g);
 
-	geos_clean(g, NULL, NULL);
+	GEOS_FREE(g);
 
 	return result;
 }
@@ -1300,7 +1321,7 @@
 lwgeom_snap(const LWGEOM* geom1, const LWGEOM* geom2, double tolerance)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom1, geom2, __func__);
+	int32_t srid = RESULT_SRID(geom1, geom2);
 	uint8_t is3d = (FLAGS_GET_Z(geom1->flags) || FLAGS_GET_Z(geom2->flags));
 	GEOSGeometry *g1, *g2, *g3;
 
@@ -1308,17 +1329,18 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom1, __func__)) return NULL;
-	if (!input_lwgeom_to_geos(&g2, geom2, __func__)) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!(g1 = LWGEOM2GEOS(geom1, AUTOFIX))) GEOS_FAIL();
+	if (!(g2 = LWGEOM2GEOS(geom2, AUTOFIX))) GEOS_FREE_AND_FAIL(g1);
 
 	g3 = GEOSSnap(g1, g2, tolerance);
 
-	if (!g3) return geos_clean_and_fail(g1, g2, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1, g2);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, g2, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g2, g3);
 
-	geos_clean(g1, g2, g3);
+	GEOS_FREE(g1, g2, g3);
 	return result;
 }
 
@@ -1326,7 +1348,7 @@
 lwgeom_sharedpaths(const LWGEOM* geom1, const LWGEOM* geom2)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom1, geom2, __func__);
+	int32_t srid = RESULT_SRID(geom1, geom2);
 	uint8_t is3d = (FLAGS_GET_Z(geom1->flags) || FLAGS_GET_Z(geom2->flags));
 	GEOSGeometry *g1, *g2, *g3;
 
@@ -1334,17 +1356,18 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom1, __func__)) return NULL;
-	if (!input_lwgeom_to_geos(&g2, geom2, __func__)) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!(g1 = LWGEOM2GEOS(geom1, AUTOFIX))) GEOS_FAIL();
+	if (!(g2 = LWGEOM2GEOS(geom2, AUTOFIX))) GEOS_FREE_AND_FAIL(g1);
 
 	g3 = GEOSSharedPaths(g1, g2);
 
-	if (!g3) return geos_clean_and_fail(g1, g2, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1, g2);
+	GEOSSetSRID(g3, srid);
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, g2, g3, __func__);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g2, g3);
 
-	geos_clean(g1, g2, g3);
+	GEOS_FREE(g1, g2, g3);
 	return result;
 }
 
@@ -1353,7 +1376,7 @@
 {
 	LWGEOM* result;
 	LWGEOM* geom = lwline_as_lwgeom(lwline);
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(geom->flags);
 	GEOSGeometry *g1, *g3;
 
@@ -1361,20 +1384,22 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom, __func__)) return NULL;
+	if (!(g1 = LWGEOM2GEOS(geom, AUTOFIX))) GEOS_FAIL();
 
 	g3 = GEOSOffsetCurve(g1, size, quadsegs, joinStyle, mitreLimit);
 
 	if (!g3)
 	{
-		geos_clean(g1, NULL, NULL);
+		GEOS_FREE(g1);
 		return NULL;
 	}
 
-	if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, NULL, g3, __func__);
+	GEOSSetSRID(g3, srid);
 
-	geos_clean(g1, NULL, g3);
+	if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g3);
+
+	GEOS_FREE(g1, g3);
 	return result;
 }
 
@@ -1382,7 +1407,7 @@
 lwcollection_offsetcurve(const LWCOLLECTION *col, double size, int quadsegs, int joinStyle, double mitreLimit)
 {
 	const LWGEOM *geom = lwcollection_as_lwgeom(col);
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(col->flags);
 	LWCOLLECTION *result;
 	LWGEOM *tmp;
@@ -1429,7 +1454,7 @@
 LWGEOM*
 lwgeom_offsetcurve(const LWGEOM* geom, double size, int quadsegs, int joinStyle, double mitreLimit)
 {
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	LWGEOM *result = NULL;
 	LWGEOM *noded = NULL;
 	if (srid == SRID_INVALID) return NULL;
@@ -1780,7 +1805,7 @@
 lwgeom_delaunay_triangulation(const LWGEOM* geom, double tolerance, int32_t output)
 {
 	LWGEOM* result;
-	int32_t srid = get_result_srid(geom, NULL, __func__);
+	int32_t srid = RESULT_SRID(geom);
 	uint8_t is3d = FLAGS_GET_Z(geom->flags);
 	GEOSGeometry *g1, *g3;
 
@@ -1794,12 +1819,13 @@
 
 	initGEOS(lwnotice, lwgeom_geos_error);
 
-	if (!input_lwgeom_to_geos(&g1, geom, __func__)) return NULL;
+	if (!(g1 = LWGEOM2GEOS(geom, AUTOFIX))) GEOS_FAIL();
 
 	/* if output != 1 we want polys */
 	g3 = GEOSDelaunayTriangulation(g1, tolerance, output == 1);
 
-	if (!g3) return geos_clean_and_fail(g1, NULL, NULL, __func__);
+	if (!g3) GEOS_FREE_AND_FAIL(g1);
+	GEOSSetSRID(g3, srid);
 
 	if (output == 2)
 	{
@@ -1806,16 +1832,16 @@
 		result = (LWGEOM*)lwtin_from_geos(g3, is3d);
 		if (!result)
 		{
-			geos_clean(g1, NULL, g3);
+			GEOS_FREE(g1, g3);
 			lwerror("%s: cannot convert output geometry", __func__);
 			return NULL;
 		}
 		lwgeom_set_srid(result, srid);
 	}
-	else if (!output_geos_as_lwgeom(&g3, &result, srid, is3d, __func__))
-		return geos_clean_and_fail(g1, NULL, g3, __func__);
+	else if (!(result = GEOS2LWGEOM(g3, is3d)))
+		GEOS_FREE_AND_FAIL(g1, g3);
 
-	geos_clean(g1, NULL, g3);
+	GEOS_FREE(g1, g3);
 	return result;
 }
 



More information about the postgis-tickets mailing list