Постгис - выдавливать многоугольник

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. Следовательно, операции с буфером в конце - единственный известный мне способ сведения фигуры к ее контуру.

Конечный результат будет вытянутой формой, представляющей исходный многоугольник. Затем я могу сместить исходный полигон на то же расстояние экструзии и поместить его сверху, чтобы сделать крышу. введите описание изображения здесь

Я рассмотрел использование функции ST_Extrude в postgis-2.1.1, НО это создает тип ST_PolyhedralSurface, и я не могу отобразить его в mapserver. Насколько я могу сказать, нет никакого способа создать схему этого также, поскольку ST_Buffer не работает с ST_polyhedralsurfaces.

Итак, мой вопрос: можно ли улучшить мою функцию? Или есть лучший подход. Вывод должен выглядеть в соответствии с диаграммой, которую я создал, поместив смещенный многоугольник на мою вытянутую форму.

user1331131
источник
Отличный вопрос! Возможно, вы могли бы вывести свои данные в виде KML для большей простоты и гибкости при экструзии? Вот некоторые отправные точки: postgis.net/docs/ST_AsKML.html , code.google.com/p/postexperiment/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;

-Стол cvxс выпуклой оболочкой из 2 функций.

Стол poly_prjдолжен быть на вершине стола cvx.

После этого вы можете играть с новыми вариантами заполнения в QGIS 2.10!

введите описание изображения здесь

Стефан
источник