Files
envi-code/SourceCode/Code2026/Dimension/ReverseElevationCalc.cpp
T
2026-09-28 15:28:50 +08:00

657 lines
17 KiB
C++

#include "StdAfx.h"
#include "AcDbObjectPtr.h"
#include "EntitySet.h"
#include "ReverseElevationCalc.h"
#include "elevationcalcdlg.h"
#include <stack>
#include "DbPipe.h"
#include "Dbwell.h"
#include "Dbpool.h"
namespace
{
BOOL IsPool(AcDbObjectId idNode)
{
if (!idNode)
return FALSE;
AcDbObjectId idBlk = NULL;
OPENOBJ_BEGIN(idNode, AcDb::kForRead, CDbPool, pEquip);
if (pEquip)
return TRUE;
else
return FALSE;
OPENOBJ_END();
}
}
ReverseElevationCalc::ReverseElevationCalc()
{
}
void ReverseElevationCalc::InitCalcSys()
{
if (m_pAllList != NULL)
{
std::stack<SSearchPipeList*> data;
data.push(m_pAllList);
while(!data.empty())
{
SSearchPipeList *pList = data.top();
data.pop();
if (pList != NULL && (pList->m_iType == 3 || pList->m_iType == 4))
{
for (int i = 0; i < pList->m_lstNode.Length(); i++)
{
SSearchPipeList *pEWell = pList, *pSWell = NULL, *pPipe = pList->m_lstNode[i];
if (pPipe->m_iType == 0 && pPipe->m_lstNode.Length() == 1 &&
(pSWell = pPipe->m_lstNode[0]) != NULL && (pSWell->m_iType == 3 || pSWell->m_iType == 4))
{
CALCNODE node;
node.idS = pSWell->m_ID;
node.idE = pEWell->m_ID;
node.idP = pPipe->m_ID;
node.dPipeDn = pPipe->m_iDn;
node.bSysStartWell = FALSE;
node.bIsDropWell = FALSE;
node.bPool = FALSE;
ads_name name;
acdbGetAdsName(name, pPipe->m_ID);
node.dGradient = GlobalFunc::GetPipeGradient(name);
node.dPipeLen = pPipe->m_nLength;
if (pEWell->m_iType == 3) //井
{
node.dWellEleUpE = GetWellEleUp(pEWell->m_ID);
node.strEWellName = GlobalFunc::GetWellName(pEWell->m_ID);
}
else if (pEWell->m_iType == 4) // 化粪池
{
node.dWellEleUpE = GetPoolGroundEle(pEWell->m_ID);
node.strEWellName = GetPoolName(pEWell->m_ID) + _T("进");
}
if (pSWell->m_iType == 3)
{
node.dWellEleUpS = GetWellEleUp(pSWell->m_ID);
node.strSWellName = GlobalFunc::GetWellName(pSWell->m_ID);
node.dWellEleDownS = GetWellEleDown(pSWell->m_ID);
node.bIsDropWell = IsDropWell(pSWell->m_ID);
}
else if (pSWell->m_iType == 4)
{
node.bPool = TRUE;
node.dWellEleUpS = GetPoolGroundEle(pSWell->m_ID);
node.strSWellName = GetPoolName(pSWell->m_ID) + _T("出");
}
if (pSWell->m_lstNode.Length() == 0) //系统起点井
{
node.bSysStartWell = TRUE;
}
node.dGradientDist = node.dGradient * node.dPipeLen;
node.dPipeEleE = 0.0;
node.dPipeEleS = 0.0;
node.dDeepS = 0.0;
node.dDeepE = 0.0;
m_vecLstData.push_back(node);
data.push(pSWell);
}
}
}
}
}
}
void ReverseElevationCalc::LayingDepthCalc()
{
m_vecCheckforPipe.clear();
// 获得反算计算序列
std::vector<CALCNODE> vecCalcforR;
SortforCalcR(vecCalcforR);
acedSetStatusBarProgressMeter(_T("计算中..."), 0, vecCalcforR.size());
for (size_t i = 0; i < vecCalcforR.size(); i++)
{
acedSetStatusBarProgressMeterPos(i);
CALCNODE &node = vecCalcforR[i];
node.dGradientDist = node.dGradient * node.dPipeLen;
if(node.idE == m_pAllList->m_ID) // 排出口
{
node.dPipeEleE = m_dPipeEleDown;
node.dPipeEleS = node.dPipeEleE + node.dGradientDist;
node.dDeepS = node.dWellEleUpS - node.dPipeEleS;
node.dDeepE = node.dWellEleUpE - node.dPipeEleE;
}
else
{
if (IsPool(node.idE)) // 化粪池
{
node.dPipeEleE = GetPipeEleDown2(vecCalcforR, node.idE) + GetPoolDrop(node.idE);
}
else // 井
{
node.dPipeEleE = GetPipeEleUp2(vecCalcforR, node.idE) - GetPipeDjById(node.idP, node.dPipeDn) * 0.001;
}
node.dPipeEleS = node.dPipeEleE + node.dGradientDist;
node.dDeepS = node.dWellEleUpS - node.dPipeEleS;
node.dDeepE = node.dWellEleUpE - node.dPipeEleE;
}
}
acedRestoreStatusBar();
m_vecLstData = vecCalcforR;
}
void ReverseElevationCalc::AutoCalc(BOOL bModify)
{
UpdateSWellLayDepth(); // cet 2012.6.25 add 更新起点井埋深
// 获得正算计算序列
std::vector<CALCNODE> vecCalcforP;
SortforCalcP(vecCalcforP);
acedSetStatusBarProgressMeter(_T("自动计算中..."), 0, vecCalcforP.size());
for (size_t i = 0; i < vecCalcforP.size(); i++)
{
acedSetStatusBarProgressMeterPos(i);
CALCNODE &node = vecCalcforP[i];
node.dGradientDist = node.dGradient * node.dPipeLen;
if (node.bSysStartWell) //系统起点井
{
double dLayingDepth = GetWellLayDepth(node.idS); // 埋设深度
node.dPipeEleS = node.dWellEleUpS - dLayingDepth;
}
else if (node.bIsDropWell) //跌水井
{
node.dPipeEleS = node.dWellEleDownS;
}
else if (node.bPool) // 化粪池
{
node.dPipeEleS = GetPipeEleDown(vecCalcforP, node.idS) - GetPoolDrop(node.idS);
}
else
{
node.bIsDropWell = isDropWell(vecCalcforP, node.idS); // cet 2011.11.29 add 判断井是否产生跌水
double dPipeEleUp = GetPipeEleUp(vecCalcforP, node.idS);
node.dPipeEleS = dPipeEleUp - GetPipeDjById(node.idP, node.dPipeDn) * 0.001;
}
// 检查起点井覆土厚度
double dThick = node.dWellEleUpS - (node.dPipeEleS + GetPipeDjById(node.idP, node.dPipeDn) * 0.001 + GetPipeThickById(node.idP, node.dPipeDn));
if (dThick + 0.001 < m_dMinThick) // 小于最小覆土厚度时调整为最小覆土厚度
{
if (!node.bIsDropWell && !node.bPool)
{
node.dPipeEleS = node.dWellEleUpS - m_dMinThick - GetPipeDjById(node.idP, node.dPipeDn) * 0.001 - GetPipeThickById(node.idP, node.dPipeDn);
if (!node.bSysStartWell && !node.bPool)
{
node.bIsDropWell = TRUE;
node.dWellEleDownS = node.dPipeEleS;
}
}
else if (node.bIsDropWell && bModify) // 跌水井
{
// 变为普通井
node.bIsDropWell = FALSE;
double dPipeEleUp = GetPipeEleUp(vecCalcforP, node.idS);
node.dPipeEleS = dPipeEleUp - GetPipeDjById(node.idP, node.dPipeDn) * 0.001;
dThick = node.dWellEleUpS - (node.dPipeEleS + GetPipeDjById(node.idP, node.dPipeDn) * 0.001 + GetPipeThickById(node.idP, node.dPipeDn));
if (dThick + 0.001 < m_dMinThick)
{
node.dPipeEleS = node.dWellEleUpS - m_dMinThick - GetPipeDjById(node.idP, node.dPipeDn) * 0.001 - GetPipeThickById(node.idP, node.dPipeDn);
node.bIsDropWell = TRUE;
}
}
}
node.dPipeEleE = node.dPipeEleS - node.dGradientDist;
// 检查终点井覆土厚度
dThick = node.dWellEleUpE - (node.dPipeEleE + GetPipeDjById(node.idP, node.dPipeDn) * 0.001 + GetPipeThickById(node.idP, node.dPipeDn));
if (dThick + 0.001 < m_dMinThick) // 小于最小覆土深度时调整为最小覆土深度
{
node.dPipeEleE = node.dWellEleUpE - m_dMinThick - GetPipeDjById(node.idP, node.dPipeDn) * 0.001 - GetPipeThickById(node.idP, node.dPipeDn);
node.dPipeEleS = node.dPipeEleE + node.dGradientDist;
if (!node.bSysStartWell && !node.bPool)
{
node.bIsDropWell = TRUE; //起点井设置为跌水井
node.dWellEleDownS = node.dPipeEleS;
}
}
node.dDeepS = node.dWellEleUpS - node.dPipeEleS;
node.dDeepE = node.dWellEleUpE - node.dPipeEleE;
// 不能修改埋深否则 无法比较起点井和用户设置的埋深关系
// if (node.bSysStartWell)
// {
// m_mapLayingDepth.erase(node.idS);
// m_mapLayingDepth.insert(std::make_pair(node.idS, node.dDeepS));
// }
}
acedRestoreStatusBar();
m_vecLstData = vecCalcforP;
}
void ReverseElevationCalc::CheckSys(CWnd *pWnd)
{
std::vector<AcDbObjectId> vecCheck1, vecCheck2;
std::vector<CALCNODE>::iterator it;
CString strMinThick, strLessDeep, strGreaterDeep;
CString strTemp = _T("、");
for (it = m_vecLstData.begin(); it != m_vecLstData.end(); it++)
{
const CALCNODE &node = *it;
//起点井覆土厚度
double dThick1 = node.dWellEleUpS - (node.dPipeEleS + GetPipeDjById(node.idP, node.dPipeDn) * 0.001 + GetPipeThickById(node.idP, node.dPipeDn));
//终点井覆土厚度
double dThick2 = node.dWellEleUpE - (node.dPipeEleE + GetPipeDjById(node.idP, node.dPipeDn) * 0.001 + GetPipeThickById(node.idP, node.dPipeDn));
if (Compare(dThick1, m_dMinThick) == -1 || Compare(dThick2, m_dMinThick) == -1) // 管段不符合最小覆土厚度
{
strMinThick += node.strSWellName + _T("-") + node.strEWellName + strTemp;
vecCheck1.push_back(node.idP);
}
if (node.bSysStartWell)
{
double dLayingDepth = GetWellLayDepth(node.idS);
// 管内底标高介于最小覆土厚度和用户设定的埋设深度之间
if ((Compare(node.dDeepS, dLayingDepth) == -1)
&& (Compare(dThick1, m_dMinThick) != -1))
{
strLessDeep += node.strSWellName + strTemp;
vecCheck2.push_back(node.idP);
}
else if (Compare(node.dDeepS, dLayingDepth) == 1
&& Compare(dThick1, m_dMinThick) != -1) // 起点埋深大于用户设定值
{
strGreaterDeep += node.strSWellName + strTemp;
}
}
}
if (!strMinThick.IsEmpty()) // 存在不符合最小覆土厚度的管段
{
strMinThick = strMinThick.Left(strMinThick.GetLength() - strTemp.GetLength());
if (pWnd != NULL)
{
pWnd->MessageBox(strMinThick + _T("管段不符合最小埋设深度要求!"), _T("反算校核"));
}
else
{
AfxMessageBox(strMinThick + _T("管段不符合最小埋设深度要求!"));
}
m_vecCheckforPipe = vecCheck1;
}
else if (!strLessDeep.IsEmpty()) // 存在管内底标高介于最小覆土厚度和用户设定的埋设深度之间的系统起点井
{
CString strTip;
strLessDeep = strLessDeep.Left(strLessDeep.GetLength() - strTemp.GetLength());
strTip = strLessDeep + _T("起点井计算所得埋设深度小于用户设定埋设深度!!");
CString strDropWellName;
std::map<AcDbObjectId,double>::iterator it;
for (it = m_mapDropWell.begin(); it != m_mapDropWell.end(); it++)
{
strDropWellName += GlobalFunc::GetWellName((*it).first) + strTemp;
}
if (!strDropWellName.IsEmpty())
{
strDropWellName = strDropWellName.Left(strDropWellName.GetLength() - strTemp.GetLength());
strTip += _T("\n") + strDropWellName + _T("设定跌水井标高与实际计算不符!");
}
if (pWnd != NULL)
{
pWnd->MessageBox(strTip, _T("反算校核"));
}
else
{
AfxMessageBox(strTip);
}
DeleteDropWell();
m_mapDropWell.clear();
m_vecCheckforPipe = vecCheck2;
}
else if (!strGreaterDeep.IsEmpty()) // 存在起点埋深大于用户设定值
{
if (pWnd != NULL)
{
if (pWnd->MessageBox(_T("是否将管网各个起点井的埋设深度提高到用户设置位置并进行自动计算"), _T("反算校核"), MB_YESNO) == IDYES)
{
AutoCalc(TRUE);
// 检查用户设置的跌水井与计算结果是否一致
CheckDropWell();
}
}
else
{
if (AfxMessageBox(_T("是否将管网各个起点井的埋设深度提高到用户设置位置并进行自动计算"), MB_YESNO) == IDYES)
{
AutoCalc(TRUE);
// 检查用户设置的跌水井与计算结果是否一致
CheckDropWell();
}
}
}
else // 起点井埋深与用户设置一致
{
// 存在跌水井时
CString strDropWellName;
std::map<AcDbObjectId,double>::iterator it;
for (it = m_mapDropWell.begin(); it != m_mapDropWell.end(); it++)
{
strDropWellName += GlobalFunc::GetWellName((*it).first) + strTemp;
}
if (!strDropWellName.IsEmpty())
{
strDropWellName = strDropWellName.Left(strDropWellName.GetLength() - strTemp.GetLength());
if (pWnd != NULL)
{
pWnd->MessageBox(strDropWellName + _T("设定跌水井标高与实际计算不符,实际计算") + strDropWellName + _T("应为普通井!"), _T("反算校核"));
}
else
{
AfxMessageBox(strDropWellName + _T("设定跌水井标高与实际计算不符,实际计算") + strDropWellName + _T("应为普通井!"));
}
DeleteDropWell();
m_mapDropWell.clear();
}
}
}
double ReverseElevationCalc::GetPipeEleUp2(const std::vector<CALCNODE> &data, const AcDbObjectId &idEWell)
{
double dRet = 0.0;
AcDbObjectId id;
double dDn = 0.0;
std::vector<CALCNODE>::const_iterator it;
for (it = data.begin(); it != data.end(); it++)
{
if ((*it).idS == idEWell)
{
dRet = (*it).dPipeEleS;
id = (*it).idP;
dDn = (*it).dPipeDn;
break;
}
}
if (!!id)
{
dRet += GetPipeDjById(id, dDn) * 0.001;
}
return dRet;
}
void ReverseElevationCalc::SortforCalcP(std::vector<CALCNODE> &vecData)
{
UpDatePipeSys();
SSearchPipeList *pList = NULL;
pList = GetFarthestSWell(m_pAllList); //获得最远起点井
if (pList != NULL)
{
vecData.clear();
std::stack<SSearchPipeList*> data;
data.push(pList);
while(!data.empty())
{
SSearchPipeList *pSWell = NULL;
pSWell = data.top();
data.pop();
if ((pSWell->m_iType == 3 || pSWell->m_iType == 4) && pSWell->m_pPrevious != NULL && pSWell->m_iSpare != 2) //管段起点井
{
int nNum = pSWell->m_lstNode.Length();
if (nNum == 1 || nNum == 0 || (nNum > 1 && pSWell->m_iSpare == 1))
{
SSearchPipeList *pPipe = pSWell->m_pPrevious;
if (pPipe->m_iType == 0 && pPipe->m_pPrevious != NULL) //管段
{
SSearchPipeList *pEWell = pPipe->m_pPrevious;
if (pEWell->m_iType == 3 || pEWell->m_iType == 4) // 管段终点井
{
pSWell->m_iSpare = 2; //表示井处理(注意只需标注管段起点井)
if (nNum == 0) //系统起点井
{
pSWell->m_bNeedCale = TRUE; //已处理
}
std::vector<CALCNODE>::iterator it;
it = std::find_if(m_vecLstData.begin(), m_vecLstData.end(), FindFunc(pSWell->m_ID));
if (it != m_vecLstData.end())
{
vecData.push_back(*it);
}
data.push(pEWell);
}
}
}
else if (nNum > 1) //存在分支
{
data.push(pSWell);
SSearchPipeList *pTemp = GetFarthestSWell(pSWell);
if (pTemp != NULL)
{
data.push(pTemp);
}
else
{
pSWell->m_iSpare = 1; //井上所有分支已处理
}
}
}
else if (pSWell->m_lstNode.Length() > 1) // 排出端存在支路
{
SSearchPipeList *pTemp = GetFarthestSWell(pSWell);
if (pTemp != NULL)
{
data.push(pTemp);
}
}
}
}
}
void ReverseElevationCalc::SortforCalcR(std::vector<CALCNODE> &vecData)
{
if (m_pAllList != NULL)
{
vecData.clear();
std::stack<SSearchPipeList*> data;
data.push(m_pAllList);
while(!data.empty())
{
SSearchPipeList *pList = data.top();
data.pop();
if (pList != NULL && (pList->m_iType == 3 || pList->m_iType == 4))
{
for (int i = 0; i < pList->m_lstNode.Length(); i++)
{
SSearchPipeList *pEWell = pList, *pSWell = NULL, *pPipe = pList->m_lstNode[i];
if (pPipe->m_iType == 0 && pPipe->m_lstNode.Length() == 1 &&
(pSWell = pPipe->m_lstNode[0]) != NULL && (pSWell->m_iType == 3 || pSWell->m_iType == 4))
{
std::vector<CALCNODE>::iterator it;
it = std::find_if(m_vecLstData.begin(), m_vecLstData.end(), FindFunc(pSWell->m_ID));
if (it != m_vecLstData.end())
{
vecData.push_back(*it);
}
data.push(pSWell);
}
}
}
}
}
}
void ReverseElevationCalc::DeleteDropWell()
{
std::vector<CALCNODE>::iterator it;
for (it = m_vecLstData.begin(); it != m_vecLstData.end(); it++)
{
CALCNODE &node = *it;
if (node.bIsDropWell)
{
node.bIsDropWell = FALSE;
}
}
}
void ReverseElevationCalc::CheckDropWell()
{
CString strTip, strTemp = _T("、");
std::map<AcDbObjectId,double>::iterator it;
for (it = m_mapDropWell.begin(); it != m_mapDropWell.end(); it++)
{
std::vector<CALCNODE>::iterator it2;
it2 = std::find_if(m_vecLstData.begin(), m_vecLstData.end(), FindFunc((*it).first));
if (it2 != m_vecLstData.end())
{
if (!(*it2).bIsDropWell || ((*it2).bIsDropWell && fabs((*it).second - (*it2).dWellEleDownS) > 1e-3))
{
strTip += (*it2).strSWellName + strTemp;
}
}
}
if (!strTip.IsEmpty())
{
strTip = strTip.Left(strTip.GetLength() - strTemp.GetLength());
AfxMessageBox(strTip + _T("设定跌水井标高与实际计算不符!"));
}
}
BOOL ReverseElevationCalc::IsModifyEleforEndWell()
{
// 如果排出井连接着多跟管段,以管内底标高最小值与用户设置值比较
BOOL bRet = FALSE;
std::vector<CALCNODE>::iterator it;
std::set<double> data;
for (it = m_vecLstData.begin(); it != m_vecLstData.end(); it++)
{
CALCNODE &node = *it;
if (node.idE == m_pAllList->m_ID)
{
// 排出井可能连接多个管
data.insert(node.dPipeEleE);
}
}
if (!data.empty())
{
// 取出最小值
double dMin = *(data.begin());
if (Compare(dMin, m_dPipeEleDown) != 0)
{
bRet = TRUE;
}
}
return bRet;
}
double ReverseElevationCalc::GetPipeEleDown2(const std::vector<CALCNODE> &data, const AcDbObjectId &idEWell)
{
double dRet = 0.0;
std::vector<CALCNODE>::const_iterator it;
for (it = data.begin(); it != data.end(); it++)
{
if ((*it).idS == idEWell)
{
dRet = (*it).dPipeEleS;
break;
}
}
return dRet;
}
bool ReverseElevationCalc::isDropWell(std::vector<CALCNODE> &data, const AcDbObjectId &idSWell)
{
double dRet = 0.0;
bool bFirst = true;
bool bDorpWell = false;
std::vector<CALCNODE>::iterator it; // cet 2011.7.5 modfiy 改为非const迭代器,方便修改
for (it = data.begin(); it != data.end(); it++)
{
if ((*it).idE == idSWell)
{
if (bFirst)
{
bFirst = false;
dRet = (*it).dPipeEleE;
}
else if (fabs(dRet - (*it).dPipeEleE) > 0.0001) // 误差值
{
bDorpWell = true;
break;
}
}
}
// cet 2011.7.5 add 通过此函数判断出的跌水井可能导致计算错误,添加以下代码纠正错误
if (bDorpWell)
{
// 找出管内底标高最小值
bFirst = true;
double dPipeDn = 0.0;
AcDbObjectId idPipe;
for (it = data.begin(); it != data.end(); it++)
{
if ((*it).idE == idSWell)
{
if (bFirst)
{
bFirst = false;
dRet = (*it).dPipeEleE;
idPipe = (*it).idP;
dPipeDn = (*it).dPipeDn;
}
else if (dRet > (*it).dPipeEleE)
{
dRet = (*it).dPipeEleE;
idPipe = (*it).idP;
dPipeDn = (*it).dPipeDn;
}
}
}
if (!!idPipe)
{
// 管内顶标高
dRet += GetPipeDjById(idPipe, dPipeDn) * 0.001;
for (it = data.begin(); it != data.end(); it++)
{
if ((*it).idS == idSWell)
{
break;
}
}
// 根据管内顶平接,计算出it中管的起点管内底标高,并将值设置给起点井底标高
if (it != data.end())
{
(*it).dWellEleDownS = dRet - GetPipeDjById((*it).idP, (*it).dPipeDn) * 0.001;
}
}
}
return bDorpWell;
}