#include "stdafx.h" #include "globalFunc.h" #include "AcDbObjectPtr.h" #include "CollectElevation.h" #include "aecdbtext.h" #include "dbxline.h" #include #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 &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 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 vecPt; std::map::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 vecId; GetNearestThreePt(vecId, pt); // 由三点求pt点的标高 if (vecId.size() >= 3) { // 保存m_mapIDToPt中的数据 std::map temp; std::map::iterator it; for (it = m_mapIDToPt.begin(); it != m_mapIDToPt.end(); it++) { temp[(*it).first] = (*it).second; } std::vector 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::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 &vecId, const AcGePoint3d &pt) { if (m_mapIDToPt.size() < 3) { return; } AcDbObjectId id; std::map temp; std::map::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::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::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 &vecPt) { std::vector::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; }