【问题标题】:How to iterate over points to split linestring into portions in PgSQL?如何迭代点以将线串拆分为 PgSQL 中的部分?
【发布时间】:2019-09-21 19:12:15
【问题描述】:

上下文:我正在使用 PostgreSQL (10.6) 数据库和 PostGIS 2.5。

我需要帮助创建一个函数,该函数将使用另一个表中的点从一个表中拆分每一行的线串,并将拆分部分插入到一个新表中。每条线都有其适当的点,并且这些点具有精确的顺序。

我知道如何使用ST_Line_Substring (documentation here) 来分割线串,并且我知道如何使用ST_LineLocatePoint (documentation here) 来使用点。


我有两个问题:我不想在一个点的位置分割线,而是根据它们在线上的位置作为分数在每个点之间分割。因此,如果有一个点位于 0% 处,而下一个点位于该行的 20% 处,则第一部分将从原始行的 0% 变为 10%。这是一个简单的插图(如果看起来很幼稚,请见谅):

黑色线代表原始线串,蓝色圆圈是点,彩色“线”代表我想要什么样的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 中的索引遍历结果集或表以轻松访问上一个或下一个元素。

所以我的主要问题是,如何遍历我的积分表,为每一行同时访问上一个、当前和下一个点?

【问题讨论】:

  • 嘿阿德里安。能否提供一些原始数据?也许应该使用子查询或 CTE。顺便说一句,很棒的插图。
  • @JimJones 我不太习惯 CTE,你想要什么样的原始数据?只需几行即可查看表格是如何制作的?
  • 一个 create table 语句和一些记录将帮助其他人重现您的环境,并将显着提高您获得答案的机会:-) CTE 只不过是一种基于创建临时表的机制查询,以便您能够在第二条语句中查询它。相当强大,但在处理大表时会变得非常慢。
  • 这里是表格创建和一些要插入的元组:collabedit.com/vk78w 我没有添加几何数据,因为我无法共享它,您只需要知道它以 SRID 4326 格式存储。这些点有规律地靠近这条线,但它们不在这条线上。

标签: sql postgresql loops geometry postgis


【解决方案1】:

我找到了一个解决方案,我使用游标,然后使用 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;

【讨论】:

    猜你喜欢
    • 2011-06-02
    • 2021-10-15
    • 1970-01-01
    • 2020-09-13
    • 2016-04-24
    • 2020-03-27
    • 2012-08-25
    • 2022-01-26
    相关资源
    最近更新 更多