Postgis - extrude um polígono

11

Quero extrudar uma forma de polígono no postgis para criar um pseudo efeito 3D. Para esse fim, escrevi uma função grosseira para alcançá-la. Isso é muito código de teste e cria um novo vértice Y para cada ponto no polígono e depois o fecha retornando ao ponto original: -

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

Funciona com polígonos simples, mas tem problemas com anéis internos, mas o principal problema é que é realmente lento. Eu preciso exibir a forma resultante como um polígono que pode ser sombreado e renderizado no mapserver. Daí as operações de buffer no final, que é a única maneira que conheço de reduzir a forma ao seu contorno.

O resultado final será uma forma extrudada representando o polígono original. Posso então deslocar o polígono original pela mesma distância de extrusão e colocá-lo no topo para fazer o telhado. insira a descrição da imagem aqui

Eu considerei usar a função ST_Extrude no postgis-2.1.1, mas isso cria um tipo ST_PolyhedralSurface e não sou capaz de renderizá-lo no mapserver. Tanto quanto posso dizer, não há como criar um esboço disso, pois ST_Buffer não funciona com superfícies ST_polyhedrals.

Então, minha pergunta é: minha função pode ser melhorada? Ou existe uma abordagem melhor. A saída precisa parecer com o diagrama que eu criei, colocando o polígono de deslocamento na minha forma extrudada.

user1331131
fonte
Ótima pergunta! Talvez você possa enviar seus dados como KML para maior facilidade e flexibilidade com sua extrusão? Aqui estão alguns pontos de partida: postgis.net/docs/ST_AsKML.html , code.google.com/p/postexperiments/wiki/… , gdal.org/drv_libkml.html
Brent Edwards

Respostas:

3

Uma solução rápida para polígonos muito simples como círculos. Resultados em 2 tabelas diferentes que devem ser renderizadas na direção certa.

-Tabela polycom polígono (s) de entrada

-Tabela poly_prjcom polígono a partir de pontos projetados

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;

-Tabela cvxcom um casco convexo dos 2 recursos.

A mesa poly_prjdeve estar em cima da mesa cvx.

Depois disso, você pode jogar com as novas opções de preenchimento no QGIS 2.10!

insira a descrição da imagem aqui

Stefan
fonte