From: Sandro Santilli Date: Thu, 11 Aug 2011 08:04:20 +0000 (+0000) Subject: Export lwgeom_split to liblwgeom, const-correct it [RT-SIGTA] X-Git-Tag: 2.0.0alpha1~1120 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=625e72615db680c43d9c0bd5132c4b0ea0265403;p=postgis Export lwgeom_split to liblwgeom, const-correct it [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@7727 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/Makefile.in b/liblwgeom/Makefile.in index eee0a762e..ce451838a 100644 --- a/liblwgeom/Makefile.in +++ b/liblwgeom/Makefile.in @@ -75,7 +75,8 @@ SA_OBJS = \ lwout_svg.o \ lwout_x3d.o \ lwgeom_geos.o \ - lwgeom_geos_clean.o + lwgeom_geos_clean.o \ + lwgeom_geos_split.o NM_OBJS = \ lwspheroid.o diff --git a/liblwgeom/liblwgeom.h b/liblwgeom/liblwgeom.h index efbbbcea3..bd7a619d1 100644 --- a/liblwgeom/liblwgeom.h +++ b/liblwgeom/liblwgeom.h @@ -2198,5 +2198,18 @@ LWGEOM* lwgeom_make_valid(LWGEOM* geom); */ LWGEOM* lwgeom_snap(const LWGEOM* geom1, const LWGEOM* geom2, double tolerance); +/* + * Split polygon by line, line by line, line by point. + * + * Returns all components as a collection. + * First element of the collection is always the part which + * remains after the cut, while the second element is the + * part which has been cut out. We arbitrarely take the part + * on the *right* of cut lines as the part which has been cut out. + * For a line cut by a point the part which remains is the one + * from start of the line to the cut point. + */ +LWGEOM* lwgeom_split(const LWGEOM* lwgeom_in, const LWGEOM* blade_in); + #endif /* !defined _LIBLWGEOM_H */ diff --git a/postgis/lwgeom_geos_split.c b/liblwgeom/lwgeom_geos_split.c similarity index 85% rename from postgis/lwgeom_geos_split.c rename to liblwgeom/lwgeom_geos_split.c index d4287bfc5..aa298d341 100644 --- a/postgis/lwgeom_geos_split.c +++ b/liblwgeom/lwgeom_geos_split.c @@ -11,8 +11,6 @@ * ********************************************************************** * - * ST_Split - * * Split polygon by line, line by line, line by point. * Returns at most components as a collection. * First element of the collection is always the part which @@ -38,24 +36,20 @@ #include "lwgeom_geos.h" #include "liblwgeom_internal.h" -#include "funcapi.h" #include #include -/* #define POSTGIS_DEBUG_LEVEL 4 */ - -static LWGEOM* lwline_split_by_line(LWLINE* lwgeom_in, LWLINE* blade_in); -static LWGEOM* lwline_split_by_point(LWLINE* lwgeom_in, LWPOINT* blade_in); -static LWGEOM* lwline_split(LWLINE* lwgeom_in, LWGEOM* blade_in); -static LWGEOM* lwpoly_split_by_line(LWPOLY* lwgeom_in, LWLINE* blade_in); -static LWGEOM* lwcollection_split(LWCOLLECTION* lwcoll_in, LWGEOM* blade_in); -static LWGEOM* lwpoly_split(LWPOLY* lwpoly_in, LWGEOM* blade_in); -static LWGEOM* lwgeom_split(LWGEOM* lwgeom_in, LWGEOM* blade_in); +static LWGEOM* lwline_split_by_line(const LWLINE* lwgeom_in, const LWLINE* blade_in); +static LWGEOM* lwline_split_by_point(const LWLINE* lwgeom_in, const LWPOINT* blade_in); +static LWGEOM* lwline_split(const LWLINE* lwgeom_in, const LWGEOM* blade_in); +static LWGEOM* lwpoly_split_by_line(const LWPOLY* lwgeom_in, const LWLINE* blade_in); +static LWGEOM* lwcollection_split(const LWCOLLECTION* lwcoll_in, const LWGEOM* blade_in); +static LWGEOM* lwpoly_split(const LWPOLY* lwpoly_in, const LWGEOM* blade_in); /* Initializes and uses GEOS internally */ static LWGEOM* -lwline_split_by_line(LWLINE* lwline_in, LWLINE* blade_in) +lwline_split_by_line(const LWLINE* lwline_in, const LWLINE* blade_in) { LWGEOM** components; LWGEOM* diff; @@ -143,7 +137,7 @@ lwline_split_by_line(LWLINE* lwline_in, LWLINE* blade_in) } static LWGEOM* -lwline_split_by_point(LWLINE* lwline_in, LWPOINT* blade_in) +lwline_split_by_point(const LWLINE* lwline_in, const LWPOINT* blade_in) { double loc, dist; POINT2D pt; @@ -210,7 +204,7 @@ lwline_split_by_point(LWLINE* lwline_in, LWPOINT* blade_in) } static LWGEOM* -lwline_split(LWLINE* lwline_in, LWGEOM* blade_in) +lwline_split(const LWLINE* lwline_in, const LWGEOM* blade_in) { switch (blade_in->type) { @@ -230,7 +224,7 @@ lwline_split(LWLINE* lwline_in, LWGEOM* blade_in) /* Initializes and uses GEOS internally */ static LWGEOM* -lwpoly_split_by_line(LWPOLY* lwpoly_in, LWLINE* blade_in) +lwpoly_split_by_line(const LWPOLY* lwpoly_in, const LWLINE* blade_in) { LWCOLLECTION* out; GEOSGeometry* g1; @@ -381,7 +375,7 @@ lwpoly_split_by_line(LWPOLY* lwpoly_in, LWLINE* blade_in) } static LWGEOM* -lwcollection_split(LWCOLLECTION* lwcoll_in, LWGEOM* blade_in) +lwcollection_split(const LWCOLLECTION* lwcoll_in, const LWGEOM* blade_in) { LWGEOM** split_vector=NULL; LWCOLLECTION* out; @@ -437,7 +431,7 @@ lwcollection_split(LWCOLLECTION* lwcoll_in, LWGEOM* blade_in) } static LWGEOM* -lwpoly_split(LWPOLY* lwpoly_in, LWGEOM* blade_in) +lwpoly_split(const LWPOLY* lwpoly_in, const LWGEOM* blade_in) { switch (blade_in->type) { @@ -451,21 +445,22 @@ lwpoly_split(LWPOLY* lwpoly_in, LWGEOM* blade_in) return NULL; } -static LWGEOM* -lwgeom_split(LWGEOM* lwgeom_in, LWGEOM* blade_in) +/* exported */ +LWGEOM* +lwgeom_split(const LWGEOM* lwgeom_in, const LWGEOM* blade_in) { switch (lwgeom_in->type) { case LINETYPE: - return lwline_split((LWLINE*)lwgeom_in, blade_in); + return lwline_split((const LWLINE*)lwgeom_in, blade_in); case POLYGONTYPE: - return lwpoly_split((LWPOLY*)lwgeom_in, blade_in); + return lwpoly_split((const LWPOLY*)lwgeom_in, blade_in); case MULTIPOLYGONTYPE: case MULTILINETYPE: case COLLECTIONTYPE: - return lwcollection_split((LWCOLLECTION*)lwgeom_in, blade_in); + return lwcollection_split((const LWCOLLECTION*)lwgeom_in, blade_in); default: lwerror("Splitting of %s geometries is unsupported", @@ -475,36 +470,3 @@ lwgeom_split(LWGEOM* lwgeom_in, LWGEOM* blade_in) } - -Datum ST_Split(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1(ST_Split); -Datum ST_Split(PG_FUNCTION_ARGS) -{ - PG_LWGEOM *in, *blade_in, *out; - LWGEOM *lwgeom_in, *lwblade_in, *lwgeom_out; - - in = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - lwgeom_in = pglwgeom_deserialize(in); - - blade_in = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); - lwblade_in = pglwgeom_deserialize(blade_in); - - error_if_srid_mismatch(lwgeom_in->srid, lwblade_in->srid); - - lwgeom_out = lwgeom_split(lwgeom_in, lwblade_in); - if ( ! lwgeom_out ) - { - PG_FREE_IF_COPY(in, 0); - PG_FREE_IF_COPY(blade_in, 1); - PG_RETURN_NULL(); - } - - out = pglwgeom_serialize(lwgeom_out); - - PG_FREE_IF_COPY(in, 0); - PG_FREE_IF_COPY(blade_in, 1); - - PG_RETURN_POINTER(out); - -} - diff --git a/postgis/Makefile.in b/postgis/Makefile.in index 97f68055f..cf809f27e 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_split.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 b767b00cc..5e7ccb1ae 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -3599,3 +3599,60 @@ Datum ST_Snap(PG_FUNCTION_ARGS) } +/* + * ST_Split + * + * Split polygon by line, line by line, line by point. + * Returns at most components as a collection. + * First element of the collection is always the part which + * remains after the cut, while the second element is the + * part which has been cut out. We arbitrarely take the part + * on the *right* of cut lines as the part which has been cut out. + * For a line cut by a point the part which remains is the one + * from start of the line to the cut point. + * + * + * Author: Sandro Santilli + * + * Work done for Faunalia (http://www.faunalia.it) with fundings + * from Regione Toscana - Sistema Informativo per il Governo + * del Territorio e dell'Ambiente (RT-SIGTA). + * + * Thanks to the PostGIS community for sharing poly/line ideas [1] + * + * [1] http://trac.osgeo.org/postgis/wiki/UsersWikiSplitPolygonWithLineString + * + */ +Datum ST_Split(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(ST_Split); +Datum ST_Split(PG_FUNCTION_ARGS) +{ + PG_LWGEOM *in, *blade_in, *out; + LWGEOM *lwgeom_in, *lwblade_in, *lwgeom_out; + + in = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + lwgeom_in = pglwgeom_deserialize(in); + + blade_in = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + lwblade_in = pglwgeom_deserialize(blade_in); + + error_if_srid_mismatch(lwgeom_in->srid, lwblade_in->srid); + + lwgeom_out = lwgeom_split(lwgeom_in, lwblade_in); + if ( ! lwgeom_out ) + { + PG_FREE_IF_COPY(in, 0); + PG_FREE_IF_COPY(blade_in, 1); + PG_RETURN_NULL(); + } + + out = pglwgeom_serialize(lwgeom_out); + + PG_FREE_IF_COPY(in, 0); + PG_FREE_IF_COPY(blade_in, 1); + + PG_RETURN_POINTER(out); + +} + +