且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ArcGIS Engine 中 Geometric Network 显示流向代码

更新时间:2022-09-10 14:43:36


以前学习几何网络时,对效用网络流向进行了总结,原理与效果图见: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;

}




本文转自94cool博客园博客,原文链接:http://www.cnblogs.com/94cool/p/4363179.html,如需转载请自行联系原作者