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

1390 lines
37 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/********************************************************************
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 <DbWell.h>
#include <rxregsvc.h>
#include <DbVerticalSection.h>
#include <DbWellDim.h>
#include <DbPool.h>
#include <PipeWireMonitor.h>
#include <dbxutil.h>
#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<ss.Length();j++){
Entity entTmp = ss[j];
if(entTmp.In(&ssAll) > 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;i<ss.Length();i++){
Entity entTmp = ss[i];
AcDbObjectId idTmp = NULL;
acdbGetObjectId(idTmp, entTmp);
idArray.append(idTmp);
}
}
len = idArray.length();
for(long i=0;i<len;i++){
AcDbObjectId idTmp = idArray[i];
ads_name ent;
Entity entTmp;
acdbGetAdsName(ent, idTmp);
entTmp = ent;
SSearchPipeList *pList = new SSearchPipeList();
pList->m_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;i<len;i++){
SSearchPipeList *pList = pListAll->m_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;i<len;i++){
SSearchPipeList *pList = pListAll->m_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;i<len;i++){
SSearchPipeList *pList = pListAll->m_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<TWellData> &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;i<len;i++){
SSearchPipeList *pList = pListAll->m_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;i<len;i++){
SSearchPipeList *pList = pListAll->m_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<AcDbObjectId> lstAttachment;
pPipe->GetAttachments(lstAttachment);
int len = lstAttachment.Length();
for(int m=0;m<len;m++)
{
AcDbObjectId idTmp = *lstAttachment[m];
OPENOBJ_BEGIN(idTmp, AcDb::kForWrite, TDbPipeAttachment, pValve);
if(pValve){
XPoint ptLoc = pValve->GetLocation();
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;i<len;i++){
SSearchPipeList *pList = pListAll->m_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<int>(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);
}