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.
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.
fuente
Respuestas:
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
poly
con polígono (s) de entrada-Tabla
poly_prj
con polígono desde puntos proyectados-Mesa
cvx
con un casco convexo de las 2 características.La mesa
poly_prj
tiene que estar encima de la mesacvx
.¡Después de eso puedes jugar con las nuevas opciones de relleno en QGIS 2.10!
fuente