Símbolo de línea en zigzag en QGIS

18

Estoy buscando un símbolo de línea en zigzag en QGIS. ¿Hay tal vez una forma fácil de hacer esto que me estoy perdiendo? He intentado crear una línea de marcador utilizando un marcador de triángulo simple (^) y ajustando el tamaño del marcador y el intervalo de colocación del marcador hasta que los traingles se tocaran y parecían hacer una buena línea en zigzag. Esto funciona para líneas rectas, pero alrededor de las curvas hay espacios entre los triángulos porque los triángulos no están realmente conectados. ¿Hay tal vez una forma de unir los marcadores? ¿O otra forma de hacer esto? ¡Estaría muy agradecido por cualquier sugerencia! (utilizando QGIS 2.4.0)

    
pregunta Joanna McMillan 16.10.2014 - 11:50

3 respuestas

11

Parece que no hay forma de simplemente simbolizar la línea como un zigzag: desafortunadamente, tendrás que alterar los datos subyacentes.

Puede obtener una línea en zigzag razonablemente buena dividiendo primero la línea original en muchos segmentos de línea equidistantes, y luego compensando cada otro punto con una cantidad fija.

Aquí hay un script de Python que hace esto, tomando la respuesta de NathanW a ¿Cómo puedo crear puntos aleatorios a lo largo de una polilínea en QGIS? como punto de partida. Guarde el fragmento de código en un archivo llamado zigzag.py en su directorio ~/.qgis/python (o {User Directory}\.qgis\python\ en Windows), y luego impórtelo en la consola QGIS Python escribiendo import zigzag . Luego, puede seleccionar una o más líneas que desee zigzagificar, y escribir zigzag.createZigzag(<wavelength>, <amplitude>) en la consola QGIS Python, donde <wavelength> y <amplitude> son la "longitud" y el "ancho" de los segmentos de zigzag, en unidades de mapa .

Aquí hay un ejemplo:

Comosepuedever,loszigzagsnosonmuyagradablescercadelasesquinasdelalíneaoriginal,peroalmenoslalíneadezigzagnotienesaltos.

SiutilizaslasugerenciadeJamesConklingdesuavizarlalíneaprimeroutilizandoelalgoritmodeChaiken,elresultadoesmuchomásagradable:

Aquí está el script:

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)
    
respondido por el Jake 20.10.2014 - 21:16
3

He intentado hacer esto antes y no he tenido mucha suerte.

qGIS coloca símbolos repetidos en una línea basándose en un punto de referencia (por defecto, el centro, aunque puede configurarlo en la parte superior / media / inferior x izquierda / central / derecha), y gira ese símbolo según la pendiente de la línea en ese punto. En una línea recta, donde la pendiente no cambia de una ubicación de símbolo a la siguiente, cada símbolo se alineará perfectamente con el anterior. Sin embargo, en una curva, ningún punto en un símbolo coincidirá perfectamente con el punto correspondiente en el siguiente símbolo.

Entonces,silalínearojaeslalíneaensímisma,repetirunsímboloalolargodeesalíneaproduceespaciosentrelossímbolosalolargodelexteriordeunacurvaysesuperponeenelinteriordeunacurva.

Paraeliminarcompletamenteloshuecosylassuperposiciones,cadacuadradodesímbolodeberíaserremodeladocomounrombodetamañovariable,similaralaformaenquesebiselanlaspiedrasenunarcoparaquecoincidanconlacurva.Queyosepa,noesposiblesimularalgoasí.Sinembargo,puededisminuirladistorsiónaldensificarysuavizarlageometríadesulíneaparaqueelcambiodeánguloseamenosextremo.El complemento generalizador puede ayudar con eso (intente usarlo con el algoritmo de Chaiken).

Además,dividirsusímboloensegmentosmáspequeñosycolocarcadaunoensucesión,demodoquenuevamentedisminuyaelánguloentrecadamarcadorsubsiguiente,ayudaría.Porejemplo,dividasusímboloVenun\yun/,cargueambosenlalíneamarcadoray,paracadauno,establezcaundesplazamientoxigualalamitaddesuancho,positivoparaunoynegativoparaelotro.

Porúltimo,untrazodesímbololigeramentemásgruesoconextremosredondeadosayudaríaaenmascararlaligeradistorsión.

Estotodavíaesunpocopirateado,meencantaríasabersialguienmástieneunenfoquemásconfiable.

Editar:

otropensamiento:ladesalineacióndeunsímboloaotrocausadaporlarotacióndelsímboloalolargodelacurvaesmayorenlapartesuperior/inferiordelsímbolo,peromenospronunciadaenelcentro.Porlotanto,unpatrónquecomienzayterminaenelcentrodelsímbolotendráespaciosmáspequeñosqueunpatrónquecomienza/terminaenlapartesuperior/inferior.Porejemplo,

... sigue siendo un truco, todavía no infalible

    
respondido por el James Conkling 20.10.2014 - 03:03
1

No creo que esta sea una característica de QGIS. Sin embargo, trataría de hacerlo de esta manera:

  1. haga dos copias de la capa con el complemento de la herramienta Affine. Una de las capas con una escala ligeramente mayor y otra con una escala ligeramente más pequeña.

  2. Densifica la geometría de las capas. Eso significa agregar más nodos.

  3. Vaya a la tabla de atributos y asigne un nombre a cada nodo de función, en consecuencia, 1,2,3, ... en una capa y 1b, 2b, 3b, ... en la segunda capa.

  4. fusione ambas capas y ordene la capa de atributo - > esto debería darle una línea en zigzag.

Tal vez esto funcione.

    
respondido por el mace 18.10.2014 - 17:46

Lea otras preguntas en las etiquetas