Files
envi-code/SourceCode/Code2026/tg_shs/shs_utility/AreaModel.cpp
T
2026-09-28 15:28:50 +08:00

1039 lines
28 KiB
C++

#include "stdafx.h"
#include "resource.h"
#include "project.h"
#include "areamodel.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//支持房间对象
TBArea::TBArea(AcDbObjectId id):m_fAreaFactor(1.0)//ok
{
TDbSpace *pSpace=NULL;
acdbOpenObject(pSpace,id,AcDb::kForRead);
if(pSpace!=NULL)
{
m_sCode=(const TCHAR*)(pSpace->m_sCode);
m_sName=(const TCHAR*)(pSpace->m_sName);
m_polyOutline=pSpace->m_outline;
if(pSpace->IsHalfArea())//用来表示计算一半面积
m_fAreaFactor=0.5;
m_fFactArea=m_polyOutline.Area()*m_fAreaFactor;//add by fxj
pSpace->close();
}
else
{
Entity ent;
acdbGetAdsName(ent.name,id);
m_polyOutline=XPoly2D(ent);
}
m_polyOutline.SetElevation(0);
m_polyOutline.Compress();
m_bCliped=false;//add by fxj
}
bool g_bUseNameCmp=false;//by fxj 090625 默认用户号排序
bool TBArea::operator >(const TBArea&a)const//ok
{
if(g_bUseNameCmp)
return _tcsicmp(m_sName,a.m_sName)>0;
else
return _tcsicmp(m_sCode,a.m_sCode)>0;
}
bool TBArea::operator ==(const TBArea&a)const//ok
{
if(g_bUseNameCmp)
return _tcsicmp(m_sName,a.m_sName)==0;
else
return _tcsicmp(m_sCode,a.m_sCode)==0;
}
void TBArea::ClipBy(TBAList& lstOutline,DList<XPoly2D>& lstHole)//ok 还不支持对建筑轮廓的剪裁
{//by fxj 090701 被洞口裁减
XPoly2D poly=m_polyOutline;
AcDbRegion *pReg=poly.AsRegion();
for(int i=0;i<lstHole.Length();i++)
{
AcDbRegion *pRegTemp=lstHole[i]->AsRegion();
pReg->booleanOper(AcDb::kBoolSubtract,pRegTemp);
}
pReg->getArea(m_fFactArea);
//if(lstOutline.GetLength()>0)
//{
// lstOutline.MoveToFirst();
// ((TBAOutline *)(lstOutline.GetCurData()))->AddDefinedValidGeomArea(m_fFactArea);
//}
m_bCliped=true;
}//被建筑轮廓和洞口裁剪
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//几何面积
double TBAList::GetGeomArea()//ok
{
double a=0;
for(MoveToFirst();!IsOut();MoveToNext())
a+=GetCurData()->GetOutline().Area();
return a;
}
//几何区域建筑面积
double TBAList::GetGeomBuildArea()//ok
{
double a=0;
for(MoveToFirst();!IsOut();MoveToNext())
a+=GetCurData()->GetGeomBuildArea();
return a;
}
//统计用最终建筑面积
double TBAList::GetStatisticsBuildArea()//ok
{
double a=0;
for(MoveToFirst();!IsOut();MoveToNext())
a+=GetCurData()->GetStatisticsBuildArea();
return a;
}
//按比例分摊面积
void TBAList::ShareArea(double area)//ok
{
double allArea=0;
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAHouse *pHouse=(TBAHouse*)GetCurData();
// Zyu modify on 100906,套内建筑面积包括阳台面积
//allArea+=pHouse->GetBuildArea();
allArea+=pHouse->GetBuildAreaEx();
}
if(allArea<1E-10)
return;
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAHouse *pHouse=(TBAHouse*)GetCurData();
// Zyu modify on 100906,套内建筑面积包括阳台面积
//double K=pHouse->GetBuildArea()/allArea;
double K=pHouse->GetBuildAreaEx()/allArea;
pHouse->AddSharedArea(area*K);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TBAOutline::TBAOutline(AcDbObjectId id):TBArea(id),m_fHoleGeomArea(0),m_fDefinedValidGeomArea(0)//ok
{
}
//轮廓内洞口几何面积(洞口不能重叠)
void TBAOutline::ClipBy(DList<XPoly2D>& lstHole)//ok
{
//当前未考虑洞口
// m_fHoleGeomArea=0;
//add by fxj
XPoly2D poly=m_polyOutline;
AcDbRegion *pReg=poly.AsRegion();
for(int i=0;i<lstHole.Length();i++)
{
AcDbRegion *pRegTemp=lstHole[i]->AsRegion();
pReg->booleanOper(AcDb::kBoolSubtract,pRegTemp);
}
pReg->getArea(m_fFactArea);
// sg add 100716,解决组成面域不成功,崩溃的问题
if (pReg != NULL)
{
pReg->getArea(m_fFactArea);
}
m_fHoleGeomArea=GetOutline().Area()-m_fFactArea;
m_bCliped=true;
}
//有效区域内默认公摊建筑面积=有效区域内默认公摊几何面积*有效区域的面积系数
double TBAOutline::GetDefaultShareArea()const//ok
{
//有效区域内默认公摊几何面积=有效区域几何面积-有效区域内洞口几何面积-有效区域内已定义非洞口几何面积(套内几何面积和共用几何面积)
double geomArea=GetOutline().Area()-m_fHoleGeomArea-m_fDefinedValidGeomArea;
return geomArea*GetAreaFactor();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TBAHole::TBAHole(AcDbObjectId id):TBArea(id)//ok
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TBASpace::TBASpace(AcDbObjectId id):TBArea(id)//ok
{
}
//被建筑轮廓和洞口裁剪,计算最终面积系数
void TBASpace::ClipBy(TBAList& lstOutline,DList<XPoly2D>& lstHole)//ok
{
//当前只支持完全在外轮廓内的情况.
TBArea::ClipBy(lstOutline,lstHole);//add by fxj
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TBABalcony::TBABalcony(AcDbObjectId id):TBArea(id)//ok
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TBAShare::TBAShare(AcDbObjectId id):TBArea(id),m_nType(kShareInFloor)//ok
{
CString sName((const TCHAR*)m_sName);
if(sName.Find(_T("全楼公摊"))>=0)
m_nType=kShareInBuilding;
}
//1,计算在建筑轮廓内的、且不包括洞口区域的几何面积
//2,计算裁剪洞口后最终面积系数
void TBAShare::ClipBy(TBAList& lstOutline,DList<XPoly2D>& lstHole)//ok
{//by fxj
TBArea::ClipBy(lstOutline,lstHole);
if(lstOutline.GetLength()>0)
{
lstOutline.MoveToFirst();
((TBAOutline *)(lstOutline.GetCurData()))->AddDefinedValidGeomArea(m_fFactArea);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Zyu add on 101119,支持名称分类
CStringArray TBAHouse::m_arHallString; // 厅字符串数组
CStringArray TBAHouse::m_arRoomString; // 室字符串数组
CStringArray TBAHouse::m_arToiletString; // 卫字符串数组
//ssSpace[in/out]返回套外房间
//ssBalcony[in/out]返回套外阳台
TBAHouse::TBAHouse(AcDbObjectId idHouse,PickSet&ssSpace,PickSet &ssBalcony,TBAFloor *pFloor):
TBArea(idHouse),m_fSharedArea(0),m_bHouseUp(false),m_pHouseUp(NULL),m_pFloor(pFloor)//ok
{
TDbSpace *pSpace=NULL;
acdbOpenObject(pSpace,idHouse,AcDb::kForRead);
if(pSpace==NULL)
return;
DualList<AcDbObjectId> lstWallId;//套内墙体
for(long i=0;i<pSpace->m_lstWallEnclosure.Length();i++)
lstWallId.FindOrAddTail(*pSpace->m_lstWallEnclosure[i]);
//选择套内房间
{
XPoly2D polyHouse=pSpace->m_outline;
polyHouse.SetElevation(0);
PickSet ssMySpace(SS_FREE);
for(long i=0;i<ssSpace.Length();i++)
{
Entity ent=ssSpace[i];
OPENOBJ_BEGIN(ent,AcDb::kForRead,TDbSpace,pSpace1)
if(pSpace1!=NULL)
{
XPoly2D polySpace=pSpace1->m_outline;
bool bInSpace=true;
for(long j=0;j<polySpace.Length();j++)
{
XPoint ptSpace=*polySpace[j];
if((ptSpace&polyHouse)==PR_OUTSIDE)
{
bInSpace=false;
break;
}
}
if(bInSpace)
{
ssMySpace+=ent;
for(j=0;j<pSpace1->m_lstWallEnclosure.Length();j++)
lstWallId.FindOrAddTail(*pSpace1->m_lstWallEnclosure[j]);
}
}
OPENOBJ_END()
}
AcDbObjectIdArray idArray;
ssMySpace.AsIdArray(idArray);
for(i=0;i<idArray.length();i++)
m_lstSpace.AddTail(new TBASpace(idArray[i]));
ssSpace-=ssMySpace;
}
//选择套内阳台房间
if(!lstWallId.IsEmpty())//得到套相关墙
{
DList<AcDbObjectId> lstWalls;
for(lstWallId.MoveToFirst();!lstWallId.IsOut();lstWallId.MoveToNext())
lstWalls.Append(new AcDbObjectId(lstWallId.GetCurData()));
//得到户墙上柱子
DualList<AcDbObjectId> lstColus;
for(long i=0;i<lstWalls.Length();i++)
{
TDbWall *pWall=NULL;
acdbOpenObject(pWall,*lstWalls[i],AcDb::kForRead);
if(pWall!=NULL)
{
lstColus.FindOrAddTail(pWall->GetStartColumnId());
lstColus.FindOrAddTail(pWall->GetEndColumnId());
pWall->close();
}
}
DList<AcDbObjectId> lstColus1;
for(lstColus.MoveToFirst();!lstColus.IsOut();lstColus.MoveToNext())
lstColus1.Append(new AcDbObjectId(lstColus.GetCurData()));
//找本户户墙的外轮廓
XSearchSpaceFromWall aSearch;
try
{
aSearch.InitStart(lstWalls, lstColus1);
}
catch (...)
{
adsout << _T("\n搜索户墙外轮廓出现例外情况!");
pSpace->close();
return;
}
XAecSpaceCell *pExt=aSearch.SearchSpaces();
if(pExt!=NULL)//成功找到户墙外轮廓
{
XPoly2D polyOutWall(1);
pExt->InternalPoly2D(polyOutWall,2);//得到套内面积区域
polyOutWall.SetElevation(0);
polyOutWall.Compress();
PickSet ssMyBalcony(SS_FREE);
for(long i=0;i<ssBalcony.Length();i++)
{
Entity ent=ssBalcony[i];
OPENOBJ_BEGIN(ent,AcDb::kForRead,TDbSpace,pSpace1)
if(pSpace1!=NULL)
{
// wyg20090508: 新的判断阳台与房间的关系
AcDbObjectId idOwner = pSpace1->GetHouseId();
if (!idOwner.isNull())
{
if (idOwner == idHouse)
{
ssMyBalcony += ent;
}
// 有id值,则用新判断方法,否则使用旧判断方法
continue;
}
// wyg20090508: 旧的判断阳台与房间的关系
XPoly2D poly1=pSpace1->m_outline;
poly1.SetElevation(0);
DList<XPoly2D> buf;
if(TchSubExport::Union(polyOutWall,poly1,buf)==RTNORM&&buf.Length()==1)//可以合并
{
DList<XCurveSegment> lst0,lstIn,lstOut,lstOn;
ExplodePoly2D(poly1,lst0);
PolyClip(lst0,polyOutWall,lstIn,lstOut,lstOn);
lstIn<<lstOn;
double lenIn=0;
for(long n=0;n<lstIn.Length();n++)
lenIn+=lstIn[n]->GetLength();
if(lenIn>500)//相接边>500(阳台最新宽度)
{
//1,要求一个阳台不能同属多户
//2,假设阳台一定在套房外(但实际有时会用墙、窗表示封闭阳台,计划新版本提供封闭阳台对象)
ssMyBalcony+=ent;
}
}
}
OPENOBJ_END()
}
AcDbObjectIdArray idArray;
ssMyBalcony.AsIdArray(idArray);
for(i=0;i<idArray.length();i++)
m_lstBalcony.AddTail(new TBABalcony(idArray[i]));
ssBalcony-=ssMyBalcony;
}
else
adsout << _T("\n搜索户墙外轮廓出现例外情况!");
}
pSpace->close();
}
//1,计算被建筑轮廓和洞口裁剪后最终面积系数
//2,计算在建筑轮廓内的、且不包括洞口区域的几何面积
void TBAHouse::ClipBy(TBAList& lstOutline,DList<XPoly2D>& lstHole)//ok
{//by fxj
TBArea::ClipBy(lstOutline,lstHole);
for(m_lstSpace.MoveToFirst();!m_lstSpace.IsOut();m_lstSpace.MoveToNext())
{
m_lstSpace.GetCurData()->ClipBy(lstOutline,lstHole);
}
if(lstOutline.GetLength()>0)
{
lstOutline.MoveToFirst();
((TBAOutline *)(lstOutline.GetCurData()))->AddDefinedValidGeomArea(m_fFactArea);
}
}
//得到户型名称
CString TBAHouse::GetHouseType()const//ok //支持跃层
{
int num1=0,num2=0,num3=0;
// Zyu modify on 101119,支持名称分类
// Begin
/*
for(long i=0;i<m_lstSpace.GetLength();i++)
{
CString sName=m_lstSpace.GetAt(i)->GetName();
if(sName.Find(_T("卫生间"))>=0)
num3++;
else if(sName.Find(_T("厅"))>=0||sName.Find(_T("起居室"))>=0)//moidfied by fxj 090617"起居室"归入“厅“
num2++;
else if(sName.Find(_T("室"))>=0&&sName.Find(_T("起居室"))<0)//moidfied by fxj 090617"起居室"不算“室”
num1++;
}
//---------------------add by fxj 090622 对于跃层住宅,加入上层的户型一起统计
if(m_pHouseUp!=NULL)
{
for(long j=0;j<m_pHouseUp->m_lstSpace.GetLength();j++)
{
CString sName=m_pHouseUp->m_lstSpace.GetAt(j)->GetName();
if(sName.Find(_T("卫生间"))>=0)
num3++;
else if(sName.Find(_T("厅"))>=0||sName.Find(_T("起居室"))>=0)
num2++;
else if(sName.Find(_T("室"))>=0&&sName.Find(_T("起居室"))<0)
num1++;
}
}
//--------------------------------------------
*/
// 房间类型
enum ERoomType
{
eHall = 0, // 厅
eRoom = 1, // 室
eToilet = 2, // 卫
eOther = 3, // 其他
};
// 房间类型的映射
// CMap<CString, LPCTSTR, ERoomType, ERoomType> mapRoomType;
CMap<CString, LPCTSTR, int, int> mapRoomType;
// 映射所有厅的字符串
for (int i = 0; i < m_arHallString.GetSize(); i++)
{
// mapRoomType.SetAt(m_arHallString.GetAt(i), eHall);
mapRoomType.SetAt(m_arHallString.GetAt(i), 0);
}
// 映射所有室的字符串
for (int j = 0; j < m_arRoomString.GetSize(); j++)
{
// mapRoomType.SetAt(m_arRoomString.GetAt(j), eRoom);
mapRoomType.SetAt(m_arRoomString.GetAt(j), 1);
}
// 映射所有卫的字符串
for (int k = 0; k < m_arToiletString.GetSize(); k++)
{
// mapRoomType.SetAt(m_arToiletString.GetAt(k), eToilet);
mapRoomType.SetAt(m_arToiletString.GetAt(k), 2);
}
// ERoomType eRoomType = eOther;
int nRoomType = 3;
for (long l = 0; l < m_lstSpace.GetLength(); l++)
{
// 查找房间名称对应的类型,统计时加1
// if (mapRoomType.Lookup(m_lstSpace.GetAt(l)->GetName(), eRoomType))
if (mapRoomType.Lookup(m_lstSpace.GetAt(l)->GetName(), nRoomType))
{
// switch (eRoomType)
switch (nRoomType)
{
case eRoom: num1++; break;
case eHall: num2++; break;
case eToilet: num3++; break;
}
}
}
// 支持跃层(多层)
TBAHouse *pHouseUp = m_pHouseUp;
while (NULL != pHouseUp)
{
for(long m = 0; m < pHouseUp->m_lstSpace.GetLength(); m++)
{
// 查找房间名称对应的类型,统计时加1
// if (mapRoomType.Lookup(pHouseUp->m_lstSpace.GetAt(m)->GetName(), eRoomType))
if (mapRoomType.Lookup(pHouseUp->m_lstSpace.GetAt(m)->GetName(), nRoomType))
{
// switch (eRoomType)
switch (nRoomType)
{
case eRoom: num1++; break;
case eHall: num2++; break;
case eToilet: num3++; break;
}
}
}
pHouseUp = pHouseUp->GetHouseUp();
}
// End
CString sType;
sType.Format(_T("%d室%d厅%d卫"),num1,num2,num3);
return sType;
}
//套内使用建筑面积
double TBAHouse::GetSpaceArea()//ok
{
return m_lstSpace.GetStatisticsBuildArea();
}
//套内阳台建筑面积
double TBAHouse::GetBalconyArea()//ok
{
return m_lstBalcony.GetStatisticsBuildArea();
}
//套内墙体建筑面积=套内建筑面积-套内使用建筑面积
//外墙和户墙取面积的1/2
double TBAHouse::GetWallArea()//ok
{
return GetGeomBuildArea()-GetSpaceArea();
}
//返回分摊所得建筑面积
double TBAHouse::GetSharedArea()//ok
{
return m_fSharedArea;
}
//套内建筑面积(不包括阳台、不包括分摊面积的建筑面积)
double TBAHouse::GetBuildArea()//ok
{//chaned by fxj 090610 不包括阳台
return GetGeomBuildArea();//return GetGeomBuildArea()+GetBalconyArea();
}
//单户建筑面积=套内建筑面积+套内阳台建筑面积+分摊所得建筑面积
double TBAHouse::GetStatisticsBuildArea()//ok
{
return GetGeomBuildArea()+GetBalconyArea()+GetSharedArea();
}
//套型建筑面积=套内使用面积/标准层使用面积系数
double TBAHouse::GetStatisticsBuildAreaEx()//ok
{
return GetSpaceArea()/m_pFloor->GetKFactor();
}
//套型阳台面积
double TBAHouse::GetBalconyAreaEx()//ok
{//bu fxj
return GetBalconyArea();
//double a=0;
//for(m_lstBalcony.MoveToFirst();!m_lstBalcony.IsOut();m_lstBalcony.MoveToNext())
//{
// TBArea *pArea=m_lstBalcony.GetCurData();
// a+=pArea->GetOutline().Area()*(pArea->GetAreaFactor());//modified by fxj 乘以面积系数(阳台是否按一半面积算)
//}
//
//return a;
}
//是否是同一套型,面积相同、形状相同,同一编号IsSameName的户型应满足这个要求
bool TBAHouse::IsSimilarHouse(TBAHouse& house)//ok
{
if(_tcsicmp(m_sName,house.GetName())!=0)//编号相同
return false;
if(GetHouseType()!=house.GetHouseType())//户型相同
return false;
if(m_lstSpace.GetLength()!=house.m_lstSpace.GetLength())//房间数相同
return false;
if(m_lstBalcony.GetLength()!=house.m_lstBalcony.GetLength())//阳台数相同
return false;
if(fabs(GetSpaceArea()-house.GetSpaceArea())>0.01)//使用面积相同
return false;
if(fabs(GetBalconyArea()-house.GetBalconyArea())>0.01)//阳台面积相同
return false;
if(fabs(GetGeomBuildArea()-house.GetGeomBuildArea())>0.01)//套内建筑面积相同
return false;
if(fabs(GetSharedArea()-house.GetSharedArea())>0.01)//分摊面积相同
return false;
if(fabs(GetStatisticsBuildAreaEx()-house.GetStatisticsBuildAreaEx())>0.000001)//套型建筑面积相同
return false;
//套内几何形状相同
if(fabs(m_polyOutline.Area()-house.m_polyOutline.Area())>0.01)
return false;
if(fabs(m_polyOutline.Distance2d()-house.m_polyOutline.Distance2d())>0.0001)
return false;
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//add by whl on 050521,加区域判断
// nCmpMethod: 0--Use _tcsicmp; 1--Use ads_wcmatch
Acad::ErrorStatus GetEntityFromDatabase2(DList<AcDbObjectId> &lstObjects,
AcDbDatabase &db, const TCHAR *pDxfWizard, int nCmpMethod, const TCHAR *pszBlock,XPoint ptMin,XPoint ptMax)
{
AcDbBlockTable *pBlockTable=NULL;
Acad::ErrorStatus es = db.getBlockTable(pBlockTable, AcDb::kForRead);
if(!pBlockTable) return es;
ASSERT(es==Acad::eOk);
AcDbBlockTableRecord *pBlockTableRec=NULL;
es = pBlockTable->getAt(pszBlock, pBlockTableRec, AcDb::kForRead);
pBlockTable->close();
if(!pBlockTableRec)
return es;
ASSERT(pBlockTableRec);
AcDbBlockTableRecordIterator* pBlockIterator=NULL;
es = pBlockTableRec->newIterator(pBlockIterator);
ASSERT(es==Acad::eOk && pBlockIterator!=NULL);
for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) {
AcDbEntity *pEntity=NULL;
es = pBlockIterator->getEntity(pEntity, AcDb::kForRead);
if(es!=Acad::eOk) continue;
ASSERT(pEntity);
XDbObject vTemp(pEntity);
//不处理不可见的实体
if (pEntity->visibility() == AcDb::kInvisible) {
continue;
}
AcRxClass *pRxInfo=pEntity->isA();
if(nCmpMethod==0) {
if(_tcsicmp(pRxInfo->dxfName(), pDxfWizard)!=0)
continue;
} else {
if(ads_wcmatch(pRxInfo->dxfName(), pDxfWizard)!=RTNORM)
continue;
}
AcDbExtents ext;
if(pEntity->isKindOf(TDbSpace::desc()))
{
XPoint pt1,pt2;
TDbSpace* pSpace=(TDbSpace*)pEntity;
pSpace->m_outline.GetExtend(pt1,pt2);
ext.set(pt1.AsAcGePoint3d(),pt2.AsAcGePoint3d());
}
else if(pEntity->getGeomExtents(ext)!=Acad::eOk)
continue;
if(ext.minPoint().x<ptMin.x-1E-6)
continue;
if(ext.minPoint().y<ptMin.y-1E-6)
continue;
if(ext.maxPoint().x>ptMax.x+1E-6)
continue;
if(ext.maxPoint().y>ptMax.y+1E-6)
continue;
lstObjects.Append(new AcDbObjectId(pEntity->objectId()));
}
delete pBlockIterator;
pBlockTableRec->close();
return Acad::eOk;
}
TBAFloor::TBAFloor(TProjectFloor*pFloor):m_pFloorDef(pFloor)//ok
{
if(pFloor==NULL)
return;
//打开DWG
CString sCurDwg=curDoc()->fileName();
XString sDwgFile=g_project.GetDwgFullName(pFloor->GetName());
AcDbDatabase dwgDb(false, true);
AcDbDatabase *pDb;
if(_tcsicmp(sCurDwg, sDwgFile)==0)
pDb=acdbCurDwg();
else
{
#if ADS < 21
if(dwgDb.readDwgFile(sDwgFile, _SH_DENYNO, false)!=Acad::eOk)
#else
if(dwgDb.readDwgFile(sDwgFile, AcDbDatabase::kForReadAndAllShare, false)!=Acad::eOk)
#endif
{
adsout << _T("\n不能访问") << sDwgFile << _T("!");
return ;
}
pDb=&dwgDb;
}
//取面积对象
DList<AcDbObjectId> spaceIds;
if(pFloor->IsFloorInFrame())
{
XPoint ptMin,ptMax;
pFloor->GetRange(ptMin,ptMax);
GetEntityFromDatabase2(spaceIds, *pDb, _T("ATS_SPACE"), 1, ACDB_MODEL_SPACE,ptMin,ptMax);
}
else
GetEntityFromDatabase(spaceIds, *pDb, _T("ATS_SPACE"), 1, ACDB_MODEL_SPACE);
PickSet ss(SS_FREE);
for(long i=0;i<spaceIds.Length();i++)
ss+=*spaceIds[i];
//填入标准层面积数据
Append(ss);
}
//由选择集构造楼层
void TBAFloor::Append(PickSet &ss)//ok
{
PickSet ssBuildingSpace(SS_FREE),ssHouseSpace(SS_FREE),ssShareSpace(SS_FREE),ssBalconySpace(SS_FREE),ssHoleSpace(SS_FREE);
ssBuildingSpace+=ss;
ssHouseSpace+=ss;
ssShareSpace+=ss;
ssBalconySpace+=ss;
ssHoleSpace+=ss;
ss.BaseFilter(RBList(90,0,NULL));//kUseArea
ssHouseSpace.BaseFilter(RBList(90,1,NULL));//kHouseArea
ssBuildingSpace.BaseFilter(RBList(90,2,NULL));//kTotalArea
ssHoleSpace.BaseFilter(RBList(90,3,NULL));//kHoleArea
ssShareSpace.BaseFilter(RBList(90,4,NULL));//kShareArea
ssBalconySpace.BaseFilter(RBList(90,5,NULL));//kBalconyArea
//定义洞口
DList<XPoly2D> lstHolePoly;
for(long i=0;i<ssHoleSpace.Length();i++)
{
Entity ent=ssHoleSpace[i];
AcDbObjectId id;
acdbGetObjectId(id,ent.name);
TBAHole *pHole=new TBAHole(id);
m_lstHole.AddTail(pHole);
lstHolePoly.Append(new XPoly2D(pHole->GetOutline()));
}
//定义建筑有效区域
for(i=0;i<ssBuildingSpace.Length();i++)
{
Entity ent=ssBuildingSpace[i];
AcDbObjectId id;
acdbGetObjectId(id,ent.name);
TBAOutline *pOutline=new TBAOutline(id);
pOutline->ClipBy(lstHolePoly);
m_lstOutline.AddTail(pOutline);
}
//定义套房及内部阳台和房间
for(i=0;i<ssHouseSpace.Length();i++)
{
Entity ent=ssHouseSpace[i];
AcDbObjectId id;
acdbGetObjectId(id,ent.name);
{
XPushMemVar<bool> bTemp(g_bUseNameCmp,false);//用户号排序
TBAHouse *pHouse=new TBAHouse(id,ss,ssBalconySpace,this);
if(m_lstHouse.BFindDataTo(*pHouse))
adsout<<_T("\n发现同一标准层中户号(")<<pHouse->GetCode()<<_T(")重复出现,户号须唯一不能重复!");//modified by fxj 090612不允许同一层中出现相同户号。
pHouse->ClipBy(m_lstOutline,lstHolePoly);
m_lstHouse.SortIn(pHouse,false);//不允许重复 modified by fxj 090612
}
}
//例外处理
if(ss.Length()>0)
{
ssShareSpace+=ss;
adsout<<_T("\n发现未分户的房间,视为共用面积!");
}
if(ssBalconySpace.Length()>0)
{
ssShareSpace+=ssBalconySpace;
adsout<<_T("\n发现未分户的阳台,视为共用面积!");
}
//定义公摊面积
for(i=0;i<ssShareSpace.Length();i++)
{
Entity ent=ssShareSpace[i];
AcDbObjectId id;
acdbGetObjectId(id,ent.name);
TBAShare *pShare=new TBAShare(id);
pShare->ClipBy(m_lstOutline,lstHolePoly);
m_lstShare.AddTail(pShare);
}
//定义默认公摊面积
double defaultShareArea=0;
for(m_lstOutline.MoveToFirst();!m_lstOutline.IsOut();m_lstOutline.MoveToNext())
{
TBAOutline*pOutline=(TBAOutline*)m_lstOutline.GetCurData();
defaultShareArea+=pOutline->GetDefaultShareArea();
}
m_lstShare.InsertHead(new TBAShareEx(defaultShareArea));
//共用层
if(m_lstHouse.IsEmpty())
{
for(m_lstShare.MoveToFirst();!m_lstShare.IsOut();m_lstShare.MoveToNext())
{
TBAShare *pShare=(TBAShare*)m_lstShare.GetCurData();
if(pShare->GetType()==TBAShare::kShareInFloor)//共用层的所有按层公摊面积实际是按整楼公摊!
pShare->SetType(TBAShare::kShareInBuilding);
}
}
//计算标准层使用面积系数
//标准层使用面积系数=标准层使用面积/标准层建筑面积(不包括阳台)
m_fKFactor=GetHouseSpaceArea()/(GetHouseArea()+GetShareArea(TBAShare::kShareAll));
}
long TBAFloor::GetLayerNum()const//ok
{
DList<int> lst;
if(m_pFloorDef!=NULL)
m_pFloorDef->GetLayerIndexList(lst);
return lst.Length()<1?1:lst.Length();
}
//按层分摊
void TBAFloor::Share(TBAShare::ShareType type)//ok
{
double area=GetShareArea(type);
if(area>1E-6&&!m_lstHouse.IsEmpty())
m_lstHouse.ShareArea(area);
}
//套内建筑面积(不包括阳台和分摊面积)
double TBAFloor::GetHouseArea()//ok
{
return m_lstHouse.GetGeomBuildArea();
}
//套内使用建筑面积
double TBAFloor::GetHouseSpaceArea()//ok
{
double a=0;
for(m_lstHouse.MoveToFirst();!m_lstHouse.IsOut();m_lstHouse.MoveToNext())
{
TBAHouse *pHouse=(TBAHouse*)m_lstHouse.GetCurData();
a+=pHouse->GetSpaceArea();
}
return a;
}
//套内阳台建筑面积
double TBAFloor::GetHouseBalconyArea()//ok
{
double a=0;
for(m_lstHouse.MoveToFirst();!m_lstHouse.IsOut();m_lstHouse.MoveToNext())
{
TBAHouse *pHouse=(TBAHouse*)m_lstHouse.GetCurData();
a+=pHouse->GetBalconyArea();
}
return a;
}
//公摊建筑面积
double TBAFloor::GetShareArea(TBAShare::ShareType type)//ok
{
double a=0;
if(type==TBAShare::kShareAll)
a=m_lstShare.GetStatisticsBuildArea();
else
{
for(m_lstShare.MoveToFirst();!m_lstShare.IsOut();m_lstShare.MoveToNext())
{
TBAShare *pShare=(TBAShare*)m_lstShare.GetCurData();
if(pShare->GetType()==type)
a+=pShare->GetStatisticsBuildArea();
}
}
return a;
}
//标准层建筑面积=套内建筑面积+套内阳台建筑面积+公摊建筑面积
double TBAFloor::GetGeomBuildArea()//ok
{
return GetHouseArea()+GetHouseBalconyArea()+GetShareArea(TBAShare::kShareAll);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//分摊共用面积
void TBABuilding::Share()//ok
{
//按栋分摊
double allShareArea=0;//按栋分摊的面积
double allHouseArea=0;//所有套内面积总和
List<TBAHouse*> lstHouse;
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAFloor* pFloor=(TBAFloor*)GetCurData();
long layerNum=pFloor->GetLayerNum();
allShareArea+=pFloor->GetShareArea(TBAShare::kShareInBuilding)*layerNum;
for(pFloor->m_lstHouse.MoveToFirst();!pFloor->m_lstHouse.IsOut();pFloor->m_lstHouse.MoveToNext())
{
TBAHouse *pHouse=(TBAHouse*)pFloor->m_lstHouse.GetCurData();
allHouseArea+=pHouse->GetBuildArea()*layerNum;
lstHouse.AddTail(pHouse);
}
}
if(allHouseArea>1E-6)
{
for(lstHouse.MoveToFirst();!lstHouse.IsOut();lstHouse.MoveToNext())
{
TBAHouse *pHouse=lstHouse.GetCurData();
double K=pHouse->GetBuildArea()/allHouseArea;
pHouse->AddSharedArea(allShareArea*K);
}
}
//按层分摊
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAFloor *pFloor=(TBAFloor*)GetCurData();
pFloor->Share(TBAShare::kShareInFloor);
}
//自由分摊...
}
// Zyu add on 100906,全楼公摊
void TBABuilding::ShareInBuilding()
{
double allShareArea=GetShareArea(); // 按栋分摊的面积
double allHouseArea=0; // 所有套内面积总和
List<TBAHouse*> lstHouse;
// 获得套内面积的总和,以及所有的TBAHouse对象
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAFloor* pFloor=(TBAFloor*)GetCurData();
long layerNum=pFloor->GetLayerNum();
for(pFloor->m_lstHouse.MoveToFirst();!pFloor->m_lstHouse.IsOut();pFloor->m_lstHouse.MoveToNext())
{
TBAHouse *pHouse=(TBAHouse*)pFloor->m_lstHouse.GetCurData();
allHouseArea+=pHouse->GetBuildAreaEx()*layerNum;
lstHouse.AddTail(pHouse);
}
}
// 进行全楼面积分摊
if(allHouseArea>1E-6)
{
for(lstHouse.MoveToFirst();!lstHouse.IsOut();lstHouse.MoveToNext())
{
TBAHouse *pHouse=lstHouse.GetCurData();
double K=pHouse->GetBuildAreaEx()/allHouseArea;
pHouse->AddSharedArea(allShareArea*K);
}
}
}
// Zyu add on 100906,按层公摊
void TBABuilding::ShareInFloor()
{
//按层分摊
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAFloor *pFloor=(TBAFloor*)GetCurData();
pFloor->Share(TBAShare::kShareInFloor);
}
}
//识别并处理跃层
void TBABuilding::FindHouseUp()
{//add by fxj 090612
//识别并标记跃层 //modifeid by fxj 090625
List<TBAHouse*> lstHouseOld;
for(MoveToLast();!IsOut();MoveToPre())
{
TBAFloor* pFloor=(TBAFloor*)GetCurData();
for(pFloor->m_lstHouse.MoveToLast();!pFloor->m_lstHouse.IsOut();pFloor->m_lstHouse.MoveToPre())
{
XPushMemVar<bool> bTemp(g_bUseNameCmp,false);//用户号排序
TBAHouse *pHouse=(TBAHouse*)pFloor->m_lstHouse.GetCurData();
CString sCode1=pHouse->GetCode();
for(int i=0;i<lstHouseOld.GetLength();i++)
{
TBAHouse *pUpHouse=lstHouseOld[i];
CString sCode1=pHouse->GetCode();
CString sCode2=pUpHouse->GetCode();
if(sCode1==sCode2)
{
pHouse->SetHouseUp(pUpHouse);
break;
}
}
}
lstHouseOld.Clear();
for(pFloor->m_lstHouse.MoveToLast();!pFloor->m_lstHouse.IsOut();pFloor->m_lstHouse.MoveToPre())
{
TBAHouse *pHouse=(TBAHouse*)pFloor->m_lstHouse.GetCurData();
lstHouseOld.AddTail(pHouse);
}
}
lstHouseOld.Clear();
}
//套内建筑面积(不包括阳台和分摊)
double TBABuilding::GetHouseArea()//ok
{
double a=0;
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAFloor *pFloor=(TBAFloor*)GetCurData();
a+=pFloor->GetHouseArea()*pFloor->GetLayerNum();
}
return a;
}
//套内使用面积
double TBABuilding::GetHouseSpaceArea()//ok
{
double a=0;
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAFloor *pFloor=(TBAFloor*)GetCurData();
a+=pFloor->GetHouseSpaceArea()*pFloor->GetLayerNum();
}
return a;
}
//套内阳台面积
double TBABuilding::GetHouseBalconyArea()//ok
{
double a=0;
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAFloor *pFloor=(TBAFloor*)GetCurData();
a+=pFloor->GetHouseBalconyArea()*pFloor->GetLayerNum();
}
return a;
}
//所有共摊面积
double TBABuilding::GetShareArea()//ok
{
double a=0;
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAFloor *pFloor=(TBAFloor*)GetCurData();
a+=pFloor->GetShareArea(TBAShare::kShareAll)*pFloor->GetLayerNum();
}
return a;
}
//建筑总面积
double TBABuilding::GetStatisticsBuildArea()//ok
{
double a=0;
for(MoveToFirst();!IsOut();MoveToNext())
{
TBAFloor *pFloor=(TBAFloor*)GetCurData();
a+=pFloor->GetStatisticsBuildArea()*pFloor->GetLayerNum();
}
return a;
}