Last active
August 29, 2015 14:01
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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