📄 利用vc+mo最短路径算法--gis开发.htm
字号:
0.00000001) <BR> { <BR> if(fabs(med)
<
0.00000001)<BR> {<BR> ptNearest->x =
Px ;<BR> ptNearest->y = Ay
;<BR> }<BR> else<BR> {<BR> ptNearest->y
= Py ;<BR> ptNearest->x = Ax
;<BR> }<BR> }<BR> else<BR> { <BR> k1
= (Ay - By) / ( Ax - Bx) ; <BR> k2 = -1.0 / k1
; <BR> b1 = Ay - k1 * Ax
;<BR> b2 = Py - k2 * Px ;<BR> S = (b2 - b1) /
(k1 - k2) ;<BR> ptNearest->x = S ;<BR> S =
k1 * S + b1 ;<BR> ptNearest->y = S
;<BR> }<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>//
得到最邻近的点<BR>void NetLine::GetNearestPoint(NetPoint point, NetPoint*
ptNearestPoint, <BR>
int* nSegmentIndex, double* dLeastDistance)<BR>{<BR> int
nPointNum = m_pCoords.GetCount(); <BR> double
dDistance;<BR> NetPoint ptTemp;<BR>
<BR> NetPoint firstPt =
m_pCoords.GetAt(m_pCoords.FindIndex(0));<BR> NetPoint secondPt
= m_pCoords.GetAt(m_pCoords.FindIndex(1));<BR> GetNearestPoint(
point, firstPt, secondPt, ptNearestPoint,
dLeastDistance);<BR> nSegmentIndex = 0 ;<BR> <BR> //
遍历每一条弧段来搜索最近的点<BR> int nIndex ;<BR> for(nIndex = 1 ;
nIndex<nPointNum-1 ; nIndex ++ )
<BR> { <BR> //
得到最近的点<BR> GetNearestPoint(point,
m_pCoords.GetAt(m_pCoords.FindIndex(0)),
<BR> m_pCoords.GetAt(m_pCoords.FindIndex(1)),
&ptTemp, &dDistance )
;<BR> <BR> //
比较最小的距离<BR> if( dDistance < *dLeastDistance
)<BR> {<BR> *dLeastDistance = dDistance
;<BR> ptNearestPoint->x = ptTemp.x;
<BR> ptNearestPoint->y =
ptTemp.y;<BR> *nSegmentIndex = nIndex
;<BR> }<BR> }<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>//
获得根据给定点分裂线得到的两个部分的比例, 但并不真正分裂线<BR>// 参数point: 给定点<BR>//
参数ptNearestPoint: 分裂线时的分裂点 (返回)<BR>// 参数dRatio: 起始结点部分的比例
(返回)<BR>BOOL NetLine::GetSplitRatioByNearestPoint(NetPoint point,
NetPoint* ptNearest,
<BR>
double* dRatio)<BR>{<BR> int nIndex = 0;<BR> double
dDistance = 0.0;<BR> <BR> int nPointNum =
m_pCoords.GetCount();<BR> //
首先得到最近的点和线段索引<BR> GetNearestPoint(point, ptNearest,
&nIndex, &dDistance );<BR> <BR> //
检查线上最近的点是否与首尾点相重合<BR> if( nIndex == 0
)<BR> {<BR> if( IsPtCoincide(*ptNearest,
m_pCoords.GetAt(m_pCoords.FindIndex(0))))<BR> {<BR> dRatio
= 0;<BR> return
true;<BR> }<BR> }</P>
<P> if( nIndex == nPointNum-2 )<BR> {<BR> if(
IsPtCoincide(*ptNearest,
m_pCoords.GetAt(<BR>
m_pCoords.FindIndex(nPointNum-1))))<BR> {<BR> *dRatio
= 1.0;<BR> return
true;<BR> }<BR> }<BR> <BR> //
计算分裂出来的第二条线的长度<BR> int nLoop;<BR> double dLength =
0;<BR> // 如果最近点与本线上的下一点不重合,则需将最近点计算在内<BR> if (
!IsPtCoincide(*ptNearest,
m_pCoords.GetAt(m_pCoords.FindIndex(nIndex+1))))<BR> {<BR> NetPoint
PostPoint =
m_pCoords.GetAt(m_pCoords.FindIndex(nIndex+1));<BR> dLength
+= sqrt( ( PostPoint.x - ptNearest->x ) * ( PostPoint.x -
ptNearest->x ) + <BR> ( PostPoint.y -
ptNearest->y ) * ( PostPoint.y - ptNearest->y
));<BR> }<BR> <BR> for( nLoop = nIndex+2;
nLoop<nPointNum; nLoop ++ )<BR> {<BR> NetPoint
CurPoint =
m_pCoords.GetAt(m_pCoords.FindIndex(nLoop));<BR> NetPoint
PrePoint =
m_pCoords.GetAt(m_pCoords.FindIndex(nLoop-1));<BR> dLength
+= sqrt( ( CurPoint.x - PrePoint.x ) * ( CurPoint.x - PrePoint.x ) +
<BR>
( PrePoint.y - PrePoint.y ) * ( PrePoint.y - PrePoint.y
));<BR> }<BR> <BR> *dRatio = 1.0 -
dLength / CalcLength();<BR> return
true;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>//
加入一个连接的弧段(调用前需确定弧段是连接在该点上的)<BR>BOOL NetNode::Add(int nLink, double
dAngle )<BR>{<BR> // 结点连接的弧段按角度排序<BR> int i =
0;<BR> for(i=0; i<m_arrLinks.GetCount(); i++
)<BR> {<BR> if(dAngle <
m_arrLinks.GetAt(m_arrLinks.FindIndex(i)).fAngle
)<BR> break;<BR> }<BR> <BR> NetEdge
pEdge;<BR> pEdge.nLink = nLink;<BR> pEdge.fAngle =
(float)dAngle;<BR> m_arrLinks.InsertBefore(m_arrLinks.FindIndex(i),
pEdge );<BR> <BR> return
true;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>//
删除一个已连接的弧段<BR>BOOL NetNode::Remove( int nLink
)<BR>{<BR> for(int i=0; i<m_arrLinks.GetCount(); i++
)<BR> {<BR> if ( nLink ==
m_arrLinks.GetAt(m_arrLinks.FindIndex(i)).nLink
)<BR> {<BR> m_arrLinks.RemoveAt(m_arrLinks.FindIndex(i));<BR> break;<BR> }<BR> }<BR> return
true;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>//
得到一个连接弧段的角度<BR>double NetNode::GetLinkAngle( int nLink
)<BR>{<BR> for(int i=0; i<m_arrLinks.GetCount(); i++
)<BR> {<BR> if ( nLink ==
m_arrLinks.GetAt(m_arrLinks.FindIndex(i)).nLink
)<BR> {<BR> return
m_arrLinks.GetAt(m_arrLinks.FindIndex(i)).fAngle;<BR> }<BR> }<BR> return
-1;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>//
构造函数<BR>NetLink::NetLink()<BR>{<BR> m_GeoID =
-1;<BR> m_nFNode = -1;<BR> m_nTNode =
-1;<BR> m_fLength = 0;<BR> m_fFromImp =
0;<BR> m_fToImp =
0;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>//
拷贝另一弧段的数据<BR>void NetLink::Copy( NetLink link
)<BR>{<BR> m_GeoID = link.m_GeoID;<BR> m_nFNode =
link.m_nFNode;<BR> m_nTNode = link.m_nTNode;<BR> m_fLength
= link.m_fLength;<BR> m_fFromImp =
link.m_fFromImp;<BR> m_fToImp =
link.m_fToImp;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>//
判断两弧段是否是同一弧段<BR>BOOL NetLink::IsEqual( NetLink link
)<BR>{<BR> return m_GeoID ==
link.m_GeoID;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>BOOL
NetLinkBackup::Add(int nSeg, double dRatio)<BR>{<BR> int i =
0;<BR> for(i = 0; i<m_arrSegs.GetCount(); i++
)<BR> {<BR> if (dRatio <
m_arrSegs.GetAt(m_arrSegs.FindIndex(i)).dRatio
)<BR> break;<BR> }<BR> <BR> NetLinkSeg
pSeg;<BR> pSeg.nSegID = nSeg;<BR> pSeg.dRatio =
dRatio;<BR> m_arrSegs.InsertBefore(m_arrSegs.FindIndex(i),
pSeg);<BR> <BR> return
true;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>CNetLayer::CNetLayer(CMoMapLayer
layer)<BR>{<BR> m_nLinkNum = 0;<BR> m_nNodeNum =
0;<BR> m_pPath = NULL;<BR> m_layer =
layer;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>CNetLayer::~CNetLayer(void)<BR>{<BR> if(m_pPath)<BR> {<BR> delete
m_pPath;<BR> m_pPath =
NULL;<BR> }<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>BOOL
CNetLayer::ReadNetTable()<BR>{<BR> CMainFrame* pMainWnd =
(CMainFrame*)AfxGetMainWnd();<BR> CDaoDatabase* tmpDB = new
CDaoDatabase;<BR> try<BR> {<BR> tmpDB->Open(pMainWnd->m_environment.m_szDBName);<BR> }<BR> catch
(CDaoException*
e)<BR> {<BR> DisplayDaoException(e);<BR> delete
tmpDB;<BR> e->Delete();<BR> return
FALSE;<BR> }</P>
<P> CDaoRecordset
rs(tmpDB); <BR> try<BR> {<BR> CString
szSQL = "Select * From AAT Order By
ARCID";<BR> rs.Open(dbOpenDynaset,szSQL);</P>
<P> COleVariant
var;<BR> while(!rs.IsEOF())<BR> {<BR> NetLink
lk; <BR> var =
rs.GetFieldValue("GeoID");<BR> lk.m_GeoID =
V_I4(&var);<BR> var =
rs.GetFieldValue("FNODE");<BR> lk.m_nFNode =
V_I4(&var);<BR> var =
rs.GetFieldValue("TNODE");<BR> lk.m_nTNode =
V_I4(&var);<BR> var =
rs.GetFieldValue("LENGTH");<BR> lk.m_fLength =
V_R8(&var);<BR> var =
rs.GetFieldValue("FIMP");<BR> lk.m_fFromImp =
V_R8(&var); <BR> var =
rs.GetFieldValue("TIMP");<BR> lk.m_fToImp =
V_R8(&var); <BR> m_arrLinks.AddTail(lk );</P>
<P> rs.MoveNext();<BR> }<BR> rs.Close();</P>
<P> szSQL = "Select * From NAT Order By
NODEID";<BR> rs.Open(dbOpenDynaset,szSQL);<BR> while(!rs.IsEOF())<BR> {<BR> int
nNode, nLink;<BR> double x, y,
dAngle;<BR> CString szArcID,
szAngle;<BR>
<BR> var =
rs.GetFieldValue("NODEID");<BR> nNode =
V_I4(&var);<BR> var =
rs.GetFieldValue("X");<BR> x =
V_R8(&var);<BR> var =
rs.GetFieldValue("Y");<BR> y =
V_R8(&var);<BR> var =
rs.GetFieldValue("ARCID");<BR> szArcID =
V_BSTRT(&var);<BR> var =
rs.GetFieldValue("ANGLE");<BR> szAngle =
V_BSTRT(&var); <BR> NetNode
node(x,y); <BR>
<BR> int nPos;<BR> CString
szTemp;<BR> while ( (nPos = szArcID.Find( ';' )) !=
-1 )<BR> {<BR> szTemp =
szArcID.Left(nPos );<BR> nLink = atoi( szTemp
);<BR> szArcID =
szArcID.Right(szArcID.GetLength() - nPos - 1
);<BR>
<BR> nPos = szAngle.Find( ';'
);<BR> if ( nPos == -1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -