重叠点的标签可以合并/合并为一个标签吗?


12

我有代表样本位置的点。通常,多个样本将在同一位置获取:具有相同位置但具有不同样本ID和其他属性的多个点。我想用一个标签标记所有位于同一位置的点,并用堆叠文本列出该点所有点的所有示例ID。

在ArcGIS中使用常规标签引擎或Maplex可以做到吗?我知道可以通过在一个属性值中为每个位置创建一个包含所有样本ID的新层来解决此问题,但我想避免创建仅用于标记的新数据。

基本上我想从这里开始:

在此处输入图片说明

为此(最重要的一点):

在此处输入图片说明

无需对标签进行任何手动编辑。


您的数据集中有多少个点?
Hornbydd

Answers:


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)更新游标以从中读取注:注:在发布解决方案I之后,try语句后的前3行已作废。意识到可以安全地将其卸下。
FelixIP

仅供参考,我还没有机会回到这个问题上,但是我计划在下个星期左右为您提供解决方案。还有另一种不使用Python的解决方法(本例中使用的一种),我也将发布有关此问题的答案。
Dan C

在Geonet 上浏览了此页面。我喜欢巧妙地使用全局词典,然后考虑此问答,并添加了链接。
Hornbydd

@Hornbydd是的,它非常聪明和详细,就像Richard所做的一切一样,将对我的解决方案产生巨大的影响。可以通过删除包括第一个在内的几行来进一步改善。但是根据OP的响应时间,他似乎失去了兴趣,我也不想打扰
FelixIP 2015年

4

以下是部分解决方案。

这进入Advance标签表达式。它不是很有效,因此我询问您数据集中的点数。因此,对于每条被标记的行,它都会构建2个字典d,其中键是XY,值是文本,d2并且是objectID和XY。使用字典的组合,可以返回单个标签,该标签是由换行符组成的串联,在我的示例中,它是TARGET_FID的串联。“ sj”是目录中的图层名称。

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]

为什么这是部分解决方案,是因为对每个点都执行了此操作,所以我还没有想到您将如何关闭所有其他堆叠的点。正因为如此,我认为最终的解决方案是一些python,该Python可以构建一个新的单点层,并使用从点堆叠中构建的单个标签。

下面是3个堆叠点的输出,您可以看到为每个点创建了标签,因为它们都存在于同一位置。

例

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.