Postgis - extruye un polígono

11

Quiero extruir una forma de polígono en postgis para crear un efecto pseudo 3D. Con este fin, he escrito una función cruda para lograrlo. Este es mucho código de prueba y crea un nuevo vértice Y para cada punto en el polígono y luego lo cierra volviendo al punto 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 con polígonos simples pero tiene problemas con los anillos interiores, pero el problema principal es que es realmente lento. Necesito generar la forma resultante como un polígono que se puede sombrear y representar en el servidor de mapas. Por lo tanto, las operaciones de almacenamiento intermedio al final, que es la única forma en que sé de reducir la forma a su contorno.

El resultado final será una forma extruida que representa el polígono original. Luego puedo compensar el polígono original por la misma distancia de extrusión y colocarlo en la parte superior para hacer el techo. ingrese la descripción de la imagen aquí

Pensé en usar la función ST_Extrude en postgis-2.1.1 PERO esto crea un tipo ST_PolyhedralSurface y no puedo renderizarlo en el servidor de mapas. Por lo que puedo decir, no hay forma de crear un esquema de esto, ya que ST_Buffer no funciona con ST_polyhedralsurfaces.

Entonces, mi pregunta es, ¿se puede mejorar mi función? ¿O hay un mejor enfoque? La salida debe verse según el diagrama que creé colocando el polígono desplazado en mi forma extruida.

usuario1331131
fuente
Gran pregunta! ¿Quizás podría generar sus datos como KML para una mayor facilidad y flexibilidad con su extrusión? Aquí hay algunos puntos de partida: postgis.net/docs/ST_AsKML.html , code.google.com/p/postexperiments/wiki/… , gdal.org/drv_libkml.html
Brent Edwards

Respuestas:

3

Una solución rápida para polígonos muy simples como círculos. Resultados en 2 tablas diferentes que se deben representar en la dirección correcta.

-Tabla polycon polígono (s) de entrada

-Tabla poly_prjcon polígono desde puntos proyectados

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;

-Mesa cvxcon un casco convexo de las 2 características.

La mesa poly_prjtiene que estar encima de la mesa cvx.

¡Después de eso puedes jugar con las nuevas opciones de relleno en QGIS 2.10!

ingrese la descripción de la imagen aquí

Stefan
fuente