Ya que mencionas que eres programador, aquí tienes un código que funciona con arcgis 10. Actualización: Si no te apetece programar, he publicado un shapefile comprimido del gráfico aquí .
public void TestGetNeighbors()
{
var fLayer = ArcMap.Document.FocusMap.get_Layer(0) as IFeatureLayer;
var dict = GetNeighborsByName((ITopologyClass)fLayer.FeatureClass, "{0} {1}", "Name", "State_Name");
foreach (KeyValuePair<string, List<string>> kvp in dict)
{
Debug.WriteLine(kvp.Key);
foreach (string neighbor in kvp.Value)
Debug.WriteLine("\t" + neighbor);
}
}
private Dictionary<string, List<string>> GetNeighborsByName(ITopologyClass topoClass, string format, params object[] fldNames)
{
var fc = topoClass as IFeatureClass;
if (topoClass.Topology.Cache.BuildExtent == null || topoClass.Topology.Cache.BuildExtent.IsEmpty)
{
Debug.WriteLine("building ...");
topoClass.Topology.Cache.Build(((IGeoDataset)fc).Extent, false);
}
// get neighbors by oid
var oidDict = GetNeighborsByOid(topoClass);
// use the full names to build the output dictionary
var nameDict = GetFullNames(fc, format, fldNames);
var outDict = new Dictionary<string, List<string>>();
foreach (KeyValuePair<int, List<int>> kvp in oidDict)
{
var list = new List<string>();
foreach (int oid in kvp.Value)
list.Add(nameDict[oid]);
outDict.Add(nameDict[kvp.Key], list);
}
return outDict;
}
private Dictionary<int, List<int>> GetNeighborsByOid(ITopologyClass topoClass)
{
var outDict = new Dictionary<int, List<int>>();
IFeatureCursor fCur = ((IFeatureClass)topoClass).Search(null, false);
try
{
IFeature feat = null;
while ((feat = fCur.NextFeature()) != null)
{
var neighbors = GetNeighboringFeatureOids(topoClass.Topology.Cache,(IFeatureClass)topoClass , feat.OID);
outDict.Add(feat.OID, neighbors);
}
}
catch
{
throw;
}
finally
{
if(fCur != null)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(fCur);
}
return outDict;
}
private List<int> GetNeighboringFeatureOids(ITopologyGraph topoGraph, IFeatureClass fc, int oid)
{
var outList = new List<int>();
var enumEdge = topoGraph.GetParentEdges(fc, oid);
for (int i = 0; i < enumEdge.Count; i++)
{
var edge = enumEdge.Next();
outList.AddRange(GetParentOids(edge.get_LeftParents(true),fc));
outList.AddRange(GetParentOids(edge.get_RightParents(true),fc));
}
// handle the kitty-corner case
var enumNode = topoGraph.GetParentNodes(fc, oid);
for(int i=0; i<enumNode.Count;i++)
{
var node = enumNode.Next();
var list = GetParentOids(node.Parents, fc);
foreach (int neighborOid in list)
{
if (!outList.Contains(neighborOid))
outList.Add(neighborOid); // kitty corner
}
}
return Reduce(outList,oid);
}
private List<int> Reduce(List<int> inList, int omit)
{
var outList = new List<int>();
foreach (int i in inList)
{
if (!(outList.Contains(i) || omit == i))
outList.Add(i);
}
return outList;
}
private List<int> GetParentOids(IEnumTopologyParent enumParent, IFeatureClass fc)
{
var outList = new List<int>();
for (int i = 0; i < enumParent.Count; i++)
{
var parent = enumParent.Next();
if (parent.m_pFC == fc)
outList.Add(parent.m_FID);
}
return outList;
}
private Dictionary<int, string> GetFullNames(IFeatureClass fc, string format, params object[] fldNames)
{
var fldList = GetFieldIndexes(fc, fldNames);
var outDict = new Dictionary<int, string>();
IFeatureCursor fCur = fc.Search(null, false);
IFeature feat = null;
try
{
while ((feat = fCur.NextFeature()) != null)
{
var valList = new List<string>();
foreach (int idx in fldList)
{
string val = feat.get_Value(idx) is DBNull ? "" : feat.get_Value(idx).ToString();
valList.Add(val);
}
outDict.Add(feat.OID, String.Format(format, valList.ToArray()));
}
}
catch
{
throw;
}
finally
{
if (fCur != null)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(fCur);
}
return outDict;
}
private static List<int> GetFieldIndexes(IFeatureClass fc, object[] fldNames)
{
var fldList = new List<int>();
foreach (string fldName in fldNames)
{
int idx = fc.FindField(fldName);
if (idx == -1)
throw new Exception(string.Format("field {0} not found on {1}", fldName, fc.AliasName));
fldList.Add(idx);
}
return fldList;
}
Produce una salida como esta:
Yukon-Koyukuk Alaska
North Slope Alaska
Northwest Arctic Alaska
Southeast Fairbanks Alaska
Nome Alaska
Fairbanks North Star Alaska
Denali Alaska
Wade Hampton Alaska
Matanuska-Susitna Alaska
Bethel Alaska
Southeast Fairbanks Alaska
Yukon-Koyukuk Alaska
Fairbanks North Star Alaska
Denali Alaska
Matanuska-Susitna Alaska
Valdez-Cordova Alaska ...