Fusionar varias líneas por campo de valor

Dec 09 2020

¿Cómo puedo unir estas líneas dependiendo del campo Disparador? La condición es la siguiente, los campos deben ordenarse en orden ascendente después del campo fid de 1a 68. Por lo tanto, quiero unir todas mis líneas comenzando con la primera que tiene el disparador 1 y las siguientes que tienen el valor 0y se detienen en el primer valor con 1y comienzan de nuevo.

Editar: lo entiendo. Pero, ¿cómo puedo solucionar este problema? ¿Cómo unir estas líneas? Trigger se refiere al ángulo. Si es 0, entonces el ángulo entre 2 segmentos es menor que x grados, y si es 1, el ángulo es mayor que x grados. Entonces, quiero que si la primera línea no es un disparador, quiero unirla con la primera línea que es el disparador.

Respuestas

3 MrXsquared Dec 09 2020 at 19:48

Para darle una idea de cómo se puede hacer esto, aquí hay una solución en Python para agregar un nuevo campo groupid, que puede usar para disolver sus líneas:

# Change your settings here:
layername = 'line' 
triggerfield = 'Trigger' # field must already exist
groupfieldname = 'mygroup' # will be added if does not exist
newlineindicator = 1

#####
# no changes needed below #
#####
layer = QgsProject.instance().mapLayersByName(layername)[0] # get the layer
layer.startEditing() # start editing the layer
layer.dataProvider().addAttributes([QgsField(groupfieldname,QVariant.Int)]) # add a group field
layer.commitChanges() # save new added field to prevent crash when searching for it later
layer.startEditing() # start editing the layer again
groupid = 0 # initialize groupid
fieldindex = layer.fields().indexFromName(groupfieldname) # get fieldindex of groupfield

for feat in layer.getFeatures(): # itereate over layer
    if feat[triggerfield] == newlineindicator: # if a new trigger appears, increase groupcounter
        groupid += 1
    attrs = { fieldindex : groupid } # prepare attributes
    layer.dataProvider().changeAttributeValues({ feat.id() : attrs }) # assign current groupid to current feature
layer.commitChanges() # save changes

Resultado:

3 Babel Dec 09 2020 at 21:08

Hay una manera de crear directamente un valor de campo usando una expresión QGIS en la calculadora de campo para agrupar todas las características que desea unir. Según el valor de este campo, puede utilizar la función Aggregatepara unir entidades con el mismo valor (consulte la segunda captura de pantalla a continuación). Los pasos de los bots deberían ser fáciles de automatizar con un modelo.

Tomando su estructura de datos y nombres de campo, la expresión se ve así (vea a continuación una explicación de cómo funciona la expresión):

array_last (
    array_sort (
        array_foreach (
            array_remove_all ( 
                array_agg ( 
                    if ( 
                        "trigger" = 1, 
                        "fid" , 
                        0
                    ) 
                ) ,
            0) ,
        if (
            if ( 
                "trigger" = 1, 
                "fid" , 
                0 
                ) = @element, 
                @element, 
                if (
                    "fid" > @element ,  
                    @element,0
                )
        )
        ) 
    )
)

Entonces puede usar este campo junto con la función Menu Processing / Toolbox / Aggregatepara unir estas características.

Para explicar la idea detrás de la expresión: para una mejor comprensión, llamemos al "segmento inicial" de la línea unida que finalmente desea obtener la " cabeza " - y los segmentos subsiguientes que se unen a ella las " colas ".

  1. Obtenga los valores fid de las cabezas , llamémoslo " ID de grupo ". El objetivo final es asignar cada segmento de cola a una cabeza (o: a cada cola se le debe asignar el valor de identificación de grupo de la siguiente cabeza más pequeña : 2 y 3 deben asignarse a 1, 5 y 6 a 4, etc.) a) Si el disparador es 1 ( cabeza ), obtenga el valor del id: este es el id del grupo . De lo contrario (para colas ) establezca un valor de 0. b) Agregue estos valores creando una matriz. c) Elimina todos los valores 0 de la matriz. Así obtenemos una matriz de ID de grupo (= fid de cabezas ): [1,4,7,9,12]. Finalmente queremos asignar cada característica a uno de estos valores de la matriz.

  2. Ahora itere sobre todas las características de la capa con cada uno de estos ID de grupo de la matriz con la expresión array_foreach: a) Para las características con trigger = 1 ( cabezas ) no tenemos ningún problema, estas ya tienen el ID de grupo correcto (correspondiente a su fid) b) En los otros casos ( colas , disparador = 0), debemos asignar nuevos valores. Por lo tanto, comparamos cada valor de entrada de la matriz (lista de todos los ID de grupo ) con el fid y mantenemos el ID de grupo si es más pequeño que el fid (como queremos asignar al siguiente valor más pequeño). De lo contrario, lo establecemos en 0. Así que en ningún caso resultará un valor de la matriz que sea mayor que el fid.

  3. Ordene la matriz para asegurarse de que tenemos los valores en el orden correcto (de menor a mayor), para eliminar los ceros finales de la última posición (vea la captura de pantalla a continuación). Sin establecer un orden de clasificación, obtenemos el valor predeterminado ascending=true.

  4. Obtenga el último valor de la matriz ordenada, por lo tanto, el último (mayor) ID de grupo que sea (recuerde el paso 2b) en ningún caso más grande que el fid Y (en caso de que el gatillo = 1) sea igual al fid (paso 2a) es siempre un número de la matriz que creamos en 1.

Vea una captura de pantalla para los resultados intermedios de los pasos 1 y 2:

Ahora es fácil usar la función agregada con el campo creado como se describe arriba.