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

📄 利用vc+mo最短路径算法--gis开发.htm

📁 Mapobjecst最短路径的计算方法,
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            弧段ID(GeoID)<BR>&nbsp;int 
            m_nFNode;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 
            起始结点(数组下标索引)<BR>&nbsp;int 
            m_nTNode;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 
            终止结点(数组下标索引)<BR>&nbsp;double m_fLength;&nbsp;&nbsp;&nbsp; // 
            长度<BR>&nbsp;double m_fFromImp;&nbsp;&nbsp; // 正向阻力(阻力系数*长度 或 
            (1+阻力系数)*长度)<BR>&nbsp;double m_fToImp;&nbsp;&nbsp;&nbsp;&nbsp; // 
            逆向阻力</P>
            <P>public:<BR>&nbsp;NetLink();<BR>&nbsp;void Copy( NetLink link 
            );&nbsp;&nbsp;&nbsp; // 拷贝操作<BR>&nbsp;BOOL IsEqual( NetLink link ); 
            // 
            判断是否相等<BR>};<BR>//-----------------------------------------------------------------------------------------<BR>// 
            用于分裂操作的结构<BR>struct 
            NetLinkSeg<BR>{<BR>&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp; 
            nSegID;&nbsp;&nbsp; // 分裂点后面的部分的弧段索引(数组下标索引)<BR>&nbsp;double&nbsp; 
            dRatio;&nbsp;&nbsp; // 
            分裂点前面的到起始结点部分的比例<BR>};<BR>//-----------------------------------------------------------------------------------------<BR>// 
            用于备份弧段的类<BR>class 
            NetLinkBackup<BR>{<BR>public:<BR>&nbsp;int&nbsp;&nbsp;&nbsp;m_nIndex;&nbsp;// 
            弧段的索引<BR>&nbsp;NetLink&nbsp;&nbsp;m_Link;&nbsp;&nbsp;// 
            备份的弧段对象<BR>&nbsp;CList&lt;NetLinkSeg, NetLinkSeg&amp;&gt; m_arrSegs; 
            // 该弧段被多次分割的比例列表</P>
            <P>public:<BR>&nbsp;NetLinkBackup()<BR>&nbsp;{<BR>&nbsp;&nbsp;m_nIndex 
            = -1;<BR>&nbsp;}</P>
            <P>&nbsp;void operator=(const NetLinkBackup&amp; netLink) 
            <BR>&nbsp;{<BR>&nbsp;&nbsp;m_nIndex = 
            netLink.m_nIndex;<BR>&nbsp;&nbsp;m_Link = 
            netLink.m_Link;<BR>&nbsp;&nbsp;for(int i=0; 
            i&lt;netLink.m_arrSegs.GetCount(); 
            i++)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;NetLinkSeg nLS = 
            netLink.m_arrSegs.GetAt(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            netLink.m_arrSegs.FindIndex(i));<BR>&nbsp;&nbsp;&nbsp;m_arrSegs.AddTail(nLS);<BR>&nbsp;&nbsp;}<BR>&nbsp;}</P>
            <P>&nbsp;BOOL Add( int nSeg, double dRatio 
            );<BR>};<BR>//-----------------------------------------------------------------------------------------<BR>// 
            定义网络上的一条路径<BR>class 
            NetPath<BR>{<BR>public:<BR>&nbsp;double&nbsp;m_dLength;&nbsp; // 
            该点到给定点的最短路径长度, -1表示不连通<BR>&nbsp;int&nbsp;&nbsp;m_nPreNode;&nbsp;// 
            该点在该路径上的前趋结点<BR>public:<BR>&nbsp;NetPath()<BR>&nbsp;{<BR>&nbsp;&nbsp;m_dLength 
            = -1;<BR>&nbsp;&nbsp;m_nPreNode = 
            -1;<BR>&nbsp;}<BR>};<BR>//-----------------------------------------------------------------------------------------<BR>class 
            CNetLayer<BR>{<BR>private:<BR>&nbsp;CList&lt;NetLink, 
            NetLink&amp;&gt; m_arrLinks;&nbsp;// 弧段表<BR>&nbsp;CList&lt;NetNode, 
            NetNode&amp;&gt; m_arrNodes;&nbsp;// 
            节点表<BR>&nbsp;CList&lt;NetLinkBackup, NetLinkBackup&amp;&gt; 
            m_arrLinkBackups;&nbsp;// 弧段备份表<BR>&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;int&nbsp;&nbsp;m_nLinkNum;&nbsp;&nbsp;// 原始弧段数目(网络拓扑建立完成后) 
            <BR>&nbsp;int&nbsp;&nbsp;m_nNodeNum;&nbsp;&nbsp;// 原始结点数目(网络拓扑建立完成后) 
            <BR>&nbsp;NetPath* m_pPath;&nbsp;&nbsp;// 
            某一个点到所有点的最短路径<BR>&nbsp;CMoMapLayer&nbsp;m_layer;&nbsp;&nbsp;&nbsp; 
            // 图层对象<BR>public:<BR>&nbsp;CNetLayer(CMoMapLayer 
            layer);<BR>&nbsp;~CNetLayer(void);</P>
            <P>&nbsp;BOOL ReadNetTable();<BR>&nbsp;BOOL PathAnalysis(double x1, 
            double y1, double x2, double y2, CList&lt;double, double&amp;&gt;* 
            path );<BR>&nbsp;BOOL LoadStops(CList&lt;NetPoint, 
            NetPoint&amp;&gt;* pPoints, CList&lt;int, int&amp;&gt;* 
            pNodes);<BR>&nbsp;BOOL UpdateLinkNodeTable( int nLineID, NetPoint 
            ptNearest, double dRatio, int* nNewNode );<BR>&nbsp;int GetNode(int 
            nLineID, int* nFNode, int* nTNode );<BR>&nbsp;double Path(int 
            nBeginNode, int nEndNode, CList&lt;int, int&amp;&gt;* pNodes, BOOL 
            bWeight);<BR>&nbsp;BOOL CalcPath( int nNode, int nEndNode , BOOL 
            bWeight );<BR>&nbsp;double GetConnectedDistance( int nNode1, int 
            nNode2, BOOL bWeight );<BR>&nbsp;BOOL CreateResultPath(CList&lt;int, 
            int&amp;&gt;* pNodes, NetLine* line, BOOL bWeight);<BR>&nbsp;int 
            IsConnectedDirectly(int nNode1, int nNode2, int* nLink, double* 
            dDistance, BOOL bWeight);<BR>&nbsp;BOOL UnloadStops();<BR>};<BR></P>
            <P>//***************************************************************************//</P>
            <P>//netlayer.cpp文件</P>
            <P>#i nclude "StdAfx.h"<BR>#i nclude "netlayer.h"<BR>#i nclude 
            "MoRecordset.h"<BR>#i nclude &lt;math.h&gt;<BR>#i nclude 
            "MoLine.h"<BR>#i nclude "MoField.h"<BR>#i nclude "MoFields.h"<BR>#i 
            nclude "MoPoints.h"<BR>#i nclude "MoPoint.h"<BR>#i nclude 
            "MoParts.h"<BR>#i nclude "MainFrm.h"<BR>#i nclude "AppApi.h"</P>
            <P>//-----------------------------------------------------------------------------------------<BR>NetLine::NetLine(CMoMapLayer 
            layer)<BR>{<BR>&nbsp;m_layer = 
            layer;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>NetLine::~NetLine()<BR>{<BR>&nbsp;m_pCoords.RemoveAll();<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>// 
            计算线的几何长度<BR>double 
            NetLine::CalcLength()<BR>{<BR>&nbsp;double&nbsp;dLength = 0.0 
            ;&nbsp;&nbsp;// 保存计算出的线几何长度的结果<BR>&nbsp;int&nbsp;&nbsp;loop 
            ;&nbsp;&nbsp;&nbsp;&nbsp;// 保存循环计数<BR>&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;// 检查线的有效性<BR>&nbsp;if ( m_pCoords.GetCount() &lt; 2 
            )<BR>&nbsp;&nbsp;return 0.0 ;<BR>&nbsp;// 
            计算线的几何长度<BR>&nbsp;double&nbsp;dist = 0.0 ;<BR>&nbsp;for ( loop = 1 ; 
            loop&lt;m_pCoords.GetCount(); loop ++ 
            )<BR>&nbsp;{<BR>&nbsp;&nbsp;NetPoint PrePoint = 
            (NetPoint)m_pCoords.GetAt(m_pCoords.FindIndex(loop 
            -1));<BR>&nbsp;&nbsp;NetPoint CurPoint = 
            (NetPoint)m_pCoords.GetAt(m_pCoords.FindIndex(loop));<BR>&nbsp;&nbsp;dist 
            = sqrt( (PrePoint.x - CurPoint.x) * (PrePoint.x - CurPoint.x) 
            +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            (PrePoint.y - CurPoint.y) * (PrePoint.y - CurPoint.y)) 
            ;<BR>&nbsp;&nbsp;dLength += dist 
            ;<BR>&nbsp;}<BR>&nbsp;<BR>&nbsp;return dLength 
            ;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>// 
            通过线的id得到线数据<BR>BOOL NetLine::GetLineData(int id)<BR>{<BR>&nbsp;char 
            buf[20];<BR>&nbsp;itoa(id, buf, 10);<BR>&nbsp;CMoRecordset 
            rs;<BR>&nbsp;rs = m_layer.SearchExpression("GeoID = " + 
            CString(buf));<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;if 
            (!rs)<BR>&nbsp;&nbsp;return FALSE;<BR>&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;rs.MoveFirst(); <BR>&nbsp;if 
            (rs.GetEof())<BR>&nbsp;&nbsp;return FALSE;<BR>&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;CMoLine 
            line(rs.GetFields().Item(COleVariant("shape")).GetValue().pdispVal);<BR>&nbsp;CMoPoints 
            pts = line.GetParts().Item(COleVariant(long(0), 
            VT_I4));<BR>&nbsp;m_pCoords.RemoveAll();<BR>&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;for (long i = 0; i&lt;pts.GetCount(); i 
            ++)<BR>&nbsp;{<BR>&nbsp;&nbsp;NetPoint pt;<BR>&nbsp;&nbsp;CMoPoint 
            moPt(pts.Item(COleVariant(i, VT_I4)));<BR>&nbsp;&nbsp;pt.x = 
            moPt.GetX();<BR>&nbsp;&nbsp;pt.y = 
            moPt.GetY();<BR>&nbsp;&nbsp;m_pCoords.AddTail(pt); 
            <BR>&nbsp;}<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;return 
            true;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>// 
            得到距离某点最近的线段,返回该线段的id<BR>int NetLine::GetNearestLineData( double x, 
            double y)<BR>{<BR>&nbsp;CMoRecordset rs = 
            m_layer.GetRecords();<BR>&nbsp;CMoPoint 
            pt;<BR>&nbsp;pt.CreateDispatch(_T("MapObjects2.Point"));<BR>&nbsp;pt.SetX(x);<BR>&nbsp;pt.SetY(y);</P>
            <P>&nbsp;double&nbsp;dDist = 9999999;<BR>&nbsp;int&nbsp;&nbsp;id = 
            -1;<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;rs.MoveFirst(); 
            <BR>&nbsp;while(!rs.GetEof())<BR>&nbsp;{<BR>&nbsp;&nbsp;CMoFields 
            fields(rs.GetFields());<BR>&nbsp;&nbsp;CMoField 
            shapeField(fields.Item(COleVariant("shape")));<BR>&nbsp;&nbsp;CMoLine 
            line(shapeField.GetValue().pdispVal);<BR>&nbsp;&nbsp;double d = 
            line.DistanceTo(pt);&nbsp;&nbsp; 
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;if (dDist &gt; 
            d)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;dDist = 
            d;<BR>&nbsp;&nbsp;&nbsp;CString szValue = 
            fields.Item(COleVariant("Geoid")).GetValueAsString();<BR>&nbsp;&nbsp;&nbsp;id 
            = atoi(szValue);<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;rs.MoveNext(); 
            <BR>&nbsp;}<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;if (id != 
            -1)<BR>&nbsp;{<BR>&nbsp;&nbsp;if 
            (!GetLineData(id))<BR>&nbsp;&nbsp;&nbsp;return 
            -1;<BR>&nbsp;}<BR>&nbsp;return 
            id;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>// 
            判断两点是否重合<BR>BOOL NetLine::IsPtCoincide( NetPoint ptFirst, NetPoint 
            ptSecond)<BR>{<BR>&nbsp;if ( fabs(ptFirst.x - ptSecond.x ) &lt;= 
            0.00000001 <BR>&nbsp;&nbsp;&amp;&amp; fabs(ptFirst.y - ptSecond.y ) 
            &lt;= 0.00000001 )<BR>&nbsp;&nbsp;return TRUE;<BR>&nbsp;return 
            FALSE;<BR>}<BR>//-----------------------------------------------------------------------------------------<BR>// 
            得到最邻近的点<BR>void NetLine::GetNearestPoint(NetPoint ptP, NetPoint ptA, 
            NetPoint ptB, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            NetPoint* ptNearest, double* dDistance )<BR>{<BR>&nbsp;double 
            Px,Py,Ax,Ay,Bx,By;<BR>&nbsp;double AB2,PA2,PB2,AB,PA,PB,S,AREA 
            ;<BR>&nbsp;double med,med1,k1,k2,b1,b2 ;<BR>&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;*dDistance = 0;<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;if ( 
            IsPtCoincide(ptA,ptB) )<BR>&nbsp;{<BR>&nbsp;&nbsp;ptNearest-&gt;x = 
            ptA.x;<BR>&nbsp;&nbsp;ptNearest-&gt;y = ptA.y;<BR>&nbsp;&nbsp;return 
            ;<BR>&nbsp;}<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;Px = ptP.x 
            ;<BR>&nbsp;Py = ptP.y ;<BR>&nbsp;Ax = ptA.x ;<BR>&nbsp;Ay = ptA.y 
            ;<BR>&nbsp;Bx = ptB.x ;<BR>&nbsp;By = ptB.y ;<BR>&nbsp;AB2 = (Ax - 
            Bx) * (Ax - Bx) + (Ay - By) * (Ay - By) ;<BR>&nbsp;PB2 = (Px - Bx) * 
            (Px - Bx) + (Py - By) * (Py - By) ;<BR>&nbsp;PA2 = (Ax - Px) * (Ax - 
            Px) + (Ay - Py) * (Ay - Py) ;&nbsp;</P>
            <P>&nbsp;if(PA2 + AB2 &lt; PB2 || AB2 + PB2 &lt; 
            PA2)&nbsp;<BR>&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;if(PA2 &gt; 
            PB2)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;med = PB2 
            ;<BR>&nbsp;&nbsp;&nbsp;ptNearest-&gt;x = Bx 
            ;<BR>&nbsp;&nbsp;&nbsp;ptNearest-&gt;y = By 
            ;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;else<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;med 
            = PA2 ;<BR>&nbsp;&nbsp;&nbsp;ptNearest-&gt;x = Ax 
            ;<BR>&nbsp;&nbsp;&nbsp;ptNearest-&gt;y = Ay 
            ;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;med = sqrt(med) 
            ;&nbsp;<BR>&nbsp;&nbsp;*dDistance = med ;<BR>&nbsp;&nbsp;return 
            ;<BR>&nbsp;}<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;if (PA2 &lt; 0.00000001 
            || PB2 &lt; 0.00000001)<BR>&nbsp;{<BR>&nbsp;&nbsp;if(PA2 &lt; 
            0.00000001)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;med = sqrt(PA2) 
            ;<BR>&nbsp;&nbsp;&nbsp;*dDistance = med 
            ;<BR>&nbsp;&nbsp;&nbsp;ptNearest-&gt;x = Ax 
            ;<BR>&nbsp;&nbsp;&nbsp;ptNearest-&gt;y = Ay 
            ;<BR>&nbsp;&nbsp;&nbsp;return ;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;else 
            <BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;med = sqrt(PB2) 
            ;<BR>&nbsp;&nbsp;&nbsp;*dDistance = med 
            ;<BR>&nbsp;&nbsp;&nbsp;ptNearest-&gt;x = Bx 
            ;<BR>&nbsp;&nbsp;&nbsp;ptNearest-&gt;y = By 
            ;<BR>&nbsp;&nbsp;&nbsp;return 
            ;<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;AB = 
            sqrt(AB2) ;<BR>&nbsp;PA = sqrt(PA2) ;<BR>&nbsp;PB = sqrt(PB2) 
            ;<BR>&nbsp;S = (AB + PA + PB) / 2.0 ;<BR>&nbsp;AREA = S 
            ;<BR>&nbsp;AREA *= (S - PA) ;<BR>&nbsp;AREA *= (S - PB) 
            ;<BR>&nbsp;AREA *= (S - AB) ;<BR>&nbsp;AREA = sqrt(AREA) 
            ;<BR>&nbsp;med = (2.0 * AREA) / AB ;<BR>&nbsp;*dDistance = med 
            ;<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;med = Ay - By ;<BR>&nbsp;med1 = Ax 
            - Bx ;<BR>&nbsp;if(fabs(med) &lt; 0.00000001 || fabs(med1) &lt; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -