Files
envi-code/SourceCode/Code2026/tg_shs/shs_siteplan/RoadDataCenterNew2.cpp
T

537 lines
15 KiB
C++
Raw Normal View History

2026-09-28 15:28:50 +08:00
#include "stdafx.h"
#include "commonRoad.h"
//#include <dbobjptr.h>
#include "TDbObjectPointer.h"
#include "RoadDataCenterNew.h"
void CRoadDataCenterNew::SelectEntInCAD(const AcGePoint2d &ptLeftDown, const AcGePoint2d &ptRightUp,
AcAryLineEntEdgeAdapterPtr &lineEdges, AcAryArcEntEdgeAdapterPtr &arcEdges,
AcAryLineEntEdgeAdapterPtr &lineMids, AcAryArcEntEdgeAdapterPtr &arcMids)
{
//add tyj 20161020:解决在UCS坐标系下,道路无法正常倒角
/*-----------------begin-------------------*/
TADSGePoint3d ptSave1(ptLeftDown.x, ptLeftDown.y, 0.0);
TADSGePoint3d ptSave2(ptRightUp.x, ptRightUp.y, 0.0);
ptSave1 = Wcs2Ucs(ptSave1);
ptSave2 = Wcs2Ucs(ptSave2);
ads_point pt1 = {ptSave1.x, ptSave1.y, 0.0};
ads_point pt2 = {ptSave2.x, ptSave2.y, 0.0};
//ads_point pt1 = {ptLeftDown.x, ptLeftDown.y, 0.0};
//ads_point pt2 = {ptRightUp.x, ptRightUp.y, 0.0};
/*------------------end--------------------*/
CString strRoadLay = LAY_ROAD;
CString strMidRoadLay = LAY_ROADDOTE;
ads_name ssName; // 差选!
acedSSGet(_T("C"), pt1, pt2, NULL, ssName);
Adesk::Int32 len = 0;
acedSSLength(ssName, &len);
ads_name ent;
AcDbObjectId id;
for (long i = 0; i < len; i++)
{
if (acedSSName(ssName, i, ent) == RTNORM)
if (acdbGetObjectId(id, ent) == Acad::eOk)
{
AcDbObjectPointer<AcDbEntity> pEnt;
if (pEnt.open(id, AcDb::kForRead) == Acad::eOk)
{
TCHAR* lay = pEnt->layer();
if (strRoadLay.CompareNoCase(pEnt->layer()) == 0)
{
if (pEnt->isKindOf(AcDbLine::desc()))
{
pEnt.close();
// CLineCADEntEdgeAdapter line(id);
lineEdges.append(new CLineCADEntEdgeAdapter(id));
}
else if (pEnt->isKindOf(AcDbArc::desc()))
{
pEnt.close();
// CArcCADEntEdgeAdapter arc(id);
arcEdges.append(new CArcCADEntEdgeAdapter(id));
}
}
else if (strMidRoadLay.CompareNoCase(pEnt->layer()) == 0)
{
if (pEnt->isKindOf(AcDbLine::desc()))
{
pEnt.close();
// CLineCADEntEdgeAdapter line(id);
lineMids.append(new CLineCADEntEdgeAdapter(id));
}
else if (pEnt->isKindOf(AcDbArc::desc()))
{
pEnt.close();
// CArcCADEntEdgeAdapter arc(id);
arcMids.append(new CArcCADEntEdgeAdapter(id));
}
}
}
}
}
ads_ssfree(ssName);
}
template <class TRoad, class TEdge, class TEdgeEnt>
void EdgeSplitFunTem(const TRoad &road, ROAD_EDGE_STRUCT &res, const TEdge &edge, TEdgeEnt &edgeEnt)
{
AcAryInterStructPointer arLeftInterDump, arRightInterDump, arIntersAll;
road.SplitEdge(edge, arLeftInterDump, arRightInterDump, edgeEnt, arIntersAll);
res.leftIntersAll.append(arLeftInterDump);
res.rightIntersAll.append(arRightInterDump);
res.intersOriginAll.append(arIntersAll);
}
// #define MidSplitFunTem(road, leftInters, rightInters, edge, edgeEnt, ArType)\
// {\
// ArType arLeftInterDump, arRightInterDump; \
// road.SplitMid(edge, arLeftInterDump, arRightInterDump, edgeEnt); \
// leftInters.append(arLeftInterDump); \
// rightInters.append(arRightInterDump); \
// }
template <class TRoad, class TEdge, class TEdgeEnt>
void MidSplitFunTem(const TRoad &road, ROAD_MID_STRUCT &rms, const TEdge &edge, TEdgeEnt &edgeEnt)
{
AcAryInterStructPointer arLeftInterDump, arRightInterDump;
road.SplitMid(edge, arLeftInterDump, arRightInterDump, edgeEnt);
rms.leftInterMid.append(arLeftInterDump);
rms.rightInterMid.append(arRightInterDump);
}
//把单线实体处理为道路左边的(interStruct),和道路右边的interStruct,
void CRoadDataCenterNew::DealLeftAndRightEnt(const CLineRoad &lineRoad, ROAD_MID_STRUCT &rms, ROAD_EDGE_STRUCT &res)
{
int i = 0;
for (i = 0; i < (int)res.lineEdges.length(); i++)
{
AcGeLineSeg2d line = res.lineEdges[i]->Line();//
EdgeSplitFunTem(lineRoad, res, line, *res.lineEdges[i]);
}
for (i = 0; i < (int)res.arcEdges.length(); i++)
{
AcGeCircArc2d arc = res.arcEdges[i]->Arc();
EdgeSplitFunTem(lineRoad, res, arc, *res.arcEdges[i]);
}
for (i = 0; i < (int)rms.lineMids.length(); i++)
{
AcGeLineSeg2d line = rms.lineMids[i]->Line();
MidSplitFunTem(lineRoad, rms, line, *rms.lineMids[i]);
}
for (i = 0; i < (int)rms.arcMids.length(); i++)
{
AcGeCircArc2d arc = rms.arcMids[i]->Arc();
MidSplitFunTem(lineRoad, rms, arc, *rms.arcMids[i]);
}
SaveMidInterStruct(rms);
}
//把单线实体处理为道路左边的(interStruct),和道路右边的interStruct,
void CRoadDataCenterNew::DealLeftAndRightEnt(const CArcRoad &arcRoad, ROAD_MID_STRUCT &rms, ROAD_EDGE_STRUCT &res)
{
int i = 0;
for (i = 0; i < (int)res.lineEdges.length(); i++)
{
AcGeLineSeg2d line = res.lineEdges[i]->Line();//
EdgeSplitFunTem(arcRoad, res, line, *res.lineEdges[i]);
}
for (i = 0; i < (int)res.arcEdges.length(); i++)
{
AcGeCircArc2d arc = res.arcEdges[i]->Arc();
EdgeSplitFunTem(arcRoad, res, arc, *res.arcEdges[i]);
}
for ( i = 0; i < (int)rms.lineMids.length(); i++)
{
AcGeLineSeg2d line = rms.lineMids[i]->Line();
MidSplitFunTem(arcRoad, rms, line, *rms.lineMids[i]);
}
for (i = 0; i < (int)rms.arcMids.length(); i++)
{
AcGeCircArc2d arc = rms.arcMids[i]->Arc();
MidSplitFunTem(arcRoad, rms, arc, *rms.arcMids[i]);
}
SaveMidInterStruct(rms);
}
struct __InterSortStruct
{
CInterStruct* pInter;
double dLen;// 带方向的长度
};
int CompareLineSortStruct(const void *p1, const void *p2)
{
const __InterSortStruct *ps1 = (__InterSortStruct*)(p1);
const __InterSortStruct *ps2 = (__InterSortStruct*)(p2);
ASSERT(ps1 != NULL);
ASSERT(ps2 != NULL);
// 不设置0返回。
return ps1->dLen < ps2->dLen ? -1 : 1;
}
// 对道路的相交结构体排序(包括的可能有直线的,弧线的)
// 问题描述,这些点分布在道路上边线上,根据道路的方向对这些点,执行排序。
void CRoadDataCenterNew::SortInterStructsSimp(const AcGeLineSeg2d &lineDir, bool bSequence, AcAryInterStructPointer &arInterPointer)
{
ASSERT(bSequence == true);
if (arInterPointer.length() < 2)
return; // 只有一个也不排序
AcGePoint2d ptStart = lineDir.startPoint();
AcGeVector2d vecDir = lineDir.direction();
__InterSortStruct *pSortStruct = new __InterSortStruct[arInterPointer.length()];
int i;
for (i = 0;i < (int)arInterPointer.length(); i++)
{
AcGeVector2d vecDump = arInterPointer[i]->InterPoint() - ptStart;
pSortStruct[i].pInter = arInterPointer[i];
pSortStruct[i].dLen = vecDump.dotProduct(vecDir);
}
qsort(pSortStruct, (int)arInterPointer.length(), sizeof(__InterSortStruct), CompareLineSortStruct);
for (i = 0; i < (int)arInterPointer.length(); i++)
{
arInterPointer[i] = pSortStruct[i].pInter;
}
delete [] pSortStruct;
}
// 方法:
// 想象圆弧是一个两端有限延伸的曲线,该排序建立在这个曲线上。从起点到终点。
void CRoadDataCenterNew::SortInterStructsSimp(const AcGeCircArc2d &arcDir, bool bSequence, AcAryInterStructPointer &arInterPointer)
{
ASSERT(bSequence == true);
if (arInterPointer.length() < 2)
return;
AcGePoint2d ptStart = arcDir.startPoint();
AcGePoint2d ptEnd = arcDir.endPoint();
AcGePoint2d ptCenter = arcDir.center();
double dStartAngle = AcGeVector2d(ptStart - ptCenter).angle();
double dEndAngle = AcGeVector2d(ptEnd - ptCenter).angle();
double dArcAngle = AngleInClock(arcDir.isClockWise() == Adesk::kTrue, dStartAngle, dEndAngle);
// 计算每个点与这个角度的夹角
double dAccurateStartAngle = AntiAngle(AddAngleInClock(arcDir.isClockWise() == Adesk::kTrue, dStartAngle, dArcAngle*0.5));
__InterSortStruct *pSortStruct = new __InterSortStruct[arInterPointer.length()];
int i;
for (i = 0; i < (int)arInterPointer.length(); i++)
{
AcGeVector2d vecDump = arInterPointer[i]->InterPoint() - ptCenter;
pSortStruct[i].pInter = arInterPointer[i];
pSortStruct[i].dLen = AngleInClock(arcDir.isClockWise() == Adesk::kTrue, dAccurateStartAngle, vecDump.angle());
}
qsort(pSortStruct, (int)arInterPointer.length(), sizeof(__InterSortStruct), CompareLineSortStruct);
for (i = 0; i < (int)arInterPointer.length(); i++)
{
arInterPointer[i] = pSortStruct[i].pInter;
}
delete [] pSortStruct;
}
bool GetInIndex(const AcAryInterStructPointer &aryInterPointer, int &nFirstIn, int &nLastIn)
{
nFirstIn = -1;
nLastIn = -1;
for (int i = 0; i < (int)aryInterPointer.length(); i++)
{
if (aryInterPointer[i]->Position() == eInEdge)
{
if (nFirstIn == -1) nFirstIn = i;
nLastIn = i;
}
}
return nFirstIn != -1 && nLastIn != -1;
}
// 判断道路的过滤方式,目前的方式有:保留第一个,不保留第一个(间隔取路),可能还会增加其他的过滤方式。
CFilterMode CRoadDataCenterNew::FindFilterMode(const AcGeLineSeg2d &lineDir, bool bSequence,
const AcAryInterStructPointer &aryInterPointer)
{
ASSERT(bSequence == true);
CFilterMode filterMode;
//此处aryInterPointer是经过排序的。
// 去总长度,然后计算平均长度
double dFirsrtLen = 0.0, dSecondLen = 0.0;
int nFirstNum = 0, nSecondNum = 0;
int nFirstIn = -1, nLastIn = -1;
GetInIndex(aryInterPointer, nFirstIn, nLastIn);
if (nFirstIn == -1 && nLastIn == -1)
filterMode.KeepFirst(TRUE);// 留下这段
else if (nFirstIn == nLastIn)
{ // 只有一个线在里边,比较两侧那边更长
AcGePoint2d ptCurrent = aryInterPointer[nFirstIn]->InterPoint();
filterMode.KeepFirst(lineDir.startPoint().distanceTo(ptCurrent) > lineDir.endPoint().distanceTo(ptCurrent));
}
else
{ // 有多个内点:
for (int i = nFirstIn; i <= nLastIn; i++)
{
if (i == nFirstIn)
{
nFirstNum = 1;
dFirsrtLen += lineDir.startPoint().distanceTo(aryInterPointer[i]->InterPoint());
continue;
}
else
{
if (EvenNum(nFirstNum+nSecondNum))
{
nFirstNum += 1;
dFirsrtLen += aryInterPointer[i-1]->InterPoint().distanceTo(aryInterPointer[i]->InterPoint());
}
else
{
nSecondNum += 1;
dSecondLen += aryInterPointer[i-1]->InterPoint().distanceTo(aryInterPointer[i]->InterPoint());
}
}
if (i == nLastIn)
{
if (EvenNum(nFirstNum+nSecondNum))
{
nFirstNum += 1;
dFirsrtLen += aryInterPointer[i]->InterPoint().distanceTo(lineDir.endPoint());
}
else
{
nSecondNum += 1;
dSecondLen += aryInterPointer[i]->InterPoint().distanceTo(lineDir.endPoint());
}
}
}
filterMode.KeepFirst(dFirsrtLen/nFirstNum > dSecondLen/nSecondNum);
}
return filterMode;
}
CFilterMode CRoadDataCenterNew::FindFilterMode(const AcGeCircArc2d &arcDir, bool bSequence, const AcAryInterStructPointer &aryInterPointer)
{
#define INTERPOINT(n) (aryInterPointer[n]->InterPoint())
ASSERT(bSequence == true);
CFilterMode filterMode;
//此处aryInterPointer是经过排序的。
// 取总长度,然后计算平均长度,比较大小。长的保留
double dFirsrtLen = 0.0, dSecondLen = 0.0;
int nFirstNum = 0, nSecondNum = 0;
int nFirstIn = -1, nLastIn = -1;
GetInIndex(aryInterPointer, nFirstIn, nLastIn);
if (nFirstIn == -1 && nLastIn == -1)
filterMode.KeepFirst(TRUE);// 留下这段
else if (nFirstIn == nLastIn)
{ // 只有一个线在里边,比较两侧那边更长
AcGePoint2d ptCurrent = INTERPOINT(nFirstIn);
filterMode.KeepFirst(LenOfArc(ConNewArc(arcDir, arcDir.startPoint(), ptCurrent)) > LenOfArc(ConNewArc(arcDir, ptCurrent, arcDir.endPoint())));
}
else
{ // 有多个内点:
for (int i = nFirstIn; i <= nLastIn; i++)
{
if (i == nFirstIn)
{
nFirstNum = 1;
dFirsrtLen += LenOfArc(ConNewArc(arcDir, arcDir.startPoint(), INTERPOINT(i)));
continue;
}
else
{
if (EvenNum(nFirstNum+nSecondNum))
{
nFirstNum += 1;
dFirsrtLen += LenOfArc(ConNewArc(arcDir, INTERPOINT(i-1), INTERPOINT(i)));
}
else
{
nSecondNum += 1;
dSecondLen += LenOfArc(ConNewArc(arcDir, INTERPOINT(i-1), INTERPOINT(i)));
}
}
if (i == nLastIn)
{
if (EvenNum(nFirstNum+nSecondNum))
{
nFirstNum += 1;
dFirsrtLen += LenOfArc(ConNewArc(arcDir, INTERPOINT(i), arcDir.endPoint()));
}
else
{
nSecondNum += 1;
dSecondLen += LenOfArc(ConNewArc(arcDir, INTERPOINT(i), arcDir.endPoint()));
}
}
}
filterMode.KeepFirst(dFirsrtLen/nFirstNum > dSecondLen/nSecondNum);
}
#undef INTERPOINT
return filterMode;
}
int CRoadDataCenterNew::InterStuctRealIn(const AcAryInterStructPointer &aryAll, AcAryInterStructPointer &aryRealIn)
{
for (int i = 0; i < (int)aryAll.length(); i++)
{
if (aryAll[i]->IsInEdge() && (aryAll[i]->Position() == eInEdge) && (!aryAll[i]->IsPara()))
aryRealIn.append(aryAll[i]);
}
return (int)aryRealIn.length();
}
// 把相交结构体合并了。
void CRoadDataCenterNew::CombinInterStruct(const AcAryLineInterStruct &lineInters, const AcAryArcInterStruct &arcInters,
AcAryInterStructPointer &arInterPointer)
{
ASSERT(arInterPointer.isEmpty());
int i = 0;
for (i = 0; i < (int)lineInters.length(); i++)
{
const CLineInterStruct *pLineInter = lineInters[i];
arInterPointer.append(const_cast<CLineInterStruct*>(pLineInter));
}
for (i = 0; i < (int)arcInters.length(); i++)
{
const CArcInterStruct *pArcInter = arcInters[i];
arInterPointer.append(const_cast<CArcInterStruct*>(pArcInter));
}
}
void CRoadDataCenterNew::RemoveShortInterStruct(AcAryInterStructPointer &aryInterStruct, double dTolLen)
{
for (int i = (int)aryInterStruct.length() - 1; i > -1; i--)
{
if (aryInterStruct[i]->Lenth() < dTolLen)
{
// delete aryInterStruct[i];
aryInterStruct[i]->SetCreateFlag(); // 因为他删除了,所以其他没有删除的需要创建。
aryInterStruct[i]->SetShortFlag(true);
aryInterStruct.removeAt(i);
}
}
}
void CRoadDataCenterNew::RemoveShortInterStruct(ROAD_EDGE_STRUCT &res, double dTolLen)
{
RemoveShortInterStruct(res.leftIntersAll, dTolLen);
RemoveShortInterStruct(res.rightIntersAll, dTolLen);
}
void CRoadDataCenterNew::ReTestInterStruct(AcAryInterStructPointer &aryInterStruct, TGGeCurveSegment &curveSeg, double dTolLen, bool bOldClock)
{
// 判断两端的,从前往后判断
int i=0;
for (i = 0; i < (int)aryInterStruct.length(); ++i)
{
if (aryInterStruct[i]->Position() == eInEdge)
{ // 在道路内
double dDist = curveSeg.PathDistance(aryInterStruct[i]->InterPoint(), bOldClock ? 0 : 1);
if (dDist < dTolLen)
aryInterStruct[i]->SetPostion(eRoadStartOut);
else
break;
}
}
for (i = (aryInterStruct.length() - 1); i > -1; --i)
{
if (aryInterStruct[i]->Position() == eInEdge)
{ // 在道路内
double dDist = curveSeg.PathDistance(aryInterStruct[i]->InterPoint(), bOldClock ? 1 : 0);
if (dDist < dTolLen)
aryInterStruct[i]->SetPostion(eRoadEndOut);
else
break;
}
}
}
void CRoadDataCenterNew::ReTestInterStruct(ROAD_EDGE_STRUCT &res, const CRoad *pRoad, double dTolLen, bool bOldClock)
{
TGGeCurveSegment c1(pRoad->ToCurveSeg(1)), c2(pRoad->ToCurveSeg(2));
ReTestInterStruct(res.leftIntersAll, c1, dTolLen, bOldClock);
ReTestInterStruct(res.rightIntersAll, c2, dTolLen, bOldClock);
}
void CRoadDataCenterNew::CreateRoadEdgeStruct(ROAD_EDGE_STRUCT &res)
{
int index = 0, ilen = (int)res.lineEdges.length();
for (index = 0; index < ilen; index++)
res.lineEdges[index]->ReCreate();
ilen = (int)res.arcEdges.length();
for (index = 0; index < ilen; index++)
res.arcEdges[index]->ReCreate();
}
void CRoadDataCenterNew::Clear(ROAD_EDGE_STRUCT &res, ROAD_MID_STRUCT &rms)
{
ClearAndDeleteAry(res.lineEdges);
ClearAndDeleteAry(res.arcEdges);
ClearAndDeleteAry(res.intersOriginAll);
ClearAndDeleteAry(rms.lineMids);
ClearAndDeleteAry(rms.arcMids);
ClearAndDeleteAry(rms.intersOriginAll);
}
void CRoadDataCenterNew::SaveMidInterStruct(ROAD_MID_STRUCT &rms)
{
rms.intersOriginAll.append(rms.leftInterMid);
rms.intersOriginAll.append(rms.rightInterMid);
}