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

537 lines
15 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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);
}