겹치는 지점의 레이블을 하나의 레이블로 결합 / 병합 할 수 있습니까?


12

샘플 위치를 나타내는 포인트가 있습니다. 종종 동일한 위치에서 여러 샘플을 채취합니다. 위치는 동일하지만 샘플 ID 및 기타 속성이 다른 여러 포인트입니다. 해당 지점에있는 모든 지점의 모든 샘플 ID를 나열하는 누적 텍스트와 함께 단일 레이블과 함께 배치 된 모든 지점에 레이블을 지정하려고합니다.

ArcGIS에서 일반 레이블 엔진 또는 Maplex를 사용하여 이것이 가능합니까? 하나의 속성 값으로 각 위치에 대한 모든 샘플 ID로 새 레이어를 만들어이 문제를 해결할 수 있지만 레이블링을 위해 새 데이터를 만드는 것을 피하고 싶습니다.

기본적으로 나는 이것에서 가고 싶다 :

여기에 이미지 설명을 입력하십시오

이것에 (가장 높은 점) :

여기에 이미지 설명을 입력하십시오

라벨을 수동으로 편집하지 않아도됩니다.


데이터 세트에 몇 점이 있습니까?
혼 비드

답변:


11

이를 수행하는 한 가지 방법은 정의 쿼리를 사용하여 레이어를 복제하고 첫 번째 레이어의 왼쪽 위만 레이블 위치를 사용하고 두 번째 레이어는 왼쪽 아래 만 사용하여 별도로 레이블을 지정하는 것입니다.

THEFIELD 유형 정수를 레이어에 추가하고 아래 표현식을 사용하여 채 웁니다.

aList=[]
def FirstOrOthers(shp):
 global aList
 key='%s%s' %(round(shp.firstPoint.X,3),round(shp.firstPoint.Y,3))
 if key in aList:
  return 2   
 aList.append(key)
 return 1

다음으로 전화하십시오 :

FirstOrOthers( !Shape! )

목차에 레이어 사본을 작성하고 정의 쿼리 THEFIELD = 1을 적용하십시오.

원본 레이어에 정의 쿼리 THEFIELD = 2를 적용합니다.

다른 고정 레이블 배치 적용

여기에 이미지 설명을 입력하십시오

원래 솔루션에 대한 의견을 기반으로 업데이트 :

COORD 필드를 추가하고 다음을 사용하여 채 웁니다.

'%s %s' %(round( !Shape!.firstPoint.X,2),round( !Shape!.firstPoint.Y,2))

레이블의 첫 번째와 마지막을 사용하여이 필드를 요약하십시오. COORD 필드를 사용하여이 테이블을 다시 원래 테이블로 결합하십시오. firs <> last가있는 레코드를 선택하고 다음을 사용하여 새 필드에서 첫 번째 레이블과 마지막 레이블을 연결하십시오.

'%s\n%s' %(!Sum_Output_4.First_MUID!, !Sum_Output_4.Last_MUID!)

Count_COORD 및 THEFIELD를 사용하여 2 개의 '다른 레이어'와 필드를 정의하여 레이블을 지정하십시오.

여기에 이미지 설명을 입력하십시오

@Hornbydd 솔루션에서 영감을 얻은 업데이트 # 2 :

import arcpy
def FindLabel ([FID],[MUID]):
  f,m=int([FID]),[MUID]
  mxd = arcpy.mapping.MapDocument("CURRENT")
  dFids={}
  dLabels={}
  lyr = arcpy.mapping.ListLayers(mxd,"centres")[0]
  with arcpy.da.SearchCursor(lyr,["FID","SHAPE@","MUID"]) as cursor:
    for row in cursor:
       FD,shp,LABEL=row
       XY='%s %s' %(round(shp.firstPoint.X,2),round( shp.firstPoint.Y,2))
       if f == FD:
         aKey=XY
       try:
          L=dFids[XY]
          L+=[FD]
          dFids[XY]=L
          L=dLabels[XY]
          L=L+'\n'+LABEL
          dLabels[XY]=L
       except:
          dFids[XY]=[FD]
          dLabels[XY]=LABEL
  Labels=dLabels[aKey]
  Fids=dFids[aKey]
  if f == Fids[0]:
    return Labels
  return ""

2016 년 11 월 업데이트.

아래의 2000 번 복제본에서 테스트 된 표현식은 매력처럼 작동합니다.

mxd = arcpy.mapping.MapDocument("CURRENT")
lyr = arcpy.mapping.ListLayers(mxd,"centres")[0]
dFids={}
dLabels={}
fidKeys={}
with arcpy.da.SearchCursor(lyr,["FID","SHAPE@","MUID"]) as cursor:
 for FD,shp,LABEL in cursor:
  XY='%s %s' %(round(shp.firstPoint.X,2),round( shp.firstPoint.Y,2))
  fidKeys[FD]=XY
  if XY in dLabels:
   dLabels[XY]+=('\n'+LABEL)
   dFids[XY]+=[FD]
  else:
   dLabels[XY]=LABEL
   dFids[XY]=[FD]

def FindLabel ([FID]):
  f=int([FID])
  aKey=fidKeys[f]
  Fids=dFids[aKey]
  if f == Fids[0]:
    return dLabels[aKey]
  return "

이봐, 너 금이 갔어! 좋은! 누군가저기서 울음을 알았습니다! 예상대로 매우 반복적 인 프로세스이므로 큰 데이터 세트에서 실행되고 레이블이 그려집니다 (테스트 데이터에서 잘 수행 됨). 몇 줄을 확장하여 코드 스타일을 조정했습니다. 나는 한 줄에 미니멀리스트가 따르기가 어렵다는 것을 안다.
Hornbydd

1
@Hornbydd 편집 해 주셔서 감사합니다. 이 너트는 라벨 (엔진?) 동작으로 인해 깨지기 어려웠습니다. 모든 함수 매개 변수를 문자열로 취급합니다! 이것이 첫 번째 IF가 f = int ([FID])없이 작동하지 않는 이유입니다. 속도와 관련하여 50 포인트보다 큰 세트에서는 사용하지 않습니다. 데이터 세트를 두 번만 통과하여 새 필드를 채우는 스크립트로 변환해야합니다 .1) 두 사전을 컴파일하기 위해 검색 커서, 2) 커서를 업데이트하여 읽을 수 있습니다. 참고 : try 문 후 첫 3 줄은 솔루션 I를 게시 한 후 사용되지 않습니다. 안전하게 제거 할 수 있다는 것을 깨달았습니다.
FelixIP

참고로 다시 돌아올 기회는 없었지만 다음 주에 솔루션에 소용돌이를 줄 계획입니다. 파이썬이없는 또 다른 해결 방법 (이 경우에는 내가 사용한 것)이 있습니다. 그에 대한 답변도 게시 할 것입니다.
Dan C

지오넷 에서이 페이지를 방문 했습니다. 나는 글로벌 사전을 영리하게 사용하는 것이 좋았고이 Q & A에 대해 생각하고 그것에 대한 링크를 추가했습니다.
Hornbydd

@Hornbydd 네, 그것은 Richard의 모든 것처럼 매우 똑똑하고 상세하며 내 (우리) 솔루션과 큰 차이를 만들 것입니다. 첫 번째 라인을 포함하는 몇 개의 라인을 제거함으로써 더 개선 될 수있다. 그러나 그가 흥미를 잃었 보인다 OP에서 응답 시간을 기준으로, 나도 귀찮게하지 않습니다
FelixIP

4

아래는 부분 솔루션입니다.

이것은 Advance 레이블 표현식으로 들어갑니다. 따라서 매우 효율적이지 않으므로 데이터 세트의 포인트 수에 대해 묻습니다. 따라서 레이블이 지정된 각 행에 대해 d키가 XY이고 값이 텍스트이고 d2objectID 및 XY 인 2 개의 사전을 빌드합니다 . 그 사전 조합을 사용하면 개행 문자와 연결되는 단일 레이블을 반환 할 수 있습니다.이 예제에서는 TARGET_FID를 연결합니다. "sj"는 TOC의 레이어 이름입니다.

import arcpy
def FindLabel ( [OBJECTID] ):
  ob = str([OBJECTID])
  mxd = arcpy.mapping.MapDocument("CURRENT")
  d ={}
  d2 = {}
  lyr = arcpy.mapping.ListLayers(mxd,"sj")[0]
  with arcpy.da.SearchCursor(lyr,["OID@","SHAPE@XY","TARGET_FID"]) as cursor:
    for row in cursor:
      objID = str(row[0])
      temp = row[1]
      tup = str(temp[0]) + "," + str(temp[1])
      d2[objID] = tup
      txt = str(row[2])
      if tup in d:
        v = d[tup] 
        v = v + "\n" + txt
        d[tup] = v
      else:
        d[tup] = txt  
  temp = d2[ob]
  return d[temp]

이것이 부분적인 해결책 인 이유는 이것이 모든 지점에 대해 수행된다는 것입니다. 다른 모든 누적 지점을 끄는 방법을 생각할 수 없었습니다. 이 때문에 궁극적 인 솔루션은 포인트 스택에서 빌드 된 단일 레이블로 단일 포인트의 새 레이어를 작성하는 파이썬이라고 생각합니다.

아래는 3 개의 누적 된 점의 출력입니다. 각 점이 동일한 위치에 있기 때문에 각 점에 대해 레이블이 생성되어 있습니다.

예

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