📄 netlayer.cpp
字号:
}
CDaoRecordset rs(tmpDB);
try
{
CString szSQL = "Select * From AAT Order By ARCID";
rs.Open(dbOpenDynaset,szSQL);
COleVariant var;
while(!rs.IsEOF())
{
NetLink lk;
var = rs.GetFieldValue("GeoID");
lk.m_GeoID = V_I4(&var);
var = rs.GetFieldValue("FNODE");
lk.m_nFNode = V_I4(&var);
var = rs.GetFieldValue("TNODE");
lk.m_nTNode = V_I4(&var);
var = rs.GetFieldValue("LENGTH");
lk.m_fLength = V_R8(&var);
var = rs.GetFieldValue("FIMP");
lk.m_fFromImp = V_R8(&var);
var = rs.GetFieldValue("TIMP");
lk.m_fToImp = V_R8(&var);
m_arrLinks.AddTail(lk );
rs.MoveNext();
}
rs.Close();
szSQL = "Select * From NAT Order By NODEID";
rs.Open(dbOpenDynaset,szSQL);
while(!rs.IsEOF())
{
int nNode, nLink;
double x, y, dAngle;
CString szArcID, szAngle;
var = rs.GetFieldValue("NODEID");
nNode = V_I4(&var);
var = rs.GetFieldValue("X");
x = V_R8(&var);
var = rs.GetFieldValue("Y");
y = V_R8(&var);
var = rs.GetFieldValue("ARCID");
szArcID = V_BSTRT(&var);
var = rs.GetFieldValue("ANGLE");
szAngle = V_BSTRT(&var);
NetNode node(x,y);
int nPos;
CString szTemp;
while ( (nPos = szArcID.Find( ';' )) != -1 )
{
szTemp = szArcID.Left(nPos );
nLink = atoi( szTemp );
szArcID = szArcID.Right(szArcID.GetLength() - nPos - 1 );
nPos = szAngle.Find( ';' );
if ( nPos == -1 )
continue;
szTemp = szAngle.Left(nPos );
dAngle = atof(szTemp );
szAngle = szAngle.Right(szAngle.GetLength() - nPos - 1 );
node.Add( nLink, dAngle );
}
m_arrNodes.AddTail( node );
rs.MoveNext();
}
rs.Close();
}
catch (CDaoException* e)
{
DisplayDaoException(e);
delete tmpDB;
e->Delete();
return FALSE;
}
if(tmpDB)
{
if(tmpDB->IsOpen())
{
tmpDB->Close();
}
delete tmpDB;
tmpDB = NULL;
}
return TRUE;
}
//-----------------------------------------------------------------------------------------
BOOL CNetLayer::PathAnalysis(double x1, double y1, double x2, double y2,
CList<double, double&>* path )
{
NetPoint pt1( x1, y1 );
NetPoint pt2( x2, y2 );
CList<NetPoint, NetPoint&> points;
points.AddTail(pt1);
points.AddTail(pt2);
CList<int, int&> stops;
if ( !LoadStops(&points, &stops ) )
return FALSE;
if ( stops.GetCount() != 2 )
return FALSE;
CList<int, int&> nodes;
double dDistance;
// 得到起点
int nFirst = stops.GetAt(stops.FindIndex(0));
// 得到终点
int nSecnd = stops.GetAt(stops.FindIndex(1));
// 计算距离
dDistance = Path(nFirst, nSecnd, &nodes, FALSE);
if ( dDistance < 0 )
return FALSE;
NetLine* line;
line = new NetLine(m_layer);
// 根据节点创建线对象
if ( !CreateResultPath(&nodes, line, FALSE) )
return FALSE;
for ( int i=0; i<line->m_pCoords.GetCount(); i++ )
{
NetPoint np = line->m_pCoords.GetAt(line->m_pCoords.FindIndex(i));
path->AddTail(np.x );
path->AddTail(np.y );
}
// 释放资源
UnloadStops();
if(line)
{
delete line;
line = NULL;
}
return true;
}
//-----------------------------------------------------------------------------------------
BOOL CNetLayer::LoadStops(CList<NetPoint, NetPoint&>* pPoints,
CList<int, int&>* pNodes )
{
int nLineID;
int i, nNewNode;
NetPoint* ptNearest = NULL;
ptNearest = new NetPoint();
double dRatio;
// 先清空站点表
int nNum = pPoints->GetCount();
for ( i = 0; i < nNum; i++ )
{
// 计算距离该点最近的线
NetLine line(m_layer);
NetPoint np = pPoints->GetAt(pPoints->FindIndex(i));
nLineID = line.GetNearestLineData( np.x, np.y);
if ( nLineID == -1 )
{
return false;
}
/* 计算该点分裂该线的位置, 并不实际分裂该线,
只是计算分裂的比例, 用于更改弧段表和结点表 */
dRatio = 0;
line.GetSplitRatioByNearestPoint (np, ptNearest, &dRatio );
// 更新弧段表和结点表
UpdateLinkNodeTable( nLineID, *ptNearest, dRatio, &nNewNode );
if ( pNodes->GetCount() > 0 )
{
int nCount = pNodes->GetCount() - 1;
if (pNodes->GetAt(pNodes->FindIndex(nCount)) == nNewNode )
continue;
}
pNodes->AddTail(nNewNode );
}
// 填充需要返回的结点数组
if ( pNodes->GetCount() == 0 )
{
pNodes = NULL;
return FALSE;
}
if(ptNearest)
{
delete ptNearest;
ptNearest = NULL;
}
return TRUE;
}
//-----------------------------------------------------------------------------------------
BOOL CNetLayer::UpdateLinkNodeTable(int nLineID, NetPoint ptNearest,
double dRatio, int* nNewNode )
{
int i, j;
bool bFound;
double dRatio2;
int nCurLink, nNewLink;
int nCurFNode, nCurTNode;
*nNewNode = -1;
// 与某条弧段的首点或者位点重合, 不需要更改弧段表和结点表
if ( fabs(dRatio) < 0.00000001 )
{
// 首点
nCurLink = GetNode( nLineID, &nCurFNode, &nCurTNode );
*nNewNode = nCurFNode;
return TRUE;
}
else if ( fabs(1-dRatio) < 0.00000001 )
{
// 尾点
nCurLink = GetNode( nLineID, &nCurFNode, &nCurTNode );
*nNewNode = nCurTNode;
return TRUE;
}
bFound = FALSE;
for ( i=0; i<m_arrLinkBackups.GetCount(); i++ )
{
NetLinkBackup* nl = &(m_arrLinkBackups.GetAt(
m_arrLinkBackups.FindIndex(i)));
if ( nl->m_Link.m_GeoID == nLineID )
{
bFound = TRUE;
break;
}
}
if ( bFound )
{
NetLinkBackup* nl = &(m_arrLinkBackups.GetAt(
m_arrLinkBackups.FindIndex(i)));
for ( j = 0; j < nl->m_arrSegs.GetCount(); j++ )
{
// 如果新点与原有的点重合, 则直接返回原来的点
NetLinkSeg nlS = nl->m_arrSegs.GetAt(nl->m_arrSegs.FindIndex(j));
double r = nlS.dRatio;
if ( fabs( r - dRatio) < 0.00000001 )
{
if ( j == 0 )
{
nCurLink = GetNode( nLineID, &nCurFNode, &nCurTNode );
*nNewNode = nCurTNode;
return true;
}
else
{
NetLinkSeg nlSPre = nl->m_arrSegs.GetAt(
nl->m_arrSegs.FindIndex(j-1));
nCurLink = nlSPre.nSegID;
*nNewNode = m_arrLinks.GetAt(
m_arrLinks.FindIndex(nCurLink)).m_nTNode;
return TRUE;
}
}
// 没有重合的点
r = nlS.dRatio;
if ( dRatio < r )
break;
}
if ( j == 0 )
{
// 第一段
nCurLink = GetNode( nLineID, &nCurFNode, &nCurTNode );
if ( nCurLink == -1 )
return false;
// 更新结点表
nNewLink = m_arrLinks.GetCount();
NetNode pNode( ptNearest.x, ptNearest.y );
pNode.Add( nNewLink, -1 );
pNode.Add( nCurLink, -1 );
m_arrNodes.AddTail( pNode );
NetNode* nd = &(m_arrNodes.GetAt(m_arrNodes.FindIndex(nCurTNode)));
nd->Remove( nCurLink );
nd->Add( nNewLink, -1 );
// 更新弧段表
*nNewNode = m_arrNodes.GetCount() - 1;
NetLinkSeg nlS = nl->m_arrSegs.GetAt(nl->m_arrSegs.FindIndex(0));
dRatio2 = nlS.dRatio;
NetLink pLink;
pLink.m_GeoID = nLineID;
pLink.m_nFNode = *nNewNode;
pLink.m_nTNode = m_arrLinks.GetAt(
m_arrLinks.FindIndex(nlS.nSegID)).m_nFNode;
NetLink* oldLink = &(m_arrLinks.GetAt(
m_arrLinks.FindIndex(nCurLink)));
pLink.m_fLength = (float)(oldLink->m_fLength * ( dRatio2 - dRatio ));
pLink.m_fFromImp = (float)(oldLink->m_fFromImp * ( dRatio2 - dRatio ));
pLink.m_fToImp = (float)(oldLink->m_fToImp * ( dRatio2 - dRatio ));
m_arrLinks.AddTail( pLink );
oldLink->m_nTNode = *nNewNode;
oldLink->m_fLength = (float) (oldLink->m_fLength * dRatio);
oldLink->m_fFromImp = (float) (oldLink->m_fFromImp * dRatio);
oldLink->m_fToImp = (float) (oldLink->m_fToImp* dRatio);
nl->Add( nNewLink, dRatio );
}
else if ( j == nl->m_arrSegs.GetCount())
{
// 最后一段
NetLinkSeg nlS = nl->m_arrSegs.GetAt(nl->m_arrSegs.FindIndex(j-1));
nCurLink = nlS.nSegID;
nCurFNode = m_arrLinks.GetAt(
m_arrLinks.FindIndex(nCurLink)).m_nFNode;
nCurTNode = m_arrLinks.GetAt(
m_arrLinks.FindIndex(nCurLink)).m_nTNode;
// 更新结点表
nNewLink = m_arrLinks.GetCount();
NetNode pNode( ptNearest.x, ptNearest.y );
pNode.Add( nNewLink, -1 );
pNode.Add( nCurLink, -1 );
m_arrNodes.AddTail( pNode );
NetNode* netNode = &(m_arrNodes.GetAt(
m_arrNodes.FindIndex(nCurTNode)));
// 最后一段保留原角度
double dAngle = netNode->GetLinkAngle( nCurLink );
netNode->Remove( nCurLink );
netNode->Add( nNewLink, dAngle );
// 更新弧段表
*nNewNode = m_arrNodes.GetCount() - 1;
NetLink pLink;
pLink.m_GeoID = nLineID;
pLink.m_nFNode = *nNewNode;
pLink.m_nTNode = nCurTNode;
NetLink nl = m_arrLinks.GetAt(m_arrLinks.FindIndex(i));
pLink.m_fLength = (float) (nl.m_fLength * ( 1 - dRatio ));
pLink.m_fFromImp = (float)(nl.m_fFromImp * ( 1 - dRatio ));
pLink.m_fToImp = (float)(nl.m_fToImp * ( 1 - dRatio ));
m_arrLinks.AddTail( pLink );
dRatio2 = nlS.dRatio;
NetLink* nlk = &(m_arrLinks.GetAt(m_arrLinks.FindIndex(nCurLink)));
nlk->m_nTNode = *nNewNode;
nlk->m_fLength = (float) (nlk->m_fLength * ( dRatio - dRatio2) );
nlk->m_fFromImp = (float) (nlk->m_fFromImp * ( dRatio - dRatio2) );
nlk->m_fToImp = (float) (nlk->m_fToImp* ( dRatio - dRatio2) );
m_arrLinkBackups.GetAt(m_arrLinkBackups.FindIndex(i)).Add(
nNewLink, dRatio );
}
else
{
// 中间某一段
NetLink* nlk = &(m_arrLinks.GetAt(m_arrLinks.FindIndex(nCurLink)));
NetLinkBackup* nlBp = &(m_arrLinkBackups.GetAt(m_arrLinkBackups.FindIndex(i)));
NetLinkSeg nlS = nlBp->m_arrSegs.GetAt(nlBp->m_arrSegs.FindIndex(j-1));
nCurLink = nlS.nSegID;
nCurFNode = nlk->m_nFNode;
nCurTNode = nlk->m_nTNode;
// 更新节点表
nNewLink = m_arrLinks.GetCount();
NetNode pNode(ptNearest.x, ptNearest.y );
pNode.Add( nNewLink, -1 );
pNode.Add( nCurLink, -1 );
m_arrNodes.AddTail( pNode );
NetNode* pNd = &(m_arrNodes.GetAt(
m_arrNodes.FindIndex(nCurTNode)));
pNd->Remove( nCurLink );
pNd->Add( nNewLink, -1 );
// 更新弧段表
*nNewNode = m_arrNodes.GetCount() - 1;
NetLinkSeg nlSPt = nlBp->m_arrSegs.GetAt(nlBp->m_arrSegs.FindIndex(j));
dRatio2 = nlSPt.dRatio;
NetLink pLink;
pLink.m_GeoID = nLineID;
pLink.m_nFNode = *nNewNode;
pLink.m_nTNode = nCurTNode;
NetLink nlkI = m_arrLinks.GetAt(m_arrLinks.FindIndex(i));
pLink.m_fLength = (float)(nlkI.m_fLength * ( dRatio2 - dRatio ));
pLink.m_fFromImp = (float)(nlkI.m_fFromImp * ( dRatio2 - dRatio ));
pLink.m_fToImp = (float)(nlkI.m_fToImp * ( dRatio2 - dRatio ));
m_arrLinks.AddTail( pLink );
dRatio2 = nlS.dRatio;
nlk->m_nTNode = *nNewNode;
nlk->m_fLength = (float)(nlk->m_fLength * ( dRatio - dRatio2) );
nlk->m_fFromImp = (float)(nlk->m_fFromImp * ( dRatio - dRatio2) );
nlk->m_fToImp = (float)(nlk->m_fToImp* ( dRatio - dRatio2) );
m_arrLinkBackups.GetAt(m_arrLinkBackups.FindIndex(i)).Add(
nNewLink, dRatio );
}
}
else
{
nCurLink = GetNode( nLineID, &nCurFNode, &nCurTNode );
if ( nCurLink == -1 )
return FALSE;
nNewLink = m_arrLinks.GetCount();
NetLink* nlk = &(m_arrLinks.GetAt(m_arrLinks.FindIndex(nCurLink)));
// 备份
NetLinkBackup pBackup;
pBackup.m_nIndex = nCurLink;
pBackup.m_Link.Copy(*nlk);
pBackup.Add( nNewLink, dRatio );
m_arrLinkBackups.AddTail( pBackup );
// 更新结点表
NetNode pNode( ptNearest.x, ptNearest.y );
pNode.Add( nNewLink, -1 );
pNode.Add( nCurLink, -1 );
m_arrNodes.AddTail( pNode );
NetNode* pTempNd = &(m_arrNodes.GetAt(
m_arrNodes.FindIndex(nCurTNode)));
// 最后一段保留原角度
double dAngle = pTempNd->GetLinkAngle( nCurLink );
int nTNode = m_arrLinks.GetAt(m_arrLinks.FindIndex(nCurLink)).m_nTNode;
NetNode* pNd = &(m_arrNodes.GetAt(m_arrNodes.FindIndex(nTNode)));
pNd->Remove( nCurLink );
pNd->Add( nNewLink, dAngle );
NetNode* pNd1 = &(m_arrNodes.GetAt(m_arrNodes.FindIndex(nTNode)));
// 更新弧段表
*nNewNode = m_arrNodes.GetCount() - 1;
NetLink pLink;
pLink.m_GeoID = nLineID;
pLink.m_nFNode = *nNewNode;
pLink.m_nTNode = nlk->m_nTNode;
pLink.m_fLength = (float)(nlk->m_fLength * ( 1 - dRatio ));
pLink.m_fFromImp = (float)(nlk->m_fFromImp * ( 1 - dRatio ));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -