PostGIS में SIA या बेज़ियर लाइन स्मूथिंग कैसे करें?


9

क्या कोई बेज़ियर कर्व्स या इटरेटिव एवरेजिंग ( SIA ) एल्गोरिथ्म का उपयोग करके पोस्टगिस टेबल से लाइनस्ट्रीम को चिकना करने के लिए एक उदाहरण एसक्यूएल प्रदान कर सकता है?

जवाबों:


6

मैंने एक छोटी, भोली स्क्रिप्ट बनाई, जो इनपुट लाइनस्ट्रीम को कुछ आंकड़ों के आधार पर CompoundCurves में परिवर्तित करती है।

यह क्या करता है:

  • मूल डेटा की तुलना में एक नेत्रहीन अधिक आकर्षक परिणाम बनाने के लिए तेज कोनों को काटता है।
  • Plpgsql का उपयोग करता है। कोई अतिरिक्त एक्सटेंशन की आवश्यकता नहीं है।
  • एक ज्यामिति के अलावा 0 और 100 के बीच एक वैकल्पिक "चौरसाई कारक" को स्वीकार करता है।

यह क्या नहीं करता है:

  • मल्टीलेनस्ट्रीम प्रक्रिया। किसी अन्य ज्यामिति प्रकार के लिए, यह केवल इनपुट लौटाता है।
  • जेड और एम मूल्यों का उपयोग करता है। यह बस उन्हें छोड़ देता है। इसका उपयोग केवल 2 डी कार्टोग्राफिक उद्देश्यों के लिए करें।
  • गणितीय रूप से सही परिणाम बनाता है। परिणाम सही से दूर हैं, और कुछ मामलों (जैसे तेज कोनों) में भी नेत्रहीन हो सकता है। मैं इसे अच्छी तरह से परीक्षण नहीं किया। हमेशा परिणामों की समीक्षा करें!
  • तेज दौड़ता है। मुझे यकीन है कि इसे एक और अधिक इष्टतम रूप में फिर से लिखा जा सकता है।
  • असली चौरसाई करता है। वास्तविक चौरसाई के लिए उपयोग करने के लिए बहुत बेहतर एल्गोरिदम (जैसे चाकेन या प्रश्न में उल्लिखित) हैं। यह उत्तर मेरे जैसे लोगों को शुद्ध पोस्टगिस दृष्टिकोण की खोज के लिए लक्षित करता है जो वास्तविक डेटा से कुछ प्रकार की घुमावदार रेखाएं बनाते हैं।

लिपी:

CREATE OR REPLACE FUNCTION CreateCurve(geom geometry, percent int DEFAULT 40)
    RETURNS geometry AS
$$
DECLARE
    result text;
    p0 geometry;
    p1 geometry;
    p2 geometry;
    intp geometry;
    tempp geometry;
    geomtype text := ST_GeometryType(geom);
    factor double precision := percent::double precision / 200;
    i integer;
BEGIN
    IF percent < 0 OR percent > 100 THEN
        RAISE EXCEPTION 'Smoothing factor must be between 0 and 100';
    END IF;
    IF geomtype != 'ST_LineString' OR factor = 0 THEN
        RETURN geom;
    END IF;
    result := 'COMPOUNDCURVE((';
    p0 := ST_PointN(geom, 1);
    IF ST_NPoints(geom) = 2 THEN
        p1:= ST_PointN(geom, 2);
        result := result || ST_X(p0) || ' ' || ST_Y(p0) || ',' || ST_X(p1) || ' ' || ST_Y(p1) || '))';
    ELSE
        FOR i IN 2..(ST_NPoints(geom) - 1) LOOP
            p1 := ST_PointN(geom, i);
            p2 := ST_PointN(geom, i + 1);
            result := result || ST_X(p0) || ' ' || ST_Y(p0) || ',';
            tempp := ST_Line_Interpolate_Point(ST_MakeLine(p1, p0), factor);
            p0 := ST_Line_Interpolate_Point(ST_MakeLine(p1, p2), factor);
            intp := ST_Line_Interpolate_Point(
                ST_MakeLine(
                    ST_Line_Interpolate_Point(ST_MakeLine(p0, p1), 0.5),
                    ST_Line_Interpolate_Point(ST_MakeLine(tempp, p1), 0.5)
                ), 0.5);
            result := result || ST_X(tempp) || ' ' || ST_Y(tempp) || '),CIRCULARSTRING(' || ST_X(tempp) || ' ' || ST_Y(tempp) || ',' || ST_X(intp) || ' ' ||
            ST_Y(intp) || ',' || ST_X(p0) || ' ' || ST_Y(p0) || '),(';
        END LOOP;
        result := result || ST_X(p0) || ' ' || ST_Y(p0) || ',' || ST_X(p2) || ' ' || ST_Y(p2) || '))';
    END IF;
    RETURN ST_SetSRID(result::geometry, ST_SRID(geom));
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE;

चूंकि यह एक ज्यामिति प्रकार में घटता है, यदि आप इसे जीआईएस में उपयोग करना चाहते हैं जैसे कि क्यूजीआईएस, तो आपको इसे पोस्टजीआईएस कार्यों में लपेटना होगा जो उन्हें चारों ओर परिवर्तित कर रहे हैं। इच्छित उपयोग सिंटैक्स है:

SELECT ST_AsText(ST_CurveToLine(CreateCurve(geom))) AS geom FROM linestringtable;

यह एक जीवन रक्षक था! स्क्रिप्ट के लिए धन्यवाद। ऐसा लगता है कि चिकिन स्मूदी पोस्टगिस 2.5 के बाद से एक फ़ंक्शन के रूप में उपलब्ध हो जाएगी, जिसे मैं आगे देख रहा हूं।
she_weeds

1

यह अभी भी पोस्टजीआईएस (और अन्य जीआईएस टूल्स) में एक खुला मुद्दा है जैसा कि अध्याय 2.2.6 "घुमावदार ज्यामितीय" में "पोस्टजीआईएस इन एक्शन" पुस्तक में कहा गया है।

एल्गोरिदम और कोड के कुछ संदर्भ यहां दिए गए हैं:



0

आप अपने LineStrings साथ घटता में बदलने की कोशिश कर सकते हैं ST_LineToCurve साथ LineStrings वापस करने के लिए और फिर ST_CurveToLine

आप ST_CurveToLine में इच्छित प्रति वर्ग सर्कल की संख्या निर्धारित कर सकते हैं।


LineToCurve, CurveToLine के आउटपुट को सौंपने के लिए बनाया गया है, न कि मनमाने इनपुट से घटता निकालने के लिए।
पॉल रैमसे

अगले पोस्टगिस संस्करणों में @PaRRamsey bezier चौरसाई जोड़ा जाएगा? मैं उदाहरण के लिए कुछ इस तरह से सोच रहा हूँ: webhelp.esri.com/arcgisdesktop/9.2/…
Gery
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.