From: Sandro Santilli Date: Thu, 11 Aug 2011 07:52:10 +0000 (+0000) Subject: Export lwgeom_snap to liblwgeom [RT-SIGTA] X-Git-Tag: 2.0.0alpha1~1121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=64acaf3bf8587bfff0562544b09ed69acafe8915;p=postgis Export lwgeom_snap to liblwgeom [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@7726 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/liblwgeom.h b/liblwgeom/liblwgeom.h index 936ae0c11..efbbbcea3 100644 --- a/liblwgeom/liblwgeom.h +++ b/liblwgeom/liblwgeom.h @@ -2189,5 +2189,14 @@ LWGEOM* lwgeom_buildarea(const LWGEOM *geom) ; */ LWGEOM* lwgeom_make_valid(LWGEOM* geom); +/** + * Snap vertices and segments of a geometry to another using a given tolerance. + * + * @param geom1 the geometry to snap + * @param geom2 the geometry to snap to + * @param tolerance the distance under which vertices and segments are snapped + */ +LWGEOM* lwgeom_snap(const LWGEOM* geom1, const LWGEOM* geom2, double tolerance); + #endif /* !defined _LIBLWGEOM_H */ diff --git a/liblwgeom/lwgeom_geos.c b/liblwgeom/lwgeom_geos.c index 9a1bd6e87..72c6bfaec 100644 --- a/liblwgeom/lwgeom_geos.c +++ b/liblwgeom/lwgeom_geos.c @@ -966,3 +966,67 @@ lwgeom_geos_noop(const LWGEOM* geom_in) return geom_out; } + +LWGEOM* +lwgeom_snap(const LWGEOM* geom1, const LWGEOM* geom2, double tolerance) +{ +#if POSTGIS_GEOS_VERSION < 33 + lwerror("The GEOS version this lwgeom library " + "was compiled against (%d) doesn't support " + "'Snap' function (3.3.0+ required)", + POSTGIS_GEOS_VERSION); + return NULL; +#else /* POSTGIS_GEOS_VERSION >= 33 */ + + int srid, is3d; + GEOSGeometry *g1, *g2, *g3; + LWGEOM* out; + + srid = geom1->srid; + error_if_srid_mismatch(srid, (int)(geom2->srid)); + + is3d = (FLAGS_GET_Z(geom1->flags) || FLAGS_GET_Z(geom2->flags)) ; + + initGEOS(lwnotice, lwgeom_geos_error); + + g1 = (GEOSGeometry *)LWGEOM2GEOS(geom1); + if ( 0 == g1 ) /* exception thrown at construction */ + { + lwerror("First argument geometry could not be converted to GEOS: %s", lwgeom_geos_errmsg); + return NULL; + } + + g2 = (GEOSGeometry *)LWGEOM2GEOS(geom2); + if ( 0 == g2 ) /* exception thrown at construction */ + { + lwerror("Second argument geometry could not be converted to GEOS: %s", lwgeom_geos_errmsg); + GEOSGeom_destroy(g1); + return NULL; + } + + g3 = GEOSSnap(g1, g2, tolerance); + if (g3 == NULL) + { + GEOSGeom_destroy(g1); + GEOSGeom_destroy(g2); + lwerror("GEOSSnap: %s", lwgeom_geos_errmsg); + return NULL; + } + + GEOSGeom_destroy(g1); + GEOSGeom_destroy(g2); + + GEOSSetSRID(g3, srid); + out = GEOS2LWGEOM(g3, is3d); + if (out == NULL) + { + GEOSGeom_destroy(g3); + lwerror("GEOSSnap() threw an error (result LWGEOM geometry formation)!"); + return NULL; + } + GEOSGeom_destroy(g3); + + return out; + +#endif /* POSTGIS_GEOS_VERSION >= 33 */ +} diff --git a/postgis/Makefile.in b/postgis/Makefile.in index 640c854e0..97f68055f 100644 --- a/postgis/Makefile.in +++ b/postgis/Makefile.in @@ -40,7 +40,6 @@ PG_OBJS=lwgeom_pg.o \ lwgeom_geos_prepared.o \ lwgeom_geos_clean.o \ lwgeom_geos_sharedpaths.o \ - lwgeom_geos_snap.o \ lwgeom_geos_split.o \ lwgeom_geos_relatematch.o \ lwgeom_export.o \ diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 73ff8543a..b767b00cc 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -3556,3 +3556,46 @@ Datum LWGEOM_buildarea(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } +/* + * ST_Snap + * + * Snap a geometry to another with a given tolerance + */ +Datum ST_Snap(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(ST_Snap); +Datum ST_Snap(PG_FUNCTION_ARGS) +{ +#if POSTGIS_GEOS_VERSION < 33 + lwerror("The GEOS version this postgis binary " + "was compiled against (%d) doesn't support " + "'ST_Snap' function (3.3.0+ required)", + POSTGIS_GEOS_VERSION); + PG_RETURN_NULL(); +#else /* POSTGIS_GEOS_VERSION >= 33 */ + PG_LWGEOM *geom1, *geom2, *result; + LWGEOM *lwgeom1, *lwgeom2, *lwresult; + double tolerance; + + geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + tolerance = PG_GETARG_FLOAT8(2); + + lwgeom1 = pglwgeom_deserialize(geom1) ; + lwgeom2 = pglwgeom_deserialize(geom2) ; + + lwresult = lwgeom_snap(lwgeom1, lwgeom2, tolerance); + result = pglwgeom_serialize(lwresult); + + lwgeom_free(lwgeom1); + lwgeom_free(lwgeom2); + lwgeom_free(lwresult); + + PG_FREE_IF_COPY(geom1, 0); + PG_FREE_IF_COPY(geom2, 1); + + PG_RETURN_POINTER(result); + +#endif /* POSTGIS_GEOS_VERSION >= 33 */ + +} + diff --git a/postgis/lwgeom_geos_snap.c b/postgis/lwgeom_geos_snap.c deleted file mode 100644 index 07a728e8a..000000000 --- a/postgis/lwgeom_geos_snap.c +++ /dev/null @@ -1,103 +0,0 @@ -/********************************************************************** - * $Id: lwgeom_geos.c 5258 2010-02-17 21:02:49Z strk $ - * - * PostGIS - Spatial Types for PostgreSQL - * http://postgis.refractions.net - * - * Copyright (C) 2010 Sandro Santilli - * - * This is free software; you can redistribute and/or modify it under - * the terms of the GNU General Public Licence. See the COPYING file. - * - ********************************************************************** - * - * ST_Snap - * - * Snap a geometry to another with a given tolerance - * - **********************************************************************/ - -#include "lwgeom_geos.h" -#include "liblwgeom_internal.h" - -#include -#include - -/* #define POSTGIS_DEBUG_LEVEL 4 */ - -Datum ST_Snap(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1(ST_Snap); -Datum ST_Snap(PG_FUNCTION_ARGS) -{ -#if POSTGIS_GEOS_VERSION < 33 - lwerror("The GEOS version this postgis binary " - "was compiled against (%d) doesn't support " - "'ST_Snap' function (3.3.0+ required)", - POSTGIS_GEOS_VERSION); - PG_RETURN_NULL(); -#else /* POSTGIS_GEOS_VERSION >= 33 */ - PG_LWGEOM *geom1, *geom2, *out; - GEOSGeometry *g1, *g2, *g3; - int is3d; - int srid; - double tolerance; - - geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); - tolerance = PG_GETARG_FLOAT8(2); - - is3d = ( pglwgeom_has_z(geom1) ) || - ( pglwgeom_has_z(geom2) ); - - srid = pglwgeom_get_srid(geom1); - error_if_srid_mismatch(srid, pglwgeom_get_srid(geom2)); - - initGEOS(lwnotice, lwgeom_geos_error); - - g1 = (GEOSGeometry *)POSTGIS2GEOS(geom1); - if ( 0 == g1 ) /* exception thrown at construction */ - { - lwerror("First argument geometry could not be converted to GEOS: %s", lwgeom_geos_errmsg); - PG_FREE_IF_COPY(geom1, 0); - PG_RETURN_NULL(); - } - PG_FREE_IF_COPY(geom1, 0); - - g2 = (GEOSGeometry *)POSTGIS2GEOS(geom2); - if ( 0 == g2 ) /* exception thrown at construction */ - { - lwerror("Second argument geometry could not be converted to GEOS: %s", lwgeom_geos_errmsg); - GEOSGeom_destroy(g1); - PG_FREE_IF_COPY(geom2, 1); - PG_RETURN_NULL(); - } - PG_FREE_IF_COPY(geom2, 1); - - g3 = GEOSSnap(g1, g2, tolerance); - if (g3 == NULL) - { - GEOSGeom_destroy(g1); - GEOSGeom_destroy(g2); - lwerror("GEOSIntersection: %s", lwgeom_geos_errmsg); - PG_RETURN_NULL(); /* never get here */ - } - - GEOSGeom_destroy(g1); - GEOSGeom_destroy(g2); - - GEOSSetSRID(g3, srid); - out = GEOS2POSTGIS(g3, is3d); - if (out == NULL) - { - GEOSGeom_destroy(g3); - lwerror("GEOSSharedPaths() threw an error (result postgis geometry formation)!"); - PG_RETURN_NULL(); /* never get here */ - } - GEOSGeom_destroy(g3); - - PG_RETURN_POINTER(out); - -#endif /* POSTGIS_GEOS_VERSION >= 33 */ - -} -