7 votos

Si dos símbolos en la misma capa de QGIS están demasiado cerca, ¿mostrar sólo uno?

Tengo una capa shapefile con diferentes piedras bajo el agua, sobre el agua y en la superficie del agua. A menudo están demasiado cerca unas de otras para mostrarse bien en el mapa generado por el compositor de impresión. Utilizo símbolos svg para las piedras, y se les aplica un estilo (se eligen los svg para las piedras) como categorizados por un id de clase en la tabla shapefile.

¿Cómo consigo que QGIS muestre sólo las piedras que están, por ejemplo, a más de 2 mm o xx unidades cartográficas de distancia?

0 votos

Por favor, eche un vistazo a mi respuesta. No la he probado a fondo, pero parece que funciona (espero que no entre en conflicto con los símbolos SVG). Avísame si hay algún problema.

0 votos

¿Cómo decidirá cuál mostrar? Si hay dos: una a la izquierda y otra a la derecha, ¿cuál debe mostrarse? ¿La más grande?

0 votos

@Fezter No sé si tu comentario va por mí pero, en mi planteamiento, no hago elecciones. Si hay dos piedras, una a la izquierda, otra a la derecha, se mostrarán si sus buffers no intersecan a la otra piedra correspondiente; en caso contrario, no se mostrarán las dos (ya que la condición debe verificarse o no para ambas piedras a la vez).

14voto

Geoffrey Puntos 228

EDITAR He editado la pregunta porque el OP especificó que está trabajando con shapefiles de puntos (el enfoque será similar al original, sin embargo).


Propongo un enfoque que sólo recurre a un generador de geometría y a una función personalizada.

Contexto

Supongamos partir de esta capa vectorial puntual que representa las piedras:

enter image description here

La capa almacena los identificadores de clase en el archivo "CLASS_ID" campo.

Solución

Ir a Layer Properties | Style y luego:

  1. Elija el Categorized renderizador;
  2. Seleccione "CLASS_ID" (o el que desee para su situación), sin necesidad de hacer clic en el campo Classify botón;
  3. Haga clic en el botón Change para el Symbol opción.

Desde el Symbol selector elija un Geometry generator como tipo de capa de símbolos y Point / MultiPoint como tipo de geometría. A continuación, haga clic en el botón Function Editor ficha:

enter image description here

A continuación, haga clic en New file y escriba show como nombre de la nueva función:

enter image description here

Verá que se ha creado una nueva función y que aparece en la parte izquierda del cuadro de diálogo. Ahora, haga clic en el nombre de la función y sustituya el valor por defecto @qgsfunction con el siguiente código (no elimine las bibliotecas importadas por defecto):

@qgsfunction(args='auto', group='Custom')
def set_dist(distance, layer_name, geom, curr_feat, feature, parent):
    layer  = QgsMapLayerRegistry.instance().mapLayersByName(layer_name)[0]
    buffered_geom = geom.buffer(distance, -1)
    req = QgsFeatureRequest().setFilterRect(buffered_geom.boundingBox())
    show = 1
    for feat in layer.getFeatures(req):
        inGeom = feat.geometry()
        if feat.id() != curr_feat.id() and buffered_geom.intersects(inGeom):
            return False
            break
    return True

Una vez hecho esto, haga clic en el botón Load y podrá ver la función desde el botón Custom Menú del Expression diálogo.

Ahora, escriba esta expresión (vea la imagen de abajo como referencia):

CASE
WHEN 
show(10,  @layer_name, $geometry, $currentfeature)
THEN 
$geometry
END

enter image description here

Acabas de ejecutar una función que dice, de forma imaginaria:

" Para la capa actual ( @nombre_capa ), visualizar la geometría ( $geometría ) de la característica actual ( $característicaactual ) metros de cualquier otro elemento de la misma capa".

Lo único que tiene que cambiar es el valor de investigación para la visualización, que en su caso debería ser 0,002 si está utilizando un SIR proyectado. Por lo tanto, deje los demás parámetros de la función como se proporcionan.

Si desea establecer símbolos SVG para las piedras, vaya a Relleno simple y seleccione la opción adecuada:

enter image description here

Por último, vuelva al Style y haga clic en el botón Classify (¡por fin!) para fijar los cambios.

Verá que algunas piedras no se renderizan (en la siguiente imagen también he informado de una capa intermedia de 10 metros en aras de la claridad):

enter image description here

0 votos

Gracias una vez más por unas instrucciones tan claras. Creo que esto me funcionaría muy bien, excepto una cosa: no lo tenía suficientemente claro pero mis objetos (piedras) son puntos, no polígonos. Es posible insertar el codigo y la expresion que das para un shapefile de puntos, pero categorizar los puntos con imagenes SVG, no funciona. QGIS automáticamente intenta hacer una línea como un sub-estilo para una imagen svg, y la imagen svg no se muestra. En su imagen de resultado (con piedras de las cuales algunas no son renderizadas) no me queda claro por qué no se muestran las piedras del centro.

0 votos

@BenjaminDonner por favor, vea mi respuesta editada (la adapté para un shapefile de puntos).

0 votos

Para obtener puntos extra, elimine el índice espacial y utilice QgsFeatureRequest().setFilterRect(tmp_geom.buffer(distance,-‌​1).boundingBox()) en su lugar. El índice sólo aceleraría las cosas si se reutiliza (almacenarlo en caché en el QgsExpressionContext sería posible pero más complicado).

2voto

Michael Puntos 11

La solución sencilla es, actualizar a QGIS 2.99/3.0 y utilizar un renderizador "Point cluster".

Vea este vídeo

https://www.youtube.com/watch?v=gNL-ZSlc4KM

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