Как перебрать точки, чтобы разделить линейную строку на части в PgSQL? - PullRequest
1 голос
/ 03 мая 2019

Контекст : я работаю с базой данных PostgreSQL (10.6) и PostGIS 2.5.

Мне нужна помощь в создании функции, которая будет разделять линейную строку каждой строки из таблицы, используя точки из другой таблицы, и вставлять разделенные части в новую таблицу. У каждой линии есть правильные точки, а точки имеют точный порядок.

Я знаю, как разделить линейную строку, используя ST_Line_Substring ( документация здесь ), и я знаю, как сделать это, используя точку, используя ST_LineLocatePoint ( документация здесь ).


У меня есть 2 проблемы: я не хочу разбивать линию в точке, а скорее между каждой точкой в ​​соответствии с их положением на линии в виде дроби. Таким образом, если точка находится в 0%, а следующая - в 20% линии, первая часть будет идти от 0% до 10% от исходной линии. Вот краткая иллюстрация (извините, если это выглядит по-детски): enter image description here

Черная линия представляет исходную линейную строку, синие кружки - это точки, а цветные "линии" - какой тип line_substring я хочу.

Решение, которое я нашел для этой проблемы, заключается в простом добавлении доли предыдущей точки и текущей точки на линии и делении на 2 для начала части, и то же самое с текущей точкой и следующей, для конца части, как написано ниже:

ST_Line_Substring(line.geom, (
    ((ST_LineLocatePoint(line.geom, previous_point.geom) + ST_LineLocatePoint(line.geom, current_point.geom)) / 2),
    ((ST_LineLocatePoint(line.geom, current_point.geom) + ST_LineLocatePoint(line.geom, next_point.geom)) / 2)
)

Моя вторая проблема, я понятия не имею, как получить доступ к предыдущей и следующей точке из таблицы, содержащей точки. Сначала я хотел использовать какой-то механизм цикла, но я видел много ответов из других тем, в которых говорилось, что это не что-то оптимальное, и лучше их избегать, и я не нашел ничего похожего на индекс в SQL для переберите набор результатов или таблицу, чтобы легко получить доступ к предыдущему или следующему элементу.

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

1 Ответ

1 голос
/ 06 мая 2019

Я нашел решение, я использую курсор, а затем опцию RELATIVE, которая позволяет мне получить доступ к другим индексам, кроме строки, по которой я перебираю, вот как выглядит моя функция:

CREATE OR REPLACE FUNCTION splitLine(
    id character varying,
    linestring geometry(POINT,4326)
    )
RETURNS VOID AS $$

DECLARE
prior_point RECORD;
current_point RECORD;
next_point RECORD;
cursor_point SCROLL CURSOR FOR  SELECT id, line_id, line_order, geom
                                  FROM points
                                  WHERE id LIKE line_id
                                  ORDER BY line_order;

BEGIN

    OPEN cursor_points;

    LOOP

        FETCH FROM cursor_point INTO prior_point;
        FETCH RELATIVE 1 FROM cursor_point INTO current_point;
        FETCH RELATIVE 2 FROM cursor_point INTO next_point;

        -- Operations on my points and line 

    END LOOP;

    CLOSE cursor_point;
END; $$

LANGUAGE plpgsql;
...