Est-il possible d'interrompre une ligne de contour sous une étiquette d'élévation?
Est-il possible d'interrompre une ligne de contour sous une étiquette d'élévation?
Réponses:
Oui, faisable Normalement, je suggérerais un tampon partiellement transparent, mais je vois pourquoi vous voulez le faire par cartographie.
Cela peut être lent et vous devez décider manuellement où vous voulez que les étiquettes aillent - mais sur le plan cartographique, ce n'est pas une mauvaise chose!
Voici une capture d'écran ...
Comme vous pouvez le voir, pas de tampons. Le raster en dessous n'est pas affecté. J'ai inclus des lignes de contour intermédiaires plus minces et les ai stylisées pour qu'elles ne soient affichées que lorsque ELEV% 50 <> 0.
Je l'ai fait dans QGIS 2.12 ... votre kilométrage peut varier par rapport aux versions précédentes.
Je suppose ici que vous avez un champ "ELEV" sur chaque ligne de contour.
Segmenter les lignes de contour
Utilisez le traitement et l’algorithme GRASS v.split.length pour scinder vos contours en segments de longueur égale. Vous devez choisir une longueur qui sera proche de la taille de votre étiquette en unités de carte, en supposant que vous utilisiez des mètres. Ici j'ai utilisé 200m.
Soyez prudent avec ceci car cela rendra votre fichier beaucoup plus gros (notez que la fonctionnalité compte dans la capture d'écran).
Pour éviter ce problème, vous pouvez générer uniquement les lignes de contour que vous souhaitez styler (par exemple, tous les 50 ou 100 mètres) pour éviter de traiter toutes les lignes de contour intermédiaires.
A cette couche, ajoutez un champ entier à 1 chiffre appelé showLabel . La valeur par défaut est 0 ou NULL.
Modifiez l'étiquette pour afficher uniquement sur un segment où ce champ est défini sur 1. Utilisez ceci pour l'expression de texte d'étiquette ...
if ( "showlabel" is not null, "ELEV", "")
Je pense que si (expression, valeur vraie, valeur fausse) est relativement nouvelle; si vous utilisez une version plus ancienne, vous pouvez utiliser CASE-ELSE
Modifiez le style de ligne afin que les segments de longueur fixe soient tous dessinés, à l' exception des segments pour lesquels l'étiquette est affichée. Utilisez donc le rendu basé sur des règles avec deux règles
Rule 1: "showLabel" is null
Black, 0% transparent
Rule 2: "showLabel" is not null
Any colour, 100% transparent
Maintenant, tous les contours seront affichés par défaut, mais pas d’étiquettes.
Modifier manuellement les segments pour lesquels vous souhaitez afficher les étiquettes
Passez en mode édition et sélectionnez manuellement les segments sur lesquels vous souhaitez afficher les valeurs de contour, puis définissez la valeur showLabel
sur 1 pour les entités sélectionnées. Vous pouvez utiliser Ctrl+ select (sur Ubuntu / Win, Cmd+ Ctrl+ Click / sur Mac?) Pour sélectionner plusieurs segments afin d’accélérer les choses.
Cela devrait maintenant «découper» les contours à l'endroit où vous souhaitez afficher les étiquettes, et les étiquettes s'afficheront dans les espaces.
Dans ce cas, mes paramètres d'étiquette étaient:
CRS: EPSG 27700 (Local UTM for UK, in meters)
Text size: 50 map units
Placement: Parallel, On Line
J'espère que ça t'as aidé!
J'utilise l'option "Tampon" de l'onglet "Paramétrage d'étiquette". (Utiliser le bouton Étiquettes, et non l'ancienne option Étiquettes de la boîte de dialogue Propriétés de la couche.) Cela n'efface pas la ligne de contour, comme je suppose que vous voulez le faire, mais cela rend l'étiquette lisible.
Je pense que le plus proche des capacités actuelles de QGIS consiste à utiliser un effet de halo (ou d’arrière-plan) avec une couleur provenant du tableau, qui sera basé sur la valeur d’altitude et le schéma de couleurs identique à celui utilisé pour la grille sous-jacente. Bien sûr, cela ne prendrait pas en compte l’ombrage et tout le reste en dessous du halo sur la carte. Exemple de couleur aléatoire: avec un peu de code, cela pourrait être réécrit comme fonction pour refléter la couleur de la grille.
En théorie, il devrait être possible d'utiliser un motif de trait personnalisé et une répétition d'étiquette + un décalage . Malheureusement, il n'y a pas de paramètre de décalage d'étiquette.
Après avoir rencontré le même problème récemment, j’ai mis au point un script QGIS Python pour effectuer le gros travail. Le script, y compris certaines données de test (UK), le fichier Readme (Guide) et les feuilles de style utilisées, est disponible à l' adresse https://github.com/pjgeng/Contour-Labels.
En bref, le script utilise deux couches vectorielles en entrée - la couche de contour annotée et une couche "guides". Ce dernier est constitué de polylignes intersectant les contours aux emplacements désirés des étiquettes.
Le script est ensuite élaboré en fonction de la distance entre les contours et de l’intervalle de contour d’index auquel les étiquettes doivent être appliquées, ajoute une valeur de rotation aux points de l’étiquette, puis coupe le calque de contour d’origine pour produire les espaces.
L'approche fonctionne particulièrement bien si l'utilisateur a besoin de produire des cartes de contours à différents intervalles dans la même zone (les guides ne changent pas). L'inconvénient est l'incapacité de modifier la position de l'étiquette une fois le script terminé. Pour cela, l'utilisateur devra ajuster les lignes de guidage et réexécuter le script avec l'entrée d'origine. Auparavant, j'avais beaucoup travaillé avec les tampons autour des étiquettes pour créer l'effet interrompu, mais cela s'est avéré esthétiquement désagréable sur les cartes vectorielles.
Malheureusement, je ne peux ajouter aucune image pour le moment pour documenter ou illustrer davantage le processus.
PS: Si vous utilisez les couches de style fournies dans le référentiel, les utilisateurs devront peut-être "activer" les champs personnalisés pour "Rotation", "Afficher le libellé" et "Toujours afficher" dans le menu libellé. Sur certaines installations de QGIS, celles-ci sont appliquées automatiquement à partir de la feuille de style - je n’ai pas encore découvert la cause de ce problème.
Voici une autre solution au problème de masquage d'étiquette de contour QGIS, dans laquelle j'utilise la fonctionnalité Spatialite de QGIS (actuellement QGIS 3.x) avec un générateur de géométrie pour le placement d'étiquette.
Cette solution très dynamique nous permet de modifier immédiatement toutes les tailles et positions de libellé d'étiquettes, et même de survivre à une exportation vectorielle au format PDF!
Pour rendre cela possible, nous avons besoin des pièces suivantes:
Une couche virtuelle appelée «contours_with_labels» avec un style basé sur des règles:
Règle 2: ELSE… simple ligne
et un texte d'étiquette conditionnel pour la règle 1:
CAS QUAND étiquette = 1 ALORS elev ELSE '' END
make_line (start_point ($ geometry), end_point ($ geometry))
attribut (get_feature ('settings', 'variable', 'contourlabel_size'), 'value')
et enfin, voici la requête SQL pour la couche virtuelle:
------------------------------------------------------------------------
-- select all contour lines that do not intersect any scratch lines
------------------------------------------------------------------------
select c.geometry,c.elev,0 as label
from contours c,
(select st_union(geometry) as geom from scratch_lines) as scr
where not st_intersects(c.geometry,scr.geom)
------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all scratch lines (bufferwidth = length(elevation_text) * txtsize/3),
-- get st_difference between contour lines and buffers
-- and set attribute "label" to 0
--------------------------------------------------------------------------------------------------------
select st_difference(c.geometry,buf.geom) as geom,c.elev,0 as label
from
(select c.fid,st_union(st_buffer(scr.geometry,length(c.elev) * txtsize.value / 3)) as geom
from scratch_lines scr,
contours c,
(select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(scr.geometry,c.geometry)
group by c.fid) as buf,
contours c
where c.fid = buf.fid
group by c.fid
--------------------------------------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all scratch lines (bufferwidth = length(elevation_text) * txtsize/3),
-- get st_intersection between contour lines and buffers
-- and set attribute "label" to 1
--------------------------------------------------------------------------------------------------------
select st_intersection(st_buffer(scr.geometry,length(c.elev) * txtsize.value / 3),c.geometry) as geom,c.elev,1 as label
from scratch_lines scr,
contours c,
(select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(c.geometry,scr.geometry)
C'est ça.
Un grand merci à toutes ces personnes enthousiastes qui rendent cela possible!
Vous souvenez-vous de ce fil Martin? Le seul moyen auquel je puisse penser pour trouver une solution à votre problème serait de superposer votre calque de contour avec un calque de contour découpé, utilisez-le pour l'étiquetage et modifiez la couleur de trait en une couleur neutre masquant les contours sous les étiquettes, on espère sans être trop intrusif. N.
Ajouté plus tard: il pourrait être intéressant de regarder ce fil aussi, la deuxième réponse. Peut-être que casser les lignes de contour pourrait être une solution, peut-être en utilisant la couche tampon utilisée pour couper les contours?
Pour rendre les étiquettes plus parfaites, j'ai modifié la requête SQL de la couche virtuelle afin de respecter les lignes de grattage parallèles aux lignes de contour (voir la solution ci-dessous):
Et voici le nouveau SQL pour la couche virtuelle:
------------------------------------------------------------------------
-- select all contour lines that do not intersect any scratch lines
------------------------------------------------------------------------
select c.geometry,c.elev,0 as label
from contours c,
(select st_union(geometry) as geom from scratch_lines) as scr
where not st_intersects(c.geometry,scr.geom)
------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all intersection points (bufferwidth = length(elevation_text) * txtsize/2.5),
-- get st_difference between contour lines and buffers
-- and set attribute "label" to 0
--------------------------------------------------------------------------------------------------------
select st_difference(c.geometry,buf.geom) as geom,c.elev,0 as label
from contours c,
(select c.fid,st_union(st_buffer(st_intersection(c.geometry,scr.geometry),length(c.elev) * txtsize.value / 3)) as geom
from contours c, scratch_lines scr, (select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(c.geometry,scr.geometry)
group by c.fid) as buf
where c.fid = buf.fid
--------------------------------------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all intersection points (bufferwidth = length(elevation_text) * txtsize/2.5),
-- get st_intersection between contour lines and buffers
-- and set attribute "label" to 1
--------------------------------------------------------------------------------------------------------
select st_intersection(c.geometry,st_buffer(st_intersection(c.geometry,scr.geometry),length(c.elev) * txtsize.value / 3)) as geom,c.elev,1 as label
from contours c,
scratch_lines scr,
(select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(c.geometry,scr.geometry)
Entrée de blog ESRI: http://blogs.esri.com/esri/arcgis/2011/11/28/variable-depth-masking-contour-label-example/
Le masquage à profondeur variable pour les étiquettes de contour comprend trois étapes:
1 créez des annotations à partir des étiquettes, 2 utilisez l'outil Masques de structure pour créer des masques et 3 utilisez les paramètres Options de dessin avancées> Masquage pour spécifier les calques que les masques masqueront.