ST_LineSubstring — 返回线段上两个分数位置之间的部分。
geometry ST_LineSubstring(geometry a_linestring, float8 startfraction, float8 endfraction);
geography ST_LineSubstring(geography a_linestring, float8 startfraction, float8 endfraction);
计算输入线的线段,该线段从给定分数位置的起始位置到结束位置。第一个参数必须是 LINESTRING。第二个和第三个参数是范围 [0, 1] 内的值,表示起始和结束位置,为线长度的分数。如果存在,则会为添加的端点插值 Z 和 M 值。
如果 startfraction 和 endfraction 的值相同,则等同于 ST_LineInterpolatePoint。
|
|
|
这仅适用于 LINESTRING。要在连续的 MULTILINESTRING 上使用,请首先使用 ST_LineMerge 将它们连接起来。 |
|
|
|
自 1.1.1 版本起,此函数插值 M 和 Z 值。之前的版本将 Z 和 M 设置为未指定的值。 |
增强:3.4.0 - 引入了对 geography 的支持。
更改:2.1.0。在 2.0.x 之前,这被称为 ST_Line_Substring。
可用性:1.1.0,1.1.1 中添加了 Z 和 M 的支持
此函数支持 3D,并且不会删除 z 索引。
以 1/3 中间范围覆盖的 LineString(0.333,0.666)
SELECT ST_AsText(ST_LineSubstring( 'LINESTRING (20 180, 50 20, 90 80, 120 40, 180 150)', 0.333, 0.666)); ------------------------------------------------------------------------------------------------ LINESTRING (45.17311810399485 45.74337011202746, 50 20, 90 80, 112.97593050157862 49.36542599789519)
如果起始和结束位置相同,则结果是一个 POINT。
SELECT ST_AsText(ST_LineSubstring( 'LINESTRING(25 50, 100 125, 150 190)', 0.333, 0.333)); ------------------------------------------ POINT(69.2846934853974 94.2846934853974)
一个查询,将 LineString 切割成长度为 100 或更短的片段。它使用 generate_series() 与 CROSS JOIN LATERAL 来产生等效于 FOR 循环的效果。
WITH data(id, geom) AS (VALUES
( 'A', 'LINESTRING( 0 0, 200 0)'::geometry ),
( 'B', 'LINESTRING( 0 100, 350 100)'::geometry ),
( 'C', 'LINESTRING( 0 200, 50 200)'::geometry )
)
SELECT id, i,
ST_AsText( ST_LineSubstring( geom, startfrac, LEAST( endfrac, 1 )) ) AS geom
FROM (
SELECT id, geom, ST_Length(geom) len, 100 sublen FROM data
) AS d
CROSS JOIN LATERAL (
SELECT i, (sublen * i) / len AS startfrac,
(sublen * (i+1)) / len AS endfrac
FROM generate_series(0, floor( len / sublen )::integer ) AS t(i)
-- skip last i if line length is exact multiple of sublen
WHERE (sublen * i) / len <> 1.0
) AS d2;
id | i | geom
----+---+-----------------------------
A | 0 | LINESTRING(0 0,100 0)
A | 1 | LINESTRING(100 0,200 0)
B | 0 | LINESTRING(0 100,100 100)
B | 1 | LINESTRING(100 100,200 100)
B | 2 | LINESTRING(200 100,300 100)
B | 3 | LINESTRING(300 100,350 100)
C | 0 | LINESTRING(0 200,50 200)
Geography 实现沿椭球面测量,geometry 沿直线测量
SELECT ST_AsText(ST_LineSubstring( 'LINESTRING(-118.2436 34.0522, -71.0570 42.3611)'::geography, 0.333, 0.666),6) AS geog_sub
, ST_AsText(ST_LineSubstring('LINESTRING(-118.2436 34.0522, -71.0570 42.3611)'::geometry, 0.333, 0.666),6) AS geom_sub;
---------------------------------------------------------------
geog_sub | LINESTRING(-104.167064 38.854691,-87.674646 41.849854)
geom_sub | LINESTRING(-102.530462 36.819064,-86.817324 39.585927)