मैंने इसके लिए एक समारोह लिखा:
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 Gist पर कोड (यदि आप यहां तक बढ़ाएंगे तो मैं वहां भी एक स्टार की सराहना करूंगा)
मापदंडों का विवरण (यदि आप sql फ़ंक्शन की टिप्पणी में उनसे चूक गए हैं):
- पहले सेगमेंट की लंबाई ओरिजनल_लिफ्ट * हेड_रेट + हेड_ कॉन्स्टेंट होगी।
- यदि आप चाहते हैं कि यह दोगुना हो जाए तो सिर की दर 2 है, स्थिर 0 है।
- हम भूख में सामान्य रूप से ईओवी प्रक्षेपण का उपयोग करते हैं जो मीटर आधारित है। इसलिए अगर मैं लाइन के अंत में 2 मीटर जोड़ना चाहता हूं, तो मैं पूंछ को निर्धारित करता हूं: 1 को दर और 2 को tail_constant।