첫 번째 라벨이 QGIS에 맞지 않으면 대체 라벨로 변경 하시겠습니까?


10

인쇄 할 맵을 만들려고하는데 폴리곤의 크기가 크게 다릅니다. 이것이 참조 맵이므로 모든 다각형에 레이블을 지정해야하지만 일부 이름은 다각형에 맞지 않습니다. 이 경우 대신 기능 ID를 사용하고 속성 테이블을 사용하여 ID를 이름에 연결하고 싶습니다.

내가하고 싶은 것은지도에서 사용할 레이블과 속성 테이블에 포함 할 행을 선택하는 데 사용할 수있는 일종의 표현식입니다. 그런 식으로 isLabelled맵 스케일, 레이블 길이, 글꼴 크기 등을 고려할 수 있습니다.


2
동일한 피쳐 클래스의 다각형에 다른 방식으로 레이블이 지정되고 추가로 일부가 속성 테이블에 나타날 때 맵 사용자에게는 혼동을 줄 수 있습니다.
tallistroan

GB의 카운티지도를 생각하고 있습니다
Ian Turton

글꼴을 동적으로 변경하려면 어떻게해야합니까? 가장 긴 피처 차원을 가져 와서 레이블 문자열의 문자 수로 나눈 다음 스케일로 수학을 수행하거나 이미 설정된 글꼴 크기를 변경하는 데 사용할 수 있습니다. feature dimension / len of string) 및 ID가 너무 긴 라벨 인 경우.
Jesse McMillan

대부분 가독성에 관심이 있으므로 글꼴 크기를 엉망으로 만들고 싶지 않습니다
Ian Turton

1
레이블, 글꼴 크기 및 크기를 사용하여 적합하면 true 또는 false를 반환하는 Python 사용자 정의 표현식을 사용할 수 있습니다. 그런 다음 표현식 엔진에서 if 절을 사용하여 레이블을 전환하십시오. 나중에 예제를 통해 답변을 드리겠습니다.
Jesse McMillan

답변:


8

여기에 대략적인 (그러나 희망적으로 효과적인) 방법이 있습니다.

먼저 수학. 지형지 물에 포함 할 수있는 특정 글꼴 크기의 문자 수를 파악해야합니다. 알아야 할 사항 / 가정 :

  • 미터법 단위를 가정 할 때 (아래에 약간의 변경 사항이 추가되어이 문제가 해결 될 수 있습니다.)
  • 글꼴 크기는 글꼴 높이를 측정 한 것입니다. 대부분의 글꼴은 높이의 절반 정도입니다.
  • 글꼴 높이에 pt를 사용하면 1pt는 대략 0.035CM입니다.
  • 소포가 대략 직사각형 / 규칙적이라고 가정

항목이 화면 / 인쇄되는 시간을 찾으려면 가장 긴 치수 (길이 또는 높이 또는 레이블이 가로 인 경우 길이) / 스케일 * 100 (M에서 CM으로 이동)을 사용할 수 있습니다.

그런 다음 라벨이 맞는지 확인할 수 있습니다.

식 엔진에서 모든 작업을 수행 할 수 있지만 사용자 지정 파이썬식이 더 효율적입니다. 다음 은 튜토리얼을 만드는 방법에 대한 튜토리얼입니다.

내 맞춤 표현 :

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
나도 비슷한 것을 생각하고 있었다. 특히지도 단위와 미터 단위의 투영을 사용하는 경우. 레이블이 중심에 있다고 가정하면 새로운 (ish) 기하 연산자가 여기에서 도움이 될 수 있습니다. 비례 글꼴보다 고정 폭 (단일 ​​간격) 글꼴을 사용하면 더 효과적입니다 (예 : 'W'가 'i'보다 훨씬 넓은 경우). 당신은 여기에 뭔가 있지만, 나는 비례 글꼴과 커닝이 복잡성을 더할 것이라고 생각합니다.
Steven Kay

pil의 imagefont.getsize ()를 사용할 수 있습니다. 선택한 글꼴로 렌더링 된 문자열의 정확한 너비를 제공하지만 성능이 크게 떨어질 것이라고 생각합니다. 화면에 수백 개의 레이블이있는 경우 위의 대략적인 수학이 훨씬 간단합니다.
Jesse McMillan

유일한 사소한 문제는 함수가 인쇄 작성기의 속성 테이블에서 필터로 작동하지 않는 것입니다.
Ian Turton

지도 규모가 페이지마다 다릅니 까? @map_scale 변수 대신 수동으로 스케일을 입력하십시오. 내 생각에 속성 테이블에는 맵 스케일을 알 수있는 방법이 없습니다. (예를 들어 작곡가에 여러 규모의지도 항목이 여러 개있을 수 있기 때문에)
Jesse McMillan

1
@iant 나는 작곡가의 규모를 프로그래밍 방식으로 얻을 수있는 다른 사용자 정의 표현식에 대한 링크를 게시했습니다.
Jesse McMillan

3

심볼이없는 레이어를 복제하고 각 레이블에 대한 확대 / 축소 수준 / 장애 설정을 다르게 설정하십시오.


1

도로 층의 모든 도로에 라벨을 붙여야하는 의무와 비슷한 상황이있었습니다. 내 해결책은 캔버스를 더 큰 크기로 만들고 PDF로 내보내고 필요한 크기로 PDF를 인쇄하는 것이 었습니다.

예를 들어, 완제품은 A3이어야했습니다. A3의 캔버스에는 모든 레이블을 넣을 수 없었습니다. 그래서 캔버스 A2를 만들었고 모든 레이블을 볼 수있었습니다. A2 크기 맵의 PDF를 작성하여 A3으로 인쇄하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.