Skip to content

Instantly share code, notes, and snippets.

@lexman
Last active August 29, 2015 14:01
Show Gist options
  • Save lexman/ca1208f04199314c33ee to your computer and use it in GitHub Desktop.
Save lexman/ca1208f04199314c33ee to your computer and use it in GitHub Desktop.
Find a possible frontier between two polygons that intersect in several points in PostGIS
CREATE OR REPLACE FUNCTION frontiere(in poly_a geometry, in poly_b geometry) RETURNS geometry AS $frontiere$
DECLARE
borders_intersection geometry;
working_geom geometry;
pct_debut float;
pct_fin float;
curs refcursor;
pt_row record;
prev_abs float;
dist float;
max_dist float;
BEGIN
IF (geometrytype(poly_a) <> 'POLYGON') OR (geometrytype(poly_b) <> 'POLYGON') THEN
RETURN NULL;
END IF;
working_geom := ST_ExteriorRing(poly_a);
borders_intersection := ST_Intersection (working_geom, ST_ExteriorRing(poly_b));
CREATE TEMPORARY TABLE ordered_points AS
SELECT pt, ST_Line_Locate_Point(working_geom, pt) AS abs FROM
( SELECT (ST_DumpPoints(borders_intersection)).geom AS pt) AS sub
ORDER BY ST_Line_Locate_Point(working_geom, pt) ;
-- on considère que la portion la plus grande du polygone entre deux points d'intersection avec l'autre
-- constitue l'extérieur. C'est pour celà qu'on recherche cette portion
OPEN curs FOR SELECT * FROM ordered_points;
FETCH LAST FROM curs INTO pt_row;
prev_abs := pt_row.abs - 1;
MOVE ABSOLUTE 0 FROM curs;
max_dist := -1;
LOOP
FETCH curs INTO pt_row;
EXIT WHEN NOT FOUND;
dist := pt_row.abs - prev_abs;
IF (dist > max_dist) THEN
max_dist := dist;
pct_debut := pt_row.abs;
pct_fin := prev_abs;
END IF;
prev_abs := pt_row.abs;
END LOOP;
CLOSE curs;
DROP TABLE IF EXISTS ordered_points;
IF pct_fin < 0 THEN
pct_fin := pct_fin + 1;
END IF;
IF pct_debut > pct_fin THEN
RETURN ST_LineMerge(ST_Union(ST_Line_Substring(working_geom, pct_debut, 1), ST_Line_Substring(working_geom, 0, pct_fin)));
ELSE
RETURN ST_Line_Substring(working_geom, pct_debut, pct_fin);
END IF;
END;
$frontiere$ LANGUAGE 'plpgsql';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment