Files
envi-code/SourceCode/Code2026/tg_shs/shs_siteplan/InterStruct.h
T

222 lines
8.9 KiB
C++
Raw Normal View History

2026-09-28 15:28:50 +08:00
// Copyright (C), 1998-2007, Beijing Tangent Engineering Software Co. Ltd.
// = FileName: RoadEdge.h
// = Version: 8.5
// = Author: lgh
// = Date: 2010-9-27 9:19:57
// = Description: 单线道路的处理结果,用来跟当前道路做处理
// = Maintainers:
#pragma once
#include "commonRoad.h"
#include "CADEntEdgeAdapter.h"
/*
CAD中存在的道路线代表单线道路,单线道路跟当前绘制的双线道路发生关系,以该类记录:
单线道路跟当前道路的关系有以下:
1、单线道路只能跟道路的一侧相交,如果某道路交与两侧,则需要拆改道路为两个interStruct;
2、当先道路相对于当前道路有以下位置:起点外,终点外,道路内。(EPointAtRoad m_eAtRoad;)
3、根据交点与自身的关系,单线道路分为这两种情况,交点在单线上,交点在单线延长线上。(BOOL m_bInEdge;)
4、需要记录单线是哪一端跟道路发生相交(BOOL m_bStart)
5、单线道路跟当前道路在同一侧可能会产生两个交点,此时实际上存在两个不同的itnerStruct;
为了防止生成单线道路的时候,重复,需要设置attach的标记,防止处理的重复。
{BOOL m_bAttached; CInterStruct *m_pInterStructAttached;}
6、单线道路肯定存在一个关联CAD中的单线,新的单线被处理之后,旧的要被删除掉。
*/
// CAD中道路单线跟当前双线道路发生相交之后,根据交点对该单线执行拆分:
// 1、拆分出来的单线在道路内部
// 2、拆分出来的单线跟当前道路没关系 (没有相交)
// 3、拆分出来的单线在道路的左边线的左侧,或者右边线的右侧(通过交点处的切线方向识别)
// 4、拆分出来的单线在道路的左边线的右侧,或者在右边线的左侧(跟左边线相交,但是交点切向是向着右边线的方向,或者相反)
// 第四种情况拆分出来的interStruct结构体需要设置bComplexOut标志。
// 程序中对这种单线只处理拐角相交,其他情况不处理。
class CLineInterStruct;
class CArcInterStruct;
class CRoad;
class CInterStruct
{
enum EFlag{
eFlagStartInter = 0x0001, // 是否起点相交
eFlagInEdge = 0x0002, // 交点在该单线道路的内部,还是外部
eFlagAttached = 0x0004, // 两端同时交与道路一端,只生成一个;// 互相关联另一个的指针
eFlagComplexOut = 0x0008, // 其意义参见文件上部注释
eFlagEdgeOrMid = 0x0010, // 是道路边线,还是中线,用于生成时,设置线条的图层
eFlagShort = 0x0020, // 是否是短线
eFlagInRoad = 0x0040, // 是否在道路内
eFlagDone = 0x0080, // 是否已经处理过。
eFlagPara = 0x0100, // 平行的interStruct
eFlagDrawed = 0x0200, // 是否已经绘制过。用于Attached实体
eFlagErase = 0x0400 // 删除标记
};
public:
CInterStruct(void);
virtual ~CInterStruct(void);
EPointAtRoadInDir Position() const{return m_eAtRoad;}
AcGePoint2d InterPoint() const{return m_ptInter;}
// 判断是否需要生成,判断是否需要添加,添加完毕之后,需要设置Attach标志
virtual void CreateNew() = 0;
virtual void EraseOldObject() = 0;
// 设置生成标记,以便在绘制道路线的时候,统一绘制。
virtual void SetCreateFlag() = 0;
virtual double Lenth() const = 0;
bool IsAttached() const{return TestFlag(eFlagAttached);}
bool IsStart() const{return TestFlag(eFlagStartInter);}
bool IsInEdge() const {return TestFlag(eFlagInEdge);}
// 是不是道路,还是中线
bool IsEdge() const {return TestFlag(eFlagEdgeOrMid);}
bool IsMidRoad() const {return !IsEdge();}
bool IsComplexOut() const {return TestFlag(eFlagComplexOut);}
bool IsDrawed() const {return TestFlag(eFlagDrawed);}
bool IsPara() const {return TestFlag(eFlagPara);}
void SetMidFlag() {SetFlag(false, eFlagEdgeOrMid);}
void SetStart(BOOL bStart){SetFlag(bStart, eFlagStartInter);}
void SetInEdge(BOOL bInEdge){SetFlag(bInEdge, eFlagInEdge);}
void SetPostion(EPointAtRoadInDir eAt){m_eAtRoad = eAt;}
void SetInterPoint(const AcGePoint2d &interPoint){m_ptInter = interPoint;}
void SetAttachedStruct(CInterStruct *pInter){m_pInterStructAttached = pInter;}
// 设置Attach标记,该标记设置之后,该数据无需再绘制
void BeAttached(){SetFlag(eFlagAttached);}
CInterStruct *AttachedStruct() const {return m_pInterStructAttached;}
void SetDrawed(BOOL bDrawed) {SetFlag(bDrawed, eFlagDrawed);}
void SetEraseFlag(BOOL bErase) {SetFlag(bErase, eFlagErase);}
void SetPara(BOOL bPara = TRUE) {SetFlag(bPara, eFlagPara);}
// 其意义,参见文件头部注释
void SetComplexOutFlag() {SetFlag(eFlagComplexOut);}
virtual CLineInterStruct* ToLineInter() const{return NULL;}
virtual CArcInterStruct* ToArcInter( ) const{return NULL;}
virtual double DistanceTo(const AcGePoint2d &pt) const = 0;
// 检测本InterStruct是否在pInter1和pInter2中间。注意,需要检测pInter1,或者pInter2是空的情况
BOOL IsMidofInterStruct(CInterStruct *pInter1, CInterStruct *pInter2) const;
// 交点向另外一个点的方向
virtual AcGeVector2d Direction() const = 0;
BOOL IsNeedCreate(const CCADEntEdgeAdapter &entAttached) const;
bool IsDone() const {return TestFlag(eFlagDone);}
bool IsShort() const {return TestFlag(eFlagShort);}
bool IsInRoad() const {return TestFlag(eFlagInRoad);}
bool IsErased() const {return TestFlag(eFlagErase);}
void SetDoneFlag(bool bSet = false) {SetFlag(bSet, eFlagDone);}
void SetShortFlag(bool bSet = false) {SetFlag(bSet, eFlagShort);}
void SetInRoadFlag(bool bSet = false) {SetFlag(bSet, eFlagInRoad);}
// 几何信息合并,必须是顺序的
virtual BOOL CombinInterStrcutInSequence(CInterStruct *pInterNext) = 0;
// AttachStruct的合并
virtual BOOL CombinAttachInterStruct() = 0;
// 创建,不判断是否需要创建。
virtual void SimpleCreate() = 0;
virtual CCADEntEdgeAdapter* GetOriginAdapter() const = 0;
//设置拆分出来的单线所在的组
void SetGroupId(AcDbObjectId &GroupId){m_GroupId = GroupId;}
//设置拆分出来的单线是否显示
void SetIsVisible(AcDb::Visibility IsVisible){m_bIsVisible = IsVisible;}
AcDbObjectId GetGroupId(){return m_GroupId;}
protected:
void SetFlag(BOOL bSet, EFlag flag) {if (bSet)SetFlag(flag); else ClearFlag(flag);}
void SetFlag(EFlag flag){m_dwFlag |= flag;}
void ClearFlag(EFlag flag){m_dwFlag &= (~flag);}
bool TestFlag(EFlag flag) const {return (flag & m_dwFlag) ? true : false;}
EPointAtRoadInDir m_eAtRoad;
AcGePoint2d m_ptInter;
CInterStruct *m_pInterStructAttached;
DWORD m_dwFlag;
AcDb::Visibility m_bIsVisible; //是否显示单线
AcDbObjectId m_GroupId; //单线所在组
};
class CLineInterStruct : public CInterStruct
{
public:
CLineInterStruct(CLineCADEntEdgeAdapter &lineEnt);
virtual ~CLineInterStruct(void);
// 未拆分的线
AcGeLineSeg2d OriginLine() const;
// 相交线
AcGeLineSeg2d InterLine() const;
void SetInterLine(const AcGeLineSeg2d &line) ;
// 检测本InterStruct是否在pInter1和pInter2中间。注意,需要检测pInter1,或者pInter2是空的情况
BOOL IsMidofInterStruct(CLineInterStruct *pInter1, CLineInterStruct *pInter2) const;
//////////////////////////////////////////////////////////////////////////
virtual void CreateNew();
virtual void EraseOldObject();
virtual double Lenth() const;
virtual CLineInterStruct* ToLineInter() const;
virtual double DistanceTo(const AcGePoint2d &pt) const;
virtual AcGeVector2d Direction() const;
virtual void SetCreateFlag();
virtual BOOL CombinInterStrcutInSequence(CInterStruct *pInterNext);
virtual BOOL CombinAttachInterStruct();
virtual void SimpleCreate();
void SimpleCreateForLandScape();
// 用于模板函数中类型提取,其值无意义
static CLineInterStruct DumpStruct();
virtual CCADEntEdgeAdapter* GetOriginAdapter() const {return &m_lineEnt;}
private:
CLineCADEntEdgeAdapter &m_lineEnt; // 对应CAD中的线。
AcGeLineSeg2d m_interLine; // 处理之后的线
};
class CArcInterStruct : public CInterStruct
{
public:
CArcInterStruct(CArcCADEntEdgeAdapter &arcEnt);
virtual ~CArcInterStruct(void);
AcGeCircArc2d OriginArc() const;
AcGeCircArc2d InterArc() const;
void SetInterArc(const AcGeCircArc2d &arc) ;
// 检测本InterStruct是否在pInter1和pInter2中间。注意,需要检测pInter1,或者pInter2是空的情况
BOOL IsMidofInterStruct(CArcInterStruct *pInter1, CArcInterStruct *pInter2) const;
//////////////////////////////////////////////////////////////////////////
virtual void CreateNew();
virtual void EraseOldObject();
virtual double Lenth() const;
virtual CArcInterStruct* ToArcInter( ) const;
virtual double DistanceTo(const AcGePoint2d &pt) const;
virtual AcGeVector2d Direction() const;
virtual void SetCreateFlag();
virtual BOOL CombinInterStrcutInSequence(CInterStruct *pInterNext);
virtual BOOL CombinAttachInterStruct();
virtual void SimpleCreate();
void SimpleCreateForLandScape();//用于创建被打断的景观路边线
// 用于模板函数中类型提取,其值无意义
static CArcInterStruct DumpStruct();
virtual CCADEntEdgeAdapter* GetOriginAdapter() const {return &m_arcEnt;}
private:
CArcCADEntEdgeAdapter &m_arcEnt; // 对应CAD中的线
AcGeCircArc2d m_interArc; // 处理之后的线。
};
CLineInterStruct* ConInterStruct(const AcGeLineSeg2d &lineEdge, bool bStart, const CRoad &road, CLineCADEntEdgeAdapter &ent, AcGeTol &geTol,
BOOL bPara, BOOL bMid = FALSE, BOOL bComplexOut = FALSE, EPointAtRoadInDir eComplexPos = eInEdge);
CArcInterStruct* ConInterStruct(const AcGeCircArc2d &arcEdge, bool bStart, const CRoad &road, CArcCADEntEdgeAdapter &ent, AcGeTol &geTol,
BOOL bPara, BOOL bMid = FALSE, BOOL bComplexOut = FALSE, EPointAtRoadInDir eComplexPos = eInEdge);
CLineInterStruct* ConInterStructInRoad(const AcGeLineSeg2d &lineEdge, CLineCADEntEdgeAdapter &ent);
CArcInterStruct* ConInterStructInRoad(const AcGeCircArc2d &arcEdge, CArcCADEntEdgeAdapter &ent);