Würden Sie eine Antwort akzeptieren, die PostGIS erfordert?
Scro
3
leider: nein :) Aber gibt es eine Möglichkeit, das Problem mit PostGIS zu lösen?
KARTE
Antworten:
22
Ja machbar Normalerweise würde ich einen teilweise transparenten Puffer vorschlagen, aber ich sehe, warum Sie dies kartografisch tun möchten.
Dies kann langsam sein, und Sie müssen manuell entscheiden, wohin die Etiketten gehen sollen - aber kartografisch gesehen ist das keine schlechte Sache!
Hier ist ein Screenshot ...
Wie Sie sehen, keine Puffer. Das Raster darunter ist nicht betroffen. Ich habe dünnere Konturzwischenlinien eingefügt und sie so gestaltet, dass sie nur angezeigt werden, wenn ELEV% 50 <> 0
Ich habe dies in QGIS 2.12 getan ... Ihr Kilometerstand kann von früheren Versionen abweichen.
Ich gehe davon aus, dass Sie hier ein "ELEV" -Feld auf jeder Konturlinie haben.
Segmentieren Sie die Konturlinien
Verwenden Sie die Verarbeitung und den GRASS-Algorithmus v.split.length , um Ihre Konturen in gleich lange Segmente aufzuteilen. Sie müssen eine Länge wählen, die der Größe Ihres Etiketts in Karteneinheiten entspricht, vorausgesetzt, Sie verwenden Meter. Hier habe ich 200m benutzt.
Seien Sie vorsichtig damit, da Ihre Datei dadurch sehr viel größer wird (beachten Sie, dass die Funktion im Screenshot zählt).
Um dies zu umgehen, möchten Sie möglicherweise nur die Konturlinien generieren, die Sie formatieren möchten (z. B. alle 50 oder 100 Meter), um zu vermeiden, dass alle Zwischenkonturlinien verarbeitet werden.
Fügen Sie dieser Ebene ein 1-stelliges Ganzzahlfeld mit dem Namen showLabel hinzu . Standardmäßig 0 oder NULL.
Ändern Sie die Beschriftung so, dass sie nur in einem Segment angezeigt wird, in dem dieses Feld auf 1 gesetzt ist. Verwenden Sie dies für den Beschriftungstextausdruck ...
if ( "showlabel" is not null, "ELEV", "")
Ich denke, wenn (Ausdruck, wahrer Wert, falscher Wert) ziemlich neu ist; Wenn Sie eine ältere Version verwenden, können Sie CASE-ELSE verwenden
Ändern Sie den Linienstil so, dass alle Segmente mit fester Länge gezeichnet werden, mit Ausnahme der Segmente, in denen die Bezeichnung angezeigt wird. Verwenden Sie daher das regelbasierte Rendern mit zwei Regeln
Rule 1: "showLabel" is null
Black, 0% transparent
Rule 2: "showLabel" is not null
Any colour, 100% transparent
Jetzt werden standardmäßig alle Konturen angezeigt, jedoch keine Beschriftungen.
Bearbeiten Sie Segmente manuell, in denen Beschriftungen angezeigt werden sollen
Wechseln Sie in den Bearbeitungsmodus und wählen Sie manuell die Segmente aus, in denen die Konturwerte angezeigt werden sollen. Setzen Sie den Wert showLabelfür die ausgewählten Features auf 1. Sie können Ctrl+ select (unter Ubuntu / Win, Cmd+ Ctrl+ Click / on Mac?) Verwenden , um Segmente mehrfach auszuwählen, um die Dinge zu beschleunigen.
Dies sollte nun die Konturen "beschneiden", an denen die Beschriftungen angezeigt werden sollen, und die Beschriftungen werden in den Lücken angezeigt.
In diesem Fall lauteten meine Beschriftungseinstellungen:
CRS: EPSG 27700 (Local UTM for UK, in meters)
Text size: 50 map units
Placement: Parallel, On Line
Dies ist die einzige voll funktionsfähige Lösung, die ich mir vorstellen kann. Sehr schmerzhaft, wenn es viele Etiketten gibt, kann ich mir nicht vorstellen, alle meine Grundwasserkopfkarten (Tausende pro Jahr) auf diese Weise zu erstellen. Wäre großartig, wenn dies in Zukunft durch Stil erreicht werden könnte - am besten durch benutzerdefiniertes Linienmuster und Etikettenwiederholung + Versatz.
Miro
2
Nur ein paar Ideen, um die Aufgabe zu vereinfachen: Um die mehreren Segmente zum Zeichnen der Beschriftung auszuwählen, kann Auswahl per Polygon oder Auswahl per Freihand nützlich sein. Ein weiterer Ansatz wäre, eine Kratzlinienebene zu erstellen, um Linien zu zeichnen, die die Konturen abfangen, und dann eine Auswahl nach Position vorzunehmen.
Alexandre Neto
7
Ich verwende die Option "Puffer" auf der Registerkarte "Etiketteneinstellung". (Verwenden Sie die Schaltfläche "Beschriftungen", nicht die Option "Alte Beschriftungen" im Dialogfeld "Ebeneneigenschaften".) Dadurch wird die Konturlinie nicht wie gewünscht verwischt, aber die Beschriftung wird lesbar.
Ich habe noch nie darüber nachgedacht, aber es wäre praktisch, wenn Sie dem Puffer keine Farbe zuweisen, sondern ihn als Aussparung auf ausgewählte Ebenen anwenden könnten.
Scro
4
Die neueste Version von QGIS verfügt über transparente Puffer, mit denen Sie die Auswirkungen auf andere Teile der Karte verringern können.
Nathan W
1
@MAP Ein Knockout löscht die Pixel darunter. Wenn dies eine Option wäre, würden Sie in diesem Fall die Konturebene aussparen.
@MAP - Sponsern Sie einen Entwickler oder senden Sie eine Feature-Anfrage und warten Sie auf das Wohlwollen anderer. :)
Scro
5
Ich denke, das Beste, was mit den aktuellen QGIS-Fähigkeiten erreicht werden kann, ist die Verwendung des Halo- (oder Hintergrund-) Effekts mit Farben aus der Tabelle, die auf dem Höhenwert und dem Farbschema basieren, die für das zugrunde liegende Raster verwendet werden. Natürlich wäre dies nicht berücksichtigt Schummerungs und alles andere unter dem Halo in der Karte. Beispiel für zufällige Farben:
Mit ein bisschen Code könnte dies als Funktion zur Darstellung der Rasterfarbe umgeschrieben werden.
Theoretisch sollte es möglich sein, benutzerdefiniertes Linienmuster und Label Repeat + Offset zu verwenden . Leider gibt es keine Einstellung für den Etikettenversatz.
Nach einigen Tests ist es unmöglich, QGIS zu zwingen, die Beschriftungen genau in Intervallen und nirgendwo anders zu platzieren (+ fehlender Startoffset)
Es ist nicht möglich, ein benutzerdefiniertes Linienmuster mit einem Abstand von 0 mm zu erstellen, um einen Startversatz von 20 Linien - 10 Leerzeichen - 70 Linien - 0 Leerzeichen zu erhalten. Die Beschriftung wird also alle 100 mm mit einem Abstand von 30 mm am Anfang platziert die Mitte von jedem 10mm Loch.
Nachdem ich kürzlich auf dasselbe Problem gestoßen bin, habe ich ein QGIS-Python-Skript zusammengestellt, um das schwere Heben durchzuführen. Das Skript mit einigen Testdaten (Großbritannien), Readme-Datei (Handbuch) und verwendeten Stylesheets finden Sie unter https://github.com/pjgeng/Contour-Labels
Kurz gesagt, das Skript verwendet zwei Vektorebenen als Eingabe - die mit Anmerkungen versehene Konturenebene und eine "Hilfslinien" -Ebene. Letzteres besteht aus Polylinien, die die Konturen an den gewünschten Etikettenpositionen schneiden.
Das Skript erarbeitet dann basierend auf dem Abstand zwischen Konturen und dem Indexkonturintervall, auf das die Beschriftungen angewendet werden sollen, fügt den Beschriftungspunkten einen Rotationswert hinzu und schneidet schließlich die ursprüngliche Konturebene ab, um die Lücken zu erzeugen.
Der Ansatz funktioniert besonders gut, wenn der Benutzer Konturenkarten in unterschiedlichen Intervallen im selben Bereich erstellen muss (dh die Hilfslinien ändern sich nicht). Ein Nachteil ist die Unfähigkeit, die Etikettenposition zu ändern, wenn das Skript beendet ist. Hierzu müsste der Benutzer die Hilfslinien anpassen und das Skript erneut mit der ursprünglichen Eingabe ausführen. Früher habe ich viel mit Puffern um Etiketten gearbeitet, um den unterbrochenen Effekt zu erzeugen, aber dies stellte sich bei vektordatengesteuerten Karten als ästhetisch unangenehm heraus.
Leider kann ich zur Zeit keine Bilder mehr hinzufügen, um den Vorgang weiter zu dokumentieren oder zu veranschaulichen.
PS: Wenn Sie die im Repository bereitgestellten Stilebenen verwenden, müssen Sie möglicherweise die benutzerdefinierten Felder für "Drehung", "Beschriftung anzeigen" und "Immer anzeigen" im Beschriftungsmenü "aktivieren". Bei einigen Installationen von QGIS werden diese automatisch aus dem Stylesheet übernommen - ich habe noch nicht herausgefunden, woran das liegt.
Erinnerst du dich an diesen Thread Martin? Ich kann mir nur vorstellen, einer Lösung für Ihr Problem nahe zu kommen, indem ich Ihre Konturebene mit einer abgeschnittenen Konturebene überschreibe, diese zum Beschriften verwende und die Linienfarbe in etwas Neutrales ändere, das die Konturen unter den Beschriftungen maskiert. man hofft, ohne zu aufdringlich zu sein. N.
Später hinzugefügt: Es könnte sich lohnen, sich auch diesen Thread anzuschauen, die zweite Antwort. Vielleicht könnte das Brechen der Konturlinien eine Antwort sein, vielleicht unter Verwendung der Pufferebene, die zum Ausschneiden der Konturen verwendet wird?
Hier ist eine weitere Lösung für das Problem der QGIS-Konturetiketten-Maskierung, bei der ich die Spatialite-Funktionalität von QGIS (derzeit QGIS 3.x) zusammen mit einem Geometriegenerator für die Etikettenplatzierung nutze.
Diese sehr dynamische Lösung ermöglicht es uns, alle Beschriftungstextgrößen und Beschriftungspositionen sofort zu ändern und sogar einen PDF-Vektorexport zu überstehen!
Um dies zu ermöglichen, benötigen wir folgende Teile:
Eine Vektorebene "LINESTRING" oder "MULTILINESTRING" mit der Bezeichnung "Konturen" und zwei Feldern: "fid" (Interger64 - Primärschlüssel), "elev" (Zeichenfolge)
Eine Vektorebene "LINESTRING" mit dem Namen "scratch_lines" (siehe rote Linien im Bild)
Eine geometrielose Tabelle mit dem Namen "settings" zum Speichern der globalen Konturbeschriftungsgröße (dies ist eine einfache Problemumgehung, da QGIS derzeit keine Projektvariablen in SQL-Abfragen verwenden kann): "fid" (Integer64 - Primärschlüssel), "variable" (String), "Wert" (String)
Eine virtuelle Ebene mit dem Namen "contours_with_labels" mit regelbasiertem Stil:
Regel 1: “label” = 1… einfache Linie, Deckkraft 0%
Regel 2: ELSE… einfache Linie
und einen bedingten Etikettentext für Regel 1:
CASE WHEN label = 1 THEN elev ELSE '' END
mit einem Geometrie-Generator zur Textplatzierung:
Und zu guter Letzt folgt hier die SQL-Abfrage für die virtuelle Ebene:
------------------------------------------------------------------------
-- 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)
Das ist es.
Vielen Dank an alle diese begeisterten Menschen, die dies möglich machen!
Die Maskierung mit variabler Tiefe für Konturetiketten umfasst drei Schritte:
1Erstellen von Anmerkungen aus den Beschriftungen, 2Erstellen von Masken mit dem Werkzeug "Feature-Gliederungsmasken" und 3Erstellen von Masken mit den Einstellungen "Erweiterte Zeichenoptionen"> "Maskieren".
Antworten:
Ja machbar Normalerweise würde ich einen teilweise transparenten Puffer vorschlagen, aber ich sehe, warum Sie dies kartografisch tun möchten.
Dies kann langsam sein, und Sie müssen manuell entscheiden, wohin die Etiketten gehen sollen - aber kartografisch gesehen ist das keine schlechte Sache!
Hier ist ein Screenshot ...
Wie Sie sehen, keine Puffer. Das Raster darunter ist nicht betroffen. Ich habe dünnere Konturzwischenlinien eingefügt und sie so gestaltet, dass sie nur angezeigt werden, wenn ELEV% 50 <> 0
Ich habe dies in QGIS 2.12 getan ... Ihr Kilometerstand kann von früheren Versionen abweichen.
Ich gehe davon aus, dass Sie hier ein "ELEV" -Feld auf jeder Konturlinie haben.
Segmentieren Sie die Konturlinien
Verwenden Sie die Verarbeitung und den GRASS-Algorithmus v.split.length , um Ihre Konturen in gleich lange Segmente aufzuteilen. Sie müssen eine Länge wählen, die der Größe Ihres Etiketts in Karteneinheiten entspricht, vorausgesetzt, Sie verwenden Meter. Hier habe ich 200m benutzt.
Seien Sie vorsichtig damit, da Ihre Datei dadurch sehr viel größer wird (beachten Sie, dass die Funktion im Screenshot zählt).
Um dies zu umgehen, möchten Sie möglicherweise nur die Konturlinien generieren, die Sie formatieren möchten (z. B. alle 50 oder 100 Meter), um zu vermeiden, dass alle Zwischenkonturlinien verarbeitet werden.
Fügen Sie dieser Ebene ein 1-stelliges Ganzzahlfeld mit dem Namen showLabel hinzu . Standardmäßig 0 oder NULL.
Ändern Sie die Beschriftung so, dass sie nur in einem Segment angezeigt wird, in dem dieses Feld auf 1 gesetzt ist. Verwenden Sie dies für den Beschriftungstextausdruck ...
Ich denke, wenn (Ausdruck, wahrer Wert, falscher Wert) ziemlich neu ist; Wenn Sie eine ältere Version verwenden, können Sie CASE-ELSE verwenden
Ändern Sie den Linienstil so, dass alle Segmente mit fester Länge gezeichnet werden, mit Ausnahme der Segmente, in denen die Bezeichnung angezeigt wird. Verwenden Sie daher das regelbasierte Rendern mit zwei Regeln
Jetzt werden standardmäßig alle Konturen angezeigt, jedoch keine Beschriftungen.
Bearbeiten Sie Segmente manuell, in denen Beschriftungen angezeigt werden sollen
Wechseln Sie in den Bearbeitungsmodus und wählen Sie manuell die Segmente aus, in denen die Konturwerte angezeigt werden sollen. Setzen Sie den Wert
showLabel
für die ausgewählten Features auf 1. Sie können Ctrl+ select (unter Ubuntu / Win, Cmd+ Ctrl+ Click / on Mac?) Verwenden , um Segmente mehrfach auszuwählen, um die Dinge zu beschleunigen.Dies sollte nun die Konturen "beschneiden", an denen die Beschriftungen angezeigt werden sollen, und die Beschriftungen werden in den Lücken angezeigt.
In diesem Fall lauteten meine Beschriftungseinstellungen:
Hoffentlich hilft das!
quelle
Ich verwende die Option "Puffer" auf der Registerkarte "Etiketteneinstellung". (Verwenden Sie die Schaltfläche "Beschriftungen", nicht die Option "Alte Beschriftungen" im Dialogfeld "Ebeneneigenschaften".) Dadurch wird die Konturlinie nicht wie gewünscht verwischt, aber die Beschriftung wird lesbar.
quelle
Ich denke, das Beste, was mit den aktuellen QGIS-Fähigkeiten erreicht werden kann, ist die Verwendung des Halo- (oder Hintergrund-) Effekts mit Farben aus der Tabelle, die auf dem Höhenwert und dem Farbschema basieren, die für das zugrunde liegende Raster verwendet werden. Natürlich wäre dies nicht berücksichtigt Schummerungs und alles andere unter dem Halo in der Karte. Beispiel für zufällige Farben: Mit ein bisschen Code könnte dies als Funktion zur Darstellung der Rasterfarbe umgeschrieben werden.
Theoretisch sollte es möglich sein, benutzerdefiniertes Linienmuster und Label Repeat + Offset zu verwenden . Leider gibt es keine Einstellung für den Etikettenversatz.
quelle
Nachdem ich kürzlich auf dasselbe Problem gestoßen bin, habe ich ein QGIS-Python-Skript zusammengestellt, um das schwere Heben durchzuführen. Das Skript mit einigen Testdaten (Großbritannien), Readme-Datei (Handbuch) und verwendeten Stylesheets finden Sie unter https://github.com/pjgeng/Contour-Labels
Kurz gesagt, das Skript verwendet zwei Vektorebenen als Eingabe - die mit Anmerkungen versehene Konturenebene und eine "Hilfslinien" -Ebene. Letzteres besteht aus Polylinien, die die Konturen an den gewünschten Etikettenpositionen schneiden.
Das Skript erarbeitet dann basierend auf dem Abstand zwischen Konturen und dem Indexkonturintervall, auf das die Beschriftungen angewendet werden sollen, fügt den Beschriftungspunkten einen Rotationswert hinzu und schneidet schließlich die ursprüngliche Konturebene ab, um die Lücken zu erzeugen.
Der Ansatz funktioniert besonders gut, wenn der Benutzer Konturenkarten in unterschiedlichen Intervallen im selben Bereich erstellen muss (dh die Hilfslinien ändern sich nicht). Ein Nachteil ist die Unfähigkeit, die Etikettenposition zu ändern, wenn das Skript beendet ist. Hierzu müsste der Benutzer die Hilfslinien anpassen und das Skript erneut mit der ursprünglichen Eingabe ausführen. Früher habe ich viel mit Puffern um Etiketten gearbeitet, um den unterbrochenen Effekt zu erzeugen, aber dies stellte sich bei vektordatengesteuerten Karten als ästhetisch unangenehm heraus.
Leider kann ich zur Zeit keine Bilder mehr hinzufügen, um den Vorgang weiter zu dokumentieren oder zu veranschaulichen.
PS: Wenn Sie die im Repository bereitgestellten Stilebenen verwenden, müssen Sie möglicherweise die benutzerdefinierten Felder für "Drehung", "Beschriftung anzeigen" und "Immer anzeigen" im Beschriftungsmenü "aktivieren". Bei einigen Installationen von QGIS werden diese automatisch aus dem Stylesheet übernommen - ich habe noch nicht herausgefunden, woran das liegt.
quelle
Erinnerst du dich an diesen Thread Martin? Ich kann mir nur vorstellen, einer Lösung für Ihr Problem nahe zu kommen, indem ich Ihre Konturebene mit einer abgeschnittenen Konturebene überschreibe, diese zum Beschriften verwende und die Linienfarbe in etwas Neutrales ändere, das die Konturen unter den Beschriftungen maskiert. man hofft, ohne zu aufdringlich zu sein. N.
Später hinzugefügt: Es könnte sich lohnen, sich auch diesen Thread anzuschauen, die zweite Antwort. Vielleicht könnte das Brechen der Konturlinien eine Antwort sein, vielleicht unter Verwendung der Pufferebene, die zum Ausschneiden der Konturen verwendet wird?
quelle
Hier ist eine weitere Lösung für das Problem der QGIS-Konturetiketten-Maskierung, bei der ich die Spatialite-Funktionalität von QGIS (derzeit QGIS 3.x) zusammen mit einem Geometriegenerator für die Etikettenplatzierung nutze.
Diese sehr dynamische Lösung ermöglicht es uns, alle Beschriftungstextgrößen und Beschriftungspositionen sofort zu ändern und sogar einen PDF-Vektorexport zu überstehen!
Um dies zu ermöglichen, benötigen wir folgende Teile:
Eine virtuelle Ebene mit dem Namen "contours_with_labels" mit regelbasiertem Stil:
Regel 2: ELSE… einfache Linie
und einen bedingten Etikettentext für Regel 1:
Und zu guter Letzt folgt hier die SQL-Abfrage für die virtuelle Ebene:
Das ist es.
Vielen Dank an alle diese begeisterten Menschen, die dies möglich machen!
quelle
ESRI-Blogeintrag: http://blogs.esri.com/esri/arcgis/2011/11/28/variable-depth-masking-contour-label-example/
Die Maskierung mit variabler Tiefe für Konturetiketten umfasst drei Schritte:
1Erstellen von Anmerkungen aus den Beschriftungen, 2Erstellen von Masken mit dem Werkzeug "Feature-Gliederungsmasken" und 3Erstellen von Masken mit den Einstellungen "Erweiterte Zeichenoptionen"> "Maskieren".
quelle