1039 lines
28 KiB
C++
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;
|
|
}
|