Name

ST_LineSubstring — Renvoie la partie d'une ligne située entre deux emplacements fractionnaires.

Synopsis

geometry ST_LineSubstring(geometry a_linestring, float8 startfraction, float8 endfraction);

geography ST_LineSubstring(geography a_linestring, float8 startfraction, float8 endfraction);

Description

Calcule la ligne qui est la section de la ligne d'entrée commençant et se terminant aux emplacements fractionnaires donnés. Le premier argument doit être un LINESTRING. Les deuxième et troisième arguments sont des valeurs dans l'intervalle [0, 1] représentant les emplacements de début et de fin en tant que fractions de la longueur de la ligne. Les valeurs Z et M sont interpolées pour les points d'extrémité ajoutés, le cas échéant.

Si startfraction et endfraction ont la même valeur, cela équivaut à ST_LineInterpolatePoint.

[Note]

Cette méthode ne fonctionne qu'avec les LINESTRING. Pour l'utiliser sur des MULTILINESTRINGs contigues, il faut d'abord les joindre avec ST_LineMerge.

[Note]

Depuis la version 1.1.1, cette fonction interpole les valeurs de M et Z. Les versions précédentes fixent Z et M à des valeurs non spécifiées.

Enhanced: 3.4.0 - Support for geography was introduced.

Modifié : 2.1.0. Jusqu'à la version 2.0.x, cette fonction était appelée ST_Line_Substring.

Disponibilité : 1.1.0, prise en charge des Z et M ajoutée dans la 1.1.1

Cette fonction prend en charge la 3D et ne supprime pas l'indice z.

Exemples

Une LineString vue avec un intervalle tous les 1/3 (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)

Si les points de départ et d'arrivée sont identiques, le résultat est un POINT.

SELECT ST_AsText(ST_LineSubstring( 'LINESTRING(25 50, 100 125, 150 190)', 0.333, 0.333));
------------------------------------------
 POINT(69.2846934853974 94.2846934853974)

Une requête pour découper une LineString en sections de longueur 100 ou moins. Elle utilise generate_series() avec un CROSS JOIN LATERAL pour produire l'équivalent d'une boucle 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 implementation measures along a spheroid, geometry along a line

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)

Voir aussi

ST_Length, ST_LineInterpolatePoint, ST_LineMerge