Các nhãn cho các điểm chồng chéo có thể được kết hợp / hợp nhất thành một nhãn không?


12

Tôi có điểm đại diện cho các địa điểm mẫu. Thông thường, nhiều mẫu sẽ được lấy ở cùng một vị trí: nhiều điểm có cùng vị trí nhưng ID mẫu khác nhau và các thuộc tính khác. Tôi muốn gắn nhãn tất cả các điểm được đặt cùng một nhãn, với văn bản xếp chồng liệt kê tất cả các ID mẫu của tất cả các điểm trong vị trí đó.

Điều này có thể có trong ArcGIS bằng cách sử dụng công cụ ghi nhãn thông thường hoặc Maplex không? Tôi biết tôi có thể giải quyết vấn đề này bằng cách tạo một lớp mới với tất cả ID mẫu cho từng vị trí trong một giá trị thuộc tính nhưng tôi muốn tránh tạo dữ liệu mới chỉ để ghi nhãn.

Về cơ bản tôi muốn đi từ đây:

nhập mô tả hình ảnh ở đây

Về điều này (cho điểm cao nhất):

nhập mô tả hình ảnh ở đây

Không làm bất kỳ chỉnh sửa thủ công của các nhãn.


Có bao nhiêu điểm trong tập dữ liệu của bạn?
Hornbydd

Câu trả lời:


11

Một cách để làm điều này là nhân bản lớp, sử dụng các truy vấn định nghĩa và gắn nhãn riêng cho chúng, sử dụng vị trí nhãn chỉ phía trên bên trái cho lớp đầu tiên và phía dưới bên trái trong giây.

Thêm số nguyên kiểu THEFIELD vào lớp và điền nó bằng biểu thức bên dưới:

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

Gọi nó bằng cách:

FirstOrOthers( !Shape! )

Tạo một bản sao của lớp trong bảng nội dung, áp dụng truy vấn định nghĩa THEFIELD = 1.

Áp dụng truy vấn định nghĩa THEFIELD = 2 cho lớp gốc.

Áp dụng vị trí nhãn cố định khác nhau

nhập mô tả hình ảnh ở đây

CẬP NHẬT dựa trên ý kiến ​​cho giải pháp ban đầu:

Thêm trường COORD và điền vào nó bằng cách sử dụng

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

Tóm tắt lĩnh vực này bằng cách sử dụng đầu tiên và cuối cùng cho nhãn. Tham gia bảng này trở lại ban đầu bằng cách sử dụng trường COORD. Chọn các bản ghi trong đó linh hồn <> cuối cùng và ghép nhãn đầu tiên và cuối cùng trong một trường mới bằng cách sử dụng

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

Sử dụng Count_COORD và THEFIELD để xác định 2 'lớp khác nhau' và các trường để gắn nhãn cho chúng:

nhập mô tả hình ảnh ở đây

Cập nhật # 2 lấy cảm hứng từ giải pháp @Hornbydd:

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 ""

CẬP NHẬT tháng 11 năm 2016, hy vọng cuối cùng.

Biểu thức dưới đây đã thử nghiệm trên 2000 bản sao, hoạt động như bùa mê:

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 "

Này bạn đã crack nó! Đẹp! Tôi biết có ai đó điên cuồng ngoài kia! Như tôi dự đoán, đó là một quá trình lặp đi lặp lại vì vậy hãy chạy trên một tập dữ liệu lớn và các nhãn phải mất để vẽ (nó cũng đã làm trên dữ liệu thử nghiệm của tôi). Tôi đã điều chỉnh kiểu mã của bạn bằng cách mở rộng một vài dòng. Tôi thấy tối giản, tất cả trên một dòng khó theo dõi.
Hornbydd 29/07/2015

1
@Hornbydd cảm ơn đã chỉnh sửa. Đai ốc này rất khó bị nứt do hành vi của nhãn (động cơ?). Nó coi tất cả các tham số hàm là chuỗi! Đây là lý do tại sao IF đầu tiên không hoạt động mà không có f = int ([FID]). Về tốc độ tôi sẽ không bao giờ sử dụng nó trên một tập hợp lớn hơn 50 điểm. Nó phải được chuyển đổi thành tập lệnh tạo ra trường mới bằng cách chỉ đi qua tập dữ liệu hai lần: 1) con trỏ tìm kiếm để biên dịch cả hai từ điển, 2) con trỏ cập nhật để đọc từ chúng LƯU Ý: 3 dòng đầu tiên sau câu lệnh try đã lỗi thời, sau khi đăng giải pháp I nhận ra họ có thể được gỡ bỏ một cách an toàn.
FelixIP

FYI Tôi chưa có cơ hội để quay lại vấn đề này nhưng tôi dự định sẽ đưa ra giải pháp cho bạn trong tuần tới. Ngoài ra còn có một cách giải quyết khác (cái tôi đã sử dụng trong trường hợp này) không có Python, tôi cũng sẽ đăng câu trả lời về điều đó.
Dan C

Đã qua trang này trên geonet. Tôi thích cách sử dụng thông minh của từ điển toàn cầu sau đó nghĩ về câu hỏi này và thêm một liên kết đến nó.
Hornbydd 27/8/2015

@Hornbydd vâng, nó rất thông minh và chi tiết như mọi thứ từ Richard và sẽ tạo ra sự khác biệt lớn cho giải pháp (của chúng tôi) của tôi. Người ta có thể cải thiện hơn nữa bằng cách loại bỏ một vài dòng trong đó có dòng đầu tiên. Tuy nhiên, dựa trên thời gian phản hồi từ OP, có vẻ như anh ấy đã mất hứng thú, tôi cũng không bận tâm
FelixIP

4

Dưới đây là một giải pháp một phần.

Điều này đi vào biểu thức nhãn Advance. Nó không hiệu quả lắm do đó tôi hỏi về số điểm trong tập dữ liệu của bạn. Vì vậy, đối với mỗi hàng được gắn nhãn, nó xây dựng 2 từ điển dtrong đó khóa là XY và giá trị là văn bản và d2đó là objectID và XY. Sử dụng kết hợp từ điển đó, nó có thể trả về một nhãn duy nhất ghép nối với các ký tự dòng mới, trong ví dụ của tôi, đó là TARGET_FID ghép nối. "Sj" là tên lớp trong 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]

Tại sao đây là một giải pháp một phần là điều này được thực hiện cho mọi điểm, tôi không thể nghĩ ra cách bạn sẽ tắt tất cả các điểm xếp chồng khác. Đó là vì điều này tôi nghĩ rằng giải pháp cuối cùng là một số con trăn xây dựng một lớp điểm mới với một nhãn duy nhất được xây dựng từ chồng điểm.

Dưới đây là đầu ra của 3 điểm xếp chồng lên nhau như bạn có thể thấy nhãn được tạo cho mỗi điểm vì tất cả chúng đều tồn tại ở cùng một vị trí.

Thí dụ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.