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


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


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.


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


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


Infelizmente, tenho muitos polígonos.
Raj
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.