📄 利用vc+mo最短路径算法--gis开发.htm
字号:
最后一段保留原角度<BR> double dAngle =
netNode->GetLinkAngle( nCurLink
);<BR> netNode->Remove( nCurLink
);<BR> netNode->Add( nNewLink, dAngle );</P>
<P> // 更新弧段表<BR> *nNewNode =
m_arrNodes.GetCount() - 1;<BR> NetLink
pLink;<BR> pLink.m_GeoID =
nLineID;<BR> pLink.m_nFNode =
*nNewNode;<BR> pLink.m_nTNode =
nCurTNode;<BR> NetLink nl =
m_arrLinks.GetAt(m_arrLinks.FindIndex(i));<BR> pLink.m_fLength
= (float) (nl.m_fLength * ( 1 - dRatio
));<BR> pLink.m_fFromImp = (float)(nl.m_fFromImp *
( 1 - dRatio ));<BR> pLink.m_fToImp =
(float)(nl.m_fToImp * ( 1 - dRatio
));<BR> m_arrLinks.AddTail( pLink );</P>
<P> dRatio2 =
nlS.dRatio;<BR> NetLink* nlk =
&(m_arrLinks.GetAt(m_arrLinks.FindIndex(nCurLink)));<BR> nlk->m_nTNode
= *nNewNode;<BR> nlk->m_fLength = (float)
(nlk->m_fLength * ( dRatio - dRatio2)
);<BR> nlk->m_fFromImp = (float)
(nlk->m_fFromImp * ( dRatio - dRatio2)
);<BR> nlk->m_fToImp = (float)
(nlk->m_fToImp* ( dRatio - dRatio2)
);<BR> m_arrLinkBackups.GetAt(m_arrLinkBackups.FindIndex(i)).Add(<BR>
nNewLink, dRatio
);<BR> }<BR> else<BR> {<BR> //
中间某一段<BR> NetLink* nlk =
&(m_arrLinks.GetAt(m_arrLinks.FindIndex(nCurLink)));<BR> NetLinkBackup*
nlBp =
&(m_arrLinkBackups.GetAt(m_arrLinkBackups.FindIndex(i)));<BR> NetLinkSeg
nlS =
nlBp->m_arrSegs.GetAt(nlBp->m_arrSegs.FindIndex(j-1));<BR> nCurLink
= nlS.nSegID;<BR> nCurFNode =
nlk->m_nFNode;<BR> nCurTNode =
nlk->m_nTNode;</P>
<P> // 更新节点表<BR> nNewLink =
m_arrLinks.GetCount();<BR> NetNode
pNode(ptNearest.x, ptNearest.y );<BR> pNode.Add(
nNewLink, -1 ); <BR> pNode.Add( nCurLink, -1
);<BR> m_arrNodes.AddTail( pNode );</P>
<P> NetNode* pNd =
&(m_arrNodes.GetAt(<BR>
m_arrNodes.FindIndex(nCurTNode)));<BR> pNd->Remove(
nCurLink );<BR> pNd->Add( nNewLink, -1 );</P>
<P> // 更新弧段表<BR> *nNewNode =
m_arrNodes.GetCount() - 1;<BR> NetLinkSeg nlSPt =
nlBp->m_arrSegs.GetAt(nlBp->m_arrSegs.FindIndex(j));<BR> dRatio2
= nlSPt.dRatio;<BR> NetLink
pLink;<BR> pLink.m_GeoID =
nLineID;<BR> pLink.m_nFNode =
*nNewNode;<BR> pLink.m_nTNode =
nCurTNode;<BR> NetLink nlkI =
m_arrLinks.GetAt(m_arrLinks.FindIndex(i));<BR> pLink.m_fLength
= (float)(nlkI.m_fLength * ( dRatio2 - dRatio
));<BR> pLink.m_fFromImp = (float)(nlkI.m_fFromImp
* ( dRatio2 - dRatio ));<BR> pLink.m_fToImp =
(float)(nlkI.m_fToImp * ( dRatio2 - dRatio
));<BR> m_arrLinks.AddTail( pLink );</P>
<P> dRatio2 =
nlS.dRatio;<BR> nlk->m_nTNode =
*nNewNode;<BR> nlk->m_fLength =
(float)(nlk->m_fLength * ( dRatio - dRatio2)
);<BR> nlk->m_fFromImp =
(float)(nlk->m_fFromImp * ( dRatio - dRatio2)
);<BR> nlk->m_fToImp = (float)(nlk->m_fToImp*
( dRatio - dRatio2)
);<BR> m_arrLinkBackups.GetAt(m_arrLinkBackups.FindIndex(i)).Add(<BR>
nNewLink, dRatio
);<BR> }<BR> }<BR> else<BR> {<BR> nCurLink
= GetNode( nLineID, &nCurFNode, &nCurTNode
);<BR> if ( nCurLink == -1 )<BR> return
FALSE;</P>
<P> nNewLink =
m_arrLinks.GetCount();<BR> NetLink* nlk =
&(m_arrLinks.GetAt(m_arrLinks.FindIndex(nCurLink)));<BR> //
备份<BR> NetLinkBackup
pBackup;<BR> pBackup.m_nIndex =
nCurLink;<BR> pBackup.m_Link.Copy(*nlk);<BR> pBackup.Add(
nNewLink, dRatio );<BR> m_arrLinkBackups.AddTail( pBackup
);</P>
<P> // 更新结点表<BR> NetNode pNode( ptNearest.x,
ptNearest.y );<BR> pNode.Add( nNewLink, -1
); <BR> pNode.Add( nCurLink, -1
);<BR> m_arrNodes.AddTail( pNode );</P>
<P> NetNode* pTempNd =
&(m_arrNodes.GetAt(<BR>
m_arrNodes.FindIndex(nCurTNode)));<BR> //
最后一段保留原角度<BR> double dAngle = pTempNd->GetLinkAngle(
nCurLink );<BR> int nTNode =
m_arrLinks.GetAt(m_arrLinks.FindIndex(nCurLink)).m_nTNode;<BR> NetNode*
pNd =
&(m_arrNodes.GetAt(m_arrNodes.FindIndex(nTNode)));<BR> pNd->Remove(
nCurLink );<BR> pNd->Add( nNewLink, dAngle
);<BR> NetNode* pNd1 =
&(m_arrNodes.GetAt(m_arrNodes.FindIndex(nTNode)));</P>
<P> // 更新弧段表<BR> *nNewNode =
m_arrNodes.GetCount() - 1;<BR> NetLink
pLink;<BR> pLink.m_GeoID =
nLineID;<BR> pLink.m_nFNode =
*nNewNode;<BR> pLink.m_nTNode =
nlk->m_nTNode;<BR> pLink.m_fLength =
(float)(nlk->m_fLength * ( 1 - dRatio
));<BR> pLink.m_fFromImp = (float)(nlk->m_fFromImp * (
1 - dRatio ));<BR> pLink.m_fToImp =
(float)(nlk->m_fToImp * ( 1 - dRatio
));<BR> m_arrLinks.AddTail( pLink );</P>
<P> nlk->m_nTNode =
*nNewNode;<BR> nlk->m_fLength =
(float)(nlk->m_fLength *
dRatio);<BR> nlk->m_fFromImp =
(float)(nlk->m_fFromImp *
dRatio);<BR> nlk->m_fToImp = (float)(nlk->m_fToImp
* dRatio);<BR> }<BR> return
true;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>int
CNetLayer::GetNode( int nLineID, int* nFNode, int* nTNode
)<BR>{<BR> *nFNode = -1;<BR> *nTNode = -1;<BR> for (
int i = 0; i<m_arrLinks.GetCount(); i++
)<BR> {<BR> NetLink nl =
m_arrLinks.GetAt(m_arrLinks.FindIndex(i));<BR> if(nLineID
== nl.m_GeoID )<BR> {<BR> *nFNode =
nl.m_nFNode;<BR> *nTNode =
nl.m_nTNode;<BR> return
i;<BR> }<BR> }<BR> return
-1;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>double
CNetLayer::Path( int nBeginNode, int nEndNode,
<BR> CList<int,
int&>* pNodes, BOOL bWeight )<BR>{ <BR> if
(nBeginNode < 0 || nBeginNode >=
m_arrNodes.GetCount())<BR> return -1;<BR> if (
nEndNode < 0 || nEndNode >=
m_arrNodes.GetCount())<BR> return
-1;<BR> <BR> // 如果两个结点相同<BR> if ( nBeginNode ==
nEndNode )<BR> {<BR> pNodes->AddTail(nBeginNode
);<BR> return 0;<BR> }<BR> //
计算nBeginNode到其他所有结点的最短路径<BR> if ( !CalcPath( nBeginNode,
nEndNode, bWeight ) )<BR> return -1;</P>
<P> // 提取从nBeginNode到nEndNode的路径<BR> //
从nEndNode向前搜索前趋结点<BR> int nNode;<BR> nNode =
nEndNode;<BR> while(TRUE)<BR> {<BR> //
如果没有前趋结点,表示不连通<BR> if ( m_pPath[nNode].m_nPreNode == -1
)<BR> return -1;</P>
<P> // 如果前趋结点为起始结点,路径结束<BR> if (
m_pPath[nNode].m_nPreNode == nBeginNode
)<BR> {<BR> pNodes->AddHead( nNode
);<BR> break;<BR> }</P>
<P> // 加入中间结点<BR> pNodes->AddHead(nNode
);<BR> nNode = m_pPath[nNode].m_nPreNode;<BR> }</P>
<P> // 加入起点<BR> pNodes->AddHead(nBeginNode );</P>
<P> return
m_pPath[nEndNode].m_dLength;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>BOOL
CNetLayer::CalcPath(int nNode, int nEndNode, BOOL bWeight
)<BR>{<BR> if ( nNode < 0 || nNode >=
m_arrNodes.GetCount())<BR> return FALSE;</P>
<P> int i, j, nNodeNum;<BR> int nLink;<BR> byte*
pMark = NULL; // 处理标志数组<BR> nNodeNum =
m_arrNodes.GetCount();<BR> if ( nNodeNum == 0
)<BR> return TRUE;</P>
<P> pMark = new byte[nNodeNum];<BR> memset(pMark, 0,
nNodeNum);</P>
<P> // (1) 初始化<BR> // 初始化路径数组, 类的构造函数会将长度置为-1,
前趋结点为-1<BR> if(m_pPath)<BR> {<BR> delete
m_pPath;<BR> m_pPath = NULL;<BR> }<BR> m_pPath
= new NetPath[nNodeNum];</P>
<P> // 自身<BR> m_pPath[nNode].m_dLength =
0;<BR> m_pPath[nNode].m_nPreNode = nNode;</P>
<P> // 对于与该结点直接相连的点, 初始化路径长度为连接弧度的阻力<BR> NetNode* nd =
&(m_arrNodes.GetAt(m_arrNodes.FindIndex(nNode)));<BR> for (
i = 0; i<nd->m_arrLinks.GetCount(); i++
)<BR> {<BR> NetEdge ng =
nd->m_arrLinks.GetAt(nd->m_arrLinks.FindIndex(i));<BR> nLink
= ng.nLink;<BR> NetLink nl =
m_arrLinks.GetAt(m_arrLinks.FindIndex(nLink));<BR> if(nl.m_nFNode
== nNode )<BR> {<BR> // 路径长度,
正向<BR> m_pPath[nl.m_nTNode].m_dLength = bWeight ?
nl.m_fFromImp : nl.m_fLength;</P>
<P> // 前趋结点, 如果长度<0,
无前趋结点<BR> if ( m_pPath[nl.m_nTNode].m_dLength <
0 )<BR> m_pPath[nl.m_nTNode].m_nPreNode =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -