ArcGIS Engine 中 Geometric Network 显示流向代码

原文地址:http://hi.baidu.com/steeeeps/item/165fbc15475e94741009b5b3

非常感谢作者。


以前学习几何网络时,对效用网络流向进行了总结,原理与效果图见:http://hi.baidu.com/llinkin_park/blog/item/7f18fff9e87cf075034f56d8.html

但是代码一直没贴出来,因为网上有很多类似的代码,这几天一个网友想交流一下,自己也好久没看这个代码了,在这里把显示流向的代码贴出来分享下,如果你有更好的方法,可以的话也请你分享一下,谢谢。

/// <summary>

        /// 得到IGeometricNetwork

        /// </summary>

        /// <param name="layer"></param>

        /// <returns></returns>

        public static IGeometricNetwork GetGeometricNetwork(ILayer layer)

        {

            IFeatureClass featureClass = ((IFeatureLayer)layer).FeatureClass;

            IFeatureDataset featureDataset = featureClass.FeatureDataset;

            INetworkCollection networkCollection = featureDataset as INetworkCollection;

            IGeometricNetwork geometricNetwork = networkCollection.get_GeometricNetworkByName(GN_NAME);

            return geometricNetwork;

        }

 

        /// <summary>

        /// 显示网络流向

        /// </summary>

        /// <param name="map"></param>

        public static void ShowFlowDirection(IMap map)

        {

            IGeometricNetwork geometricNetwork = GetGeometricNetwork(map.get_Layer(0));

 

            IFeatureClass featureClass = ((IFeatureLayer)map.get_Layer(0)).FeatureClass;

            IFeatureDataset featureDataset = featureClass.FeatureDataset;

            IWorkspace workspace = featureDataset.Workspace;

            IWorkspaceEdit workspaceEdit = workspace as IWorkspaceEdit;

            workspaceEdit.StartEditing(false);

            workspaceEdit.StartEditOperation();

 

 

            ILayer netLayer = null;

 

            //得到网络图层

            for (int i = 0; i < map.LayerCount; i++)

            {

                if (map.get_Layer(i).Name == NET_NAME)

                {

                    netLayer = map.get_Layer(i);

                    break;

                }

            }

 

            if (netLayer != null)

            {

                IFeatureClass netFeatureClass = ((IFeatureLayer)netLayer).FeatureClass;

                IFeatureCursor featureCursor = netFeatureClass.Search(null, true);

                IFeature edgeFeature = featureCursor.NextFeature();

                while (edgeFeature != null)

                {

                    //得到每条边的流向

                    INetwork network = geometricNetwork.Network;

                    IUtilityNetworkGEN utilityNetworkGEN = network as IUtilityNetworkGEN;

 

                    int edgeID = GetFeatureDID(edgeFeature, network);

                    esriFlowDirection edgeFlowDirection = utilityNetworkGEN.GetFlowDirection(edgeID);

                    DrawSymbol2FlowDirection(edgeFeature, edgeFlowDirection, map);

 

                    edgeFeature = featureCursor.NextFeature();

                }

            }

            workspaceEdit.StopEditOperation();

            workspaceEdit.StopEditing(true);

            ((IActiveView)map).Refresh();

        }

 

        /// <summary>

        /// 给边线要素添加流向标志

        /// </summary>

        /// <param name="edgeFeature"></param>

        /// <param name="edgeFlowDirection"></param>

        /// <param name="map"></param>

        private static void DrawSymbol2FlowDirection(IFeature edgeFeature, esriFlowDirection edgeFlowDirection, IMap map)

        {

            IPolyline polyline = edgeFeature.Shape as IPolyline;

            //找到线段的中点

            IPoint midPoint = new PointClass();

            polyline.QueryPoint(esriSegmentExtension.esriNoExtension, polyline.Length / 2, false, midPoint);

 

            IArrowMarkerSymbol arrowMarkerSymbol = new ArrowMarkerSymbolClass(); ;

            IMarkerElement markerElement = new MarkerElementClass();

            IElement element;

            IMarkerSymbol markerSymbol;

            switch (edgeFlowDirection)

            {

                //存在正向流向(数字化方向)

                case esriFlowDirection.esriFDWithFlow:

                    arrowMarkerSymbol.Color = Utility.GetRGBColor(255, 0, 0);

                    arrowMarkerSymbol.Size = 13;

                    arrowMarkerSymbol.Style = esriArrowMarkerStyle.esriAMSPlain;

                    arrowMarkerSymbol.Angle = GetDirectionAngle(polyline.FromPoint, polyline.ToPoint);

                    markerElement.Symbol = arrowMarkerSymbol;

                    element = markerElement as IElement;

                    element.Geometry = midPoint;

                    ((IGraphicsContainer)map).AddElement(element, 0);

                    break;

                //逆向流向

                case esriFlowDirection.esriFDAgainstFlow:

                    arrowMarkerSymbol.Color = Utility.GetRGBColor(255, 0, 0);

                    arrowMarkerSymbol.Size = 13;

                    arrowMarkerSymbol.Style = esriArrowMarkerStyle.esriAMSPlain;

                    arrowMarkerSymbol.Angle = GetDirectionAngle(polyline.ToPoint, polyline.FromPoint);

                    markerElement.Symbol = arrowMarkerSymbol;

                    element = markerElement as IElement;

                    element.Geometry = midPoint;

                    ((IGraphicsContainer)map).AddElement(element, 0);

                    break;

                //不确定流

                case esriFlowDirection.esriFDIndeterminate:

                    markerSymbol = new SimpleMarkerSymbolClass();

                    markerSymbol.Color = Utility.GetRGBColor(0, 0, 255);

                    markerSymbol.Size = 10;

                    markerElement.Symbol = markerSymbol;

                    element = markerElement as IElement;

                    element.Geometry = midPoint;

                    ((IGraphicsContainer)map).AddElement(element, 0);

                    break;

                //未实例化的流

                case esriFlowDirection.esriFDUninitialized:

                    markerSymbol = new SimpleMarkerSymbolClass();

                    markerSymbol.Color = Utility.GetRGBColor(0, 0, 0);

                    markerSymbol.Size = 10;

                    markerElement.Symbol = markerSymbol;

                    element = markerElement as IElement;

                    element.Geometry = midPoint;

                    ((IGraphicsContainer)map).AddElement(element, 0);

                    break;

            }

        }

 

        /// <summary>

        /// 通过线段的起点和终点来确定线段的流向方向

        /// 我的理解是流向和数字化方向挂钩,所以就有正向数字化和逆向数字化之分

        /// 所以在求线段流向方向时,根据实际情况来调用线段的起点和终点作为流向的起点和终点

        /// </summary>

        /// <param name="startPoint">流向起点</param>

        /// <param name="endPoint">流向终点</param>

        /// <returns></returns>

        public static double GetDirectionAngle(IPoint startPoint, IPoint endPoint)

        {

            //弧度

            double radian;

            //角度

            double angle = 0;

 

            if (startPoint.X == endPoint.X)

            {

                if (startPoint.Y > endPoint.Y)

                    angle = 270;

                else if (startPoint.Y < endPoint.Y)

                    angle = 90;

            }

            else if (startPoint.X > endPoint.X)

            {

                if (startPoint.Y == endPoint.Y)

                    angle = 180;

                else if (startPoint.Y > endPoint.Y)

                {

                    radian = Math.Atan((startPoint.Y - endPoint.Y) / (startPoint.X - endPoint.X));

                    angle = radian * (180 / Math.PI) + 180;

                }

                else if (startPoint.Y < endPoint.Y)

                {

                    radian = Math.Atan((startPoint.X - endPoint.X) / (endPoint.Y - startPoint.Y));

                    angle = radian * (180 / Math.PI) + 90;

                }

            }

            else if (startPoint.X < endPoint.X)

            {

                if (startPoint.Y == endPoint.Y)

                    angle = 0;

                else if (startPoint.Y < endPoint.Y)

                {

                    radian = Math.Atan((endPoint.Y - startPoint.Y) / (endPoint.X - startPoint.X));

                    angle = radian * (180 / Math.PI);

                }

                else if (startPoint.Y > endPoint.Y)

                {

                    radian = Math.Atan((startPoint.Y - endPoint.Y) / (endPoint.X - startPoint.X));

                    angle = 360 - (radian * (180 / Math.PI));

                }

            }

            return angle;

        }

 

        /// <summary>

        /// 得到要素的EID

        /// </summary>

        /// <param name="feature"></param>

        /// <param name="network"></param>

        /// <returns></returns>

        private static int GetFeatureDID(IFeature feature, INetwork network)

        {

            INetElements netElements = network as INetElements;

            int eID = 0;

            esriElementType elementType = esriElementType.esriETNone;

            switch (feature.FeatureType)

            {

                case esriFeatureType.esriFTSimpleEdge:

                case esriFeatureType.esriFTComplexEdge:

                    elementType = esriElementType.esriETEdge;

                    break;

                case esriFeatureType.esriFTSimpleJunction:

                case esriFeatureType.esriFTComplexJunction:

                    elementType = esriElementType.esriETJunction;

                    break;

            }

            eID = netElements.GetEID(feature.Class.ObjectClassID, feature.OID, -1, elementType);

            return eID;

        }

posted @ 2015-03-24 16:23  94cool  阅读(567)  评论(0编辑  收藏  举报