📄 netlayer.cs
字号:
}
}
public class NetLinkSeg
{
public int nSegID; // 分裂点后面的部分的弧段索引(数组下标索引)
public double dRatio; // 分裂点前面的到起始结点部分的比例
};
// 用于备份弧段的类
public class NetLinkBackup
{
public int m_nIndex; // 弧段的索引
public NetLink m_Link=null; // 备份的弧段对象
public ArrayList m_arrSegs; // 该弧段被多次分割的比例列表, 数目=段数-1, 即等于分裂点数
public NetLinkBackup()
{
m_nIndex = -1;
m_Link = new NetLink();
m_arrSegs = new ArrayList();
}
public bool Add( int nSeg, double dRatio )
{
int i = 0;
for ( i = 0; i < m_arrSegs.Count; i++ )
{
if ( dRatio < ((NetLinkSeg)m_arrSegs[i]).dRatio )
break;
}
NetLinkSeg pSeg = new NetLinkSeg();
pSeg.nSegID = nSeg;
pSeg.dRatio = dRatio;
m_arrSegs.Insert( i, pSeg );
return true;
}
}
public class NetPath
{
public double m_dLength; // 该点到给定点的最短路径长度, -1表示无穷大,即不连通
public int m_nPreNode; // 该点在该路径上的前趋结点
public NetPath()
{
m_dLength = -1;
m_nPreNode = -1;
}
}
/// <summary>
/// Summary description for NetLayer.
/// </summary>
public class NetLayer
{
private ArrayList m_arrLinks; // 弧段表
private ArrayList m_arrNodes; // 结点表
private ArrayList m_arrStops; // 站点表
private ArrayList m_arrLinkBackups; // 弧段备份表
private int m_nLinkNum; // 原始弧段数目(网络拓扑建立完成后) 注意: 和m_arrLinks的大小可能是不相等的
private int m_nNodeNum; // 原始结点数目(网络拓扑建立完成后) 注意: 和m_arrNodes的大小可能是不相等的
private NetPath[] m_pPath; // 某一个点到所有点的最短路径. 每个点只记录它在路径上的前趋结点
private MapObjects2.MapLayer m_layer = null;
private System.Data.DataSet m_dataSet = null;
public NetLayer(MapObjects2.MapLayer layer, System.Data.DataSet dataSet)
{
m_nLinkNum = 0;
m_nNodeNum = 0;
m_pPath = null;
m_dataSet = dataSet;
m_layer = layer;
}
public bool ReadNetTable()
{
m_arrLinks = new ArrayList();
m_arrNodes = new ArrayList();
m_arrStops = new ArrayList();
m_arrLinkBackups = new ArrayList();
System.Data.DataTable Tbl = m_dataSet.Tables["AAT"];
System.Data.DataRow[] rows = Tbl.Select();
foreach (System.Data.DataRow myRow in rows)
{
NetLink lk = new NetLink();
lk.m_GeoID = (int)myRow["GeoID"];
lk.m_nFNode = (int)myRow["FNODE"];
lk.m_nTNode = (int)myRow["TNODE"];
lk.m_fLength = (double)myRow["LENGTH"];
lk.m_fFromImp = (double)myRow["FIMP"];
lk.m_fToImp = (double)myRow["TIMP"];
m_arrLinks.Add( lk );
}
Tbl = m_dataSet.Tables["NAT"];
rows = Tbl.Select();
foreach (System.Data.DataRow myRow in rows)
{
int nNode, nLink;
double x, y, dAngle;
string szArcID, szAngle;
nNode = (int)myRow["NODEID"];
x = (double)myRow["X"];
y = (double)myRow["Y"];
szArcID = myRow["ARCID"].ToString();
szAngle = myRow["ANGLE"].ToString();
NetNode node = new NetNode(x,y);
m_arrNodes.Add( node );
int nPos;
string szTemp;
while ( (nPos = szArcID.IndexOf( ';' )) != -1 )
{
szTemp = szArcID.Substring( 0,nPos );
nLink = Convert.ToInt32( szTemp );
szArcID = szArcID.Substring( nPos+1 );
nPos = szAngle.IndexOf( ';' );
if ( nPos == -1 )
continue;
szTemp = szAngle.Substring(0, nPos );
dAngle = Convert.ToDouble( szTemp );
szAngle = szAngle.Substring( nPos + 1 );
node.Add( nLink, dAngle );
}
}
return true;
}
public bool PathAnalysis( double x1, double y1, double x2, double y2, out ArrayList path )
{
path = new ArrayList();
NetPoint pt1 = new NetPoint( x1, y1 );
NetPoint pt2 = new NetPoint( x2, y2 );
ArrayList points = new ArrayList();
points.Add( pt1 );
points.Add( pt2 );
ArrayList stops = null;
if ( !LoadStops( points, out stops ) )
return false;
if ( stops.Count != 2 )
return false;
ArrayList nodes = null;
double dDistance;
dDistance = Path( (int)stops[0], (int)stops[1], out nodes, false );
if ( dDistance < 0 )
return false;
NetLine line = null;
if ( !CreateResultPath( nodes, out line, false ) )
return false;
for ( int i = 0; i < line.m_pCoords.Count; i++ )
{
path.Add( ((NetPoint)line.m_pCoords[i]).x );
path.Add( ((NetPoint)line.m_pCoords[i]).y );
}
UnloadStops();
return true;
}
// 加入一组坐标作为站点或者中心点, 用于分析. LoadStops与UnloadStops必须一一对应
private bool LoadStops( ArrayList pPoints, out ArrayList pNodes )
{
int nLineID;
int i, nNewNode;
NetPoint ptNearest;
double dRatio;
pNodes = new ArrayList();
// 先清空站点表
m_arrStops.Clear();
int nNum = pPoints.Count;
for ( i = 0; i < nNum; i++ )
{
// 计算距离该点最近的线
NetLine line = new NetLine(m_layer);
nLineID = line.GetNearestLineData( ((NetPoint)pPoints[i]).x, ((NetPoint)pPoints[i]).y);
if ( nLineID == -1 )
{
line = null;
return false;
}
// 计算该点分裂该线的位置, 并不实际分裂该线, 只是计算分裂的比例, 用于更改弧段表和结点表
dRatio = 0;
line.GetSplitRatioByNearestPoint( (NetPoint)pPoints[i], out ptNearest, out dRatio );
// 更新弧段表和结点表
UpdateLinkNodeTable( nLineID, ptNearest, dRatio, out nNewNode );
line = null;
if ( pNodes.Count > 0 )
{
if ( ((int)pNodes[pNodes.Count-1]) == nNewNode )
continue;
}
pNodes.Add( nNewNode );
}
// 填充需要返回的结点数组
if ( pNodes.Count == 0 )
{
pNodes = null;
return false;
}
return true;
}
// 外部结点更新弧段表和结点表
// nNewNode: 加入该点后返回的新结点的标识
private bool UpdateLinkNodeTable( int nLineID, NetPoint ptNearest, double dRatio, out int nNewNode )
{
int i, j;
bool bFound;
double dRatio2;
int nCurLink, nNewLink;
int nCurFNode, nCurTNode;
nNewNode = -1;
// 与某条弧段的首点或者位点重合, 不需要更改弧段表和结点表
if ( Math.Abs(dRatio) < 0.00000001 )
{
// 首点
nCurLink = GetNode( nLineID, out nCurFNode, out nCurTNode );
nNewNode = nCurFNode;
return true;
}
else if ( Math.Abs(1-dRatio) < 0.00000001 )
{
// 尾点
nCurLink = GetNode( nLineID, out nCurFNode, out nCurTNode );
nNewNode = nCurTNode;
return true;
}
bFound = false;
for ( i = 0; i < m_arrLinkBackups.Count; i++ )
{
if ( ((NetLinkBackup)m_arrLinkBackups[i]).m_Link.m_GeoID == nLineID )
{
bFound = true;
break;
}
}
if ( bFound )
{
for ( j = 0; j < ((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs.Count; j++ )
{
// 如果新点与原有的点重合, 则直接返回原来的点
double r = ((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[j]).dRatio;
if ( Math.Abs( r - dRatio) < 0.00000001 )
{
if ( j == 0 )
{
nCurLink = GetNode( nLineID, out nCurFNode, out nCurTNode );
nNewNode = nCurTNode;
return true;
}
else
{
nCurLink = ((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[j-1]).nSegID;
nNewNode = ((NetLink)m_arrLinks[nCurLink]).m_nTNode;
return true;
}
}
// 没有重合的点
r = ((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[j]).dRatio;
if ( dRatio < r )
break;
}
if ( j == 0 )
{
// 第一段
nCurLink = GetNode( nLineID, out nCurFNode, out nCurTNode );
if ( nCurLink == -1 )
return false;
// 更新结点表
nNewLink = m_arrLinks.Count;
NetNode pNode = new NetNode( ptNearest.x, ptNearest.y );
pNode.Add( nNewLink, -1 ); // 这里暂时用-1角度,待修改 Add code here
pNode.Add( nCurLink, -1 );
m_arrNodes.Add( pNode );
((NetNode)m_arrNodes[nCurTNode]).Remove( nCurLink );
((NetNode)m_arrNodes[nCurTNode]).Add( nNewLink, -1 );
// 更新弧段表
nNewNode = m_arrNodes.Count - 1;
dRatio2 = ((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[0]).dRatio;
NetLink pLink = new NetLink();
pLink.m_GeoID = nLineID;
pLink.m_nFNode = nNewNode;
pLink.m_nTNode = ((NetLink)m_arrLinks[((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[0]).nSegID]).m_nFNode;
pLink.m_fLength = (float)(((NetLink)m_arrLinks[nCurLink]).m_fLength * ( dRatio2 - dRatio ));
pLink.m_fFromImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fFromImp * ( dRatio2 - dRatio ));
pLink.m_fToImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fToImp * ( dRatio2 - dRatio ));
m_arrLinks.Add( pLink );
((NetLink)m_arrLinks[nCurLink]).m_nTNode = nNewNode;
((NetLink)m_arrLinks[nCurLink]).m_fLength = (float)(((NetLink)m_arrLinks[nCurLink]).m_fLength * dRatio);
((NetLink)m_arrLinks[nCurLink]).m_fFromImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fFromImp * dRatio);
((NetLink)m_arrLinks[nCurLink]).m_fToImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fToImp* dRatio);
((NetLinkBackup)m_arrLinkBackups[i]).Add( nNewLink, dRatio );
}
else if ( j == ((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs.Count )
{
// 最后一段
nCurLink = ((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[j-1]).nSegID;
nCurFNode = ((NetLink)m_arrLinks[nCurLink]).m_nFNode;
nCurTNode = ((NetLink)m_arrLinks[nCurLink]).m_nTNode;
// 更新结点表
nNewLink = m_arrLinks.Count;
NetNode pNode = new NetNode( ptNearest.x, ptNearest.y );
pNode.Add( nNewLink, -1 ); // 这里暂时用-1角度,待修改 Add code here
pNode.Add( nCurLink, -1 );
m_arrNodes.Add( pNode );
double dAngle = ((NetNode)m_arrNodes[nCurTNode]).GetLinkAngle( nCurLink ); // 最后一段保留原角度
((NetNode)m_arrNodes[nCurTNode]).Remove( nCurLink );
((NetNode)m_arrNodes[nCurTNode]).Add( nNewLink, dAngle );
// 更新弧段表
nNewNode = m_arrNodes.Count - 1;
NetLink pLink = new NetLink();
pLink.m_GeoID = nLineID;
pLink.m_nFNode = nNewNode;
pLink.m_nTNode = nCurTNode;
pLink.m_fLength = (float)(((NetLink)m_arrLinks[i]).m_fLength * ( 1 - dRatio ));
pLink.m_fFromImp = (float)(((NetLink)m_arrLinks[i]).m_fFromImp * ( 1 - dRatio ));
pLink.m_fToImp = (float)(((NetLink)m_arrLinks[i]).m_fToImp * ( 1 - dRatio ));
m_arrLinks.Add( pLink );
dRatio2 = ((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[j-1]).dRatio;
((NetLink)m_arrLinks[nCurLink]).m_nTNode = nNewNode;
((NetLink)m_arrLinks[nCurLink]).m_fLength = (float)(((NetLink)m_arrLinks[nCurLink]).m_fLength * ( dRatio - dRatio2) );
((NetLink)m_arrLinks[nCurLink]).m_fFromImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fFromImp * ( dRatio - dRatio2) );
((NetLink)m_arrLinks[nCurLink]).m_fToImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fToImp* ( dRatio - dRatio2) );
((NetLinkBackup)m_arrLinkBackups[i]).Add( nNewLink, dRatio );
}
else
{
// 中间某一段
nCurLink = ((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[j-1]).nSegID;
nCurFNode = ((NetLink)m_arrLinks[nCurLink]).m_nFNode;
nCurTNode = ((NetLink)m_arrLinks[nCurLink]).m_nTNode;
// 更新结点表
nNewLink = m_arrLinks.Count;
NetNode pNode = new NetNode( ptNearest.x, ptNearest.y );
pNode.Add( nNewLink, -1 ); // 这里暂时用-1角度,待修改 Add code here
pNode.Add( nCurLink, -1 );
m_arrNodes.Add( pNode );
((NetNode)m_arrNodes[nCurTNode]).Remove( nCurLink );
((NetNode)m_arrNodes[nCurTNode]).Add( nNewLink, -1 );
// 更新弧段表
nNewNode = m_arrNodes.Count - 1;
dRatio2 = ((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[j]).dRatio;
NetLink pLink = new NetLink();
pLink.m_GeoID = nLineID;
pLink.m_nFNode = nNewNode;
pLink.m_nTNode = nCurTNode;
pLink.m_fLength = (float)(((NetLink)m_arrLinks[i]).m_fLength * ( dRatio2 - dRatio ));
pLink.m_fFromImp = (float)(((NetLink)m_arrLinks[i]).m_fFromImp * ( dRatio2 - dRatio ));
pLink.m_fToImp = (float)(((NetLink)m_arrLinks[i]).m_fToImp * ( dRatio2 - dRatio ));
m_arrLinks.Add( pLink );
dRatio2 = ((NetLinkSeg)((NetLinkBackup)m_arrLinkBackups[i]).m_arrSegs[j-1]).dRatio;
((NetLink)m_arrLinks[nCurLink]).m_nTNode = nNewNode;
((NetLink)m_arrLinks[nCurLink]).m_fLength = (float)(((NetLink)m_arrLinks[nCurLink]).m_fLength * ( dRatio - dRatio2) );
((NetLink)m_arrLinks[nCurLink]).m_fFromImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fFromImp * ( dRatio - dRatio2) );
((NetLink)m_arrLinks[nCurLink]).m_fToImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fToImp* ( dRatio - dRatio2) );
((NetLinkBackup)m_arrLinkBackups[i]).Add( nNewLink, dRatio );
}
}
else
{
nCurLink = GetNode( nLineID, out nCurFNode, out nCurTNode );
if ( nCurLink == -1 )
return false;
nNewLink = m_arrLinks.Count;
// 备份
NetLinkBackup pBackup = new NetLinkBackup();
pBackup.m_nIndex = nCurLink;
pBackup.m_Link.Copy((NetLink)m_arrLinks[nCurLink]);
pBackup.Add( nNewLink, dRatio );
m_arrLinkBackups.Add( pBackup );
// 更新结点表
NetNode pNode = new NetNode( ptNearest.x, ptNearest.y );
pNode.Add( nNewLink, -1 ); // 这里暂时用0角度,待修改 Add code here
pNode.Add( nCurLink, -1 );
m_arrNodes.Add( pNode );
double dAngle = ((NetNode)m_arrNodes[nCurTNode]).GetLinkAngle( nCurLink ); // 最后一段保留原角度
((NetNode)m_arrNodes[((NetLink)m_arrLinks[nCurLink]).m_nTNode]).Remove( nCurLink );
((NetNode)m_arrNodes[((NetLink)m_arrLinks[nCurLink]).m_nTNode]).Add( nNewLink, dAngle );
// 更新弧段表
nNewNode = m_arrNodes.Count - 1;
NetLink pLink = new NetLink();
pLink.m_GeoID = nLineID;
pLink.m_nFNode = nNewNode;
pLink.m_nTNode = ((NetLink)m_arrLinks[nCurLink]).m_nTNode;
pLink.m_fLength = (float)(((NetLink)m_arrLinks[nCurLink]).m_fLength * ( 1 - dRatio ));
pLink.m_fFromImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fFromImp * ( 1 - dRatio ));
pLink.m_fToImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fToImp * ( 1 - dRatio ));
m_arrLinks.Add( pLink );
((NetLink)m_arrLinks[nCurLink]).m_nTNode = nNewNode;
((NetLink)m_arrLinks[nCurLink]).m_fLength = (float)(((NetLink)m_arrLinks[nCurLink]).m_fLength * dRatio);
((NetLink)m_arrLinks[nCurLink]).m_fFromImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fFromImp * dRatio);
((NetLink)m_arrLinks[nCurLink]).m_fToImp = (float)(((NetLink)m_arrLinks[nCurLink]).m_fToImp* dRatio);
}
return true;
}
// 得到结点号, 返回弧段索引号(数组下标索引), -1表示失败
private int GetNode( int nLineID, out int nFNode, out int nTNode )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -