Postgis - extruder un polygone

11

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. entrez la description de l'image ici

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.

user1331131
la source
Grande question! Peut-être pourriez-vous produire vos données au format KML pour plus de facilité et de flexibilité avec votre extrusion? Voici quelques points de départ: postgis.net/docs/ST_AsKML.html , code.google.com/p/postexperiments/wiki/… , gdal.org/drv_libkml.html
Brent Edwards

Réponses:

3

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 polyavec polygone (s) d'entrée

-Table poly_prjavec polygone à partir des points projetés

WITH points AS (
  SELECT (ST_DumpPoints(geom)).geom AS geom 
FROM poly
  SELECT 
    ST_MakePolygon(
      ST_MakeLine(
        ST_Project(geom, 5000, radians(0.0))::geometry)) AS geom 
  FROM points;

-Table cvxavec une coque convexe des 2 fonctionnalités.

La table poly_prjdoit être au-dessus de la table cvx.

Après cela, vous pouvez jouer avec les nouvelles options de remplissage de QGIS 2.10!

entrez la description de l'image ici

Stefan
la source