'''Note:''' As of PostGIS 2.0, [http://postgis.net/docs/ST_Split.html ST_Split] returns a collection of geometries resulting by splitting a geometry. = Split Polygon With Line String = This example demonstrates how to Split a Polygon into multiple polygons using a Line. '''[http://postgis.refractions.net/pipermail/postgis-users/2008-May/019750.html James asks]:''' I think the steps below will work but I have one question. I am creating an application that allows a user to split a polygon by drawing a linestring across the polygon they wish to change. The crossing linestring has parts that are outside the polygon and I want to remove that before I geomunion. What's the easiest way to do that? - extract the lines that make up the polygon - add to this your crossing linestring - geomunion the lines together. - polygonize the union-ed set Thanks, Jim --THE BELOW solution may not work with holes --- '''[http://postgis.refractions.net/pipermail/postgis-users/2008-May/019902.html Kevin answers]:''' Here's an example splitting a polygon with a line. Note that the dangling cutlines outside the polygon are quietly dropped. {{{ SELECT ST_AsText(geom ) FROM ST_Dump (( SELECT ST_Polygonize(ST_Union(ST_Boundary(poly), line)) AS mpoly FROM (SELECT 'POLYGON ((1 1, 1 3, 3 3, 3 1, 1 1 ))'::geometry AS poly) AS a, (SELECT 'LINESTRING (0 2, 4 2)'::geometry AS line) AS b )); }}} Result: {{{ st_astext -------------------------------- POLYGON((1 1,1 2,3 2,3 1,1 1)) POLYGON((1 2,1 3,3 3,3 2,1 2)) (2 rows) }}} Cheers, Kevin '''[http://postgis.refractions.net/pipermail/postgis-users/2008-May/019903.html Regina asks]:''' This doesn't work with holes does it? '''[http://postgis.refractions.net/pipermail/postgis-users/2008-May/019904.html Kevin answers]''' Things would get a little bit more complicated when holes are involved, but I don't think overly so. The polygonizer builds polygons from all linework - this includes building polygons for what should be holes. What you would need to do as a post-process is remove all polygons that don't belong. (In the following example, I use contains and pointonsurface to determine which polygons I should exclude from the final result. Here is another sample polygon splitting, this time the polygon has two holes where one is intersected by the splitting line. {{{ CREATE TABLE poly AS SELECT 'POLYGON (( 1 1, 1 7, 7 7, 7 1, 1 1 ), ( 2 3, 4 3, 4 5, 2 5, 2 3 ), ( 5 5, 6 5, 6 6, 5 6, 5 5 ))'::geometry AS geom; CREATE TABLE line AS SELECT 'LINESTRING (0 4, 8 4)'::geometry AS geom; CREATE TABLE split_polys AS SELECT geom FROM ST_Dump (( SELECT polygonize(ST_Union(ST_Boundary(poly.geom), line.geom)) FROM poly, line )); DELETE FROM split_polys a USING poly b WHERE NOT ST_Contains(b.geom, ST_PointOnSurface(a.geom)); SELECT ST_AsText(geom) FROM split_polys; }}} Result: {{{ st_astext ---------------------------------------------------------------------- POLYGON((1 1,1 4,2 4,2 3,4 3,4 4,7 4,7 1,1 1)) POLYGON((1 4,1 7,7 7,7 4,4 4,4 5,2 5,2 4,1 4),(5 5,6 5,6 6,5 6,5 5)) (2 rows) ---------------------------------------------------------------------- }}} You can also make mosaic from polygons from one table. When you have for example this table {{{ CREATE TABLE geoms ( id serial NOT NULL, geom geometry, CONSTRAINT geoms_pkey PRIMARY KEY (id), CONSTRAINT enforce_dims_geom CHECK (ndims(geom) = 2), CONSTRAINT enforce_srid_geom CHECK (srid(geom) = (-1)) ) WITH (OIDS=FALSE); }}} This is the query that returns mosaic: {{{ SELECT geom FROM (SELECT (ST_Dump(g)).geom as geom FROM ( SELECT ST_Polygonize(g) as g FROM ( SELECT ST_Union(ST_Boundary(geom)) as g FROM geoms ) r )t) a WHERE EXISTS (SELECT geom FROM geoms b WHERE ST_Contains(b.geom, ST_PointOnSurface(a.geom))); }}} Yo!Zik == Function: `ST_SplitPolygon` == A custom function can be used to split a `[Multi]Polygon` with a `[Multi]LineString` blade. {{{ CREATE OR REPLACE FUNCTION ST_SplitPolygon(poly geometry, blade geometry) RETURNS geometry AS 'SELECT ST_Collect((d).geom) FROM (SELECT ST_Dump(ST_Polygonize(ST_Union(ST_Boundary($1), $2))) AS d) f WHERE ST_Area(ST_Intersection($1, (d).geom)) / ST_Area((d).geom) >= 1 - 1e-10;' LANGUAGE sql IMMUTABLE STRICT COST 100; }}} For example: {{{ SELECT ST_AsText(ST_SplitPolygon(poly, blade)) AS result FROM ( SELECT 'POLYGON ((20 30, 100 180, 160 20, 20 30), (70 70, 92 105, 110 50, 70 70))'::geometry AS poly, 'MULTILINESTRING ((150 90, 90 70, 60 20), (50 140, 90 70))'::geometry AS blade ) f; result ----------------------------------------- MULTIPOLYGON(((20 30,64.8275862068966 114.051724137931,80.4761904761905 86.6666666666667, 70 70,85.3846153846154 62.3076923076923,64.1095890410959 26.8493150684932,20 30)), ((64.8275862068966 114.051724137931,100 180,135.555555555556 85.1851851851852, 102.131147540984 74.0437158469945,92 105,80.4761904761905 86.6666666666667, 64.8275862068966 114.051724137931)), ((135.555555555556 85.1851851851852,160 20,64.1095890410959 26.8493150684932, 85.3846153846154 62.3076923076923,110 50,102.131147540984 74.0437158469945, 135.555555555556 85.1851851851852))) }}}