private void AddNodesDegreeTwo(IEnumSchematicInMemoryFeature enumInMemoryFeature,
                                       Dictionary <string, ISchematicInMemoryFeature> colSchfeatureNode, ISchematicRulesHelper rulesHelper)
        {
            ISchematicInMemoryFeature schInMemoryfeature;

            if (enumInMemoryFeature == null || colSchfeatureNode == null || rulesHelper == null)
            {
                return;
            }

            enumInMemoryFeature.Reset();
            schInMemoryfeature = enumInMemoryFeature.Next();
            while (schInMemoryfeature != null)
            {
                if (schInMemoryfeature.Displayed)
                {
                    IEnumSchematicInMemoryFeature enumLinks = rulesHelper.GetDisplayedIncidentLinks((ISchematicInMemoryFeatureNode)schInMemoryfeature, esriSchematicEndPointType.esriSchematicOriginOrExtremityNode);
                    if (enumLinks != null && enumLinks.Count == 2)
                    {
                        if (!colSchfeatureNode.ContainsKey(schInMemoryfeature.Name))
                        {
                            colSchfeatureNode.Add(schInMemoryfeature.Name, schInMemoryfeature);
                        }
                    }
                }

                schInMemoryfeature = enumInMemoryFeature.Next();
            }
        }
Example #2
0
        private bool SameIncidentLinkAttributeValue(IEnumSchematicInMemoryFeature enumInMemoryLinks, string attributeName, ISchematicRulesHelper ruleHelper)
        {
            ISchematicInMemoryFeature inMemoryFeature = null;

            enumInMemoryLinks.Reset();

            bool   bFirstVariant  = true;
            object vPreviousValue = null;
            object vCurrentValue  = null;

            inMemoryFeature = enumInMemoryLinks.Next();

            while (inMemoryFeature != null)
            {
                // Do not take account the link if the link is not displayed
                //
                // Search for an attribute with the given name
                //
                ISchematicElementClass schematicElementClass;
                schematicElementClass = inMemoryFeature.SchematicElementClass;
                ISchematicAttributeContainer attributeContainer = (ISchematicAttributeContainer)schematicElementClass;
                ISchematicAttribute          schematicAttribute = null;
                if (attributeContainer != null)
                {
                    schematicAttribute = attributeContainer.GetSchematicAttribute(attributeName, true);
                }

                if (schematicAttribute != null)
                {
                    ISchematicObject schematicObject = (ISchematicObject)inMemoryFeature;
                    vCurrentValue = schematicAttribute.GetValue(schematicObject);
                }
                else
                {
                    // If schematic attribute not existing ==> find a field in the associated feature
                    IObject iObject = null;

                    ISchematicInMemoryFeaturePrimaryAssociation primaryAssociation = (ISchematicInMemoryFeaturePrimaryAssociation)inMemoryFeature;
                    if (primaryAssociation != null)
                    {
                        iObject = primaryAssociation.AssociatedObject;
                    }

                    IRow row = (IRow)iObject;

                    int fieldIndex = 0;
                    if (row != null)
                    {
                        IFields fields = row.Fields;

                        if (fields != null)
                        {
                            fieldIndex = fields.FindField(attributeName);
                        }
                    }

                    if (fieldIndex > 0)
                    {
                        vCurrentValue = row.get_Value(fieldIndex);
                        if (DBNull.Value.Equals(vCurrentValue))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }

                if (bFirstVariant)
                {
                    vPreviousValue = vCurrentValue;
                    bFirstVariant  = false;
                }
                else
                {
                    // Compare PreviousValue and CurrentValue
                    if (vPreviousValue.GetType() != vCurrentValue.GetType())
                    {
                        return(false);
                    }

                    if (DBNull.Value.Equals(vPreviousValue) || DBNull.Value.Equals(vCurrentValue))
                    {
                        return(false);
                    }

                    if (vPreviousValue.GetType().FullName is System.String)//Speciale Case for string.
                    {
                        string str1 = (string)vPreviousValue;
                        string str2 = (string)vCurrentValue;
                        if (string.Compare(str1, str2, true) != 0)
                        {
                            return(false);
                        }
                    }
                    else if (vPreviousValue != vCurrentValue)// == or != operator compare for Variant match the right type.
                    {
                        return(false);
                    }
                }

                inMemoryFeature = enumInMemoryLinks.Next();
            }

            return(true);
        }
Example #3
0
        private void ReduceNode(ISchematicRulesHelper rulesHelper, ISchematicInMemoryFeatureClass superspanLinkClass, ISpatialReference spatialRef, ISchematicInMemoryFeature schFeatureToReduce)
        {
            if (schFeatureToReduce.Displayed == false || rulesHelper == null || spatialRef == null)
            {
                return;
            }

            // get the two connected links
            IEnumSchematicInMemoryFeature enumLink = rulesHelper.GetDisplayedIncidentLinks((ISchematicInMemoryFeatureNode)schFeatureToReduce, esriSchematicEndPointType.esriSchematicOriginOrExtremityNode);

            if (enumLink == null || enumLink.Count != 2)
            {
                return;
            }

            enumLink.Reset();
            ISchematicInMemoryFeature     schFeat1 = enumLink.Next();
            ISchematicInMemoryFeature     schFeat2 = enumLink.Next();
            ISchematicInMemoryFeatureLink schLink1 = (ISchematicInMemoryFeatureLink)schFeat1;
            ISchematicInMemoryFeatureLink schLink2 = (ISchematicInMemoryFeatureLink)schFeat2;

            if (schLink1 == null || schLink2 == null)
            {
                return;
            }


            ISchematicInMemoryFeature schFeatureSuperspan = null;
            ISchematicInMemoryFeature schFeatureTmp       = null;

            ISchematicInMemoryFeatureNode schNodeToReduce = (ISchematicInMemoryFeatureNode)schFeatureToReduce;
            ISchematicInMemoryFeatureNode schFromNode;
            ISchematicInMemoryFeatureNode schToNode;
            int iFromPort;
            int iToPort;


            IGeometry superspanGeometry;

            if (schLink2.FromNode == schNodeToReduce)
            {
                superspanGeometry = BuildLinkGeometry(schLink1, schNodeToReduce, schLink2, rulesHelper);
                if (schLink1.ToNode == schNodeToReduce)
                {
                    schFromNode = schLink1.FromNode;
                    iFromPort   = schLink1.FromPort;
                }
                else
                {
                    schFromNode = schLink1.ToNode;
                    iFromPort   = schLink1.ToPort;
                }

                schToNode = schLink2.ToNode;
                iToPort   = schLink2.ToPort;
            }
            else
            {
                superspanGeometry = BuildLinkGeometry(schLink2, schNodeToReduce, schLink1, rulesHelper);


                schFromNode = schLink2.FromNode;
                iFromPort   = schLink2.FromPort;

                if (schLink1.FromNode == schNodeToReduce)
                {
                    schToNode = schLink1.ToNode;
                    iToPort   = schLink1.ToPort;
                }
                else
                {
                    schToNode = schLink1.FromNode;
                    iToPort   = schLink1.FromPort;
                }
            }

            if (superspanGeometry != null)
            {
                superspanGeometry.SpatialReference = spatialRef;
            }


            // find a unique name for the superspan
            string strFromName = schFromNode.Name;
            string strtoName   = schToNode.Name;
            string strName;
            long   lCount = 1;

            while (schFeatureSuperspan == null)
            {
                strName = strFromName + ";" + strtoName + ";" + lCount.ToString();
                if (strName.Length >= 128)
                {
                    break; // too long a name
                }
                try
                {
                    schFeatureTmp = rulesHelper.AlterLink(superspanLinkClass, strName, null, superspanGeometry, -2, -2,
                                                          strFromName, strtoName, esriFlowDirection.esriFDWithFlow, iFromPort, iToPort);
                }
                catch
                {
                    schFeatureTmp = null;
                }

                if (schFeatureTmp == null)
                {
                    continue;
                }

                // valid new feature
                schFeatureSuperspan = schFeatureTmp;
            }


            // last chance for a unique name
            lCount = 1;
            while (schFeatureSuperspan == null)
            {
                strName = schNodeToReduce.Name + ";" + lCount.ToString();
                if (strName.Length >= 128)
                {
                    break; // too long a name
                }
                try
                {
                    schFeatureTmp = rulesHelper.AlterLink(superspanLinkClass, strName, null, superspanGeometry, -2, -2,
                                                          strFromName, strtoName, esriFlowDirection.esriFDWithFlow, iFromPort, iToPort);
                }
                catch
                {
                    schFeatureTmp = null;
                }

                if (schFeatureTmp == null)
                {
                    continue;
                }

                // valid new feature
                schFeatureSuperspan = schFeatureTmp;
            }

            if (schFeatureSuperspan == null)
            {
                return; // cannot find a unique name
            }
            // otherwise report the cumulated length of the reduced links to the superspan
            ReportCumulativeValues(schFeat1, schFeat2, schFeatureSuperspan);

            //    report the associations on the superspan link
            rulesHelper.ReportAssociations(schFeatureToReduce, schFeatureSuperspan);
            rulesHelper.ReportAssociations(schFeat1, schFeatureSuperspan);
            rulesHelper.ReportAssociations(schFeat2, schFeatureSuperspan);

            // hide the reduced objects
            rulesHelper.HideFeature(schFeatureToReduce);
            rulesHelper.HideFeature(schFeat1);
            rulesHelper.HideFeature(schFeat2);
        }
Example #4
0
        public void Apply(ISchematicInMemoryDiagram inMemoryDiagram, ESRI.ArcGIS.esriSystem.ITrackCancel cancelTracker)
        {
            if (m_reducedNodeClassName == "" || inMemoryDiagram == null)
            {
                return;
            }

            // initialize the schematic rules helper
            ISchematicRulesHelper rulesHelper = new SchematicRulesHelperClass();

            rulesHelper.InitHelper(inMemoryDiagram);
            rulesHelper.KeepVertices = m_keepVertices;

            ////////////////////////
            // get the feature classes processed by the rule
            ISchematicDiagramClass diagramClass = null;

            try
            {
                diagramClass = inMemoryDiagram.SchematicDiagramClass;
            }
            catch { }

            if (diagramClass == null)
            {
                return;
            }
            ISchematicDataset schematicDataset = null;

            try
            {
                schematicDataset = diagramClass.SchematicDataset;
            }
            catch { }

            ISchematicElementClassContainer elementclassContainer = (ISchematicElementClassContainer)schematicDataset;

            if (elementclassContainer == null)
            {
                return;
            }

            ISchematicElementClass elementClassReducedNode = null;

            elementClassReducedNode = elementclassContainer.GetSchematicElementClass(m_reducedNodeClassName);

            ISchematicElementClass elementClassSuperspan = null;

            elementClassSuperspan = elementclassContainer.GetSchematicElementClass(m_superspanLinkClassName);

            if (elementClassSuperspan == null || elementClassReducedNode == null)
            {
                return;
            }

            ISchematicInMemoryFeatureClassContainer featureClassContainer = (ISchematicInMemoryFeatureClassContainer)inMemoryDiagram;

            if (featureClassContainer == null)
            {
                return;
            }

            ISchematicInMemoryFeatureClass superspanLinkClass = featureClassContainer.GetSchematicInMemoryFeatureClass(elementClassSuperspan);
            //
            /////////////////////////

            // fetch the superspan spatial reference
            IGeoDataset geoDataset = (IGeoDataset)superspanLinkClass;

            ISpatialReference spatialRef = null;

            if (geoDataset != null)
            {
                spatialRef = geoDataset.SpatialReference;
            }
            if (spatialRef == null)
            {
                return;
            }

            // Retrieve the schematic in memory feature nodes to reduce


            System.Collections.Generic.Dictionary <string, ISchematicInMemoryFeature> colSchfeatureNode = new Dictionary <string, ISchematicInMemoryFeature>();

            // get all feature of parent node class
            IEnumSchematicInMemoryFeature enumSchematicInMemoryFeature = inMemoryDiagram.GetSchematicInMemoryFeaturesByClass(elementClassReducedNode);

            // retain only the nodes of degree two
            RetainNodesDegreeTwo(enumSchematicInMemoryFeature, colSchfeatureNode, rulesHelper);    // there would be inserted a SQL query to also filter by attributes

            IProgressor msgProgressor = null;

            if (cancelTracker != null)
            {
                msgProgressor = cancelTracker.Progressor;
                IStepProgressor stepProgressor = (IStepProgressor)msgProgressor;
                if (stepProgressor != null)
                {
                    stepProgressor.MinRange  = 0;
                    stepProgressor.MaxRange  = colSchfeatureNode.Count;
                    stepProgressor.StepValue = 1;
                    stepProgressor.Position  = 0;
                    stepProgressor.Message   = m_description;
                    cancelTracker.Reset();
                    cancelTracker.Progressor = msgProgressor;
                    stepProgressor.Show();
                }
            }

            ISchematicInMemoryFeature schFeatureToReduce;

            foreach (KeyValuePair <string, ISchematicInMemoryFeature> kvp in colSchfeatureNode)
            {
                if (cancelTracker != null)
                {
                    if (cancelTracker.Continue() == false)
                    {
                        break;
                    }
                }

                schFeatureToReduce = colSchfeatureNode[kvp.Key];
                if (schFeatureToReduce != null)
                {
                    ReduceNode(rulesHelper, superspanLinkClass, spatialRef, schFeatureToReduce);
                }
            }


            // release memory
            colSchfeatureNode.Clear();
            colSchfeatureNode = null;
            rulesHelper       = null;
        }
        private void AddNodesDegreeTwo(IEnumSchematicInMemoryFeature enumInMemoryFeature,
                Dictionary<string, ISchematicInMemoryFeature> colSchfeatureNode, ISchematicRulesHelper rulesHelper)
        {
            ISchematicInMemoryFeature schInMemoryfeature;

            if (enumInMemoryFeature == null || colSchfeatureNode == null || rulesHelper == null) 
                return;

            enumInMemoryFeature.Reset();
            schInMemoryfeature = enumInMemoryFeature.Next();
            while (schInMemoryfeature != null)
            {
                if (schInMemoryfeature.Displayed)
                {
                    IEnumSchematicInMemoryFeature enumLinks = rulesHelper.GetDisplayedIncidentLinks((ISchematicInMemoryFeatureNode)schInMemoryfeature, esriSchematicEndPointType.esriSchematicOriginOrExtremityNode);
                    if (enumLinks != null && enumLinks.Count == 2)
                    {
                        if (!colSchfeatureNode.ContainsKey(schInMemoryfeature.Name))
                            colSchfeatureNode.Add(schInMemoryfeature.Name, schInMemoryfeature);
                    }
                }

                schInMemoryfeature = enumInMemoryFeature.Next();
            }
        }
        public void Apply(ISchematicInMemoryDiagram inMemoryDiagram, ESRI.ArcGIS.esriSystem.ITrackCancel cancelTracker)
        {
            ISchematicRulesHelper rulesHelper = new SchematicRulesHelperClass();

            System.Collections.Generic.Dictionary <string, ISchematicInMemoryFeature> colSchfeatureNode = new Dictionary <string, ISchematicInMemoryFeature>();
            rulesHelper.InitHelper(inMemoryDiagram);
            rulesHelper.KeepVertices = true;

            ISchematicDiagramClass     diagramClass = null;
            ISchematicElementClass     elementClass;
            ISchematicElementClass     elementClassParentNode = null;
            IEnumSchematicElementClass enumSchEltCls;

            try
            {
                diagramClass = inMemoryDiagram.SchematicDiagramClass;
            }
            catch { }

            if (diagramClass == null)
            {
                return;
            }

            enumSchEltCls = diagramClass.AssociatedSchematicElementClasses;

            if (enumSchEltCls.Count == 0)
            {
                return;
            }

            enumSchEltCls.Reset();
            elementClass = enumSchEltCls.Next();

            while (elementClass != null)
            {
                if (elementClass.Name == m_parentNodeClassName)
                {
                    elementClassParentNode = elementClass;
                    m_parentNodeClass      = GetSchematicInMemoryFeatureClass(inMemoryDiagram, elementClass);
                }

                if (elementClass.Name == m_targetNodeClassName)
                {
                    m_targetNodeClass = GetSchematicInMemoryFeatureClass(inMemoryDiagram, elementClass);
                }

                if (elementClass.Name == m_targetLinkClassName)
                {
                    m_targetLinkClass = GetSchematicInMemoryFeatureClass(inMemoryDiagram, elementClass);
                }

                elementClass = enumSchEltCls.Next();
            }

            if (m_parentNodeClass == null || m_targetNodeClass == null || m_targetLinkClass == null)
            {
                return;
            }

            IEnumSchematicInMemoryFeature enumSchematicInMemoryFeature;

            // list nodes degree two
            // get all feature of parent node class
            enumSchematicInMemoryFeature = inMemoryDiagram.GetSchematicInMemoryFeaturesByClass(elementClassParentNode);
            enumSchematicInMemoryFeature.Reset();

            // add the node into collection if it contains only 2 links displayed.
            AddNodesDegreeTwo(enumSchematicInMemoryFeature, colSchfeatureNode, rulesHelper);
            ISchematicInMemoryFeature schFeatureParent;

            foreach (KeyValuePair <string, ISchematicInMemoryFeature> kvp in colSchfeatureNode)
            {
                schFeatureParent = colSchfeatureNode[kvp.Key];

                if (schFeatureParent == null)
                {
                    continue;
                }

                // get 2 links connected of eache feature node
                IEnumSchematicInMemoryFeature enumLinks = rulesHelper.GetDisplayedIncidentLinks((ISchematicInMemoryFeatureNode)schFeatureParent, esriSchematicEndPointType.esriSchematicOriginOrExtremityNode);
                // enumLinks surely not null    and it contain 2 links displayed

                double angle1, angle2, angleBisector;
                bool   first = true;

                angle1 = angle2 = angleBisector = 0;
                IPoint pointParent = null;
                ISchematicInMemoryFeatureNodeGeometry geoParent;
                geoParent = (ISchematicInMemoryFeatureNodeGeometry)schFeatureParent;

                pointParent = geoParent.InitialPosition;
                IPoint pointSon        = null;
                bool   enableCalculate = true;

                ISchematicInMemoryFeature schInMemoryFeature = enumLinks.Next();

                ISchematicInMemoryFeatureLink schInMemoryLink = (ISchematicInMemoryFeatureLink)schInMemoryFeature;
                while (schInMemoryLink != null)
                {
                    ISchematicInMemoryFeatureNodeGeometry nodeGeo;
                    // get angle of 2 links connected
                    if (schInMemoryLink.FromNode.Name == schFeatureParent.Name)
                    {
                        nodeGeo = (ISchematicInMemoryFeatureNodeGeometry)schInMemoryLink.ToNode;
                    }
                    else
                    {
                        nodeGeo = (ISchematicInMemoryFeatureNodeGeometry)schInMemoryLink.FromNode;
                    }

                    if (nodeGeo == null)
                    {
                        enableCalculate = false;
                        break;
                    }

                    pointSon = nodeGeo.InitialPosition;
                    if (first)
                    {
                        angle1 = CalculateAngle(pointParent, pointSon);
                        first  = false;
                    }
                    else
                    {
                        angle2 = CalculateAngle(pointParent, pointSon);
                    }

                    schInMemoryFeature = enumLinks.Next();
                    schInMemoryLink    = (ISchematicInMemoryFeatureLink)schInMemoryFeature;
                }

                // caculate angle bisector
                if (enableCalculate)
                {
                    angleBisector = CalculateAngleBisector(angle1, angle2);
                }
                else
                {
                    continue;
                }

                // construct a geometry for the new node node
                // now call alterNode to create a new schematic feature
                // construct a correct name
                string uniqueNodeName, featureCreateName;
                featureCreateName = schFeatureParent.Name + Separator + extensionName;
                esriSchematicElementType elementType = esriSchematicElementType.esriSchematicNodeType;
                uniqueNodeName = GetUniqueName(inMemoryDiagram, elementType, featureCreateName);
                IWorkspace workspace = null;

                try
                {
                    workspace = inMemoryDiagram.SchematicDiagramClass.SchematicDataset.SchematicWorkspace.Workspace;
                }
                catch { }

                int datasourceID = -1;

                if (workspace != null)
                {
                    datasourceID = rulesHelper.FindDataSourceID(workspace, false);
                }

                if (datasourceID == -1)
                {
                    datasourceID = m_diagramClass.SchematicDataset.DefaultSchematicDataSource.ID;
                }

                ISchematicInMemoryFeature schFeatureNodeCreate = null;
                IPoint pointBisector = null;
                pointBisector = GetCoordPointBisector(pointParent, angleBisector, m_distance);
                try
                {
                    schFeatureNodeCreate = rulesHelper.AlterNode(m_targetNodeClass, uniqueNodeName, null, (IGeometry)pointBisector, datasourceID, 0);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.WriteLine(ex.Message, "Impossible to create a feature Node");
                }

                // now construct a unique link name
                string linkName = schFeatureParent.Name + Separator + uniqueNodeName;
                string uniqueLinkName;

                elementType    = esriSchematicElementType.esriSchematicLinkType;
                uniqueLinkName = GetUniqueName(inMemoryDiagram, elementType, linkName);
                // construct a link
                ISchematicInMemoryFeature schFeatureLinkCreate = null;
                try
                {
                    schFeatureLinkCreate = rulesHelper.AlterLink(m_targetLinkClass, uniqueLinkName, null, null, datasourceID, 0, schFeatureParent.Name, uniqueNodeName, esriFlowDirection.esriFDWithFlow, 0, 0);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.WriteLine(ex.Message, "Impossible to create a feature link");
                }
            }

            if (colSchfeatureNode.Count > 0)
            {
                colSchfeatureNode.Clear();
            }

            colSchfeatureNode = null;
            rulesHelper       = null;
        }
        private bool SameIncidentLinkAttributeValue(IEnumSchematicInMemoryFeature enumInMemoryLinks, string attributeName, ISchematicRulesHelper ruleHelper)
        {
            ISchematicInMemoryFeature inMemoryFeature = null;

            enumInMemoryLinks.Reset();

            bool bFirstVariant = true;
            object vPreviousValue = null;
            object vCurrentValue = null;

            inMemoryFeature = enumInMemoryLinks.Next();

            while (inMemoryFeature != null)
            {
            // Do not take account the link if the link is not displayed
            //
            // Search for an attribute with the given name
            //
                ISchematicElementClass schematicElementClass;
                schematicElementClass = inMemoryFeature.SchematicElementClass;
                ISchematicAttributeContainer attributeContainer = (ISchematicAttributeContainer)schematicElementClass;
                ISchematicAttribute schematicAttribute = null;
                if (attributeContainer != null)
                    schematicAttribute = attributeContainer.GetSchematicAttribute(attributeName, true);

                if (schematicAttribute != null)
                {
                    ISchematicObject schematicObject = (ISchematicObject)inMemoryFeature;
                    vCurrentValue = schematicAttribute.GetValue(schematicObject);
                }
                else
                {
                // If schematic attribute not existing ==> find a field in the associated feature
                    IObject iObject = null;

                    ISchematicInMemoryFeaturePrimaryAssociation primaryAssociation = (ISchematicInMemoryFeaturePrimaryAssociation)inMemoryFeature;
                    if (primaryAssociation != null)
                        iObject = primaryAssociation.AssociatedObject;
            
                    IRow row = (IRow)iObject;

                    int fieldIndex = 0;
                    if (row != null)
                    {
                        IFields fields = row.Fields;

                        if (fields != null)
                            fieldIndex = fields.FindField(attributeName);
                    }

                    if (fieldIndex > 0)
                    {
                        vCurrentValue = row.get_Value(fieldIndex);
                        if (DBNull.Value.Equals(vCurrentValue))
                            return false;
                    }
                    else
                        return false;
                }

                if (bFirstVariant)
                {
                    vPreviousValue = vCurrentValue;
                    bFirstVariant = false;
                }
                else
                {
                    // Compare PreviousValue and CurrentValue
                    if (vPreviousValue.GetType() != vCurrentValue.GetType())
                        return false;

                    if (DBNull.Value.Equals(vPreviousValue) || DBNull.Value.Equals(vCurrentValue))
                        return false;
                    
                    if (vPreviousValue.GetType().FullName is System.String)//Speciale Case for string.
                    {
                        string str1 = (string)vPreviousValue;
                        string str2 = (string)vCurrentValue;
                        if( string.Compare(str1, str2, true) != 0)
                            return false;
                    }
                    else if (vPreviousValue != vCurrentValue)// == or != operator compare for Variant match the right type.
                        return false;
                }

                inMemoryFeature = enumInMemoryLinks.Next();
            }
        
            return true;
        }
        private void RetainNodesDegreeTwo(IEnumSchematicInMemoryFeature enumInMemoryFeature,
                Dictionary<string, ISchematicInMemoryFeature> colSchfeatureNode, ISchematicRulesHelper ruleHelper)
        {
            ISchematicInMemoryFeature schInMemoryfeature;

            if (ruleHelper == null) return;

            enumInMemoryFeature.Reset();
            schInMemoryfeature = enumInMemoryFeature.Next();
            while (schInMemoryfeature != null)
            {
                if (schInMemoryfeature.Displayed)
                {
                    IEnumSchematicInMemoryFeature enumLinks = ruleHelper.GetDisplayedIncidentLinks((ISchematicInMemoryFeatureNode)schInMemoryfeature, esriSchematicEndPointType.esriSchematicOriginOrExtremityNode);
                    if (enumLinks != null && enumLinks.Count == 2)
                    {
                        // Valid degree two node
                        if (!colSchfeatureNode.ContainsKey(schInMemoryfeature.Name))
                        {
                            if (!LinkAttribute)
                                colSchfeatureNode.Add(schInMemoryfeature.Name, schInMemoryfeature);
                            else
                            {
                                if(SameIncidentLinkAttributeValue(enumLinks, LinkAttributeName, ruleHelper))
                                    colSchfeatureNode.Add(schInMemoryfeature.Name, schInMemoryfeature);
                            }
                        }
                    }
                }

                schInMemoryfeature = enumInMemoryFeature.Next();
            }
        }