I would like to add new coded values to an existing domain, but I don't know how to do that.
I tried to add values like that, but it doesn't work.
oDomainsList = oGeodatabase.GetDomains();
foreach (Domain oDomain in oDomainsList)
{
if (oDomain != null && oDomain is CodedValueDomain)
{
if(oDomain.GetName() == sDomainName)
{
(oDomain as CodedValueDomain).GetCodedValuePairs().Add("New value 1", "NV_1");
break;
}
}
}
I can create an new domain if it doesn't exists like this :
SortedList<object, string> oList = new SortedList<object, string> {{"Copper", "C_1"}, {"Steel", "S_2"}};
oCodedValueDomainDescription = new CodedValueDomainDescription(sName, FieldType.String, oList)
{
SplitPolicy = SplitPolicy.Duplicate,
MergePolicy = MergePolicy.DefaultValue
};
CodedValueDomainToken codedValueDomainToken = schemaBuilder.Create(oCodedValueDomainDescription);
schemaBuilder.Build();
But the domain is not overwritten if it exists.
I tried to delete the domain, hopping I could create a new with all coded values, but I don't know how to do that.
SchemaBuilder.Delete needs a Description parameter, but it looks like there is no way to get that from an existing domain.
https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/topic40928.html
Remarks
When deleting domains, a CodedValueDomainDescription must be used to delete a ArcGIS.Core.Data.CodedValueDomain and a RangeDomainDescription must be used to delete a ArcGIS.Core.Data.RangeDomain.
There is no example.
Thanks
Solved! Go to Solution.
Hi,
You can call the same geoprocessing tools from ArcGIS Pro SDK:
var parameters = Geoprocessing.MakeValueArray(gdb, domName, code, domDict[code]);
var gpResult = Geoprocessing.ExecuteToolAsync("management.AddCodedValueToDomain", parameters,
null, CancelableProgressor.None, GPExecuteToolFlags.None);
I found that it is possible with Python, but I need to do that with ArcGIS Pro SDK.
for code in domDict:
arcpy.AddCodedValueToDomain_management(gdb, domName, code, domDict[code])
import arcpy
arcpy.env.workspace = "C:/data"
arcpy.DeleteCodedValueFromDomain_management("montgomery.gdb", "DistDiam", ["20","24"])
Hi,
You can call the same geoprocessing tools from ArcGIS Pro SDK:
var parameters = Geoprocessing.MakeValueArray(gdb, domName, code, domDict[code]);
var gpResult = Geoprocessing.ExecuteToolAsync("management.AddCodedValueToDomain", parameters,
null, CancelableProgressor.None, GPExecuteToolFlags.None);
Thank you so much @GKmieliauskas I didn't know that Geoprocessing tool could do the same as Python.
I tried your code and it works!
This is my working code to create or update a domain :
public static void AddCodedValueToDomain(Geodatabase oGeodatabase, string sDomainName, string sKey, string sValue)
{
var parameters = Geoprocessing.MakeValueArray(oGeodatabase.GetPath().AbsolutePath, sDomainName, sKey, sValue);
var gpResult = Geoprocessing.ExecuteToolAsync("management.AddCodedValueToDomain", parameters, null, CancelableProgressor.None, GPExecuteToolFlags.None);
}
public static void DeleteCodedValueToDomain(Geodatabase oGeodatabase, string sDomainName, string sKey)
{
var parameters = Geoprocessing.MakeValueArray(oGeodatabase.GetPath().AbsolutePath, sDomainName, sKey);
var gpResult = Geoprocessing.ExecuteToolAsync("management.DeleteCodedValueFromDomain", parameters, null, CancelableProgressor.None, GPExecuteToolFlags.None);
}
public static void CreateOrUpdateDomain(Geodatabase oGeodatabase, string sDomainName, SortedList<object, string> oNewValuesList, FieldType oFieldType = FieldType.String)
{
IReadOnlyList<Domain> oDomainsList;
CodedValueDomainDescription oCodedValueDomainDescription;
SchemaBuilder schemaBuilder = new SchemaBuilder(oGeodatabase);
bool bDomainExists = false;
bool bValueExists;
oDomainsList = oGeodatabase.GetDomains();
foreach (Domain oDomain in oDomainsList)
{
if (oDomain != null && oDomain is CodedValueDomain)
{
if (oDomain.GetName() == sDomainName)
{
bDomainExists = true;
foreach (var oExistingValue in (oDomain as CodedValueDomain).GetCodedValuePairs())
{
if (!oNewValuesList.ContainsKey(oExistingValue.Key.ToString()))
{
DeleteCodedValueToDomain(oGeodatabase, sDomainName, oExistingValue.Key.ToString());
}
}
foreach (var oNewValue in oNewValuesList)
{
bValueExists = false;
foreach (var oExistingValue in (oDomain as CodedValueDomain).GetCodedValuePairs())
{
if (oExistingValue.Key.ToString() == oNewValue.Key.ToString())
{
bValueExists = true;
break;
}
}
if (!bValueExists)
{
AddCodedValueToDomain(oGeodatabase, sDomainName, oNewValue.Key.ToString(), oNewValue.Value);
}
}
break;
}
}
}
if (!bDomainExists)
{
oCodedValueDomainDescription = new CodedValueDomainDescription(sDomainName, oFieldType, oNewValuesList)
{
SplitPolicy = SplitPolicy.Duplicate,
MergePolicy = MergePolicy.DefaultValue
};
CodedValueDomainToken codedValueDomainToken = schemaBuilder.Create(oCodedValueDomainDescription);
schemaBuilder.Build();
}
}
Hi Rejean,
You cannot use the Pro SDK to add new coded values to a domain- Python is the answer for now.
The good news is that we'll be adding this capability in Pro 3.1, targeted for Q1 2023.
--Rich
Thanks Rich. I will try Gintautas solution using Geoprocessing Tool.
Hi Rich
Is this functionality added to Pro SDK?
-Rahul
@Rahul_Chahel, Yes. Since Pro SDK 3.1, the API supports adding values to an existing domain using the SchemaBuilder.Modify method. Please refer to the modifying and renaming domain conceptual document and code snippet.