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