# Postgis - extrude a polygon

I want to extrude a polygon shape in postgis to create a pseudo 3D effect. To this end I have written a crude function to achieve it. This is very much test code and it creates a new Y vertice for each point on the polygon and then closes it by returning to the original point:-

CREATE OR REPLACE FUNCTION public.extrude_polygon(wkb_geometry_param geometry, height integer, simplify boolean DEFAULT false)
RETURNS geometry AS
$BODY$
DECLARE
f int;
ret_geom geometry;
wkb_geometry geometry;
BEGIN

--convert polygon to linestring
IF ST_GeometryType(wkb_geometry_param) != 'ST_Polygon' THEN
RETURN NULL;
END IF;

IF simplify THEN
wkb_geometry =         ST_Simplify(ST_Transform(ST_Exteriorring(wkb_geometry_param), 27700), 0.5);
ELSE
wkb_geometry = ST_Transform(ST_Exteriorring(wkb_geometry_param), 27700);
END IF;

--initialise output geometry
ret_geom =ST_MakeLine(ST_PointN(wkb_geometry,1),ST_PointN(wkb_geometry,1));

--Move first point to up

ST_MakePoint(ST_X(ST_PointN(wkb_geometry, 1)),
ST_Y(ST_PointN(wkb_geometry, 1)) + height)
) into ret_geom;

FOR f IN 1..ST_NPoints(wkb_geometry) LOOP
IF f < ST_NPoints(wkb_geometry) THEN
--across to next high point
ST_MakePoint(ST_X(ST_PointN(wkb_geometry, f + 1)),
ST_Y(ST_PointN(wkb_geometry, f + 1)) + height)
) into ret_geom;
--down to next point
SELECT ST_AddPoint(ret_geom, ST_PointN(wkb_geometry,f + 1)) into ret_geom;
--back to last point
--back then up again
SELECT ST_AddPoint(ret_geom, ST_PointN(wkb_geometry,f + 1)) into ret_geom;
ST_MakePoint(ST_X(ST_PointN(wkb_geometry, f + 1)),
ST_Y(ST_PointN(wkb_geometry, f + 1)) + height)
) into ret_geom;
ELSE
--across to first high point
ST_MakePoint(ST_X(ST_PointN(wkb_geometry, 1)),
ST_Y(ST_PointN(wkb_geometry, 1)) + height)
) into ret_geom;

END IF;
END LOOP;

RETURN ST_Buffer(ST_Buffer(ST_MakePolygon(ret_geom),10), -10);

END;

$BODY$
LANGUAGE plpgsql


It works with simple polygons but has problems with interior rings, but the main issue is that it is really slow. I need to output the resultant shape as a polygon that can be shaded and rendered in mapserver. Hence the buffer operations at the end which is the only way I know of reducing the shape to it's outline.

The end result will be an extruded shape representing the original polygon. I can then offset the original polygon by the same extrusion distance and place it on top to make the roof.

I considered using the ST_Extrude function in postgis-2.1.1 BUT this creates a ST_PolyhedralSurface type and I am not able to render it in mapserver. As far as I can tell there is no way to create an outline of this either as ST_Buffer does not work with ST_polyhedralsurfaces.

So, my question is, can my function be improved? Or is there a better approach. The output needs to look as per the diagram which I created by placing the offset polygon onto my extruded shape.

A fast solution for very simple polygons like circles. Results in 2 different tables which have to be rendered in the right direction.

-Table poly with input polygon(s)

-Table poly_prj with polygon from projected points

WITH points AS (
SELECT (ST_DumpPoints(geom)).geom AS geom
FROM poly
SELECT
ST_MakePolygon(
ST_MakeLine(
FROM points;


-Table cvx with a convex hull of the 2 features.

Table poly_prj has to be on top of the table cvx.

After that you can play with the new fill options in QGIS 2.10!