Postgis - wyciągnij wielokąt

11

Chcę wyciągnąć kształt wielokąta w postgisie, aby stworzyć efekt pseudo 3D. W tym celu napisałem prostą funkcję, aby to osiągnąć. Jest to bardzo testowy kod, który tworzy nowy wierzchołek Y dla każdego punktu na wielokącie, a następnie zamyka go, wracając do pierwotnego punktu: -

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

Działa z prostymi wielokątami, ale ma problemy z pierścieniami wewnętrznymi, ale głównym problemem jest to, że jest naprawdę wolny. Muszę wygenerować wynikowy kształt jako wielokąt, który można zacienić i renderować w serwerze map. Stąd operacje buforowania na końcu, co jest jedynym znanym mi sposobem zmniejszenia kształtu do jego obrysu.

Efektem końcowym będzie wytłoczony kształt reprezentujący oryginalny wielokąt. Następnie mogę przesunąć oryginalny wielokąt o tę samą odległość wyciągnięcia i umieścić go na górze, aby wykonać dach. wprowadź opis zdjęcia tutaj

Rozważałem użycie funkcji ST_Extrude w postgis-2.1.1 ALE to tworzy typ ST_PolyhedralSurface i nie jestem w stanie wyrenderować jej w serwerze map. O ile mogę stwierdzić, nie ma możliwości stworzenia tego konturu, ponieważ ST_Buffer nie działa z ST_polyhedralsurfaces.

Moje pytanie brzmi: czy można poprawić moją funkcję? Czy jest lepsze podejście? Dane wyjściowe muszą wyglądać jak na schemacie, który utworzyłem, umieszczając przesunięty wielokąt na moim wyciągniętym kształcie.

użytkownik1331131
źródło
Świetne pytanie! Być może mógłbyś wyprowadzić swoje dane w formacie KML dla większej łatwości i elastyczności podczas ekstruzji? Oto kilka punktów wyjścia: postgis.net/docs/ST_AsKML.html , code.google.com/p/postexperiments/wiki/… , gdal.org/drv_libkml.html
Brent Edwards

Odpowiedzi:

3

Szybkie rozwiązanie dla bardzo prostych wielokątów takich jak koła. Wyniki w 2 różnych tabelach, które muszą być renderowane we właściwym kierunku.

-Tabela polyz wielokątem wejściowym

-Tabela poly_prjz wielokątem z rzutowanych punktów

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;

- Stół cvxz wypukłym kadłubem z 2 cechami.

Stół poly_prjmusi znajdować się na stole cvx.

Następnie możesz grać z nowymi opcjami wypełnienia w QGIS 2.10!

wprowadź opis zdjęcia tutaj

Stefan
źródło