st_linesubstring

时间:2017-04-21 19:15:35

标签: postgis postgresql-9.3

鉴于ST_LINESUBSTRING(https://postgis.net/docs/ST_LineSubstring.html)的文档,您可以直接将2d线串分成两个相等的部分。

见下文:

SELECT ST_LENGTH( ST_LINESUBSTRING( geom, 0.0, 0.5 )::GEOGRAPHY ),
       ST_LENGTH( ST_LINESUBSTRING( geom, 0.5, 1.0 )::GEOGRAPHY )
FROM data.street WHERE id = '11242';

    st_length     |    st_length
------------------+------------------
2003.80912128768 | 2153.56113185375 (1 row)

请注意,上面执行的命令应该产生两半相等的长度。但是,这两半的长度不同。

鉴于以下情况,您可以预期每一半都是~2078:

SELECT ST_LENGTH( geom::GEOGRAPHY )
FROM data.street WHERE id = '11242';
    st_length    
-----------------
4157.37025314031
(1 row)

至少,如果你将每一半加在一起,你会得到4157.370253,这是正确的长度。因此,ST_LINESUBSTRING不会缩小或扩展几何体。

那么,有人有答案吗?为什么ST_LINESUBSTRING会以这种方式运行?

2 个答案:

答案 0 :(得分:2)

此行为的原因是ST_LineSubstring拆分几何,而不是地理位置。换句话说,它在存储LineStrings的投影坐标中进行分割。

例如,假设某条特定线连接地球上的两个点A,B。现在,如果将这些点投影到lon / lat坐标并计算中点,则结果将不同于投影连接A和B的大圆的中点。

一种解决方案是使用ST_Segmentize

CREATE TEMPORARY TABLE lines(
  geom GEOMETRY
);

INSERT INTO lines VALUES
  (ST_MakeLine(ST_MakePoint(-13.4, 52.25), ST_MakePoint(-11.582, 48.1351)))
;

SELECT ST_Length(geom::geography) FROM lines;

SELECT
  ST_Length( ST_LineSubstring(geom, 0.0, 0.5 )::GEOGRAPHY ),
  ST_Length( ST_LineSubstring(geom, 0.5, 1.0 )::GEOGRAPHY )
FROM lines;

SELECT
  ST_AsText(ST_MakeLine(start_point, end_point)) AS segment,
  ST_Length(ST_MakeLine(start_point, end_point)::geography) AS len
FROM
(
    SELECT
        ST_Pointn(geom, generate_series(1, ST_NumPoints(geom)-1)) as start_point,
        ST_Pointn(geom, generate_series(2, ST_NumPoints(geom))) as end_point
    FROM (
        SELECT ST_Segmentize(geom::geography, ST_Length(geom::geography)/2)::geometry AS geom FROM lines
    ) AS line
) AS tmp;

这会产生:

CREATE TABLE
INSERT 0 1
    st_length     
------------------
 475724.617118868
(1 row)

    st_length    |    st_length     
-----------------+------------------
 237537.46004128 | 238220.186078105
(1 row)

                            segment                             |       len        
----------------------------------------------------------------+------------------
 LINESTRING(-13.4 52.25,-12.4518126471826 50.1960897877664)     |  237904.63855338
 LINESTRING(-12.4518126471826 50.1960897877664,-11.582 48.1351) | 237819.978632575
(2 rows)

使用后一种方法,这些段确实具有大致相等的长度。

答案 1 :(得分:0)

我有问题。我有2个表作为点和多线串。我使用st_closespoint将记录点捕捉到行,我从使用st_endpoint的行定义了坐标的结尾。然后我想知道每个点到线端点的长度。我该怎么办?谢谢 第一步定义端点

  

选择st_endpoint((st_dump(geom))。geom)作为端点   来自rel   petak2 =' Maguwo&#39 ;;

使用st_closespoint

捕捉点的第二步
  

选择st_closestpoint(geom,st_transform(rute_geom,32749))作为快照   来自rel,prm2   group by st_closestpoint(geom,st_transform(rute_geom,32749))

以及我如何加入它们以提取行的长度

  

选择st_length(st_line_substring(rel.geom,st_line_locate_point(rel.geom,rute_geom),   st_line_locate_point(geom,st_transform(st_endpoint((st_dump(rel.geom))。geom),32749))))as jarak   来自rel,prm2   petak2 =' Maguwo&#39 ;;