名前

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]の範囲内で、開始点と終了点の、ライン長に対する割合の位置です。ジオメトリー入力に対する割合は2次元長で計算されます。Z値とM値が存在する場合には、追加された端点に対して補間計算を行います。

startfractionendfractionが同じ値である場合には、ST_LineInterpolatePointと同じになります。

[注記]

この関数はLINESTRINGに対してのみ動作します。連続するMULTILINESTRINGで使うには、先にST_LineMergeで結合させます。

[注記]

1.1.1リリースからは、この関数はM値とZ値を補間します。それより前のリリースでは、Z値とM値は不定値になります。

Enhanced: 3.4.0 ジオグラフィ対応が導入されました。

Changed: 2.1.0 2.0.xではST_Line_Substringと呼ばれていました。

Availability: 1.1.0 Z軸とM軸のサポートが1.1.1で追加されました

この関数は3次元に対応し、Z値を削除しません。

Extract the middle third of a LineString, from 0.333 to 0.666.

Code
SELECT 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)
Figure
Geometry figure for visual-st-linesubstring-01

開始点と終了点とが同じ場合には、結果はPOINTになります。

Code
SELECT ST_LineSubstring(
'LINESTRING(25 50,100 125,150 190)',
0.333,
0.333);
出力:
POINT(69.28469348539744 94.28469348539744)
Figure
Geometry figure for visual-st-linesubstring-02

LINESTRINGを長さ100以下の断片に分解するクエリ。FORループと同等のものを生成するためにgenerate_series()とCROSS JOIN LATERALとを併用しています。

The final generated step is filtered out when the line length is an exact multiple of the requested section length.

Code
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_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)
    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)
Figure
Geometry figure for visual-st-linesubstring-03

Split a LineString by points by locating the points along the line, adding the 0 and 1 endpoints, and extracting substrings between adjacent locations.

Code
WITH data AS (
  SELECT 'LINESTRING(0 0, 10 0)'::geometry AS line,
         'MULTIPOINT((2 0),(5 0),(8 0))'::geometry AS points
),
fractions AS (
  SELECT 0.0 AS fraction
  UNION ALL
  SELECT 1.0
  UNION ALL
  SELECT ST_LineLocatePoint(line, (dp).geom)
  FROM data
  CROSS JOIN LATERAL ST_Dump(points) AS dp
),
ordered AS (
  SELECT DISTINCT fraction
  FROM fractions
),
segments AS (
  SELECT fraction AS start_fraction,
         lead(fraction) OVER (ORDER BY fraction) AS end_fraction
  FROM ordered
)
SELECT row_number() OVER (ORDER BY start_fraction) AS segment_id,
       ST_LineSubstring(line, start_fraction, end_fraction) AS geom
FROM data
CROSS JOIN segments
WHERE end_fraction IS NOT NULL
  AND start_fraction <
> end_fraction
ORDER BY start_fraction;
出力:
segment_id |         geom
------------+----------------------
          1 | LINESTRING(0 0,2 0)
          2 | LINESTRING(2 0,5 0)
          3 | LINESTRING(5 0,8 0)
          4 | LINESTRING(8 0,10 0)
Figure
Geometry figure for visual-st-linesubstring-04

ジオグラフィ実装では回転楕円体面に沿って計測し、ジオメトリではラインに沿って計測します。

Code
SELECT ST_LineSubstring(
'LINESTRING(-118.2436 34.0522,-71.0570 42.3611)'::geography,
0.333,
0.666) AS geog_sub,
ST_LineSubstring(
    'LINESTRING(-118.2436 34.0522,-71.0570 42.3611)'::geometry,
    0.333,
    0.666) AS geom_sub;
出力:
-[ RECORD 1 ]----------
geog_sub | LINESTRING(-103.911641 38.931128,-87.941787 41.831072)
geom_sub | LINESTRING(-102.530462 36.819064,-86.817324 39.585927)
Figure
Geometry figure for visual-st-linesubstring-05

ジオメトリー入力の場合には、割合による位置はZ値を持っていてもラインの2次元長を基に計算します。結果のZ値は選択した2次元位置に沿って補間しています。

Code
WITH data AS (
  SELECT 'LINESTRING Z (0 0 0,0 2 5,0 10 10)'::geometry AS geom
)
SELECT ST_Length(geom) AS length_2d,
       ST_3DLength(geom) AS length_3d,
       ST_LineSubstring(geom, 0, 0.5) AS substring
FROM data;
出力:
length_2d |    length_3d     |              substring
-----------+------------------+-------------------------------------
        10 | 14.819145939191106 | LINESTRING Z (0 0 0,0 2 5,0 5 6.875)
Figure
Geometry figure for visual-st-linesubstring-06