由于我认为python不处理子类型,因此我将发布此C#代码。我使用Esri的示例水/废水geodb进行了测试,发现以下未使用的域:
HistoryType is not used
PLSSFirstDivisionType is not used
PLSSDirection is not used
PLSSPrincipalMeridian is not used
ParcelType is not used
PLSSSpecialSurveyType is not used
CartoLineType is not used
PLSSSecondDivisionType is not used
通常,DBA会烦恼无法通过SQL访问域(本质上是查找表)。
这段代码是通过arcmap测试的(根据Matt的评论进行了更新):
protected override void OnClick()
{
string fgdbPath = @"C:\projects\NetTools\InfrastructureEditingTemplate\MapsandGeodatabase\LocalGovernment.gdb";
var dict = SummarizeDomains(fgdbPath);
ListDomains(dict);
// list what featureclasses use a particular domain ...
string domName = "State_Bnd_Rules";
if (dict.ContainsKey(domName))
{
if (dict[domName].Count > 0)
{
Debug.Print("{0} is used by these featureclasses: ", domName);
foreach (string fcfldName in dict[domName])
{
Debug.Print("\t{0}", fcfldName);
}
}
else
Debug.Print("{0} is not used by any featureclasses", domName);
}
else
{
Debug.Print("Domain name not found in geodb: {0}", domName);
}
}
private void ListDomains(Dictionary<string,List<string>> dict)
{
foreach (KeyValuePair<string, List<string>> kvp in dict)
{
Debug.Print("Domain {0}",kvp.Key);
if (kvp.Value.Count > 0)
{
foreach (string fcfldName in kvp.Value)
{
Debug.Print("\t{0}", fcfldName);
}
}
else
Debug.Print("\tUNUSED DOMAIN!");
}
}
private Dictionary<string, List<string>> SummarizeDomains(string fgdPath)
{
var ws = Open(fgdPath);
var dict = InitDict(ws);
var enumDs1 = ws.get_Datasets(esriDatasetType.esriDTAny);
IDataset ds;
while ((ds = enumDs1.Next()) != null)
{
Debug.Print("processing {0}", ds.Name);
if (ds is IObjectClass)
LoadDomains((IObjectClass)ds, dict);
else if (ds is IFeatureDataset)
{
var enumDs2 = ds.Subsets;
enumDs2.Reset();
IDataset ds2;
while ((ds2 = enumDs2.Next()) != null)
{
if (ds2 is IObjectClass)
LoadDomains((IObjectClass)ds2, dict);
}
}
}
return dict;
}
private void LoadDomains(IObjectClass oc, Dictionary<string, List<string>> dict)
{
if (oc is ISubtypes && ((ISubtypes)oc).HasSubtype)
LoadSubtypeDomains(oc, dict);
else
{
for (int i = 0; i < oc.Fields.FieldCount; i++)
{
var fld = oc.Fields.get_Field(i);
if (fld.Domain == null)
continue;
if (dict.ContainsKey(fld.Domain.Name))
dict[fld.Domain.Name].Add(String.Format("{0}.{1}",((IDataset)oc).Name,fld.Name));
else
throw new Exception("domain not found: " + fld.Domain.Name);
}
}
}
private void LoadSubtypeDomains(IObjectClass oc, Dictionary<string, List<string>> dict)
{
ISubtypes subTypes = oc as ISubtypes;
var enumSubtypes = subTypes.Subtypes;
enumSubtypes.Reset();
int code;
string stName;
while ((stName = enumSubtypes.Next(out code)) != null)
{
for (int i = 0; i < oc.Fields.FieldCount; i++)
{
string fldName = oc.Fields.get_Field(i).Name;
var domain = subTypes.get_Domain(code, fldName);
if (domain != null)
{
if (dict.ContainsKey(domain.Name))
dict[domain.Name].Add(String.Format("{0}.{1}.{2}",stName,((IDataset)oc).Name,fldName));
else
throw new Exception("domain not found: " + domain.Name);
}
}
}
}
private Dictionary<string, List<string>> InitDict(IWorkspace ws)
{
var dict = new Dictionary<string, List<string>>(StringComparer.InvariantCultureIgnoreCase);
var enumDomain = ((IWorkspaceDomains)ws).Domains;
enumDomain.Reset();
IDomain d = null;
while ((d = enumDomain.Next()) != null)
dict.Add(d.Name, new List<string>());
return dict;
}
private IWorkspace Open(string fgdbPath)
{
Type t = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
var wsf = Activator.CreateInstance(t) as IWorkspaceFactory;
return wsf.OpenFromFile(fgdbPath, 0);
}