/******************************************************************** created: 2004/03/01 created: 1:3:2004 9:59 filename: f:\tg_dev\telecdev\twtkernal\outdoor.cpp file path: f:\tg_dev\telecdev\twtkernal file base: outdoor file ext: cpp author: 沈睿 purpose: 室外 *********************************************************************/ #include "stdafx.h" #include #include #include #include #include #include #include #include "InsBlockDlg.h" //#include "SprinklerDimPipeDnDlg.h" #include "jig.h" #include "SelectBlkDlg.h" #include "SprinklerByLineDlg.h" #include "GradientEleCalcDlg.h" #include "DbPump.h" //*************************************************************************************************** // 搜索室外井系统 //*************************************************************************************************** // sr modify 2004/10/25 2005/5/24 // 搜索室外系统,可以定终止井,entEnd输入空,自动搜索最后一个井 // 搜索原则:顺着流向方向找,如果有分叉就结束,有汇集不关,继续向前 BOOL AutoSearchOutdoorWell(Entity ent, AcDbObjectId idFront, SSearchPipeList *pListAll, PickSet &ssAll, BOOL bFeedSys) { AcDbObjectId id = NULL; acdbGetObjectId(id, ent); pListAll->m_ID = id; AcDbObjectIdArray idArray; int len(0); { PickSet ss(SS_FREE); if(ent.Is(_T("ATS_PIPE"))){ pListAll->m_iType = 0; OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbPipe, pPipe); if(pPipe){ //2008.4.30 增加以下代码, 在室外中, 标注管长不需要标注真实管长, 只需要标注平面管长 double dLen = pPipe->GetPlanLength(); pListAll->m_nLength = dLen; pListAll->m_iDn = (int)pPipe->GetDnDiameter(); } OPENOBJ_END(); pListAll->m_nI = GetPipeGradient(ent); GetAllPipeAndNodeByPipe(id, idFront, ss); } else if(ent.Is(_T("ATS_POOL"))){ //2009-4-3 池改用单独对象实现 OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbPool, pEquip); if(pEquip){ pListAll->m_nDang = pEquip->GetGroundEle(); } OPENOBJ_END(); pListAll->m_iType = 4; pListAll->m_csName = _T("HC"); GetAllPipeAndNodeByNode(id, idFront, ss); } else{ OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWell, pEquip); if(pEquip){ pListAll->m_nDang = pEquip->GetWellEleUp(); //井地面标高 pListAll->m_csName = pEquip->GetWellName(); //井编号 pListAll->m_iType = 3; AcDbObjectId idBlk = pEquip->GetBlock2d(); CString csBlkName = GetBlkNameById(idBlk); if(_tcsicmp(_T("$TWTSYS$00000186"), csBlkName) == 0) //阀门井 pListAll->m_iNum = 1; else if(_tcsicmp(_T("$TWTSYS$00000187"), csBlkName) == 0 || _tcsicmp(_T("$TWTSYS$00000336"), csBlkName) == 0) //检查井 pListAll->m_iNum = 2; else if(_tcsicmp(_T("$TWTSYS$00000190"), csBlkName) == 0) //水封井 pListAll->m_iNum = 3; else if(_tcsicmp(_T("$TWTSYS$00000191"), csBlkName) == 0) //跌水井 pListAll->m_iNum = 4; if(pEquip->IsDropWell()) pListAll->m_iNum = 4; pListAll->m_nStartPress = pEquip->GetWellEleDown(); //跌水井底标高 pListAll->m_nLost = pEquip->GetScale(); //井口直径 } else if(pListAll->m_iType != 4){ pListAll->m_iType = -1; if(!bFeedSys){ adsout << _T("\n2管线相交之处缺少井!"); } } OPENOBJ_END(); GetAllPipeAndNodeByNode(id, idFront, ss); } ss -= ent; PickSet ssDel(SS_FREE); XPoint ptFront; OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeNode, pNode); if(pNode){ ptFront = pNode->GetLocation(); ptFront.z = 0; } OPENOBJ_END(); for(long j=0;j 0){ return FALSE; } if(entTmp.Is(_T("ATS_PIPE"))){ OPENOBJ_BEGIN(entTmp, AcDb::kForRead, TDbPipe, pPipe); if(pPipe){ XPoint ptS = pPipe->StartPoint(); XPoint ptE = pPipe->EndPoint(); ptS.z = 0; ptE.z = 0; TPipeSys::FlowDirection dir = pPipe->GetFlowDir(); BOOL bDel = FALSE; if(!ent.Is(_T("ATS_POOL"))) { //从起点->终点 或 按【管线坡度】的方向 if(dir == TPipeSys::kUnknownDir){ bDel = TRUE; } else if(dir == TPipeSys::kFromStart){ double nDist = fabs(ads_distance(ptFront, ptS)); if(ptFront != ptS && nDist > 0.1) //xpoint != _distSnap=0.01 室外坐标过大的时候,精度太小 bDel = TRUE; } else if(dir == TPipeSys::kFromEnd){ double nDist = fabs(ads_distance(ptFront, ptE)); if(ptFront != ptE && nDist > 0.1) bDel = TRUE; } } double dn = pPipe->GetDnDiameter(); if(bDel) ssDel += entTmp; if(!bDel && dn < 0){ AfxMessageBox(_T("管线没有进行管径标注")); return TRUE; } } OPENOBJ_END(); } } ss -= ssDel; len = ss.Length(); if(len != 1) //自动搜索,只能顺水流方向搜索,如果有分叉就结束 return TRUE; ssAll += ss; for(long i=0;im_ID = idTmp; pList->m_pPrevious = pListAll; pListAll->m_lstNode.Append(pList); if(!AutoSearchOutdoorWell(entTmp, id, pList, ssAll, bFeedSys)) return FALSE; if(pList->m_lstNode.Length() == 0 && pList->m_iType == -1){ pListAll->m_lstNode.Remove(0); ssAll -= entTmp; } if(pList->m_lstNode.Length() == 0 && pList->m_iType == 0){ pListAll->m_lstNode.Remove(0); ssAll -= entTmp; } } return TRUE; } //将井编号写入链表 BOOL SetWellData(SSearchPipeList *pListAll, BOOL bFeedSys) { BOOL bRet = TRUE; AcDbObjectId id = NULL; id = pListAll->m_ID; ads_name adsent; acdbGetAdsName(adsent, id); Entity ent = adsent; if(ent.Is(_T("ATS_PIPE"))){ pListAll->m_iType = 0; OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbPipe, pPipe); if(pPipe){ //2008.4.30 增加以下代码, 在室外中, 标注管长不需要标注真实管长, 只需要标注平面管长 double dLen = pPipe->GetPlanLength(); // XPoint ptS = pPipe->StartPoint(); // XPoint ptE = pPipe->EndPoint(); // ptS.z = 0; // ptE.z = 0; // dLen = ads_distance(ptS, ptE); pListAll->m_nLength = dLen; pListAll->m_iDn = (int)pPipe->GetDnDiameter(); } OPENOBJ_END(); pListAll->m_nI = GetPipeGradient(ent); } // else if(IsPool(id)){ else if(ent.Is(_T("ATS_POOL"))){ OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbPool, pEquip); if(pEquip){ pListAll->m_nDang = pEquip->GetGroundEle(); } OPENOBJ_END(); pListAll->m_iType = 4; pListAll->m_csName = _T("HC"); //GetAllPipeAndNodeByNode(id, idFront, ss); } else{ OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWell, pEquip); if(pEquip){ pListAll->m_nDang = pEquip->GetWellEleUp(); //井地面标高 pListAll->m_csName = pEquip->GetWellName(); //井编号 pListAll->m_iType = 3; AcDbObjectId idBlk = pEquip->GetBlock2d(); CString csBlkName = GetBlkNameById(idBlk); if(_tcsicmp(_T("$TWTSYS$00000186"), csBlkName) == 0) //阀门井 pListAll->m_iNum = 1; else if(_tcsicmp(_T("$TWTSYS$00000187"), csBlkName) == 0 || _tcsicmp(_T("$TWTSYS$00000336"), csBlkName) == 0) //检查井 pListAll->m_iNum = 2; else if(_tcsicmp(_T("$TWTSYS$00000190"), csBlkName) == 0) //水封井 pListAll->m_iNum = 3; else if(_tcsicmp(_T("$TWTSYS$00000191"), csBlkName) == 0) //跌水井 pListAll->m_iNum = 4; if(pEquip->IsDropWell()) pListAll->m_iNum = 4; pListAll->m_nStartPress =pEquip->GetWellEleDown(); //跌水井底标高 pListAll->m_nLost = pEquip->GetScale(); //井口直径 } // else if(pListAll->m_iType == 4){ // pListAll->m_csName = _T("HC"); //井编号 // } else if(pListAll->m_iType != 4){ pListAll->m_iType = -1; if(!bFeedSys){ //如果是雨污系统,不允许管线相交之处缺少井// 2008-3-19 adsout << _T("\n2管线相交之处缺少井!"); return FALSE; } } OPENOBJ_END(); } long len = pListAll->m_lstNode.Length(); for(long i=0;im_lstNode[i]; bRet = SetWellData(pList, bFeedSys); } return bRet; } //本节点往下走,能通向终止井吗? BOOL IsNodeLink2EndWell(SSearchPipeList *pListAll, Entity entEnd) { BOOL bRet = FALSE; AcDbObjectId id = NULL; if(pListAll->m_iType == 3){ id = pListAll->m_ID; ads_name adsent; acdbGetAdsName(adsent, id); Entity ent = adsent; if(ent == entEnd) return TRUE; } long len = pListAll->m_lstNode.Length(); for(long i=0;im_lstNode[i]; bRet = IsNodeLink2EndWell(pList, entEnd); if(bRet) return TRUE; } return bRet; } //将整个系统pListAll的唯一通道提取出来放到pListNew中 //pListNew 是一个从 “起始井”到“终止井”的单向链表 BOOL SearchSysFromAll(SSearchPipeList *pListAll, SSearchPipeList *pListNew, Entity entEnd, PickSet &ssAll) { BOOL bRet = TRUE; //复制内容 pListNew->m_iDn = pListAll->m_iDn; pListNew->m_bNeedCale = pListAll->m_bNeedCale; pListNew->m_iNum = pListAll->m_iNum; pListNew->m_ID = pListAll->m_ID; pListNew->m_iType = pListAll->m_iType; pListNew->m_csName = pListAll->m_csName; pListNew->m_nLength = pListAll->m_nLength; pListNew->m_nPipeQ = pListAll->m_nPipeQ; pListNew->m_nDang = pListAll->m_nDang; pListNew->m_nStartPress = pListAll->m_nStartPress; pListNew->m_nI = pListAll->m_nI; pListNew->m_nV = pListAll->m_nV; pListNew->m_nLost = pListAll->m_nLost; long len = pListAll->m_lstNode.Length(); ssAll+=pListNew->m_ID; //重新确定水流方向 if(pListAll->m_iType == 0){ XPoint ptFront; if(pListAll->m_pPrevious != NULL){ OPENOBJ_BEGIN(pListAll->m_pPrevious->m_ID, AcDb::kForRead, TDbPipeNode, pNode); if(pNode){ ptFront = pNode->GetLocation(); } OPENOBJ_END(); } OPENOBJ_BEGIN(pListNew->m_ID, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe){ XPoint p1 = ptFront; p1.z = 0; XPoint p2 = pPipe->StartPoint(); p2.z = 0; if(p1 == p2) pPipe->SetFlowDir(TPipeSys::kFromStart); else pPipe->SetFlowDir(TPipeSys::kFromEnd); } OPENOBJ_END(); } for(long i=0;im_lstNode[i]; if(!IsNodeLink2EndWell(pList, entEnd)) continue; SSearchPipeList *pNodeNew = new SSearchPipeList(); pNodeNew->m_pPrevious = pListNew; pListNew->m_lstNode.Append(pNodeNew); bRet = SearchSysFromAll(pList, pNodeNew, entEnd, ssAll); } return bRet; } BOOL SearchOutdoorWell(Entity ent, Entity entEnd, SSearchPipeList *pListAll, PickSet &ssAll, BOOL bFeedSys) { if(!entEnd) //没有指定终止井 return AutoSearchOutdoorWell(ent, NULL, pListAll, ssAll, bFeedSys); //有指定井,由于系统绘制方向可能不是有序的,首先搜索整个系统 SSearchPipeList *pListAll2 = new SSearchPipeList(); PickSet ss(SS_FREE); ss += ent; if(!SearchSprinkPipeSys(ent, NULL, pListAll2, ss)){ delete pListAll2; return FALSE; } long len = ss.Length(); int pos = entEnd.In(&ss); // ss.Redraw(3); if(pos == 0){ ssAll+=ss; delete pListAll2; return FALSE; } // if(!SetWellData(pListAll2)){ // ssAll+=ss; // delete pListAll2; // return FALSE; // } BOOL ret = SearchSysFromAll(pListAll2, pListAll, entEnd, ssAll); if(!SetWellData(pListAll, bFeedSys)){ ssAll+=ss; delete pListAll2; return FALSE; } delete pListAll2; len = ssAll.Length(); return ret; } //把树结构的数据转化为DLIST链表结构 BOOL GetWellListData(SSearchPipeList *pListAll, DList &lstWellSys) { if(pListAll->m_iType == -1) return FALSE; TWellData *pList = new TWellData(); pList->m_iDn = pListAll->m_iDn; if(pListAll->m_iType == 0) { OPENOBJ_BEGIN(pListAll->m_ID, AcDb::kForRead, TDbPipe, pPipe); if(pPipe){ CString csMat = GetPipeMaterialByIdx(pPipe->GetMaterial()); double nDnOut = GetPipeOutDByDn(csMat, pList->m_iDn)*1000; pList->m_iSpare = (int)nDnOut; } OPENOBJ_END(); } if(pListAll->m_iType == 3 || pListAll->m_iType == 4){ pList->m_bIsWell = TRUE; AcDbObjectId id = pListAll->m_ID; ads_name ent; acdbGetAdsName(ent, id); CString csWellRadius = ReadXdata(ent, _T("TG-WELL-RADIUS")); CString csGroundEle = ReadXdata(ent, _T("TG-WELL-GroundEle")); BOOL bIsRectWell = FALSE; OPENOBJ_BEGIN(id, AcDb::kForRead, TDbEquipment, pEquip); if(pEquip){ AcDbObjectId idRec = pEquip->GetBlock2d(); if(_tcsicmp(GetBlkNameById(idRec), _T("$TwtSys$00000336")) == 0) bIsRectWell = TRUE; } OPENOBJ_END(); pList->m_nGroundEle = _tstof(csGroundEle); pList->m_nWellRadius = _tstof(csWellRadius)/2.0; //转化为半径 if(fabs(pList->m_nWellRadius) < 0.1) pList->m_nWellRadius = 350; if(bIsRectWell) pList->m_nWellRadius *= (-1); } else pList->m_bIsWell = FALSE; if(pListAll->m_iNum == 4) pList->m_bIsDropWell = TRUE; //如果接化粪池,管线长度要减去化粪池遮挡的部分 if(pListAll->m_iType == 0){ SSearchPipeList *pListPrevious = pListAll->m_pPrevious; BOOL bFlag = FALSE; if(pListPrevious != NULL && pListPrevious->m_iType == 4){ bFlag = TRUE; } else if(pListAll->m_lstNode.Length() == 1){ pListPrevious = pListAll->m_lstNode[0]; if(pListPrevious != NULL && pListPrevious->m_iType == 4) //4:化粪池 bFlag = TRUE; } if(bFlag){ AcDbObjectId id = pListPrevious->m_ID; OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPool, pEquip); if(pEquip){ double nXScale = pEquip->GetSizeX(); if(!DocGetMeterUnitDraw()) nXScale = nXScale/2000; else nXScale = nXScale/2.0; pListAll->m_nSpare = pListAll->m_nLength + nXScale;//管长=对象长-池长度/2 // pListAll->m_nLength = pListAll->m_nLength - nXScale/2000;//管长=对象长-池长度/2 } OPENOBJ_END(); } } pList->m_csName = pListAll->m_csName; pList->m_ID = pListAll->m_ID; pList->m_nI = pListAll->m_nI; pList->m_nUpEle = pListAll->m_nDang; //井地面标高 pList->m_nDownEle = pListAll->m_nStartPress; //跌水井底标高 pList->m_nLength = pListAll->m_nLength; pList->m_dRealLength = pListAll->m_nSpare; //真实管长用m_nSpare存放 // if(!DocGetMeterUnitDraw()) // pList->m_nLength = pList->m_nLength/1000; lstWellSys.Append(pList); BOOL bRet = TRUE; long len = pListAll->m_lstNode.Length(); for(long i=0;im_lstNode[i]; bRet = GetWellListData(pList, lstWellSys); } return bRet; } //*************************************************************************************************** // 坡度定高 //*************************************************************************************************** //重新确定水流方向 void ResetPipeDir(SSearchPipeList *pListAll) { long len = pListAll->m_lstNode.Length(); if(pListAll->m_iType == 0){ XPoint ptFront; if(pListAll->m_pPrevious != NULL){ // 考虑管连接化粪池 cet 2011.11.8 add // OPENOBJ_BEGIN(pListAll->m_pPrevious->m_ID, AcDb::kForRead, TDbPipeNode, pNode); // if(pNode){ // ptFront = pNode->GetLocation(); // } // OPENOBJ_END(); OPENOBJ_BEGIN(pListAll->m_pPrevious->m_ID, AcDb::kForRead, TDbPool, pPool); if(pPool != NULL) // 先查看是否为化粪池 { int nNum = pPool->GetInterfaceNum(); TPipeInterface face; for(int j = 0; j < nNum; j++) { pPool->GetInterface(j, face); if (face.m_idPipe == pListAll->m_ID) { ptFront = face.m_ptLocation; break; } } } OPENOBJ_END(); if (!ptFront) { OPENOBJ_BEGIN(pListAll->m_pPrevious->m_ID, AcDb::kForRead, TDbPipeNode, pNode); if(pNode) { ptFront = pNode->GetLocation(); } OPENOBJ_END(); } } OPENOBJ_BEGIN(pListAll->m_ID, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe && !!ptFront){ XPoint p1 = ptFront; p1.z = 0; XPoint p2 = pPipe->StartPoint(); p2.z = 0; if(p1 == p2) pPipe->SetFlowDir(TPipeSys::kFromEnd); else pPipe->SetFlowDir(TPipeSys::kFromStart); } OPENOBJ_END(); } for(long i=0;im_lstNode[i]; ResetPipeDir(pList); } } // 修改管线上的附件和接口设备 cet 2010.9.27 add void ModifyPipeEquimentAttachment(TDbPipe *pPipe) { if (pPipe != NULL) { XPoint ptTmp = pPipe->StartPoint(); XPoint ptTmp2 = pPipe->EndPoint(); AcDbObjectId nodeId1(NULL), nodeId2(NULL); nodeId1 = pPipe->GetNode(0); nodeId2 = pPipe->GetNode(1); OPENOBJ_BEGIN(nodeId1, AcDb::kForRead, TDbEquipment, pEquip); if(pEquip && !pEquip->isKindOf(TDbPump::desc())) { if(pEquip->upgradeOpen()==Acad::eOk) { XPoint ptTmp4 = pEquip->GetInsert(); if(ptTmp.Distance2d(ptTmp4) < 1e-3) { ptTmp4.z = ptTmp.z; } else { ptTmp4.z = ptTmp2.z; } pEquip->SetInsert(ptTmp4); XPoint ptTmp3 = pEquip->GetLocation(); if(ptTmp.Distance2d(ptTmp3) < 1e-3) { ptTmp3.z = ptTmp.z; } else { ptTmp3.z = ptTmp2.z; } pEquip->SetLocation(ptTmp3); pEquip->downgradeOpen(); } } OPENOBJ_END(); OPENOBJ_BEGIN(nodeId2, AcDb::kForRead, TDbEquipment, pEquip); if(pEquip && !pEquip->isKindOf(TDbPump::desc())) { if(pEquip->upgradeOpen()==Acad::eOk) { XPoint ptTmp4 = pEquip->GetInsert(); if(ptTmp.Distance2d(ptTmp4) < 1e-3) { ptTmp4.z = ptTmp.z; } else { ptTmp4.z = ptTmp2.z; } pEquip->SetInsert(ptTmp4); XPoint ptTmp3 = pEquip->GetLocation(); if(ptTmp.Distance2d(ptTmp3) < 1e-3) { ptTmp3.z = ptTmp.z; } else { ptTmp3.z = ptTmp2.z; } pEquip->SetLocation(ptTmp3); pEquip->downgradeOpen(); } } OPENOBJ_END(); DList lstAttachment; pPipe->GetAttachments(lstAttachment); int len = lstAttachment.Length(); for(int m=0;mGetLocation(); AcDbLine line(ptTmp, ptTmp2); XPoint pt; line.getClosestPointTo(ptLoc, AcGeVector3d::kZAxis, pt); ptLoc = pt; pValve->SetLocation(ptLoc); // 设置方向 XCurveSegment seg(ptTmp, ptTmp2, 0); XVector3D vectBase(seg.EndPoint().x - seg.StartPoint().x, seg.EndPoint().y - seg.StartPoint().y, seg.EndPoint().z - seg.StartPoint().z); vectBase.Normalize(); if(vectBase.y < -0.000001 ||(vectBase.y<0.000001&&vectBase.y>=-0.000001&&vectBase.x<0)) //管线逆向绘制 { vectBase.x = -vectBase.x; vectBase.y = -vectBase.y; } pValve->SetDirection(vectBase); } OPENOBJ_END(); } } } // 修改管线上的附件和接口设备 cet 2010.9.27 add void ModifyPipeEquimentAttachment(AcDbObjectId idPipe) { TDbPipe *pPipe = NULL; acdbOpenObject(pPipe, idPipe, AcDb::kForRead); if (pPipe != NULL) { ModifyPipeEquimentAttachment(pPipe); pPipe->close(); } } //计算标高 void CalcPipeEle(SSearchPipeList *pListAll) { double dMeter(1); if(!DocGetMeterUnitDraw()) dMeter = 1000; long len = pListAll->m_lstNode.Length(); double dCalcEle(0), dEle(0); if(pListAll->m_iType == 0){ dCalcEle = pListAll->m_nSpare; // if(pListAll->m_pPrevious != NULL || fabs(dCalcEle) > 0.01){ if(pListAll->m_pPrevious != NULL) dEle = pListAll->m_pPrevious->m_nSpare; else dEle = dCalcEle; OPENOBJ_BEGIN(pListAll->m_ID, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe){ double dLen = pPipe->GetPlanLength(); // if(!DocGetMeterUnitDraw()) // dLen = dLen/1000; double dGradient = pPipe->GetPipeGradient(); dCalcEle = dEle + dLen * dGradient; if(pPipe->GetFlowDir() == TPipeSys::kFromStart) { pPipe->StartPoint().z = dCalcEle*dMeter; pPipe->EndPoint().z = dEle*dMeter; } else { pPipe->StartPoint().z = dEle*dMeter; pPipe->EndPoint().z = dCalcEle*dMeter; } // cet 2010.9.27 add 修改与管线相关的附件和设备 ModifyPipeEquimentAttachment(pPipe); } OPENOBJ_END(); // } } for(long i=0;im_lstNode[i]; if(pListAll->m_iType == 0) pList->m_nSpare = dCalcEle; CalcPipeEle(pList); } } void CalcEleByGradient() { Entity entMainPipe; RBList rbMask(RTDXF0, _T("ATS_PIPE,ATS_PIPECANAL"), NULL); double dMeter(1); if(!DocGetMeterUnitDraw()) dMeter = 1000; if(SelectEntity(_T("\n请选择管线下游端点<退出>"), entMainPipe, rbMask) != RTNORM) return; SSearchPipeList *pListAll = new SSearchPipeList(); PickSet ssAll(SS_FREE); ssAll += entMainPipe; if(!SearchSprinkPipeSys(entMainPipe, NULL, pListAll, ssAll)){ AfxMessageBox(_T("系统有回路!")); delete pListAll; return; } ads_name entHead; if(pListAll->m_lstNode.Length() == 2) { SSearchPipeList *p1 = pListAll->m_lstNode[0]; SSearchPipeList *p2 = pListAll->m_lstNode[1]; if((p1->m_lstNode.Length() == 1 && p2->m_lstNode.Length() == 1) || (p1->m_lstNode.Length() > 1 && p2->m_lstNode.Length() > 1)) { adsout << _T("\n没有正确选择末端管线,无法计算!"); delete pListAll; return; } if(p1->m_lstNode.Length() == 0) acdbGetAdsName(entHead, p1->m_ID); else if(p2->m_lstNode.Length() == 0) acdbGetAdsName(entHead, p2->m_ID); } int len = ssAll.Length(); if(len == 3) { adsout << _T("单管修改标高请直接双击管线即可.本命令用于多管标高计算\n"); delete pListAll; return; } XPoint ptS, ptE, ptLoc; double dEle(0); GetPipePoint(entMainPipe, ptS, ptE); OPENOBJ_BEGIN(entHead, AcDb::kForRead, TDbPipeNode, pNode); if(pNode){ XPoint ptS2 = ptS; XPoint ptE2 = ptE; ptS2.z = 0; ptE2.z = 0; ptLoc = pNode->GetLocation(); ptLoc.z = 0; //先把主管线流向给纠正 OPENOBJ_BEGIN(entMainPipe, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe){ if(ptLoc == ptS2) { pPipe->SetFlowDir(TPipeSys::kFromEnd); dEle = ptS.z / dMeter; } else if(ptLoc == ptE2) { pPipe->SetFlowDir(TPipeSys::kFromStart); dEle = ptE.z / dMeter; } } OPENOBJ_END(); } OPENOBJ_END(); CString csPrompt; csPrompt.Format(_T("\n输入此下游端点的标高<%.3f米>:"), dEle); ads_getreal(csPrompt, &dEle); pListAll->m_nSpare = dEle; if(pListAll->m_pPrevious != NULL) pListAll->m_pPrevious->m_nSpare = dEle; //再把系统其他管线流向都纠正 ResetPipeDir(pListAll); CalcPipeEle(pListAll); delete pListAll; } //*************************************************************************************************** // 坡高计算 //*************************************************************************************************** // 检查上下游端点是否在同一管道系统 pListAll为下游端点获得的 // 管道系统 ent为上游端点 BOOL IsInSamePipeSys(SSearchPipeList *pListAll, Entity &ent) { if (pListAll == NULL) { return FALSE; } AcDbObjectId id; acdbGetObjectId(id, ent); if (pListAll->m_ID == id) { if (pListAll->m_lstNode.Length() > 1 || pListAll->m_lstNode.Length() == 0) { return FALSE; } else { if (pListAll->m_lstNode[0]->m_lstNode.Length() == 0) { return TRUE; } return FALSE; } } for (int i = 0; i < pListAll->m_lstNode.Length(); i++) { if (IsInSamePipeSys(pListAll->m_lstNode[i], ent)) { return TRUE; } } return FALSE; } // 修改主管线流向 void ModifyMainPipeDir(Entity &entMainPipe, Entity &entHead) { XPoint ptS, ptE, ptLoc; GetPipePoint(entMainPipe, ptS, ptE); OPENOBJ_BEGIN(entHead, AcDb::kForRead, TDbPipeNode, pNode); if(pNode) { XPoint ptS2 = ptS; XPoint ptE2 = ptE; ptS2.z = 0; ptE2.z = 0; ptLoc = pNode->GetLocation(); ptLoc.z = 0; //先把主管线流向给纠正 OPENOBJ_BEGIN(entMainPipe, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe) { if(ptLoc == ptS2) { pPipe->SetFlowDir(TPipeSys::kFromEnd); } else if(ptLoc == ptE2) { pPipe->SetFlowDir(TPipeSys::kFromStart); } } OPENOBJ_END(); } OPENOBJ_END(); } // 管线端点标高: bUp = true 上游端点标高,否则下游端点标高 double GetPipeEle(Entity &ent, BOOL bUp) { double dMeter = 1.0; if (!DocGetMeterUnitDraw()) { dMeter = 1000.0; } double dEle = 0.0; OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL) { TPipeSys::FlowDirection sys; sys = pPipe->GetFlowDir(); if (sys == TPipeSys::kFromEnd) { if (bUp) { dEle = pPipe->EndPoint().z / dMeter; } else { dEle = pPipe->StartPoint().z / dMeter; } } else { if (bUp) { dEle = pPipe->StartPoint().z / dMeter; } else { dEle = pPipe->EndPoint().z / dMeter; } } } OPENOBJ_END(); return dEle; } // 获得上游端点 SSearchPipeList* GetUpPipe(SSearchPipeList *pListAll, Entity &ent) { if (pListAll == NULL) { return NULL; } AcDbObjectId id; acdbGetObjectId(id, ent); if (pListAll->m_ID == id) { if (pListAll->m_lstNode.Length() == 1) { pListAll = pListAll->m_lstNode[0]; } return pListAll; } SSearchPipeList* pLstRes = NULL; for (int i = 0; i < pListAll->m_lstNode.Length(); i++) { SSearchPipeList* pLst = pListAll->m_lstNode[i]; pLstRes = GetUpPipe(pLst, ent); if (pLstRes != NULL) { return pLstRes; } } return pLstRes; } // 反算标高(从下游端点计算) void CalcPipeEleByAntitone(SSearchPipeList *pListAll, double dGrad, BOOL bGrad) { double dMeter(1); if(!DocGetMeterUnitDraw()) dMeter = 1000; long nLen = pListAll->m_lstNode.Length(); double dCalcEle(0), dEle(0); dCalcEle = pListAll->m_nSpare; if(pListAll->m_iType == 0) // 管线 { if(pListAll->m_pPrevious != NULL) dEle = pListAll->m_pPrevious->m_nSpare; else dEle = dCalcEle; OPENOBJ_BEGIN(pListAll->m_ID, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe != NULL) { double dLen = pPipe->GetPlanLength(); if (bGrad) // 按管线本身坡度计算 { dGrad = pPipe->GetPipeGradient(); } else { pPipe->SetPipeGradient(dGrad); } dCalcEle = dEle + dLen * dGrad; if(pPipe->GetFlowDir() == TPipeSys::kFromStart) { pPipe->StartPoint().z = dCalcEle * dMeter; pPipe->EndPoint().z = dEle * dMeter; } else { pPipe->StartPoint().z = dEle * dMeter; pPipe->EndPoint().z = dCalcEle * dMeter; } ModifyPipeEquimentAttachment(pPipe); } OPENOBJ_END(); } for(long i=0;i < nLen; i++) { SSearchPipeList *pList = pListAll->m_lstNode[i]; pList->m_nSpare = dCalcEle; CalcPipeEleByAntitone(pList, dGrad, bGrad); } } // 计算支路标高 void CalcSpurTrackEle(SSearchPipeList *pListAll) { for (int i = 0; i < pListAll->m_lstNode.Length(); i++) { SSearchPipeList *pLst = NULL; pLst = pListAll->m_lstNode[i]; if (pLst->m_iSpare != 1) { CalcPipeEleByAntitone(pLst, 0.0, TRUE); } else { CalcSpurTrackEle(pLst); } } } // 正算标高(从上游端点计算) void CalcPipeEleByPositive(SSearchPipeList *pListAll, double dGrad, BOOL bGrad) { double dMeter = 1.0; if (!DocGetMeterUnitDraw()) { dMeter = 1000.0; } SSearchPipeList *pLst = NULL; // 保存管网的下游节点 while(pListAll != NULL) // 计算主干标高 { double dCalcEle = 0; double dEle = 0.0; dCalcEle = pListAll->m_nSpare; dEle = dCalcEle; if(pListAll->m_iType == 0) // 管线 { OPENOBJ_BEGIN(pListAll->m_ID, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe != NULL) { double dLen = pPipe->GetPlanLength(); if (bGrad) { dGrad = pPipe->GetPipeGradient(); } else { pPipe->SetPipeGradient(dGrad); } dCalcEle = dEle - dLen * dGrad; if(pPipe->GetFlowDir() == TPipeSys::kFromStart) { pPipe->EndPoint().z = dCalcEle * dMeter; pPipe->StartPoint().z = dEle * dMeter; } else { pPipe->EndPoint().z = dEle * dMeter; pPipe->StartPoint().z = dCalcEle * dMeter; } ModifyPipeEquimentAttachment(pPipe); } OPENOBJ_END(); } pListAll->m_iSpare = 1; // 为1表示已经处理 pLst = pListAll; pListAll = pListAll->m_pPrevious; if (pListAll != NULL) { pListAll->m_nSpare = dCalcEle; } } // 处理支路 CalcSpurTrackEle(pLst); } // 上游端点到下游端点管线长度 double GetTotalLen(SSearchPipeList *pListAll) { double dLen = 0.0; while(pListAll != NULL) { if(pListAll->m_iType == 0) // 管线 { OPENOBJ_BEGIN(pListAll->m_ID, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL) { dLen += pPipe->GetPlanLength(); } OPENOBJ_END(); } pListAll = pListAll->m_pPrevious; } return dLen; } // cet 2011.6.3 add 将与井相连的管道的管内底标高添加到井中,以便标注等使用 void AddPipeEleForWell(SSearchPipeList *pListAll) { if (pListAll == NULL) { return; } if (pListAll->m_iType == 3) // 井 { TDbWell *pWell = NULL; acdbOpenObject(pWell, pListAll->m_ID, AcDb::kForWrite); if (pWell != NULL) { double dMeter = 1; if (!DocGetMeterUnitDraw()) { dMeter = 1000; } int nNum = pWell->GetInterfaceNum(); for(int j = 0; j < nNum; j++) { TPipeInterface face; pWell->GetInterface(j, face); XPoint ptLoc = pWell->GetLocation(); TDbPipe *pPipe = NULL; acdbOpenObject(pPipe, face.m_idPipe, AcDb::kForRead); if (pPipe != NULL) { double dEle = 0.0; if (ptLoc.Distance2d(pPipe->StartPoint()) < _DIST_SNAP) // 井插入点与管起点重合 { dEle = pPipe->StartPoint().z / dMeter; } else // 井插入点与管终点重合 { dEle = pPipe->EndPoint().z / dMeter; } CString sMat = GetPipeMaterialByIdx(pPipe->GetMaterial()); double dRadius = GetPipeDjByDn(sMat, static_cast(pPipe->GetDnDiameter())) * 0.5; // 管内半径 dEle -= dRadius; CString sEle; sEle.Format(_T("%.3f"), dEle); pWell->SetPipeEndEle(face.m_idPipe, sEle); pPipe->close(); } } pWell->close(); } } for (int i = 0; i < pListAll->m_lstNode.Length(); i++) { AddPipeEleForWell(pListAll->m_lstNode[i]); } } // 主函数 void CalcGradientEle() { Entity entUpPipe, entLowPipe; XPoint ptPick; RBList rbMask(RTDXF0, _T("ATS_PIPE,ATS_PIPECANAL"), NULL); double dMeter(1); if(!DocGetMeterUnitDraw()) dMeter = 1000; TCHAR chRet = _T('\0'); int nRet = 0; BOOL bUp = FALSE; // 选择的是否为管线上游端点 INITGET_BEG(0, _T("S")); nRet = SelectEntity(_T("\n请选择管线下游端点[选择上游端点(S)]<退出>:"), entLowPipe, ptPick, rbMask, _T("S"),chRet); INITGET_END(); #if (ADS == 19) if (chRet == _T('\0')) { TCHAR szCh[20]; acedGetInput(szCh); chRet = szCh[0]; } #endif if (nRet == RTKWORD) { if (chRet == _T('S')) { bUp = TRUE; if(SelectEntity(_T("\n请选择上游端点位置<退出>"), entUpPipe, rbMask) != RTNORM) { return; } if(SelectEntity(_T("\n请选择下游端点位置<退出>"), entLowPipe, rbMask) != RTNORM) { return; } } } else if (nRet != RTNORM) { return; } SSearchPipeList *pListAll = new SSearchPipeList(); PickSet ssAll(SS_FREE); ssAll += entLowPipe; if(!SearchSprinkPipeSys(entLowPipe, NULL, pListAll, ssAll)) { AfxMessageBox(_T("系统有回路!")); delete pListAll; return; } ads_name entHead; if(pListAll->m_lstNode.Length() == 2) { SSearchPipeList *p1 = pListAll->m_lstNode[0]; SSearchPipeList *p2 = pListAll->m_lstNode[1]; if((p1->m_lstNode.Length() == 1 && p2->m_lstNode.Length() == 1) || (p1->m_lstNode.Length() > 1 && p2->m_lstNode.Length() > 1)) { adsout << _T("\n没有正确选择末端管线,无法计算!"); delete pListAll; return; } if(p1->m_lstNode.Length() == 0) acdbGetAdsName(entHead, p1->m_ID); else if(p2->m_lstNode.Length() == 0) acdbGetAdsName(entHead, p2->m_ID); } int nLen = ssAll.Length(); if(nLen == 3) { adsout << _T("单管修改标高请直接双击管线即可.本命令用于多管标高计算\n"); delete pListAll; return; } // 修改管线流向 Entity xx(entHead); ModifyMainPipeDir(entLowPipe, xx); ResetPipeDir(pListAll); if (bUp) // 管线上游端点 { if (!IsInSamePipeSys(pListAll, entUpPipe)) { adsout << _T("\n上下游端点不在同一管道系统或上游端点不是末端管线!"); return; } CGradientEleCalcDlg dlg; dlg.SetUpElevation(bUp); dlg.SetUpEle(GetPipeEle(entUpPipe, TRUE)); dlg.SetLowEle(GetPipeEle(entLowPipe, FALSE)); if (dlg.DoModal() != IDOK) { return; } BOOL bLowEle = FALSE; //是否设置了下游端点标高 bLowEle = dlg.GetChkLowEle(); if (bLowEle) // 按上下游端点标高计算 { double dUpEle = dlg.GetUpEle(); // 上游端点标高 double dLowEle = dlg.GetLowEle(); // 下游端点标高 SSearchPipeList *pLstUp = NULL; pLstUp = GetUpPipe(pListAll, entUpPipe); // 上游端点 if (pLstUp != NULL) { double dLen = GetTotalLen(pLstUp); // 上游端点到下游端点管线长度 double dGrad = (dUpEle - dLowEle) / dLen; // 主干上管线的坡度 pLstUp->m_nSpare = dUpEle; CalcPipeEleByPositive(pLstUp, dGrad, FALSE); // 正算标高 } } else // 按上游端点和坡度计算 { double dGrad = dlg.GetGradient(); double dEle = dlg.GetUpEle(); BOOL bGrad = dlg.GetChkGradient(); SSearchPipeList *pLstUp = NULL; pLstUp = GetUpPipe(pListAll, entUpPipe); if (pLstUp != NULL) { pLstUp->m_nSpare = dEle; CalcPipeEleByPositive(pLstUp, dGrad, bGrad); // 正算标高 } } } else // 管线下游端点 { CGradientEleCalcDlg dlg; dlg.SetUpElevation(bUp); dlg.SetPipeSys(pListAll); dlg.SetLowEle(GetPipeEle(entLowPipe, FALSE)); if (dlg.DoModal() != IDOK) { return; } BOOL bUpEle = FALSE; // 是否设置了上游端点标高 bUpEle = dlg.GetChkUpEle(); if (bUpEle) // 按上下游端点标高计算 { double dUpEle = dlg.GetUpEle(); // 上游端点标高 double dLowEle = dlg.GetLowEle(); // 下游端点标高 dlg.GetEnt(entUpPipe); if (!IsInSamePipeSys(pListAll, entUpPipe)) { adsout << _T("\n上下游端点不在同一管道系统或上游端点不是末端管线!"); return; } SSearchPipeList *pLstUp = NULL; pLstUp = GetUpPipe(pListAll, entUpPipe); // 上游端点 if (pLstUp != NULL) { double dLen = GetTotalLen(pLstUp); // 上游端点到下游端点管线长度 double dGrad = (dUpEle - dLowEle) / dLen; // 主干上管线的坡度 pLstUp->m_nSpare = dUpEle; CalcPipeEleByPositive(pLstUp, dGrad, FALSE); // 正算标高 } } else // 按下游端点和坡度计算 { double dGrad = dlg.GetGradient(); double dEle = dlg.GetLowEle(); BOOL bGrad = dlg.GetChkGradient(); pListAll->m_nSpare = dEle; CalcPipeEleByAntitone(pListAll,dGrad, bGrad); // 反算标高 } } // cet 2011.6.3 add 将与井相连的管道的管内底标高添加到井中,以便标注等使用 AddPipeEleForWell(pListAll); }