Postgis-ポリゴンを押し出す


11

postgisでポリゴンシェイプを押し出し、疑似3D効果を作成したい。この目的のために、私はそれを達成するための粗雑な関数を書きました。これは非常に多くのテストコードであり、ポリゴン上の各ポイントに対して新しいY頂点を作成し、元のポイントに戻ることで閉じます。

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

単純なポリゴンでは機能しますが、内部リングには問題がありますが、主な問題は本当に遅いことです。結果のシェイプを、mapserverでシェーディングおよびレンダリングできるポリゴンとして出力する必要があります。したがって、最後のバッファ操作は、形状をアウトラインに縮小する唯一の方法です。

最終結果は、元のポリゴンを表す押し出し形状になります。次に、元のポリゴンを同じ押し出し距離でオフセットし、そのポリゴンを上に配置して屋根を作成します。 ここに画像の説明を入力してください

postgis-2.1.1でST_Extrude関数を使用することを検討しましたが、これによりST_PolyhedralSurfaceタイプが作成され、mapserverでレンダリングできません。私が知る限り、ST_BufferはST_polyhedralsurfacesでは機能しないため、このアウトラインを作成する方法はありません。

だから、私の質問は、私の機能を改善できますか?または、より良いアプローチがあります。出力は、オフセットポリゴンを押し出しシェイプに配置して作成した図のように見える必要があります。


いい質問です!おそらく、データをKMLとして出力して、押し出しをより簡単かつ柔軟にすることができますか?:ここではいくつかの開始点ですpostgis.net/docs/ST_AsKML.htmlcode.google.com/p/postexperiments/wiki/...gdal.org/drv_libkml.html
ブレント・エドワーズ

回答:


3

円のような非常に単純なポリゴンの高速ソリューション。正しい方向にレンダリングする必要がある2つの異なるテーブルになります。

- poly入力ポリゴンのあるテーブル

- poly_prj投影された点からの多角形を持つテーブル

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;

-2 cvxつの特徴の凸包を持つテーブル。

テーブルpoly_prjはテーブルの上になければなりませんcvx

その後、QGIS 2.10の新しい塗りつぶしオプションで遊ぶことができます!

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.