ฉันเขียนฟังก์ชันสำหรับสิ่งนี้:
CREATE OR REPLACE FUNCTION st_extend (
geom geometry,
head_rate double precision,
head_constant double precision,
tail_rate double precision,
tail_constant double precision)
RETURNS geometry AS
$BODY$
-- Extends a linestring.
-- First segment get extended by length * head_rate + head_constant.
-- Last segment get extended by length * tail_rate + tail_constant.
--
-- References:
-- http://blog.cleverelephant.ca/2015/02/breaking-linestring-into-segments.html
-- /gis//a/104451/44921
-- /gis//a/16701/44921
WITH segment_parts AS (
SELECT
(pt).path[1]-1 as segment_num
,
CASE
WHEN
(nth_value((pt).path, 2) OVER ()) = (pt).path
AND
(last_value((pt).path) OVER ()) = (pt).path
THEN
3
WHEN
(nth_value((pt).path, 2) OVER ()) = (pt).path
THEN
1
WHEN
(last_value((pt).path) OVER ()) = (pt).path
THEN
2
ELSE
0
END AS segment_flag
,
(pt).geom AS a
,
lag((pt).geom, 1, NULL) OVER () AS b
FROM ST_DumpPoints($1) pt
)
,
extended_segment_parts
AS
(
SELECT
*
,
ST_Azimuth(a,b) AS az1
,
ST_Azimuth(b,a) AS az2
,
ST_Distance(a,b) AS len
FROM
segment_parts
where b IS NOT NULL
)
,
expanded_segment_parts
AS
(
SELECT
segment_num
,
CASE
WHEN
bool(segment_flag & 2)
THEN
ST_Translate(b, sin(az2) * (len*tail_rate+tail_constant), cos(az2) * (len*tail_rate+tail_constant))
ELSE
a
END
AS a
,
CASE
WHEN
bool(segment_flag & 1)
THEN
ST_Translate(a, sin(az1) * (len*head_rate+head_constant), cos(az1) * (len*head_rate+head_constant))
ELSE
b
END
AS b
FROM extended_segment_parts
)
,
expanded_segment_lines
AS
(
SELECT
segment_num
,
ST_MakeLine(a, b) as geom
FROM
expanded_segment_parts
)
SELECT
ST_LineMerge(ST_Collect(geom ORDER BY segment_num)) AS geom
FROM expanded_segment_lines
;
$BODY$
LANGUAGE sql;
การใช้งาน:
SELECT st_extend(
st_makeline(
'0101000020E6100000300DC347C49418C03EE8D9ACFAA44A40',
'0101000020E6100000FB743C66A03218C0CDCCCCCCCC7C4A40'
),
1.333::double precision,
0::double precision,
1::double precision,
0::double precision
);
โปรดทราบว่าสิ่งนี้ให้ผลตอบแทนที่ยาวนานกว่า แต่ไม่ใช่จุดสิ้นสุด
รหัสเกี่ยวกับ GitHub สรุปสาระสำคัญ (ถ้าคุณ upvote ที่นี่ฉันจะขอบคุณดาวที่นั่นด้วย)
คำอธิบายของพารามิเตอร์ (ในกรณีที่คุณพลาดในความคิดเห็นของฟังก์ชัน sql):
- ความยาวส่วนแรกจะเป็นแบบดั้งเดิม _length * head_rate + head_constant
- ถ้าคุณต้องการให้มันเพิ่มเป็นสองเท่าอัตราของหัวคือ 2, ค่าคงที่คือ 0
- พวกเราในฮังการีมักใช้เครื่องฉาย EOV ซึ่งเป็นเครื่องวัด ดังนั้นหากฉันต้องการเพิ่ม 2 เมตรถึงจุดสิ้นสุดของเส้นฉันตั้งค่า tail: rate เป็น 1 และ tail_constant เป็น 2