สัญลักษณ์เส้นคดเคี้ยวไปมาใน QGIS


18

ฉันกำลังมองหาสัญลักษณ์เส้นซิกแซกใน QGIS อาจมีวิธีง่ายๆในการทำสิ่งนี้ที่ฉันขาดหายไปหรือไม่? ฉันได้ลองสร้างบรรทัดมาร์กเกอร์โดยใช้เครื่องหมายสามเหลี่ยมแบบง่าย (^) และปรับขนาดของเครื่องหมายและช่วงเวลาการจัดตำแหน่งของเครื่องหมายจนกระทั่งแทร็กเดิลได้สัมผัสกันและปรากฏเป็นเส้นซิกแซกที่สวยงาม มันใช้งานได้กับเส้นตรง แต่รอบ ๆ เส้นโค้งมีช่องว่างระหว่างสามเหลี่ยมเพราะสามเหลี่ยมไม่ได้เชื่อมต่อกัน อาจมีวิธีเข้าร่วมเครื่องหมายด้วยกันไหม หรือวิธีอื่นที่จะไปเกี่ยวกับเรื่องนี้? ฉันจะขอบคุณมากสำหรับคำแนะนำใด ๆ ! (ใช้ QGIS 2.4.0) ความพยายามของฉันที่เส้นซิกแซก

คำตอบ:


11

ดูเหมือนว่าไม่มีวิธีใดที่จะเป็นสัญลักษณ์ของเส้นซิกแซก แต่น่าเสียดายที่คุณจะต้องแก้ไขข้อมูลพื้นฐาน

คุณสามารถได้รับเส้นซิกแซกที่ดีพอสมควรโดยแยกสายแรกออกเป็นส่วนของเส้นที่มีระยะเท่ากันจำนวนมากก่อนแล้วจึงชดเชยจุดอื่น ๆ ด้วยจำนวนคงที่

นี่คือสคริปต์ Python ที่ทำสิ่งนี้โดยรับคำตอบของ NathanW ไปที่ฉันจะสร้างจุดสุ่มตามแนวหลายเหลี่ยมใน QGIS ได้อย่างไร เป็นจุดเริ่มต้น บันทึกก้อนรหัสลงในไฟล์ที่เรียกว่าzigzag.pyของคุณใน~/.qgis/pythonไดเรกทอรี (หรือ{User Directory}\.qgis\python\บน Windows) แล้วนำเข้าในคอนโซล QGIS import zigzagหลามโดยการพิมพ์ จากนั้นคุณสามารถเลือกหนึ่งบรรทัดหรือมากกว่านั้นที่คุณต้องการซิกแซกซิกส์และพิมพ์zigzag.createZigzag(<wavelength>, <amplitude>)ในคอนโซล QGIS Python ที่ใด<wavelength>และ<amplitude>เป็น "ความยาว" และ "ความกว้าง" ของส่วนซิกแซกในหน่วยแผนที่

นี่คือตัวอย่าง:

อย่างที่คุณเห็นซิกแซกไม่ค่อยดีใกล้กับมุมบรรทัดเดิม แต่อย่างน้อยบรรทัดซิกแซกไม่มีตัวแบ่งใด ๆ

หากคุณใช้ข้อเสนอแนะของ James Conkling ในการทำให้เส้นเรียบก่อนโดยใช้ Algorithm ของ Chaiken ผลลัพธ์จะดีขึ้นมาก:


นี่คือสคริปต์:

from qgis.utils import iface
from qgis.core import *
import numpy as np
from cmath import rect, phase


# Function for calculating the mean of two angles.
# Based on http://rosettacode.org/wiki/Averages/Mean_angle#Python
def meanAngle(a1, a2):
    return phase((rect(1, a1) + rect(1, a2)) / 2.0)


def createZigzag(wavelength, amplitude):
    # Create a new memory layer to store the zigzag line.
    vl = QgsVectorLayer("LineString", "Zigzag", "memory")
    pr = vl.dataProvider()

    # For each selected object in the current layer
    layer = iface.mapCanvas().currentLayer()
    for feature in layer.selectedFeatures():
        geom = feature.geometry()

        # Number of zigzag segments
        length = geom.length()
        segments = np.round(length / wavelength)

        # Find equally spaced points that approximate the line
        points = [geom.interpolate(distance).asPoint() for
            distance in np.linspace(0, length, segments)]

        # Calculate the azimuths of the approximating line segments
        azimuths = np.radians(
            [points[i].azimuth(points[i + 1]) for i in range(len(points) - 1)])

        # Average consecutive azimuths and rotate 90 deg counterclockwise
        zigzagazimuths = [azimuths[0] - np.pi / 2]
        zigzagazimuths.extend([meanAngle(azimuths[i],
            azimuths[i - 1]) - np.pi / 2 for i in range(len(points) - 1)]
        )
        zigzagazimuths.append(azimuths[-1] - np.pi / 2)

        # Offset the points along the zigzagazimuths
        zigzagpoints = []
        for i in range(len(points)):
            # Alternate the sign
            dst = amplitude * (1 - 2 * np.mod(i, 2))
            zigzagpoints.append(
                QgsPoint(points[i][0] + np.sin(zigzagazimuths[i]) * dst,
                    points[i][1] + np.cos(zigzagazimuths[i]) * dst
                )
            )

        # Create new feature from the list of zigzag points
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPolyline(zigzagpoints))

        pr.addFeatures([fet])
        vl.updateExtents()

    QgsMapLayerRegistry.instance().addMapLayer(vl)

ทางออกที่โดดเด่น! เหลือคำถามเดียวของฉันคือถ้าอัลกอริทึมนี้สามารถใช้กับ polylines
Gabor Farkas

1
@GaborFarkas: ตัวอย่างนี้ใช้ polyline คุณอาจหมายถึงชั้นที่มีโพลีลีนไม่ต่อเนื่องหลายเส้น (หลายเส้น) ที่ได้ผลเช่นกัน
Jake

3

ฉันเคยลองทำแบบนี้มาก่อนและโชคไม่ดี

qGIS วางสัญลักษณ์ซ้ำ ๆ บนบรรทัดตามจุดอ้างอิงหนึ่งจุด (โดยค่าเริ่มต้นกึ่งกลางแม้ว่าคุณสามารถตั้งค่าไว้ที่ด้านบน / กลาง / ล่าง x ซ้าย / กลาง / ขวา) และหมุนสัญลักษณ์นั้นตามความชันของบรรทัดที่ จุดนั้น ในแนวเส้นตรงที่ความลาดเอียงไม่ได้เปลี่ยนจากตำแหน่งสัญลักษณ์หนึ่งเป็นอีกสัญลักษณ์หนึ่งแต่ละสัญลักษณ์จะเรียงกันอย่างสมบูรณ์แบบกับตำแหน่งก่อนหน้า บนโค้ง แต่ไม่มีจุดบนสัญลักษณ์ใดสัญลักษณ์หนึ่งจะจับคู่จุดที่สอดคล้องกันบนสัญลักษณ์ถัดไปได้อย่างสมบูรณ์แบบ

สัญลักษณ์มาร์กเกอร์ซ้ำใน qGIS

ดังนั้นหากเส้นสีแดงคือเส้นนั้นการทำสัญลักษณ์ซ้ำตามแนวนั้นจะส่งผลให้เกิดช่องว่างระหว่างสัญลักษณ์ที่อยู่ด้านนอกของเส้นโค้งและทับซ้อนกันภายในด้านในของเส้นโค้ง

เพื่อกำจัดช่องว่างและทับซ้อนกันอย่างสมบูรณ์สี่เหลี่ยมจตุรัสทุกสัญลักษณ์จะต้องได้รับการปรับแต่งใหม่ให้เป็นรูปสี่เหลี่ยมขนมเปียกปูนที่มีขนาดแตกต่างกัน - คล้ายกับวิธีที่หินบนโค้งถูกยกนูนให้ตรงกับส่วนโค้ง เท่าที่ฉันรู้มันเป็นไปไม่ได้ที่จะจำลองอะไรแบบนั้น แต่คุณสามารถลดการบิดเบือนได้โดยทำให้เรขาคณิตเส้นตรงของคุณหนาแน่นและราบเรียบเพื่อให้การเปลี่ยนแปลงของมุมมีความรุนแรงน้อยลง ปลั๊กอิน generalizerความช่วยเหลือสามารถมีว่า (ลองใช้กับอัลกอริทึมของ Chaiken)

สัญลักษณ์มาร์กเกอร์ที่ราบรื่นใน qGIS

นอกจากนี้การแบ่งสัญลักษณ์ของคุณออกเป็นส่วนย่อย ๆ และวางแต่ละจุดอย่างต่อเนื่องเพื่อให้คุณลดมุมระหว่างเครื่องหมายที่ตามมาแต่ละอันอีกครั้งจะช่วยได้ ตัวอย่างเช่นแบ่งVสัญลักษณ์ของคุณเป็น a \และ a /, โหลดทั้งสองบนบรรทัดของ marker และสำหรับแต่ละอันให้ตั้งค่า x-offset เท่ากับครึ่งหนึ่งของความกว้างของพวกมันบวกสำหรับหนึ่งและลบสำหรับอีกอัน

สุดท้ายสัญลักษณ์รูปสัญลักษณ์ที่หนาขึ้นเล็กน้อยที่มีปลายโค้งมนจะช่วยปกปิดความผิดเพี้ยนเล็กน้อย

นี่ยังเป็นการแฮ็กอยู่เล็กน้อย - ชอบที่จะได้ยินถ้าใครมีวิธีการที่เชื่อถือได้มากกว่า

แก้ไข:

ความคิดอื่น: การเยื้องศูนย์จากสัญลักษณ์หนึ่งไปยังอีกอันเกิดจากการหมุนของสัญลักษณ์ตามแนวโค้งนั้นยิ่งใหญ่ที่สุดที่ด้านบน / ล่างของสัญลักษณ์ แต่เด่นชัดน้อยกว่าตรงกลาง ดังนั้นรูปแบบที่เริ่มต้นและสิ้นสุดที่ศูนย์สัญลักษณ์จะมีช่องว่างขนาดเล็กกว่ารูปแบบที่เริ่มต้น / สิ้นสุดที่ด้านบน / ล่าง เช่น

คดเคี้ยวไปมา

... ยังเป็นแฮ็ก - ยังไม่ผิดพลาด


1

ฉันไม่คิดว่านี่เป็นคุณสมบัติใน QGIS อย่างไรก็ตามฉันจะพยายามทำเช่นนี้:

  1. ทำสำเนาเลเยอร์สองชุดโดยใช้ปลั๊กอินเครื่องมือ Affine หนึ่งในชั้นที่มีขนาดใหญ่กว่าเล็กน้อยและอีกหนึ่งชั้นที่มีขนาดเล็กกว่าเล็กน้อย

  2. ทำให้เรขาคณิตของเลเยอร์หนาแน่นขึ้น นั่นหมายถึงเพิ่มโหนดเพิ่มเติม

  3. ไปที่ตารางแอ็ตทริบิวต์และตั้งชื่อโหนดแต่ละคุณลักษณะตามลำดับที่ 1,2,3, ... ในชั้นหนึ่งและ 1b, 2b, 3b, ... ในชั้นที่สอง

  4. ผสานทั้งเลเยอร์แล้วเรียงลำดับเลเยอร์ของแอททริบิวต์ -> นี่ควรจะให้คุณมีเส้นซิกแซก

อาจใช้งานได้


1
ขอบคุณสำหรับคำตอบ! อย่างไรก็ตามฉันไม่คิดว่ามันจะทำงานได้ยกเว้นกรณีที่เฉพาะเจาะจงมาก ๆ เช่นส่วนโค้งวงกลมที่มีจุดยอดเท่า ๆ กันไม่งั้นคุณจะจบด้วยเส้นซิกแซกที่ไม่สม่ำเสมอ (เนื่องจากการขยายและเนื่องจากความหนาแน่น)
Jake
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.