最初のラベルがQGISに適合しない場合、代替ラベルに変更しますか?


10

印刷するマップを作成しようとしていますが、ポリゴンのサイズが大きく異なります。これは参照マップになるので、すべてのポリゴンにラベルを付ける必要がありますが、一部の名前はポリゴンに収まりません。そのような場合は、代わりに機能IDを使用し、IDを名前にリンクする属性テーブルを用意します。

私がやりたいのは、マップで使用するラベルと属性テーブルに含める行を選択するために使用できるある種の式です。このようなisLabelledものは、マップの縮尺、ラベルの長さ、フォントサイズなどを考慮に入れることができます。


2
同じフィーチャクラスのポリゴンにさまざまな方法でラベルが付けられ、さらにそれらの一部だけが属性テーブルに表示される場合、マップのユーザーを混乱させる可能性があることに注意してください。
タリストローン

私はGBの郡マップを考えています
Ian Turton

フォントを動的に変更して合わせるのはどうですか?最長の機能の寸法を取り、ラベル文字列の文字数で除算し、スケールを使用していくつかの計算を行うか、単にそれを使用して、既に設定されているフォントサイズを変更します...または、その測定値(最長feature dimension / len of string)、それが長すぎる場合は、IDのラベル。
ジェシーマクミラン2017年

私は、フォントサイズを台無しにしたくないので、ほとんど私は読みやすさに関係しています
イアンTurton

1
ラベル、フォントサイズ、およびスケールを取り、収まる場合はtrueまたはfalseを返すPythonカスタム式を使用できます。次に、式エンジンでif句を使用してラベルを切り替えます。後で例を挙げて、答えを作成します。
ジェシーマクミラン2017年

回答:


8

これを行うには、多少おおよその(しかしうまくいけば効果的)方法があります。

最初にいくつかの数学。機能に含めることができる特定のフォントサイズの文字数を把握する必要があります。ここで知っておくべきこと/仮定:

  • メートル法の単位であると仮定します(これをわずかに変更したため、足のcrsでこれが機能する場合があります)。
  • フォントサイズはフォントの高さの尺度です。ほとんどのフォントの幅は、高さの約半分です。
  • フォントの高さとしてptを使用すると、1ptはおおよそ0.035CMです
  • あなたの区画がおおよそ長方形/規則的であると仮定します

アイテムが画面上にある長さ/印刷を見つけるには、最長寸法(長さまたは高さ、またはラベルが水平方向のみの場合は長さ)/スケール* 100(MからCMに移動)を使用できます。

次に、ラベルが適合するかどうかを確認できます。

すべてを式エンジンで実行できますが、カスタムPython式の方が効率的です。これを作成する方法のチュートリアルです。

私のカスタム表現:

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

次に、その式をラベルで使用します。

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

もちろん、実際に使用している属性をすべてプラグインし、フォントサイズを8から使用しているものに変更する必要があります。また、フォントはかなり異なるため、正しく表示されるまで少し微調整する必要がある場合があります。

この式を使用して、ラベルが適合するかどうかに基づいて色を変更することなどもできます。


この式をマップキャンバスの外部(つまり、コンポーザーラベルまたは属性テーブル)で使用するには、プログラムで特定のマップアイテムの縮尺を取得する方法が必要です。これを達成するためのコードをここに別の答え投稿しまし 。そこのメソッドは、式getScale( 'composername'、 'mapname')を与えて、それを式に組み込みます:

if(
    labelFits( "yourAttribute" , 8 , getScale('composername','mapname')),
    "yourAttribute",$id)

1
私も似たようなことを考えていました。特に、マップ単位とメートル単位の投影を使用している場合。ラベルが重心の中央にあると仮定すると、new(ish)ジオメトリオペレーターもここで役立ちます。これは、プロポーショナルフォントよりも固定幅(等幅)フォントの方がうまく機能します(たとえば、「W」は「i」よりもはるかに幅が広い場合など)。ここまで進んでいますが、プロポーショナルフォントとカーニングによって複雑さが増すのではないかと思います。
スティーブンケイ

pilのimagefont.getsize()を使用できます。これにより、選択したフォントでレンダリングされた文字列の幅が正確になりますが、パフォーマンスに大きな影響があると思います。上記の大まかな計算は、画面に何百ものラベルがある場合は特に、はるかに単純です
Jesse McMillan

唯一のマイナーな問題は、関数がPrint Composerの属性テーブルのフィルターとして機能していないように見えることです。
Ian Turton

マップの縮尺はページごとに異なりますか?@map_scale変数ではなく、手動で縮尺を入力してみてください。私の推測では、属性テーブルにはマップの縮尺を知る方法がありません。(たとえば、さまざまな縮尺でcomposerに複数のマップアイテムを含めることができるため)
Jesse McMillan

1
@iantプログラムで作曲家マップのスケールを取得する別のカスタム式へのリンクを投稿しました。
ジェシーマクミラン2017年


1

同様の状況で、道路レイヤーのすべての道路にラベルを付ける義務がありました。私の解決策は、キャンバスをより大きなサイズで作成し、PDFにエクスポートしてから、PDFを必要なサイズに印刷することでした。

たとえば、完成品はA3である必要がありました。A3のキャンバスでは、すべてのラベルを合わせることができませんでした。だから私はキャンバスをA2にして、すべてのラベルが見えるようにしました。A2サイズの地図のPDFを作成し、A3として印刷します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.