From: Sandro Santilli Date: Fri, 12 Aug 2011 09:11:26 +0000 (+0000) Subject: Export lwgeom_sharedpaths to liblwgeom, and fix exception message [RT-SIGTA] X-Git-Tag: 2.0.0alpha1~1116 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=09ea66209abb4e1948c3439c3fba77bdf90cbc69;p=postgis Export lwgeom_sharedpaths to liblwgeom, and fix exception message [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@7731 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/liblwgeom.h b/liblwgeom/liblwgeom.h index bd7a619d1..8214477a7 100644 --- a/liblwgeom/liblwgeom.h +++ b/liblwgeom/liblwgeom.h @@ -2211,5 +2211,18 @@ LWGEOM* lwgeom_snap(const LWGEOM* geom1, const LWGEOM* geom2, double tolerance); */ LWGEOM* lwgeom_split(const LWGEOM* lwgeom_in, const LWGEOM* blade_in); +/* + * Return the set of paths shared between two linear geometries, + * and their direction (same or opposite). + * + * Developed by Sandro Santilli for Faunalia + * (http://www.faunalia.it) with funding from Regione Toscana - Sistema + * Informativo per la Gestione del Territorio e dell' Ambiente + * [RT-SIGTA]". For the project: "Sviluppo strumenti software per il + * trattamento di dati geografici basati su QuantumGIS e Postgis (CIG + * 0494241492)" + */ +LWGEOM* lwgeom_sharedpaths(const LWGEOM* geom1, const LWGEOM* geom2); + #endif /* !defined _LIBLWGEOM_H */ diff --git a/liblwgeom/lwgeom_geos.c b/liblwgeom/lwgeom_geos.c index 72c6bfaec..81a1bf7ab 100644 --- a/liblwgeom/lwgeom_geos.c +++ b/liblwgeom/lwgeom_geos.c @@ -1030,3 +1030,67 @@ lwgeom_snap(const LWGEOM* geom1, const LWGEOM* geom2, double tolerance) #endif /* POSTGIS_GEOS_VERSION >= 33 */ } + +LWGEOM* +lwgeom_sharedpaths(const LWGEOM* geom1, const LWGEOM* geom2) +{ +#if POSTGIS_GEOS_VERSION < 33 + lwerror("The GEOS version this postgis binary " + "was compiled against (%d) doesn't support " + "'SharedPaths' function (3.3.0+ required)", + POSTGIS_GEOS_VERSION); + return NULL; +#else /* POSTGIS_GEOS_VERSION >= 33 */ + GEOSGeometry *g1, *g2, *g3; + LWGEOM *out; + int is3d, srid; + + 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 = GEOSSharedPaths(g1,g2); + + if (g3 == NULL) + { + GEOSGeom_destroy(g1); + GEOSGeom_destroy(g2); + lwerror("GEOSSharedPaths: %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("GEOS2LWGEOM threw an error"); + return NULL; + } + GEOSGeom_destroy(g3); + + return out; +#endif /* POSTGIS_GEOS_VERSION >= 33 */ +} diff --git a/postgis/Makefile.in b/postgis/Makefile.in index cf809f27e..1f0953cb3 100644 --- a/postgis/Makefile.in +++ b/postgis/Makefile.in @@ -39,7 +39,6 @@ PG_OBJS=lwgeom_pg.o \ lwgeom_geos.o \ lwgeom_geos_prepared.o \ lwgeom_geos_clean.o \ - lwgeom_geos_sharedpaths.o \ lwgeom_geos_relatematch.o \ lwgeom_export.o \ lwgeom_in_gml.o \ diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 5e7ccb1ae..106cfb289 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -3655,4 +3655,57 @@ Datum ST_Split(PG_FUNCTION_ARGS) } +/********************************************************************** + * + * ST_SharedPaths + * + * Return the set of paths shared between two linear geometries, + * and their direction (same or opposite). + * + * Developed by Sandro Santilli (strk@keybit.net) for Faunalia + * (http://www.faunalia.it) with funding from Regione Toscana - Sistema + * Informativo per la Gestione del Territorio e dell' Ambiente + * [RT-SIGTA]". For the project: "Sviluppo strumenti software per il + * trattamento di dati geografici basati su QuantumGIS e Postgis (CIG + * 0494241492)" + * + **********************************************************************/ +Datum ST_SharedPaths(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(ST_SharedPaths); +Datum ST_SharedPaths(PG_FUNCTION_ARGS) +{ +#if POSTGIS_GEOS_VERSION < 33 + lwerror("The GEOS version this postgis binary " + "was compiled against (%d) doesn't support " + "'ST_SharedPaths' function (3.3.0+ required)", + POSTGIS_GEOS_VERSION); + PG_RETURN_NULL(); +#else /* POSTGIS_GEOS_VERSION >= 33 */ + PG_LWGEOM *geom1, *geom2, *out; + LWGEOM *g1, *g2, *lwgeom_out; + + geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + + g1 = pglwgeom_deserialize(geom1); + g2 = pglwgeom_deserialize(geom2); + + lwgeom_out = lwgeom_sharedpaths(g1, g2); + if ( ! lwgeom_out ) + { + PG_FREE_IF_COPY(geom1, 0); + PG_FREE_IF_COPY(geom2, 1); + PG_RETURN_NULL(); + } + + out = pglwgeom_serialize(lwgeom_out); + PG_FREE_IF_COPY(geom1, 0); + PG_FREE_IF_COPY(geom2, 1); + + PG_RETURN_POINTER(out); + +#endif /* POSTGIS_GEOS_VERSION >= 33 */ + +} + diff --git a/postgis/lwgeom_geos_sharedpaths.c b/postgis/lwgeom_geos_sharedpaths.c deleted file mode 100644 index 9214c3dc0..000000000 --- a/postgis/lwgeom_geos_sharedpaths.c +++ /dev/null @@ -1,111 +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_SharedPaths - * - * Return the set of paths shared between two linear geometries, - * and their direction (same or opposite). - * - * Developed by Sandro Santilli (strk@keybit.net) for Faunalia - * (http://www.faunalia.it) with funding from Regione Toscana - Sistema - * Informativo per la Gestione del Territorio e dell' Ambiente - * [RT-SIGTA]". For the project: "Sviluppo strumenti software per il - * trattamento di dati geografici basati su QuantumGIS e Postgis (CIG - * 0494241492)" - * - **********************************************************************/ - -#include "lwgeom_geos.h" -#include "liblwgeom_internal.h" - -#include -#include - -/* #define POSTGIS_DEBUG_LEVEL 4 */ - -Datum ST_SharedPaths(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1(ST_SharedPaths); -Datum ST_SharedPaths(PG_FUNCTION_ARGS) -{ -#if POSTGIS_GEOS_VERSION < 33 - lwerror("The GEOS version this postgis binary " - "was compiled against (%d) doesn't support " - "'ST_SharedPaths' 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; - - geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); - - 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 = GEOSSharedPaths(g1,g2); - if (g3 == NULL) - { - GEOSGeom_destroy(g1); - GEOSGeom_destroy(g2); - lwerror("GEOSIntersection: %s", lwgeom_geos_errmsg); - PG_RETURN_NULL(); /* never get here */ - } - - GEOSSetSRID(g3, srid); - out = GEOS2POSTGIS(g3, is3d); - if (out == NULL) - { - GEOSGeom_destroy(g1); - GEOSGeom_destroy(g2); - GEOSGeom_destroy(g3); - lwerror("GEOSSharedPaths() threw an error (result postgis geometry formation)!"); - PG_RETURN_NULL(); /* never get here */ - } - - GEOSGeom_destroy(g1); - GEOSGeom_destroy(g2); - GEOSGeom_destroy(g3); - - PG_RETURN_POINTER(out); - -#endif /* POSTGIS_GEOS_VERSION >= 33 */ - -} - diff --git a/regress/sharedpaths_expected b/regress/sharedpaths_expected index 1ab5a5a75..46e848841 100644 --- a/regress/sharedpaths_expected +++ b/regress/sharedpaths_expected @@ -3,6 +3,6 @@ t2|SRID=10;GEOMETRYCOLLECTION(MULTILINESTRING((0 0,10 0)),MULTILINESTRING EMPTY) t3|GEOMETRYCOLLECTION(MULTILINESTRING EMPTY,MULTILINESTRING((0 0,10 0))) t4|GEOMETRYCOLLECTION(MULTILINESTRING EMPTY,MULTILINESTRING EMPTY) t5|GEOMETRYCOLLECTION(MULTILINESTRING((20 0,30 0)),MULTILINESTRING((70 0,80 0))) -ERROR: GEOSIntersection: IllegalArgumentException: Geometry is not lineal +ERROR: GEOSSharedPaths: IllegalArgumentException: Geometry is not lineal t7|GEOMETRYCOLLECTION(MULTILINESTRING((4 2,7 2)),MULTILINESTRING((14 7,11 6))) t8|GEOMETRYCOLLECTION(MULTILINESTRING((4 2,7 2)),MULTILINESTRING((14 7,11 6)))