2 votos

Construir un buscador de vértices cercano en QGIS

En OpenJump hay una herramienta llamada ClosedVertexFinder que puedes utilizar para encontrar vértices que estén demasiado cerca unos de otros.

https://github.com/ssinger/roadmatcher/blob/master/src/com/vividsolutions/jcs/qa/CloseVertexFinder.java

Me gustaría construir una herramienta como esta en QGIS.

¿Hay algo que ya se pueda utilizar para no construir la herramienta desde cero o tendré que calcular la distancia entre todos los vértices de una capa?

5voto

J. Monticolo Puntos 46

Con QGIS 3.10, puede duplicar su capa (polilínea o polígono), entrar en su simbología, elegir Geometry generator con Point / Multi-Point y pegar este código :

with_variable(
  'distance_threshold',
  5, --treshold to modify
  collect_geometries(
    array_filter(
      array_foreach(
        generate_series(1, num_points($geometry)),
          if(
            --condition
            distance(
              geometry_n(nodes_to_points($geometry), @element),
              geometry_n(nodes_to_points($geometry), @element + 1)
            ) >= @distance_threshold,
            --result_when_true
            Null,
            --result_when_false
            collect_geometries(
              geometry_n(nodes_to_points($geometry), @element),
              geometry_n(nodes_to_points($geometry), @element + 1)
            )
          )
      ),
      @element is not Null
    )
  )
)

Puede ajustar el umbral (3ª línea) en unidades de capa. Puede sustituirlo por un campo de capa (por ejemplo "my_treshold_layer_field" ) si tiene diferentes umbrales según las características.

Explicaciones :

  • creación de una variable umbral with_variable función > @distance_threshold
  • iterar sobre todos los vértices con generate_series para el vértice 1 hasta el último vértice (= num_points($geometry) y array_foreach . Si la distancia entre el vértice y el siguiente es superior o igual a @distance_threshold , entonces crea una geometría multipunto con el vértice y el siguiente, si no Null valor
  • filtrar la matriz creada por última vez con array_filter para mantener sólo los valores no nulos
  • crear una geometría multipunto collect_geometries para todas las geometrías filtradas.

El resultado es una capa de puntos con puntos en los vértices que están más cerca que el umbral.


He creado un modelo de QGIS 3 que extrae los segmentos más cortos o iguales a la distancia de entrada. La capa de entrada puede ser un polígono o una polilínea.

Aquí está el código para poner en un .model3 archivo, por ejemplo CloseVertexFinder.model3 :

<!DOCTYPE model>
<Option type="Map">
  <Option type="Map" name="children">
    <Option type="Map" name="native:explodelines_1">
      <Option value="true" type="bool" name="active"/>
      <Option name="alg_config"/>
      <Option value="native:explodelines" type="QString" name="alg_id"/>
      <Option value="Explode lines" type="QString" name="component_description"/>
      <Option value="181" type="double" name="component_pos_x"/>
      <Option value="192" type="double" name="component_pos_y"/>
      <Option name="dependencies"/>
      <Option value="native:explodelines_1" type="QString" name="id"/>
      <Option name="outputs"/>
      <Option value="true" type="bool" name="outputs_collapsed"/>
      <Option value="true" type="bool" name="parameters_collapsed"/>
      <Option type="Map" name="params">
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option value="qgis:convertgeometrytype_1" type="QString" name="child_id"/>
            <Option value="OUTPUT" type="QString" name="output_name"/>
            <Option value="1" type="int" name="source"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="native:extractbyattribute_1">
      <Option value="true" type="bool" name="active"/>
      <Option name="alg_config"/>
      <Option value="native:extractbyattribute" type="QString" name="alg_id"/>
      <Option value="Extract by attribute" type="QString" name="component_description"/>
      <Option value="408" type="double" name="component_pos_x"/>
      <Option value="361" type="double" name="component_pos_y"/>
      <Option name="dependencies"/>
      <Option value="native:extractbyattribute_1" type="QString" name="id"/>
      <Option type="Map" name="outputs">
        <Option type="Map" name="Close vertices">
          <Option value="native:extractbyattribute_1" type="QString" name="child_id"/>
          <Option value="Close vertices" type="QString" name="component_description"/>
          <Option value="408" type="double" name="component_pos_x"/>
          <Option value="423" type="double" name="component_pos_y"/>
          <Option type="invalid" name="default_value"/>
          <Option value="false" type="bool" name="mandatory"/>
          <Option value="Close vertices" type="QString" name="name"/>
          <Option value="OUTPUT" type="QString" name="output_name"/>
        </Option>
      </Option>
      <Option value="true" type="bool" name="outputs_collapsed"/>
      <Option value="true" type="bool" name="parameters_collapsed"/>
      <Option type="Map" name="params">
        <Option type="List" name="FIELD">
          <Option type="Map">
            <Option value="2" type="int" name="source"/>
            <Option value="v_length" type="QString" name="static_value"/>
          </Option>
        </Option>
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option value="qgis:fieldcalculator_1" type="QString" name="child_id"/>
            <Option value="OUTPUT" type="QString" name="output_name"/>
            <Option value="1" type="int" name="source"/>
          </Option>
        </Option>
        <Option type="List" name="OPERATOR">
          <Option type="Map">
            <Option value="2" type="int" name="source"/>
            <Option value="5" type="int" name="static_value"/>
          </Option>
        </Option>
        <Option type="List" name="VALUE">
          <Option type="Map">
            <Option value="verticesdistance" type="QString" name="parameter_name"/>
            <Option value="0" type="int" name="source"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="qgis:convertgeometrytype_1">
      <Option value="true" type="bool" name="active"/>
      <Option name="alg_config"/>
      <Option value="qgis:convertgeometrytype" type="QString" name="alg_id"/>
      <Option value="Convert geometry type" type="QString" name="component_description"/>
      <Option value="177" type="double" name="component_pos_x"/>
      <Option value="100" type="double" name="component_pos_y"/>
      <Option name="dependencies"/>
      <Option value="qgis:convertgeometrytype_1" type="QString" name="id"/>
      <Option name="outputs"/>
      <Option value="true" type="bool" name="outputs_collapsed"/>
      <Option value="true" type="bool" name="parameters_collapsed"/>
      <Option type="Map" name="params">
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option value="layertoanalyse" type="QString" name="parameter_name"/>
            <Option value="0" type="int" name="source"/>
          </Option>
        </Option>
        <Option type="List" name="TYPE">
          <Option type="Map">
            <Option value="2" type="int" name="source"/>
            <Option value="3" type="int" name="static_value"/>
          </Option>
        </Option>
      </Option>
    </Option>
    <Option type="Map" name="qgis:fieldcalculator_1">
      <Option value="true" type="bool" name="active"/>
      <Option name="alg_config"/>
      <Option value="qgis:fieldcalculator" type="QString" name="alg_id"/>
      <Option value="Field calculator" type="QString" name="component_description"/>
      <Option value="182" type="double" name="component_pos_x"/>
      <Option value="286" type="double" name="component_pos_y"/>
      <Option name="dependencies"/>
      <Option value="qgis:fieldcalculator_1" type="QString" name="id"/>
      <Option name="outputs"/>
      <Option value="true" type="bool" name="outputs_collapsed"/>
      <Option value="true" type="bool" name="parameters_collapsed"/>
      <Option type="Map" name="params">
        <Option type="List" name="FIELD_LENGTH">
          <Option type="Map">
            <Option value="2" type="int" name="source"/>
            <Option value="10" type="int" name="static_value"/>
          </Option>
        </Option>
        <Option type="List" name="FIELD_NAME">
          <Option type="Map">
            <Option value="2" type="int" name="source"/>
            <Option value="v_length" type="QString" name="static_value"/>
          </Option>
        </Option>
        <Option type="List" name="FIELD_PRECISION">
          <Option type="Map">
            <Option value="2" type="int" name="source"/>
            <Option value="3" type="int" name="static_value"/>
          </Option>
        </Option>
        <Option type="List" name="FIELD_TYPE">
          <Option type="Map">
            <Option value="2" type="int" name="source"/>
            <Option value="0" type="int" name="static_value"/>
          </Option>
        </Option>
        <Option type="List" name="FORMULA">
          <Option type="Map">
            <Option value="2" type="int" name="source"/>
            <Option value="$length" type="QString" name="static_value"/>
          </Option>
        </Option>
        <Option type="List" name="INPUT">
          <Option type="Map">
            <Option value="native:explodelines_1" type="QString" name="child_id"/>
            <Option value="OUTPUT" type="QString" name="output_name"/>
            <Option value="1" type="int" name="source"/>
          </Option>
        </Option>
        <Option type="List" name="NEW_FIELD">
          <Option type="Map">
            <Option value="2" type="int" name="source"/>
            <Option value="true" type="bool" name="static_value"/>
          </Option>
        </Option>
      </Option>
    </Option>
  </Option>
  <Option name="help"/>
  <Option name="modelVariables"/>
  <Option value="Vector general" type="QString" name="model_group"/>
  <Option value="CloseVertexFinder" type="QString" name="model_name"/>
  <Option type="Map" name="parameterDefinitions">
    <Option type="Map" name="layertoanalyse">
      <Option type="List" name="data_types">
        <Option value="-1" type="int"/>
      </Option>
      <Option type="invalid" name="default"/>
      <Option value="Layer to analyze" type="QString" name="description"/>
      <Option value="0" type="int" name="flags"/>
      <Option name="metadata"/>
      <Option value="layertoanalyse" type="QString" name="name"/>
      <Option value="vector" type="QString" name="parameter_type"/>
    </Option>
    <Option type="Map" name="native:extractbyattribute_1:Close vertices">
      <Option value="true" type="bool" name="create_by_default"/>
      <Option value="-1" type="int" name="data_type"/>
      <Option type="invalid" name="default"/>
      <Option value="Close vertices" type="QString" name="description"/>
      <Option value="0" type="int" name="flags"/>
      <Option name="metadata"/>
      <Option value="native:extractbyattribute_1:Close vertices" type="QString" name="name"/>
      <Option value="sink" type="QString" name="parameter_type"/>
      <Option value="true" type="bool" name="supports_non_file_outputs"/>
    </Option>
    <Option type="Map" name="verticesdistance">
      <Option value="1" type="int" name="data_type"/>
      <Option value="0" type="QString" name="default"/>
      <Option value="Vertices distance" type="QString" name="description"/>
      <Option value="0" type="int" name="flags"/>
      <Option value="9999999999" type="double" name="max"/>
      <Option name="metadata"/>
      <Option value="0" type="double" name="min"/>
      <Option value="verticesdistance" type="QString" name="name"/>
      <Option value="number" type="QString" name="parameter_type"/>
    </Option>
  </Option>
  <Option type="Map" name="parameters">
    <Option type="Map" name="layertoanalyse">
      <Option value="layertoanalyse" type="QString" name="component_description"/>
      <Option value="175" type="double" name="component_pos_x"/>
      <Option value="37" type="double" name="component_pos_y"/>
      <Option value="layertoanalyse" type="QString" name="name"/>
    </Option>
    <Option type="Map" name="verticesdistance">
      <Option value="verticesdistance" type="QString" name="component_description"/>
      <Option value="443" type="double" name="component_pos_x"/>
      <Option value="35" type="double" name="component_pos_y"/>
      <Option value="verticesdistance" type="QString" name="name"/>
    </Option>
  </Option>
</Option>

Detalles del código :

Entradas :

  1. Capa vectorial : cualquier tipo de geometría / Obligatorio
  2. Número : Flotante / Mín: 0, Max: 9999999999, Por defecto: 0 / Obligatorio

Algoritmos :

  1. Convertir el tipo de geometría : entrada: Capa vectorial (1), Nuevo tipo de geometría: Multilíneas
  2. Explotar líneas : entrada: "Convertido" del algoritmo "Convertir tipo de geometría" (3)
  3. Calculadora de campo : entrada: 'Exploded' del algoritmo 'Explode lines' (4), Nombre del campo resultado: v_length, Float, longitud: 10, precisión: 3, Crear un nuevo campo: Sí, fórmula: $length
  4. Extraer por atributo : entrada: 'Calculado' del algoritmo 'Calculadora de campos' (5), Atributo de selección: v_length operador: <= El valor de la entrada del modelo: Number (2), Extraído (atributo): Close vertices

El resultado es una capa de líneas con sólo las partes del segmento más cortas que la distancia especificada como parámetro. Si desea una capa de puntos, puede editar el modelo y añadir un paso con el botón Extract vertices algoritmo.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X