⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netlayer.cs

📁 经典的GIS二次开发系列书籍的一本
💻 CS
📖 第 1 页 / 共 3 页
字号:
		}
	}

	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 + -