Bisakah label untuk titik yang tumpang tindih digabungkan / digabung menjadi satu label?


12

Saya memiliki poin yang mewakili lokasi sampel. Seringkali, banyak sampel akan diambil di lokasi yang sama: beberapa titik dengan lokasi yang sama tetapi ID sampel yang berbeda dan atribut lainnya. Saya ingin memberi label semua titik yang ditempatkan bersama dengan satu label, dengan teks bertumpuk yang mencantumkan semua ID sampel dari semua titik di tempat itu.

Apakah ini mungkin di ArcGIS menggunakan mesin pelabelan biasa atau Maplex? Saya tahu saya bisa mengatasi ini dengan membuat layer baru dengan semua ID sampel untuk setiap lokasi dalam satu nilai atribut tetapi saya ingin menghindari membuat data baru hanya untuk pelabelan.

Pada dasarnya saya ingin beralih dari ini:

masukkan deskripsi gambar di sini

Untuk ini (untuk titik paling atas):

masukkan deskripsi gambar di sini

Tanpa melakukan pengeditan label secara manual.


Berapa banyak poin dalam dataset Anda?
Hornbydd

Jawaban:


11

Salah satu cara untuk melakukan ini adalah mengkloning layer, menggunakan query definisi dan memberi label secara terpisah, menggunakan posisi label hanya kiri atas untuk layer pertama dan kiri bawah untuk kedua.

Tambahkan integer tipe THEFIELD ke layer dan isi dengan menggunakan ekspresi di bawah ini:

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

Sebut dengan:

FirstOrOthers( !Shape! )

Buat salinan layer di tabel konten, terapkan query definisi THEFIELD = 1.

Terapkan kueri definisi THEFIELD = 2 untuk lapisan asli.

Terapkan penempatan label tetap berbeda

masukkan deskripsi gambar di sini

UPDATE berdasarkan komentar terhadap solusi asli:

Tambahkan bidang COORD dan isi dengan menggunakan

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

Ringkas bidang ini menggunakan label pertama dan terakhir untuk label. Gabung tabel ini kembali ke aslinya menggunakan bidang COORD. Pilih catatan di mana firs <> terakhir dan menggabungkan label pertama dan terakhir dalam bidang baru menggunakan

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

Gunakan Count_COORD dan THEFIELD untuk mendefinisikan 2 'lapisan berbeda' dan bidang untuk memberi label:

masukkan deskripsi gambar di sini

Perbarui # 2 terinspirasi oleh solusi @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 ""

UPDATE November 2016, semoga berlangsung.

Ekspresi di bawah ini diuji pada 2000 duplikat, berfungsi seperti pesona:

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 "

Hei kamu memecahkannya! Bagus! Saya tahu ada seseorang yang di luar sana! Seperti yang saya harapkan itu adalah proses yang sangat berulang jadi jalankan pada dataset besar dan label mengambil selamanya untuk menggambar (baik itu pada data pengujian saya). Saya telah mengubah gaya kode Anda dengan memperluas beberapa baris. Saya menemukan minimalis, semua pada satu baris sulit untuk diikuti.
Hornbydd

1
@Hornbydd terima kasih untuk suntingan. Kacang ini sulit retak karena perilaku label (mesin?). Ini memperlakukan semua parameter fungsi sebagai string! Inilah sebabnya mengapa IF pertama tidak berfungsi tanpa f = int ([FID]). Mengenai kecepatan saya tidak akan pernah menggunakannya pada set yang lebih besar dari 50 poin. Itu harus dikonversi ke skrip yang mengisi bidang baru dengan pergi melalui dataset hanya dua kali: 1) kursor pencarian untuk mengkompilasi kedua kamus, 2) perbarui kursor untuk membaca dari mereka CATATAN: 3 baris pertama setelah pernyataan mencoba usang, setelah memposting solusi I menyadari bahwa mereka dapat dihapus dengan aman.
FelixIP

FYI saya belum punya kesempatan untuk kembali ke masalah ini, tetapi saya berencana untuk memberikan solusi Anda berputar-putar di minggu depan atau lebih. Ada juga solusi lain (yang saya gunakan dalam kasus ini) tanpa Python, saya akan mengirim jawaban tentang itu juga.
Dan C

Datang di halaman ini di geonet. Saya menyukai penggunaan kamus global yang cerdas, lalu memikirkan T&J ini dan menambahkan tautan ke dalamnya.
Hornbydd

@Hornbydd ya, itu sangat cerdas dan terperinci seperti segala sesuatu dari Richard dan akan membuat perbedaan besar untuk solusi (kami). Satu dapat lebih ditingkatkan dengan menghapus beberapa baris yang termasuk yang paling pertama. Namun berdasarkan waktu respon dari OP sepertinya dia kehilangan minat, saya juga tidak peduli
FelixIP

4

Di bawah ini adalah solusi parsial.

Ini masuk ke ekspresi label Advance. Ini tidak terlalu efisien maka saya bertanya tentang jumlah poin dalam dataset Anda. Jadi untuk setiap baris yang diberi label itu membangun 2 kamus di dmana kuncinya adalah XY dan nilainya adalah teks dan d2yang merupakan objectID dan XY. Menggunakan kombinasi kamus itu dapat mengembalikan label tunggal yang merupakan gabungan dengan karakter baris baru, dalam contoh saya ini menggabungkan TARGET_FID. "sj" adalah nama layer dalam 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]

Mengapa ini adalah solusi parsial adalah bahwa ini dilakukan untuk setiap titik, saya belum dapat memikirkan bagaimana Anda akan mematikan semua poin yang ditumpuk lainnya. Itu karena ini saya pikir solusi pamungkas adalah beberapa python yang membangun lapisan baru dari titik tunggal dengan label tunggal yang dibangun dari tumpukan titik.

Di bawah ini adalah output dari 3 titik yang ditumpuk karena Anda dapat melihat label dibuat untuk setiap titik karena semuanya ada di lokasi yang sama.

Contoh

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.