Note: As of PostGIS 2.0, 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.

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
• geomunion the lines together.
• polygonize the union-ed set

Thanks,

Jim

—THE BELOW solution may not work with holes —-

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

This doesn't work with holes does it?

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)))
```