यहां मैं @whuber समाधान के बारे में थोड़ा अनुकूलन दिखाता हूं, और "बफर चौड़ाई" के संदर्भ में डाल रहा हूं, क्योंकि यह एक अधिक सामान्य समस्या के समाधान को एकीकृत करने के लिए उपयोगी है: क्या एक st_buffer उलटा फ़ंक्शन है, जो एक चौड़ाई का अनुमान देता है?
CREATE FUNCTION buffer_width(
-- rectangular strip mean width estimator
p_len float, -- len of the central line of g
p_geom geometry, -- g
p_btype varchar DEFAULT 'endcap=flat' -- st_buffer() parameter
) RETURNS float AS $f$
DECLARE
w_half float;
w float;
BEGIN
w_half := 0.25*ST_Area(p_geom)/p_len;
w := 0.50*ST_Area( ST_Buffer(p_geom,-w_half,p_btype) )/(p_len-2.0*w_half);
RETURN w_half+w;
END
$f$ LANGUAGE plpgsql IMMUTABLE;
इस समस्या के लिए, के बारे में @celenius सवाल सड़क चौड़ाई , sw
, समाधान है
sw = buffer_width(ST_Length(g1), g2)
जहां sw
"औसत चौड़ाई" है, g1
की केंद्रीय पंक्ति g2
और सड़क g2
एक POLYGON है । मैंने केवल OGC मानक पुस्तकालय का उपयोग किया, PostGIS के साथ परीक्षण किया , और एक ही बफर_ एक्सपोज़र फ़ंक्शन के साथ अन्य गंभीर व्यावहारिक अनुप्रयोगों को हल किया।
प्रदर्शन
A2
का क्षेत्रफल g2
, L1
केंद्रीय रेखा की लंबाई ( g1
) है g2
।
यह मानते हुए कि हम g2
द्वारा उत्पन्न किया जा सकता है g2=ST_Buffer(g1,w)
, और g1
यह एक सीधा है, इसलिए g2
लंबन L1
और चौड़ाई के साथ एक आयत है 2*w
, और
A2 = L1*(2*w) --> w = 0.5*A2/L1
यह @whuber का समान सूत्र नहीं है, क्योंकि यहां w
आयत ( g2
) चौड़ाई का आधा हिस्सा है । यह एक अच्छा अनुमानक है, लेकिन जैसा कि हम परीक्षण (नीचे) द्वारा देख सकते हैं, सटीक नहीं है, और फ़ंक्शन इसे एक सुराग के रूप में उपयोग करता है, g2
क्षेत्र को कम करने के लिए , और अंतिम अनुमानक के रूप में।
यहां हम "एंडकैप = स्क्वायर" या "एंडकैप = राउंड" वाले बफ़र्स का मूल्यांकन नहीं करते हैं, A2
उन्हें उसी के साथ एक बिंदु बफर के एक क्षेत्र की राशि की आवश्यकता होती है w
।
संदर्भ: 2005 के एक समान फोरम में , डब्ल्यू। ह्यूबर इस तरह के और अन्य समाधान बताते हैं।
TESTS और REASONS
उम्मीद के अनुसार, सीधी रेखा के परिणाम सटीक हैं। लेकिन अन्य ज्यामितीयों के लिए परिणाम निराशाजनक हो सकते हैं। मुख्य कारण, शायद, सभी मॉडल सटीक आयतों के लिए हैं, या ज्यामितीय के लिए जिसे "स्ट्रिप आयत" के रूप में अनुमानित किया जा सकता है। इस सन्निकटन की सीमा की जाँच के लिए एक "परीक्षण किट" ( wfactor
ऊपर के परिणामों में देखें )।
SELECT *, round(100.0*(w_estim-w)/w,1) as estim_perc_error
FROM (
SELECT btype, round(len,1) AS len, w, round(w/len,3) AS wfactor,
round( buffer_width(len, gbase, btype) ,2) as w_estim ,
round( 0.5*ST_Area(gbase)/len ,2) as w_near
FROM (
SELECT
*, st_length(g) AS len, ST_Buffer(g, w, btype) AS gbase
FROM (
-- SELECT ST_GeomFromText('LINESTRING(50 50,150 150)') AS g, -- straight
SELECT ST_GeomFromText('LINESTRING(50 50,150 150,150 50,250 250)') AS g,
unnest(array[1.0,10.0,20.0,50.0]) AS w
) AS t,
(SELECT unnest(array['endcap=flat','endcap=flat join=bevel']) AS btype
) AS t2
) as t3
) as t4;
परिणाम:
RECTANGLES के साथ (केंद्रीय लाइन एक चमक लाइन है):
btype | len | w | wfactor | w_estim | w_near | estim_perc_error
------------------------+-------+------+---------+---------+--------+------------------
endcap=flat | 141.4 | 1.0 | 0.007 | 1 | 1 | 0
endcap=flat join=bevel | 141.4 | 1.0 | 0.007 | 1 | 1 | 0
endcap=flat | 141.4 | 10.0 | 0.071 | 10 | 10 | 0
endcap=flat join=bevel | 141.4 | 10.0 | 0.071 | 10 | 10 | 0
endcap=flat | 141.4 | 20.0 | 0.141 | 20 | 20 | 0
endcap=flat join=bevel | 141.4 | 20.0 | 0.141 | 20 | 20 | 0
endcap=flat | 141.4 | 50.0 | 0.354 | 50 | 50 | 0
endcap=flat join=bevel | 141.4 | 50.0 | 0.354 | 50 | 50 | 0
अन्य GEOMETRIES के साथ (मध्य रेखा मुड़ी हुई):
btype | len | w | wfactor | w_estim | w_near | estim_perc_error
-----------------------+-----+------+---------+---------+--------+------------------
endcap=flat | 465 | 1.0 | 0.002 | 1 | 1 | 0
endcap=flat join=bevel | 465 | 1.0 | 0.002 | 1 | 0.99 | 0
endcap=flat | 465 | 10.0 | 0.022 | 9.98 | 9.55 | -0.2
endcap=flat join=bevel | 465 | 10.0 | 0.022 | 9.88 | 9.35 | -1.2
endcap=flat | 465 | 20.0 | 0.043 | 19.83 | 18.22 | -0.9
endcap=flat join=bevel | 465 | 20.0 | 0.043 | 19.33 | 17.39 | -3.4
endcap=flat | 465 | 50.0 | 0.108 | 46.29 | 40.47 | -7.4
endcap=flat join=bevel | 465 | 50.0 | 0.108 | 41.76 | 36.65 | -16.5
wfactor= w/len
w_near = 0.5*area/len
w_estim is the proposed estimator, the buffer_width function.
के बारे में btype
देख ST_Buffer गाइड , अच्छा ilustratins और यहां इस्तेमाल किया LineStrings साथ।
निष्कर्ष :
- का अनुमानक
w_estim
हमेशा से बेहतर होता है w_near
;
- "आयताकार के पास"
g2
ज्यामितीय, इसके ठीक, किसी भी के लिएwfactor
- एक अन्य ज्यामिति के लिए ("आयताकार स्ट्रिप्स के पास"),
wfactor=~0.01
त्रुटि के 1% के लिए सीमा का उपयोग करें w_estim
। इस wfactor तक, किसी अन्य अनुमानक का उपयोग करें।
सावधानी और रोकथाम
अनुमान त्रुटि क्यों होती है? जब आप उपयोग करते हैं ST_Buffer(g,w)
, तो आप उम्मीद करते हैं, "आयताकार पट्टी मॉडल" द्वारा, कि चौड़ाई के बफर द्वारा जोड़ा गया नया क्षेत्र w
लगभग ... w*ST_Length(g)
या w*ST_Perimeter(g)
नहीं है, आमतौर पर ओवरले द्वारा (मुड़ी हुई लाइनों को देखें) या "स्टाइलिंग" द्वारा, जब है औसत w
गलती का अनुमान । यह परीक्षणों का मुख्य संदेश है।
बफर के किसी भी राजा में इस समस्या का पता लगाने के लिए, बफर पीढ़ी के व्यवहार की जाँच करें:
SELECT btype, w, round(100.0*(a1-len1*2.0*w)/a1)::varchar||'%' AS straight_error,
round(100.0*(a2-len2*2.0*w)/a2)::varchar||'%' AS curve2_error,
round(100.0*(a3-len3*2.0*w)/a3)::varchar||'%' AS curve3_error
FROM (
SELECT
*, st_length(g1) AS len1, ST_Area(ST_Buffer(g1, w, btype)) AS a1,
st_length(g2) AS len2, ST_Area(ST_Buffer(g2, w, btype)) AS a2,
st_length(g3) AS len3, ST_Area(ST_Buffer(g3, w, btype)) AS a3
FROM (
SELECT ST_GeomFromText('LINESTRING(50 50,150 150)') AS g1, -- straight
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)') AS g2,
ST_GeomFromText('LINESTRING(50 50,150 150,150 50,250 250)') AS g3,
unnest(array[1.0,20.0,50.0]) AS w
) AS t,
(SELECT unnest(array['endcap=flat','endcap=flat join=bevel']) AS btype
) AS t2
) as t3;
परिणाम:
btype | w | straight_error | curve2_error | curve3_error
------------------------+------+----------------+--------------+--------------
endcap=flat | 1.0 | 0% | -0% | -0%
endcap=flat join=bevel | 1.0 | 0% | -0% | -1%
endcap=flat | 20.0 | 0% | -5% | -10%
endcap=flat join=bevel | 20.0 | 0% | -9% | -15%
endcap=flat | 50.0 | 0% | -14% | -24%
endcap=flat join=bevel | 50.0 | 0% | -26% | -36%