Arcengine geometric network 流向代码(转载)

转自:http://www.thinkgis.cn/topic/54203518d97a20db38e59101/

以前学习几何网络时,对效用网络流向进行了总结,原理与效果图见:http://thinkgis.duapp.com/topic/542034b0d97a20db38e59100 但是代码一直没贴出来,因为网上有很多类似的代码,这几天一个网友想交流一下,自己也好久没看这个代码了,在这里把显示流向的代码贴出来分享下,如果你有更好的方法,可以的话也请你分享一下,谢谢。

/// <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 asIElement;
                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 asIElement;
                element.Geometry= midPoint;((IGraphicsContainer)map).AddElement(element,0);break;//不确定流case esriFlowDirection.esriFDIndeterminate:
                markerSymbol =newSimpleMarkerSymbolClass();
                markerSymbol.Color=Utility.GetRGBColor(0,0,255);
                markerSymbol.Size=10;
                markerElement.Symbol= markerSymbol;
                element = markerElement asIElement;
                element.Geometry= midPoint;((IGraphicsContainer)map).AddElement(element,0);break;//未实例化的流case esriFlowDirection.esriFDUninitialized:
                markerSymbol =newSimpleMarkerSymbolClass();
                markerSymbol.Color=Utility.GetRGBColor(0,0,0);
                markerSymbol.Size=10;
                markerElement.Symbol= markerSymbol;
                element = markerElement asIElement;
                element.Geometry= midPoint;((IGraphicsContainer)map).AddElement(element,0);break;}}/// <summary>/// 通过线段的起点和终点来确定线段的流向方向/// 我的理解是流向和数字化方向挂钩,所以就有正向数字化和逆向数字化之分/// 所以在求线段流向方向时,根据实际情况来调用线段的起点和终点作为流向的起点和终点/// </summary>/// <param name="startPoint">流向起点</param>/// <param name="endPoint">流向终点</param>/// <returns></returns>publicstaticdoubleGetDirectionAngle(IPoint startPoint,IPoint endPoint){//弧度double radian;//角度double angle =0;if(startPoint.X == endPoint.X){if(startPoint.Y > endPoint.Y)
                angle =270;elseif(startPoint.Y < endPoint.Y)
                angle =90;}elseif(startPoint.X > endPoint.X){if(startPoint.Y == endPoint.Y)
                angle =180;elseif(startPoint.Y > endPoint.Y){
                radian =Math.Atan((startPoint.Y - endPoint.Y)/(startPoint.X - endPoint.X));
                angle = radian *(180/Math.PI)+180;}elseif(startPoint.Y < endPoint.Y){
                radian =Math.Atan((startPoint.X - endPoint.X)/(endPoint.Y - startPoint.Y));
                angle = radian *(180/Math.PI)+90;}}elseif(startPoint.X < endPoint.X){if(startPoint.Y == endPoint.Y)
                angle =0;elseif(startPoint.Y < endPoint.Y){
                radian =Math.Atan((endPoint.Y - startPoint.Y)/(endPoint.X - startPoint.X));
                angle = radian *(180/Math.PI);}elseif(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>privatestaticintGetFeatureDID(IFeature feature,INetwork network){INetElements netElements = network asINetElements;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 @ 2016-06-15 15:30  焦涛  阅读(273)  评论(0)    收藏  举报