Files
envi-code/SourceCode/Code2026/Dimension/CollectElevation.cpp
T
2026-09-28 15:28:50 +08:00

1381 lines
28 KiB
C++

#include "stdafx.h"
#include "globalFunc.h"
#include "AcDbObjectPtr.h"
#include "CollectElevation.h"
#include "aecdbtext.h"
#include "dbxline.h"
#include <algorithm>
#include "AecDbSymbElevation.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CCollectElevation::CCollectElevation()
{
m_nMinObjectCount = 5;
m_dAngel = PI/4;
m_bExternalBlk = false; // cet 2011.12.2 add
}
CCollectElevation::~CCollectElevation()
{
}
bool CCollectElevation::GetSelectPointElevation(XPoint ptSel,Entity ent,int nType, double &dEle)
{
bool bRet = true;
PickSet ssAll(SS_FREE);
ssAll += m_ssAll;
// 获取实体的id和插入点
GetAllPickSetPt(ssAll, ptSel, nType);
if (m_nLandForm == 0) // 平地采集
{
bRet = GetNearestPtEle(ptSel, nType, dEle);
}
else if (m_nLandForm == 1) // 坡地采集
{
bRet = GetEleByThreePt(ssAll, ptSel, nType, dEle);
// 坡地采集失败时,使用平地采集
if (!bRet)
{
bRet = GetNearestPtEle(ptSel, nType, dEle);
}
}
return bRet;
}
//通过实体得到文字数值 并得到选择点与文字的距离
double CCollectElevation::GetTextValue(XPoint pt,Entity ent,double &dDis,XPoint &ptVal)
{
double dValue = 0.0;
if (ent.Is(_T("ATS_TEXT")))
{
CString csText;
//上华文字
OPENOBJ_BEGIN(ent, AcDb::kForRead, AecXDbText, pEnt);
if(pEnt)
{
csText = pEnt->GetText();
ptVal = pEnt->GetLocation();
// cet 2011.12.2 add
if(m_bExternalBlk)
{
ptVal.TransformBy(m_mat);
}
dDis = pt.Distance2d(ptVal);
dValue = _tstof(csText);
}
OPENOBJ_END();
}
else if (ent.Is(_T("ATS_ELEVATION")))
{
CString csText;
OPENOBJ_BEGIN(ent, AcDb::kForRead, AecXDbSymbElevation, pEnt);
if(pEnt)
{
csText = pEnt->GetText();
ptVal = pEnt->GetLocation();
// cet 2011.12.2 add
if(m_bExternalBlk)
{
ptVal.TransformBy(m_mat);
}
dDis = pt.Distance2d(ptVal);
dValue = _tstof(csText);
}
OPENOBJ_END();
}
else
{
AcDbText *pText = NULL;
AcDbObjectId id;
acdbGetObjectId(id, ent);
AcDbEntity *pEnt = NULL;
acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite);
if (pEnt != NULL)
{
pText = AcDbText::cast(pEnt);
if (pText != NULL)
{
ptVal = pText->position();
// cet 2011.12.2 add
if(m_bExternalBlk)
{
ptVal.TransformBy(m_mat);
}
dDis = pt.Distance2d(ptVal);
CString sText = pText->textString();
dValue = _tstof(sText);
}
pEnt->close();
}
}
return dValue;
}
/*
//通过实体得到点Z坐标 并得到选择点与该实体的距离
double CCollectElevation::GetPointZValue(XPoint pt,Entity ent,double &dDis)
{
double dValue = 0.0;
AcDbPoint *pPoint = NULL;
AcDbObjectId id;
acdbGetObjectId(id, ent);
AcDbEntity *pEnt = NULL;
acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite);
if (pEnt != NULL)
{
pPoint = AcDbPoint::cast(pEnt);
if (pPoint != NULL)
{
XPoint ptValue = pPoint->position();
dValue = ptValue.z;
dDis = pt.Distance2d(ptValue);
}
pEnt->close();
}
return dValue;
}
//得到实体圆Z坐标 并得到选择点与该实体的距离
double CCollectElevation::GetCirCleZValue(XPoint pt,Entity ent,double &dDis)
{
double dValue = 0.0;
AcDbCircle *pCirCle = NULL;
AcDbObjectId id;
acdbGetObjectId(id, ent);
AcDbEntity *pEnt = NULL;
acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite);
if (pEnt != NULL)
{
pCirCle = AcDbCircle::cast(pEnt);
if (pCirCle != NULL)
{
XPoint ptValue = pCirCle->center();
dValue = ptValue.z;
dDis = pt.Distance2d(ptValue);
}
pEnt->close();
}
return dValue;
}
void CCollectElevation::SetCollectObjectCount(int nCount)
{
m_nMinObjectCount = nCount;
}
void CCollectElevation::GetAllPickSet(PickSet &ssAll,int nType,RBList &rbMask,Entity ent)
{
resbuf *rb = NULL;
TCHAR szLayerName[256];
ent.GetData(8,szLayerName);
if (nType == 0)
{
rb = ads_buildlist(RTDXF0, _T("TEXT,ATS_TEXT"),8,szLayerName, NULL);
ssAll.Get(_T("X"), NULL, NULL, rb);
}
else if (nType == 1)
{
rb = ads_buildlist(RTDXF0, _T("POINT"), 8,szLayerName,NULL);
ssAll.Get(_T("X"), NULL, NULL, rb);
}
else if (nType == 2)
{
rb = ads_buildlist(RTDXF0, _T("CIRCLE"),8,szLayerName, NULL);
ssAll.Get(_T("X"), NULL, NULL, rb);
}
else if (nType == 5)
{
rb = ads_buildlist(RTDXF0, _T("ATS_ELEVATION"),8,szLayerName, NULL);
ssAll.Get(_T("X"), NULL, NULL, rb);
}
else
{
TCHAR szBlkName[256];
ent.GetData(2,szBlkName);
rb = ads_buildlist(RTDXF0, _T("INSERT"),8,szLayerName,2,szBlkName, NULL);
ssAll.Get(_T("X"), NULL, NULL, rb);
}
FiletratePickSet(ssAll, ent); // 过滤非数值文字 cet 2010.4.12 add
rbMask.Append(rb);
}
void CCollectElevation::GetNeedPicSet(PickSet &ss,double &dRidus,int nType,XPoint ptSel,PickSet &ssAll,RBList &rbMask)
{
long len = 0;
int nCount = 1;//圆半径扩大的倍数
XPoint ptLow,ptUp;
ssAll.GetExtend(ptLow,ptUp);
double nMaxRidius = ptUp.Distance2d(ptLow);
while (len < m_nMinObjectCount)
{
AcDbPolyline *pPLine = new AcDbPolyline;
dRidus *= nCount;
GetCirClePolyLine(pPLine,ptSel,dRidus);
//得到POLYLINE范围内实体
XPoly2D poly;
PolyConvert(*pPLine, poly);
delete pPLine;
XPoint ptLow,ptUp;
poly.GetExtend(ptLow,ptUp);
poly.TransUCS(Groups(0), Groups(1));//Groups(0) wcs, Groups(1) ucs
RBList rbFence = poly.Fence();
AssureInCurrentView_New(ptLow, ptUp);
ss.Get(_T("CP"), rbFence, NULL, rbMask);
len = ss.Length();
if (len == 0)
break;
if (dRidus > 2*nMaxRidius)
break;
nCount++;
}
}
void CCollectElevation::GetAroundElevation(PickSet &ss,std::vector<SourcePoint> &vecPt,int nType,XPoint ptSel,LPCTSTR lpTag)
{
Entity ent;
double dHeightTemp = 0.0;
double dDis = 0.0;
CString sValueTemp;
XPoint ptVal;
SourcePoint sp;
int nSize = ss.Length();
for(long i=0;i<nSize;i++)
{
ent = ss[i];
switch(nType)
{
case 0:
case 5:
{
//文字 标高
dHeightTemp = GetTextValue(ptSel,ent,dDis,ptVal);
if (fabs(dHeightTemp) > 0.0001) //SB修改 20090929 支持负数
{
sp.dHeight = dHeightTemp;
sp.dDist = dDis;
vecPt.push_back(sp);
}
}
break;
case 1:
{
//点
dHeightTemp = GetPointZValue(ptSel,ent,dDis);
if (fabs(dHeightTemp) > 0.0001)//SB修改 20090929 支持负数
{
sp.dHeight = dHeightTemp;
sp.dDist = dDis;
vecPt.push_back(sp);
}
}
break;
case 2:
{
//圆
dHeightTemp = GetCirCleZValue(ptSel,ent,dDis);
if (fabs(dHeightTemp) > 0.0001)//SB修改 20090929 支持负数
{
sp.dHeight = dHeightTemp;
sp.dDist = dDis;
vecPt.push_back(sp);
}
}
break;
case 3:
{
//图块
dHeightTemp = GetBlockZValue(ptSel,ent,dDis);
if (fabs(dHeightTemp) > 0.0001)//SB修改 20090929 支持负数
{
sp.dHeight = dHeightTemp;
sp.dDist = dDis;
vecPt.push_back(sp);
}
}
break;
case 4:
{
if (GetTextValueByTag(ptSel,lpTag,sValueTemp,ent,dDis))
{
//属性字
dHeightTemp = _ttoi(sValueTemp);
sp.dHeight = dHeightTemp;
sp.dDist = dDis;
vecPt.push_back(sp);
}
}
break;
default:
break;
}
}
}
//过滤掉部分无用点
//过滤掉无用实体
//ss :需要过滤的实体集 作为返回参数时表示过滤后的实体集
//pt 需要计算标高的点的坐标
//rbMask 选择数据源的 MASK
//dRidus 包含实体范围的圆的半径
//算法:从圆心向最近的点射出射线,将射线经过的实体删除
void CCollectElevation::FiletratePickSet(PickSet &ss,XPoint pt,RBList &rbMask,double dRidus)
{
PickSet ssTemp(SS_FREE);
ssTemp += ss;
PickSet ssDel(SS_FREE);
double nMin = 0.0;
int nIndexDel = -1;
XPoint ptVal;
Entity ent;
AcDbObjectId id,tempID;
while (ssTemp.Length() > 0)
{
//找距离pt的实体的最小值
for (long i = 0; i < ssTemp.Length(); ++i)
{
ent = ssTemp[i];
acdbGetObjectId(id,ent);
if (m_mapIDToPt.find(id) != m_mapIDToPt.end())
ptVal = m_mapIDToPt[id];
if (i == 0)
{
nMin = pt.Distance2d(ptVal);
tempID = id;
}
else
{
if (nMin > pt.Distance2d(ptVal))
{
nMin = pt.Distance2d(ptVal);
tempID = id;
}
}
}
ssTemp -= tempID;
PickSet ssTemp2(SS_FREE);
ptVal = m_mapIDToPt[tempID];
//得到通过最小点的射线与圆的交点
AcGeVector2d vec2d = ptVal - pt;
vec2d.normalize();
vec2d *= dRidus;
ptVal = pt + vec2d;
int n = ssDel.Length();
CString sTemp;
sTemp.Format(_T("%d"),n);
XCircle circle(pt,dRidus);
circle.Make();
XLine l(pt,ptVal);
l.Make();
TCHAR sTemp2[100];
ads_getstring(NULL, sTemp, sTemp2);
struct resbuf *pointlist;
pointlist = ads_buildlist(RTPOINT, &pt, RTPOINT, &ptVal, NULL);
ssTemp2.Get(_T("F"), pointlist, NULL, rbMask);
ads_relrb(pointlist);
//得到需要删除的实体
Entity entDel;
for (long j = 0; j < ssTemp2.Length(); ++j)
{
entDel = ssTemp2[j];
acdbGetObjectId(id,entDel);
if (ssTemp.IsInclude(entDel))
{
ssDel += id;
ssTemp -= id;
}
}
}
ss -= ssDel;
}
//过滤掉无用实体
//ss :需要过滤的实体集 作为返回参数时表示过滤后的实体集
//pt 需要计算标高的点的坐标
//算法:将一个圆分成多个扇形,将同一个扇形中离圆心最近的点保留,其他点删除
void CCollectElevation::FiletratePickSet(PickSet &ss,XPoint pt,double dAngle)
{
AcGeVector3d vec3dFirst,vec3dNext;
XPoint ptTemp,ptVal;
//求得形成扇形区域的两向量
pt.z = 0;
ptTemp = pt;
ptTemp.y = pt.y -1;
vec3dFirst = ptTemp - pt;
vec3dFirst.normalize();
vec3dFirst.rotateBy(dAngle,AcGeVector3d::kZAxis);
vec3dNext = vec3dFirst;
PickSet ssTemp(SS_FREE);
ssTemp += ss;
PickSet ssRel(SS_FREE);
Entity ent,entTemp;
AcDbObjectId id,tempID;
double dMin = 0.0;
XPoint ptProject;
for (int k = 0; k < (2*PI)/m_dAngel; ++k)
{
vec3dNext.rotateBy(m_dAngel,AcGeVector3d::kZAxis);
XLine xLineFirst(pt,pt+vec3dFirst);
XLine xLineNext(pt,pt+vec3dNext);
//求得扇形区域内距离圆心最近的点
BOOL bFirst = TRUE;
BOOL bHasPointsIn = FALSE;
for (long i = 0; i < ssTemp.Length(); ++i)
{
ent = ssTemp[i];
acdbGetObjectId(id,ent);
if (m_mapIDToPt.find(id) != m_mapIDToPt.end())
ptVal = m_mapIDToPt[id];
//ptVal点不在扇形区域则继续循环
if (!IsPointInArc(vec3dFirst,vec3dNext,ptVal,pt))
continue;
else
bHasPointsIn = TRUE;
if (ptVal.Distance(&xLineFirst) < ptVal.Distance(&xLineNext))
ptVal.Project(&xLineFirst,ptProject);
else
ptVal.Project(&xLineNext,ptProject);
if (bFirst)
{
dMin = pt.Distance2d(ptProject);
tempID = id;
entTemp = ent;
bFirst = FALSE;
}
else
{
if (dMin > pt.Distance2d(ptProject))
{
dMin = pt.Distance2d(ptProject);
tempID = id;
entTemp = ent;
}
}
}
if (bHasPointsIn)
{
//至少有 一点在 扇形区域
if (!ssRel.IsInclude(entTemp))
{
if (!!entTemp)
ssRel += entTemp;
}
if (m_mapIDToPt.find(tempID) != m_mapIDToPt.end())
ptVal = m_mapIDToPt[tempID];
if (dAngle > 0.01)
{
XPoint pt1 = ptVal,pt2 = ptVal,pt3 = ptVal,pt4 = ptVal;
pt1.y += 10*GlobalFunc::DocGetPScale();
pt2.y -= 10*GlobalFunc::DocGetPScale();
pt3.x += 10*GlobalFunc::DocGetPScale();
pt4.x -= 10*GlobalFunc::DocGetPScale();
ads_grdraw(GlobalFunc::Wcs2Ucs(pt1),GlobalFunc::Wcs2Ucs(pt2),1,0);
ads_grdraw(GlobalFunc::Wcs2Ucs(pt3),GlobalFunc::Wcs2Ucs(pt4),1,0);
}
}
vec3dFirst = vec3dNext;
}
for (long j = 0; j < ssTemp.Length(); ++j)
{
if (!ssRel.IsInclude(ssTemp[j]))
ss -= ssTemp[j];
}
}
//判断点是否在两个向量组成扇形区域
BOOL CCollectElevation::IsPointInArc(AcGeVector3d vec1,AcGeVector3d vec2,AcGePoint3d pt,AcGePoint3d ptCenter)
{
pt.z = 0;
AcGeVector3d vec = pt - ptCenter;
vec.normalize();
AcDbLine xLine(pt,ptCenter);
XPoint pt1,pt2;
pt1 = ptCenter + vec1;
pt2 = ptCenter + vec2;
AcGePoint3dArray ptArray;
AcDbLine line(pt1,pt2);
line.intersectWith(&xLine,AcDb::kOnBothOperands,ptArray);
if (ptArray.length() > 0)
return TRUE;
else
return FALSE;
}
*/
//设置地形
void CCollectElevation::SetLandForm(int nType)
{
m_nLandForm = nType;
}
// 过滤含非数值型数据的实体
void CCollectElevation::FiletratePickSet(PickSet &ss, Entity &ent)
{
PickSet ssDel(SS_FREE);
if (ent.Is(_T("ATS_TEXT")))
{
AcDbObjectId id;
AecXDbText *pEnt = NULL;
CString strText;
for(long i = 0; i < ss.Length(); i++)
{
acdbGetObjectId(id, ss[i]);
acdbOpenObject(pEnt, id, AcDb::kForRead);
if (pEnt != NULL)
{
strText = pEnt->GetText();
pEnt->close();
// 是否为数值
if (!IsNumValue(strText))
{
ssDel += ss[i];
}
}
}
}
else if (ent.Is(_T("TEXT")))
{
AcDbObjectId id;
AcDbText *pEnt = NULL;
CString strText;
for(long i = 0; i < ss.Length(); i++)
{
acdbGetObjectId(id, ss[i]);
acdbOpenObject(pEnt, id, AcDb::kForRead);
if (pEnt != NULL)
{
strText = pEnt->textString();
pEnt->close();
// 是否为数值
if (!IsNumValue(strText))
{
ssDel += ss[i];
}
}
}
}
else if (ent.Is(_T("ATS_ELEVATION")))
{
CString strText;
AcDbObjectId id;
AecXDbSymbElevation *pEnt = NULL;
for(long i = 0; i < ss.Length(); i++)
{
acdbGetObjectId(id, ss[i]);
acdbOpenObject(pEnt, id, AcDb::kForRead);
if (pEnt != NULL)
{
strText = pEnt->GetText();
pEnt->close();
// 是否为数值
if (!IsNumValue(strText))
{
ssDel += ss[i];
}
}
}
}
ss -= ssDel;
}
bool CCollectElevation::IsNumValue(const CString &strText)
{
bool bRet = true;
TCHAR ch;
for (int j = 0; j < strText.GetLength(); j++)
{
ch = strText.GetAt(j);
if ((ch < _T('0') || ch > _T('9')) &&
ch != _T('.') && ch != _T('-') && ch != _T('+'))
{
bRet = false;
break;
}
}
return bRet;
}
bool CCollectElevation::GetNearestPtEle(const AcGePoint3d &pt, int nType, double &dEle)
{
bool bRet = false;
//获取最近点
Entity ent;
AcDbObjectId id;
id = GetNearestPt(pt);
if (id.isValid())
{
std::vector<AcGePoint3d> vecPt;
std::map<AcDbObjectId,XPoint>::iterator it;
it = m_mapIDToPt.find(id);
vecPt.push_back((*it).second);
DrawAcrossLine(vecPt);
//获取最近点标高
dEle = GetEntEle(id, nType);
bRet = true;
}
return bRet;
}
bool CCollectElevation::GetEleByThreePt(PickSet &ssAll, const AcGePoint3d &pt, int nType, double &dEle)
{
bool bRet = false;
// 获取三个最近点
std::vector<AcDbObjectId> vecId;
GetNearestThreePt(vecId, pt);
// 由三点求pt点的标高
if (vecId.size() >= 3)
{
// 保存m_mapIDToPt中的数据
std::map<AcDbObjectId,XPoint> temp;
std::map<AcDbObjectId,XPoint>::iterator it;
for (it = m_mapIDToPt.begin(); it != m_mapIDToPt.end(); it++)
{
temp[(*it).first] = (*it).second;
}
std::vector<AcGePoint3d> vecPt;
AcGePoint3d pt1, pt2, pt3;
AcDbObjectId id;
double dEle2 = 0.0;
// 确定三点的Z值
id = vecId[0];
it = m_mapIDToPt.find(id);
if (it != m_mapIDToPt.end())
{
pt1 = (*it).second;
dEle2 = GetEntEle(id, nType);
pt1.z = dEle2;
m_mapIDToPt.erase(it);
}
id = vecId[1];
it = m_mapIDToPt.find(id);
if (it != m_mapIDToPt.end())
{
pt2 = (*it).second;
dEle2 = GetEntEle(id, nType);
pt2.z = dEle2;
m_mapIDToPt.erase(it);
}
id = vecId[2];
it = m_mapIDToPt.find(id);
if (it != m_mapIDToPt.end())
{
pt3 = (*it).second;
dEle2 = GetEntEle(id, nType);
pt3.z = dEle2;
m_mapIDToPt.erase(it);
}
vecPt.push_back(pt1);
vecPt.push_back(pt2);
vecPt.push_back(pt3);
if(IsPtInTriangle(pt1, pt2, pt3, pt)) // pt 点在三角形内
{
// 构造经过三点的平面
AcGePlane plan(pt1, pt2, pt3);
// 求点到面的投影点
AcGePoint3d ptPrj;
ptPrj = pt.project(plan, AcGeVector3d::kZAxis);
double d = tan(GetAnglePlaneToXYPlane(plan));
dEle = ptPrj.z;
bRet = true;
DrawAcrossLine(vecPt);
}
else // pt点不在三角形内
{
AcGePoint3d ptPrj, ptT1, ptT2, ptT3;
std::map<AcDbObjectId, XPoint>::iterator it;
AcGePoint3d pt4;
while (m_mapIDToPt.size() != 0)
{
id = GetNearestPt(pt);
it = m_mapIDToPt.find(id);
if (it == m_mapIDToPt.end())
{
continue;
}
pt4 = (*it).second;
m_mapIDToPt.erase(it);
// cet 2011.12.7 add 判断第四个点距pt点是否在合理范围
if (!IsValidPt(pt1, pt2, pt3, pt4, pt, 1.5))
{
continue;
}
dEle2 = GetEntEle(id, nType);
pt4.z = dEle2;
bool bRes1 = IsPtInTriangle(pt4, pt2, pt3, pt);
bool bRes2 = IsPtInTriangle(pt1, pt4, pt3, pt);
bool bRes3 = IsPtInTriangle(pt1, pt2, pt4, pt);
if (bRes1 && !bRes2 && !bRes3)
{
ptPrj = GetProjectPt(pt4, pt2, pt3, pt);
vecPt[0] = pt4;
}
else if (!bRes1 && bRes2 && !bRes3)
{
ptPrj = GetProjectPt(pt1, pt4, pt3, pt);
vecPt[1] = pt4;
}
if (!bRes1 && !bRes2 && bRes3)
{
ptPrj = GetProjectPt(pt1, pt2, pt4, pt);
vecPt[2] = pt4;
}
else if (bRes1 && bRes2 && !bRes3)
{
ptT1 = pt1;
ptT2 = pt2;
ptT3 = pt;
ptT1.z = 0;
ptT2.z = 0;
ptT3.z = 0;
if (ptT3.distanceTo(ptT1) < ptT3.distanceTo(ptT2))
{
ptPrj = GetProjectPt(pt1, pt4, pt3, pt);
vecPt[1] = pt4;
}
else
{
ptPrj = GetProjectPt(pt4, pt2, pt3, pt);
vecPt[0] = pt4;
}
}
if (bRes1 && !bRes2 && bRes3)
{
ptT1 = pt1;
ptT2 = pt3;
ptT3 = pt;
ptT1.z = 0;
ptT2.z = 0;
ptT3.z = 0;
if (ptT3.distanceTo(ptT1) < ptT3.distanceTo(ptT2))
{
ptPrj = GetProjectPt(pt1, pt2, pt4, pt);
vecPt[2] = pt4;
}
else
{
ptPrj = GetProjectPt(pt4, pt2, pt3, pt);
vecPt[0] = pt4;
}
}
else if (!bRes1 && bRes2 && bRes3)
{
ptT1 = pt3;
ptT2 = pt2;
ptT3 = pt;
ptT1.z = 0;
ptT2.z = 0;
ptT3.z = 0;
if (ptT3.distanceTo(ptT1) < ptT3.distanceTo(ptT2))
{
ptPrj = GetProjectPt(pt1, pt4, pt3, pt);
vecPt[1] = pt4;
}
else
{
ptPrj = GetProjectPt(pt1, pt2, pt4, pt);
vecPt[2] = pt4;
}
}
if (!bRes1 && !bRes2 && !bRes3)
{
continue;
}
dEle = ptPrj.z;
bRet = true;
DrawAcrossLine(vecPt);
break;
}
}
// 恢复m_mapIDToPt
m_mapIDToPt.clear();
for (it = temp.begin(); it != temp.end(); it++)
{
m_mapIDToPt[(*it).first] = (*it).second;
}
}
return bRet;
}
void CCollectElevation::GetNearestThreePt(std::vector<AcDbObjectId> &vecId, const AcGePoint3d &pt)
{
if (m_mapIDToPt.size() < 3)
{
return;
}
AcDbObjectId id;
std::map<AcDbObjectId,XPoint> temp;
std::map<AcDbObjectId,XPoint>::iterator it;
for (it = m_mapIDToPt.begin(); it != m_mapIDToPt.end(); it++)
{
temp[(*it).first] = (*it).second;
}
id = GetNearestPt(pt);
vecId.push_back(id);
m_mapIDToPt.erase(id);
id = GetNearestPt(pt);
vecId.push_back(id);
m_mapIDToPt.erase(id);
id = GetNearestPt(pt);
vecId.push_back(id);
m_mapIDToPt.erase(id);
m_mapIDToPt.clear();
for (it = temp.begin(); it != temp.end(); it++)
{
m_mapIDToPt[(*it).first] = (*it).second;
}
}
AcDbObjectId CCollectElevation::GetNearestPt(const AcGePoint3d &pt)
{
Entity ent;
AcDbObjectId id = AcDbObjectId::kNull;
double nMin = 0.0;
XPoint ptTemp;
std::map<AcDbObjectId,XPoint>::iterator it;
id = AcDbObjectId::kNull;
for (it = m_mapIDToPt.begin(); it != m_mapIDToPt.end(); it++)
{
ptTemp = (*it).second;
if (it == m_mapIDToPt.begin())
{
nMin = ptTemp.Distance2d(pt);
id = (*it).first;
}
else
{
if (nMin > ptTemp.Distance2d(pt))
{
nMin = ptTemp.Distance2d(pt);
id = (*it).first;
}
}
}
return id;
}
void CCollectElevation::GetAllPickSetPt(PickSet &ssAll, const AcGePoint3d &pt, int nType)
{
Entity ent;
AcDbObjectId id;
XPoint ptVal;
AcDbPoint *pPt = NULL;
AcDbCircle *pCir = NULL;
AcDbBlockReference *pRef = NULL;
for (long j = 0; j < ssAll.Length(); ++j)
{
ent = ssAll[j];
acdbGetObjectId(id,ent);
if (nType == 0 || nType == 5) // 文字
{
double dDis = 0.0;
GetTextValue(pt,ent,dDis,ptVal);
}
else if (nType == 1) // 点
{
acdbOpenObject(pPt, id, AcDb::kForRead);
if(pPt != NULL)
{
ptVal = pPt->position();
pPt->close();
// cet 2011.12.2 add
if(m_bExternalBlk)
{
ptVal.TransformBy(m_mat);
}
}
}
else if (nType == 2) // 圆
{
acdbOpenObject(pCir, id, AcDb::kForRead);
if(pCir != NULL)
{
ptVal = pCir->center();
pCir->close();
// cet 2011.12.2 add
if(m_bExternalBlk)
{
ptVal.TransformBy(m_mat);
}
}
}
else // 块
{
acdbOpenObject(pRef, id, AcDb::kForRead);
if(pRef != NULL)
{
ptVal = pRef->position();
pRef->close();
// cet 2011.12.2 add
if(m_bExternalBlk)
{
ptVal.TransformBy(m_mat);
}
}
}
m_mapIDToPt[id] = ptVal;
}
}
double CCollectElevation::GetEntEle(const AcDbObjectId &id, int nType)
{
double dEle = 0.0;
XPoint ptVal;
AcDbPoint *pPt = NULL;
AcDbCircle *pCir = NULL;
AcDbBlockReference *pRef = NULL;
if (nType == 0) // 文字
{
ads_name sName;
acdbGetAdsName(sName, id);
Entity ent(sName);
if (ent.Is(_T("ATS_TEXT")))
{
AecXDbText *pText = NULL;
acdbOpenObject(pText, id, AcDb::kForRead);
if (pText != NULL)
{
CString strText = pText->GetText();
dEle = _tstof(strText);
pText->close();
}
}
else if (ent.Is(_T("TEXT")))
{
AcDbText *pText = NULL;
acdbOpenObject(pText, id, AcDb::kForRead);
if (pText != NULL)
{
CString strText = pText->textString();
dEle = _tstof(strText);
pText->close();
}
}
}
else if ( nType == 5) // 文字
{
AecXDbSymbElevation *pEle = NULL;
acdbOpenObject(pEle, id, AcDb::kForRead);
if (pEle != NULL)
{
CString strText = pEle->GetText();
pEle->close();
dEle = _tstof(strText);
}
}
else if (nType == 1) // 点
{
acdbOpenObject(pPt, id, AcDb::kForRead);
if(pPt != NULL)
{
ptVal = pPt->position();
pPt->close();
// cet 2011.12.2 add
if (m_bExternalBlk)
{
ptVal.TransformBy(m_mat);
}
dEle = ptVal.z;
}
}
else if (nType == 2) // 圆
{
acdbOpenObject(pCir, id, AcDb::kForRead);
if(pCir != NULL)
{
ptVal = pCir->center();
pCir->close();
// cet 2011.12.2 add
if (m_bExternalBlk)
{
ptVal.TransformBy(m_mat);
}
dEle = ptVal.z;
}
}
else // 块
{
acdbOpenObject(pRef, id, AcDb::kForRead);
if(pRef != NULL)
{
if (nType == 3) //图块Z坐标
{
ptVal = pRef->position();
pRef->close();
// cet 2011.12.2 add
if (m_bExternalBlk)
{
ptVal.TransformBy(m_mat);
}
dEle = ptVal.z;
}
else if (nType == 4) // 图块属性值
{
AcDbObjectIterator *pIterator = NULL;
pIterator = pRef->attributeIterator();
for (pIterator->start(); !pIterator->done(); pIterator->step())
{
//遍历块中实体
AcDbEntity *pEnt = NULL;
AcDbAttribute *pAtt = NULL;
AcDbObjectId att_id;
att_id = pIterator -> objectId();
acdbOpenAcDbEntity(pEnt, att_id, AcDb::kForRead);
pAtt = AcDbAttribute::cast(pEnt);
if(pAtt != NULL)
{
CString strText = pAtt->textString();
dEle = _tstof(strText);
}
pEnt->close();
}
delete pIterator;
pRef->close();
}
}
}
return dEle;
}
void CCollectElevation::GetNeedPicSet(Entity ent, AcGePoint3d pt, int nType)
{
// 设置过滤器
resbuf *rb = NULL;
TCHAR szLayerName[256];
ent.GetData(8,szLayerName);
if (nType == 0)
{
rb = ads_buildlist(RTDXF0, _T("TEXT,ATS_TEXT"), 8, szLayerName, NULL);
}
else if (nType == 1)
{
rb = ads_buildlist(RTDXF0, _T("POINT"), 8, szLayerName,NULL);
}
else if (nType == 2)
{
rb = ads_buildlist(RTDXF0, _T("CIRCLE"),8, szLayerName, NULL);
}
else if (nType == 5)
{
rb = ads_buildlist(RTDXF0, _T("ATS_ELEVATION"), 8, szLayerName, NULL);
}
else
{
TCHAR szBlkName[256];
ent.GetData(2,szBlkName);
rb = ads_buildlist(RTDXF0, _T("INSERT"), 8, szLayerName, 2, szBlkName, NULL);
}
// 选取数据源
int nSize = 0;
if (m_nLandForm == 0)
{
nSize = 1;
}
else
{
nSize = 3;
}
double dLen = 2 * GlobalFunc::DocGetPScale();
int nCount = 1;
XPoint pt1, pt2, pt3, pt4;
PickSet ssSel(SS_FREE);
pt = GlobalFunc::Wcs2Ucs(pt);
while (ssSel.Length() < nSize)
{
dLen *= nCount;
ssSel.Free();
pt1 = pt - AcGeVector3d::kXAxis * dLen + AcGeVector3d::kYAxis * dLen;
pt2 = pt - AcGeVector3d::kXAxis * dLen - AcGeVector3d::kYAxis * dLen;
pt3 = pt2 + AcGeVector3d::kXAxis * 2 * dLen;
pt4 = pt1 + AcGeVector3d::kXAxis * 2 * dLen;
pt = GlobalFunc::Ucs2Wcs(pt);
RBList rbPt = acutBuildList(RTPOINT,&pt1,RTPOINT,&pt2,RTPOINT,&pt3,RTPOINT,&pt4,NULL);
acedSSGet(_T("CP"),rbPt,NULL,rb,ssSel);
FiletrateInvalidEnt(ssSel, ent); // 删除选择集中的无效数据
nCount *= 10;
}
// 保存选择集中的实体id
m_vecId.clear();
for (long i = 0; i < ssSel.Length(); i++)
{
AcDbObjectId id = AcDbObjectId::kNull;
acdbGetObjectId(id, ssSel[i]);
m_vecId.push_back(id);
}
}
void CCollectElevation::FiletrateInvalidEnt(PickSet &ss, Entity &ent)
{
PickSet ssDel(SS_FREE);
std::map<AcDbObjectId, XPoint>::iterator it;
for (long i = 0; i < ss.Length(); i++)
{
AcDbObjectId id = AcDbObjectId::kNull;
acdbGetObjectId(id, ss[i]);
it = m_mapIDToPt.find(id);
if (it == m_mapIDToPt.end())
{
ssDel += ss[i];
}
}
ss -= ssDel;
}
void CCollectElevation::DrawAcrossLine(std::vector<AcGePoint3d> &vecPt)
{
std::vector<AcGePoint3d>::iterator it;
double dLen = 10*GlobalFunc::DocGetPScale();
for (it = vecPt.begin(); it != vecPt.end(); it++)
{
XPoint pt;
pt = *it;
pt = GlobalFunc::Wcs2Ucs(pt);
XPoint pt1 = pt,pt2 = pt,pt3 = pt,pt4 = pt;
pt1.y += dLen;
pt2.y -= dLen;
pt3.x += dLen;
pt4.x -= dLen;
ads_grdraw(pt1,pt2,1,0);
ads_grdraw(pt3,pt4,1,0);
}
}
void CCollectElevation::SetPickSet(PickSet &ssAll)
{
m_ssAll.Free();
m_ssAll += ssAll;
}
double CCollectElevation::GetAnglePlaneToXYPlane(const AcGePlane &plane)
{
AcGeVector3d normal1, normal2;
normal1 = plane.normal();
normal2 = (AcGePlane::kXYPlane).normal();
double dAngle = normal2.angleTo(normal1);
if (dAngle > PI / 2)
{
dAngle = PI - dAngle;
}
return dAngle;
}
void CCollectElevation::SetGradient(bool bGradient)
{
m_bGradient = bGradient;
}
double CCollectElevation::GetGradient()
{
return m_dGradient;
}
void CCollectElevation::SetGradient(double dGradient)
{
m_dGradient = dGradient;
}
bool CCollectElevation::IsPtInTriangle(AcGePoint3d pt1, AcGePoint3d pt2, AcGePoint3d pt3, AcGePoint3d pt)
{
bool bRet = false;
pt1.z = 0;
pt2.z = 0;
pt3.z = 0;
pt.z =0;
AcDbLine l1(pt1, pt2), l2(pt1, pt3), l3(pt3, pt2);
if (IsPtOnLine(l1, pt) || IsPtOnLine(l2, pt) || IsPtOnLine(l2, pt)) // 点在边上
{
bRet = true;
}
else
{
AcGePoint3d ptMin1, ptMin2;
ptMin1.x = (pt1.x + pt2.x) / 2;
ptMin1.y = (pt1.y + pt2.y) / 2;
ptMin1.z = (pt1.z + pt2.z) / 2;
ptMin2.x = (pt1.x + pt3.x) / 2;
ptMin2.y = (pt1.y + pt3.y) / 2;
ptMin2.z = (pt1.z + pt3.z) / 2;
AcDbLine l4(ptMin1, pt3), l5(ptMin2, pt2);
AcGePoint3dArray arPt;
l4.intersectWith(&l5, AcDb::kOnBothOperands, arPt);
if (arPt.length() == 1)
{
AcGePoint3d ptIns = arPt[0];
AcDbLine l6(ptIns, pt);
if (!IsIntersectionLineByLine(l6, l1) &&
!IsIntersectionLineByLine(l6, l2) &&
!IsIntersectionLineByLine(l6, l3))
{
bRet = true;
}
}
}
return bRet;
}
bool CCollectElevation::IsPtOnLine(const AcDbLine &line, const AcGePoint3d &pt)
{
bool bRet = false;
AcGePoint3d ptTemp;
line.getClosestPointTo(pt, ptTemp);
if (pt.distanceTo(ptTemp) < 1e-3)
{
bRet = true;
}
return bRet;
}
bool CCollectElevation::IsIntersectionLineByLine(const AcDbLine &l1, const AcDbLine &l2)
{
AcGePoint3dArray arPt;
l1.intersectWith(&l2, AcDb::kOnBothOperands, arPt);
if (arPt.length() == 0)
{
return false;
}
return true;
}
AcGePoint3d CCollectElevation::GetProjectPt(const AcGePoint3d pt1, const AcGePoint3d pt2, const AcGePoint3d pt3, const AcGePoint3d pt)
{
// 构造经过三点的平面
AcGePlane plan(pt1, pt2, pt3);
// 求点到面的投影点
AcGePoint3d ptPrj;
ptPrj = pt.project(plan, AcGeVector3d::kZAxis);
return ptPrj;
}
void CCollectElevation::SetExternalBlk(bool bExternalBlk)
{
m_bExternalBlk = bExternalBlk;
}
void CCollectElevation::SetExnternalBlkMat(const AcGeMatrix3d &mat)
{
m_mat = mat;
}
bool CCollectElevation::IsValidPt(const AcGePoint3d &pt1, const AcGePoint3d &pt2, const AcGePoint3d &pt3, const AcGePoint3d &pt4, const AcGePoint3d &pt, double dScale)
{
AcGePoint3d ptTemp1 = pt1, ptTemp2 = pt2;
AcGePoint3d ptTemp3 = pt3, ptTemp4 = pt4;
AcGePoint3d ptTemp = pt;
ptTemp1.z = 0.0;
ptTemp2.z = 0.0;
ptTemp3.z = 0.0;
ptTemp4.z = 0.0;
ptTemp.z = 0.0;
double dDist1 = ptTemp1.distanceTo(ptTemp);
double dDist2 = ptTemp2.distanceTo(ptTemp);
double dDist3 = ptTemp3.distanceTo(ptTemp);
double dDist4 = ptTemp4.distanceTo(ptTemp);
double dMaxDist = dDist1 > dDist2 ? (dDist1 > dDist3 ? dDist1 : dDist3) : (dDist2 > dDist3 ? dDist2 : dDist3);
if (dMaxDist * dScale < dDist4)
{
return false;
}
return true;
}