Files
envi-code/SourceCode/Code2026/tg_shs/shs_siteplan/RoadFillterMgr.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

555 lines
16 KiB
C++

#include "stdafx.h"
#include "RoadDataCenterNew.h"
#include "RoadFillterMgr.h"
CRoadFillterMgr::CRoadFillterMgr(void)
{
}
CRoadFillterMgr::~CRoadFillterMgr(void)
{
ReleaseMem();
}
CString CRoadFillterMgr::PromptRadiusString(double dRadiusSys)
{
CString sRadius;
if (g_bMeterUnitDraw)
{
sRadius.Format(_T("%.3f"), dRadiusSys);
}
else
{
sRadius.Format(_T("%d"), (int)dRadiusSys);
}
return sRadius;
}
CString CRoadFillterMgr::PromptSelectString(BOOL bSameCenter, double dRadiusMM)
{
//请框选要倒角的道路线或[同半径倒角(Q),当前:同圆心/倒角半径(R),当前:5000]<退出>:
double dRadiusSys = _AS_SYS_UNIT(dRadiusMM);
CString sRadius = PromptRadiusString(dRadiusSys);
CString sPrompt;
if (bSameCenter)
{
sPrompt.Format(_T("\n请框选要倒角的道路线或[同半径倒角(Q),当前:同圆心/倒角半径(R),当前:%s]<退出>:"), sRadius);
}
else
{
sPrompt.Format(_T("\n请框选要倒角的道路线或[同圆心倒角(Q),当前:同半径/倒角半径(R),当前:%s]<退出>:"), sRadius);
}
return sPrompt;
}
#define AddRoadData(id, arEnt, arEntAdatper, TCAdEntType, TCADEntAdapterType)\
{\
TCAdEntType *_pEnt = new TCAdEntType(id);\
arEnt.append(_pEnt);\
arEntAdatper.append(new TCADEntAdapterType(_pEnt));\
}
// do Select,get data from CAD,把他们处理出适配器类型
BOOL CRoadFillterMgr::SelectRoad()
{
static double dRadiusMM = 5000.0;
static BOOL bSameCenter = TRUE;
CString sKeyFilType = _T("Q");
CString sKeyFilRadius = _T("R");
CString sKeyAll = _T("Q R");
CString strRoadLay = LAY_ROAD;
CString strMidRoadLay = LAY_ROADDOTE;
do
{
g_ssPickFirst.Free();
TCHAR chRet;
TPickEntSet ssRes(SS_FREE);
// TRBList rbList(RTDXF0, _T("LINE,ARC"), 8, _T("ROAD,ROAD_DOTE"), NULL);
TRBList rbList(RTDXF0, _T("LINE,ARC"), 8, XString(_T("%s,%s"), LAY_ROAD, LAY_ROADDOTE), NULL);
int nRet = SelectEntitiesOnce(PromptSelectString(bSameCenter, dRadiusMM), ssRes, rbList, (LPCTSTR)sKeyAll, chRet);
switch (nRet)
{
case RTNORM:
{
for(long i=0; i < ssRes.Length(); i++)
{
Entity ent=ssRes[i];
OPENOBJ_BEGIN(ent, AcDb::kForWrite,AcDbEntity,pEnt);
TCHAR* lay = pEnt->layer();
if (strRoadLay.CompareNoCase(pEnt->layer()) == 0)
{ // 道路图层,
if (pEnt->isKindOf(AcDbLine::desc()))
{ // line型
pEnt->close();
AddRoadData(pEnt->id(), m_arEdgeLine, m_arEdgeLineAdapter, CLineCADEnt, CLineCADEntFilRoadAdapter);
}
else if (pEnt->isKindOf(AcDbArc::desc()))
{// arc型
pEnt->close();
AddRoadData(pEnt->id(), m_arEdgeArc, m_arEdgeArcAdapter, CArcCADEnt, CArcCADEntFilRoadAdapter);
}
}
else if (strMidRoadLay.CompareNoCase(pEnt->layer()) == 0)
{ // 中线图层
if (pEnt->isKindOf(AcDbLine::desc()))
{
pEnt->close();
AddRoadData(pEnt->id(), m_arMidLine, m_arMidLineAdapter, CLineCADEnt, CLineCADEntFilRoadAdapter);
}
else if (pEnt->isKindOf(AcDbArc::desc()))
{
pEnt->close();
AddRoadData(pEnt->id(), m_arMidArc, m_arMidArcAdapter, CArcCADEnt, CArcCADEntFilRoadAdapter);
}
}
OPENOBJ_END();
}
m_dRadius = dRadiusMM;
m_bSameCenter = bSameCenter;
return TRUE;
}
break;
case RTKWORD:
if (sKeyFilType.CompareNoCase(CString(chRet)) == 0)
{ // 切换选择模式
bSameCenter = !bSameCenter;
}
else if (sKeyFilRadius.CompareNoCase(CString(chRet)) == 0)
{
ads_real dreal;
CString sPrompt;
sPrompt.Format(_T("\n请输入倒角半径 <%s>: "), PromptRadiusString(_AS_SYS_UNIT(dRadiusMM)));
int nrealGet = ads_getreal(sPrompt, &dreal);
if (nrealGet == RTNORM)
{
dRadiusMM = _AS_MM(dreal);
}
else
{
if (nrealGet != RTNONE)
return FALSE;
}
}
else // 其他关键字,不可能。
{
return FALSE;
} //ASSERT(0);
m_dRadius = dRadiusMM;
m_bSameCenter = bSameCenter;
break;
default:
return FALSE;
break;
}
} while (true);
return FALSE;
}
void CRoadFillterMgr::MakeFilroadConnect (ArLineFilroadAdapterPointer &arLineAdatper,
ArArcFilroadAdapterPointer &arArcAdapter,
ArFilroadConnectPointer &arConnect)
{
int i = 0, j = 0, iArLen1 = 0, iArLen2 = 0;
ArFilroadConnectPointer arConnectDump;
// 遍历直线Adapter
for (i = 0, iArLen1 = (int)arLineAdatper.length(); i < iArLen1; i++)
{
if (arLineAdatper[i]->IsLinkOver())
continue;
// 直线Adapter自身遍历
for (j = i + 1; j < iArLen1; j++)
{
if (arLineAdatper[j]->IsLinkOver())
continue;
if (CFilroadConnect::CreateConnect(arLineAdatper[i], arLineAdatper[j], arConnectDump))
arConnect.append(arConnectDump);
}
// 遍历ArcAdapter
for (j = 0, iArLen2 = (int)arArcAdapter.length(); j < iArLen2; j++)
{
if (arArcAdapter[j]->IsLinkOver())
continue;
if (CFilroadConnect::CreateConnect(arLineAdatper[i], arArcAdapter[j], arConnectDump))
arConnect.append(arConnectDump);
}
}
// ArcAdapter自身遍历
for (i = 0, iArLen1 = (int)arArcAdapter.length(); i < iArLen1; i++)
{
if (arArcAdapter[i]->IsLinkOver())
continue;
for (j = i + 1; j < iArLen1; j++)
{
if (arArcAdapter[j]->IsLinkOver())
continue;
if(CFilroadConnect::CreateConnect(arArcAdapter[i], arArcAdapter[j], arConnectDump))
arConnect.append(arConnectDump);
}
}
}
void CRoadFillterMgr::IdentifyOldFilterConnect(ArLineFilroadAdapterPointer &arLineAdatper,
ArArcFilroadAdapterPointer &arArcAdapter,
ArFilroadConnectPointer &arConnect)
{
// 遍历圆弧,查找两端都有相切连接的,把这三段设置为连接标记
int i = 0, j = 0, iArLen1 = 0, iArLen2 = 0;
ArFilroadConnectPointer arConnectDump;
// 遍历圆弧,查找两段都具有相切连接关系的情形
for (i = 0, iArLen1 = (int)arArcAdapter.length(); i < iArLen1; i++)
{
if (arArcAdapter[i]->IsLinkOver())
continue;
// 跟圆弧相切的边线是起点重合,还是终点重合..
bool bStartLink1 = true, bStartLink2 = true;
// 1跟圆弧起点相连,2跟圆弧终点相连
CCADEntFilRoadAdatper *pAdapter1 = NULL, *pAdapter2 = NULL;
AcGePoint2d ptStart = arArcAdapter[i]->CurrSeg().startPoint();
AcGePoint2d ptEnd = arArcAdapter[i]->CurrSeg().endPoint();
AcGePoint2d ptCen = arArcAdapter[i]->CurrSeg().center();
AcGeVector2d vecStart = ptCen - ptStart;
AcGeVector2d vecEnd = ptCen - ptEnd;
double dVecStartLen = vecStart.length();
double dVecEndLen = vecEnd.length();
const double dTol = 1e-6; // 使用内积来判断垂直的时候,一定要考虑向量的模。这样才具有意义
// 遍历arLineAdapter;
for (j = 0; j < (int)arLineAdatper.length(); j++)
{
if (arLineAdatper[j]->IsLinkOver())
continue;
double dTempLen = arLineAdatper[j]->CurrSeg().length();
if (pAdapter1 == NULL)
{
if (ptStart.isEqualTo(arLineAdatper[j]->CurrSeg().startPoint()) &&
vecStart.dotProduct(arLineAdatper[j]->CurrSeg().direction()) < dTol * dVecStartLen * dTempLen)
{ // 点重合,并且在该点是相切的
pAdapter1 = arLineAdatper[j];
bStartLink1 = true; // 起点重合
}
else if (ptStart.isEqualTo(arLineAdatper[j]->CurrSeg().endPoint()) &&
vecStart.dotProduct(arLineAdatper[j]->CurrSeg().direction()) < dTol * dVecStartLen * dTempLen)
{
pAdapter1 = arLineAdatper[j];
bStartLink1 = false; // 终点重合
}
}
if (pAdapter2 == NULL)
{
if (ptEnd.isEqualTo(arLineAdatper[j]->CurrSeg().startPoint()) &&
vecEnd.dotProduct(arLineAdatper[j]->CurrSeg().direction()) < dTol * dVecEndLen * dTempLen)
{
pAdapter2 = arLineAdatper[j];
bStartLink2 = true;
}
else if (ptEnd.isEqualTo(arLineAdatper[j]->CurrSeg().endPoint()) &&
vecEnd.dotProduct(arLineAdatper[j]->CurrSeg().direction()) < dTol * dVecEndLen * dTempLen)
{
pAdapter2 = arLineAdatper[j];
bStartLink2 = false; // 终点重合
}
}
if (pAdapter1 != NULL &&pAdapter2 != NULL)
break;
}
// 遍历ArcAdapter
AcGeVector2d vecStartPlumb(vecStart.y, -vecStart.x);
AcGeVector2d vecEndPlumb(vecEnd.y, -vecEnd.x);
for (j = 0, iArLen2 = (int)arArcAdapter.length(); j < iArLen2; j++)
{
if (pAdapter1 != NULL &&pAdapter2 != NULL)
break;
if (arArcAdapter[j]->IsLinkOver() || (j == i))
continue;
AcGeVector2d vecThisStart = arArcAdapter[j]->CurrSeg().center() - arArcAdapter[j]->CurrSeg().startPoint();
AcGeVector2d vecThisEnd = arArcAdapter[j]->CurrSeg().center() - arArcAdapter[j]->CurrSeg().endPoint();
double dVecThisStartLen = vecThisEnd.length();
double dVecThisEndLen = vecThisEnd.length();
if (pAdapter1 == NULL)
{
if (ptStart.isEqualTo(arArcAdapter[j]->CurrSeg().startPoint()) &&
vecStartPlumb.dotProduct(vecThisStart) < dTol * dVecStartLen * dVecThisStartLen)
{ // 点重合,并且在该点是相切的
pAdapter1 = arArcAdapter[j];
bStartLink1 = true; // 起点重合
}
else if (ptStart.isEqualTo(arArcAdapter[j]->CurrSeg().endPoint()) &&
vecStartPlumb.dotProduct(vecThisEnd) < dTol * dVecStartLen * dVecThisEndLen)
{
pAdapter1 = arArcAdapter[j];
bStartLink1 = false; // 终点重合
}
}
if (pAdapter2 == NULL)
{
if (ptEnd.isEqualTo(arArcAdapter[j]->CurrSeg().startPoint()) &&
vecEndPlumb.dotProduct(vecThisStart) < dTol * dVecEndLen * dVecThisStartLen)
{
pAdapter2 = arArcAdapter[j];
bStartLink2 = true;
}
else if (ptEnd.isEqualTo(arArcAdapter[j]->CurrSeg().endPoint()) &&
vecEndPlumb.dotProduct(vecThisEnd) < dTol * dVecEndLen * dVecThisEndLen)
{
pAdapter2 = arArcAdapter[j];
bStartLink2 = false; // 终点重合
}
}
if (pAdapter1 != NULL &&pAdapter2 != NULL)
break;
}
if (pAdapter1 != NULL && pAdapter2 != NULL)
{ // 找到了这么两个东西,建立这两个的链接关系
arArcAdapter[i]->SetStartLink();
arArcAdapter[i]->SetEndLink();
// 创建链接
CFilroadConnect *pConnect = NULL;
if (pAdapter1->ToLineAdapter() != NULL && pAdapter2->ToLineAdapter() != NULL)
{
if (CFilroadConnect::CreateConnectFilted(pAdapter1->ToLineAdapter(), bStartLink1,
pAdapter2->ToLineAdapter(), bStartLink2, pConnect, arArcAdapter[i]))
arConnect.append(pConnect);
}
else if (pAdapter1->ToLineAdapter() != NULL && pAdapter2->ToArcAdapter() != NULL)
{
if (CFilroadConnect::CreateConnectFilted(pAdapter1->ToLineAdapter(), bStartLink1,
pAdapter2->ToArcAdapter(), bStartLink2, pConnect, arArcAdapter[i]))
arConnect.append(pConnect);
}
else if (pAdapter1->ToArcAdapter() != NULL && pAdapter2->ToLineAdapter() != NULL)
{
if (CFilroadConnect::CreateConnectFilted(pAdapter2->ToLineAdapter(), bStartLink2,
pAdapter1->ToArcAdapter(), bStartLink1, pConnect, arArcAdapter[i]))
arConnect.append(pConnect);
}
else if (pAdapter1->ToArcAdapter() != NULL && pAdapter2->ToArcAdapter() != NULL)
{
if (CFilroadConnect::CreateConnectFilted(pAdapter1->ToArcAdapter(), bStartLink1,
pAdapter2->ToArcAdapter(), bStartLink2, pConnect, arArcAdapter[i]))
arConnect.append(pConnect);
}
}
}
}
// 检测道路的链接关系。
void CRoadFillterMgr::MakeFilroadConnect()
{
CFilroadConnect::SetInterTol();
// 先识别已经倒角的道路边线,两两成对
IdentifyOldFilterConnect(m_arEdgeLineAdapter, m_arEdgeArcAdapter, m_arFilroadEdgeConnect);
IdentifyOldFilterConnect(m_arMidLineAdapter, m_arMidArcAdapter, m_arFilroadMidConnect);
// 在识别普通的道路边线,两两成对
MakeFilroadConnect(m_arEdgeLineAdapter, m_arEdgeArcAdapter, m_arFilroadEdgeConnect);
MakeFilroadConnect(m_arMidLineAdapter, m_arMidArcAdapter, m_arFilroadMidConnect);
}
// 根据距离检测分组。
void CRoadFillterMgr::GroupConnect()
{
ASSERT(m_bSameCenter);
CFilroadConnectGroup::SetSameCenterLimit(SameCenterTol());
// 只选了两组连接线,则直接分为一组(分组仅仅考虑了距离)
if (m_arFilroadEdgeConnect.length() == 2)
{
CFilroadConnectGroup *pGroup = new CFilroadConnectGroup();
pGroup->AddConnect(m_arFilroadEdgeConnect[0]);
pGroup->AddConnect(m_arFilroadEdgeConnect[1]);
m_arFilroadGroup.append(pGroup);
}
else
{
// 选择了多个线段,则匹配分组
int i = 0, j = 0;
for (i = (int)m_arFilroadEdgeConnect.length() - 1; i > -1; i--)
{
CFilroadConnect *pConnect = m_arFilroadEdgeConnect[i];
CFilroadConnectGroup *pGroup = NULL;
for ( j = (int)m_arFilroadGroup.length() - 1; j > -1; j--)
{
if (m_arFilroadGroup[j]->CheckAConnect(pConnect))
{
if (pGroup != NULL)
{
pGroup->AddGroup(*(m_arFilroadGroup[j]));
m_arFilroadGroup.removeAt(j);
}
else
{
pGroup = m_arFilroadGroup[j];
}
pGroup->AddConnect(pConnect);
}
}
if (pGroup == NULL)
m_arFilroadGroup.append(new CFilroadConnectGroup(pConnect, FALSE));
}
}
// 处理中线:
for (int i = (int)m_arFilroadMidConnect.length() - 1; i > -1; i--)
{
CFilroadConnect *pConnectMid = m_arFilroadMidConnect[i];
for (int j = (int)m_arFilroadGroup.length() - 1; j > -1; j--)
{
// 当然,只有道路拐角处的中线才会被添加进来。
if (m_arFilroadGroup[j]->CheckInsideMidConnect(pConnectMid))
{
m_arFilroadGroup[j]->AddMidConnect(pConnectMid);
break;
}
}
if (j == -1)
m_arFilroadGroupMid.append(new CFilroadConnectGroup(pConnectMid, TRUE));
}
}
BOOL CRoadFillterMgr::FilltRoad()
{
BOOL bRet = TRUE;
if (m_bSameCenter)
{ // 同圆心
AcAryCircArc2d arEdgeArcDump, arMidArcDump; //
ArFilroadGroupPointer arGroupDump;
arGroupDump.append(m_arFilroadGroupMid);
arGroupDump.append(m_arFilroadGroup);
for (int i = 0; i < (int)arGroupDump.length(); i++)
{
ClearAcaryAll(arEdgeArcDump);
ClearAcaryAll(arMidArcDump);
if (!arGroupDump[i]->Draw(m_dRadius, arEdgeArcDump, arMidArcDump))
bRet = FALSE;
m_arEdgeInterCircle.append(arEdgeArcDump);
m_arMidInterCircle.append(arMidArcDump);
}
}
else
{ // 同半径
AcGeCircArc2d arcEdge, arcMid;
ArFilroadConnectPointer arConnectDump;
for (int i = 0; i < (int)m_arFilroadEdgeConnect.length(); i++)
{
if (m_arFilroadEdgeConnect[i]->Filroad(m_dRadius, arcEdge))
m_arEdgeInterCircle.append(arcEdge);
else
bRet = FALSE;
}
for (i = 0; i < (int)m_arFilroadMidConnect.length(); i++)
{
if (m_arFilroadMidConnect[i]->Filroad(m_dRadius, arcMid))
m_arMidInterCircle.append(arcMid);
else
bRet = FALSE;
}
}
return bRet;
}
void CRoadFillterMgr::Draw()
{
// 重现绘制原来的线
int index = 0, iLen = 0;
for (index = 0, iLen = (int)m_arEdgeLineAdapter.length(); index < iLen; index++)
{
m_arEdgeLineAdapter[index]->Redraw(eRoadEdgeType);
}
for (index = 0, iLen = (int)m_arEdgeArcAdapter.length(); index < iLen; index++)
{
m_arEdgeArcAdapter[index]->Redraw(eRoadEdgeType);
}
for (index = 0, iLen = (int)m_arMidLineAdapter.length(); index < iLen; index++)
{
m_arMidLineAdapter[index]->Redraw(eRoadMidType);
}
for (index = 0, iLen = (int)m_arMidArcAdapter.length(); index < iLen; index++)
{
m_arMidArcAdapter[index]->Redraw(eRoadMidType);
}
// 绘制新添加的倒角线
for (index = 0, iLen = (int)m_arEdgeInterCircle.length(); index < iLen; index++)
{
AcDbArc *pArc = new AcDbArc;
GeArcToDbSys(m_arEdgeInterCircle[index], *pArc);
SetLayer(pArc, eRoadEdgeType);
AddToModelSpace(pArc);
}
for (index = 0, iLen = (int)m_arMidInterCircle.length(); index < iLen; index++)
{
AcDbArc *pArc = new AcDbArc;
GeArcToDbSys(m_arMidInterCircle[index], *pArc);
SetLayer(pArc, eRoadMidType);
AddToModelSpace(pArc);
}
}
void CRoadFillterMgr::ReleaseMem()
{
ClearAndDeleteAry(m_arEdgeLine);
ClearAndDeleteAry(m_arEdgeArc);
ClearAndDeleteAry(m_arMidLine);
ClearAndDeleteAry(m_arMidArc);
ClearAndDeleteAry(m_arEdgeLineAdapter);
ClearAndDeleteAry(m_arEdgeArcAdapter);
ClearAndDeleteAry(m_arMidLineAdapter);
ClearAndDeleteAry(m_arMidArcAdapter);
ClearAndDeleteAry(m_arFilroadEdgeConnect);
ClearAndDeleteAry(m_arFilroadMidConnect);
ClearAndDeleteAry(m_arFilroadGroup);
ClearAndDeleteAry(m_arFilroadGroupMid);
ClearAcaryAll(m_arEdgeInterCircle);
ClearAcaryAll(m_arMidInterCircle);
}