原文地址: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;
}