amf
.public
Tables
(current)
Columns
Constraints
Relationships
Orphan Tables
Anomalies
Routines
_st_concavehull(param_inputgeom geometry)
Parameters
Name
Type
Mode
param_inputgeom
geometry
IN
Definition
DECLARE vexhull public.geometry; var_resultgeom public.geometry; var_inputgeom public.geometry; vexring public.geometry; cavering public.geometry; cavept public.geometry[]; seglength double precision; var_tempgeom public.geometry; scale_factor float := 1; i integer; BEGIN -- First compute the ConvexHull of the geometry vexhull := public.ST_ConvexHull(param_inputgeom); var_inputgeom := param_inputgeom; --A point really has no concave hull IF public.ST_GeometryType(vexhull) = 'ST_Point' OR public.ST_GeometryType(vexHull) = 'ST_LineString' THEN RETURN vexhull; END IF; -- convert the hull perimeter to a linestring so we can manipulate individual points vexring := CASE WHEN public.ST_GeometryType(vexhull) = 'ST_LineString' THEN vexhull ELSE public.ST_ExteriorRing(vexhull) END; IF abs(public.ST_X(public.ST_PointN(vexring,1))) < 1 THEN --scale the geometry to prevent stupid precision errors - not sure it works so make low for now scale_factor := 100; vexring := public.ST_Scale(vexring, scale_factor,scale_factor); var_inputgeom := public.ST_Scale(var_inputgeom, scale_factor, scale_factor); --RAISE NOTICE 'Scaling'; END IF; seglength := public.ST_Length(vexring)/least(public.ST_NPoints(vexring)*2,1000) ; vexring := public.ST_Segmentize(vexring, seglength); -- find the point on the original geom that is closest to each point of the convex hull and make a new linestring out of it. cavering := public.ST_Collect( ARRAY( SELECT public.ST_ClosestPoint(var_inputgeom, pt ) As the_geom FROM ( SELECT public.ST_PointN(vexring, n ) As pt, n FROM generate_series(1, public.ST_NPoints(vexring) ) As n ) As pt ) ) ; var_resultgeom := public.ST_MakeLine(geom) FROM public.ST_Dump(cavering) As foo; IF public.ST_IsSimple(var_resultgeom) THEN var_resultgeom := public.ST_MakePolygon(var_resultgeom); --RAISE NOTICE 'is Simple: %', var_resultgeom; ELSE --RAISE NOTICE 'is not Simple: %', var_resultgeom; var_resultgeom := public.ST_ConvexHull(var_resultgeom); END IF; IF scale_factor > 1 THEN -- scale the result back var_resultgeom := public.ST_Scale(var_resultgeom, 1/scale_factor, 1/scale_factor); END IF; -- make sure result covers original (#3638) -- Using ST_UnaryUnion since SFCGAL doesn't replace with its own implementation -- and SFCGAL one chokes for some reason var_resultgeom := public.ST_UnaryUnion(public.ST_Collect(param_inputgeom, var_resultgeom) ); RETURN var_resultgeom; END;