QGIS zikzak çizgi sembolü


18

QGIS'te zikzak çizgi sembolü arıyorum. Bunu yapmanın belki kolay bir yolu yok mu? Basit bir üçgen işaretleyici (^) kullanarak bir işaretleyici çizgi oluşturmayı denedim ve traingles birbirlerine dokundu ve güzel bir zikzak çizgi yapmak için ortaya çıkana kadar işaretleyici ve işaretleyici yerleştirme aralığını ayarlamayı denedim. Bu düz çizgiler için geçerlidir, ancak eğrilerin etrafında üçgenler arasında boşluklar vardır, çünkü üçgenler aslında bağlı değildir. İşaretçileri bir araya getirmenin belki bir yolu var mı? Ya da bununla ilgili başka bir yol mu? Herhangi bir öneri için çok minnettar olurum! (QGIS 2.4.0 kullanarak) Bir zikzak çizgisindeki girişimim

Yanıtlar:


11

Görünüşe göre çizgiyi bir zikzak olarak sembolize etmenin bir yolu yok: maalesef, alttaki verileri değiştirmeniz gerekecek.

İlk önce orijinal çizgiyi birçok eşit uzaklıktaki çizgi segmentine bölerek ve sonra diğer her noktayı sabit bir miktarda dengeleyerek makul derecede iyi bir zikzak çizgisi elde edebilirsiniz.

İşte bunu yapan bir Python betiği, NathanW'nin QGIS'de bir çoklu çizgi boyunca nasıl rastgele noktalar oluşturabilirim? başlangıç ​​noktası olarak. Kod yığınını dizininizde (veya Windows'da) adlandırılan bir dosyaya zigzag.pykaydedin ve ardından yazarak QGIS Python konsoluna alın . Sonra sen zigzagify istediğiniz bir veya daha fazla çizgi seçin ve yazabilirsiniz QGIS Python konsolu içinde ve harita birimlerinde, zikzak segmentlerinin "uzunluk" ve "genişlik" dir.~/.qgis/python{User Directory}\.qgis\python\import zigzagzigzag.createZigzag(<wavelength>, <amplitude>)<wavelength><amplitude>

İşte bir örnek:

Gördüğünüz gibi, zikzaklar orijinal çizginin köşelerinde çok hoş değil, ama en azından zikzak çizgisinde herhangi bir kopukluk yok.

James Conkling'in önce Chaiken'in Algoritmasını kullanarak çizgiyi yumuşatma önerisini kullanırsanız, sonuç çok daha güzel olur:


İşte senaryo:

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)

Olağanüstü çözüm! Geriye kalan tek sorum bu algoritmanın çoklu hatlara uygulanıp uygulanamayacağı.
Gabor Farkas

1
@GaborFarkas: Örnek bir çoklu çizgi kullanır. Belki de birkaç ayrık polinlin (çok-çoklu) içeren bir tabaka mu demek istediniz? Bu da işe yarıyor.
Jake

3

Bunu daha önce yapmaya çalıştım ve çok şansım olmadı.

qGIS, bir referans noktasına dayalı olarak tekrarlanan sembolleri bir satıra yerleştirir (varsayılan olarak merkez, üst / orta / alt x sol / orta / sağ olarak ayarlayabilirsiniz) ve bu sembolü, çizginin eğimine göre döndürür. o nokta. Eğimin bir sembol yerleşiminden diğerine değişmediği düz bir çizgide, her sembol bir öncekiyle mükemmel şekilde hizalanacaktır. Bununla birlikte, bir eğride, bir sembol üzerindeki hiçbir nokta, bir sonraki sembol üzerindeki karşılık gelen noktaya mükemmel şekilde uymayacaktır.

qGIS'de tekrarlanan işaretleyici simgesi

Dolayısıyla, kırmızı çizgi çizginin kendisiyse, bu çizgi boyunca bir sembolün tekrarlanması bir eğrinin dışındaki semboller arasında boşluklarla sonuçlanır ve bir eğrinin içinde çakışır.

Boşlukları ve örtüşmeleri tamamen ortadan kaldırmak için, her sembol karesinin, farklı büyüklükteki bir eşkenar dörtgen olarak yeniden şekillendirilmesi gerekir - bir kemer üzerindeki taşların eğriye uyacak şekilde nasıl eğildiğine benzer. Bildiğim kadarıyla böyle bir şeyi simüle etmek mümkün değil. Ancak, çizgi geometrisinizi yoğunlaştırarak ve düzleştirerek deformasyonu azaltabilirsiniz, böylece açıdaki değişiklik daha az aşırı olur. Generalizer eklentisi (Chaiken algoritması ile kullanmayı deneyin) bu konuda yardımcı olabilir.

qGIS'de düzeltici tekrarlayıcı işaret simgesi

Ayrıca, sembolünüzü daha küçük bölümlere ayırmak ve her birini art arda yerleştirmek, böylece sonraki her işaretçi arasındaki açıyı tekrar azaltmak yardımcı olacaktır. Örneğin, Vsembolünüzü a \ve a'ya ayırın, /hem işaret çizgisine hem de her birine yükleyin, genişliklerinin yarısına eşit, biri için pozitif ve diğeri için negatif bir x-ofseti ayarlayın.

Son olarak, yuvarlak uçları olan biraz daha kalın bir sembol darbesi, hafif bozulmanın maskelenmesine yardımcı olacaktır.

Bu hala bir kesmek - başka birisinin daha güvenilir bir yaklaşımı varsa duymak isterim.

Düzenle:

başka bir düşünce: sembolün eğri boyunca dönmesinden kaynaklanan bir sembolden diğerine yanlış hizalama, sembolün üst / alt kısmında en büyüktür, ancak ortada daha az belirgindir. Dolayısıyla, sembol merkezinde başlayan ve sona eren bir desen, üstte / altta başlayan / sona eren bir desenden daha küçük boşluklara sahip olacaktır. Örneğin

zikzaklı

... hala bir hack - hala kusursuz değil


1

Bunun QGIS'te bir özellik olduğunu düşünmüyorum. Ancak ben bu şekilde yapmaya çalışacağız:

  1. Affine aracı eklentisini kullanarak katmanın iki kopyasını oluşturun. Biri biraz daha büyük ölçekli, diğeri biraz daha küçük ölçekli.

  2. Katmanların geometrisini yoğunlaştırın. Bu, daha fazla düğüm eklemek anlamına gelir.

  3. Öznitelik tablosuna gidin ve her bir özellik düğümünü sonuç olarak bir katmanda 1,2,3, ... ve ikinci katmanda 1b, 2b, 3b, ... olarak adlandırın.

  4. her iki katmanı birleştirin ve nitelik katmanını sıralayın -> bu size bir zikzak çizgisi vermelidir.

Belki de işe yarar.


1
Cevap için teşekkürler! Ancak, bunun eşit köşeleri olan dairesel bir yay gibi çok özel durumlar dışında işe yarayacağını düşünmüyorum, aksi takdirde düzensiz bir zikzak çizgisi (ölçekleme ve yoğunlaşma nedeniyle) ile sonuçlanacaksınız.
Jake
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.