Je souhaite extruder une forme de polygone dans des postgis pour créer un effet pseudo 3D. À cette fin, j'ai écrit une fonction brute pour y parvenir. Il s'agit très bien d'un code de test qui crée un nouveau sommet Y pour chaque point du polygone, puis le ferme en revenant au point d'origine: -
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
Il fonctionne avec des polygones simples mais a des problèmes avec les anneaux intérieurs, mais le problème principal est qu'il est vraiment lent. J'ai besoin de produire la forme résultante sous forme de polygone qui peut être ombré et rendu dans mapserver. D'où les opérations de tampon à la fin, qui est le seul moyen que je connaisse de réduire la forme à son contour.
Le résultat final sera une forme extrudée représentant le polygone d'origine. Je peux ensuite décaler le polygone d'origine de la même distance d'extrusion et le placer sur le dessus pour faire le toit.
J'ai envisagé d'utiliser la fonction ST_Extrude dans postgis-2.1.1 MAIS cela crée un type ST_PolyhedralSurface et je ne suis pas en mesure de le rendre dans mapserver. Pour autant que je sache, il n'y a aucun moyen de créer un aperçu de cela, car ST_Buffer ne fonctionne pas avec ST_polyhedralsurfaces.
Donc, ma question est, ma fonction peut-elle être améliorée? Ou existe-t-il une meilleure approche. La sortie doit ressembler au diagramme que j'ai créé en plaçant le polygone décalé sur ma forme extrudée.
la source
Réponses:
Une solution rapide pour les polygones très simples comme les cercles. Résultats dans 2 tableaux différents qui doivent être rendus dans la bonne direction.
-Table
poly
avec polygone (s) d'entrée-Table
poly_prj
avec polygone à partir des points projetés-Table
cvx
avec une coque convexe des 2 fonctionnalités.La table
poly_prj
doit être au-dessus de la tablecvx
.Après cela, vous pouvez jouer avec les nouvelles options de remplissage de QGIS 2.10!
la source