Symbolise le contour du polygone où il ne coïncide pas avec une autre entité à l'aide du générateur de géométrie dans QGIS?

10

Je voudrais symboliser un polygone sans les convertir en ligne. J'ai une entité polygonale (hachurée et délimitée par une ligne rouge) qui coïncide en haut et en bas du littoral (ligne bleue). Je voudrais symboliser le contour d'un polygone uniquement sur deux côtés et je souhaite supprimer la couleur rouge en haut et en bas.

Image

Je voudrais voir le résultat final comme ça.

Image

Raj
la source
Pourriez-vous fournir plus d'informations sur votre flux de travail? Par exemple, s'il s'agit d'un cas d'utilisation unique, ou devrez-vous afficher plusieurs polygones de cette façon? Si plusieurs polygones sont-ils orientés différemment et ont-ils des proportions différentes ou similaires? La numérisation manuelle des lignes latérales pourrait-elle être une option appropriée?
Erik
1
Ce n'est pas un cas d'utilisation unique. J'ai plusieurs polygones et ils seraient mis à jour de sorte que les formes changent très souvent. Et je ne veux pas les numériser manuellement ou convertir le polygone en lignes.
Raj

Réponses:

12

J'ai eu un peu de mal avec le Geometry generator@GSienko. Pour la partie d'intersection, vous pouvez également utiliser la fonction intégrée aggregate. J'ai également utilisé une segment_to_linesfonction qui convertit les polygones en lignes.

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)))
)

entrez la description de l'image ici

Si vous avez un polygone "sans rapport" avec les lignes, vous pouvez ajouter une ifcondition d'intersection. Si les couches sont en intersection, la différence est appliquée pour la symbologie, sinon la géométrie entière est appliquée.

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)
)

entrez la description de l'image ici

edit : Utiliser le générateur de lignes de cette façon a un point faible - vous devez gérer le symbole de légende, car il rend la ligne à travers le polygone (pas comme une bordure). Cependant, vous pouvez toujours dupliquer le calque, définir un remplissage simple et l'utiliser comme légende.

entrez la description de l'image ici

Oto Kaláb
la source
1
Solution plus complexe, et j'apprends encore un peu :)
GSienko
Moi aussi :). Je n'avais pas besoin d'utiliser le générateur de géométrie avant, mais c'était la première chose à laquelle j'ai pensé après avoir lu OP. Je suis resté un peu coincé à essayer de combiner les intersections, et votre réponse m'a également aidé, car j'ai complètement oublié la fonction Différence :).
Oto Kaláb,
Solution parfaite pour mon cas. J'apprécie beaucoup toute votre aide :)
Raj
Le seul inconvénient de l'utilisation du générateur de lignes est que vous devez gérer le symbole de légende, car il rend la ligne à travers le polygone (pas comme une bordure). Cependant, vous pouvez toujours dupliquer le calque, définir un remplissage simple et l'utiliser comme légende.
Oto Kaláb,
4

Essayez d'utiliser le plugin refFunction dans le générateur de géométrie.

Supposition. 2 couches - une ligne comme ligne et des polygones comme polygone.

Polygone de style comme ça:entrez la description de l'image ici

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

geomintersect fera une requête spatiale entre la couche polygone et la couche ligne, et retournera la géométrie d'intersection de deux d'entre eux, dans notre cas, deux bordures de polygones. L'étape suivante consiste à faire la différence avec la bordure du polygone. Je ne sais pas si vous aurez des trous à l'intérieur ou non, alors exterior_ring () ne retournera que la bordure extérieure.

Résultat final: entrez la description de l'image ici

La limitation - geomintersect ne vérifiera l'intersection que pour un seul polygone. Je gère cette limitation en créant des polygones en couches sur un grand multipolygone, par exemple par une couche virtuelle pour le style des bordures.

GSienko
la source
3

Que diriez-vous d'ajouter une ligne blanche sous la ligne bleue dans l'autre couche, qui a la même largeur que la ligne rouge? Si vous placez la ligne bleue au-dessus de la couche de polygones, la ligne blanche masquera la ligne rouge.

Bien sûr, cela suppose que vous avez un fond blanc comme dans votre exemple, et que vous êtes d'accord avec certains réticules également masqués.

Voici mon résultat de test rapide:

Image de la carte indiquant le style

Paramètres de la ligne bleue:

Symbologie

hexamon
la source
Dans mon cas, l'épaisseur du trait et les couleurs peuvent varier. Je dois également utiliser des symboles de lignes de marqueur pour les polygones à travers la carte où l'épaisseur de l'autre entité et l'épaisseur du polygone ne seront pas les mêmes.
Raj
2

Avertissement: Cette réponse ne fonctionnera pas si vous avez plusieurs polygones

Ce que vous pourriez faire est de découvrir quels nœuds forment les quatre coins du polygone entre lesquels vous souhaitez tracer des lignes, puis utilisez ceux des fonctions MAKE_LINE () pour tracer les lignes:

Pour trouver les nœuds dont vous avez besoin:

  • Ajoutez d'abord une symbologie de générateur de géométrie
  • Définissez le type de géométrie sur Point / MultiPoint
  • Utilisez l'expression POINT_N($geometry, 1)pour afficher le premier nœud comme un point
  • Continuez à changer la valeur jusqu'à ce que vous connaissiez le nombre de chacun des quatre coins du polygone, notez-les car vous en utiliserez des paires pour tracer les lignes

Pour tracer les lignes:

  • Changez le type de géométrie du générateur de géométrie en LineString / MultiLineString
  • Utilisez l'expression MAKE_LINE(POINT_N($geometry, *first point*), POINT_N($geometry, *second point*)
  • Dupliquez cela en utilisant l'autre paire de points
  • Cela dessinera les deux lignes de démarcation

Ensuite, vous ajoutez simplement une symbologie de remplissage de motif de ligne normale sous ces deux générateurs de géométrie

TeddyTedTed
la source
Malheureusement, j'ai plein de polygones.
Raj