Voglio estrudere una forma poligonale in postgis per creare un pseudo effetto 3D. A tal fine ho scritto una funzione grezza per raggiungerlo. Questo è molto codice di prova e crea un nuovo vertice Y per ogni punto sul poligono e poi lo chiude ritornando al punto originale: -
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
SELECT ST_AddPoint(ret_geom,
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
SELECT ST_AddPoint(ret_geom,
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
SELECT ST_AddPoint(ret_geom, ST_PointN(wkb_geometry,f)) into ret_geom;
--back then up again
SELECT ST_AddPoint(ret_geom, ST_PointN(wkb_geometry,f + 1)) into ret_geom;
SELECT ST_AddPoint(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
SELECT ST_AddPoint(ret_geom,
ST_MakePoint(ST_X(ST_PointN(wkb_geometry, 1)),
ST_Y(ST_PointN(wkb_geometry, 1)) + height)
) into ret_geom;
SELECT ST_AddPoint(ret_geom, ST_PointN(wkb_geometry,1)) into ret_geom;
END IF;
END LOOP;
RETURN ST_Buffer(ST_Buffer(ST_MakePolygon(ret_geom),10), -10);
END;
$BODY$
LANGUAGE plpgsql
Funziona con poligoni semplici ma ha problemi con gli anelli interni, ma il problema principale è che è molto lento. Devo produrre la forma risultante come un poligono che può essere ombreggiato e reso in mapserver. Da qui le operazioni del buffer alla fine, che è l'unico modo che conosco per ridurre la forma al suo contorno.
Il risultato finale sarà una forma estrusa che rappresenta il poligono originale. Posso quindi compensare il poligono originale della stessa distanza di estrusione e posizionarlo in cima per creare il tetto.
Ho pensato di usare la funzione ST_Extrude in postgis-2.1.1 MA questo crea un tipo ST_PolyhedralSurface e non sono in grado di renderizzarlo in mapserver. Per quanto ne so, non c'è modo di crearne uno, poiché ST_Buffer non funziona con ST_polyhedralsurfaces.
Quindi, la mia domanda è: la mia funzione può essere migliorata? O c'è un approccio migliore. L'output deve essere simile al diagramma che ho creato posizionando il poligono offset sulla mia forma estrusa.