2038 lines
55 KiB
C++
2038 lines
55 KiB
C++
#include "StdAfx.h"
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
#include <iterator>
|
|
#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<double, double> 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<CString, EWNodeDimInfo> EWNodeDimInfos;
|
|
void catalogNodeType(const std::vector<AcDbObjectId> &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<std::pair<CString, CString>> 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<CString> &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<CString> vec(0);
|
|
std::pair<CString, CString> pr;
|
|
std::vector<std::pair<CString, CString>> _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<std::pair<CString, CString>>::iterator it_temp = _temp.begin()
|
|
, it_config = g_config.begin();
|
|
|
|
std::advance(it_temp, countOfHead);
|
|
std::advance(it_config, countOfHead);
|
|
|
|
// 将 g_config 尾部备份
|
|
std::vector<std::pair<CString, CString>> 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<std::pair<CString, CString>>::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<AcDbBlockTableRecord>(paperID)) return;
|
|
if (arIDs.isEmpty()) return;
|
|
|
|
// 读出纵断比例
|
|
CString str(getScaleS2());
|
|
std::vector<CString> 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<AcGePoint3d> 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<AcGePoint3d, double, _compare_pt_y> &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<CStakeRecord> &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<CString> 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<CString> 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<CString> 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<CString, std::vector<CString>> &features, std::vector<CString> &vfeatures)
|
|
{
|
|
std::vector<CString> v0(0); // <电力舱:xxx;xxx;xxx><燃气舱:xxx;xxx;xxx>...
|
|
std::vector<CString> v1(0); // <电力舱><xxx;xxx;xxx>
|
|
std::vector<CString> v2(0); // <电力舱><xxx;xxx;xxx>
|
|
split(src, _T('|'), v0);
|
|
if (v0.empty()) return;
|
|
vfeatures.assign(v0.begin(), v0.end());
|
|
std::pair<CString, std::vector<CString>> 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::vector<CString>vecs(0);
|
|
std::pair<std::set<CString>::iterator, bool> pr;
|
|
CString strStake(_T("")), strType(_T(""));
|
|
int fnType(0);
|
|
CStakeRecord::_Data_ *pData(NULL), data;
|
|
std::map<CString, std::vector<CString>> 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<CString, AcDbObjectId>::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<CString, AcDbObjectId> 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<AcDbObjectId> &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<CString> &stakes
|
|
, const std::vector<CString> &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<CString> &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<CString>::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<CString>::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<CStakeRecord> &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<CStakeRecord> 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<CStakeRecord>::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<CStakeRecord> &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<AcGePoint3d, double, _compare_pt_y> ptMap;
|
|
getMarkPoints(arrIDs, ptMap);
|
|
if (ptMap.size() != 3) return;
|
|
|
|
std::map<AcGePoint3d, double, _compare_pt_y>::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<std::pair<CString, CString>> &v)
|
|
{
|
|
v.assign(g_config.begin(), g_config.end());
|
|
}
|
|
|
|
void insertDimension(AcDbObjectId &recId)
|
|
{
|
|
std::vector<AcDbObjectId> 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<CString> strSet1;
|
|
std::pair<std::set<CString>::iterator, bool> pr;
|
|
AcDbEntity *pDim(NULL);
|
|
|
|
AcGePoint3d ptMax(AcGePoint3d::kOrigin), ptMin(AcGePoint3d::kOrigin);
|
|
EWNodeDimInfos nds;
|
|
catalogNodeType(ids, nds);
|
|
int nCharLen(0);
|
|
|
|
std::multiset<CString> mmapStrs;
|
|
typedef std::multiset<CString>::iterator mmapIt;
|
|
std::pair<mmapIt, mmapIt> _pr;
|
|
size_t dif(0);
|
|
std::wstringstream ss;
|
|
|
|
std::vector<EWNodeDimInfo> 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<CString, double> guids;
|
|
if (TypeConvert::s2i(getConfiguration(KEY_NODE_DIMTYPE)) != 1)
|
|
{
|
|
std::vector<CStakeRecord> 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<EWNodeDimInfo>::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<CString, double>::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<CStakeRecord> 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<CStakeRecord> records(0);
|
|
for (size_t i = 0; i < g_config.size(); ++i)
|
|
{
|
|
std::vector<CStakeRecord>::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;
|
|
}
|
|
}
|
|
|