Files
envi-code/SourceCode/Code2026/tg_shs/shs_TwtKernal/HydrantCalcDataDlg.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1219 lines
35 KiB
C++

#include "stdafx.h"
#include "HydrantCalcDataDlg.h"
#include "HydrantCalcDlg.h"
#include <stack>
#include "DbEquipment.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern void ImportHydrantWord(DList<SSearchPipeList> &lstNode, CHydrantCalcDlg &dlg);
extern SSearchPipeList *GetNextDimNode(SSearchPipeList *pListAll, SSearchPipeList *pDisadvantage);
extern int DoSerialNumber(SSearchPipeList *pListLast, int idx, BOOL IsMainNode);
extern void CalcSprinkNum(SSearchPipeList *pListAll);
extern SSearchPipeList *GetNextCalcNode(SSearchPipeList *pListAll, SSearchPipeList *pDisadvantage);
extern double GetDangLenByElbow90(int iDn1, int iDn2); //90度弯头当量长度
extern double GetDangLenByTaiIn(int iDn1, int iDn2); //接头当量长度
extern double GetDangLenByCorner(int iDn); //3通4通当量长度
extern SSearchPipeList *GetNextExportNode(SSearchPipeList *pListAll, SSearchPipeList *pDisadvantage);
extern void ModifyPipeSysFlow(SSearchPipeList *pListAll, PickSet &ss);
extern void DoCalcHydrantNg(SSearchPipeList *pListAll, BOOL bOnlyFlow = TRUE);
extern double DoCalcHydrantNode(SSearchPipeList *pListLast, int &idx, double B, double Ad, double Ld, double nQ, const bool bPGraph);
extern double GetTerminalNodePress(SSearchPipeList *pListLast);
extern double DoTryCalcHydrantNode(SSearchPipeList *pListLast, double B, double Ad, double Ld, double nQ, const bool bPGraph);
extern double GetDangLenByElbow90(int iDn1); //90度弯头当量长度
extern BOOL IsNeedCalc(SSearchPipeList *pListAll);
TGridHydrantCalcGrid::TGridHydrantCalcGrid()
{
AppendCol(_T("管段名称"), 55);
AppendCol(_T("起点压力"), 55);
AppendCol(_T("流量L/s"), 50);
AppendCol(_T("管长(m)"), 55);
AppendCol(_T("当量"), 50);
AppendCol(_T("管径(mm)"), 55);
AppendCol(_T("水力坡降"), 55);
AppendCol(_T("流速m/s"), 55);
AppendCol(_T("损失mH2O"), 55);
AppendCol(_T("终点压力"), 55);
SetColPosFix();
SetColFixLength();
SetNoPaste();
GetCol(5).SetComboEdit();
GetCol(4).SetRightButton();
COLORREF color = RGB(255,0,0);
GetCol(5).SetTextColor(color);
COLORREF color2 = RGB(0,0,255);
GetCol(6).SetTextColor(color2);
GetCol(7).SetTextColor(color2);
GetCol(8).SetTextColor(color2);
GetCol(9).SetTextColor(color2);
m_pDlg = NULL;
}
void TGridHydrantCalcGrid::OnCellComboString(WDGridCell&cell,CComboBox&combo)
{
if(cell.GetColIndex()==5)
{
combo.AddString(_T("25"));
combo.AddString(_T("32"));
combo.AddString(_T("40"));
combo.AddString(_T("50"));
combo.AddString(_T("65"));
combo.AddString(_T("80"));
combo.AddString(_T("100"));
combo.AddString(_T("125"));
combo.AddString(_T("150"));
combo.AddString(_T("200"));
}
}
bool TGridHydrantCalcGrid::OnCellButtonDown(WDGridCell &cell, CString &res)
{
if(cell.GetColIndex() == 4)
{
WDGridRow &row = cell.GetRow();
TGridHydrantData *pNewData = (TGridHydrantData *)row.GetExtendData();
AfxMessageBox(pNewData->m_csNg);
return true;
}
return false;
}
void TGridHydrantCalcGrid::SetDlg( CHydrantCalcDataDlg *pDlg )
{
m_pDlg = pDlg;
}
void TGridHydrantCalcGrid::ShowPipe()
{
if (m_pDlg == NULL)
{
return;
}
long nSelRow = GetCurRowIndex();
if (nSelRow == -1)
{
return;
}
WDGridRow &row = GetRow(nSelRow);
TGridHydrantData *pNewData = (TGridHydrantData *)row.GetExtendData();
if (pNewData == NULL)
{
return;
}
OPENOBJ_BEGIN(pNewData->m_idPipe, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe != NULL)
{
XPoint ptCen, p1, p2, p3, p4;
ptCen = pPipe->MidPoint();
double nDist = pPipe->Length()*2000;
arxZoomTo(ptCen, nDist, nDist);
ads_polar(ptCen, 0, nDist/5, p1);
ads_polar(p1, PI/2, nDist/5, p1);
ads_polar(ptCen, PI, nDist/5, p2);
ads_polar(p2, PI/2, -nDist/5, p2);
ads_grdraw(p1, p2, 2, 0);
ads_polar(ptCen, PI/2, nDist/5, p3);
ads_polar(p3, PI, nDist/5, p3);
ads_polar(ptCen, PI/2, -nDist/5, p4);
ads_polar(p4, 0, nDist/5, p4);
ads_grdraw(p3, p4, 2, 0);
}
OPENOBJ_END();
HideDialog(m_pDlg, TRUE);
TCHAR szTmp[256];
ads_getstring(NULL, _T("\n按任意键返回对话框:<返回>"), szTmp);
HideDialog(m_pDlg, FALSE);
}
bool TGridHydrantCalcGrid::OnModified( WDGridCell&cell,CString &text )
{
if (cell.GetColIndex() == 5)
{
WDGridRow &row = cell.GetRow();
TGridHydrantData *pNewData = (TGridHydrantData *)row.GetExtendData();
if (pNewData != NULL)
{
m_pDlg->UpdatePipeDn(pNewData->m_idPipe, _tstof(text));
}
}
else if (cell.GetColIndex() == 4)
{
return false;
}
return true;
}
void TGridHydrantCalcGrid::OnDblClick( WDGridRow&row )
{
ShowPipe();
}
CHydrantCalcDataDlg::CHydrantCalcDataDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHydrantCalcDataDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CHydrantCalcDataDlg)
m_bNg = TRUE;
m_dPress = 50;
//}}AFX_DATA_INIT
m_pHydrantCalcDlg = NULL;
m_pListAll = NULL;
m_bShow = false;
m_bPGraph = false;
}
CHydrantCalcDataDlg::~CHydrantCalcDataDlg()
{
delete m_pListAll;
}
void CHydrantCalcDataDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHydrantCalcDataDlg)
DDX_Control(pDX, IDC_LIST_PIPE, m_wndGrid);
DDX_Check(pDX, IDC_CHECK_NG, m_bNg);
DDX_Text(pDX, IDC_EDT_PRESS, m_dPress);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHydrantCalcDataDlg, CDialog)
//{{AFX_MSG_MAP(CHydrantCalcDataDlg)
ON_BN_CLICKED(IDC_BTN_WORD, OnBtnWord)
ON_BN_CLICKED(IDC_BUTTON_SHOW, OnButtonShow)
ON_BN_CLICKED(IDC_BTN_PRESS, OnBtnPress)
ON_BN_CLICKED(IDC_BTN_SHEET, OnBtnSheet)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CHydrantCalcDataDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_wndGrid.Clear();
m_wndGrid.Create(this, IDC_LIST_PIPE);
m_wndGrid.SetNoAppendButton(TRUE);
m_wndGrid.SetNoDefaultMenu(true);
m_wndGrid.GetCol(0).SetReadOnly(true);
m_wndGrid.GetCol(1).SetReadOnly(true);
m_wndGrid.GetCol(2).SetReadOnly(true);
m_wndGrid.GetCol(3).SetReadOnly(true);
m_wndGrid.GetCol(4).SetReadOnly(false);
m_wndGrid.GetCol(5).SetReadOnly(false);
m_wndGrid.GetCol(6).SetReadOnly(true);
m_wndGrid.GetCol(7).SetReadOnly(true);
m_wndGrid.GetCol(8).SetReadOnly(true);
m_wndGrid.GetCol(9).SetReadOnly(true);
m_wndGrid.SetDlg(this);
Calc();
return TRUE;
}
void CHydrantCalcDataDlg::OnBtnWord()
{
ImportHydrantWord(m_lstNode, *m_pHydrantCalcDlg);
}
void CHydrantCalcDataDlg::SetHydrantCalcDlg( CHydrantCalcDlg *pDlg )
{
m_pHydrantCalcDlg = pDlg;
}
// zxl 2013.04.28 add
//计算本节点往后共计管线长度
BOOL CalcLstPipeLength2(SSearchPipeList *pListAll, SSearchPipeList *pListFront, PickSet &ss, bool &bPGraph)
{
BOOL ret = TRUE;
AcDbObjectId id = NULL;
id = pListAll->m_ID;
ads_name ent;
double nCurPipeLength(0);
acdbGetAdsName(ent, id);
if(pListAll->m_iType == 2){
Entity entTmp = ent;
int iK = _ttoi(ReadXdata(entTmp, _T("SPRINKLER_K")));
pListAll->m_iSpare = iK;
if(entTmp.In(&ss))
pListAll->m_bNeedCale = TRUE;
}
else if (pListAll->m_iType < 0)// 系统搜索时 消火栓木有类型
{
Entity entTmp = ent;
if(IsHydrant(id) && entTmp.In(&ss))
{
pListAll->m_iType = 2;
pListAll->m_bNeedCale = TRUE;
int iK = _ttoi(ReadXdata(entTmp, _T("SPRINKLER_K")));
pListAll->m_iSpare = iK;
bPGraph = true;
}
}
else if(pListAll->m_iType == 0){
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe){
int iDn = (int)(pPipe->GetDnDiameter());
pListAll->m_iDn = iDn;
double nGradient = pPipe->GetPipeGradient();
pListAll->m_nI = nGradient*1000;
nCurPipeLength = pPipe->Length();
pListAll->m_nLength = nCurPipeLength;
if(pPipe->GetDnDiameter() < 0 && !pPipe->IsVertical())
return FALSE;
}
OPENOBJ_END();
}
if(pListFront)
pListAll->m_nLength += pListFront->m_nLength;
long len = pListAll->m_lstNode.Length();
for(long i=0;i<len;i++){
SSearchPipeList *pList = pListAll->m_lstNode[i];
pList->m_pPrevious = pListAll;
ret = CalcLstPipeLength2(pList, pListAll, ss, bPGraph);
if(!ret)
return FALSE;
}
return ret;
}
void CHydrantCalcDataDlg::Calc()
{
double nPress = _tstof(m_pHydrantCalcDlg->m_csRetPress);
double nQ = _tstof(m_pHydrantCalcDlg->m_csRet);
if(nQ < _tstof(m_pHydrantCalcDlg->m_csQ))//小于水枪最小流量
{
nQ = _tstof(m_pHydrantCalcDlg->m_csQ);
nPress = m_pHydrantCalcDlg->m_nAd * m_pHydrantCalcDlg->m_nLd * nQ * nQ + nQ * nQ / m_pHydrantCalcDlg->m_nB + 2;
}
CalcLstPipeLength2(m_pListAll, NULL, m_ssCalc, m_bPGraph);
if(m_pListAll->m_lstNode.Length() == 2)
{
m_ssAll.Free();
//计算源头应为节点,而不是管线. 以下计算管线2节点哪个是源头
CalcSprinkNum(m_pListAll); //所连喷头多的节点是源头
SSearchPipeList *p1 = m_pListAll->m_lstNode[0];
SSearchPipeList *p2 = m_pListAll->m_lstNode[1];
SSearchPipeList *p3 = p1->m_iNum > p2->m_iNum ? p2 : p1;
ads_name ent;
acdbGetAdsName(ent, p3->m_ID);
delete m_pListAll;
m_pListAll = new SSearchPipeList();
//重新搜索系统
m_ssAll.Free();
if(!SearchSprinkPipeSys(ent, NULL, m_pListAll, m_ssAll))
{
OnCancel();
AfxMessageBox(_T("喷淋系统有回路!"));
delete m_pListAll;
return;
}
m_pListAll->m_iType = 1;
CalcLstPipeLength2(m_pListAll, NULL, m_ssCalc, m_bPGraph);
}
ModifyPipeSysFlow(m_pListAll, m_ssAll); // cet 2010.7.8 add 更改管道流向
//////////////////////////////////////////////////////////////////////////////////////////
DoCalcHydrantNg(m_pListAll, m_bNg);
int idx = 1;
SSearchPipeList *pNode = GetNextDimNode(m_pListAll, NULL);
while(pNode){
BOOL IsMainNode = FALSE;
if(idx == 1)
IsMainNode = TRUE;
idx = DoSerialNumber(pNode, idx, IsMainNode); //标注节点编号
pNode = GetNextDimNode(m_pListAll, NULL); //得到下一支路起点节点
}
DoDimPipeSerialNumber(m_pListAll); //标注管段编号
pNode = GetNextCalcNode(m_pListAll, NULL); //得到下一支路起点节点
pNode->m_nPipeQ = nQ;
idx = 1;
while(pNode){
pNode->m_nStartPress = nPress;
idx = (int)DoCalcHydrantNode(pNode, idx, m_pHydrantCalcDlg->m_nB, m_pHydrantCalcDlg->m_nAd, m_pHydrantCalcDlg->m_nLd, _tstof(m_pHydrantCalcDlg->m_csQ), m_bPGraph);
idx ++;
pNode = GetNextCalcNode(m_pListAll, NULL); //得到下一支路起点节点
if(pNode){
nPress = GetTerminalNodePress(pNode);
pNode->m_nStartPress = nPress;
double nCalcPress = DoTryCalcHydrantNode(pNode, m_pHydrantCalcDlg->m_nB, m_pHydrantCalcDlg->m_nAd, m_pHydrantCalcDlg->m_nLd, _tstof(m_pHydrantCalcDlg->m_csQ), m_bPGraph);
double nPlus(0.1), nVal(0), nTmp(1);
int n(0);
//利用交叉节点的压力作为末端消火栓的默认压力(肯定大),然后不断减少,直至从末端计算到交叉节点的压力等于最不利点计算到交叉节点的压力
while(fabs(nPress - nCalcPress) > 0.01)
{
n++;
if((nPress - nCalcPress) < 0)
pNode->m_nStartPress -= nPlus;
else
pNode->m_nStartPress += nPlus;
nCalcPress = DoTryCalcHydrantNode(pNode, m_pHydrantCalcDlg->m_nB, m_pHydrantCalcDlg->m_nAd, m_pHydrantCalcDlg->m_nLd, _tstof(m_pHydrantCalcDlg->m_csQ), m_bPGraph);
nVal = nPress - nCalcPress;
if(fabs(nPress - nCalcPress) > 10)
nPlus = 2;
else if(fabs(nPress - nCalcPress) > 1)
nPlus = 0.5;
else if(fabs(nPress - nCalcPress) > 0.1)
nPlus = 0.1;
else
nPlus = 0.01;
if(n > 60) //死循环, 主动退出
break;
}
nPress = pNode->m_nStartPress;
}
}
CString csNg, csName;
pNode = GetNextExportNode(m_pListAll, NULL);
while(pNode != NULL)
{
csNg = GetPipeNg(pNode);
csName = pNode->m_csName + _T(" 管 当量 = ") + csNg;
SSearchPipeList *pNodeNew = new SSearchPipeList();
pNodeNew->m_iDn = pNode->m_iDn;
pNodeNew->m_csName = csName;
pNodeNew->m_nLength = pNode->m_nLength;
pNodeNew->m_nPipeQ = pNode->m_nPipeQ;
pNodeNew->m_nDang = pNode->m_nDang;
pNodeNew->m_nStartPress = pNode->m_nStartPress;
pNodeNew->m_nI = pNode->m_nI;
pNodeNew->m_nV = pNode->m_nV;
pNodeNew->m_nLost = pNode->m_nLost;
pNodeNew->m_ID = pNode->m_ID;
m_lstNode.Append(pNodeNew);
pNode->m_iNum = 0;
pNode = GetNextExportNode(m_pListAll, NULL);
}
UpdateGrid();
UpdatePress();
}
void CHydrantCalcDataDlg::SetListAll( SSearchPipeList *pListAll )
{
m_pListAll = pListAll;
}
void CHydrantCalcDataDlg::SetSSAll( PickSet &ssAll )
{
m_ssAll.Free();
m_ssAll += ssAll;
}
void CHydrantCalcDataDlg::SetSSCalc( PickSet &ssCalc )
{
m_ssCalc.Free();
m_ssCalc += ssCalc;
}
void CHydrantCalcDataDlg::UpdateGrid()
{
m_wndGrid.Clear();
int nLen = m_lstNode.Length();
CString sTmp, sName;
for(int i = 0; i < nLen; i++)
{
m_wndGrid.AppendRow();
sName = m_lstNode[i]->m_csName;
int idx = sName.Find(_T(" "));
sName = sName.Left(idx);
TGridHydrantData *pNewData = new TGridHydrantData();
pNewData->m_csNg = m_lstNode[i]->m_csName;
pNewData->m_idPipe = m_lstNode[i]->m_ID;
WDGridRow &row = m_wndGrid.GetRow(i);
row.SetExtendData(pNewData);
//管段名称
m_wndGrid.GetCell(i, 0).SetText(sName);
//起点压力mH2O
sTmp.Format(_T("%.2f"), m_lstNode[i]->m_nStartPress);
m_wndGrid.GetCell(i, 1).SetText(sTmp);
//管道流量L/s
sTmp.Format(_T("%.2f"), m_lstNode[i]->m_nPipeQ);
m_wndGrid.GetCell(i, 2).SetText(sTmp);
//管长m
sTmp.Format(_T("%.2f"), m_lstNode[i]->m_nLength);
m_wndGrid.GetCell(i, 3).SetText(sTmp);
//当量长度m
sTmp.Format(_T("%.2f"), m_lstNode[i]->m_nDang);
m_wndGrid.GetCell(i, 4).SetText(sTmp);
//管径mm
sTmp.Format(_T("%d"), m_lstNode[i]->m_iDn);
m_wndGrid.GetCell(i, 5).SetText(sTmp);
//水力坡降mH2O/m
sTmp.Format(_T("%.3f"), m_lstNode[i]->m_nI);
m_wndGrid.GetCell(i, 6).SetText(sTmp);
//流速m/s
sTmp.Format(_T("%.2f"), m_lstNode[i]->m_nV);
m_wndGrid.GetCell(i, 7).SetText(sTmp);
//损失mH2O
sTmp.Format(_T("%.2f"), m_lstNode[i]->m_nLost);
m_wndGrid.GetCell(i, 8).SetText(sTmp);
//终点压力mH2O
sTmp.Format(_T("%.2f"), m_lstNode[i]->m_nLost + m_lstNode[i]->m_nStartPress);
m_wndGrid.GetCell(i, 9).SetText(sTmp);
}
}
void CHydrantCalcDataDlg::UpdatePress()
{
CWnd *pWnd = GetDlgItem(IDC_EDIT_RET_PRESS);
if (pWnd == NULL)
{
return;
}
int nLen = m_lstNode.Length();
if (nLen < 1)
{
pWnd->SetWindowText(_T(""));
return;
}
CString sRet;
sRet.Format(_T("%.2f"), m_lstNode[nLen - 1]->m_nLost + m_lstNode[nLen - 1]->m_nStartPress);
pWnd->SetWindowText(sRet);
}
//计算得到每段管线的当量
CString CHydrantCalcDataDlg::GetPipeNg(SSearchPipeList *pListAll)
{
CString csRet;
double dNg(0);
if(pListAll->m_iType == 0){
AcDbObjectId id = NULL;
id = pListAll->m_ID;
int iDn1(0), iDn2(0), iDn0(0);
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe){
iDn1 = (int)pPipe->GetDnDiameter();
}
OPENOBJ_END();
DList<AcDbObjectId> lstPipe;
if(pListAll->m_lstNode.Length() == 1){
SSearchPipeList *pList = pListAll->m_lstNode[0]; //得到后节点
if(IsNeedCalc(pList)){
BOOL bIsSprinkler = FALSE;
if(pList->m_iType == 2)
bIsSprinkler = TRUE;
//第一步, 得到后节点管件的当量
int iLen = pList->m_lstNode.Length();
int iNoCalc(0);
if(m_bNg) //当量统计仅考虑水流情况
{
for(int j=0;j<iLen;j++){
SSearchPipeList *pListTmp = pList->m_lstNode[j];
if(!IsNeedCalc(pListTmp))
iNoCalc++;
}
iLen-=iNoCalc;
}
if(bIsSprinkler)
iLen++;
iLen++;
if(iLen > 2){ //三通 四通
double dNg1 = GetDangLenByCorner(iDn1);
csRet.Format(_T("三通四通 %.2f "), dNg1);
}
else if(iLen == 2){
if(bIsSprinkler){ //接喷淋立管弯头
double dNg1 = GetDangLenByElbow90(iDn1);
csRet.Format(_T("90度弯头 %.2f "), dNg1);
}
else if(iNoCalc==0){
SSearchPipeList *pListTmp = pList->m_lstNode[0];
OPENOBJ_BEGIN(pListTmp->m_ID, AcDb::kForRead, TDbPipe, pPipe2);
if(pPipe2){
iDn2 = (int)pPipe2->GetDnDiameter();
}
OPENOBJ_END();
if(Is2PipeParallel(pListTmp->m_ID, id)){ //前后管是否平行
double dNg1 = GetDangLenByTaiIn(iDn1, iDn2); //根据接头查当量长度
csRet.Format(_T("异径接头 %.2f "), dNg1);
}
else{
double dNg1 = GetDangLenByElbow90(iDn1); //根据弯头查当量长度
csRet.Format(_T("90度弯头 %.2f "), dNg1);
}
}
}
//第二步, 看看和前节点是否存在变径
if(pListAll->m_pPrevious != NULL){
SSearchPipeList *pList2 = pListAll->m_pPrevious;
int iLen2 = pList2->m_lstNode.Length();
if(iLen2 > 1 || pList2->m_iType == 2){//肯定是个三通
if(pList2->m_pPrevious != NULL){
SSearchPipeList *pList3 = pList2->m_pPrevious;//得到前管
OPENOBJ_BEGIN(pList3->m_ID, AcDb::kForRead, TDbPipe, pPipe2);
if(pPipe2){
iDn0 = (int)pPipe2->GetDnDiameter();
}
OPENOBJ_END();
double dNg2 = GetDangLenByTaiIn(iDn0, iDn1); //异径接头
csRet.Format(_T("%s 异径接头 %.2f "), csRet, dNg2);
dNg += dNg2;
}
}
}
}
}
}
return csRet;
}
void CHydrantCalcDataDlg::ReCalc()
{
double nPress = _tstof(m_pHydrantCalcDlg->m_csRetPress);
double nQ = _tstof(m_pHydrantCalcDlg->m_csRet);
if(nQ < _tstof(m_pHydrantCalcDlg->m_csQ))//小于水枪最小流量
{
nQ = _tstof(m_pHydrantCalcDlg->m_csQ);
nPress = m_pHydrantCalcDlg->m_nAd * m_pHydrantCalcDlg->m_nLd * nQ * nQ + nQ * nQ / m_pHydrantCalcDlg->m_nB + 2;
}
ResetList(m_pListAll);
CalcLstPipeLength2(m_pListAll, NULL, m_ssCalc, m_bPGraph);
// if(m_pListAll->m_lstNode.Length() == 2)
// {
// m_ssAll.Free();
// //计算源头应为节点,而不是管线. 以下计算管线2节点哪个是源头
// CalcSprinkNum(m_pListAll); //所连喷头多的节点是源头
// SSearchPipeList *p1 = m_pListAll->m_lstNode[0];
// SSearchPipeList *p2 = m_pListAll->m_lstNode[1];
// SSearchPipeList *p3 = p1->m_iNum > p2->m_iNum ? p2 : p1;
//
// ads_name ent;
// acdbGetAdsName(ent, p3->m_ID);
// delete m_pListAll;
// m_pListAll = new SSearchPipeList();
// //重新搜索系统
// m_ssAll.Free();
// if(!SearchSprinkPipeSys(ent, NULL, m_pListAll, m_ssAll))
// {
// OnCancel();
// AfxMessageBox(_T("喷淋系统有回路!"));
// delete m_pListAll;
// return;
// }
// m_pListAll->m_iType = 1;
// CalcLstPipeLength(m_pListAll, NULL, m_ssCalc);
// }
//
// ModifyPipeSysFlow(m_pListAll, m_ssCalc); // cet 2010.7.8 add 更改管道流向
//////////////////////////////////////////////////////////////////////////////////////////
DoCalcHydrantNg2(m_pListAll, m_bNg);
int idx = 1;
SSearchPipeList *pNode = GetNextDimNode(m_pListAll, NULL);
while(pNode){
BOOL IsMainNode = FALSE;
if(idx == 1)
IsMainNode = TRUE;
idx = DoSerialNumber(pNode, idx, IsMainNode); //标注节点编号
pNode = GetNextDimNode(m_pListAll, NULL); //得到下一支路起点节点
}
DoDimPipeSerialNumber(m_pListAll); //标注管段编号
pNode = GetNextCalcNode(m_pListAll, NULL); //得到下一支路起点节点
pNode->m_nPipeQ = nQ;
idx = 1;
while(pNode){
pNode->m_nStartPress = nPress;
idx = (int)DoCalcHydrantNode(pNode, idx, m_pHydrantCalcDlg->m_nB, m_pHydrantCalcDlg->m_nAd, m_pHydrantCalcDlg->m_nLd, _tstof(m_pHydrantCalcDlg->m_csQ), m_bPGraph);
idx ++;
pNode = GetNextCalcNode(m_pListAll, NULL); //得到下一支路起点节点
if(pNode){
nPress = GetTerminalNodePress(pNode);
pNode->m_nStartPress = nPress;
double nCalcPress = DoTryCalcHydrantNode(pNode, m_pHydrantCalcDlg->m_nB, m_pHydrantCalcDlg->m_nAd, m_pHydrantCalcDlg->m_nLd, _tstof(m_pHydrantCalcDlg->m_csQ), m_bPGraph);
double nPlus(0.1), nVal(0), nTmp(1);
int n(0);
//利用交叉节点的压力作为末端消火栓的默认压力(肯定大),然后不断减少,直至从末端计算到交叉节点的压力等于最不利点计算到交叉节点的压力
while(fabs(nPress - nCalcPress) > 0.01)
{
n++;
if((nPress - nCalcPress) < 0)
pNode->m_nStartPress -= nPlus;
else
pNode->m_nStartPress += nPlus;
nCalcPress = DoTryCalcHydrantNode(pNode, m_pHydrantCalcDlg->m_nB, m_pHydrantCalcDlg->m_nAd, m_pHydrantCalcDlg->m_nLd, _tstof(m_pHydrantCalcDlg->m_csQ), m_bPGraph);
nVal = nPress - nCalcPress;
if(fabs(nPress - nCalcPress) > 10)
nPlus = 2;
else if(fabs(nPress - nCalcPress) > 1)
nPlus = 0.5;
else if(fabs(nPress - nCalcPress) > 0.1)
nPlus = 0.1;
else
nPlus = 0.01;
if(n > 60) //死循环, 主动退出
break;
}
nPress = pNode->m_nStartPress;
}
}
m_lstNode.Reset();
CString csNg, csName;
pNode = GetNextExportNode(m_pListAll, NULL);
while(pNode != NULL)
{
csNg = GetPipeNg(pNode);
csName = pNode->m_csName + _T(" 管 当量 = ") + csNg;
SSearchPipeList *pNodeNew = new SSearchPipeList();
pNodeNew->m_iDn = pNode->m_iDn;
pNodeNew->m_csName = csName;
pNodeNew->m_nLength = pNode->m_nLength;
pNodeNew->m_nPipeQ = pNode->m_nPipeQ;
pNodeNew->m_nDang = pNode->m_nDang;
pNodeNew->m_nStartPress = pNode->m_nStartPress;
pNodeNew->m_nI = pNode->m_nI;
pNodeNew->m_nV = pNode->m_nV;
pNodeNew->m_nLost = pNode->m_nLost;
pNodeNew->m_ID = pNode->m_ID;
m_lstNode.Append(pNodeNew);
pNode->m_iNum = 0;
pNode = GetNextExportNode(m_pListAll, NULL);
}
UpdateGrid();
UpdatePress();
m_mapColor.clear();
}
//计算得到每段管线的当量
void CHydrantCalcDataDlg::DoCalcHydrantNg2(SSearchPipeList *pListAll, BOOL bOnlyFlow)
{
if(pListAll->m_iType == 0)
{
AcDbObjectId id = NULL;
id = pListAll->m_ID;
int iDn1(0), iDn2(0), iDn0(0);
std::map<AcDbObjectId,double>::iterator it;
it = m_mapPipeDN.find(id);
if (it != m_mapPipeDN.end())
{
iDn1 = (int)(it->second);
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipe, pPipe);
if(pPipe != NULL)
{
pPipe->SetDnDiameter(it->second);
}
OPENOBJ_END();
}
else
{
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe != NULL)
{
iDn1 = (int)pPipe->GetDnDiameter();
}
OPENOBJ_END();
}
double dNg(0);
DList<AcDbObjectId> lstPipe;
if(pListAll->m_lstNode.Length() == 1)
{
SSearchPipeList *pList = pListAll->m_lstNode[0]; //得到后节点
if(IsNeedCalc(pList))
{
//第一步, 得到后节点管件的当量
int iLen = pList->m_lstNode.Length();
int iNoCalc(0);
if(bOnlyFlow) //当量统计仅考虑水流情况
{
for(int j=0;j<iLen;j++){
SSearchPipeList *pListTmp = pList->m_lstNode[j];
if(!IsNeedCalc(pListTmp))
iNoCalc++;
}
iLen-=iNoCalc;
}
iLen++;
if(iLen > 2) //三通 四通
{
dNg = GetDangLenByCorner(iDn1);
}
else if(iLen == 2)
{
if(iNoCalc==0) //iNoCalc==0 表示不考虑水流情况下,实际情况就是2跟管。
{
SSearchPipeList *pListTmp = pList->m_lstNode[0];
it = m_mapPipeDN.find(pListTmp->m_ID);
if (it != m_mapPipeDN.end())
{
iDn2 = (int)(it->second);
OPENOBJ_BEGIN(pListTmp->m_ID, AcDb::kForWrite, TDbPipe, pPipe2);
if(pPipe2 != NULL)
{
pPipe2->SetDnDiameter(it->second);
}
OPENOBJ_END();
}
else
{
OPENOBJ_BEGIN(pListTmp->m_ID, AcDb::kForRead, TDbPipe, pPipe2);
if(pPipe2 != NULL)
{
iDn2 = (int)pPipe2->GetDnDiameter();
}
OPENOBJ_END();
}
if(Is2PipeParallel(pListTmp->m_ID, id)) //前后管是否平行
dNg = GetDangLenByTaiIn(iDn1, iDn2); //根据接头查当量长度
else
dNg = GetDangLenByElbow90(iDn1); //根据弯头查当量长度
}
}
//第二步, 看看和前节点是否存在变径
if(pListAll->m_pPrevious != NULL)
{
SSearchPipeList *pList2 = pListAll->m_pPrevious;
int iLen2 = pList2->m_lstNode.Length();
if(iLen2 > 1 || pList2->m_iType == 2) //肯定是个三通
{
if(pList2->m_pPrevious != NULL)
{
SSearchPipeList *pList3 = pList2->m_pPrevious;//得到前管
it = m_mapPipeDN.find(pList3->m_ID);
if (it != m_mapPipeDN.end())
{
iDn0 = (int)(it->second);
OPENOBJ_BEGIN(pList3->m_ID, AcDb::kForWrite, TDbPipe, pPipe2);
if(pPipe2 != NULL)
{
pPipe2->SetDnDiameter(it->second);
}
OPENOBJ_END();
}
else
{
OPENOBJ_BEGIN(pList3->m_ID, AcDb::kForRead, TDbPipe, pPipe2);
if(pPipe2 != NULL)
{
iDn0 = (int)pPipe2->GetDnDiameter();
}
OPENOBJ_END();
}
double dNg2 = GetDangLenByTaiIn(iDn0, iDn1); //异径接头
dNg += dNg2;
}
}
}
}
}
pListAll->m_nDang = dNg;
}
long len = pListAll->m_lstNode.Length();
for(long i = 0; i < len; i++)
{
SSearchPipeList *pList = pListAll->m_lstNode[i];
DoCalcHydrantNg2(pList, bOnlyFlow);
}
}
void CHydrantCalcDataDlg::UpdatePipeDn( const AcDbObjectId &idPipe, double dDn )
{
m_mapPipeDN[idPipe] = dDn;
}
void CHydrantCalcDataDlg::OnOK()
{
UpdateData(TRUE);
ReCalc();
}
void CHydrantCalcDataDlg::ResetList(SSearchPipeList *pListAll)
{
pListAll->m_nStartPress = 0;
pListAll->m_nPipeQ = 0;
long nLen = pListAll->m_lstNode.Length();
for(long i = 0; i < nLen; i++)
{
SSearchPipeList *pList = pListAll->m_lstNode[i];
ResetList(pList);
}
}
void CHydrantCalcDataDlg::OnButtonShow()
{
m_wndGrid.ShowPipe();
}
void CHydrantCalcDataDlg::OnBtnPress()
{
UpdateData(TRUE);
// 未构建节点压力关系
if (m_mapCalcedNodePress.empty())
{
ConstructNode();
}
// 计算节点压力并检查不符合压力条件的节点
std::map<AcDbObjectId,NODEPRESS>::iterator it;
std::map<AcDbObjectId,NODEPRESS>::iterator itEnd = m_mapCalcedNodePress.end();
m_vecIds.clear();
for (it = m_mapCalcedNodePress.begin(); it != itEnd; ++it)
{
it->second.dPress = it->second.pListClaced->m_nStartPress + it->second.dPressDiff;
double dd = it->second.dPress;
if (it->second.dPress > m_dPress)
{
m_vecIds.push_back(it->first);
}
}
// Dim();
if (m_vecIds.empty())
{
MessageBox(_T("消火栓皆满足压力要求!"));
return;
}
CString sTip;
sTip.Format(_T("共有%d组消火栓需减压稳压!"), m_vecIds.size());
MessageBox(sTip);
HideDialog(this, TRUE);
GetEntityColor();
SetTimer(1, 300, NULL);
TCHAR szTmp[256];
ads_getstring(NULL, _T("\n按任意键返回对话框:<返回>"), szTmp);
HideDialog(this, FALSE);
KillTimer(1);
ShowHydrant(false);
acedUpdateDisplay();
actrTransactionManager->flushGraphics();
}
void CHydrantCalcDataDlg::ConstructNode()
{
std::stack<SSearchPipeList*> stackNode;
stackNode.push(m_pListAll);
SSearchPipeList *pTemp = NULL, *pList = NULL;
XPoint ptStart, ptEnd;
while(!stackNode.empty())
{
pTemp = stackNode.top();
stackNode.pop();
double dHeight = 0.0;
pList = NULL;
// 未参与计算消火栓
if ((pTemp->m_iType == 2) && (pTemp->m_csName == _T("")))
{
pList = pTemp->m_pPrevious;
double dPressDiff = 0.0;
while(pList != NULL && pList->m_csName == _T(""))
{
if (pList->m_iType == 0)
{
OPENOBJ_BEGIN(pList->m_ID, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe != NULL)
{
ptStart = pPipe->StartPoint();
ptEnd = pPipe->EndPoint();
if(fabs(ptStart.x - ptEnd.x) < 0.001)
{
TPipeSys::FlowDirection sys = pPipe->GetFlowDir();
if (sys == TPipeSys::kFromEnd)
{
dHeight += (ptEnd.y - ptStart.y) / 1000;
}
else
{
dHeight += (ptStart.y - ptEnd.y) / 1000;
}
}
}
OPENOBJ_END();
}
pList = pList->m_pPrevious;
}
}
else if (pTemp->m_iType == 2 && pTemp->m_csName != _T(""))
{
pList = pTemp;
}
if (pList != NULL)
{
NODEPRESS node;
node.dPressDiff = dHeight;
node.pListClaced = pList;
node.pList = pTemp;
node.dPress = 0.0;
m_mapCalcedNodePress.insert(std::make_pair(pTemp->m_ID, node));
}
int nNum = pTemp->m_lstNode.Length();
for (int i = 0; i < nNum; ++i)
{
stackNode.push(pTemp->m_lstNode[i]);
}
}
}
void CHydrantCalcDataDlg::ShowHydrant( bool bShow )
{
AcApDocument* pDoc = acDocManager->curDocument();
if (pDoc == NULL)
{
return;
}
acDocManager->lockDocument(pDoc, AcAp::kWrite);
Adesk::Int16 nColor = 6;
std::map<AcDbObjectId, Adesk::UInt16>::iterator itColor;
std::vector<AcDbObjectId>::const_iterator it;
std::vector<AcDbObjectId>::const_iterator itEnd = m_vecIds.end();
for (it = m_vecIds.begin(); it != itEnd; ++it)
{
TDbEquipment *pEquip = NULL;
acdbOpenObject(pEquip, *it, AcDb::kForWrite);
if (pEquip != NULL)
{
if (bShow)
{
pEquip->SetVisible(AcDb::kInvisible);
pEquip->setColorIndex(nColor);
}
else
{
pEquip->SetVisible(AcDb::kVisible);
if (m_mapColor.count(*it) > 0)
{
pEquip->setColorIndex(m_mapColor[*it]);
}
}
pEquip->close();
}
}
acedUpdateDisplay();
actrTransactionManager->flushGraphics();
acDocManager->unlockDocument(pDoc);
}
void CHydrantCalcDataDlg::OnTimer(UINT_PTR nIDEvent)
{
ShowHydrant(m_bShow);
m_bShow = !m_bShow;
CDialog::OnTimer(nIDEvent);
}
void CHydrantCalcDataDlg::GetEntityColor()
{
if (!m_mapColor.empty())
{
return;
}
std::vector<AcDbObjectId>::const_iterator it;
std::vector<AcDbObjectId>::const_iterator itEnd = m_vecIds.end();
for (it = m_vecIds.begin(); it != itEnd; ++it)
{
TDbEquipment *pEquip = NULL;
acdbOpenObject(pEquip, *it, AcDb::kForRead);
if (pEquip != NULL)
{
m_mapColor[*it] = pEquip->colorIndex();
pEquip->close();
}
}
}
// 测试使用
void CHydrantCalcDataDlg::Dim()
{
double dDist = 500;
if (DocGetCurMeterUnitDraw())
{
dDist = 0.5;
}
CString sPress;
std::map<AcDbObjectId,NODEPRESS>::iterator it;
std::map<AcDbObjectId,NODEPRESS>::iterator itEnd = m_mapCalcedNodePress.end();
for(it = m_mapCalcedNodePress.begin(); it != itEnd; ++it)
{
XPoint ptLoc;
TDbEquipment *pEquip = NULL;
acdbOpenObject(pEquip, it->first, AcDb::kForRead);
if (pEquip != NULL)
{
ptLoc = pEquip->GetLocation();
pEquip->close();
}
ptLoc += AcGeVector3d::kXAxis * dDist;
AcDbText *pText = new AcDbText;
pText->setHeight(500);
pText->setPosition(ptLoc);
sPress.Format(_T("%.3f"), it->second.dPress);
pText->setTextString(sPress);
AddToCurrentSpace(pText, Adesk::kTrue);
}
}
void CHydrantCalcDataDlg::OnBtnSheet()
{
UpdateData(TRUE);
HideDialog(this, TRUE);
XPoint pt;
if(acedGetPoint(NULL, _T("\n点取表格左上角位置:<返回>"), pt) != RTNORM)
{
HideDialog(this, FALSE);
return;
}
double nTextSize = g_nSheetHeight;
double nTableHeight = g_nSheetHeight+2;
AcDbObjectId idTextStyle=InitTwtTextStyle(g_csSheetStyle);
TDbSheet *pSheet = new TDbSheet;
TGridStyle gridStyle;
gridStyle.SetOverrideAll(TRUE);
gridStyle.SetTextHeight(nTextSize);
gridStyle.SetTextStyleId(idTextStyle);
TSheetTitle &title=pSheet->GetTitle();
title.SetHeight(nTextSize);
title.SetText(_T("消防计算表"));
TGridStyle &gridStyle2=title.GetGridStyle();
gridStyle2.SetTextHeight(nTextSize);
gridStyle2.SetTextStyleId(idTextStyle);
TDividerStyle &style=title.GetDividerStyle();
style.SetDividerFlag(TDividerStyle::kNone);
gridStyle.SetHorMode(AcDb::kTextCenter);
gridStyle.SetVerMode(AcDb::kTextVertMid);
gridStyle.SetLineSpaceFactor(0.2);
gridStyle.SetTextWrap(FALSE);
pSheet->SetGridStyle(gridStyle);
pSheet->SetRowHeight(nTableHeight);
pSheet->SetLayoutRotation(Ucs2Wcs(0.0));
pSheet->SetLocation(Ucs2Wcs(pt));
int nAllRow = (int)m_wndGrid.GetRowNum();
pSheet->InitSheet(nAllRow + 1, 10, nTableHeight, 50);
TDividerStyle &styleBorder = pSheet->GetBorderStyle();
styleBorder.SetLineWidth(0.2);
TSheetRow *pRow = pSheet->GetRow(0);
if (pRow != NULL)
{
TDividerStyle &styleRow = pRow->GetDividerStyle();
styleRow.SetLineWidth(0.2);
styleRow.SetDividerFlag(TDividerStyle::kLocal);
}
pSheet->SetLocation(Ucs2Wcs(pt));
XPoint ptex = pSheet->GetExtents(FALSE);
TSheetColumn column;
column.SetWidth(20);
pSheet->SetColumnAt(0, column);
column.SetWidth(20);
pSheet->SetColumnAt(1, column);
column.SetWidth(20);
pSheet->SetColumnAt(2, column);
column.SetWidth(20);
pSheet->SetColumnAt(3, column);
column.SetWidth(20);
pSheet->SetColumnAt(4, column);
column.SetWidth(15);
pSheet->SetColumnAt(5, column);
column.SetWidth(25);
pSheet->SetColumnAt(6, column);
column.SetWidth(15);
pSheet->SetColumnAt(7, column);
column.SetWidth(20);
pSheet->SetColumnAt(8, column);
column.SetWidth(20);
pSheet->SetColumnAt(9, column);
TGridCell &cell01=*(*pSheet)(0, 0);
cell01.SetText(_T("管段名称"));
TGridCell &cell02=*(*pSheet)(0, 1);
cell02.SetText(_T("起点压力"));
TGridCell &cell03=*(*pSheet)(0, 2);
cell03.SetText(_T("流量L/s"));
TGridCell &cell04=*(*pSheet)(0, 3);
cell04.SetText(_T("管长(m)"));
TGridCell &cell05=*(*pSheet)(0, 4);
cell05.SetText(_T("当量"));
TGridCell &cell06=*(*pSheet)(0, 5);
cell06.SetText(_T("管径(mm)"));
TGridCell &cell07=*(*pSheet)(0, 6);
cell07.SetText(_T("水力坡降"));
TGridCell &cell08=*(*pSheet)(0, 7);
cell08.SetText(_T("流速m/s"));
TGridCell &cell09=*(*pSheet)(0, 8);
cell09.SetText(_T("损失mH2O"));
TGridCell &cell010=*(*pSheet)(0, 9);
cell010.SetText(_T("终点压力"));
for(int j = 1; j < m_wndGrid.GetRowNum() + 1; j++)
{
for (int i = 0; i < m_wndGrid.GetColNum(); i++)
{
TGridCell &Cell=*(*pSheet)(j, i);
CString sText = m_wndGrid.GetCell(j-1,i).GetText().cs();
Cell.SetText(sText);
}
}
pSheet->AddToCSpace(TRUE);
TCHAR szTmp[32];
ads_getstring(NULL, _T("\n按任意键返回对话框:<返回>"), szTmp);
HideDialog(this, FALSE);
}