วิธีการทำให้เส้น SIA หรือ Bezier เป็นไปอย่างราบรื่นใน PostGIS


9

ทุกคนสามารถให้ SQL ตัวอย่างสำหรับการปรับให้เรียบ linestrings จากตาราง postgis โดยใช้ Bezier curves หรืออัลกอริทึมIterative Averaging ( SIA )

คำตอบ:


6

ฉันสร้างสคริปต์ขนาดเล็กที่ไร้เดียงสาซึ่งแปลง LineStrings อินพุตไปเป็น CompoundCurves โดยอิงตามฮิวริสติกบางอย่าง

มันทำอะไร:

  • ตัดมุมที่คมชัดเพื่อสร้างผลลัพธ์ที่ดึงดูดสายตามากกว่าข้อมูลดั้งเดิม
  • ใช้ plpgsql ไม่จำเป็นต้องมีส่วนขยายเพิ่มเติม
  • ยอมรับตัวเลือก "ปัจจัยการปรับให้เรียบ" ระหว่าง 0 ถึง 100 นอกเหนือจากรูปทรงเรขาคณิต

มันไม่ได้ทำอะไร:

  • ประมวลผล MultiLineStrings สำหรับรูปแบบเรขาคณิตอื่น ๆ เพียงแค่คืนค่าอินพุต
  • ใช้ค่า Z และ M มันเพียงแค่ปล่อยพวกเขา ใช้สิ่งนี้เพื่อการทำแผนที่สองมิติเท่านั้น
  • สร้างผลลัพธ์ที่ถูกต้องทางคณิตศาสตร์ ผลลัพธ์ยังห่างไกลจากความถูกต้องและอาจไม่ชัดเจนในบางกรณี (เช่นมุมที่คมชัด) ฉันไม่ได้ทดสอบอย่างละเอียด ตรวจสอบผลลัพธ์เสมอ!
  • วิ่งเร็ว ฉันแน่ใจว่ามันสามารถเขียนใหม่ในรูปแบบที่เหมาะสมที่สุด
  • เรียบจริงหรือไม่ มีอัลกอริทึมที่ดีกว่ามาก (เช่น Chaiken หรือที่กล่าวถึงในคำถาม) เพื่อใช้สำหรับการปรับให้เรียบจริง คำตอบนี้กำหนดเป้าหมายให้คนอย่างฉันค้นหาวิธีการ PostGIS ที่บริสุทธิ์โดยอัตโนมัติสร้างเส้นโค้งบางประเภทจากข้อมูลจริง

สคริปต์:

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;

ในขณะที่มันคืนค่าเส้นโค้งในรูปทรงเรขาคณิตหากคุณต้องการใช้ใน GIS เช่น QGIS คุณจะต้องห่อมันไว้ในฟังก์ชัน PostGIS เพื่อแปลงมัน ไวยากรณ์การใช้งานที่ต้องการคือ:

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

นี่คือผู้ช่วยชีวิต! ขอบคุณสำหรับสคริปต์ ดูเหมือนว่าการปรับเรียบของ Chaikin จะสามารถใช้งานได้ตั้งแต่ฟังก์ชั่น postgis 2.5 เป็นต้นไปซึ่งฉันตั้งตารอคอย
she_weeds

1

นี่ยังคงเป็นปัญหาที่เปิดกว้างใน PostGIS (และเครื่องมือ GIS อื่น ๆ ) ตามที่ระบุไว้ในหนังสือ "PostGIS in Action" ในบทที่ 2.2.6 "รูปทรงโค้ง"

นี่คือการอ้างอิงถึงอัลกอริทึมและรหัส:


ฉันเพิ่มpostgis.17.x6 ... ลิงก์
Martin F

0

คุณสามารถพยายามที่จะแปลง LineStrings ของคุณเพื่อโค้งด้วยST_LineToCurveแล้วกลับไป LineStrings กับST_CurveToLine

คุณสามารถตั้งค่าจำนวนเซ็กเมนต์ต่อวงกลมควอเตอร์ที่คุณต้องการใน ST_CurveToLine


LineToCurve ถูกสร้างขึ้นเพื่อส่งผลลัพธ์ของ CurveToLine ไม่ใช่เพื่อแยกส่วนโค้งจากอินพุตที่กำหนดเอง
Paul Ramsey

@PaulRamsey จะถูกปรับให้เรียบยิ่งขึ้นใน Postgis รุ่นถัดไปหรือไม่ ฉันเคยคิดเกี่ยวกับสิ่งนี้เช่น: webhelp.esri.com/arcgisdesktop/9.2/…
Gery
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.