Esempio n. 1
0
        // 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);
        }