Çakışan noktalar için etiketler tek bir etikette birleştirilebilir / birleştirilebilir mi?


12

Örnek yerleri temsil eden puanlarım var. Genellikle, aynı yerde birden fazla örnek alınır: aynı konumda ancak farklı örnek kimlikleri ve diğer nitelikleri olan birden fazla nokta. Tek bir etiketle birlikte bulunan tüm noktaları, bu noktadaki tüm noktaların tüm örnek kimliklerini listeleyen yığılmış metinle etiketlemek istiyorum.

ArcGIS'de normal etiketleme motoru veya Maplex kullanarak bu mümkün müdür? Ben bir öznitelik değeri her konum için tüm örnek kimlikleri ile yeni bir katman oluşturarak bu geçici çözüm olabilir biliyorum ama ben sadece etiketleme için yeni veri oluşturmaktan kaçınmak istiyorum.

Temelde bundan gitmek istiyorum:

resim açıklamasını buraya girin

Buna (en üst nokta için):

resim açıklamasını buraya girin

Etiketleri elle düzenlemeden.


Veri kümenizde kaç puan var?
Hornbydd

Yanıtlar:


11

Bunu yapmanın bir yolu, katmanı klonlamak, tanım sorgularını kullanmak ve bunları ayrı ayrı etiketlemek, birinci katman için yalnızca sol üst ve ikinci saniye için sol alt etiket konumunu kullanmaktır.

Katmana THEFIELD türü tamsayı ekleyin ve aşağıdaki ifadeyi kullanarak doldurun:

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

Arayan:

FirstOrOthers( !Shape! )

İçerik tablosunda katmanın bir kopyasını oluşturun, tanım sorgusunu uygulayın THEFIELD = 1.

Orijinal katman için tanım sorgusu THEFIELD = 2 uygula.

Farklı sabit etiket yerleşimleri uygulama

resim açıklamasını buraya girin

Orijinal çözüm yorumlarına göre GÜNCELLEME:

COORD alanı ekleyin ve şunu kullanarak doldurun:

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

Etiket için ilk ve sonuncuyu kullanarak bu alanı özetleyin. COORD alanını kullanarak bu tabloyu orijinal haline geri getirin. Firların <> son olduğu kayıtları seçin ve kullanarak yeni bir alandaki ilk ve son etiketi birleştirin

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

Count_COORD ve THEFIELD öğelerini kullanarak bunları etiketlemek için 2 farklı katman ve alan tanımlayın:

resim açıklamasını buraya girin

@Hornbydd çözümünden esinlenen 2. güncelleme:

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

GÜNCELLEME Kasım 2016, umarım sürer.

2000 kopyalarında test edilen ifadenin altındaki çekicilik gibi çalışır:

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 "

Hey sen kırdın! Güzel! Dışarıda vızıldayan biri olduğunu biliyordum! Beklediğim gibi çok yinelemeli bir süreç bu yüzden büyük bir veri kümesinde çalıştırın ve etiketlerin çizilmesi sonsuza kadar sürüyor (test verilerimde de iyi). Birkaç satırı genişleterek kod stilinizi değiştirdim. Minimalist buluyorum, hepsini tek bir satırda takip etmek zor.
Hornbydd

1
@Hornbydd düzenlemeler için teşekkürler. Etiket (motor?) Davranışı nedeniyle bu somunun çatlaması zordu. Tüm fonksiyon parametrelerini dize olarak ele alır! Bu nedenle ilk EĞER f = int ([FID]) olmadan çalışmadı. Hız ile ilgili olarak asla 50 puandan daha büyük bir sette kullanmam. Sadece iki kez veri kümesinden geçerek yeni alanı dolduran komut dosyasına dönüştürülmelidir: 1) her iki sözlükleri derlemek için arama imleci, 2) onlardan okumak için güncelleme imleci NOT: try ifadesinden sonraki ilk 3 satır eski, çözüm gönderdikten sonra I güvenli bir şekilde çıkarılabileceğini fark etti.
FelixIP

FYI Buna geri dönme şansım olmadı, ancak çözümünüze önümüzdeki hafta içinde bir koşuşturma vermeyi planlıyorum. Ayrıca başka bir geçici çözüm (bu durumda kullandığım) Python olmadan, ben de bu konuda bir cevap göndereceğim.
Dan C

Geonet'te bu sayfaya rastladım . Küresel sözlüklerin akıllıca kullanılmasını sevdim ve ardından bu soru-cevapları düşündüm ve buna bir bağlantı ekledim.
Hornbydd

@Hornbydd evet, Richard'ın her şeyi gibi çok akıllı ve ayrıntılı ve benim (bizim) çözümümde büyük bir fark yaratacak. İlki dahil birkaç çizgiyi kaldırarak daha da geliştirilebilir. Ancak OP yanıt süresi dayalı o ilgi kaybetti görünüyor, ben de rahatsız etmeyin
FelixIP

4

Aşağıda kısmi bir çözüm var.

Bu, Gelişmiş etiket ifadesine gider. Bu çok etkili değil, bu yüzden veri kümenizdeki puanların sayısını soruyorum. Bu nedenle, etiketlenen her satır için d, anahtarın XY ve değerin metin d2olduğu ve objectID ve XY olan 2 sözlük oluşturur . Bu sözlük kombinasyonunu kullanarak, yeni satır karakterleriyle birleştirme olan tek bir etiket döndürebilir, örneğimde TARGET_FID'yi birleştiriyor. "sj", İçindekiler'deki katman adıdır.

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]

Bu neden kısmi bir çözüm, bunun her nokta için yapıldığı, diğer tüm yığılmış noktaları nasıl kapatacağınızı düşünemedim. Bu nedenle nihai çözüm, nokta yığınından inşa edilen tek bir etiketle yeni bir tek nokta katmanı oluşturan bazı python olduğunu düşünüyorum.

Aşağıda, her bir nokta için etiketin hepsi aynı yerde bulunduğundan oluşturulduğunu görebileceğiniz 3 yığılmış noktanın çıktısı bulunmaktadır.

Misal

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.