How to add new coded values to an existing domain

625
6
Jump to solution
10-25-2022 09:35 AM
RejeanLabbe
New Contributor III

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

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
GKmieliauskas
Esri Regular Contributor

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);

View solution in original post

6 Replies
RejeanLabbe
New Contributor III

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"])
0 Kudos
GKmieliauskas
Esri Regular Contributor

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);
RejeanLabbe
New Contributor III

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!

0 Kudos
RejeanLabbe
New Contributor III

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();
	}
}
RichRuh
Esri Regular Contributor

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

0 Kudos
RejeanLabbe
New Contributor III

Thanks Rich. I will try Gintautas solution using Geoprocessing Tool.

0 Kudos