Simboliza o contorno do polígono onde ele não coincide com outro recurso usando o gerador de geometria no QGIS?

10

Gostaria de simbolizar um polígono sem convertê-los em uma linha. Eu tenho um recurso de polígono (tracejado e delimitado pela linha vermelha) que coincide na parte superior e inferior da linha de costa (linha azul). Gostaria de simbolizar o contorno de um polígono apenas nos dois lados e gostaria de eliminar a cor vermelha na parte superior e inferior.

Imagem

Eu gostaria de ver o resultado final assim.

Imagem

Raj
fonte
Você poderia fornecer mais informações sobre seu fluxo de trabalho? Por exemplo, se este for um caso de uso único ou você precisará exibir vários polígonos dessa maneira? Se vários polígonos, eles são orientados de maneira diferente e têm proporções diferentes ou similares? A digitalização manual das linhas laterais pode ser uma opção adequada?
`
1
Este não é um caso de uso único. Eu tenho vários polígonos e eles seriam atualizados, então as formas mudam com muita frequência. E não quero digitalizá-los manualmente ou ocultar o polígono em linhas.
Raj

Respostas:

12

Geometry generatorLutei um pouco com o @GSienko. Para peça de interseção, você também pode usar a função embutida aggregate. Também usei a segment_to_linesfunção que converte polígonos em linhas.

difference(
    segments_to_lines($geometry),
    aggregate(
        layer:= 'line',
        aggregate:='collect',  
        expression:= $geometry,
        filter:=intersects($geometry, geometry(@parent))
    )
)

ou

difference(
    segments_to_lines($geometry),
    aggregate('line','collect',$geometry,intersects($geometry, geometry(@parent)))
)

insira a descrição da imagem aqui

Se você tiver algum polígono "não relacionado" às linhas, poderá adicionar uma ifcondição para a interseção. Se as camadas estiverem em interseção, a diferença será aplicada à simbologia; caso contrário, toda a geometria será aplicada.

if(
    intersects(
        segments_to_lines($geometry),
        aggregate('line','collect',$geometry,intersects($geometry, geometry(@parent)))
    ),
    difference(
        segments_to_lines($geometry),
        aggregate('line','collect',$geometry,intersects($geometry, geometry(@parent)))
    ),
    segments_to_lines($geometry)
)

insira a descrição da imagem aqui

edit : O uso do gerador de linha dessa maneira tem um ponto fraco - você precisa lidar com o símbolo da legenda, porque ele renderiza a linha através do polígono (não como uma borda). No entanto, você ainda pode duplicar a camada, definir preenchimento simples e usá-lo para legenda.

insira a descrição da imagem aqui

Oto Kaláb
fonte
1
Solução mais complexa, e eu aprender um pouco mais novamente :)
GSienko
Eu também :). Eu não precisava usar o gerador de geometria antes, mas foi a primeira coisa que pensei depois de ler o OP. Fiquei um pouco preso nisso tentando combinar interseções, e sua resposta também me ajudou, porque eu esqueci totalmente a função Diferença :).
Oto Kalab
Solução perfeita para o meu caso. Aprecio muito sua ajuda :)
Raj
A única desvantagem do uso do gerador de linha é que você precisa manipular o símbolo da legenda, porque ela renderiza a linha através do polígono (não como uma borda). No entanto, você ainda pode duplicar a camada, definir preenchimento simples e usá-lo para legenda.
Oto Kalab
4

Tente usar o plugin refFunction no gerador de geometria.

Suposição. 2 camadas - uma linha como linha e polígonos como polígono.

Estilo polígono assim:insira a descrição da imagem aqui

difference(exterior_ring( $geometry ),geom_from_wkt(geomintersects('line','$geometry')))

geomintersect fará uma consulta espacial entre a camada de polígono e a linha, e retornará a geometria de interseção de duas delas, no nosso caso, duas bordas de polígonos. O próximo passo é fazer a diferença com a borda do polígono. Não sei se você terá orifícios dentro ou não, então exterior_ring () retornará apenas a borda externa.

Resultado final: insira a descrição da imagem aqui

A limitação - geomintersect verificará a interseção apenas para um polígono. Eu gerencio essa limitação criando uma camada de polígonos em um grande multipolígono, por exemplo, uma camada virtual para o estilo da borda.

GSienko
fonte
3

Que tal adicionar uma linha branca sob a linha azul na outra camada, que tenha a mesma largura que a linha vermelha? Se você colocar a linha azul acima da camada de polígono, a linha branca obscurecerá a linha vermelha.

Obviamente, isso pressupõe que você tenha um plano de fundo branco como no seu exemplo, e que esteja bem com algumas das crosshashes também sendo obscurecidas.

Este é o meu resultado rápido de teste:

Imagem do mapa mostrando o estilo

Configurações para a linha azul:

Simbologia

hexamon
fonte
No meu caso, a espessura e as cores da linha podem variar. Também tenho que usar símbolos de linhas de marcador para os polígonos no mapa, onde a espessura do outro recurso e a espessura do polígono não serão as mesmas.
Raj
2

Isenção de responsabilidade: esta resposta não funcionará se você tiver vários polígonos

O que você pode fazer é descobrir quais nós formam os quatro cantos do polígono nos quais você deseja desenhar linhas e, em seguida, use os das funções MAKE_LINE () para desenhar as linhas:

Para encontrar quais nós você precisa:

  • Primeiro adicione uma simbologia do gerador de geometria
  • Defina o tipo de geometria como Point / MultiPoint
  • Use a expressão POINT_N($geometry, 1)para exibir o primeiro nó como um ponto
  • Continue alterando o valor até saber o número de cada um dos quatro cantos do polígono. Anote-os, pois você usará pares para desenhar as linhas

Para desenhar as linhas:

  • Altere o tipo de geometria do gerador de geometria para LineString / MultiLineString
  • Use a expressão MAKE_LINE(POINT_N($geometry, *first point*), POINT_N($geometry, *second point*)
  • Duplique isso usando o outro par de pontos
  • Isso desenhará as duas linhas de limite

Em seguida, basta adicionar uma simbologia de preenchimento de padrão de linha normal abaixo desses dois geradores de geometria

TeddyTedTed
fonte
Infelizmente, tenho muitos polígonos.
Raj