/// <summary>
        /// Gets the fiber record for a given fiber number on a given cable ft
        /// </summary>
        /// <param name="cableFeature"></param>
        /// <param name="fiberNumber"></param>
        /// <returns>IRow</returns>
        private ESRI.ArcGIS.Geodatabase.IRow GetFiberRecord(ESRI.ArcGIS.Geodatabase.IFeature cableFeature, int fiberNumber)
        {
            ESRI.ArcGIS.Geodatabase.IRow result = null;

            ESRI.ArcGIS.Geodatabase.IRelationshipClass fiberRelationship = GdbUtils.GetRelationshipClass(cableFeature.Class, ConfigUtil.FiberCableToFiberRelClassName);
            if (null != fiberRelationship && null != fiberRelationship.DestinationClass)
            {
                ESRI.ArcGIS.Geodatabase.ITable fiberTable = fiberRelationship.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable;
                if (null != fiberTable)
                {
                    ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                    filter.WhereClause = string.Format("{0}='{1}' AND {2}={3}",
                                                       fiberRelationship.OriginForeignKey,
                                                       cableFeature.get_Value(cableFeature.Fields.FindField(fiberRelationship.OriginPrimaryKey)),
                                                       ConfigUtil.Fiber_NumberFieldName,
                                                       fiberNumber);

                    ESRI.ArcGIS.Geodatabase.ICursor cursor = null;
                    try
                    {
                        cursor = fiberTable.Search(filter, false);
                        result = cursor.NextRow();
                    }
                    finally
                    {
                        if (null != cursor)
                        {
                            ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(cursor);
                        }
                    }
                }
            }

            return(result);
        }
예제 #2
0
        public List <BaseModel> Search(BaseModel BaseModel, string AOWhereClause, BaseModel.LoadMethod ChooseLoadMethod)
        {
            List <BaseModel> _ModelsReturn = new List <BaseModel>();

            string _fields = "";

            foreach (ModelProperty _property in BaseModel.ModelProperties.Where(x => !(x.Attribute is EntityManyToManyFieldAttribute)))
            {
                _fields += _property.Attribute.FieldName + ",";
            }

            _fields = _fields.Substring(0, _fields.Length - 1);

            ESRI.ArcGIS.Geodatabase.ITable tbProjeto = ((IFeatureWorkspace)_workspace).OpenTable(BaseModel.EntityName);
            ICursor _rows = GDBCursor.obterCursor(tbProjeto, _fields, AOWhereClause, "");

            IRow _row;

            while ((_row = _rows.NextRow()) != null)
            {
                object[]  _parameters = { _workspace };
                BaseModel _model      = (BaseModel)Activator.CreateInstance(BaseModel.GetType(), _parameters);

                foreach (ModelProperty _property in BaseModel.ModelProperties)
                {
                    _property.Attribute.Load(_workspace, _row, (BaseModel)_model, _property, ChooseLoadMethod);
                }

                _ModelsReturn.Add((BaseModel)_model);
            }

            return(_ModelsReturn);
        }
예제 #3
0
        /// <summary>
        /// Deletes all splices for a cable to any other at any splice closure
        /// </summary>
        /// <param name="cable">Cable</param>
        /// <param name="isExistingOperation">Are we already in an edit operation?</param>
        /// <returns>Success</returns>
        public bool BreakAllSplices(FiberCableWrapper cable, bool isExistingOperation)
        {
            bool success         = false;
            bool isOperationOpen = false;

            #region Validation
            if (null == cable)
            {
                throw new ArgumentNullException("cable");
            }

            if (ESRI.ArcGIS.Editor.esriEditState.esriStateNotEditing == _editor.EditState)
            {
                throw new InvalidOperationException("You must be editing to perform this operation");
            }
            #endregion

            if (!isExistingOperation)
            {
                _editor.StartOperation();
                isOperationOpen = true;
            }

            try
            {
                ESRI.ArcGIS.Geodatabase.ITable spliceTable = _wkspHelper.FindTable(ConfigUtil.FiberSpliceTableName);
//                ESRI.ArcGIS.Geodatabase.ITable spliceTable = GdbUtils.GetTable(cable.Feature.Class, ConfigUtil.FiberSpliceTableName);
                ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();

                // A and B is arbitrary, so we check the given combinations going both ways. The structure is:
                // Where either the A or B cableID is our cable ID
                filter.WhereClause = string.Format("{0}='{1}' OR {2}='{1}'",
                                                   ConfigUtil.ACableIdFieldName,
                                                   cable.IPID,
                                                   ConfigUtil.BCableIdFieldName);

                spliceTable.DeleteSearchedRows(filter);
                ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(filter);

                if (isOperationOpen)
                {
                    _editor.StopOperation("Break Splices");
                    isOperationOpen = false;
                }

                success = true;
            }
            catch
            {
                if (isOperationOpen)
                {
                    _editor.AbortOperation();
                }

                success = false;
            }

            return(success);
        }
        /// <summary>
        /// Finds the connected device/port
        /// </summary>
        /// <param name="siblingFtClass">Any feature class from the workspace</param>
        /// <param name="cableId">Cable ID to check connx for</param>
        /// <param name="fiberNumber">Fiber Number to check connx for</param>
        /// <param name="isFromEnd">Whether to check the cable's from or to end</param>
        /// <param name="portRow">(out) result port</param>
        /// <param name="deviceFt">(out) result device</param>
        /// <returns>True if a connx was found</returns>
        private bool GetConnectedPort(ESRI.ArcGIS.Geodatabase.IFeatureClass siblingFtClass, string cableId, int fiberNumber, bool isFromEnd, out ESRI.ArcGIS.Geodatabase.IRow portRow, out ESRI.ArcGIS.Geodatabase.IFeature deviceFt)
        {
            portRow  = null;
            deviceFt = null;

            bool result = false;

            string[] portTableNames = ConfigUtil.PortTableNames;
            using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
            {
                ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                filter.WhereClause = string.Format("{0}='{1}' AND {2}={3} AND {4}='{5}'",
                                                   ConfigUtil.ConnectedCableFieldName,
                                                   cableId,
                                                   ConfigUtil.ConnectedFiberFieldName,
                                                   fiberNumber,
                                                   ConfigUtil.ConnectedEndFieldName,
                                                   isFromEnd ? "T" : "F");
                releaser.ManageLifetime(filter);

                for (int i = 0; i < portTableNames.Length; i++)
                {
                    string portTableName = portTableNames[i];
                    ESRI.ArcGIS.Geodatabase.ITable  portTable = _wkspHelper.FindTable(portTableName);
                    ESRI.ArcGIS.Geodatabase.ICursor cursor    = portTable.Search(filter, false);
                    releaser.ManageLifetime(cursor);

                    portRow = cursor.NextRow();
                    if (null != portRow)
                    {
                        ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetDeviceRelationship(portTable);
                        if (null == deviceHasPorts)
                        {
                            throw new Exception("Device to port relationship is missing or cannot be opened.");
                        }

                        ESRI.ArcGIS.Geodatabase.IFeatureClass deviceClass = deviceHasPorts.OriginClass as ESRI.ArcGIS.Geodatabase.IFeatureClass;
                        if (null == deviceClass)
                        {
                            throw new Exception("Device feature class is missing or cannot be opened.");
                        }

                        filter.WhereClause = string.Format("{0}='{1}'",
                                                           deviceHasPorts.OriginPrimaryKey,
                                                           portRow.get_Value(portTable.FindField(deviceHasPorts.OriginForeignKey)));
                        ESRI.ArcGIS.Geodatabase.IFeatureCursor deviceCursor = deviceClass.Search(filter, false);
                        deviceFt = deviceCursor.NextFeature();

                        result = true;
                        break;
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// Delete the ports for a given device
        /// </summary>
        /// <param name="device">The device feature</param>
        /// <returns>True if completed</returns>
        private bool DeletePorts(ESRI.ArcGIS.Geodatabase.IFeature device, int highInputPort, int highOutputPort, ESRI.ArcGIS.Framework.IProgressDialog2 progressDialog, ESRI.ArcGIS.esriSystem.ITrackCancel trackCancel)
        {
            bool isCancelled = false;

            ESRI.ArcGIS.esriSystem.IStepProgressor     stepProgressor = (ESRI.ArcGIS.esriSystem.IStepProgressor)progressDialog;
            ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship((ESRI.ArcGIS.Geodatabase.IFeatureClass)device.Class);

            if (null != deviceHasPorts)
            {
                using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
                {
                    ESRI.ArcGIS.Geodatabase.ITable portTable = (ESRI.ArcGIS.Geodatabase.ITable)deviceHasPorts.DestinationClass;
                    releaser.ManageLifetime(portTable);

                    ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                    releaser.ManageLifetime(filter);

                    filter.WhereClause = string.Format("{0}='{1}' AND {2} > {3} AND {4}='{5}'",
                                                       deviceHasPorts.OriginForeignKey,
                                                       device.get_Value(device.Fields.FindField(deviceHasPorts.OriginPrimaryKey)),
                                                       ConfigUtil.PortIdFieldName,
                                                       highInputPort,
                                                       ConfigUtil.PortTypeFieldName,
                                                       1);

                    stepProgressor.Message = "Deleting higher input ports...";
                    int deletedPorts = portTable.RowCount(filter);

                    portTable.DeleteSearchedRows(filter);
                    for (int i = 0; i < deletedPorts; i++)
                    {
                        stepProgressor.Step();
                    }

                    filter.WhereClause = string.Format("{0}='{1}' AND {2} > {3} AND {4}='{5}'",
                                                       deviceHasPorts.OriginForeignKey,
                                                       device.get_Value(device.Fields.FindField(deviceHasPorts.OriginPrimaryKey)),
                                                       ConfigUtil.PortIdFieldName,
                                                       highOutputPort,
                                                       ConfigUtil.PortTypeFieldName,
                                                       2);

                    stepProgressor.Message = "Deleting higher output ports...";
                    deletedPorts           = portTable.RowCount(filter);

                    portTable.DeleteSearchedRows(filter);
                    for (int i = 0; i < deletedPorts; i++)
                    {
                        stepProgressor.Step();
                    }
                }
            }

            return(!isCancelled);
        }
예제 #6
0
        //根据配置文件初始化系统环境 added by chulili 20110531
        public static void InitSystemByXML(IWorkspace sourceWorkspace, IWorkspace targetWorkspace, bool iscover)
        {
            //xml模板位置固定,根据模板中规定的表名进行拷贝
            string      xmlpath = Application.StartupPath + "\\..\\Template\\InitUserRoleConfig.Xml";
            XmlDocument doc     = new XmlDocument();

            doc.Load(xmlpath);
            string      strSearch       = "//InitSystemRoot";
            XmlNode     pInitSystemnode = doc.SelectSingleNode(strSearch);
            XmlNodeList pInitSystemlist = pInitSystemnode.ChildNodes;

            //遍历需要拷贝的表名
            foreach (XmlNode pnode in pInitSystemlist)
            {
                if (pnode.NodeType == XmlNodeType.Element)
                {
                    XmlElement pEle         = pnode as XmlElement;
                    string     strTableName = pEle.GetAttribute("Name");
                    if (iscover)//如果覆盖,则先把目标库中该表删除
                    {
                        try
                        {
                            IFeatureWorkspace ptmpwks             = targetWorkspace as IFeatureWorkspace;
                            ESRI.ArcGIS.Geodatabase.ITable ptable = ptmpwks.OpenTable(strTableName);
                            IDataset pdataset = ptable as IDataset;
                            pdataset.Delete();
                        }
                        catch (Exception e)
                        {
                        }
                        CopyPasteGDBData.CopyPasteGeodatabaseData(sourceWorkspace, targetWorkspace, strTableName, esriDatasetType.esriDTTable);
                    }
                    else
                    {
                        try//如果不覆盖,判断该表是否存在,不存在则拷贝表
                        {
                            IFeatureWorkspace ptmpwks = targetWorkspace as IFeatureWorkspace;
                            ptmpwks.OpenTable(strTableName);
                        }
                        catch (Exception e)
                        {
                            CopyPasteGDBData.CopyPasteGeodatabaseData(sourceWorkspace, targetWorkspace, strTableName, esriDatasetType.esriDTTable);
                        }
                    }
                }
            }
        }
예제 #7
0
        public void LoadAnalysisObjectsByField(ESRI.ArcGIS.Geodatabase.ITable inputClass,
                                               string naClassName, ESRI.ArcGIS.NetworkAnalyst.INAContext naContext)
        {
            // Both Initialize and Load take a cursor from the input class
            ESRI.ArcGIS.Geodatabase.ICursor cursor = inputClass.Search(null, false) as
                                                     ESRI.ArcGIS.Geodatabase.ICursor;
            ESRI.ArcGIS.NetworkAnalyst.INAClassLoader2 naClassLoader = new
                                                                       ESRI.ArcGIS.NetworkAnalyst.NAClassLoaderClass();
            naClassLoader.Initialize(naContext, naClassName, cursor);

            // Store the current set of locator agents, so they can be added back later
            int agentCount   = naContext.Locator.LocatorAgentCount;
            var listOfAgents = new System.Collections.Generic.List <
                ESRI.ArcGIS.NetworkAnalyst.INALocatorAgent>();

            for (int locIndex = 0; locIndex < agentCount; locIndex++)
            {
                listOfAgents.Add(naContext.Locator.get_LocatorAgent(locIndex));
            }

            // Remove the existing locator agents from the locator
            // This for loop is done in reverse order, because agents are being removed as the loop executes
            for (int locIndex = agentCount - 1; locIndex >= 0; locIndex--)
            {
                naContext.Locator.RemoveLocatorAgent(locIndex);
            }

            // Create and add a fields agent
            var fieldsAgent = new
                              ESRI.ArcGIS.NetworkAnalyst.NALocatorLocationFieldsAgentClass() as
                              ESRI.ArcGIS.NetworkAnalyst.INALocatorLocationFieldsAgent2;

            // Set the field names appropriately based on input data and NAClass
            var naClass = naContext.NAClasses.get_ItemByName(naClassName) as
                          ESRI.ArcGIS.NetworkAnalyst.INAClass;
            var naFeatureClass = naClass as ESRI.ArcGIS.Geodatabase.IFeatureClass;

            // Check to see if the NAClass is of type NALocation or NALocationRanges
            ESRI.ArcGIS.esriSystem.UID naLocationFeatureUID = new
                                                              ESRI.ArcGIS.esriSystem.UIDClass();
            naLocationFeatureUID.Value = "esriNetworkAnalyst.NALocationFeature";
            ESRI.ArcGIS.esriSystem.UID naLocationFeatureRangesUID = new
                                                                    ESRI.ArcGIS.esriSystem.UIDClass();
            naLocationFeatureRangesUID.Value = "esriNetworkAnalyst.NALocationRangesFeature";
            if (naFeatureClass.CLSID.Compare(naLocationFeatureUID))
            {
                // The field names listed below are the names used in ArcGIS Network Analyst extension classes to represent NALocations.
                //  These are also the names of fields added by the CalculateLocations geoprocessing tool
                fieldsAgent.OIDFieldName      = "SourceOID";
                fieldsAgent.SourceIDFieldName = "SourceID";
                fieldsAgent.PositionFieldName = "PosAlong";
                fieldsAgent.SideFieldName     = "SideOfEdge";
            }
            else if (naFeatureClass.CLSID.Compare(naLocationFeatureRangesUID))
            {
                // The location ranges input field must be of type BLOB
                fieldsAgent.LocationRangesFieldName = "Locations";
                var blobField = inputClass.Fields.get_Field(inputClass.FindField
                                                                (fieldsAgent.LocationRangesFieldName));
                if (blobField.Type !=
                    ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeBlob)
                {
                    System.Windows.Forms.MessageBox.Show(
                        "Loading location ranges by field requires a blob field");
                    return;
                }
            }
            naContext.Locator.AddLocatorAgent(fieldsAgent as
                                              ESRI.ArcGIS.NetworkAnalyst.INALocatorAgent);

            // After Loading is complete, the rowsIn and rowsLocated variable can be used to verify
            //  that every row from the input feature class has been loaded into the network analysis class
            int rowsIn      = 0;
            int rowsLocated = 0;

            naClassLoader.Load(cursor, null, ref rowsIn, ref rowsLocated);

            // Now remove the custom fields agent and add back the stored agents
            naContext.Locator.RemoveLocatorAgent(0);
            foreach (var agent in listOfAgents)
            {
                naContext.Locator.AddLocatorAgent(agent);
            }
        }
        /// <summary>
        /// Deletes given connections between cable to device
        /// </summary>
        /// <param name="cable">Cable</param>
        /// <param name="device">Device</param>
        /// <param name="units">Units to connect</param>
        /// <param name="portType">Input or Output?</param>
        /// <param name="isExistingOperation">Flag to control whether we need to wrap this in an edit operation</param>
        /// <returns>Success</returns>
        public bool BreakConnections(FiberCableWrapper cable, DeviceWrapper device, Dictionary <int, int> units, PortType portType, bool isExistingOperation)
        {
            bool success         = false;
            bool isOperationOpen = false;

            #region Validation
            if (null == cable)
            {
                throw new ArgumentNullException("cable");
            }

            if (null == device)
            {
                throw new ArgumentNullException("device");
            }

            if (null == units)
            {
                throw new ArgumentNullException("units");
            }

            if (ESRI.ArcGIS.Editor.esriEditState.esriStateNotEditing == _editor.EditState)
            {
                throw new InvalidOperationException("You must be editing to perform this operation");
            }
            #endregion

            if (0 < units.Count)
            {
                if (!isExistingOperation)
                {
                    _editor.StartOperation();
                    isOperationOpen = true;
                }

                try
                {
                    ESRI.ArcGIS.Geodatabase.IFeatureClass      deviceFtClass  = device.Feature.Class as ESRI.ArcGIS.Geodatabase.IFeatureClass;
                    ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(deviceFtClass);
                    if (null == deviceFtClass)
                    {
                        throw new Exception("Unable to find port relationship class.");
                    }

                    ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable;
                    if (null == portTable)
                    {
                        throw new Exception("Invalid destination on port relationship class.");
                    }

                    using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
                    {
                        ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                        releaser.ManageLifetime(filter);

                        StringBuilder inList = new StringBuilder(1024);
                        foreach (KeyValuePair <int, int> pair in units)
                        {
                            string appendFormat = "{0},";
                            if (PortType.Input == portType)
                            {
                                inList.AppendFormat(appendFormat, pair.Key);
                            }
                            else
                            {
                                inList.AppendFormat(appendFormat, pair.Value);
                            }
                        }
                        inList.Remove(inList.Length - 1, 1);

                        string format = "{0}='{1}' AND {2}='{3}' AND {4}='{5}' AND {6} IN ({7})";
                        filter.WhereClause = string.Format(format,
                                                           deviceHasPorts.OriginForeignKey,
                                                           device.Feature.get_Value(deviceFtClass.FindField(deviceHasPorts.OriginPrimaryKey)),
                                                           ConfigUtil.ConnectedCableFieldName,
                                                           cable.IPID,
                                                           ConfigUtil.PortTypeFieldName,
                                                           (PortType.Input == portType ? "1" : "2"),
                                                           ConfigUtil.ConnectedFiberFieldName,
                                                           inList.ToString());

                        filter.SubFields = string.Format("{0},{1},{2}", ConfigUtil.ConnectedEndFieldName, ConfigUtil.ConnectedFiberFieldName, ConfigUtil.ConnectedCableFieldName);

                        ESRI.ArcGIS.Geodatabase.IRowBuffer buffer = portTable.CreateRowBuffer();
                        releaser.ManageLifetime(buffer);
                        // We want to set them to null, so we can just send the empty buffer
                        portTable.UpdateSearchedRows(filter, buffer);

                        if (isOperationOpen)
                        {
                            _editor.StopOperation("Break Connections");
                            isOperationOpen = false;
                        }

                        success = true;
                    }
                }
                catch
                {
                    if (isOperationOpen)
                    {
                        _editor.AbortOperation();
                    }

                    success = false;
                }
            }

            return(success);
        }
        /// <summary>
        /// Break all connections for a given cable
        /// </summary>
        /// <param name="cable">Cable to break connections</param>
        /// <param name="isExistingOperation">Should we start/stop the edit operation, or are we already in one?</param>
        /// <returns>Success</returns>
        public bool BreakAllConnections(FiberCableWrapper cable, bool isExistingOperation)
        {
            bool success         = false;
            bool isOperationOpen = false;

            #region Validation
            if (null == cable)
            {
                throw new ArgumentNullException("cable");
            }

            if (ESRI.ArcGIS.Editor.esriEditState.esriStateNotEditing == _editor.EditState)
            {
                throw new InvalidOperationException("You must be editing to perform this operation");
            }
            #endregion

            if (!isExistingOperation)
            {
                _editor.StartOperation();
                isOperationOpen = true;
            }

            try
            {
                using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
                {
                    ESRI.ArcGIS.Geodatabase.IFeatureClass cableFtClass = cable.Feature.Class as ESRI.ArcGIS.Geodatabase.IFeatureClass;
                    ESRI.ArcGIS.Geodatabase.IQueryFilter  filter       = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                    releaser.ManageLifetime(filter);

                    filter.WhereClause = string.Format("{0}='{1}'", ConfigUtil.ConnectedCableFieldName, cable.IPID);
                    filter.SubFields   = string.Format("{0},{1},{2}", ConfigUtil.ConnectedCableFieldName, ConfigUtil.ConnectedFiberFieldName, ConfigUtil.ConnectedEndFieldName);

                    string[] deviceClassNames = ConfigUtil.DeviceFeatureClassNames;
                    for (int i = 0; i < deviceClassNames.Length; i++)
                    {
                        string deviceClassName = deviceClassNames[i];


                        ESRI.ArcGIS.Geodatabase.IFeatureClass deviceFtClass = _wkspHelper.FindFeatureClass(deviceClassName);
//                        ESRI.ArcGIS.Geodatabase.IFeatureClass deviceFtClass = GdbUtils.GetFeatureClass(cableFtClass, deviceClassName);
                        ESRI.ArcGIS.Geodatabase.ITable     portTable = ConfigUtil.GetPortTable(deviceFtClass);
                        ESRI.ArcGIS.Geodatabase.IRowBuffer buffer    = portTable.CreateRowBuffer();
                        // We want to set them to null, so we can just send the empty buffer
                        portTable.UpdateSearchedRows(filter, buffer);

                        ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(buffer);
                    }

                    if (isOperationOpen)
                    {
                        _editor.StopOperation("Break Connections");
                        isOperationOpen = false;
                    }

                    success = true;
                }
            }
            catch
            {
                if (isOperationOpen)
                {
                    _editor.AbortOperation();
                }

                success = false;
            }

            return(success);
        }
        /// <summary>
        /// Returns a list of connections between the cable and the device, at the cable's given end, to the device's given port type
        /// </summary>
        /// <param name="cable">Cable to check</param>
        /// <param name="device">Device to check</param>
        /// <param name="isFromEnd">Digitized end of cable</param>
        /// <param name="portType">Input or output</param>
        /// <returns>List of Connection</returns>
        public List <Connection> GetConnections(FiberCableWrapper cable, DeviceWrapper device, bool isFromEnd, PortType portType)
        {
            if (null == cable)
            {
                throw new ArgumentNullException("cable");
            }

            if (null == device)
            {
                throw new ArgumentNullException("device");
            }

            List <Connection> result  = new List <Connection>();
            List <int>        ports   = new List <int>();
            List <int>        strands = new List <int>();

            using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
            {
                ESRI.ArcGIS.Geodatabase.IFeatureClass      deviceFtClass  = device.Feature.Class as ESRI.ArcGIS.Geodatabase.IFeatureClass;
                ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(deviceFtClass);
                if (null == deviceHasPorts)
                {
                    throw new Exception("Unable to find port relationship class.");
                }

                ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable;
                if (null == portTable)
                {
                    throw new Exception("Invalid destination on port relationship class.");
                }

                ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                releaser.ManageLifetime(filter);
                filter.WhereClause = string.Format("{0}='{1}' AND {2}='{3}' AND {4}='{5}' AND {6}='{7}' AND {8} IS NOT NULL AND {9} IS NOT NULL",
                                                   deviceHasPorts.OriginForeignKey,
                                                   device.Feature.get_Value(deviceFtClass.FindField(deviceHasPorts.OriginPrimaryKey)),
                                                   ConfigUtil.ConnectedCableFieldName,
                                                   cable.IPID,
                                                   ConfigUtil.PortTypeFieldName,
                                                   (PortType.Input == portType ? "1" : "2"),
                                                   ConfigUtil.ConnectedEndFieldName,
                                                   (isFromEnd ? "T" : "F"),
                                                   ConfigUtil.ConnectedFiberFieldName,
                                                   ConfigUtil.PortIdFieldName);


                // ORDER BY does not work outside of SDE.
                // Removing for now, should not be important.
                string orderFormat = "ORDER BY {0}";
                if (PortType.Input == portType)
                {
//                    ((ESRI.ArcGIS.Geodatabase.IQueryFilterDefinition2)filter).PostfixClause = string.Format(orderFormat, ConfigUtil.ConnectedFiberFieldName);
                }
                else
                {
//                    ((ESRI.ArcGIS.Geodatabase.IQueryFilterDefinition2)filter).PostfixClause = string.Format(orderFormat, ConfigUtil.PortIdFieldName);
                }

                ESRI.ArcGIS.Geodatabase.ICursor portCursor = portTable.Search(filter, true);
                ESRI.ArcGIS.Geodatabase.IRow    portRow    = portCursor.NextRow();

                int portIdIdx      = portTable.FindField(ConfigUtil.PortIdFieldName);
                int fiberNumberIdx = portTable.FindField(ConfigUtil.ConnectedFiberFieldName);

                while (null != portRow)
                {
                    ports.Add((int)portRow.get_Value(portIdIdx));
                    strands.Add((int)portRow.get_Value(fiberNumberIdx));

                    ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(portRow);
                    portRow = portCursor.NextRow();
                }

                ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(portCursor);
            }


            List <Range> portRanges   = SpliceAndConnectionUtils.MergeRanges(ports);
            List <Range> strandRanges = SpliceAndConnectionUtils.MergeRanges(strands);

            if (PortType.Input == portType)
            {
                result = SpliceAndConnectionUtils.MatchUp(strandRanges, portRanges);
            }
            else
            {
                result = SpliceAndConnectionUtils.MatchUp(portRanges, strandRanges);
            }

            return(result);
        }
        /// <summary>
        /// Creates given connections between cable and device
        /// </summary>
        /// <param name="cable">Cable</param>
        /// <param name="device">Device</param>
        /// <param name="units">Units to connect</param>
        /// <param name="isFromEnd">Is it the cable's from end?</param>
        /// <param name="portType">Input or Output?</param>
        /// <param name="isExistingOperation">Flag to control whether we need to wrap this in a new edit operation</param>
        /// <returns>Success</returns>
        public bool MakeConnections(FiberCableWrapper cable, DeviceWrapper device, Dictionary <int, int> units, bool isFromEnd, PortType portType, bool isExistingOperation)
        {
            bool success         = false;
            bool isOperationOpen = false;

            #region Validation
            if (null == cable)
            {
                throw new ArgumentNullException("cable");
            }

            if (null == device)
            {
                throw new ArgumentNullException("device");
            }

            if (null == units)
            {
                throw new ArgumentNullException("units");
            }

            if (ESRI.ArcGIS.Editor.esriEditState.esriStateNotEditing == _editor.EditState)
            {
                throw new InvalidOperationException("You must be editing to perform this operation");
            }
            #endregion

            if (!isExistingOperation)
            {
                _editor.StartOperation();
                isOperationOpen = true;
            }

            try
            {
                ESRI.ArcGIS.Geodatabase.IFeatureClass      deviceFtClass  = device.Feature.Class as ESRI.ArcGIS.Geodatabase.IFeatureClass;
                ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(deviceFtClass);
                if (null == deviceHasPorts)
                {
                    throw new Exception("Unable to get port relationship class.");
                }

                ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable;
                if (null == portTable)
                {
                    throw new Exception("Invalid destination on port relationship class.");
                }

                int    portIdIdx      = portTable.FindField(ConfigUtil.PortIdFieldName);
                int    fiberNumberIdx = portTable.FindField(ConfigUtil.ConnectedFiberFieldName);
                int    cableIdIdx     = portTable.FindField(ConfigUtil.ConnectedCableFieldName);
                int    isFromEndIdx   = portTable.FindField(ConfigUtil.ConnectedEndFieldName);
                string isFromEndValue = isFromEnd ? "T" : "F";

                Dictionary <int, int> portsAsKeys = units;
                if (PortType.Input == portType)
                {
                    portsAsKeys = new Dictionary <int, int>();
                    foreach (KeyValuePair <int, int> pair in units)
                    {
                        portsAsKeys[pair.Value] = pair.Key;
                    }
                }

                using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
                {
                    ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                    releaser.ManageLifetime(filter);

                    string format = "{0}='{1}' AND {2}='{3}'";
                    filter.WhereClause = string.Format(format,
                                                       deviceHasPorts.OriginForeignKey,
                                                       device.Feature.get_Value(deviceFtClass.FindField(deviceHasPorts.OriginPrimaryKey)),
                                                       ConfigUtil.PortTypeFieldName,
                                                       (PortType.Input == portType ? "1" : "2"));

                    // Non recylcing cursor since we are doing updates.
                    ESRI.ArcGIS.Geodatabase.ICursor portCursor = portTable.Update(filter, false);
                    releaser.ManageLifetime(portCursor);

                    ESRI.ArcGIS.Geodatabase.IRow portRow = portCursor.NextRow();
                    while (null != portRow)
                    {
                        object portIdObj = portRow.get_Value(portIdIdx);
                        if (DBNull.Value != portIdObj)
                        {
                            int portId = System.Convert.ToInt32(portIdObj);
                            if (portsAsKeys.ContainsKey(portId))
                            {
                                portRow.set_Value(cableIdIdx, cable.IPID);
                                portRow.set_Value(isFromEndIdx, isFromEndValue);
                                portRow.set_Value(fiberNumberIdx, portsAsKeys[portId]);
                                portRow.Store();
                            }
                        }

                        ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(portRow);
                        portRow = portCursor.NextRow();
                    }

                    if (isOperationOpen)
                    {
                        _editor.StopOperation("Create Connections");
                        isOperationOpen = false;
                    }

                    success = true;
                }
            }
            catch (Exception ex)
            {
                if (isOperationOpen)
                {
                    _editor.AbortOperation();
                }

                success = false;

                throw new Exception("Save operation failed.");
            }

            return(success);
        }
예제 #12
0
        /// <summary>
        /// Splices all available strands from one cable to the other, at a given splice closure
        /// </summary>
        /// <param name="cableA">Cable A</param>
        /// <param name="cableB">Cable B</param>
        /// <param name="splice">Splice Closure</param>
        /// <param name="strands">Strands to splice together</param>
        /// <param name="isExistingOperation">Flag to control whether we need to wrap this in an edit operation</param>
        /// <returns>Success</returns>
        public bool CreateSplices(FiberCableWrapper cableA, SpliceableCableWrapper cableB, SpliceClosureWrapper splice, Dictionary <int, FiberSplice> strands, bool isExistingOperation)
        {
            bool success         = false;
            bool isOperationOpen = false;

            #region Validation
            if (null == cableA)
            {
                throw new ArgumentNullException("cableA");
            }

            if (null == cableB)
            {
                throw new ArgumentNullException("cableB");
            }

            if (ESRI.ArcGIS.Editor.esriEditState.esriStateNotEditing == _editor.EditState)
            {
                throw new InvalidOperationException("You must be editing to perform this operation");
            }
            #endregion

            if (!isExistingOperation)
            {
                _editor.StartOperation();
                isOperationOpen = true;
            }


            if (null == splice)
            {
                splice = GenerateSpliceClosure(cableA, cableB);
            }
            else if (0 == splice.IPID.Length)
            {
                // Populate an IPID; we will need it
                ESRI.ArcGIS.Geodatabase.IFeature spliceFt = splice.Feature;
                Guid g = Guid.NewGuid();

                spliceFt.set_Value(spliceFt.Fields.FindField(ConfigUtil.IpidFieldName), g.ToString("B").ToUpper());
                spliceFt.Store();
            }

            try
            {
                ESRI.ArcGIS.Geodatabase.ITable fiberSpliceTable = _wkspHelper.FindTable(ConfigUtil.FiberSpliceTableName);
//                ESRI.ArcGIS.Geodatabase.ITable fiberSpliceTable = GdbUtils.GetTable(cableA.Feature.Class, ConfigUtil.FiberSpliceTableName);
                int aCableIdx     = fiberSpliceTable.FindField(ConfigUtil.ACableIdFieldName);
                int bCableIdx     = fiberSpliceTable.FindField(ConfigUtil.BCableIdFieldName);
                int aFiberNumIdx  = fiberSpliceTable.FindField(ConfigUtil.AFiberNumberFieldName);
                int bFiberNumIdx  = fiberSpliceTable.FindField(ConfigUtil.BFiberNumberFieldName);
                int spliceIpidIdx = fiberSpliceTable.FindField(ConfigUtil.SpliceClosureIpidFieldName);
                int isAFromIdx    = fiberSpliceTable.FindField(ConfigUtil.IsAFromEndFieldName);
                int isBFromIdx    = fiberSpliceTable.FindField(ConfigUtil.IsBFromEndFieldName);
                int lossIdx       = fiberSpliceTable.FindField(ConfigUtil.LossFieldName);
                int typeIdx       = fiberSpliceTable.FindField(ConfigUtil.TypeFieldName);
                ESRI.ArcGIS.Geodatabase.IField typeField = fiberSpliceTable.Fields.get_Field(typeIdx);

                string aCableId   = cableA.IPID;
                string bCableId   = cableB.IPID;
                string isAFromEnd = cableB.IsOtherFromEnd ? "T" : "F";
                string isBFromEnd = cableB.IsThisFromEnd ? "T" : "F";
                string spliceIpid = splice.IPID;

                using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
                {
                    // TODO cant use insert cursor since edit events wont fire.
                    // We need evetns to fire for dynamic values to get populated.
                    // ESRI.ArcGIS.Geodatabase.ICursor insertCursor = fiberSpliceTable.Insert(true);
                    // releaser.ManageLifetime(insertCursor);

                    foreach (KeyValuePair <int, FiberSplice> pair in strands)
                    {
                        IRow row = fiberSpliceTable.CreateRow();

                        releaser.ManageLifetime(row);

                        FiberSplice fiberSplice = pair.Value;

                        row.set_Value(aCableIdx, aCableId);
                        row.set_Value(bCableIdx, bCableId);
                        row.set_Value(aFiberNumIdx, pair.Key);
                        row.set_Value(bFiberNumIdx, fiberSplice.BRange.Low);
                        row.set_Value(spliceIpidIdx, spliceIpid);
                        row.set_Value(isAFromIdx, isAFromEnd);
                        row.set_Value(isBFromIdx, isBFromEnd);

                        if (null == fiberSplice.Loss)
                        {
                            row.set_Value(lossIdx, DBNull.Value);
                        }
                        else
                        {
                            row.set_Value(lossIdx, fiberSplice.Loss);
                        }

                        object typeValue = DBNull.Value;
                        if (null != fiberSplice.Type)
                        {
                            try
                            {
                                typeValue = GdbUtils.CheckForCodedValue(typeField, fiberSplice.Type);
                            }
                            catch
                            {
                                // TODO: Log a warning about why we can't set the default split splice type?
                            }
                        }

                        row.set_Value(typeIdx, typeValue);
                        row.Store();
                    }
                }

                if (isOperationOpen)
                {
                    _editor.StopOperation("Edit Splices");
                }

                success = true;
            }
            catch
            {
                if (isOperationOpen)
                {
                    _editor.AbortOperation();
                }

                success = false;
            }

            return(success);
        }
        // create table in file geodatabase
        #region "create table in file geodatabase"
        public static ESRI.ArcGIS.Geodatabase.ITable CreateTable(String tableName, UID classExtensionUID, IFeatureWorkspace featureWorkspace)
        {
            // Create a fields collection for the feature class.
            IFields     fields     = new FieldsClass();
            IFieldsEdit fieldsEdit = (IFieldsEdit)fields;

            // Add an object ID field to the fields collection. This is mandatory for feature classes.
            IField     oidField     = new FieldClass();
            IFieldEdit oidFieldEdit = (IFieldEdit)oidField;

            oidFieldEdit.Name_2 = "OBJECTID";
            oidFieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;
            fieldsEdit.AddField(oidField);

            // Create a text field called "ADDRSYS_L" for the fields collection.
            IField     addrSysLField     = new FieldClass();
            IFieldEdit addrSysLFieldEdit = (IFieldEdit)addrSysLField;

            addrSysLFieldEdit.Name_2   = "ADDRSYS_L";
            addrSysLFieldEdit.Type_2   = esriFieldType.esriFieldTypeString;
            addrSysLFieldEdit.Length_2 = 30;
            fieldsEdit.AddField(addrSysLField);

            // Create a text field called "ADDRSYS_R" for the fields collection.
            IField     addrSysRField     = new FieldClass();
            IFieldEdit addrSysRFieldEdit = (IFieldEdit)addrSysRField;

            addrSysRFieldEdit.Name_2   = "ADDRSYS_R";
            addrSysRFieldEdit.Type_2   = esriFieldType.esriFieldTypeString;
            addrSysRFieldEdit.Length_2 = 30;
            fieldsEdit.AddField(addrSysRField);

            // Create a text field called "FROMADDR_L" for the fields collection.
            IField     rangeL_Ffield     = new FieldClass();
            IFieldEdit rangeL_FfieldEdit = (IFieldEdit)rangeL_Ffield;

            rangeL_FfieldEdit.Name_2      = "FROMADDR_L";
            rangeL_FfieldEdit.Type_2      = esriFieldType.esriFieldTypeDouble;
            rangeL_FfieldEdit.Precision_2 = 38;
            rangeL_FfieldEdit.Scale_2     = 8;
            fieldsEdit.AddField(rangeL_Ffield);

            // Create a text field called "TOADDR_L" for the fields collection.
            IField     rangeL_Tfield     = new FieldClass();
            IFieldEdit rangeL_TfieldEdit = (IFieldEdit)rangeL_Tfield;

            rangeL_TfieldEdit.Name_2      = "TOADDR_L";
            rangeL_TfieldEdit.Type_2      = esriFieldType.esriFieldTypeDouble;
            rangeL_TfieldEdit.Precision_2 = 38;
            rangeL_TfieldEdit.Scale_2     = 8;
            fieldsEdit.AddField(rangeL_Tfield);

            // Create a text field called "FROMADDR_R" for the fields collection.
            IField     rangeR_Ffield     = new FieldClass();
            IFieldEdit rangeR_FfieldEdit = (IFieldEdit)rangeR_Ffield;

            rangeR_FfieldEdit.Name_2      = "FROMADDR_R";
            rangeR_FfieldEdit.Type_2      = esriFieldType.esriFieldTypeDouble;
            rangeR_FfieldEdit.Precision_2 = 38;
            rangeR_FfieldEdit.Scale_2     = 8;
            fieldsEdit.AddField(rangeR_Ffield);

            // Create a text field called "TOADDR_R" for the fields collection.
            IField     rangeR_Tfield     = new FieldClass();
            IFieldEdit rangeR_TfieldEdit = (IFieldEdit)rangeR_Tfield;

            rangeR_TfieldEdit.Name_2      = "TOADDR_R";
            rangeR_TfieldEdit.Type_2      = esriFieldType.esriFieldTypeDouble;
            rangeR_TfieldEdit.Precision_2 = 38;
            rangeR_TfieldEdit.Scale_2     = 8;
            fieldsEdit.AddField(rangeR_Tfield);

            // Create a text field called "PREDIR" for the fields collection.
            IField     predirField     = new FieldClass();
            IFieldEdit predirFieldEdit = (IFieldEdit)predirField;

            predirFieldEdit.Name_2   = "PREDIR";
            predirFieldEdit.Type_2   = esriFieldType.esriFieldTypeString;
            predirFieldEdit.Length_2 = 1;
            fieldsEdit.AddField(predirField);

            // Create a text field called "NAME" for the fields collection.
            IField     nameField     = new FieldClass();
            IFieldEdit nameFieldEdit = (IFieldEdit)nameField;

            nameFieldEdit.Name_2   = "NAME";
            nameFieldEdit.Type_2   = esriFieldType.esriFieldTypeString;
            nameFieldEdit.Length_2 = 30;
            fieldsEdit.AddField(nameField);

            // Create a text field called "POSTTYPE" for the fields collection.
            IField     streettypeField     = new FieldClass();
            IFieldEdit streettypeFieldEdit = (IFieldEdit)streettypeField;

            streettypeFieldEdit.Name_2   = "POSTTYPE";
            streettypeFieldEdit.Type_2   = esriFieldType.esriFieldTypeString;
            streettypeFieldEdit.Length_2 = 4;
            fieldsEdit.AddField(streettypeField);

            // Create a text field called "POSTDIR" for the fields collection.
            IField     sufdirField     = new FieldClass();
            IFieldEdit sufdirFieldEdit = (IFieldEdit)sufdirField;

            sufdirFieldEdit.Name_2   = "POSTDIR";
            sufdirFieldEdit.Type_2   = esriFieldType.esriFieldTypeString;
            sufdirFieldEdit.Length_2 = 2;
            fieldsEdit.AddField(sufdirField);

            // Create a text field called "ZIPCODE_L" for the fields collection.
            IField     zipleftField     = new FieldClass();
            IFieldEdit zipleftFieldEdit = (IFieldEdit)zipleftField;

            zipleftFieldEdit.Name_2   = "ZIPCODE_L";
            zipleftFieldEdit.Type_2   = esriFieldType.esriFieldTypeString;
            zipleftFieldEdit.Length_2 = 5;
            fieldsEdit.AddField(zipleftField);

            // Create a text field called "ZIPCODE_R" for the fields collection.
            IField     ziprightField     = new FieldClass();
            IFieldEdit ziprightFieldEdit = (IFieldEdit)ziprightField;

            ziprightFieldEdit.Name_2   = "ZIPCODE_R";
            ziprightFieldEdit.Type_2   = esriFieldType.esriFieldTypeString;
            ziprightFieldEdit.Length_2 = 5;
            fieldsEdit.AddField(ziprightField);

            // Create a text field called "GLOBALID_SGID" for the fields collection - to join back to the feature class or sgid.
            IField     globalidField     = new FieldClass();
            IFieldEdit globalidFieldEdit = (IFieldEdit)globalidField;

            globalidFieldEdit.Name_2   = "GLOBALID_SGID";
            globalidFieldEdit.Type_2   = esriFieldType.esriFieldTypeString; // use string and not the globalid type b/c it might that might assign it's own unique global id and this is for joinging back to sgid
            globalidFieldEdit.Length_2 = 50;
            fieldsEdit.AddField(globalidField);

            // Use IFieldChecker to create a validated fields collection.
            IFieldChecker   fieldChecker    = new FieldCheckerClass();
            IEnumFieldError enumFieldError  = null;
            IFields         validatedFields = null;

            fieldChecker.ValidateWorkspace = (IWorkspace)featureWorkspace;
            fieldChecker.Validate(fields, out enumFieldError, out validatedFields);

            // Create the feature class. Note that the CLSID parameter is null - this indicates to use the
            // default CLSID, esriGeodatabase.Feature (acceptable in most cases for feature classes).
            ESRI.ArcGIS.Geodatabase.ITable arcTable = featureWorkspace.CreateTable(tableName, validatedFields, null, classExtensionUID, "");

            return(arcTable);
        }
예제 #14
0
        /// <summary>
        /// Deletes given splices from one cable to the other, at a given splice closure
        /// </summary>
        /// <param name="cableA">Cable A</param>
        /// <param name="cableB">Cable B</param>
        /// <param name="splice">Splice Closure</param>
        /// <param name="strands">Strands to remove</param>
        /// <param name="isExistingOperation">Flag to control whether we need to wrap this in an edit operation</param>
        /// <returns>Success</returns>
        public bool BreakSplices(FiberCableWrapper cableA, SpliceableCableWrapper cableB, SpliceClosureWrapper splice, Dictionary <int, FiberSplice> strands, bool isExistingOperation)
        {
            bool success         = false;
            bool isOperationOpen = false;

            #region Validation
            if (null == cableA)
            {
                throw new ArgumentNullException("cableA");
            }

            if (null == cableB)
            {
                throw new ArgumentNullException("cableB");
            }

            if (null == splice)
            {
                throw new ArgumentNullException("splice");
            }

            if (ESRI.ArcGIS.Editor.esriEditState.esriStateNotEditing == _editor.EditState)
            {
                throw new InvalidOperationException("You must be editing to perform this operation");
            }
            #endregion

            if (!isExistingOperation)
            {
                _editor.StartOperation();
                isOperationOpen = true;
            }

            try
            {
                ESRI.ArcGIS.Geodatabase.ITable spliceTable = _wkspHelper.FindTable(ConfigUtil.FiberSpliceTableName);
//                ESRI.ArcGIS.Geodatabase.ITable spliceTable = GdbUtils.GetTable(splice.Feature.Class, ConfigUtil.FiberSpliceTableName);

                using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
                {
                    ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                    releaser.ManageLifetime(filter);

                    // A and B is arbitrary, so we check the given combinations going both ways. The structure is:
                    // Where the splice closure IPID is ours and
                    // ((the A Cable/Fiber matches our A cable and B Cable/Fiber matches our B)
                    //  OR (the A Cable/Fiber matches our B cable and B Cable/Fiber matches our A))
                    string format = "{0}='{1}' AND (({2}='{3}' AND {4}={5} AND {6}='{7}' AND {8}={9})" +
                                    " OR ({2}='{7}' AND {4}={9} AND {6}='{3}' AND {8}={5}))";

                    foreach (KeyValuePair <int, FiberSplice> pair in strands)
                    {
                        filter.WhereClause = string.Format(format,
                                                           ConfigUtil.SpliceClosureIpidFieldName,
                                                           splice.IPID,
                                                           ConfigUtil.ACableIdFieldName,
                                                           cableA.IPID,
                                                           ConfigUtil.AFiberNumberFieldName,
                                                           pair.Key,
                                                           ConfigUtil.BCableIdFieldName,
                                                           cableB.IPID,
                                                           ConfigUtil.BFiberNumberFieldName,
                                                           pair.Value.BRange.Low);

                        spliceTable.DeleteSearchedRows(filter);
                    }

                    if (isOperationOpen)
                    {
                        _editor.StopOperation("Break Splices");
                        isOperationOpen = false;
                    }

                    success = true;
                }
            }
            catch
            {
                if (isOperationOpen)
                {
                    _editor.AbortOperation();
                }

                success = false;
            }

            return(success);
        }
        /// <summary>
        /// Generate the ports for a given device
        /// </summary>
        /// <param name="device">The device feature</param>
        /// <returns>True if completed</returns>
        private bool GeneratePorts(ESRI.ArcGIS.Geodatabase.IFeature device, int lowInputPort, int inputPortCount, int lowOutputPort, int outputPortCount, ESRI.ArcGIS.Framework.IProgressDialog2 progressDialog, ESRI.ArcGIS.esriSystem.ITrackCancel trackCancel)
        {
            bool isCancelled = false;

            ESRI.ArcGIS.esriSystem.IStepProgressor     stepProgressor = (ESRI.ArcGIS.esriSystem.IStepProgressor)progressDialog;
            ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship((ESRI.ArcGIS.Geodatabase.IFeatureClass)device.Class);
            Guid g;

            if (null != deviceHasPorts)
            {
                using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
                {
                    ESRI.ArcGIS.Geodatabase.ITable portTable = (ESRI.ArcGIS.Geodatabase.ITable)deviceHasPorts.DestinationClass;
                    releaser.ManageLifetime(portTable);

                    // Fields to populate on port
                    int portIpidIdx   = portTable.Fields.FindField(ConfigUtil.IpidFieldName);
                    int portNumberIdx = portTable.Fields.FindField(ConfigUtil.PortIdFieldName);
                    int portTypeIdx   = portTable.Fields.FindField(ConfigUtil.PortTypeFieldName);
                    int fkeyIdx       = portTable.Fields.FindField(deviceHasPorts.OriginForeignKey);

                    object originPrimaryKey = device.get_Value(device.Fields.FindField(deviceHasPorts.OriginPrimaryKey));

                    for (int portIdx = lowInputPort; portIdx <= inputPortCount; portIdx++)
                    {
                        stepProgressor.Message = string.Format("Creating input port {0} of {1}", portIdx, inputPortCount);
                        stepProgressor.Step();

                        g = Guid.NewGuid();
                        string portIpid = g.ToString("B").ToUpper();

                        ESRI.ArcGIS.Geodatabase.IRow portRow = portTable.CreateRow();
                        releaser.ManageLifetime(portRow);

                        portRow.set_Value(portIpidIdx, portIpid);
                        portRow.set_Value(portTypeIdx, PortType.Input);
                        portRow.set_Value(portNumberIdx, portIdx);
                        portRow.set_Value(fkeyIdx, originPrimaryKey);

                        portRow.Store();

                        if (!trackCancel.Continue())
                        {
                            isCancelled = true;
                            break;
                        }
                    }

                    if (trackCancel.Continue())
                    {
                        for (int portIdx = lowOutputPort; portIdx <= outputPortCount; portIdx++)
                        {
                            stepProgressor.Message = string.Format("Creating output port {0} of {1}", portIdx, outputPortCount);
                            stepProgressor.Step();

                            g = Guid.NewGuid();
                            string portIpid = g.ToString("B").ToUpper();

                            ESRI.ArcGIS.Geodatabase.IRow portRow = portTable.CreateRow();
                            releaser.ManageLifetime(portRow);

                            portRow.set_Value(portIpidIdx, portIpid);
                            portRow.set_Value(portTypeIdx, PortType.Output);
                            portRow.set_Value(portNumberIdx, portIdx);
                            portRow.set_Value(fkeyIdx, originPrimaryKey);

                            portRow.Store();

                            if (!trackCancel.Continue())
                            {
                                isCancelled = true;
                                break;
                            }
                        }
                    }
                }
            }

            return(!isCancelled);
        }
        ///// <summary>
        ///// The active view has refreshed. Redraw our results, if we have any
        ///// </summary>
        ///// <param name="Display">Display to draw on</param>
        ///// <param name="phase"></param>
        //private void _arcMapWrapper_ActiveViewAfterDraw(ESRI.ArcGIS.Display.IDisplay Display, ESRI.ArcGIS.Carto.esriViewDrawPhase phase)
        //{
        //    if (phase == ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection)
        //    {
        //        // Draw after the selection
        //        if (null != _currentResults)
        //        {
        //            ESRI.ArcGIS.Display.ILineSymbol lineSymbol = new ESRI.ArcGIS.Display.SimpleLineSymbol();
        //            ESRI.ArcGIS.Display.IRgbColor color = new ESRI.ArcGIS.Display.RgbColorClass();
        //            color.Red = 255;
        //            color.Green = 0;
        //            color.Blue = 0;

        //            lineSymbol.Color = color;
        //            lineSymbol.Width = 4;

        //            ESRI.ArcGIS.Display.ISimpleMarkerSymbol markerSymbol = new ESRI.ArcGIS.Display.SimpleMarkerSymbolClass();
        //            markerSymbol.Color = color;
        //            markerSymbol.Style = ESRI.ArcGIS.Display.esriSimpleMarkerStyle.esriSMSCircle;
        //            markerSymbol.Size = 6;

        //            for (int i = 0; i < _currentResults.Count; i++)
        //            {
        //                ESRI.ArcGIS.Geometry.IGeometry geometry = _currentResults[i];
        //                if (geometry is ESRI.ArcGIS.Geometry.IPolyline)
        //                {
        //                    Display.SetSymbol((ESRI.ArcGIS.Display.ISymbol)lineSymbol);
        //                    Display.DrawPolyline((ESRI.ArcGIS.Geometry.IPolyline)geometry);
        //                }
        //                else if (geometry is ESRI.ArcGIS.Geometry.IPoint)
        //                {
        //                    Display.SetSymbol((ESRI.ArcGIS.Display.ISymbol)markerSymbol);
        //                    Display.DrawPoint((ESRI.ArcGIS.Geometry.IPoint)geometry);
        //                }
        //            }
        //        }
        //    }
        //}

        private List <ESRI.ArcGIS.Geodatabase.IRow> TracePath(ESRI.ArcGIS.Geodatabase.IFeature cableFeature, int fiberNumber, bool isStartingAtFromEnd)
        {
            List <ESRI.ArcGIS.Geodatabase.IRow> result = new List <ESRI.ArcGIS.Geodatabase.IRow>();

            string ipid = cableFeature.get_Value(cableFeature.Fields.FindField(ConfigUtil.IpidFieldName)).ToString();

            ESRI.ArcGIS.Geodatabase.IFeatureClass cableFtClass = (ESRI.ArcGIS.Geodatabase.IFeatureClass)cableFeature.Class;

            ESRI.ArcGIS.Geodatabase.IFeatureClass spliceFtClass    = _wkspHelper.FindFeatureClass(ConfigUtil.SpliceClosureFtClassName);
            ESRI.ArcGIS.Geodatabase.ITable        fiberSpliceTable = _wkspHelper.FindTable(ConfigUtil.FiberSpliceTableName);

            ESRI.ArcGIS.Geodatabase.IFields spliceFields = fiberSpliceTable.Fields;

            string fiberClassName = ConfigUtil.FiberTableName;

            ESRI.ArcGIS.Geodatabase.IRelationshipClass fiberRelationship = GdbUtils.GetRelationshipClass(cableFtClass, ConfigUtil.FiberCableToFiberRelClassName);
            if (null != fiberRelationship && null != fiberRelationship.DestinationClass)
            {
                fiberClassName = GdbUtils.ParseTableName(fiberRelationship.DestinationClass as ESRI.ArcGIS.Geodatabase.IDataset);
            }

            ESRI.ArcGIS.Geodatabase.ITable fiberTable = _wkspHelper.FindTable(fiberClassName);

            _aCableIdx            = spliceFields.FindField(ConfigUtil.ACableIdFieldName);
            _bCableIdx            = spliceFields.FindField(ConfigUtil.BCableIdFieldName);
            _aFiberNumIdx         = spliceFields.FindField(ConfigUtil.AFiberNumberFieldName);
            _bFiberNumIdx         = spliceFields.FindField(ConfigUtil.BFiberNumberFieldName);
            _isAFromIdx           = spliceFields.FindField(ConfigUtil.IsAFromEndFieldName);
            _isBFromIdx           = spliceFields.FindField(ConfigUtil.IsBFromEndFieldName);
            _spliceClosureIpidIdx = spliceFields.FindField(ConfigUtil.SpliceClosureIpidFieldName);

            ESRI.ArcGIS.Geodatabase.IQueryFilter spliceFilter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
            spliceFilter.WhereClause = string.Format("({0}='{1}' AND {2}={3})"
                                                     + " OR ({4}='{1}' AND {5}={3})",
                                                     ConfigUtil.ACableIdFieldName,
                                                     ipid,
                                                     ConfigUtil.AFiberNumberFieldName,
                                                     fiberNumber,
                                                     ConfigUtil.BCableIdFieldName,
                                                     ConfigUtil.BFiberNumberFieldName);

            int connections = fiberSpliceTable.RowCount(spliceFilter);

            if (2 < connections)
            {
                // TODO: warning?
                System.Windows.Forms.MessageBox.Show("Less than 2 connections were detected: " + fiberNumber, "Telecom Trace", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
            }

            string spliceClosureIpid = string.Empty;
            string nextCableId       = string.Empty;
            int    nextFiberNumber   = -1;
            bool   isNextFromEnd     = false;

            // {{0}} causes the string.format to
            string cableWhereFormat  = string.Format("{0}='{{0}}'", ConfigUtil.IpidFieldName);
            string spliceWhereFormat = string.Format("{0}='{{0}}'", ConfigUtil.IpidFieldName);
            string fiberWhereFormat  = string.Format("{0}='{{0}}' AND {1}={{1}}", fiberRelationship.OriginForeignKey, ConfigUtil.Fiber_NumberFieldName);

            using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
            {
                ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                releaser.ManageLifetime(filter);

                // Ripple down the start cable's to end
                ESRI.ArcGIS.Geodatabase.IRow spliceRow = GetNextSplice(fiberSpliceTable, ipid, fiberNumber, isStartingAtFromEnd, out nextCableId, out nextFiberNumber, out spliceClosureIpid, out isNextFromEnd);
                while (null != spliceRow)
                {
                    ESRI.ArcGIS.Geodatabase.IFeature spliceClosure = null;

                    if (spliceClosureIpid.Equals(""))
                    {
                        System.Windows.Forms.MessageBox.Show("Found Splice with no SpliceClosure (ID/#) " + nextCableId + "/" + nextFiberNumber, "Telecom Trace", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                    }
                    else
                    {
                        filter.WhereClause = string.Format(spliceWhereFormat, spliceClosureIpid);
                        ESRI.ArcGIS.Geodatabase.IFeatureCursor spliceCursor = spliceFtClass.Search(filter, false);
                        releaser.ManageLifetime(spliceCursor);
                        spliceClosure = spliceCursor.NextFeature();
                        if (spliceClosure == null)
                        {
                            System.Windows.Forms.MessageBox.Show("Invalid SpliceClosure referenced: (IPID)" + spliceClosureIpid, "Telecom Trace", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                        }
                    }

                    filter.WhereClause = string.Format(cableWhereFormat, nextCableId);
                    ESRI.ArcGIS.Geodatabase.IFeatureCursor cableCursor = cableFtClass.Search(filter, false);
                    releaser.ManageLifetime(cableCursor);
                    ESRI.ArcGIS.Geodatabase.IFeature cable = cableCursor.NextFeature();
                    if (cable == null)
                    {
                        System.Windows.Forms.MessageBox.Show("Invalid cable ID referenced: (ID)" + nextCableId, "Telecom Trace", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                    }

                    filter.WhereClause = string.Format(fiberWhereFormat, nextCableId, nextFiberNumber);
                    ESRI.ArcGIS.Geodatabase.ICursor fiberCursor = fiberTable.Search(filter, false);
                    releaser.ManageLifetime(fiberCursor);
                    ESRI.ArcGIS.Geodatabase.IRow fiber = fiberCursor.NextRow();
                    if (fiber == null)
                    {
                        System.Windows.Forms.MessageBox.Show("Invalid Fiber Cable or # referenced: (ID/#) " + nextCableId + "/" + nextFiberNumber, "Telecom Trace", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                    }

                    if (isStartingAtFromEnd)
                    {
                        if (spliceRow != null)
                        {
                            result.Add(spliceRow);
                        }
                        if (spliceClosure != null)
                        {
                            result.Add(spliceClosure);
                        }
                        if (fiber != null)
                        {
                            result.Add(fiber);
                        }
                        if (cable != null)
                        {
                            result.Add(cable);
                        }
                    }
                    else
                    {
                        if (spliceClosure != null)
                        {
                            result.Add(spliceClosure);
                        }
                        if (spliceRow != null)
                        {
                            result.Add(spliceRow);
                        }
                        if (cable != null)
                        {
                            result.Add(cable);
                        }
                        if (fiber != null)
                        {
                            result.Add(fiber);
                        }
                    }

                    spliceRow = GetNextSplice(fiberSpliceTable, nextCableId, nextFiberNumber, !isNextFromEnd, out nextCableId, out nextFiberNumber, out spliceClosureIpid, out isNextFromEnd);
                }

                // See if there is a port for this one
                ESRI.ArcGIS.Geodatabase.IRow     portRow  = null;
                ESRI.ArcGIS.Geodatabase.IFeature deviceFt = null;
                if (GetConnectedPort(cableFtClass, nextCableId, nextFiberNumber, isNextFromEnd, out portRow, out deviceFt))
                {
                    if (isStartingAtFromEnd)
                    {
                        result.Add(portRow);
                        result.Add(deviceFt);
                    }
                    else
                    {
                        result.Add(deviceFt);
                        result.Add(portRow);
                    }
                }

                return(result);
            }
        }
        /// <summary>
        /// Looks for a fiber splice record at one end of a given cable
        /// </summary>
        /// <param name="fiberSpliceTable">Fiber splice table</param>
        /// <param name="cableId">Cable ID of the cable we are checking</param>
        /// <param name="fiberNumber">Fiber Number we are checking</param>
        /// <param name="checkFromEnd">Which end of the cable are we checking?</param>
        /// <param name="nextCableId">(out) Cable ID of the cable spliced on this end, or string.Empty if none</param>
        /// <param name="nextFiberNumber">(out) Fiber Number of spliced on this end, or -1 if none</param>
        /// <param name="spliceClosureIpid">(out) IPID of Splice Closure</param>
        /// <param name="isNextFromEnd">(out) Is the result cable spliced on its from end or its to end?</param>
        /// <returns>The splice record</returns>
        private ESRI.ArcGIS.Geodatabase.IRow GetNextSplice(ESRI.ArcGIS.Geodatabase.ITable fiberSpliceTable, string cableId, int fiberNumber, bool checkFromEnd, out string nextCableId, out int nextFiberNumber, out string spliceClosureIpid, out bool isNextFromEnd)
        {
            ESRI.ArcGIS.Geodatabase.IRow spliceRow = null;

            spliceClosureIpid = string.Empty;
            nextCableId       = cableId;
            nextFiberNumber   = fiberNumber;
            isNextFromEnd     = checkFromEnd;

            using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
            {
                ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                filter.WhereClause = string.Format("({0}='{1}' AND {2}={3} AND {4}='{5}')"
                                                   + " OR ({6}='{1}' AND {7}={3} AND {8}='{5}')",
                                                   ConfigUtil.ACableIdFieldName,
                                                   cableId,
                                                   ConfigUtil.AFiberNumberFieldName,
                                                   fiberNumber,
                                                   ConfigUtil.IsAFromEndFieldName,
                                                   (checkFromEnd ? "T" : "F"),
                                                   ConfigUtil.BCableIdFieldName,
                                                   ConfigUtil.BFiberNumberFieldName,
                                                   ConfigUtil.IsBFromEndFieldName);

                releaser.ManageLifetime(filter);

                // TODO: should we give a warning if the rowcount is more than 1? We should technically only find one splice
                // record on this end of the fiber...

                ESRI.ArcGIS.Geodatabase.ICursor search = fiberSpliceTable.Search(filter, false);
                releaser.ManageLifetime(search);

                spliceRow = search.NextRow();
                if (null != spliceRow)
                {
                    object scIpidValue = spliceRow.get_Value(_spliceClosureIpidIdx);
                    if (DBNull.Value != scIpidValue)
                    {
                        spliceClosureIpid = scIpidValue.ToString();
                    }

                    string aCableId = spliceRow.get_Value(_aCableIdx).ToString();
                    if (0 == string.Compare(aCableId, cableId))
                    {
                        // b is the one we want to return
                        nextCableId     = spliceRow.get_Value(_bCableIdx).ToString();
                        nextFiberNumber = (int)spliceRow.get_Value(_bFiberNumIdx);
                        isNextFromEnd   = spliceRow.get_Value(_isBFromIdx).ToString() == "T" ? true : false;
                    }
                    else
                    {
                        // a is the one we want to return
                        nextCableId     = aCableId;
                        nextFiberNumber = (int)spliceRow.get_Value(_aFiberNumIdx);
                        isNextFromEnd   = spliceRow.get_Value(_isAFromIdx).ToString() == "T" ? true : false;
                    }
                }
            }

            return(spliceRow);
        }
        private FiberCableWrapper GetConnectedFiber(DeviceWrapper device, int portId, PortType portType, out int fiberNumber)
        {
            FiberCableWrapper result = null;

            fiberNumber = -1;

            ESRI.ArcGIS.Geodatabase.IFeatureClass      deviceFtClass  = (ESRI.ArcGIS.Geodatabase.IFeatureClass)device.Feature.Class;
            ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(deviceFtClass);
            if (null == deviceHasPorts)
            {
                throw new Exception("Device to port relationship is missing or cannot be opened.");
            }

            ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable;
            if (null == portTable)
            {
                throw new Exception("Port table is missing or cannot be opened.");
            }


            using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser())
            {
                ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
                releaser.ManageLifetime(filter);
                filter.WhereClause = string.Format("{0}='{1}' AND {2}={3} AND {4}='{5}'",
                                                   deviceHasPorts.OriginForeignKey,
                                                   device.Feature.get_Value(deviceFtClass.FindField(deviceHasPorts.OriginPrimaryKey)),
                                                   ConfigUtil.PortIdFieldName,
                                                   portId,
                                                   ConfigUtil.PortTypeFieldName,
                                                   PortType.Input == portType ? 1 : 2);

                ESRI.ArcGIS.Geodatabase.ICursor cursor = portTable.Search(filter, false);
                releaser.ManageLifetime(cursor);
                ESRI.ArcGIS.Geodatabase.IRow portRow = cursor.NextRow();

                if (null != portRow)
                {
                    //releaser.ManageLifetime(portRow);

                    object cableIdValue = portRow.get_Value(portTable.FindField(ConfigUtil.ConnectedCableFieldName));
                    if (DBNull.Value != cableIdValue)
                    {
                        ESRI.ArcGIS.Geodatabase.IFeatureClass cableFtClass = _wkspHelper.FindFeatureClass(ConfigUtil.FiberCableFtClassName);
                        filter.WhereClause = string.Format("{0}='{1}'", ConfigUtil.IpidFieldName, cableIdValue);
                        ESRI.ArcGIS.Geodatabase.IFeatureCursor cableCursor = cableFtClass.Search(filter, false);
                        releaser.ManageLifetime(cableCursor);

                        ESRI.ArcGIS.Geodatabase.IFeature cable = cableCursor.NextFeature();
                        if (null != cable)
                        {
                            result = new FiberCableWrapper(cable);
                            object fiberNumberValue = portRow.get_Value(portTable.FindField(ConfigUtil.ConnectedFiberFieldName));
                            if (DBNull.Value != fiberNumberValue)
                            {
                                int.TryParse(fiberNumberValue.ToString(), out fiberNumber);
                            }
                        }
                    }
                }
            }

            return(result);
        }