Propongo un enfoque que sólo recurre a un generador de geometría y un función personalizada .
Contexto
Supongamos que partimos de esta situación (esperemos que sea muy parecida a la suya), en la que las diversas restricciones de aparcamiento se almacenan en el "Condition"
campo:
![enter image description here]()
También asumo que sabes cómo funcionan las funciones personalizadas de QGIS, de lo contrario este post podría ser útil: Cómo crear funciones personalizadas en QGIS utilizando el editor de funciones .
Tarea preliminar - Creación de la función personalizada
Después de haber cargado sus capas en QGIS, abra el Field Calculator
y haga clic en el botón Function Editor
ficha.
A continuación, haga clic en New file
y escriba curb_lines
como nombre de la nueva función:
![enter image description here]()
Verá que se ha creado una nueva función que aparece en la parte izquierda del diálogo. Ahora, haga clic en el nombre de la función y sustituya la función por defecto @qgsfunction
con el siguiente código:
from qgis.core import *
from qgis.gui import *
@qgsfunction(args='auto', group='Custom')
def curb_lines(restrictions_layer_name, roads_layer_name, feature, parent):
def segments(polyline):
for x in range(0, len(polyline)-1):
first_point = polyline[x]
second_point = polyline[x +1]
seg = QgsGeometry.fromPolyline([first_point, second_point])
idsList = index.intersects(seg.boundingBox())
for id in idsList:
tmp_geom = all_feats[id].geometry()
if seg.touches(tmp_geom):
num.append(seg)
return num
layer = QgsMapLayerRegistry.instance().mapLayersByName(restrictions_layer_name)[0]
ro_layer = QgsMapLayerRegistry.instance().mapLayersByName(roads_layer_name)[0]
all_feats = {}
index = QgsSpatialIndex()
for ft in ro_layer.getFeatures():
index.insertFeature(ft)
all_feats[ft.id()] = ft
input_geometry = QgsGeometry(feature.geometry())
line_geom = QgsGeometry(input_geometry.geometry().boundary())
polyline = line_geom.asPolyline()
num = []
res = segments(polyline)
first = True
for h in num:
if first:
geom = QgsGeometry(h)
first = False
else:
geom = geom.combine(h)
return geom
Una vez hecho esto, haga clic en el botón Load
y podrá ver la función del Custom
Menú del Expression
diálogo.
Solución
En primer lugar, vaya a Layer Properties | Style
y luego elegir el Rule-based
renderizador.
Cree dos reglas diferentes (si sólo tiene dos categorías, si no, adáptelas a su caso): Te mostraré cómo conseguir una solución que funcione sólo para la primera categoría, ya que el procedimiento es el mismo para todas las demás.
Haga doble clic en la primera regla y establezca la expresión del filtro ( paso 1 (véase la imagen de abajo):
"Condition" = 'Residential only'
![enter image description here]()
Desde el Symbol selector
elija un Geometry generator
como tipo de capa de símbolos ( paso 2 ) y Linestring / MultiLinestring
como tipo de geometría ( paso 3 ).
Ahora, escriba esta expresión ( paso 4 ):
curb_lines('restr', 'roads')
donde 'restr'
y 'roads'
son los nombres de las capas de restricciones y carreteras, respectivamente (adáptelos a su caso).
Si desea establecer un estilo diferente para cada categoría, vaya a paso 5 y establecer Color
, Pen width
, Offset
y así sucesivamente (la respuesta no cubrirá esta parte).
Haga clic en el botón OK
y repita los pasos anteriores para las demás categorías.
Por último, haga clic en el botón Apply
para aplicar los cambios.
Verás algo así:
![enter image description here]()
0 votos
¿Los polígonos comparten una arista común (o una parte de ella)? Lo pregunto en referencia a las dos aristas blancas de la derecha, por ejemplo. Entonces, ¿está permitido utilizar una función personalizada?
0 votos
Si quieres suprimir las líneas (como en el ejemplo que has puesto) puedes probar diferentes "modos de mezcla", pero por lo que tengo entendido, puedes probar a dar un desplazamiento a la línea de tu polígono (propiedades de la capa>relleno>línea simple>desplazamiento
0 votos
@mgri Algunos de los polígonos de restricción comparten límites, mientras que otros no. La distinción clave es que quiero mostrar los contornos que se comparten con los contornos de la carretera solamente. Una función personalizada que se llame desde el generador de geometría estaría bien.
0 votos
@ElioDiaz si desplazo el polígono, seguiré teniendo todo el perímetro renderizado, solo que estará en un lugar diferente. Igualmente los modos de mezcla afectarán a todo el polígono, no sólo a la parte que necesito.
0 votos
@firefly-orange por favor, ¿podrías compartir un conjunto de datos de muestra? Tengo una idea pero quiero comprobar si es aplicable a tu caso.
0 votos
@mgri No puedo compartir los datos en este momento. ¿Serías tan amable de compartir la solución que propones de todos modos? Puede ser suficiente para que me adapte, si no se ajusta al 100% a mi caso de uso.