#include "StdAfx.h" #include #include #include #include "UITools.h" #include "ZDOutput.h" #include "KTCadUtility.h" #include "KTCadUtilityEx.h" #include "KTSetting.h" #include "aecdbObjXDataMap.h" #include "KTModelLayoutXData.h" #include "MakeDim.h" #include "sorttab.h" #include "dimfactory.h" namespace { #define TEXT_STYLE _T("Pipe_Dim") #define STAKE_SECTION _T("DIM_DATA") #define STAKE_SEGMENT _T("szStake") #define STAKE_TYPE _T("szNodeSpec") #define STAKE_FNTYPE _T("eFnType") #define NODE_TYPE _T("szNodeSpec") #define NODE_ID _T("szLockId") #define NODE_NAME _T("szNodeName") #define ZDTB_FILE _T("\\zdtbsz.dat") #define STAKE_FILE_NAME _T("\\stakedata.dat") // 标尺与网格最左侧间距 static double g_rule_grid_space = 2; // 内容块需要平移的矩阵 static AcGeMatrix3d g_content_blk_mat; // 最后一张图宽度范围 static std::pair g_prRang; } namespace { bool AddToTableRecord(AcDbEntity* pEnt, AcDbObjectId &id, bool bClose = true, AcDbObjectId *pEntID = NULL) { if (!pEnt) return false; AcDbObjectId entID; OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbBlockTableRecord, pRec) if (!pRec) return false; pRec->appendAcDbEntity(entID, pEnt); if (bClose) pEnt->close(); OPENOBJ_END() if (pEntID) *pEntID = entID; return true; } double getScale(LPCTSTR s) { if (!s) return .0; AecDbObjXDataMap xDataMap; KTModelLayoutXData::ReadModelXData(_T("EW_EARTHWORMINIT"), xDataMap); CString scale(_T("1:100")); xDataMap.GetAt(s, scale); int idx = scale.Find(_T(":")); CString a = scale.Left(idx); CString b = scale.Mid(idx+1); //return _ttof(b)/_ttof(a); return 1; } bool InBox(const AcGePoint3d &pt, const double maxX, const double &minX) { return ( pt.x <= maxX && pt.x >= minX ); } void drawCircle(AcDbObjectId id, const AcGePoint3d &pt, const double &r = 10) { AcDbCircle *p = new AcDbCircle(pt, AcGeVector3d::kZAxis, r); AddToTableRecord(p, id); } struct EWNodeDimInfo { CString strType; CString strID; CString strStake; CString strName; int fnType; AcDbExtents ext; AcGePoint3d getInsPnt() const { AcGePoint3d ptIns(AcGePoint3d::kOrigin); Midpoint((ext.maxPoint()), (ext.minPoint()), ptIns); return ptIns; } struct _com_by_x { bool operator () (EWNodeDimInfo &a, EWNodeDimInfo &b) { return a.getInsPnt().x < b.getInsPnt().x; } }; }; typedef std::map EWNodeDimInfos; void catalogNodeType(const std::vector &ids, EWNodeDimInfos &nds) { AecDbObjXDataMap xmap; CString strType(_T("")), strID(_T("")), strStake(_T("")), strName(_T("")); int fnType; AcDbObjectId id; EWNodeDimInfo info; double dist(.0); for (size_t i = 0; i < ids.size(); ++i) { id = ids[i]; xmap.Empty(); OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbEntity, pEnt) if (!xmap.Read(pEnt, STAKE_SECTION)) continue; if (!xmap.GetAt(NODE_TYPE, strType)) continue; if (!xmap.GetAt(NODE_ID, strID)) continue; if (!xmap.GetAt(STAKE_FNTYPE, fnType)) continue; if (xmap.GetAt(STAKE_SEGMENT, strStake)) // 非必须 info.strStake = strStake; xmap.GetAt(NODE_NAME, strName); // 里程节点不需要标注 if (fnType == kStackNode) continue; // 变形缝不需要标注 if (fnType == kEspJoint) continue; // 子变形缝需要看一下配置 if (fnType == kSubEspJoint) { bool bDimJoin = TypeConvert::s2i(ZD_OUT::getConfiguration(ZD_OUT::KEY_BXFBZ_S)) == 0 ? false : true; if (!bDimJoin) continue; } info.strID = strID; info.fnType = fnType; info.strType = strType; info.strName = strName; EWNodeDimInfos::iterator it = nds.find(strID); AcDbExtents ext; pEnt->getGeomExtents(ext); if (it == nds.end())// 未找到,新建 { info.ext = ext; nds.insert(std::make_pair(strID, info)); } else it->second.ext.addExt(ext); OPENOBJ_END() } } } namespace { std::vector> g_config; // 生成默认的配置数据 int initConfig() { for (size_t i = 0; i < sizeof(ZD_OUT::g_TableHead) / sizeof(LPCTSTR); i++) g_config.push_back(std::make_pair(ZD_OUT::g_TableHead[i], _T("1"))); // 纵断计算数据 文字设置 g_config.push_back(std::make_pair(ZD_OUT::KEY_HEAD_H, _T("2"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_HEAD_S, _T("Pipe_Dim"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_HEAD_W, _T("0.75"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_DATA_H, _T("1.5"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_DATA_S, _T("Pipe_Dim"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_DATA_W, _T("0.5"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_DATA_GL_STAKENO, _T("K0+000"))); // 网格设置 g_config.push_back(std::make_pair(ZD_OUT::KEY_GRID_INTERVAL, _T("1"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_GRID_PREC, _T("1"))); // 网格设置 文字设置 g_config.push_back(std::make_pair(ZD_OUT::KEY_RATIO_H , _T("0.5"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_RATIO_S , _T("Pipe_Dim"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_RATIO_W , _T("0.5"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_GRID_H , _T("0.5"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_GRID_S , _T("Pipe_Dim"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_GRID_W , _T("0.5"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_ARROW_W , _T("0.25"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_GRID_WH, _T("0.25"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_GRID_TEXT_INTERVAL, _T("0.75"))); // 节点设置 g_config.push_back(std::make_pair(ZD_OUT::KEY_NODE_SCALE, _T("1.0"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_BXFBZ_S, _T("1"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_NODE_DIMTYPE, _T("1"))); // 引出标注设置 g_config.push_back(std::make_pair(ZD_OUT::KEY_YCBZ_H , _T("1.75"))); g_config.push_back(std::make_pair(ZD_OUT::KEY_YCBZ_S , _T("Pipe_Dim"))); // 其它设置 g_config.push_back(std::make_pair(ZD_OUT::KEY_QTSZ_LCJG , _T("200"))); return 1; } void split(LPCTSTR pszSrc, TCHAR sp, std::vector &vec) { if (!pszSrc) return; vec.clear(); CString src(pszSrc); CString oneString(_T("")); TCHAR ch; for (int i = 0; i < src.GetLength(); ++i) { ch = src[i]; if (ch == sp) { if (oneString.IsEmpty()) continue; else { vec.push_back(oneString); oneString.Empty(); } } else oneString += ch; } if (!oneString.IsEmpty()) vec.push_back(oneString); } void analyGradeAndDistance(LPCTSTR psz, CString &sGrade, CString &sDistance, CString &start, CString &end) { // 坡度%/距离(起始号-结束号) if (!psz) return; CString str(psz); // idx1 '/' 位置 int idx1 = str.FindOneOf(_T("/")); if (idx1 == -1) return; sGrade = str.Left(idx1); // idx2 '(' 位置 int idx2 = str.Find(_T("("), idx1); if (idx2 == -1) return; sDistance = str.Mid(idx1 + 1, idx2 - idx1 - 1); // idx3 '-'位置 int idx3 = str.Find(_T("-"), idx2); if (idx3 == -1) return; start = str.Mid(idx2 + 1, idx3 - idx2 - 1); // idx4 ')'位置 int idx4 = str.Find(_T(")"), idx3); if (idx4 == -1) return; end = str.Mid(idx3 + 1, idx4 - idx3 - 1); return; } bool readConfiguration() { CString sPath = FilePath::getProgramDataFolder() + ZDTB_FILE; if (_taccess(sPath, 0x0) != 0x0) return false; CStdioFile file(sPath, CFile::shareDenyRead); if (!file.m_hFile) return false; CString line(_T("")); std::vector vec(0); std::pair pr; std::vector> _temp(0); while (file.ReadString(line)) { split(line, _T('='), vec); if (vec.size() != 2) continue; pr.first = vec[0]; pr.second = vec[1]; _temp.push_back(pr); } int countOfHead = sizeof(ZD_OUT::g_TableHead) / sizeof(LPCTSTR); // 前countOfHead个为纵断数据顺序,所以要与文件中一至 if (_temp.size() < countOfHead) return false; std::vector>::iterator it_temp = _temp.begin() , it_config = g_config.begin(); std::advance(it_temp, countOfHead); std::advance(it_config, countOfHead); // 将 g_config 尾部备份 std::vector> xx(it_config, g_config.end()); // 取文件中前 countOfHead 的数据给g_config,此时,g_config会变成countOfHead个 g_config.assign(_temp.begin(), it_temp); // 把尾部备份还原 g_config.insert(g_config.end(), xx.begin(), xx.end()); // 把尾部的数据与文件中的一一对应 for (size_t i = countOfHead; i < g_config.size(); ++i) { for (size_t j = 0; j < _temp.size(); ++j) { if (_temp[j].first == g_config[i].first) { g_config[i].second = _temp[j].second; } } } return true; } static int g_init = initConfig(); CString getConfiguration(LPCTSTR key) { if (!key) return _T(""); std::vector>::iterator it = g_config.begin(); for (; it != g_config.end(); ++it) { if (it->first.CompareNoCase(key) == 0) return it->second; } return _T(""); } CString getScaleS2() { // 读出纵断比例 AecDbObjXDataMap xDataMap; xDataMap.SetAt(_T("S2"), _T("1:100")); KTModelLayoutXData::ReadModelXData(_T("EW_EARTHWORMINIT"), xDataMap); CString str(_T("1:100")); xDataMap.GetAt(_T("S2"), str); return str; } void scalePaperSpace(AcDbObjectId paperID , AcDbObjectIdArray &arIDs) { if (!GLTools::isThisClass(paperID)) return; if (arIDs.isEmpty()) return; // 读出纵断比例 CString str(getScaleS2()); std::vector vecs(0); split(str, _T(':'), vecs); if (vecs.size() != 2) return; double Yscale = _ttoi(vecs[1]) / _ttoi(vecs[0]); // end // 首先新建一个块表 AcDbObjectId bkID(AcDbObjectId::kNull); AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase(); if (!pDb) return; AcDbBlockTable *pTbl(NULL); Acad::ErrorStatus es = pDb->getBlockTable(pTbl, AcDb::kForWrite); if (es != Acad::eOk) return; AcDbBlockTableRecord *pRc = new AcDbBlockTableRecord; pRc->setName(_T("*xx")); if (pTbl->add(pRc) != Acad::eOk) { pTbl->close(); return; } bkID = pRc->objectId(); pTbl->close(); // end // 将所有 arIDs 内的实本,都clone出一份,加入到新的块表内,然后删除。 AcDbExtents ext, extAll; AcDbObjectIdArray arrTemp(arIDs); for (int i = 0; i < arrTemp.length(); ++i) { OPENOBJ_BEGIN(arrTemp[i], AcDb::kForWrite, AcDbEntity, pEnt) if (!pEnt) continue; if (!AcDbCurve::cast(pEnt)) continue; pEnt->getGeomExtents(ext); extAll.addExt(ext); if (pRc->appendAcDbEntity((AcDbCurve*)pEnt->clone()) == Acad::eOk) { arIDs.removeAt(i); pEnt->erase(); } OPENOBJ_END() } pRc->close(); // end // 新建一个 块参照 按比例进行缩放后炸碎,将炸出的实体入到到 paper 中。 AcDbVoidPtrArray arrPtr; AcGePoint3d ptIns(extAll.minPoint()); AcDbBlockReference *pRef = new AcDbBlockReference(ptIns, bkID); AcGeScale3d scale; scale.set(1., Yscale, 1.); pRef->setScaleFactors(scale); es = pRef->explode(arrPtr); OPENOBJ_BEGIN(paperID, AcDb::kForWrite, AcDbBlockTableRecord, pPaper) for (size_t i = 0; i < arrPtr.length(); i++) { AcDbEntity *p = (AcDbEntity*)arrPtr[i]; if (pPaper->appendAcDbEntity(p) == Acad::eOk) arIDs.append(p->objectId()); } OPENOBJ_END() //pRef->close(); DELETE_PTR(pRef); // end // 最后删除 新建的 块表 OPENOBJ_BEGIN(bkID, AcDb::kForWrite, AcDbBlockTableRecord, pRec) if (pRec) pRec->erase(); OPENOBJ_END() // pRc->erase(); // pRc->close(); // end } void ADSProjectSendToBottom(AcDbObjectId &idPaper, AcDbObjectIdArray &ids) { Acad::ErrorStatus es; OPENOBJ_BEGIN(idPaper, AcDb::kForRead, AcDbBlockTableRecord, pBlock) if (!pBlock) return; AcDbSortentsTable *pSortTbl(NULL); if (Acad::eOk == pBlock->getSortentsTable(pSortTbl, AcDb::kForWrite, true)) { es = pSortTbl->moveToBottom(ids);//moveToTop pSortTbl->close(); } OPENOBJ_END() acDocManager->sendStringToExecute ( acDocManager->curDocument(), _T("_regen\n"), false, true ); } } namespace { struct _compare_pt_y { bool operator () (AcGePoint3d pt1, AcGePoint3d pt2) const { return pt1.y < pt2.y; } }; // bWeitght 粗线在左,细线在右 void insertSegmentOfRuleline(AcDbObjectId &id, const AcGePoint3d &ptS, const AcGePoint3d &ptE, bool bWeight) { double w(TypeConvert::s2f(getConfiguration(ZD_OUT::KEY_GRID_WH))); AcGeVector3d vtl(AcGeVector3d::kXAxis * w); AcGeVector2d vtp(AcGeVector2d::kXAxis * w * .25f); AcDbLine *pLine = new AcDbLine(bWeight ? ptS : ptS - vtl, bWeight ? ptE : ptE - vtl); AcDbPolyline *pPLine = new AcDbPolyline(); AcGePoint2d pt2S(ptS.x, ptS.y), pt2E(ptE.x, ptE.y); pPLine->addVertexAt(0, bWeight ? pt2S - 3*vtp : pt2S - vtp, 0, w*.5, w*.5); pPLine->addVertexAt(1, bWeight ? pt2E - 3*vtp : pt2E - vtp, 0, w*.5, w*.5); g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_RULE); g_LayerMgr::instance().setLayer(pPLine, GLTools::gLayer_ZD_RULE); AddToTableRecord(pLine, id); AddToTableRecord(pPLine, id); } void insertRulelineText( AcDbObjectId &id , const AcGePoint3d &pt , LPCTSTR pszText , int clr , const float &textH , const float &textWFactor , LPCTSTR pszTextStyle ) { float fIntervalWithRule(TypeConvert::s2f(getConfiguration(ZD_OUT::KEY_GRID_TEXT_INTERVAL))); AcDbText *pText = new AcDbText(); pText->setHeight(textH); pText->setWidthFactor(textWFactor); pText->setHorizontalMode(AcDb::kTextRight); pText->setTextString(pszText); AcGeVector3d vtX(AcGeVector3d::kXAxis * (fIntervalWithRule)); AcGeVector3d vtY(AcGeVector3d::kYAxis * textH * .5); pText->setAlignmentPoint(pt - vtX - vtY); AcDbObjectId idTextStyle = GLTools::getTextStyle(TEXT_STYLE); if (!idTextStyle.isNull()) pText->setTextStyle(idTextStyle); g_LayerMgr::instance().setLayer(pText, GLTools::gLayer_ZD_TEXT_RULE); AddToTableRecord(pText, id); } // 画比例尺 void drawScaleRule( AcDbObjectId recID , AcGePoint3d pt , LPCTSTR pszH , LPCTSTR pszV , const double &arW , const double &textH , const double &textWF , LPCTSTR textStyle ) { AcDbExtents extH, extV; AcDbObjectId idTextStyle = GLTools::getTextStyle(textStyle); double deltaXH(.0), deltaYH(.0); double deltaXV(.0), deltaYV(.0); double lenghtH(.0), lenghtV(.0); ////////////////////////////////////////////////////////////////////////// AcDbText *pTextH = new AcDbText(); pTextH->setHeight(textH); pTextH->setWidthFactor(textWF); pTextH->setHorizontalMode(AcDb::kTextMid); pTextH->setTextString(pszH); if (!idTextStyle.isNull()) pTextH->setTextStyle(idTextStyle); pTextH->getGeomExtents(extH); deltaXH = extH.maxPoint().x - extH.minPoint().x; deltaYH = extH.maxPoint().y - extH.minPoint().y; lenghtH = deltaXH * 2.5; ////////////////////////////////////////////////////////////////////////// AcDbText *pTextV = new AcDbText(); pTextV->setHeight(textH); pTextV->setWidthFactor(textWF); pTextV->setRotation(PI * .5); pTextV->setVerticalMode(AcDb::kTextVertMid); pTextV->setTextString(pszV); if (!idTextStyle.isNull()) pTextV->setTextStyle(idTextStyle); pTextV->getGeomExtents(extV); deltaXV = extV.maxPoint().x - extV.minPoint().x; deltaYV = extV.maxPoint().y - extV.minPoint().y; lenghtV = deltaYV * 2.5; ////////////////////////////////////////////////////////////////////////// AcGePoint3d ptIns(pt); ptIns.x += arW; double delta(.01); pTextV->setAlignmentPoint(AcGePoint3d(ptIns.x - delta, ptIns.y + lenghtV * .5 - deltaYV * .5, ptIns.z)); pTextH->setAlignmentPoint(AcGePoint3d(ptIns.x + lenghtH * .5 + deltaXV * .5, ptIns.y + deltaYH * .5 + delta, ptIns.z)); g_LayerMgr::instance().setLayer(pTextH, GLTools::gLayer_ZD_TEXT_SCALE); g_LayerMgr::instance().setLayer(pTextV, GLTools::gLayer_ZD_TEXT_SCALE); AddToTableRecord(pTextH, recID); AddToTableRecord(pTextV, recID); ptIns.x += deltaXV * .5; AcGeVector3d vt; AcGePoint3d ptEndH(AcGePoint3d::kOrigin); AcGePoint3d ptEndV(AcGePoint3d::kOrigin); float arL = arW * 100 / 33; // 画横轴 vt.normalize(); vt = AcGeVector3d::kXAxis; vt *= lenghtH; ptEndH = ptIns + vt; AcDbPolyline *pLineH = new AcDbPolyline; pLineH->addVertexAt(0, AcGePoint2d(ptIns.x, ptIns.y)); pLineH->addVertexAt(1, AcGePoint2d(ptEndH.x, ptEndH.y), .0, arW, 0.); vt.normalize(); vt *= lenghtH + arL; ptEndH = ptIns + vt; pLineH->addVertexAt(2, AcGePoint2d(ptEndH.x, ptEndH.y)); g_LayerMgr::instance().setLayer(pLineH, GLTools::gLayer_ZD_SCALE); AddToTableRecord(pLineH, recID); // 画纵轴 vt.normalize(); vt = AcGeVector3d::kYAxis; vt *= lenghtV; ptEndV = ptIns + vt; AcDbPolyline *pLineV = new AcDbPolyline; pLineV->addVertexAt(0, AcGePoint2d(ptIns.x, ptIns.y)); pLineV->addVertexAt(1, AcGePoint2d(ptEndV.x, ptEndV.y), 0., arW, .0); vt.normalize(); vt *= lenghtV + arL; ptEndV = ptIns + vt; pLineV->addVertexAt(2, AcGePoint2d(ptEndV.x, ptEndV.y)); g_LayerMgr::instance().setLayer(pLineV, GLTools::gLayer_ZD_SCALE); AddToTableRecord(pLineV, recID); } // 在 pt 点生成一个标尺和网格,以pt点位原点, 以dOrigin为起始标尺 // delta grid间距 // height 垂直总高 // width 水平总距离 // factor 为 现实高程与图纸坐标Y值的比例 // prec 刻度的小数个数 void drawGrid(AcDbObjectId &id , const AcGePoint3d &ptOrigin , const double dOrigin , const int &ideltaYInterval , const double &deltaY , const double &deltaX , const double &height , const double &width , const int &prec , const float & textH , const float & textWFactor , LPCTSTR pszTextStyle , double &dLeft // 标尺的 X 值 , double &dMid // 网格最左 X 值 , double &dRight // 网格最右 X 值 , double &dDown // 网格最下 Y 值 ) { // 计算格子 double dSpace(g_rule_grid_space); double _deltaY = deltaY * ideltaYInterval; int h = int((width - dSpace) / deltaX); int v = int(height / deltaY); int v1 = int(height / _deltaY); AcGeVector3d vtY(AcGeVector3d::kYAxis), vtX(AcGeVector3d::kXAxis); vtX.normalize(); vtX *= dSpace; vtY.normalize(); vtY *= _deltaY; std::vector hpts(0); hpts.push_back(ptOrigin + vtX); AcGePoint3d ptUp(ptOrigin/* - vtX*/); dLeft = ptUp.x; int i(0); for (i = 0; i < v1; ++i) { // 先向上 insertSegmentOfRuleline(id, ptUp, ptUp + vtY, i % 2 != 0); insertRulelineText(id, ptUp, TypeConvert::f2s(dOrigin + (i * ideltaYInterval), &prec), i == 0 ? 1 : 256, textH, textWFactor, pszTextStyle); ptUp += vtY; } insertRulelineText(id, ptUp, TypeConvert::f2s(dOrigin + (i * ideltaYInterval), &prec), i == 0 ? 1 : 256, textH, textWFactor, pszTextStyle); vtY.normalize(); vtY *= deltaY; ptUp = ptOrigin + vtX; for (i = 0; i < v; ++i) { ptUp += vtY; hpts.push_back(ptUp); } AcDbObjectIdArray ids; AcDbObjectId entID; // 画横线 vtX.normalize(); vtX *= h * deltaX; AcDbLine *pL(NULL); AcDbObjectId _id; AcGePoint3d ptTemp(AcGePoint3d::kOrigin); for (size_t i = 0; i < hpts.size(); ++i) { ptTemp = hpts[i]; pL = new AcDbLine(ptTemp, ptTemp + vtX); g_LayerMgr::instance().setLayer(pL, GLTools::gLayer_ZD_GRID_LINE); AddToTableRecord(pL, id, true, &_id); ids.append(_id); } dMid = ptTemp.x; dRight = ptTemp.x + vtX.length(); // 画纵线 vtX.normalize(); vtX *= deltaX; vtY.normalize(); vtY *= (v)* deltaY; AcGePoint3d ptS(*hpts.begin()); for (int i = 0; i < h + 1; ++i) { pL = new AcDbLine(ptS, ptS + vtY); g_LayerMgr::instance().setLayer(pL, GLTools::gLayer_ZD_GRID_LINE); AddToTableRecord(pL, id, true, &_id); ptS += vtX; ids.append(_id); } dDown = ptS.y; ads_name ss; acedSSAdd(NULL, NULL, ss); for (long i = 0; i < ids.length(); ++i) { ads_name nn; acdbGetAdsName(nn, ids[i]); acedSSAdd(nn, ss, ss); acedSSFree(nn); } SHacedCommand(RTSTR, _T(".DRAWORDER"), RTPICKS, ss, RTSTR, _T(""), RTSTR, _T("B"), RTSTR, _T(""), RTNONE); acedSSFree(ss); } // 得到纵断的标志点,共三点,“设计道路端点” “上标程点” “下标程点” void getMarkPoints(const AcDbObjectIdArray &arrIDs, std::map &ptMap) { AecDbObjXDataMap xmap; AcGePoint3d pt(AcGePoint3d::kOrigin); double dY(.0); for (int i = 0; i < arrIDs.length(); ++i) { OPENOBJ_BEGIN(arrIDs[i], AcDb::kForRead, AcDbPoint, pPt) if (!pPt) continue; if (!xmap.Read(pPt, _T("StaEl"))) continue; if (!xmap.GetAt(_T("StaEl"), dY)) continue; ptMap.insert(std::make_pair(pPt->position(), dY)); xmap.Empty(); OPENOBJ_END() } } bool generateStakeRecordByFile(std::vector &records) { CString sPath = FilePath::getSystemTemporaryFolder() + _T("\\") + STAKE_FILE_NAME; if (_taccess(sPath, 0x0) != 0x0) return false; CStdioFile file(sPath, CFile::shareDenyRead); if (!file.m_hFile) return false; std::vector stakes(0) // 桩号 , soils(0) // 管廊覆土 , topElev(0) // 管廊外顶标高 , currentGroundElev(0) // 现状地面高程 , designGroundElev(0) // 设计地面高程 , gradAndDistance(0) // 设计坡度与距离 , bottomInnerElev(0) // 管廊内底标高 , glStakes(0) // 管廊内底标高 , soilElev(0) // 覆土高度 , shEwVol(0) // 盾构体积 , guid(0) // GUID ; CString sLine(_T("")); std::vector vec(0); while (file.ReadString(sLine)) { vec.clear(); split(sLine, ' ', vec); if (vec.empty()) continue; if (vec[0].Compare(ZD_OUT::KEY_STAKENO) == 0) stakes.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_SOIL) == 0) soils.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_TOP_ELEV) == 0) topElev.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_CURRENT_GROUND_ELEV) == 0) currentGroundElev.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_DESIGN_GROUND_ELEV) == 0) designGroundElev.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_GRADE_DISTANCE) == 0) gradAndDistance.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_BOTTOM_INNER_ELEV) == 0) bottomInnerElev.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_GL_STAKENO) == 0) glStakes.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_SOIL_ELEV) == 0) soilElev.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_NODE_GUID) == 0) guid.assign(++vec.begin(), vec.end()); else if (vec[0].Compare(ZD_OUT::KEY_SH_EW_VOL) == 0) shEwVol.assign(++vec.begin(), vec.end()); } file.Close(); if (stakes.empty()) return false; if (stakes.size() != soils.size() || stakes.size() != topElev.size() || stakes.size() != currentGroundElev.size() || stakes.size() != designGroundElev.size()) return false; CStakeRecord record0(ZD_OUT::KEY_STAKENO, stakes, stakes); CStakeRecord record1(ZD_OUT::KEY_SOIL, stakes, soils); CStakeRecord record2(ZD_OUT::KEY_TOP_ELEV, stakes, topElev); CStakeRecord record3(ZD_OUT::KEY_CURRENT_GROUND_ELEV, stakes, currentGroundElev); CStakeRecord record4(ZD_OUT::KEY_DESIGN_GROUND_ELEV, stakes, designGroundElev); CStakeRecord record5(ZD_OUT::KEY_GRADE_DISTANCE, gradAndDistance); CStakeRecord record6(ZD_OUT::KEY_BOTTOM_INNER_ELEV, stakes, bottomInnerElev); CStakeRecord record7(ZD_OUT::KEY_GL_STAKENO, stakes, glStakes); CStakeRecord record8(ZD_OUT::KEY_SOIL_ELEV, stakes, soilElev); CStakeRecord record9(ZD_OUT::KEY_NODE_GUID, stakes, guid); CStakeRecord record10(ZD_OUT::KEY_SH_EW_VOL, stakes, shEwVol); records.push_back(record0); records.push_back(record1); records.push_back(record2); records.push_back(record3); records.push_back(record4); records.push_back(record5); records.push_back(record6); records.push_back(record7); records.push_back(record8); records.push_back(record9); // 检查 "盾构体积" 是否有效,如有效,放入 for (size_t i = 0; i < shEwVol.size(); ++i) { double d = TypeConvert::s2f(shEwVol[i]); if (!EQUAL_ZERO(d)) { records.push_back(record10); break; } } return true; } void generateStakeInsertPoint(const AcDbObjectIdArray &arrIDs, CStakeRecord::StakeInsPts &stPts) { AecDbObjXDataMap xmap; CString strStake(_T("")), strType(_T("")); int fnType(0); AcGePoint3d ptS(AcGePoint3d::kOrigin) , ptE(AcGePoint3d::kOrigin) , ptIns(AcGePoint3d::kOrigin); int bCenterPt(0); AcDbExtents ext, extAll; CStakeRecord::StakeInsPts arCenPts; for (int i = 0; i < arrIDs.length(); ++i) { OPENOBJ_BEGIN(arrIDs[i], AcDb::kForRead, AcDbEntity, pEnt) if (!pEnt) continue; if (AcDbBlockReference::cast(pEnt)) continue; pEnt->getGeomExtents(ext); extAll.addExt(ext); if (!xmap.Read(pEnt, STAKE_SECTION)) continue; if (!xmap.GetAt(STAKE_SEGMENT, strStake)) continue; if (!xmap.GetAt(STAKE_TYPE, strType)) continue; if (!xmap.GetAt(STAKE_FNTYPE, fnType)) continue; // 直线上的起点和终点,哪一点的Y值小,取哪一点 AcDbPoint *pPt = AcDbPoint::cast(pEnt); if (pPt) { if (xmap.GetAt(_T("CenterPoint"), bCenterPt) && fnType == kProModel) { ptIns = pPt->position(); arCenPts.insert(std::make_pair(strStake, ptIns)); } else { ptIns = pPt->position(); stPts.insert(std::make_pair(strStake, ptIns)); } } xmap.Empty(); OPENOBJ_END() } for (CStakeRecord::StakeInsPts::iterator it = arCenPts.begin(); it != arCenPts.end(); ++it) { CString key(it->first); CStakeRecord::StakeInsPts::iterator _it = stPts.find(key); if (_it != stPts.end()) _it->second = it->second; } // 所有桩号的对应的点的Y值统一为最小值 for (CStakeRecord::StakeInsPts::iterator it = stPts.begin(); it != stPts.end(); ++it) (it->second).y = extAll.minPoint().y; } void generateMileStoneRecord(const AcDbObjectIdArray &arrIDs, CStakeRecord &rec) { rec.setRecType(CStakeRecord::eMilestoneRec); rec.setHeadString(ZD_OUT::KEY_MILESTONE); AecDbObjXDataMap xmap; std::set stakeSet; CString strStake(_T("")), strType(_T("")); int fnType(0); CStakeRecord::_Data_ data; for (int i = 0; i < arrIDs.length(); ++i) { OPENOBJ_BEGIN(arrIDs[i], AcDb::kForRead, AcDbEntity, pEnt) if (!pEnt) continue; if (!xmap.Read(pEnt, STAKE_SECTION)) continue; if (!xmap.GetAt(STAKE_SEGMENT, strStake)) continue; if (!xmap.GetAt(STAKE_TYPE, strType)) continue; if (!xmap.GetAt(STAKE_FNTYPE, fnType)) continue; if (fnType != kStackNode) continue; if (!stakeSet.insert(strStake).second) continue; data.stake = strStake; data.sData = strStake; rec.addData(data); xmap.Empty(); OPENOBJ_END() } } void analyFeatureString(LPCTSTR src, std::map> &features, std::vector &vfeatures) { std::vector v0(0); // <电力舱:xxx;xxx;xxx><燃气舱:xxx;xxx;xxx>... std::vector v1(0); // <电力舱> std::vector v2(0); // <电力舱> split(src, _T('|'), v0); if (v0.empty()) return; vfeatures.assign(v0.begin(), v0.end()); std::pair> pr; for (size_t i = 0; i < v0.size(); ++i) { pr.second.clear(); split(v0[i], _T(':'), v1); if (v1.size() != 2) continue; pr.first = v1[0]; split(v1[1], _T(';'), v2); for (size_t j = 0; j < v2.size(); ++j) { pr.second.push_back(v2[j]); } features.insert(pr); } } void generatekFeatureRecord(const AcDbObjectIdArray &arrIDs, CStakeRecord &rec) { rec.setRecType(CStakeRecord::eFeatureRec); rec.setHeadString(ZD_OUT::KEY_FEATURE); AecDbObjXDataMap xmap; std::vectorvecs(0); std::pair::iterator, bool> pr; CString strStake(_T("")), strType(_T("")); int fnType(0); CStakeRecord::_Data_ *pData(NULL), data; std::map> features; for (int i = 0; i < arrIDs.length(); ++i) { OPENOBJ_BEGIN(arrIDs[i], AcDb::kForRead, AcDbEntity, pEnt) if (!pEnt) continue; if (!xmap.Read(pEnt, STAKE_SECTION)) continue; if (!xmap.GetAt(STAKE_SEGMENT, strStake)) continue; if (!xmap.GetAt(STAKE_TYPE, strType)) continue; if (!xmap.GetAt(STAKE_FNTYPE, fnType)) continue; // 去掉变形缝 //if (fnType < kEspJoint || fnType > kProModel) continue; if (fnType < kEspJoint + 1 || fnType > kProModel) continue; data.clear(); if (fnType == kProModel) { features.clear(); vecs.clear(); analyFeatureString(strType, features, vecs); if (rec.findData(strStake, pData)) { for (size_t i = 0; i < vecs.size(); ++i) pData->features.insert(vecs[i]); } else { data.stake = strStake; for (size_t i = 0; i < vecs.size(); ++i) data.features.insert(vecs[i]); rec.addData(data); } } else { if (rec.findData(strStake, pData)) { pData->features.insert(strType); } else { data.stake = strStake; data.features.insert(strType); rec.addData(data); } } xmap.Empty(); OPENOBJ_END() } } // 得到存有所有实体的匿名块ID AcDbObjectId getBlockID(const AcDbObjectIdArray &arrIDs) { AcDbExtents ext; for (int i = 0; i < arrIDs.length(); ++i) { OPENOBJ_BEGIN(arrIDs[i], AcDb::kForRead, AcDbBlockReference, pEnt) if (!pEnt) continue; OPENOBJ_BEGIN(pEnt->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord, pRc) if (!pRc) continue; if (pRc->isAnonymous()) // 匿名块 return pEnt->objectId(); OPENOBJ_END() OPENOBJ_END() return AcDbObjectId::kNull; } return AcDbObjectId::kNull; } // 得到所有实体的外接矩形 void getExtent(AcDbObjectId &idBlk, AcGePoint3d &ptMin, AcGePoint3d &ptMax) { AcDbExtents ext; OPENOBJ_BEGIN(idBlk, AcDb::kForRead, AcDbBlockReference, pEnt) if (!pEnt) return; OPENOBJ_BEGIN(pEnt->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord, pRc) if (!pRc) return; if (pRc->isAnonymous()) // 匿名块 pEnt->getGeomExtents(ext); OPENOBJ_END() OPENOBJ_END() ptMin = ext.minPoint(); ptMax = ext.maxPoint(); } // 缩放节点 typedef std::multimap::iterator _IT; void scaleNodes(_IT it1, _IT it2, const double &scale) { AcGePoint3d pt(AcGePoint3d::kOrigin); AcDbExtents ext, extAll; for (_IT it = it1; it != it2; ++it) { AcDbObjectId &id = it->second; OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt) if (!pEnt) continue; pEnt->getGeomExtents(ext); extAll.addExt(ext); OPENOBJ_END() } pt = extAll.minPoint(); pt.x += (extAll.maxPoint().x - extAll.minPoint().x) * .5; AcGeMatrix3d mat; mat.setToScaling(scale, pt); for (_IT it = it1; it != it2; ++it) { AcDbObjectId &id = it->second; OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbEntity, pEnt) if (!pEnt) continue; pEnt->transformBy(mat); OPENOBJ_END() } } void scaleNodes(const AcDbObjectIdArray &arrIDs, const float &scale) { AcGeMatrix3d mat; mat.setToScaling(scale); int iType(0); CString strID(_T("")); AecDbObjXDataMap xmap; std::multimap idmaps; for (int i = 0; i < arrIDs.length(); ++i) { OPENOBJ_BEGIN(arrIDs[i], AcDb::kForRead, AcDbEntity, pEnt) if (!pEnt) continue; if (AcDbBlockReference::cast(pEnt)) continue; if (!xmap.Read(pEnt, STAKE_SECTION)) continue; if (!xmap.GetAt(STAKE_FNTYPE, iType)) continue; if (!xmap.GetAt(NODE_ID, strID)) continue; if (pEnt->colorIndex() <= 0 || pEnt->colorIndex() > 6) continue; if (iType == kPipeDoghouse || iType == kCableDoghouse || iType == kHeatDoghouse || iType == kVenDoghouse || iType == kEscapeHatch) { idmaps.insert(std::make_pair(strID, pEnt->objectId())); } xmap.Empty(); OPENOBJ_END() } _IT it(idmaps.begin()); std::pair<_IT, _IT> pr; while (it != idmaps.end()) { pr = idmaps.equal_range(it->first); scaleNodes(pr.first, pr.second, scale); it = pr.second; } } double getFrameScaleD(const AcDbObjectIdArray &arrIDs) { AcGeScale3d scale; CString str(_T("")); for (size_t i = 0; i < arrIDs.length(); ++i) { OPENOBJ_BEGIN(arrIDs[i], AcDb::kForRead, AcDbBlockReference, pEnt) if (!pEnt) continue; OPENOBJ_BEGIN(pEnt->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord, pRc) if (!pRc) continue; if (!pRc->isAnonymous()) // 非匿名块,即是图框块 { scale = pEnt->scaleFactors(); return scale.sx; } OPENOBJ_END() OPENOBJ_END() } return 1.; } CString getFrameScaleS(const AcDbObjectIdArray &arrIDs) { AcGeScale3d scale; CString str(_T("")); for (size_t i = 0; i < arrIDs.length(); ++i) { OPENOBJ_BEGIN(arrIDs[i], AcDb::kForRead, AcDbBlockReference, pEnt) if (!pEnt) continue; OPENOBJ_BEGIN(pEnt->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord, pRc) if (!pRc) continue; if (!pRc->isAnonymous()) // 非匿名块,即是图框块 { scale = pEnt->scaleFactors(); str.Format(_T("1:%d"), (int)(scale.sx * 1000)); return str; } OPENOBJ_END() OPENOBJ_END() } return _T("1:1"); } void collectEntityByXData(AcDbObjectId &recId, LPCTSTR pszSection, std::vector &ids) { if (!pszSection) return; // 遍历所有实体,判断其扩展数据为桩号的直线,将其保存 Acad::ErrorStatus es; AcDbEntity *pEnt(NULL); AcDbBlockTableRecordIterator *pIter(NULL); OPENOBJ_BEGIN(recId, AcDb::kForWrite, AcDbBlockTableRecord, pRec) if (!pRec) return; pRec->newIterator(pIter); if (!pIter) return; AecDbObjXDataMap xDataMap; CString stakeNo(_T("")); AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin); for (pIter->start(); !pIter->done(); pIter->step()) { es = pIter->getEntity(pEnt, AcDb::kForRead); if (!pEnt) continue; if (xDataMap.Read(pEnt, pszSection)) { ids.push_back(pEnt->objectId()); } pEnt->close(); } OPENOBJ_END() return; } AcGePoint3d getGeometryCenter(AcDbEntity *pEnt) { if (!pEnt) return AcGePoint3d::kOrigin; AcDbExtents ext; pEnt->getGeomExtents(ext); return AcGePoint3d((ext.maxPoint().x + ext.minPoint().x) * .5 ,(ext.maxPoint().y + ext.minPoint().y) * .5 , (ext.maxPoint().z + ext.minPoint().z) * .5); } CString getTraitString(LPCTSTR psz, const AcGePoint3d &pt) { if (!psz) return _T(""); CString str(psz); str += TypeConvert::f2s(pt.x); str += TypeConvert::f2s(pt.y); str += TypeConvert::f2s(pt.z); return str; } Acad::ErrorStatus transformBy(AcDbObjectId &id, AcGeMatrix3d mat) { OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbEntity, pEnt) if (pEnt) return pEnt->transformBy(mat); OPENOBJ_END() return Acad::eInvalidInput; } } ////////////////////////////////////////////////////////////////////////// #pragma region CStakeRecord float CStakeRecord::m_dataTextHeight; float CStakeRecord::m_dataTextFactor; CString CStakeRecord::m_dataTextStyle; float CStakeRecord::m_headTextHeight; float CStakeRecord::m_headTextFactor; CString CStakeRecord::m_headTextStyle; double CStakeRecord::m_dTxtSpace = 1; double CStakeRecord::m_dHeadTblTxtSpace = 1; CStakeRecord::CStakeRecord(LPCTSTR head , const std::vector &stakes , const std::vector &data) : m_sHead(head) , m_type(eStringRec) , m_datas(0) { if (stakes.size() != data.size()) return; _Data_ d; for (size_t i = 0; i < stakes.size(); ++i) { d.stake = stakes[i]; d.sData = data[i]; m_datas.push_back(d); } } CStakeRecord::CStakeRecord(LPCTSTR head , const std::vector &data) : m_sHead(head) , m_type(eGradRec) , m_datas(0) { _Data_ d1, d2; CString grade(_T("")), distance(_T("")), start(_T("")), end(_T("")); for (size_t i = 0; i < data.size(); ++i) { analyGradeAndDistance(data[i], grade, distance, start, end); d1.stake = start; d1.sData = grade; d2.stake = end; d2.sData = distance; m_datas.push_back(d1); m_datas.push_back(d2); } } double CStakeRecord::getHeadStringExtentX() { AcDbExtents ext; AcDbText *p = generateText_H(m_sHead, m_headTextHeight, m_headTextFactor, m_headTextStyle); if (p) { p->getGeomExtents(ext); DELETE_PTR(p); } return ext.maxPoint().x - ext.minPoint().x; } double CStakeRecord::getHeadStringExtentY() { AcDbExtents ext; AcDbText *p = generateText_H(m_sHead, m_headTextHeight, m_headTextFactor, m_headTextStyle); if (p) { p->getGeomExtents(ext); DELETE_PTR(p); } return ext.maxPoint().y - ext.minPoint().y; } double CStakeRecord::getMaxHeight() { AcDbText *p(NULL); AcDbExtents result; p = generateText_H(m_sHead, m_headTextHeight, m_headTextFactor, m_headTextStyle); if (p) { result = getTextExtent(p); DELETE_PTR(p); } if (m_type == eFeatureRec) { for (size_t i = 0; i < m_datas.size(); i++) { _Data_ &data = m_datas[i]; std::set::iterator it = data.features.begin(); for (; it != data.features.end(); ++it) { p = generateText_V(*it, m_dataTextHeight, m_dataTextFactor, m_dataTextStyle); if (p) { result.addExt(getTextExtent(p)); DELETE_PTR(p); } } } } else if (m_type != eGradRec) { for (size_t i = 0; i < m_datas.size(); i++) { _Data_ &data = m_datas[i]; p = generateText_V(data.sData, m_dataTextHeight, m_dataTextFactor, m_dataTextStyle); if (p) { result.addExt(getTextExtent(p)); DELETE_PTR(p); } } } return result.maxPoint().y - result.minPoint().y + m_dTxtSpace; } void CStakeRecord::calcInsertPointY(const double &up, double &rowMaxH) { double delta(.2); rowMaxH = getMaxHeight(); double down = up - rowMaxH; double dTxtY = down + rowMaxH * .5; for (size_t i = 0; i < m_datas.size(); ++i) m_datas[i].pt.y = dTxtY; m_ptHead.y = dTxtY; } double CStakeRecord::draw( AcDbObjectId &id , const double &preY , const double &headW , const double &dLeft , const double &dMid , const double &dRight , const AcGeMatrix3d mat ) { m_ptHead.x = dLeft - headW * .5; double rowMaxH; calcInsertPointY(preY, rowMaxH); AcDbText *pText = generateText_H(m_sHead, m_headTextHeight, m_headTextFactor, m_headTextStyle); pText->setAlignmentPoint(m_ptHead); g_LayerMgr::instance().setLayer(pText, GLTools::gLayer_ZD_TEXT_HEAD); AddToTableRecord(pText, id); // 共画8条线,四横四纵,包围 表头 和 数据 ////////////////////////////////////////////////////////////////////////// // 画数据长线 AcDbLine *pLine = new AcDbLine(AcGePoint3d(dLeft, preY, 0.), AcGePoint3d(dRight, preY, 0.)); g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_TABLE_LINE); AddToTableRecord(pLine, id); pLine = new AcDbLine(AcGePoint3d(dLeft, preY - rowMaxH, 0.), AcGePoint3d(dRight, preY - rowMaxH, 0.)); g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_TABLE_LINE); AddToTableRecord(pLine, id); // 两根数据短线 // pLine = new AcDbLine(AcGePoint3d(dMid, preY, 0.), AcGePoint3d(dMid, preY - rowMaxH, 0.)); // g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_TABLE_LINE); // AddToTableRecord(pLine, id); pLine = new AcDbLine(AcGePoint3d(dRight, preY, 0.), AcGePoint3d(dRight, preY - rowMaxH, 0.)); g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_TABLE_LINE); AddToTableRecord(pLine, id); ////////////////////////////////////////////////////////////////////////// // 再画2根短竖线 pLine = new AcDbLine(AcGePoint3d(dLeft, preY, 0.), AcGePoint3d(dLeft, preY - rowMaxH, 0.)); g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_TABLE_LINE); AddToTableRecord(pLine, id); pLine = new AcDbLine(AcGePoint3d(dLeft - headW, preY, 0.), AcGePoint3d(dLeft - headW, preY - rowMaxH, 0.)); g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_TABLE_LINE); AddToTableRecord(pLine, id); // 画2根短横线 pLine = new AcDbLine(AcGePoint3d(dLeft, preY - rowMaxH, 0.), AcGePoint3d(dLeft - headW, preY - rowMaxH, 0.)); g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_TABLE_LINE); AddToTableRecord(pLine, id); pLine = new AcDbLine(AcGePoint3d(dLeft, preY, 0.), AcGePoint3d(dLeft - headW, preY, 0.)); g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_TABLE_LINE); AddToTableRecord(pLine, id); ////////////////////////////////////////////////////////////////////////// if (m_type == eStringRec || m_type == eMilestoneRec) { // 绘制数据 for (size_t i = 0; i < m_datas.size(); ++i) { _Data_ &data = m_datas[i]; if (i != 0) { if (!InBox(data.pt, dRight, dMid)) continue; } pText = generateText_V(data.sData, m_dataTextHeight, m_dataTextFactor, m_dataTextStyle); pText->setAlignmentPoint(data.pt); g_LayerMgr::instance().setLayer(pText, GLTools::gLayer_ZD_TEXT_DATA); pText->transformBy(mat); AddToTableRecord(pText, id); } } else if (m_type == eFeatureRec) { double x(0); for (size_t i = 0; i < m_datas.size(); ++i) { _Data_ &data(m_datas[i]); if (!InBox(data.pt, dRight, dMid)) continue; if (data.features.empty()) continue; x = data.pt.x; std::set::iterator it = data.features.begin(); for (; it != data.features.end(); ++it) { pText = generateText_V(*it, m_dataTextHeight, m_dataTextFactor, m_dataTextStyle); pText->setAlignmentPoint(AcGePoint3d(x, data.pt.y, .0)); pText->transformBy(mat); g_LayerMgr::instance().setLayer(pText, GLTools::gLayer_ZD_TEXT_DATA); AddToTableRecord(pText, id); x += m_dataTextHeight; } } } else { // 绘制坡度 AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin), ptIns(AcGePoint3d::kOrigin); AcDbExtents ext; double w(.0), h(.0), delta(.1); for (size_t i = 0; i < m_datas.size(); ++i) { _Data_ &data = m_datas[i]; if (!InBox(data.pt, dRight, dMid)) continue; // 先画一条竖线 ptS.x = ptE.x = data.pt.x; ptS.y = preY; ptE.y = preY - rowMaxH; pLine = new AcDbLine(ptS, ptE); g_LayerMgr::instance().setLayer(pLine, GLTools::gLayer_ZD_TEXT_DATA); pLine->transformBy(mat); AddToTableRecord(pLine, id); pText = generateText_H(data.sData, m_dataTextHeight*.5f, m_dataTextFactor, m_dataTextStyle); ptIns = data.pt; pText->getGeomExtents(ext); w = ext.maxPoint().x - ext.minPoint().x; h = ext.maxPoint().y - ext.minPoint().y; w *= .5; h *= .5; w += delta; h += delta; if (data.sData.Find(_T("%")) != -1) { // 有 "%" 为坡度数据,插入点向右移整段宽度的一半 ptIns.x += w; ptIns.y += h; } else { // 无 "%" 为距离数据,插入点向左移整段宽度的一半 ptIns.x -= w; ptIns.y += h; } pText->setAlignmentPoint(ptIns); pText->transformBy(mat); g_LayerMgr::instance().setLayer(pText, GLTools::gLayer_ZD_TEXT_DATA); AddToTableRecord(pText, id); } } return preY - rowMaxH; } void CStakeRecord::init(const StakeInsPts &dataSet) { // 从 dataSet 内找出需要的点 for (size_t i = 0; i < m_datas.size(); ++i) { _Data_ &data = m_datas[i]; StakeInsPts::const_iterator it = dataSet.find(data.stake); // 文件中存在的数据,在图形中并没有实体对应 if (it == dataSet.end()) continue; data.pt = it->second; } } bool CStakeRecord::findData(const CString &stake, _Data_ *&data) { for (size_t i = 0; i < m_datas.size(); i++) { if (m_datas[i].stake.CompareNoCase(stake) == 0) { data = &m_datas[i]; return true; } } return false; } void CStakeRecord::setStaticValue(const double &dScale) { // 数据字高 m_dataTextHeight = TypeConvert::s2f(getConfiguration(ZD_OUT::KEY_DATA_H)) * dScale; // 数据宽度比例 m_dataTextFactor = TypeConvert::s2f(getConfiguration(ZD_OUT::KEY_DATA_W)); // 数据文字样式 m_dataTextStyle = getConfiguration(ZD_OUT::KEY_DATA_S); // 行头字高 m_headTextHeight = TypeConvert::s2f(getConfiguration(ZD_OUT::KEY_HEAD_H)) * dScale; // 行头宽度比例 m_headTextFactor = TypeConvert::s2f(getConfiguration(ZD_OUT::KEY_HEAD_W)); // 行头文字样式 m_headTextStyle = getConfiguration(ZD_OUT::KEY_HEAD_S); m_dTxtSpace *= dScale; m_dHeadTblTxtSpace *= dScale; } AcDbText* CStakeRecord::generateHeadText() { return generateText_H(m_sHead, m_headTextHeight, m_headTextFactor, m_headTextStyle); } AcDbText* CStakeRecord::generateText_V(LPCTSTR str, const float &dH, const float &dF, LPCTSTR style) { double dScale = getScale(_T("S2")); AcDbText *pText = new AcDbText(); pText->setHeight(dH * dScale); pText->setWidthFactor(dF); pText->setRotation(PI * .5); pText->setVerticalMode(AcDb::kTextVertMid); pText->setHorizontalMode(AcDb::kTextCenter); pText->setTextString(str); AcDbObjectId idTextStyle = GLTools::getTextStyle(style); if (!idTextStyle.isNull()) pText->setTextStyle(idTextStyle); return pText; } AcDbText* CStakeRecord::generateText_H(LPCTSTR str, const float &dH, const float &dF, LPCTSTR style) { double dScale = getScale(_T("S2")); AcDbText *pText = new AcDbText(); pText->setHeight(dH * dScale); pText->setWidthFactor(dF); pText->setHorizontalMode(AcDb::kTextMid); pText->setTextString(str); AcDbObjectId idTextStyle = GLTools::getTextStyle(style); if (!idTextStyle.isNull()) pText->setTextStyle(idTextStyle); return pText; } AcDbExtents CStakeRecord::getTextExtent(AcDbText *p) { AcDbExtents ext; if (p) p->getGeomExtents(ext); return ext; } #pragma endregion CStakeRecord namespace ZD_OUT { void getDataRecords(AcDbObjectIdArray &arrIDs , std::vector &records) { records.clear(); if (arrIDs.isEmpty()) return; CStakeRecord::setStaticValue(getFrameScaleD(arrIDs)); // 得到空间中存在的桩号的插入点 CStakeRecord::StakeInsPts stPts; generateStakeInsertPoint(arrIDs, stPts); if (stPts.empty()) { acutPrintf(_T("\n未能在图形中提取出桩号信息。")); return; } // 得到桩号所对应的数据,从文件中。 std::vector recs(0); if (!generateStakeRecordByFile(recs)) { acutPrintf(_T("\n未在本地找到桩号数据。")); return; } // 里程节点记录 CStakeRecord rec; generateMileStoneRecord(arrIDs, rec); recs.push_back(rec); // 特征节点记录 CStakeRecord rec1; generatekFeatureRecord(arrIDs, rec1); recs.push_back(rec1); // 初始化插入点 for (size_t i = 0; i < recs.size(); ++i) recs[i].init(stPts); // 按 rules顺序进行输出 for (size_t i = 0; i < g_config.size(); ++i) { std::vector::iterator it = std::find_if(recs.begin(), recs.end(), CStakeRecord::compare(g_config[i].first)); if (it != recs.end()) { if (g_config[i].second.CompareNoCase(_T("0")) != 0) records.push_back(*it); } } } void insertZDTable(AcDbObjectId &recId , AcDbObjectIdArray &arrIDs , std::vector &records , const AcGePoint3d &_ptMin , const AcGePoint3d &_ptMax , const bool &bEnd // 最后一次调用 ) { if (arrIDs.isEmpty()) return; if (!recId.isValid()) return; if (records.empty()) return; double dScaleH(getFrameScaleD(arrIDs)); readConfiguration(); // 网格设置参数 int i_wg_grid_interval(TypeConvert::s2i(getConfiguration(KEY_GRID_INTERVAL))); int i_wg_prec(TypeConvert::s2i(getConfiguration(KEY_GRID_PREC))); float f_wg_arrow_w(TypeConvert::s2f(getConfiguration(KEY_ARROW_W))); float f_wg_grid_h(TypeConvert::s2f(getConfiguration(KEY_GRID_H)) * dScaleH); CString s_wg_grid_s(getConfiguration(KEY_GRID_S)); float f_wg_grid_w(TypeConvert::s2f(getConfiguration(KEY_GRID_W))); float f_wg_ratio_h(TypeConvert::s2f(getConfiguration(KEY_RATIO_H)) * dScaleH); CString s_wg_ratio_s(getConfiguration(KEY_RATIO_S)); float f_wg_ratio_w(TypeConvert::s2f(getConfiguration(KEY_RATIO_W))); // 引出标注设置参数 float f_ycbz_h(TypeConvert::s2f(getConfiguration(KEY_YCBZ_H))); CString f_ycbz_s(getConfiguration(KEY_YCBZ_S)); // 节点设置参数 float f_jd_scale(TypeConvert::s2f(getConfiguration(KEY_NODE_SCALE))); ////////////////////////////////////////////////////////////////////////// // 下面代码绘制网格标尺 // 先取出三个特征点,三个特征点用来计算真实高程 std::map ptMap; getMarkPoints(arrIDs, ptMap); if (ptMap.size() != 3) return; std::map::iterator it(ptMap.begin()); AcGePoint3d ptDown(it->first); double dDown(it->second); ++it; AcGePoint3d ptUp(it->first); double dUp(it->second); ++it; AcGePoint3d ptRoad(it->first); double dRoad(it->second); //drawCircle(recId, ptUp, 5); //drawCircle(recId, ptDown, 5); // 得到所有实体的范围 AcDbObjectId idBlk = getBlockID(arrIDs); // 所有实体都在此块中 AcGePoint3d ptMin(AcGePoint3d::kOrigin), ptMax(AcGePoint3d::kOrigin); getExtent(idBlk, ptMin, ptMax); AcGePoint3d ptMinBk(ptMin), ptMaxBk(ptMax); //drawCircle(recId, ptMin, 1); //drawCircle(recId, ptMax, 1); // factor 为 现实高程差与图纸坐标Y值差的比 double factorY = (dUp - dDown) / (ptUp.y - ptDown.y); double factorX = dScaleH; double deltaY = 1 / factorY; double deltaX = deltaY; ////////////////////////////////////////////////////////////////////////// // 下面输出计算数据 AcDbExtents extHead; double dHeadW(.0), dHeadDelta(.0), dTblH(.0); for (size_t i = 0; i < records.size(); ++i) { CStakeRecord &rec = records[i]; AcDbText *pText = rec.generateHeadText(); if (!pText) continue; AcDbExtents ext; pText->getGeomExtents(ext); extHead.addExt(ext); DELETE_PTR(pText); dTblH += records[i].getMaxHeight(); } dHeadDelta = extHead.maxPoint().x - extHead.minPoint().x; dHeadW = dHeadDelta + CStakeRecord::m_dTxtSpace; // 根据 dHeadW 重新计算 dLeft AcGePoint3d ptInsMin(AcGePoint3d::kOrigin); double dLeft, dMid, dRight; ptInsMin.x = _ptMin.x - g_rule_grid_space; // 把 ptInsMin.y 算一下,用最小的Y值加表格高度,再加一个间隙 ptInsMin.y = _ptMin.y + dTblH + 1; // dMinDown 为标尺左下角高程 double dMinDown = dDown - factorY * (ptDown.y - ptInsMin.y); // iDown 为取整后的dMinDown int iDown(0); if (dMinDown - (int)(dMinDown) < 1e-6) iDown = (int)(dMinDown); else iDown = (int)(dMinDown) + 1; // 根据 iDown 算出坐标 ptInsMin.y = ptDown.y - (dDown - iDown) / factorY; drawGrid(recId , ptInsMin , iDown , i_wg_grid_interval , deltaY , deltaX , _ptMax.y - ptInsMin.y + deltaY , _ptMax.x - ptInsMin.x + deltaY , i_wg_prec , f_wg_grid_h , f_wg_grid_w , s_wg_grid_s , dLeft , dMid , dRight , dDown); // 将存有实体的块移动到网格处 AcGeVector3d vtMove(AcGeVector3d::kXAxis); vtMove *= dMid - ptMinBk.x; g_content_blk_mat.setToIdentity(); g_content_blk_mat.setTranslation(vtMove); if (bEnd) transformBy(idBlk, g_content_blk_mat); double preY(_ptMin.y + dTblH); for (size_t i = 0; i < records.size(); ++i) preY = records[i].draw(recId, preY, dHeadW, dLeft, dMid, dRight, g_content_blk_mat); // 缩放节点 scaleNodes(arrIDs, f_jd_scale); // 绘制比例尺 double dHLength(.0), dVLength(.0); CString strV(getScaleS2()); CString strH = getFrameScaleS(arrIDs); AcGePoint3d ptRule(dLeft - dHeadW, dDown, 0); drawScaleRule(recId, ptRule, strH, strV, f_wg_arrow_w, f_wg_ratio_h, f_wg_ratio_w, s_wg_ratio_s); if (bEnd) { g_prRang.first = _ptMin.x; g_prRang.second = _ptMax.x; } } bool readConfiguration() { return ::readConfiguration(); } CString getConfiguration(LPCTSTR key) { return ::getConfiguration(key); } void getConfiguration(std::vector> &v) { v.assign(g_config.begin(), g_config.end()); } void insertDimension(AcDbObjectId &recId) { std::vector ids; collectEntityByXData(recId, STAKE_SECTION, ids); if (ids.empty()) return; CString strType(_T("")), strID(_T("")), strTextStyle(getConfiguration(KEY_YCBZ_S)); if (strTextStyle.IsEmpty()) strTextStyle = _T("standard"); float textH(TypeConvert::s2f(getConfiguration(KEY_YCBZ_H))); int nDimByStake(TypeConvert::s2i(getConfiguration(KEY_NODE_DIMTYPE))); AcGePoint3d ptIns(AcGePoint3d::kOrigin), pt2(AcGePoint3d::kOrigin); std::set strSet1; std::pair::iterator, bool> pr; AcDbEntity *pDim(NULL); AcGePoint3d ptMax(AcGePoint3d::kOrigin), ptMin(AcGePoint3d::kOrigin); EWNodeDimInfos nds; catalogNodeType(ids, nds); int nCharLen(0); std::multiset mmapStrs; typedef std::multiset::iterator mmapIt; std::pair _pr; size_t dif(0); std::wstringstream ss; std::vector vnds(0); for (EWNodeDimInfos::iterator it = nds.begin(); it != nds.end(); ++it) { vnds.push_back(it->second); } std::sort(vnds.begin(), vnds.end(), EWNodeDimInfo::_com_by_x()); // first 管廊长度,second.first 管廊起始桩号,second.second 管廊结束桩号 std::map guids; if (TypeConvert::s2i(getConfiguration(KEY_NODE_DIMTYPE)) != 1) { std::vector recs(0); if (!generateStakeRecordByFile(recs)) { acutPrintf(_T("\n未在本地找到桩号数据。")); return; } if (recs.size() < 9) return; CStakeRecord recDist(recs[7]); CStakeRecord recGuid(recs[9]); if (recDist.m_datas.size() == recGuid.m_datas.size()) { double d; for (size_t i = 0; i < recDist.m_datas.size() - 1; i++) { StakeTools::analyStakeString(recDist.m_datas[i].sData, d); guids.insert(std::make_pair(recGuid.m_datas[i].sData, d)); } } } CString strDim(_T("")); double dStake(.0); for (std::vector::iterator it = vnds.begin(); it != vnds.end(); ++it) { ss.str(_T("")); mmapStrs.insert(it->strType); _pr = std::equal_range(mmapStrs.begin(), mmapStrs.end(), it->strType); dif = std::distance(_pr.first, _pr.second); ss << dif; ptMax = it->ext.maxPoint(); ptMin = it->ext.minPoint(); ptIns.x = (ptMax.x + ptMin.x) * .5; ptIns.y = (ptMax.y + ptMin.y) * .5; pr = strSet1.insert(getTraitString(it->strType, ptIns)); if (!pr.second) continue; pt2 = ptIns; pt2.y += (ptMax.y - ptMin.y) * .5 + 1; if (it->fnType == kFirwWall) pt2.y += 5; nCharLen = it->strType.GetLength(); // 在这里判断是否需要根据距离来标注节点 strDim = it->strStake; if (TypeConvert::s2i(getConfiguration(KEY_NODE_DIMTYPE)) != 1) { std::map::iterator mIt(guids.end()); mIt = guids.find(it->strID); if (mIt != guids.end()) strDim = StakeTools::generateStakeString(mIt->second, _T("L")); } //pDim = MK_DIM::makeSymbNode(ptIns #ifndef ZWCAD pDim = DimFactory(FilePath::GetArxDir() + _T("//dimension.arx")).makeSymbNode(ptIns #else pDim = DimFactory(FilePath::GetArxDir() + _T("//dimension.zrx")).makeSymbNode(ptIns #endif , pt2 , nCharLen * .7 , strDim + _T(":") + it->strName + _T(" ") + it->strType + ss.str().c_str() , strTextStyle , textH //, MK_DIM::eNoneArrow , DimFactory::eNoneArrow , 3. //, MK_DIM::eBeginAlign); , DimFactory::eBeginAlign); if (!pDim) continue; if (ptIns.x > g_prRang.first) pDim->transformBy(g_content_blk_mat); g_LayerMgr::instance().setLayer(pDim, GLTools::gLayer_ZD_DIM); AddToTableRecord(pDim, recId); } // 在这里删除所有多余点 for (size_t i = 0; i < ids.size(); ++i) { AcDbObjectId &id = ids[i]; OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbEntity, pEnt) if (pEnt) pEnt->erase(); OPENOBJ_END() } } // 网格最左侧(不算标尺)与表格最左侧的距离(+1) double getGridLeftPointDist() { std::vector recs(0); CStakeRecord rec; rec.setHeadString(ZD_OUT::KEY_STAKENO); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_SOIL); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_TOP_ELEV); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_CURRENT_GROUND_ELEV); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_DESIGN_GROUND_ELEV); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_GRADE_DISTANCE); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_GRADE); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_DISTANCE); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_FEATURE); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_MILESTONE); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_BOTTOM_INNER_ELEV); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_GL_STAKENO); recs.push_back(rec); rec.setHeadString(ZD_OUT::KEY_SOIL_ELEV); recs.push_back(rec); std::vector records(0); for (size_t i = 0; i < g_config.size(); ++i) { std::vector::iterator it = std::find_if(recs.begin(), recs.end(), CStakeRecord::compare(g_config[i].first)); if (it != recs.end()) { if (g_config[i].second.CompareNoCase(_T("0")) != 0) records.push_back(*it); } } AcDbExtents extHead; double dHeadW(.0), dHeadDelta(.0); for (size_t i = 0; i < records.size(); ++i) { CStakeRecord &rec = records[i]; AcDbText *pText = rec.generateHeadText(); if (!pText) continue; AcDbExtents ext; pText->getGeomExtents(ext); extHead.addExt(ext); DELETE_PTR(pText); } dHeadDelta = extHead.maxPoint().x - extHead.minPoint().x; dHeadW = dHeadDelta + CStakeRecord::m_dTxtSpace + g_rule_grid_space + CStakeRecord::m_dHeadTblTxtSpace; return dHeadW; } }