Postgis - extrudiere ein Polygon

11

Ich möchte eine Polygonform in Postgis extrudieren, um einen Pseudo-3D-Effekt zu erzeugen. Zu diesem Zweck habe ich eine grobe Funktion geschrieben, um dies zu erreichen. Dies ist sehr viel Testcode und erstellt einen neuen Y-Eckpunkt für jeden Punkt auf dem Polygon und schließt ihn dann, indem er zum ursprünglichen Punkt zurückkehrt: -

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

Es funktioniert mit einfachen Polygonen, hat aber Probleme mit Innenringen, aber das Hauptproblem ist, dass es sehr langsam ist. Ich muss die resultierende Form als Polygon ausgeben, das in Mapserver schattiert und gerendert werden kann. Daher die Pufferoperationen am Ende, die die einzige Möglichkeit sind, die Form auf den Umriss zu reduzieren.

Das Endergebnis ist eine extrudierte Form, die das ursprüngliche Polygon darstellt. Ich kann dann das ursprüngliche Polygon um denselben Extrusionsabstand versetzen und es oben platzieren, um das Dach herzustellen. Geben Sie hier die Bildbeschreibung ein

Ich habe überlegt, die ST_Extrude-Funktion in postgis-2.1.1 zu verwenden, ABER dies erzeugt einen ST_PolyhedralSurface-Typ und ich kann ihn nicht in Mapserver rendern. Soweit ich das beurteilen kann, gibt es auch keine Möglichkeit, einen Umriss davon zu erstellen, da ST_Buffer nicht mit ST_polyhedralsurfaces funktioniert.

Meine Frage ist also, kann meine Funktion verbessert werden? Oder gibt es einen besseren Ansatz. Die Ausgabe muss gemäß dem Diagramm aussehen, das ich durch Platzieren des versetzten Polygons auf meiner extrudierten Form erstellt habe.

user1331131
quelle
Gute Frage! Vielleicht könnten Sie Ihre Daten als KML ausgeben, um Ihre Extrusion einfacher und flexibler zu gestalten? Hier sind einige Ausgangspunkte: postgis.net/docs/ST_AsKML.html , code.google.com/p/postexperiments/wiki/… , gdal.org/drv_libkml.html
Brent Edwards

Antworten:

3

Eine schnelle Lösung für sehr einfache Polygone wie Kreise. Das Ergebnis sind 2 verschiedene Tabellen, die in die richtige Richtung gerendert werden müssen.

-Tabelle polymit Eingabepolygon (en)

-Tabelle poly_prjmit Polygon von projizierten Punkten

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;

-Tabelle cvxmit einer konvexen Hülle der 2 Merkmale.

Der Tisch poly_prjmuss oben auf dem Tisch stehen cvx.

Danach können Sie mit den neuen Fülloptionen in QGIS 2.10 spielen!

Geben Sie hier die Bildbeschreibung ein

Stefan
quelle