// 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);