Skip to content

Instantly share code, notes, and snippets.

@joshbrooks
Created May 12, 2013 13:10
Show Gist options
  • Save joshbrooks/5563502 to your computer and use it in GitHub Desktop.
Save joshbrooks/5563502 to your computer and use it in GitHub Desktop.
PostGIS functions to split polygons along their longest length. Uses a count of the number of interior polygons as a measuer of complexity. Change "WHERE st_numinteriorrings(geom)" to area or another geom function if necessary
--CREATE SCHEMA sandbox;
CREATE TABLE IF NOT EXISTS sandbox.test(id serial, geom geometry);
TRUNCATE sandbox.test;
CREATE OR REPLACE FUNCTION sandbox.split_geometry(ageom geometry, OUT the_geom geometry)
RETURNS SETOF geometry AS
$$
-- If polygon bbox is longer in the East-West direction, split by a North-South
-- line at the center of the polygon
DECLARE
srid int;
BEGIN
SELECT ST_SRID(ageom) INTO srid;
IF ST_XMax(ST_SetSRID(box2d(ageom),srid)) - ST_X(ST_Centroid(ageom)) < ST_YMax(ST_SetSRID(box2d(ageom),srid)) - ST_Y(ST_Centroid(ageom)) THEN
RETURN QUERY SELECT (ST_Dump(ST_Split(ageom,ST_MakeLine(
ST_SetSRID(ST_MakePoint(ST_XMax(ST_SetSRID(box2d(ageom),srid)), ST_Y(ST_Centroid(ageom))),srid),
ST_SetSRID(ST_MakePoint(ST_XMin(ST_SetSRID(box2d(ageom),srid)), ST_Y(ST_Centroid(ageom))),srid)
)
))).geom;
ELSE
RETURN QUERY SELECT (ST_Dump(ST_Split(ageom,ST_MakeLine(
ST_SetSRID(ST_MakePoint(ST_X(ST_Centroid(ageom)), ST_YMax(ST_SetSRID(box2d(ageom),srid))),srid),
ST_SetSRID(ST_MakePoint(ST_X(ST_Centroid(ageom)), ST_YMin(ST_SetSRID(box2d(ageom),srid))),srid)
)
))).geom;
END IF;
RETURN;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION sandbox.recursive_split_geometry(ageom geometry, threshold int, OUT the_geom geometry)
RETURNS setof geometry AS $$
BEGIN
RETURN QUERY
WITH RECURSIVE t(geom) AS (
SELECT sandbox.split_geometry(ageom) geom
UNION ALL
SELECT sandbox.split_geometry(geom) FROM t WHERE st_numinteriorrings(geom) > threshold)
--INSERT INTO sandbox.test(geom)
SELECT geom FROM t WHERE st_numinteriorrings(geom) <= threshold LIMIT 500 ;
RETURN;
END;
$$ LANGUAGE plpgsql;
INSERT INTO sandbox.test (geom)
SELECT sandbox.recursive_split_geometry((SELECT geom FROM inundation_nsl WHERE ogc_fid = 6655), 10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment