ST_LineSubstring — Returnerar delen av en linje mellan två fraktionerade platser.
geometry ST_LineSubstring(geometry a_linestring, float8 startfraction, float8 endfraction);
geography ST_LineSubstring(geography a_linestring, float8 startfraction, float8 endfraction);
Beräknar den linje som är den del av indatalinjen som börjar och slutar vid de angivna fraktionella positionerna. Det första argumentet måste vara en LINESTRING. Det andra och tredje argumentet är värden i intervallet [0, 1] som representerar start- och slutpositionerna. För geometridata mäts fraktionerna i 2D-linjelängd. Z- och M-värdena interpoleras för tillagda ändpunkter om sådana finns.
Om startfraktion och slutfraktion har samma värde är detta likvärdigt med ST_LineInterpolatePoint.
|
|
|
Detta fungerar endast med LINESTRINGs. För att använda på sammanhängande MULTILINESTRINGs måste du först sammanfoga dem med ST_LineMerge. |
|
|
|
Sedan release 1.1.1 interpolerar denna funktion M- och Z-värden. Tidigare utgåvor satte Z och M till ospecificerade värden. |
Förbättrad: 3.4.0 - Stöd för geografi infördes.
Ändrad: 2.1.0. Fram till 2.0.x kallades detta ST_Line_Substring.
Tillgänglighet: 1.1.0, stöd för Z och M tillkommer i 1.1.1
Denna funktion stöder 3d och kommer inte att tappa z-index.
Extrahera den mellersta tredjedelen av en LineString, från 0,333 till 0,666.
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)
Om start- och slutplatserna är desamma blir resultatet en POINT.
SELECT ST_LineSubstring( 'LINESTRING(25 50,100 125,150 190)', 0.333, 0.333);
POINT(69.28469348539744 94.28469348539744)
En fråga för att klippa en LineString i sektioner med längden 100 eller kortare. Den använder generate_series() med en CROSS JOIN LATERAL för att producera motsvarigheten till en FOR-loop.
Det sista genererade steget filtreras bort när linjelängden är en exakt multipel av den begärda sektionslängden.
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)
Dela en LineString med punkter genom att lokalisera punkterna längs linjen, lägga till ändpunkterna 0 och 1 och extrahera delsträngar mellan intilliggande positioner.
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)
Geografiska implementeringsåtgärder längs en sfäroid, geometri längs en linje
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;
För geometridata baseras de fraktionella positionerna på linjens 2D-längd, även när indata har Z-värden. De resulterande Z-värdena interpoleras längs den valda 2D-positionen.
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)