Wechseln Sie zu einem alternativen Etikett, wenn das erste Etikett nicht in QGIS passt?

10

Ich versuche, eine Karte zum Ausdrucken zu erstellen, und die Größe meiner Polygone variiert stark. Da dies eine Referenzkarte ist, muss ich jedes Polygon beschriften, aber einige der Namen passen nicht in das Polygon. In diesen Fällen möchte ich stattdessen die Feature-ID verwenden und dann eine Attributtabelle die ID mit dem Namen verknüpfen lassen.

Was ich tun möchte, ist eine Art Ausdruck, mit dem ich auswählen kann, welche Beschriftung auf der Karte verwendet werden soll und welche Zeilen in die Attributtabelle aufgenommen werden sollen. So etwas isLabelledkönnte den Kartenmaßstab, die Etikettenlänge, die Schriftgröße usw. berücksichtigen.

Ian Turton
quelle
2
Beachten Sie, dass es für den Benutzer der Karte verwirrend sein kann, wenn Polygone derselben Feature-Class auf unterschiedliche Weise beschriftet werden und zusätzlich nur einige davon in einer Attributtabelle angezeigt werden.
Tallistroan
Ich denke an eine Landkarte von GB
Ian Turton
Was ist mit der dynamischen Änderung der Schriftart? Sie können die längste der Feature-Dimensionen verwenden, durch die Anzahl der Zeichen in der Beschriftungszeichenfolge dividieren und entweder mit der Skalierung rechnen oder diese verwenden, um Ihre bereits festgelegte Schriftgröße zu ändern ... Alternativ können Sie diese Kennzahl verwenden (längste) Feature Dimension / Länge der Zeichenfolge) und wenn es zu lang ist, beschriften Sie mit der ID.
Jesse McMillan
Meistens geht es mir um Lesbarkeit, damit ich mich nicht mit der Schriftgröße
anlegen
1
Sie können einen benutzerdefinierten Python-Ausdruck verwenden, der die Bezeichnung, die Schriftgröße und die Skalierung übernimmt und true oder false zurückgibt, wenn dies passt. Verwenden Sie dann in der Ausdrucks-Engine eine if-Klausel, um die Beschriftungen zu wechseln. Ich werde später eine Antwort mit Beispielen für Sie ausarbeiten.
Jesse McMillan

Antworten:

8

Hier ist eine etwas ungefähre (aber hoffentlich effektive) Möglichkeit, dies zu tun.

Zuerst etwas Mathe. Wir müssen herausfinden, wie viele Zeichen bei einer bestimmten Schriftgröße ein Feature enthalten kann. Hier Dinge / Annahmen zu wissen:

  • unter der Annahme von metrischen Einheiten (hinzugefügte geringfügige Änderung, die dazu führen kann, dass dies für uns Fuß-Crs funktioniert.)
  • Die Schriftgröße ist ein Maß für die Schrifthöhe. Die meisten Schriftarten sind etwa halb so breit wie hoch.
  • Bei Verwendung von pt für die Schrifthöhe beträgt 1pt ungefähr 0,035 cm
  • Angenommen, Ihre Pakete sind ungefähr rechteckig / regelmäßig

Um herauszufinden, wie lange ein Artikel auf dem Bildschirm / Druck angezeigt wird, können Sie die längste Abmessung (Länge oder Höhe oder nur Länge, wenn Ihre Etiketten nur horizontal sind) / Skala * 100 (von M nach CM) verwenden.

Dann können wir sehen, ob unser Etikett passt.

Sie könnten alles in der Ausdrucks-Engine tun, aber ein benutzerdefinierter Python-Ausdruck wäre effizienter. Hier ist ein Tutorial zum Erstellen eines solchen.

Mein benutzerdefinierter Ausdruck:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def labelFits(labelStr, fontPt, scaleM, feature, parent):
    # returns true if a label will fit in the feature at a given
    # font size and scale

    bbox = feature.geometry().boundingBox()

    # for CRS in us foot
    # fontWidth = fontPt * 0.0875

    # for CRS in metric
    # 1pt = 0.035CM
    fontWidth = fontPt * 0.035 * 0.5

    # length of maximum dimension on-screen/print in CM
    labelRoom =  max(bbox.width(),bbox.height()) / scaleM * 100

    # approx length of our label in CM based on font height * 0.5
    labelLen = len(labelStr) * fontWidth

    if labelRoom > labelLen:
        return True
    else:
        return False

Verwenden Sie dann einfach diesen Ausdruck im Etikett:

if(labelFits( "yourAttribute" , 8 , @map_scale ), "yourAttribute",$id)

Sie müssen natürlich jedes Attribut einfügen, das Sie tatsächlich verwenden, und die Schriftgröße von 8 auf das ändern, was Sie verwenden. Da die Schriftarten sehr unterschiedlich sind, müssen Sie sie möglicherweise ein wenig anpassen, bis sie richtig aussehen.

Sie können diesen Ausdruck auch verwenden, um beispielsweise die Farbe zu ändern, je nachdem, ob das Etikett passt oder nicht.


Um diesen Ausdruck außerhalb des Kartenbereichs (dh in einer Komponistenbeschriftung oder Attributtabelle) zu verwenden, benötigen wir eine Möglichkeit, den Maßstab eines bestimmten Kartenelements programmgesteuert abzurufen. Ich habe Code veröffentlicht, um dies in einer anderen Antwort hier zu erreichen. Die dortige Methode gibt uns einen Ausdruck getScale ('composername', 'mapname'), um ihn in unseren Ausdruck aufzunehmen:

if(
    labelFits( "yourAttribute" , 8 , getScale('composername','mapname')),
    "yourAttribute",$id)
Jesse McMillan
quelle
1
Ich dachte auch an etwas Ähnliches. Besonders wenn Karteneinheiten und eine Projektion in Metern verwendet werden. Die neuen (ish) Geometrieoperatoren könnten auch hier helfen, vorausgesetzt, die Beschriftungen sind auf dem Schwerpunkt zentriert. Dies funktioniert besser mit einer Schriftart mit fester Breite (monospaced) als mit einer proportionalen Schriftart (wobei ein 'W' beispielsweise viel breiter als ein 'i' ist). Sie haben hier etwas vor, aber ich vermute, dass proportionale Schriftarten und Kerning die Komplexität erhöhen werden.
Steven Kay
Sie können pils imagefont.getsize () verwenden. Das würde Ihnen eine genaue Breite einer Zeichenfolge geben, die in der von Ihnen gewählten Schriftart gerendert wird, aber ich denke, das hätte einen großen Leistungseinbruch zur Folge. Die grobe Mathematik oben ist viel einfacher, besonders wenn Sie Hunderte von Etiketten auf dem Bildschirm haben
Jesse McMillan
Das einzige kleine Problem ist, dass die Funktion in Attributtabellen in Print Composer nicht als Filter zu funktionieren scheint.
Ian Turton
Variiert Ihr Kartenmaßstab von Seite zu Seite? Versuchen Sie, die Skalierung manuell anstelle der Variablen @map_scale einzugeben. Ich vermute, die Attributtabelle hat keine Möglichkeit, Ihren Kartenmaßstab zu kennen. (Weil Sie zum Beispiel mehrere Kartenelemente in Composer in verschiedenen Maßstäben haben könnten)
Jesse McMillan
1
@iant Ich habe einen Link zu einem anderen benutzerdefinierten Ausdruck gepostet, der den Maßstab Ihrer Composer-Map programmgesteuert abruft.
Jesse McMillan
3

Duplizieren Sie die Ebene, eine ohne Symbologie, und legen Sie für jede Beschriftung unterschiedliche Zoomstufen / Hinderniseinstellungen für die Beschriftungen fest.

Tom Chadwin
quelle
1

Ich hatte eine ähnliche Situation mit der Verpflichtung, jede Straße in einer Straßenschicht zu kennzeichnen. Meine Lösung bestand darin, die Leinwand in einer größeren Größe zu erstellen, in PDF zu exportieren und die PDF-Datei dann in der erforderlichen Größe zu drucken.

Zum Beispiel musste das fertige Produkt A3 sein. Auf der Leinwand bei A3 konnte ich nicht alle Etiketten anbringen. Also habe ich die Leinwand A2 gemacht und so konnten alle Etiketten gesehen werden. Erstellen Sie ein PDF der Karte im Format A2 und drucken Sie es als A3 aus.

Johanna
quelle