Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LabelCenterline function #426

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions sql/LabelCenterline.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/******************************************************************************
### LabelCenterline ###

Given a polygon or multipolygon, calculates a linestring suitable for a label.

__Parameters:__

- `geometry` inGeometry - A polygon or multipolygon.

__Returns:__ `geometry(multiline)`
******************************************************************************/
CREATE OR REPLACE FUNCTION CountDisconnectedEndpoints(polyline geometry, testline geometry)
RETURNS integer AS $$
BEGIN
RETURN ST_NPoints(ST_RemoveRepeatedPoints(ST_Points(polyline)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An explanation of the equation would be good here.

- ST_NPoints(ST_RemoveRepeatedPoints(ST_Points(ST_Difference(polyline, testline))))
- ST_NPoints(testline) + 2;
END
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION TrimmedCenterline(inPolyline geometry)
RETURNS geometry AS $$
DECLARE outPolyline geometry;
BEGIN
WITH tbla AS (
quincylvania marked this conversation as resolved.
Show resolved Hide resolved
SELECT inPolyline as polyline, (ST_Dump(inPolyline)).geom as edge
),
tblb AS (
SELECT polyline, edge as shortestBranchLine
FROM tbla
WHERE CountDisconnectedEndpoints(polyline, edge) > 0
ORDER BY ST_Length(edge) ASC
LIMIT 1
),
tblc AS (
SELECT ST_LineMerge(ST_Difference(polyline, shortestBranchLine)) as polyline
FROM tblb
)
SELECT TrimmedCenterline(polyline) as polyline
FROM tblc
WHERE ST_NumGeometries(polyline) > 1
UNION ALL
SELECT polyline INTO outPolyline FROM tblc;
RETURN outPolyline;
END
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION LabelCenterline(inGeometry geometry)
RETURNS geometry AS $$
DECLARE outPolyline geometry;
BEGIN
WITH tbla AS (
quincylvania marked this conversation as resolved.
Show resolved Hide resolved
SELECT inGeometry as inPolygon WHERE ST_GeometryType(inGeometry) = 'ST_Polygon'
UNION ALL
SELECT ST_ConcaveHull(ST_Simplify(inGeometry, 25), 0.2) as inPolygon WHERE ST_GeometryType(inGeometry)='ST_MultiPolygon'
quincylvania marked this conversation as resolved.
Show resolved Hide resolved
),
tblb AS (
SELECT ST_MakePolygon(ST_ExteriorRing(inPolygon)) as shellPolygon
FROM tbla
),
tblc AS (
SELECT shellPolygon, (ST_Dump(ST_VoronoiLines(ST_LineInterpolatePoints(ST_Boundary(shellPolygon), 0.0075)))).geom as voroniLines
FROM tblb
),
tbld AS (
SELECT ST_LineMerge(ST_Collect(voroniLines)) as voroniPolyline
FROM tblc
WHERE ST_Contains(shellPolygon, voroniLines)
)
SELECT ST_ChaikinSmoothing(ST_SimplifyPreserveTopology(TrimmedCenterline(voroniPolyline), 80), 3, false) INTO outPolyline FROM tbld;
RETURN outPolyline;
END
$$ LANGUAGE plpgsql;