//public static FiberDeviceConnectionHelper Instance(HookHelperExt hookHelper, ESRI.ArcGIS.Editor.IEditor editor) //{ // if(_instance != null) // { // return _instance; // } // else // { // _instance = new FiberDeviceConnectionHelper(hookHelper, editor); // return _instance; // } //} /// <summary> /// Returns cables which have an endpoint coincident with the device point /// </summary> /// <param name="deviceWrapper">Device to check</param> /// <returns>List of ConnectableCableWrapper</returns> public List <ConnectableCableWrapper> GetCoincidentCables(DeviceWrapper deviceWrapper) { List <ConnectableCableWrapper> result = new List <ConnectableCableWrapper>(); if (null == deviceWrapper) { throw new ArgumentNullException("deviceWrapper"); } ESRI.ArcGIS.Geometry.IPoint devicePoint = deviceWrapper.Feature.Shape as ESRI.ArcGIS.Geometry.IPoint; ESRI.ArcGIS.Carto.IFeatureLayer cableLayer = _hookHelper.FindFeatureLayer(ConfigUtil.FiberCableFtClassName); ESRI.ArcGIS.Geodatabase.IFeatureClass cableFtClass = cableLayer.FeatureClass; int displayIdx = cableFtClass.FindField(cableLayer.DisplayField); double buffer = _hookHelper.ConvertPixelsToMapUnits(1); List <ESRI.ArcGIS.Geodatabase.IFeature> coincidentCables = GdbUtils.GetLinearsWithCoincidentEndpoints(devicePoint, cableFtClass, buffer); for (int i = 0; i < coincidentCables.Count; i++) { ESRI.ArcGIS.Geodatabase.IFeature ft = coincidentCables[i]; ESRI.ArcGIS.Geometry.IPolyline line = ft.Shape as ESRI.ArcGIS.Geometry.IPolyline; ESRI.ArcGIS.Geometry.IRelationalOperator lineToPoint = line.ToPoint as ESRI.ArcGIS.Geometry.IRelationalOperator; bool isFromEnd = true; if (lineToPoint.Equals(devicePoint)) { isFromEnd = false; } result.Add(new ConnectableCableWrapper(ft, isFromEnd, displayIdx)); } return(result); }
/// <summary> /// Generates a splice closure at the coincident endpoint. Does not start an edit operation. /// </summary> /// <param name="cableA">Cable A</param> /// <param name="cableB">Cable B</param> /// <returns>SpliceClosureWRapper based on new feature</returns> private SpliceClosureWrapper GenerateSpliceClosure(FiberCableWrapper cableA, SpliceableCableWrapper cableB) { SpliceClosureWrapper wrapper = null; #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 // Populate an IPID; we will need it Guid g = Guid.NewGuid(); string spliceIpid = g.ToString("B").ToUpper(); try { ESRI.ArcGIS.Geometry.IPolyline line = cableB.Feature.Shape as ESRI.ArcGIS.Geometry.IPolyline; if (null != line) { ESRI.ArcGIS.Geometry.IPoint splicePoint = null; if (cableB.IsThisFromEnd) { splicePoint = line.FromPoint; } else { splicePoint = line.ToPoint; } ESRI.ArcGIS.Geodatabase.IFeatureClass spliceClosureFtClass = _wkspHelper.FindFeatureClass(ConfigUtil.SpliceClosureFtClassName); // ESRI.ArcGIS.Geodatabase.IFeatureClass spliceClosureFtClass = GdbUtils.GetFeatureClass(cableA.Feature.Class, ConfigUtil.SpliceClosureFtClassName); ESRI.ArcGIS.Geodatabase.IFeature spliceFt = spliceClosureFtClass.CreateFeature(); spliceFt.Shape = splicePoint; spliceFt.set_Value(spliceClosureFtClass.Fields.FindField(ConfigUtil.IpidFieldName), spliceIpid); spliceFt.Store(); wrapper = new SpliceClosureWrapper(spliceFt); } } catch { wrapper = null; } return(wrapper); }
/// <summary> /// Constructs a new SpliceableCableWrapper, determining which ends to use by comparing to the other cable /// </summary> /// <param name="thisFeature">IFeature to wrap</param> /// <param name="otherFeature">IFeature with which to compare endpoints</param> public SpliceableCableWrapper(ESRI.ArcGIS.Geodatabase.IFeature thisFeature, ESRI.ArcGIS.Geodatabase.IFeature otherFeature) : base(thisFeature, true) { #region Validation // We already know thisFeature is not null from the base validation if (null == otherFeature) { throw new ArgumentNullException("otherFeature"); } else if (null == otherFeature.Class) { throw new ArgumentException("otherFeature.Class cannot be null."); } ESRI.ArcGIS.Geometry.IPolyline thisPolyline = thisFeature.Shape as ESRI.ArcGIS.Geometry.IPolyline; if (null == thisPolyline) { throw new ArgumentException("thisFeature.Shape must be IPolyline."); } ESRI.ArcGIS.Geometry.IPolyline otherPolyline = otherFeature.Shape as ESRI.ArcGIS.Geometry.IPolyline; if (null == otherPolyline) { throw new ArgumentException("otherPolyline.Shape must be IPolyline."); } #endregion ESRI.ArcGIS.Geometry.IRelationalOperator thisFrom = thisPolyline.FromPoint as ESRI.ArcGIS.Geometry.IRelationalOperator; ESRI.ArcGIS.Geometry.IRelationalOperator thisTo = thisPolyline.ToPoint as ESRI.ArcGIS.Geometry.IRelationalOperator; ESRI.ArcGIS.Geometry.IPoint otherFrom = otherPolyline.FromPoint; ESRI.ArcGIS.Geometry.IPoint otherTo = otherPolyline.ToPoint; // Assume it will be the from end of thisFeature and the to end of otherFeature base._isThisFromEnd = true; _isOtherFromEnd = false; if (thisTo.Equals(otherFrom)) { base._isThisFromEnd = false; _isOtherFromEnd = true; } else if (thisFrom.Equals(otherFrom)) { _isOtherFromEnd = true; } else if (thisTo.Equals(otherTo)) { base._isThisFromEnd = false; } }
/// <summary> /// Returns devices at the endpoints of the given cable /// </summary> /// <param name="deviceWrapper">Cable to check</param> /// <returns>List of ConnectableDeviceWrapper</returns> public List <ConnectableDeviceWrapper> GetCoincidentDevices(FiberCableWrapper fiberCableWrapper) { List <ConnectableDeviceWrapper> result = new List <ConnectableDeviceWrapper>(); if (null == fiberCableWrapper) { throw new ArgumentNullException("fiberCableWrapper"); } ESRI.ArcGIS.Geometry.IPolyline cableGeometry = (ESRI.ArcGIS.Geometry.IPolyline)fiberCableWrapper.Feature.Shape; string[] deviceFtClassNames = ConfigUtil.DeviceFeatureClassNames; double buffer = _hookHelper.ConvertPixelsToMapUnits(1); for (int i = 0; i < deviceFtClassNames.Length; i++) { string ftClassName = deviceFtClassNames[i]; ESRI.ArcGIS.Carto.IFeatureLayer ftLayer = _hookHelper.FindFeatureLayer(ftClassName); if (ftLayer == null) { // Layer might not be in the map so just skip if not found. continue; } ESRI.ArcGIS.Geodatabase.IFeatureClass ftClass = ftLayer.FeatureClass; int displayIdx = ftClass.FindField(ftLayer.DisplayField); List <ESRI.ArcGIS.Geodatabase.IFeature> fromFts = GdbUtils.GetFeaturesWithCoincidentVertices(cableGeometry.FromPoint, ftClass, false, buffer); for (int fromIdx = 0; fromIdx < fromFts.Count; fromIdx++) { result.Add(new ConnectableDeviceWrapper(fromFts[fromIdx], true, displayIdx)); } List <ESRI.ArcGIS.Geodatabase.IFeature> toFts = GdbUtils.GetFeaturesWithCoincidentVertices(cableGeometry.ToPoint, ftClass, false, buffer); for (int toIdx = 0; toIdx < toFts.Count; toIdx++) { result.Add(new ConnectableDeviceWrapper(toFts[toIdx], false, displayIdx)); } } return(result); }
// The following CreateXMLLinkElt private procedure is used to create all the expected XML items for a XML LinkFeature related to a HV_Line or LV_Line simple edge feature private void CreateXMLLinkElt(ESRI.ArcGIS.Geodatabase.IFeature inFeature, ref MSXML2.DOMDocument outDOMDoc, ref MSXML2.IXMLDOMElement outXMLElements, string inLinkTypeName) { if (!inFeature.HasOID) { MessageBox.Show("No OID"); return; } MSXML2.IXMLDOMElement xmlLink; MSXML2.IXMLDOMElement xmlLink_FromNode; MSXML2.IXMLDOMElement xmlLink_ToNode; int indexListPoints; string listPoints; int nbVertices; string vertices; MSXML2.IXMLDOMElement xmlLink_Vertices; MSXML2.IXMLDOMElement xmlLink_Vertex; MSXML2.IXMLDOMElement xmlLink_XVertex; MSXML2.IXMLDOMElement xmlLink_YVertex; string xValue; string yValue; //-------- Feature Section START related to the "infeature" -------- // Creating the LinkFeature Feature xmlLink = outDOMDoc.createElement("LinkFeature"); outXMLElements.appendChild(xmlLink); // Specifying basic XML items for this LinkFeature CreateBasicXMLItemsForSchematicElt(inFeature, ref outDOMDoc, ref xmlLink, inLinkTypeName); // Specifying its FromNode xmlLink_FromNode = outDOMDoc.createElement("FromNode"); xmlLink.appendChild(xmlLink_FromNode); xmlLink_FromNode.nodeTypedValue = inFeature.get_Value(inFeature.Fields.FindField("FromJunctionType")) + "-" + inFeature.get_Value(inFeature.Fields.FindField("FromJunctionOID")); // Specifying its ToNode xmlLink_ToNode = outDOMDoc.createElement("ToNode"); xmlLink.appendChild(xmlLink_ToNode); xmlLink_ToNode.nodeTypedValue = inFeature.get_Value(inFeature.Fields.FindField("ToJunctionType")) + "-" + inFeature.get_Value(inFeature.Fields.FindField("ToJunctionOID")); //Add Vertices to LinkFeature ---- NEED TO BE COMPLETED indexListPoints = inFeature.Fields.FindField("ListPoints"); if (indexListPoints > 0) { listPoints = ""; listPoints = inFeature.get_Value(indexListPoints).ToString(); if (listPoints != "") { int foundChar = listPoints.IndexOf(";", 1); nbVertices = System.Convert.ToInt32(listPoints.Substring(0, foundChar)); vertices = listPoints.Substring(foundChar + 1); if (nbVertices > 0) { // Specifying its Vertices xmlLink_Vertices = outDOMDoc.createElement("Vertices"); xmlLink.appendChild(xmlLink_Vertices); int iLoc; for (int i = 1; i <= nbVertices; i++) { xValue = ""; yValue = ""; iLoc = vertices.IndexOf(";", 1); if (vertices != "" && (iLoc) > 0) { xValue = vertices.Substring(0, iLoc); } vertices = vertices.Substring(iLoc + 1); iLoc = vertices.IndexOf(";", 1); if (vertices != ";" && (iLoc) > 0) { yValue = vertices.Substring(0, iLoc); } if (xValue != "" && yValue != "") { xmlLink_Vertex = outDOMDoc.createElement("Vertex"); xmlLink_Vertices.appendChild(xmlLink_Vertex); xmlLink_XVertex = outDOMDoc.createElement("X"); xmlLink_Vertex.appendChild(xmlLink_XVertex); xmlLink_XVertex.nodeTypedValue = xValue; xmlLink_YVertex = outDOMDoc.createElement("Y"); xmlLink_Vertex.appendChild(xmlLink_YVertex); xmlLink_YVertex.nodeTypedValue = yValue; if (vertices.Length - iLoc > 0) { vertices = vertices.Substring(iLoc + 1); //sVertices.Length - iLoc) } else { break; } } else { break; } } } } } else { // Retrieving ListPoint from geometry ESRI.ArcGIS.Geometry.IPolyline oPoly = (ESRI.ArcGIS.Geometry.IPolyline)inFeature.ShapeCopy; ESRI.ArcGIS.Geometry.IPointCollection colLink = (ESRI.ArcGIS.Geometry.IPointCollection)oPoly; if (colLink != null && colLink.PointCount > 2) { ESRI.ArcGIS.Geometry.IPoint oPoint; xmlLink_Vertices = outDOMDoc.createElement("Vertices"); xmlLink.appendChild(xmlLink_Vertices); for (int i = 1; i < colLink.PointCount - 1; i++) { oPoint = colLink.get_Point(i); xmlLink_Vertex = outDOMDoc.createElement("Vertex"); xmlLink_Vertices.appendChild(xmlLink_Vertex); xmlLink_XVertex = outDOMDoc.createElement("X"); xmlLink_Vertex.appendChild(xmlLink_XVertex); xmlLink_XVertex.nodeTypedValue = oPoint.X; xmlLink_YVertex = outDOMDoc.createElement("Y"); xmlLink_Vertex.appendChild(xmlLink_YVertex); xmlLink_YVertex.nodeTypedValue = oPoint.Y; } } } //Specifying its properties switch (inFeature.Class.AliasName) { case "LV_Line": { CompleteXMLEltByProperties(inFeature, ref outDOMDoc, ref xmlLink, m_LVLinesPropertiesArray); break; } } //-------- Feature Section END related to the "infeature" -------- }
/// <summary> /// Returns all features from a given feature class that have a vertex or endpoint coincident with a given point /// </summary> /// <param name="point">IPoint to use as the spatial filter</param> /// <param name="searchFtClass">IFeatureClass to search in</param> /// <param name="linearEndpointsOnly">Flag to use only the endpoints of a line instead of all vertices</param> /// <param name="buffer">Search geometry buffer in map units</param> /// <returns>List of IFeature</returns> public static List <ESRI.ArcGIS.Geodatabase.IFeature> GetFeaturesWithCoincidentVertices(ESRI.ArcGIS.Geometry.IPoint point, ESRI.ArcGIS.Geodatabase.IFeatureClass searchFtClass, bool linearEndpointsOnly, double buffer) { List <ESRI.ArcGIS.Geodatabase.IFeature> result = new List <ESRI.ArcGIS.Geodatabase.IFeature>(); using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.Geodatabase.ISpatialFilter filter = new ESRI.ArcGIS.Geodatabase.SpatialFilterClass(); releaser.ManageLifetime(filter); ESRI.ArcGIS.Geometry.IEnvelope filterGeometry = point.Envelope; if (0 < buffer) { filterGeometry.Expand(buffer, buffer, false); } filter.SpatialRel = ESRI.ArcGIS.Geodatabase.esriSpatialRelEnum.esriSpatialRelIntersects; filter.Geometry = filterGeometry; ESRI.ArcGIS.Geodatabase.IFeatureCursor fts = searchFtClass.Search(filter, false); releaser.ManageLifetime(fts); ESRI.ArcGIS.Geodatabase.IFeature ft = fts.NextFeature(); while (null != ft) { if (searchFtClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint) { result.Add(ft); } else if (searchFtClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline && linearEndpointsOnly) { ESRI.ArcGIS.Geometry.IPolyline polyline = (ESRI.ArcGIS.Geometry.IPolyline)ft.Shape; ESRI.ArcGIS.Geometry.IRelationalOperator fromPoint = polyline.FromPoint as ESRI.ArcGIS.Geometry.IRelationalOperator; ESRI.ArcGIS.Geometry.IRelationalOperator toPoint = polyline.ToPoint as ESRI.ArcGIS.Geometry.IRelationalOperator; if (fromPoint.Equals(point) || toPoint.Equals(point)) { result.Add(ft); } } else { ESRI.ArcGIS.Geometry.IPointCollection pointCollection = ft.Shape as ESRI.ArcGIS.Geometry.IPointCollection; if (null != pointCollection) { for (int i = 0; i < pointCollection.PointCount; i++) { ESRI.ArcGIS.Geometry.IRelationalOperator testPoint = pointCollection.get_Point(i) as ESRI.ArcGIS.Geometry.IRelationalOperator; if (testPoint.Equals(point)) { result.Add(ft); break; } } } } ft = fts.NextFeature(); } } return(result); }