/// <summary> /// Rebuilds the connectivity for the <paramref name="networkFeature" /> network feature. /// </summary> /// <param name="networkFeature">The network feature.</param> protected virtual void RebuildConnectivity(INetworkFeature networkFeature) { try { if (networkFeature == null) { return; } // If network connectivity errors are found within the geometric network, they can generally be corrected through // the use of the RebuildConnectivity2 method. // // The RebuildConnectivity2 method does not check for invalid connectivity, it will remove and then rebuild the // of any feature contained within or intersecting the specified envelope. // // It is generally faster to call RebuildConnectivity2 on small individual areas rather than one large area that // encompasses the smaller areas. IFeature feature = (IFeature)networkFeature; Log.Info("Rebuilding the connectivity for the network feature with the OID of {0}.", feature.OID); IGeometricNetworkConnectivity2 networkConnectivity = (IGeometricNetworkConnectivity2)networkFeature.GeometricNetwork; networkConnectivity.RebuildConnectivity2(feature.Shape.Envelope); } catch (COMException e) { Log.Error("Attempted to rebuild connectivity on a network feature that is outside of the edit session.", e); } }
/// <summary> /// Commits the changes to the specified <paramref name="currentRow" /> and rebuilds connectivity of the /// specified <paramref name="currentRow" /> when there are network connectivity issues. /// </summary> /// <param name="currentRow">The current row.</param> protected virtual void SaveAndRebuild(IRow currentRow) { if (currentRow == null) { return; } INetworkFeature networkFeature = currentRow as INetworkFeature; if (networkFeature == null) { currentRow.Store(); } else { try { // Disconnect from network. networkFeature.Disconnect(); // It is not necessary to explicitly call Connect on network features or create and associate network elements // with network features. All network behavior is handled by the object behavior when Store is called on the feature. IFeature feature = (IFeature)currentRow; feature.Store(); } catch (COMException ex) { switch (ex.ErrorCode) { // A requested feature object could not be located. case (int)fdoError.FDO_E_FEATURE_NOT_FOUND: Log.Error("The requested feature object could not be located."); this.RebuildConnectivity(networkFeature); break; // Invalid network element id. case (int)esriNetworkErrors.NETWORK_E_INVALID_ELEMENT_ID: Log.Error("The network element id is invalid."); this.RebuildConnectivity(networkFeature); break; // SDE Error. (Shape or row not found) // The feature has been deleted. case (int)fdoError.FDO_E_SE_ROW_NOEXIST: case (int)fdoError.FDO_E_FEATURE_DELETED: break; default: throw; } } } }
private void OnSketchFinished() { ConfigUtil.type = "water"; IFeature pFeat = null; try { m_editor.StartOperation(); pFeat = Globals.CreateFeature(m_edSketch.Geometry, m_editor.CurrentTemplate as IEditTemplate, m_editor, ArcMap.Application, false, false, true); bool splitOccured = GeometryTools.SplitLinesAtClick(ArcMap.Application, ConfigUtil.GetConfigValue("SplitLinesSuspendAA", "true"), ConfigUtil.GetConfigValue("SplitLinesAtLocation_Snap", 10.0), ConfigUtil.GetConfigValue("SplitLines_SkipDistance", .5), m_edSketch.Geometry as IPoint, false, true, false); try { //Check to see if the source feature is the Junction FC, if so, and a edge was split, the junction will be created, do not create it as to not construct an orphaned junction //https://github.com/Esri/local-government-desktop-addins/issues/239 bool storeFeature = true; INetworkFeature netFeature = pFeat as INetworkFeature; if (netFeature != null) { if (pFeat.Class.ObjectClassID == netFeature.GeometricNetwork.OrphanJunctionFeatureClass.FeatureClassID && pFeat.Class.CLSID.Value.ToString() == netFeature.GeometricNetwork.OrphanJunctionFeatureClass.CLSID.Value.ToString() && splitOccured == true) { storeFeature = false; } } if (storeFeature == true) { pFeat.Store(); } netFeature = null; m_editor.StopOperation(A4LGSharedFunctions.Localizer.GetString("AddPtsAndSplitLn")); } catch (Exception ex) { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("errorOnIFeatureStore")); m_editor.AbortOperation(); } } catch (Exception ex) { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("ErrorInThe") + A4LGSharedFunctions.Localizer.GetString("AddPtsAndSplitLn") + "\n" + ex.ToString()); m_editor.AbortOperation(); } finally { if (pFeat != null) { (ArcMap.Application.Document as IMxDocument).ActiveView.PartialRefresh(esriViewDrawPhase.esriViewAll, pFeat, null); } pFeat = null; } }
/// <summary> /// Gets the network element information for the specified feature. /// </summary> /// <param name="feature">The feature.</param> /// <param name="elementType">Type of the element.</param> /// <returns> /// Returns the <see cref="int" /> representing the network information. /// </returns> protected int GetEID(IFeature feature, out esriElementType elementType) { elementType = esriElementType.esriETNone; INetworkFeature networkFeature = feature as INetworkFeature; if (networkFeature == null) { return(-1); } return(networkFeature.GetEID(out elementType)); }
public virtual int CompareTo(INetworkFeature other) { if (this is IBranch) { return(Network.Branches.IndexOf((IBranch)this).CompareTo(Network.Branches.IndexOf((IBranch)other))); } if (this is INode) { return(Network.Nodes.IndexOf((INode)this).CompareTo(Network.Nodes.IndexOf((INode)other))); } throw new NotImplementedException(); }
public virtual int CompareTo(INetworkFeature other) { if (this is IBranch) { return Network.Branches.IndexOf((IBranch) this).CompareTo(Network.Branches.IndexOf((IBranch) other)); } if(this is INode) { return Network.Nodes.IndexOf((INode) this).CompareTo(Network.Nodes.IndexOf((INode)other)); } throw new NotImplementedException(); }
/// <summary> /// Gets the network element identifier for the network feature. /// </summary> /// <param name="source">The source.</param> /// <param name="elementType">Type of the element.</param> /// <returns> /// Returns a <see cref="int" /> representing the network element identifier. /// </returns> public static int GetEID(this INetworkFeature source, out esriElementType elementType) { IGeometricNetwork geometricNetwork = source.GeometricNetwork; INetwork network = geometricNetwork.Network; INetElements netElements = (INetElements)network; ISimpleJunctionFeature sjf = source as ISimpleJunctionFeature; elementType = sjf != null ? esriElementType.esriETJunction : esriElementType.esriETEdge; IFeature feature = (IFeature)source; int eid = netElements.GetEID(feature.Class.ObjectClassID, feature.OID, -1, elementType); return(eid); }
public static void SetBeingMoved(this INetworkFeature networkFeature, bool beingMoved) { if (beingMoved) { if (!networkFeaturesBeingMoved.Contains(networkFeature)) { networkFeaturesBeingMoved.Add(networkFeature); } } else { if (networkFeaturesBeingMoved.Contains(networkFeature)) { networkFeaturesBeingMoved.Remove(networkFeature); } } }
/// <summary> /// Called before the trace executes the <see cref="OnTrace(IFeature)" /> method. /// </summary> /// <param name="feature">The feature.</param> /// <exception cref="System.ArgumentNullException">feature</exception> protected virtual void OnBeforeTrace(IFeature feature) { if (feature == null) { throw new ArgumentNullException("feature"); } this.Workspace = ((IDataset)feature.Class).Workspace; esriElementType elementType; this.EID = this.GetEID(feature, out elementType); this.ElementType = elementType; INetworkFeature networkFeature = (INetworkFeature)feature; this.GeometricNetwork = networkFeature.GeometricNetwork; }
private bool _IsDisabled(int eid, esriElementType elementType, INetElements netElements) { // Check enabled field in Network Feature since it might not be in synch with network element enabled property (ESRI bug?) int classID, userID, subID; netElements.QueryIDs(eid, elementType, out classID, out userID, out subID); INetElementDescriptionEdit elementDescription = new NetElementDescriptionClass(); elementDescription.ElementType_2 = elementType; elementDescription.UserClassID_2 = classID; elementDescription.UserID_2 = userID; elementDescription.UserSubID_2 = subID; INetworkFeature netFeature = this.GeometricNetwork.get_NetworkFeature(elementDescription); bool enabled = _IsEnabled((IFeature)netFeature); return(!enabled); }
public static NetworkLocation ToNetworkLocation(this INetworkFeature networkFeature) { var branchFeature = networkFeature as IBranchFeature; if (branchFeature != null) { return(branchFeature.ToNetworkLocation()); } var node = networkFeature as INode; if (node != null) { IBranch outgoingBranch = node.OutgoingBranches.FirstOrDefault(); if (outgoingBranch != null) { return(new NetworkLocation(outgoingBranch, 0)); } IBranch incomingBranch = node.IncomingBranches.First(); return(new NetworkLocation(incomingBranch, incomingBranch.Length)); } return(null); }
public Nullable <double> RotatePointByNetwork(IMap pMap, INetworkFeature pPointFeature, bool bArithmeticAngle, string strDiameterFld, string strLayerName) { //This routine is used by both RotateDuringCreateFeature and RotateSelectedFeature. //It contains all of logic for determining the rotation angle. double xyTol; const int iAngleTol = 5; diameterMeterFeat diamPnt = null; IPoint pPoint = default(IPoint); ISimpleJunctionFeature pSimpJunc = null; IEdgeFeature pEdgeFeat = default(IEdgeFeature); List <string> pLstInt = new List <string>(); List <diameterMeterFeat> diametersWithPoints = new List <diameterMeterFeat>(); UID pId = new UID(); IFeature pTempFeat = null; try { pPoint = (IPoint)((IFeature)pPointFeature).Shape; if (pPoint.IsEmpty) { return(0); } //Create spatial filter to find intersecting features at this given point xyTol = Globals.GetXYTolerance(pPoint); pSimpJunc = (ISimpleJunctionFeature)pPointFeature; for (int i = 0; i <= pSimpJunc.EdgeFeatureCount - 1; i++) { pEdgeFeat = pSimpJunc.get_EdgeFeature(i); if (pLstInt.Count > 0) { if (pLstInt.Contains(((IFeature)pEdgeFeat).Class.ObjectClassID + " " + ((IFeature)pEdgeFeat).OID)) { continue; } } pTempFeat = (IFeature)pEdgeFeat; if (strLayerName == Globals.getClassName((IDataset)pTempFeat.Class) || strLayerName == "" || strLayerName == null) { string listInt; diamPnt = null; angleLogic(pPoint, pTempFeat, bArithmeticAngle, strDiameterFld, xyTol, out listInt, out diamPnt); pLstInt.Add(listInt); diametersWithPoints.Add(diamPnt); } } return(getAngle(diametersWithPoints, iAngleTol)); } catch { return(0); } finally { diamPnt = null; pPoint = null; pSimpJunc = null; pEdgeFeat = null; pLstInt.Clear(); diametersWithPoints.Clear(); pId = null; pTempFeat = null; } }
// Uses Geometric Network to find connected edges which determine desired rotation of point public Nullable <double> GetRotationUsingConnectedEdges(IFeature inFeature) { Nullable <double> rotationAngle = null; if (inFeature.Shape.GeometryType == esriGeometryType.esriGeometryPoint) { try { double diameter = 0; List <double> angles = new List <double>(); List <double> diameters = new List <double>(); List <Boolean> flipDirections = new List <Boolean>(); IPoint pnt = (ESRI.ArcGIS.Geometry.IPoint)inFeature.Shape; INetworkFeature netFeat = (INetworkFeature)inFeature; ISimpleJunctionFeature simpleJunctionFeature = (ISimpleJunctionFeature)netFeat; INetworkClass netClass = (INetworkClass)inFeature.Class; IGeometricNetwork geomNetwork = (IGeometricNetwork)netClass.GeometricNetwork; INetwork network = (INetwork)geomNetwork.Network; INetElements netElements = (INetElements)network; IFeatureClass fc; IFeature feat; IGeometry geometry; IPolyline polyline; ISegmentCollection segmentCollection; ISegmentCollection segColTest; ISegment testSegment; IEnumSegment enumSegment; System.Object edgeWeight; Boolean edgeOrient; int partIndex = 0; int segmentIndex = 0; int edgesCount; int edgeEID; int classId; int userId; int subId; int posField; double angle; object Missing = Type.Missing; IPoint toPoint; ITopologicalOperator topoOp; IPolygon poly; IRelationalOperator relOp; IForwardStarGEN forwardStar = (IForwardStarGEN)network.CreateForwardStar(false, null, null, null, null); forwardStar.FindAdjacent(0, simpleJunctionFeature.EID, out edgesCount); for (int i = 0; i < edgesCount; i++) { forwardStar.QueryAdjacentEdge(i, out edgeEID, out edgeOrient, out edgeWeight); geometry = geomNetwork.get_GeometryForEdgeEID(edgeEID); polyline = (IPolyline5)geometry; //Special case for reducer if (m_useDiameter & (edgesCount == 2)) { netElements.QueryIDs(edgeEID, esriElementType.esriETEdge, out classId, out userId, out subId); fc = GetFeatureClassByClassId(classId, geomNetwork); feat = fc.GetFeature(userId); posField = GetFieldPosition(m_diameterFieldName, feat); if (posField > -1) { diameter = (double)feat.get_Value(posField); } } //given line and point, return angles of all touching segments segmentCollection = (ISegmentCollection)polyline; enumSegment = (IEnumSegment)segmentCollection.EnumSegments; enumSegment.Next(out testSegment, ref partIndex, ref segmentIndex); while (testSegment != null) { angle = GetAngleOfSegment(testSegment); toPoint = testSegment.ToPoint; topoOp = toPoint as ITopologicalOperator; poly = topoOp.Buffer(0.01) as IPolygon; //ML: 20090617 Added test for segment touching point to be rotated segColTest = new PolylineClass(); segColTest.AddSegment(testSegment, ref Missing, ref Missing); relOp = segColTest as IRelationalOperator; if (relOp.Touches(pnt)) { relOp = poly as IRelationalOperator; flipDirections.Add(relOp.Contains(pnt)); diameters.Add(diameter); angles.Add(angle); } enumSegment.Next(out testSegment, ref partIndex, ref segmentIndex); } ///end of possible function returning list of angles } switch (angles.Count) { case 0: break; case 1: // End cap or plug fitting or simliar. rotationAngle = angles[0]; if (flipDirections[0]) { rotationAngle += 180; } break; case 2: if (m_useDiameter & (diameters[0] < diameters[1])) { rotationAngle = angles[0]; if (flipDirections[0]) { rotationAngle += 180; } } else if (m_useDiameter & (diameters[0] >= diameters[1])) { rotationAngle = angles[1]; if (flipDirections[1]) { rotationAngle += 180; } } else { rotationAngle = angles[0]; } break; case 3: //Tee or Tap fitting or similiar. Rotate toward the odd line. int tee = FindTee(angles[0], angles[1], angles[2]); rotationAngle = angles[tee]; if (flipDirections[tee]) { rotationAngle += 180; } break; case 4: // Cross fitting or similar. Any of the angles should work. rotationAngle = (int)angles[0]; break; default: break; } } catch { return(-1); } } //If needed, convert to geographic degrees(zero north clockwise) if (rotationAngle > 360) { rotationAngle -= 360; } if (rotationAngle < 0) { rotationAngle += 360; } if (rotationAngle != null & m_rotationType == esriSymbolRotationType.esriRotateSymbolGeographic) { int a = (int)rotationAngle; if (a > 0 & a <= 90) { rotationAngle = 90 - a; } else if (a > 90 & a <= 360) { rotationAngle = 450 - a; } } //Apply any spin angle if (rotationAngle != null) { rotationAngle += m_spinAngle; if (rotationAngle > 360) { rotationAngle -= 360; } if (rotationAngle < 0) { rotationAngle += 360; } } return(rotationAngle); }
public int CompareTo(INetworkFeature other) { return(Network.Nodes.IndexOf(this).CompareTo(Network.Nodes.IndexOf((INode)other))); }
public int CompareTo(INetworkFeature other) { return Network.Branches.IndexOf(this).CompareTo(Network.Branches.IndexOf((IBranch) other)); }
/// <summary> /// Returns the <see cref="IEIDInfo" /> for the specified network feature. /// </summary> /// <param name="source">The source.</param> /// <param name="elementType">Type of the element.</param> /// <returns> /// Returns a <see cref="IEIDInfo" /> representing the network information. /// </returns> public static IEIDInfo GetEIDInfo(this INetworkFeature source, out esriElementType elementType) { int eid = source.GetEID(out elementType); return(source.GeometricNetwork.GetEIDInfo(eid, elementType)); }
/// <summary> /// /// </summary> /// <param name="circBreaker"></param> private void TraceFeeder(INetworkFeature circBreaker) { #region Initialize some variables listView1.Items.Clear(); Int32 phaseABit = (int) Math.Pow(2, 28); // 268435456 Int32 phaseBBit = (int) Math.Pow(2, 29); // 536870912 Int32 phaseCBit = (int) Math.Pow(2, 30); // 1073741824 #endregion #region Create a queue of junctions to visit and a hash table for path information Queue<int> junctionsToVisit = new Queue<int>(); Dictionary<int, int> pathHash = new Dictionary<int, int>(); int startEID = ((ISimpleJunctionFeature) circBreaker).EID; junctionsToVisit.Enqueue(startEID); pathHash.Add(startEID, -99999999); #endregion #region Get the MMElectricTraceWeight and create a ForwardStar so that we can stop the trace when we reach an open point _network = circBreaker.GeometricNetwork.Network; _geomNet = circBreaker.GeometricNetwork; INetSchema netSchema = (INetSchema) _network; INetWeight mmElectricTraceWeight = netSchema.get_WeightByName("MMElectricTraceWeight"); IForwardStarGEN fStar = (IForwardStarGEN) _network.CreateForwardStar(false, mmElectricTraceWeight, null, null, null); #endregion while (junctionsToVisit.Count > 0) { #region Orient the Forward Star at the current junction EID int eid = junctionsToVisit.Dequeue(); int adjEdgeCount = 0; fStar.FindAdjacent(0, eid, out adjEdgeCount); #endregion #region Declare and initialize arrays to hold edges and junctions, weights, and orientations int[] adjJuncEIDS = new int[adjEdgeCount]; object[] adjJuncWeights = new object[adjEdgeCount]; int[] adjEdgeEIDS = new int[adjEdgeCount]; object[] adjEdgeWeights = new object[adjEdgeCount]; // We don't use this, but we still have to declare the array bool[] adjRevOrientations = new bool[adjEdgeCount]; // We don't use this, but we still have to declare the array #endregion #region Query the adjacent junctions and edges (while we are at it, get the weights too) fStar.QueryAdjacentJunctions(ref adjJuncEIDS, ref adjJuncWeights); fStar.QueryAdjacentEdges(ref adjEdgeEIDS, ref adjRevOrientations, ref adjEdgeWeights); #endregion #region Loop through all of the connected edges for (int i = 0; i < adjEdgeCount; i++) { #region Get the connected edge and junction int connectedEdgeEID = -1*adjEdgeEIDS[i]; int oppositeJuncEID = adjJuncEIDS[i]; #endregion #region Check to see if the adjacent junctions has already been added to the paths hashtable if (pathHash.ContainsKey(oppositeJuncEID) == false) { #region Add the opposite junction and the connected edge to the paths hashtable pathHash.Add(oppositeJuncEID, connectedEdgeEID); pathHash.Add(connectedEdgeEID, eid); #endregion #region If the opposite junction is closed on at least one phase (A or B or C), then enque the opposite junction Int32 juncWeight = System.Convert.ToInt32(adjJuncWeights[i]); if ((juncWeight & phaseABit) == 0 || (juncWeight & phaseBBit) == 0 || (juncWeight & phaseCBit) == 0 || (juncWeight == 0)) { junctionsToVisit.Enqueue(oppositeJuncEID); } #endregion } #endregion } #endregion } _pathHash = pathHash; PopulateListView(pathHash, _network, _geomNet); }
public int CompareTo(INetworkFeature other) { throw new NotImplementedException(); }
private void setDynamicDefaults(IObject inObject, string mode) { try { //Convert row to feature (test for feature is null before using - this could be a table update) IFeature inFeature = inObject as IFeature; // Skip Orphan Junctions (saves time) if (inFeature != null) { INetworkFeature inNetFeat = inObject as INetworkFeature; if ((inNetFeat != null) && (inFeature.Class.ObjectClassID == inNetFeat.GeometricNetwork.OrphanJunctionFeatureClass.ObjectClassID)) { return; } } //Get cursor to dynamic values table retriving only ICursor tabCursor; getDefaultRows(inObject, out tabCursor); IRow row = null; if (tabCursor != null) { row = tabCursor.NextRow(); } //for each row in the matching rows (matched by table name or wildcard) returned from the config table while (row != null) { //get fieldname string fieldName = row.get_Value(dynTargetField).ToString(); //if this field is found in the feature/object being added or modified... int fieldNum = inObject.Fields.FindField(fieldName); if (fieldNum > -1) { // get requested method and any data parameters string valMethod = row.get_Value(dynMethodField).ToString(); string valData = row.get_Value(dynDataField).ToString(); switch (mode) { case "OnCreate": //Continue to next field in config table if create events were not requested if (row.get_Value(dynCreateField).ToString() == "0") { row = tabCursor.NextRow(); continue; } break; case "OnChange": // Collect value for changed feature (stored for LAST VALUE method) IRowChanges inChanges = inObject as IRowChanges; bool changed = inChanges.get_ValueChanged(fieldNum); if (changed) { lastValueProperties.SetProperty(fieldName, inObject.get_Value(fieldNum)); } //Continue to next field in config table if change events were not requested if (row.get_Value(dynChangeField).ToString() == "0") { row = tabCursor.NextRow(); continue; } break; } // set values as specified switch (valMethod) { case "TIMESTAMP": inObject.set_Value(fieldNum, DateTime.Now); break; case "LAST_VALUE": if (mode == "OnCreate") { //if (inObject.get_Value(fieldNum) == null) //{ object lastValue = lastValueProperties.GetProperty(fieldName); if (lastValue != null) { inObject.set_Value(fieldNum, lastValue); } //} } break; case "FIELD": // verify that field to copy exists int fieldCopy = inObject.Fields.FindField(valData as string); if (fieldCopy > -1) { //copy value only if current field is empty string currentValue = inObject.get_Value(fieldNum).ToString(); if (currentValue == "") { inObject.set_Value(fieldNum, inObject.get_Value(fieldCopy)); } } break; case "CURRENT_USER": if (lastEditorName == null) { lastEditorName = getCurrentUser(); } inObject.set_Value(fieldNum, lastEditorName); break; case "GUID": if (mode == "OnCreate") // SHould only set this once on create to give the object a unique value { object currentValue = inObject.get_Value(fieldNum); if (DBNull.Value == currentValue) // Do not overwrite if someone else has already generated { Guid g = Guid.NewGuid(); inObject.set_Value(fieldNum, g.ToString("B").ToUpper()); } } break; case "EXPRESSION": if (mode == "OnCreate") { if (inFeature != null & valData != null) { try { int calcField = inFeature.Fields.FindField(fieldName); //if (inFeature.get_Value(calcField) == null) //{ int[] fids = { inFeature.OID }; IGeoDatabaseBridge gdbBridge = new GeoDatabaseHelperClass(); IFeatureCursor fCursor = (IFeatureCursor)gdbBridge.GetFeatures((IFeatureClass)inFeature.Class, ref fids, false); ICalculator calc = new CalculatorClass(); calc.Expression = valData; calc.Field = fieldName; calc.Cursor = (ICursor)fCursor; calc.ShowErrorPrompt = false; ICalculatorCallback calculatorCallback = new CalculatorCallback(); calc.Callback = calculatorCallback; calc.Calculate(); calculatorCallback = null; //} } catch { } } } break; default: break; } } row = tabCursor.NextRow(); } if (null != tabCursor) { System.Runtime.InteropServices.Marshal.ReleaseComObject(tabCursor); } } catch (Exception ex) { _logHelper.addLogEntry(DateTime.Now.ToString(), "ERROR", "Error applying dynamic defaults.", ex.ToString()); MessageBox.Show("Error: \n" + ex.ToString()); } }
public int CompareTo(INetworkFeature other) { return Network.Nodes.IndexOf(this).CompareTo(Network.Nodes.IndexOf((INode) other)); }
public virtual int CompareTo(INetworkFeature other) { throw new NotImplementedException(); }
public int CompareTo(INetworkFeature other) { return(Network.Branches.IndexOf(this).CompareTo(Network.Branches.IndexOf((IBranch)other))); }
public double RotatePointByNetwork(IMap pMap, INetworkFeature pPointFeature, bool bArithmeticAngle, string strDiameterFld, string strLayerName ) { //This routine is used by both RotateDuringCreateFeature and RotateSelectedFeature. //It contains all of logic for determining the rotation angle. const int iAngleTol = 5; double dblAngle = 0; double dblDiameter = 0; double ltest = 0; int iLineDiameterFieldPos = 0; IPoint pPoint = default(IPoint); ISimpleJunctionFeature pSimpJunc = null; IEdgeFeature pEdgeFeat = default(IEdgeFeature); List<string> pLstInt = new List<string>(); List<double> cAngles = new List<double>(); List<double> cDiameters = new List<double>(); UID pId = new UID(); IFeature pTempFeat = null; try { pPoint = (IPoint)((IFeature)pPointFeature).Shape; if (pPoint.IsEmpty) { return 0; } //Create spatial filter to find intersecting features at this given point pSimpJunc = (ISimpleJunctionFeature)pPointFeature; for (int i = 0; i <= pSimpJunc.EdgeFeatureCount - 1; i++) { pEdgeFeat = pSimpJunc.get_EdgeFeature(i); if (pLstInt.Count > 0) { if (pLstInt.Contains(((IFeature)pEdgeFeat).Class.ObjectClassID + " " + ((IFeature)pEdgeFeat).OID)) { continue; } } pTempFeat = (IFeature)pEdgeFeat; if (strLayerName == Globals.getClassName((IDataset)pTempFeat.Class) || strLayerName == "" || strLayerName == null) { pLstInt.Add(((IFeature)pEdgeFeat).Class.ObjectClassID.ToString() + " " + ((IFeature)pEdgeFeat).OID.ToString()); dblAngle = Globals.GetAngleOfLineAtPoint((IPolyline)pTempFeat.ShapeCopy, pPoint, Globals.GetXYTolerance(pPoint)); dblAngle = Globals.ConvertRadsToDegrees(dblAngle); //Convert to geographic degrees(zero north clockwise) if (!(bArithmeticAngle)) { dblAngle = Globals.ConvertArithmeticToGeographic(dblAngle); } //Round angle dblAngle = Math.Round(dblAngle, 4); //Find diameter field, if it exists iLineDiameterFieldPos = ((IFeature)pEdgeFeat).Fields.FindField(strDiameterFld); //Get diameter of line if (iLineDiameterFieldPos < 0) { dblDiameter = -9999; } else if (((IFeature)pEdgeFeat).get_Value(iLineDiameterFieldPos) == null) { dblDiameter = -9999; } else if (object.ReferenceEquals(((IFeature)pEdgeFeat).get_Value(iLineDiameterFieldPos), DBNull.Value)) { dblDiameter = -9999; } else { double.TryParse(((IFeature)pEdgeFeat).get_Value(iLineDiameterFieldPos).ToString(), out dblDiameter); } //add this line (angle and diameter) to a collection of line info for this point cAngles.Add(dblAngle); if (dblDiameter != -9999) { cDiameters.Add(dblDiameter); } } } //Read the collection of line segment angles and diameters //and use them to derive a symbol rotation angle for the point switch (cAngles.Count) { case 0: //One line such as at valves return 0.0; case 1: //One line such as at valves return cAngles[0]; case 2: //Two lines such as at reducers Or at tee fittings where line is not broken if (cDiameters.Count == 2) { //If cDiameters(0) Is Nothing Or cDiameters(1) Is Nothing Then // Return cAngles.Item(0) //Else if (cDiameters[0] > cDiameters[1]) { return cAngles[1]; //If cAngles.Item(0) = cAngles.Item(1) Then // Return cAngles.Item(1) //Else // Return cAngles.Item(1) - 180 //End If } else { return cAngles[0]; //If cAngles.Item(0) = cAngles.Item(1) Then // Return cAngles.Item(0) - 180 //Else // Return cAngles.Item(1) //End If } } else { return cAngles[0]; } break; case 3: //Three lines such as at tee fittings where line is broken ltest = Math.Abs(cAngles[0] - cAngles[1]); if (ltest >= 180 - iAngleTol & ltest <= 180 + iAngleTol) { return cAngles[2]; } else { ltest = Math.Abs(cAngles[0] - cAngles[2]); if (ltest >= 180 - iAngleTol & ltest <= 180 + iAngleTol) { return cAngles[1]; } else { ltest = Math.Abs(cAngles[1] - cAngles[2]); if (ltest >= 180 - iAngleTol & ltest <= 180 + iAngleTol) { return cAngles[0]; } else { return -360; } } } break; case 4: //Four lines such as at crosses //the angle of any of the four lines should work since the symbol should be symetrically return cAngles[0]; default: return 0; } //Clear collections } catch { return 0; } finally { pPoint=null; pSimpJunc = null; pEdgeFeat = null; pLstInt.Clear(); cAngles.Clear(); cDiameters.Clear(); pId = null; pTempFeat = null; } }
public double RotatePointByNetwork(IMap pMap, INetworkFeature pPointFeature, bool bArithmeticAngle, string strDiameterFld, string strLayerName) { //This routine is used by both RotateDuringCreateFeature and RotateSelectedFeature. //It contains all of logic for determining the rotation angle. const int iAngleTol = 5; double dblAngle = 0; double dblDiameter = 0; double ltest = 0; int iLineDiameterFieldPos = 0; IPoint pPoint = default(IPoint); ISimpleJunctionFeature pSimpJunc = null; IEdgeFeature pEdgeFeat = default(IEdgeFeature); List <string> pLstInt = new List <string>(); List <double> cAngles = new List <double>(); List <double> cDiameters = new List <double>(); UID pId = new UID(); IFeature pTempFeat = null; try { pPoint = (IPoint)((IFeature)pPointFeature).Shape; if (pPoint.IsEmpty) { return(0); } //Create spatial filter to find intersecting features at this given point pSimpJunc = (ISimpleJunctionFeature)pPointFeature; for (int i = 0; i <= pSimpJunc.EdgeFeatureCount - 1; i++) { pEdgeFeat = pSimpJunc.get_EdgeFeature(i); if (pLstInt.Count > 0) { if (pLstInt.Contains(((IFeature)pEdgeFeat).Class.ObjectClassID + " " + ((IFeature)pEdgeFeat).OID)) { continue; } } pTempFeat = (IFeature)pEdgeFeat; if (strLayerName == Globals.getClassName((IDataset)pTempFeat.Class) || strLayerName == "" || strLayerName == null) { pLstInt.Add(((IFeature)pEdgeFeat).Class.ObjectClassID.ToString() + " " + ((IFeature)pEdgeFeat).OID.ToString()); dblAngle = Globals.GetAngleOfLineAtPoint((IPolyline)pTempFeat.ShapeCopy, pPoint, Globals.GetXYTolerance(pPoint)); dblAngle = Globals.ConvertRadsToDegrees(dblAngle); //Convert to geographic degrees(zero north clockwise) if (!(bArithmeticAngle)) { dblAngle = Globals.ConvertArithmeticToGeographic(dblAngle); } //Round angle dblAngle = Math.Round(dblAngle, 4); //Find diameter field, if it exists iLineDiameterFieldPos = ((IFeature)pEdgeFeat).Fields.FindField(strDiameterFld); //Get diameter of line if (iLineDiameterFieldPos < 0) { dblDiameter = -9999; } else if (((IFeature)pEdgeFeat).get_Value(iLineDiameterFieldPos) == null) { dblDiameter = -9999; } else if (object.ReferenceEquals(((IFeature)pEdgeFeat).get_Value(iLineDiameterFieldPos), DBNull.Value)) { dblDiameter = -9999; } else { double.TryParse(((IFeature)pEdgeFeat).get_Value(iLineDiameterFieldPos).ToString(), out dblDiameter); } //add this line (angle and diameter) to a collection of line info for this point cAngles.Add(dblAngle); if (dblDiameter != -9999) { cDiameters.Add(dblDiameter); } } } //Read the collection of line segment angles and diameters //and use them to derive a symbol rotation angle for the point switch (cAngles.Count) { case 0: //One line such as at valves return(0.0); case 1: //One line such as at valves return(cAngles[0]); case 2: //Two lines such as at reducers Or at tee fittings where line is not broken if (cDiameters.Count == 2) { //If cDiameters(0) Is Nothing Or cDiameters(1) Is Nothing Then // Return cAngles.Item(0) //Else if (cDiameters[0] > cDiameters[1]) { return(cAngles[1]); //If cAngles.Item(0) = cAngles.Item(1) Then // Return cAngles.Item(1) //Else // Return cAngles.Item(1) - 180 //End If } else { return(cAngles[0]); //If cAngles.Item(0) = cAngles.Item(1) Then // Return cAngles.Item(0) - 180 //Else // Return cAngles.Item(1) //End If } } else { return(cAngles[0]); } break; case 3: //Three lines such as at tee fittings where line is broken ltest = Math.Abs(cAngles[0] - cAngles[1]); if (ltest >= 180 - iAngleTol & ltest <= 180 + iAngleTol) { return(cAngles[2]); } else { ltest = Math.Abs(cAngles[0] - cAngles[2]); if (ltest >= 180 - iAngleTol & ltest <= 180 + iAngleTol) { return(cAngles[1]); } else { ltest = Math.Abs(cAngles[1] - cAngles[2]); if (ltest >= 180 - iAngleTol & ltest <= 180 + iAngleTol) { return(cAngles[0]); } else { return(-360); } } } break; case 4: //Four lines such as at crosses //the angle of any of the four lines should work since the symbol should be symetrically return(cAngles[0]); default: return(0); } //Clear collections } catch { return(0); } finally { pPoint = null; pSimpJunc = null; pEdgeFeat = null; pLstInt.Clear(); cAngles.Clear(); cDiameters.Clear(); pId = null; pTempFeat = null; } }
public static bool IsBeingMoved(this INetworkFeature networkFeature) { return(networkFeaturesBeingMoved.Contains(networkFeature)); }