重複するポイントのラベルを1つのラベルに結合/マージできますか?


12

サンプルの場所を表すポイントがあります。多くの場合、複数のサンプルが同じ場所で取得されます。同じ場所にあるが、サンプルIDと他の属性が異なる複数のポイントです。単一のラベルと同じ場所にあるすべてのポイントにラベルを付けたいと思います。スタックされたテキストには、そのスポットのすべてのポイントのすべてのサンプルIDがリストされます。

これは、通常のラベリングエンジンまたはMaplexを使用してArcGISで可能ですか?1つの属性値で各場所のすべてのサンプルIDを使用して新しいレイヤーを作成することでこれを回避できることはわかっていますが、ラベリングのためだけに新しいデータを作成することは避けたいと思います。

基本的に私はこれから行きたいです:

ここに画像の説明を入力してください

これに(一番上のポイントの場合):

ここに画像の説明を入力してください

ラベルを手動で編集せずに。


データセットにはいくつのポイントがありますか?
ホーンビッド

回答:


11

これを行う1つの方法は、定義クエリを使用してレイヤーを複製し、最初のレイヤーに左上のみのラベル位置を使用し、2番目に左下のみを使用してラベル付けすることです。

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 "

ねえ、あなたはそれを割った!いいね!気まぐれな人がいることは知っていました!予想通り、それは非常に反復的なプロセスなので、大きなデータセットで実行すると、ラベルの描画に時間がかかります(テストデータでも同様です)。数行を拡張して、コードスタイルを調整しました。私はミニマリストをすべて一行で理解するのが難しいと感じています。
ホーンビッド

1
@Hornbydd編集に感謝します。このナットは、ラベル(エンジン?)の動作によりひび割れにくいものでした。すべての関数パラメーターを文字列として扱います!これが、f = int([FID])なしでは最初のIFが機能しなかった理由です。速度に関しては、50ポイントを超えるセットでは使用しません。データセットを2回だけ通過することで新しいフィールドに入力するスクリプトに変換する必要があります:1)カーソルを検索して両方の辞書をコンパイルする、2)カーソルを更新してそれらから読み取る安全に削除できることに気付きました。
FelixIP

参考までに私はこれに戻る機会がありませんでしたが、私は来週かそこらであなたのソリューションを旋回させるつもりです。Pythonを使用しない別の回避策(この場合に使用した回避策)もあります。これについても回答を投稿します。
ダンC

出くわしたこのページジオネットに。グローバル辞書の巧妙な使用が気に入ったので、このQ&Aについて考え、リンクを追加しました。
ホーンバイド

@Hornbyddはい、それはリチャードのすべてのように非常にスマートで詳細であり、私の(私たちの)ソリューションに大きな違いをもたらします。最初の行を含むいくつかの行を削除することにより、さらに改善できます。しかし、OPからの応答時間に基づいて、彼は興味を失ったようです。私も気にしません
-FelixIP

4

以下は部分的な解決策です。

これはAdvanceラベル式に入ります。非常に効率的ではないため、データセット内のポイントの数について質問します。したがって、ラベルが付けられる各行に対してd、キーがXYで値がテキストでd2あり、objectIDとXYである2つの辞書を作成します。辞書のその組み合わせを使用すると、改行文字との連結である単一のラベルを返すことができます。私の例では、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であると思います。

以下は3つの積み重ねられたポイントの出力です。これらのポイントはすべて同じ場所に存在するため、各ポイントに対してラベルが作成されていることがわかります。

例

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.