Fix Duplicate Labels using WaterObjects.NET Tool

Fix Duplicate Labels - A WaterObjects.NET Tool
Introduction
Every now and then, we end up with duplicate labels in our hydraulic network. There are certain situations where having duplicate labels really hurts, especially when a network needs to be exported out to EPANET, EPASWMM or LandXML formats. There is an inbuilt way (via the Network Navigator) to find the duplicate labels, however, you are on your own when it comes to fixing those labels.

If your network has duplicate labels and you are on this blog page, then consider yourself a lucky one.
How to Run the Tool
If you simply obtain the executable (.exe) file, then make sure to place this file in the right directory. This tool is built for SewerGEMS (08.11.02.75) and also for WaterGEMS (08.11.03.19). The .exe needs to be placed in the %ProgramFiles%\Bentley\SewerGEMS\ directory for SewerGEMS and %ProgramFiles%\Bentley\WaterGEMS\ directory for WaterGEMS. Once it is there, you can run it and the window shown in the figure above will appear. In the “Fix Duplicate Labels” window, click on the “Browse” button and select the appropriate file. Clicking the “Analyze” button will list all the elements that have duplicate labels, and it will also display what the labels will be after fixing them. A different separator can be selected from the dropdown when required. The “Fix” button will finalize the process by fixing the duplicate labels in the database. 

Closing the “Fix Duplicate Labels” window will close the model automatically. From here, simply open up the model from standard SewerGEMS/WaterGEMS user interface and check the updated labels.
Programming Details
Bentleys WaterObjects.NET API will be primarily discussed in the sections below using C# as a programming language. It is assumed that the reader has some basic knowledge about the .NET programming.
References used
Haestad.Domain
Haestad.Domain.ModelingObjects
Haestad.Framework.Windows.Forms
Haestad.Support
Namespaces used
Haestad.Domain
Haestad.Domain.ModelingObjects
Haestad.Framework.Windows.Forms.Forms
Haestad.Framework.Windows.Forms.Resources
Haestad.Support.Support
How to open a model database
Please refer to this page:
Summarize_Scenario_#HowToOpenHydraulicModel
Analyze for the duplicate Labels
Obtaining the all the duplicate labels is not difficult. A GetElementIDsWithDuplicateLabels method can be obtained after casting DomainDataSet to IDomainDataSetSearch. This method will return the duplicate IDs as HmIDCollection. One of the required arguments is an array of element types on which IDomainDataSetSerach will search for the duplicate labels. The collection of element types can be obtained from DomainDataSet by calling DomainDataSetType().DomainElementTypes(true/false).
private HmIDCollection FindElementIDsWithDuplicateLabel()
{
    HmIDCollection duplicateLabels;
    DomainElementTypeCollection domainElementTypes = DomainDataSet.DomainDataSetType().DomainElementTypes(false);
    int[] elementTypeIDs = new int[domainElementTypes.Count];
    for (int i = 0; i < elementTypeIDs.Length; i++)
    {
        elementTypeIDs[i] = ((IDomainElementType)domainElementTypes[i]).Id;
    }
    //Alternative way   
    //int[] elementTypeIDs = new int[4];
    //elementTypeIDs[0] = (int)DomainElementType.BaseLinkElementManager;
    //elementTypeIDs[1] = (int)DomainElementType.BaseDirectedNodeElementManager;
    //elementTypeIDs[2] = (int)DomainElementType.BaseNodeElementManager;
    //elementTypeIDs[3] = (int)DomainElementType.BasePolygonElementManager;
    duplicateLabels = ((IDomainDataSetSearch)DomainDataSet).GetElementIDsWithDuplicateLabels(ModelingElementType.DomainElement, elementTypeIDs,false);
    return duplicateLabels;
}
Update the label attributes with new values
Not only the label field, but for most of the fields, if any data needs to be updated, first get IField and cast it to IEditField. Then call SetValue and provide the element ID and value to set. Be careful when working with the fields that have units associated with them such as diameter, elevation etc. To obtain the Label field, first ElementManager is required (there are other ways too). It can be obtained from DomainDataSet. From ElementManger call DomainElementField with StandardFieldName.HmiLabel as the only argument. Cast the return IField to IEditField and call SetValue.
// HydropneumaticTank is just an example. It could be any element type name.
IDomainElementManagerelementManager = DomainDataSet.DomainElementManager(StandardDomainElementTypeName.HydropneumaticTank);
EditField labelField = (IEditField)elementManager.DomainElementField(StandardFieldName.HmiLabel);
labelField.SetValue(elementID, newValue);
Notes
In the actual solution (Visual Studio file), there are a lot more lines of code than the code discussed above, and some additional steps are taken for the integrity. There, the solution file may exhibit slightly different code lines than above. Last but not least, I would like to thank my colleague from Bentley Software Development, Diego Diaz, for his support in developing this sample application.
What if the tool does not work or help is needed?
-If you just receive the exe file, make sure the file is placed in the right location
-If you are working with Visual Studio/Express, you can contact me (by email at Akshaya.Niraula@bentley.com )