Biểu tượng đường ngoằn ngoèo trong QGIS


18

Tôi đang tìm kiếm một biểu tượng đường ngoằn ngoèo trong QGIS. Có lẽ có một cách dễ dàng để làm điều này mà tôi đang thiếu? Tôi đã thử tạo một đường đánh dấu bằng cách sử dụng một dấu tam giác đơn giản (^) và điều chỉnh kích thước của điểm đánh dấu và khoảng cách vị trí đánh dấu cho đến khi các đường kẻ chạm vào nhau và xuất hiện để tạo một đường ngoằn ngoèo đẹp. Điều này hoạt động cho các đường thẳng nhưng xung quanh các đường cong có những khoảng trống giữa các hình tam giác vì các hình tam giác không thực sự được kết nối. Có lẽ có một cách để tham gia đánh dấu với nhau? Hoặc một cách khác để đi về điều này? Tôi sẽ rất biết ơn cho bất kỳ đề nghị! (sử dụng QGIS 2.4.0) Cố gắng của tôi tại một đường ngoằn ngoèo

Câu trả lời:


11

Có vẻ như không có cách nào để chỉ tượng trưng cho đường kẻ ngoằn ngoèo: thật không may, bạn sẽ phải thay đổi dữ liệu cơ bản.

Bạn có thể có được một đường ngoằn ngoèo khá hợp lý bằng cách trước tiên chia dòng ban đầu thành nhiều phân đoạn dòng tương đương, sau đó bù đắp mọi điểm khác bằng một lượng cố định.

Đây là một kịch bản Python thực hiện điều này, lấy câu trả lời của NathanW về Làm cách nào tôi có thể tạo các điểm ngẫu nhiên dọc theo một đa tuyến trong QGIS? như một điểm khởi đầu. Lưu đoạn mã vào một tệp có tên zigzag.pytrong ~/.qgis/pythonthư mục của bạn (hoặc {User Directory}\.qgis\python\trên Windows), sau đó nhập nó vào bảng điều khiển PythonIS Python bằng cách nhập import zigzag. Sau đó, bạn có thể chọn một hoặc nhiều dòng mà bạn muốn zigzagify và nhập zigzag.createZigzag(<wavelength>, <amplitude>)vào bảng điều khiển Python của QGIS, trong đó <wavelength><amplitude>là "chiều dài" và "chiều rộng" của các đoạn ngoằn ngoèo, theo đơn vị bản đồ.

Đây là một ví dụ:

Như bạn có thể thấy, các đường zích zắc không đẹp lắm ở các góc của đường ban đầu, nhưng ít nhất thì đường ngoằn ngoèo không có bất kỳ ngắt.

Nếu bạn sử dụng đề xuất làm mịn dòng của James Conkling trước bằng cách sử dụng Thuật toán của Chaiken, kết quả sẽ đẹp hơn nhiều:


Đây là kịch bản:

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)

Giải pháp nổi bật! Câu hỏi duy nhất còn lại của tôi là nếu thuật toán này có thể được áp dụng trên polylines.
Gabor Farkas

1
@GaborFarkas: Ví dụ sử dụng đa tuyến. Bạn có thể có nghĩa là một lớp có chứa một số polylines rời rạc (một đa tuyến)? Điều đó cũng làm việc.
Jake

3

Tôi đã thử làm điều này trước đây và không gặp nhiều may mắn.

qGIS đặt các ký hiệu lặp lại trên một dòng dựa trên một điểm tham chiếu (theo mặc định là tâm, mặc dù bạn có thể đặt nó thành đỉnh / giữa / dưới x trái / giữa / phải) và xoay biểu tượng đó dựa trên độ dốc của đường tại điểm đó. Trên một đường thẳng, nơi độ dốc không thay đổi từ vị trí một biểu tượng sang vị trí tiếp theo, mỗi biểu tượng sẽ xếp hàng hoàn hảo với vị trí trước đó. Tuy nhiên, trên một đường cong, không có điểm nào trên một biểu tượng sẽ khớp hoàn hảo với điểm tương ứng trên biểu tượng tiếp theo.

biểu tượng đánh dấu lặp đi lặp lại trong qGIS

Vì vậy, nếu đường màu đỏ là chính đường đó, việc lặp lại một biểu tượng dọc theo đường đó dẫn đến khoảng cách giữa các biểu tượng dọc bên ngoài đường cong và chồng chéo lên bên trong đường cong.

Để loại bỏ hoàn toàn các khoảng trống và chồng lấp, mỗi ô vuông biểu tượng sẽ cần được định hình lại thành hình thoi có kích thước khác nhau - tương tự như cách các viên đá trên vòm được vát để khớp với đường cong. Theo như tôi biết, không thể mô phỏng thứ gì đó như thế. Tuy nhiên, bạn có thể giảm độ méo bằng cách tăng cường và làm mịn hình dạng đường thẳng của mình để thay đổi góc ít hơn. Các Plugin generalizer có thể giúp với điều đó (hãy thử sử dụng nó với thuật toán chương trình Chaiken của).

biểu tượng đánh dấu lặp lại được làm mịn trong qGIS

Ngoài ra, chia biểu tượng của bạn thành các phân đoạn nhỏ hơn và đặt từng phân đoạn liên tiếp, để một lần nữa bạn giảm góc giữa mỗi điểm đánh dấu tiếp theo, sẽ giúp ích. Ví dụ: chia Vbiểu tượng của bạn thành a \và a /, tải cả trên dòng đánh dấu và cho mỗi điểm, đặt độ lệch x bằng một nửa chiều rộng của chúng, dương cho một và âm cho cái kia.

Cuối cùng, một nét biểu tượng dày hơn một chút với các đầu tròn sẽ giúp che đi sự biến dạng nhẹ.

Đây vẫn là một chút hack - rất thích nghe nếu có ai có cách tiếp cận đáng tin cậy hơn.

Biên tập:

Một suy nghĩ khác: sự sai lệch từ biểu tượng này sang biểu tượng khác gây ra bởi sự quay của biểu tượng dọc theo đường cong là lớn nhất ở trên cùng / dưới cùng của biểu tượng, nhưng ít được phát âm ở giữa. Vì vậy, một mẫu bắt đầu và kết thúc tại trung tâm biểu tượng sẽ có những khoảng trống nhỏ hơn một mẫu bắt đầu / kết thúc ở trên cùng / dưới cùng. Ví dụ

ngoằn ngoèo

... vẫn là hack - vẫn không thể đánh lừa


1

Tôi không nghĩ rằng đây là một tính năng trong QGIS. Tuy nhiên tôi sẽ cố gắng làm theo cách này:

  1. tạo hai bản sao của lớp bằng cách sử dụng plugin công cụ Affine. Một trong các lớp có tỷ lệ lớn hơn một chút và một lớp có tỷ lệ nhỏ hơn một chút.

  2. Mật độ hình học của các lớp. Điều đó có nghĩa là thêm nhiều nút hơn.

  3. Chuyển đến bảng thuộc tính và đặt tên cho mỗi nút tính năng là 1,2,3, ... trong một lớp và 1b, 2b, 3b, ... trong lớp thứ hai.

  4. hợp nhất cả hai lớp và sắp xếp lớp thuộc tính -> điều này sẽ cung cấp cho bạn một đường ngoằn ngoèo.

Có lẽ điều này hoạt động.


1
Cảm ơn câu trả lời! Tuy nhiên, tôi không nghĩ rằng nó sẽ hoạt động ngoại trừ các trường hợp rất cụ thể như một vòng cung tròn với các đỉnh cách đều nhau, nếu không, bạn sẽ kết thúc với một đường ngoằn ngoèo không đều (do tỷ lệ và do mật độ hóa).
Jake
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.