QGISのジグザグ線記号


18

QGISでジグザグラインシンボルを探しています。これを行う簡単な方法はおそらくありませんか?シンプルな三角形のマーカー(^)を使用してマーカーラインを作成し、トレーンが互いに触れてジグザグの線を作るように見えるまで、マーカーのサイズとマーカーの配置間隔を調整してみました。これは直線に対しては機能しますが、曲線は三角形の間に実際には接続されていないため、三角形の間に隙間があります。マーカーを結合する方法はおそらくありますか?またはこれについて別の方法を使用しますか?どんな提案にも感謝します!(QGIS 2.4.0を使用) ジグザグ線での私の試み

回答:


11

線をジグザグとして記号化する方法はないようです。残念ながら、基礎となるデータを変更する必要があります。

最初に元の線を多くの等距離線分に分割し、次に一定量だけ他のすべての点をオフセットすることにより、かなり良いジグザグ線を得ることができます。

これを行うPythonスクリプトを次に示します。QGISのポリラインに沿ってランダムポイントを作成するにはどうすればよいかに対するNathanWの回答を参考にしてください出発点として。ファイルにコードチャンクを保存しzigzag.py、あなたの中に~/.qgis/python(またはディレクトリ{User Directory}\.qgis\python\Windowsの場合)、その後、次のように入力してQGIS Pythonのコンソールでそれをインポートしますimport zigzag。次に、ジグザグにしたい1つ以上の行を選択zigzag.createZigzag(<wavelength>, <amplitude>)し、QGIS Pythonコンソールに入力します。ここで<wavelength>および<amplitude>は、ジグザグセグメントの「長さ」と「幅」をマップ単位で入力します。

以下に例を示します。

ご覧のとおり、ジグザグは元の線の角の近くではあまり良くありませんが、少なくともジグザグ線には切れ目がありません。

最初にChaikenのアルゴリズムを使用して線を平滑化するというJames Conklingの提案を使用すると、結果はより良くなります。


スクリプトは次のとおりです。

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)

優れたソリューション!残っている私の唯一の質問は、このアルゴリズムをポリラインに適用できるかどうかです。
ガボールファーカス14年

1
@GaborFarkas:この例ではポリラインを使用しています。おそらく、いくつかのばらばらのポリライン(マルチポリライン)を含むレイヤーを意味しますか?それも機能します。
ジェイク14年

3

私はこれを以前にやろうとしたことがあり、あまり運がありませんでした。

qGISは、1つの基準点(デフォルトでは中央、上/中/下x左/中央/右に設定できます)に基づいて、繰り返されるシンボルをラインに配置し、ラインの傾斜に基づいてそのシンボルを回転させますその点。シンボルの配置ごとに勾配が変わらない直線では、各シンボルは前の配置と完全に揃います。ただし、曲線上では、あるシンボルのポイントが次のシンボルの対応するポイントと完全に一致することはありません。

qGISで繰り返されるマーカーシンボル

そのため、赤い線が線そのものである場合、その線に沿ってシンボルを繰り返すと、曲線の外側に沿ってシンボル間のギャップが生じ、曲線の内側に重なります。

ギャップとオーバーラップを完全に排除するには、すべてのシンボルスクエアをさまざまなサイズの菱形に再形成する必要があります。これは、アーチの石が曲線に一致するように斜角を付ける方法に似ています。私の知る限り、そのようなものをシミュレートすることはできません。ただし、ラインジオメトリを高密度化およびスムージングして、角度の変化が極端に少なくなるようにすることで、歪みを減らすことができます。generalizerプラグインは(Chaikenのアルゴリズムでそれを使ってみてください)それを支援することができます。

qGISの平滑化されたリピーターマーカーシンボル

また、シンボルを小さなセグメントに分割し、それぞれを連続して配置することで、後続の各マーカー間の角度を再び小さくすることが役立ちます。たとえば、Vシンボルをa \とa /に分割し、マーカーラインの両方にロードし、それぞれの幅の半分に等しいxオフセットを設定し、一方を正、他方を負に設定します。

最後に、丸みを帯びた端を持つわずかに太いシンボルストロークは、わずかな歪みを隠すのに役立ちます。

これはまだちょっとしたハックです。他の誰かがより信頼性の高いアプローチを持っているなら、ぜひ聞いてみてください。

編集:

別の考え:曲線に沿ったシンボルの回転によって引き起こされるあるシンボルから別のシンボルへの不整列は、シンボルの上部/下部で最大ですが、中央ではそれほど顕著ではありません。そのため、シンボルの中心で開始および終了するパターンは、上部/下部で開始/終了するパターンよりも小さなギャップがあります。例えば

ジグザグ

...まだハック-だまされない


1

これがQGISの機能だとは思いません。しかし、私はそれを次のようにしようとします:

  1. Affineツールプラグインを使用して、レイヤーの2つのコピーを作成します。わずかに大きなスケールを持つレイヤーと、わずかに小さなスケールを持つレイヤー。

  2. レイヤーのジオメトリを高密度化します。つまり、ノードをさらに追加します。

  3. 属性テーブルに移動し、各フィーチャノードに1つ目のレイヤーで1、2、3、...、2つ目のレイヤーで1b、2b、3b、...という名前を付けます。

  4. 両方のレイヤーをマージし、属性レイヤーを並べ替えます->これにより、ジグザグの線が表示されます。

たぶんこれは動作します。


1
答えてくれてありがとう!ただし、等距離の頂点を持つ円弧のような非常に特殊な場合を除いて、これは機能しないと思います。
ジェイク14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.