////////////////////////////////////////////////////////////////////////////// //文件: SegY文件操作类 //主要功能: // 保存构建好的三维地震剖面的索引数据 //程序编写: 2011-4-1 // // ///////////////////////////////////////////////////////////////////////////// #pragma once #include "SeisSampleInfo.h" #include "SeisSurvey3D.h" #include "DrawModel/ColorBase.h" namespace NSeis { ////////////////////////////////////////////////////////////////////////// //主测线保存方式 // // 1------------------------------2 // 线/|\ ------------------------------ // 增 | ...... ...... // 大 | ------------------------------ // | 0------------------------------3 // // -------->道号增大 ////////////////////////////////////////////////////////////////////////// //3D数据体的线定位信息,每一条CLineData为一条inline,线段号为crossline //考虑了线道号步长、每道的采样点个数(每道的数据长度) class AFX_EXT_CLASS CSeisIndexLine3D { public: CSeisIndexLine3D( ); CSeisIndexLine3D( int i, EOrientation ori = oriInline ); ~CSeisIndexLine3D(void); bool NextTrace(int& col); //获得下一道的道号,也就是增加了一个步长 bool PrevTrace(int& col); //获得上一道的道号,也就是减少了一个步长 bool GetIndexPoint(int col, OUT CSeisIndexPoint& gp);//根据道号获得坐标及文件定位 __int64 GetFilePosition(int col); //获得文件道定位,获得不正确时返回-1 int size() const { return segments.size(); } //返回线段的个数 int GetTraceCount(); //获得总道数 bool GetRange(TInterval& range) const; //获得道号范围 int GetRange(CRect8& range); //获得坐标范围,返回参与运算的点个数 int segmentOf(int) const; //获得包含该道号的线段 //void merge(const CLineData&, bool incl); //!< incl=union, !incl=intersection int GetSurveyCurve(CSurveyLine* pCurve); //获得测线,包括坐标、桩号、名称等值 //获得索引中的指定段索引 bool GetIndexSegment(OUT CSeisIndexLine3D& id, int startCol, int stopCol); int nearestSegment(double) const; void WriteLine(CStdioFile& fw); //将inline测线保存为DFD文件,以便检查是否正确 void Write(CFile& fw); //保存索引线的数据为文本文件 int Read(CFile& fr); void Serialize(CArchive& ar, const short &ver); public: /////////////////////////////////////////////////////////////////////////////////////// class AFX_EXT_CLASS CSegment3D : public TIntervalStep { public: //根据道号获得坐标及文件定位 bool GetIndexPoint(int col, OUT CSeisIndexPoint& gp); bool GetIndexPointStart(OUT CSeisIndexPoint& gp); bool GetIndexPointStop(OUT CSeisIndexPoint& gp); __int64 GetFilePosition(int col); //获得文件道定位 //获得其中的一段的索引 bool GetSegment(OUT CSegment3D& sd, int startCol, int stopCol); void operator=(CSegment3D& sg); bool isEqual(CSegment3D* psg); public: //crossline号: start stop step TIntervalStep<__int64> m_pos; //对应crossline号在文件中的位置, //仅为了SegY文件格式,主要是为了适应不规划工区, //一般步长为(240+采样点长度*采样点个数) CPoint2D m_coorStart; //对应crossline号的开始坐标信息 CPoint2D m_coorStop; //对应crossline号的结束坐标信息 }; EOrientation m_orientation; //Inline、Crossline方向 int line_num; //Inline:线号,Crossline:道号 TObjectSet segments; //道号的集合 }; //管理三维SegY文件中的线道号、坐标及道在文件中的位置, class AFX_EXT_CLASS CSeisIndex3D : public TObjectSet { public: CSeisIndex3D(void); ~CSeisIndex3D(void); int FindInline( int lnr ) const; //返回-1为没有该线 CSeisIndexLine3D* GetInline(int inr); bool GetCrossline(int crl, OUT CSeisIndexLine3D& sl); bool isIncludes(int inl,int crl) const; bool getInlRange(TIntervalStep& rg) const; //!< Returns whether fully regular. bool getCrlRange(TIntervalStep& rg) const; //!< Returns whether fully regular. bool getCubeRange(CCubeRange& cr); //获得指定剖面的线道号范围 bool getInlRange(int inline_num, OUT TIntervalStep& rg) const; bool getCrlRange(int crossline_num, OUT TIntervalStep& rg) const; //获得指定剖面的最大最小坐标,isCoor为true时表示获得坐标范围,为false表示获得线道号范围 bool getInlRange(int inline_num, CPoint3D& minPoint, CPoint3D& maxPoint, bool isCoor); bool getCrlRange(int crossline_num, CPoint3D& minPoint, CPoint3D& maxPoint, bool isCoor); bool isFullyRectAndReg() const; //根据线道号获得坐标及文件定位,参数gp中的线道号必须提前指定 bool GetIndexPoint(CSeisIndexPoint& gp); //获得可形成的最大矩形范围(不规则工区时不是工区的最大范围),pseg为4个对象长度 bool GetRectRange(CSeisIndexPoint* pseg); //仅获得工区线道号范围为矩形时的四角点,内部并不判断是否是矩形线道号范围 void GetFullyRectRange(CSeisIndexPoint* pseg); //获得坐标范围,返回参与运算的点个数 int GetRange(CRect8& range); //获得工区边框,返回获得的坐标点个数 int GetFrame(CCurve& curve); int GetFrame(TTypeSet& tp); void WriteInline(LPCTSTR lpszFileName); //将inline测线保存为DFD文件,以便检查是否正确 void WriteCrossline(LPCTSTR lpszFileName); //将crossline测线保存为DFD文件,以便检查是否正确 //void merge(const CCubePosition&,bool incl); //void sort(); void Write(LPCTSTR lpszFileName); void Write(CFile& fw, const short& ver); int Read(CFile& fr, const short& ver); void Serialize(CArchive& ar, const short &ver); void operator = (CSeisIndex3D& si); CSeisSampleInfo& GetSampleInfo() { return m_sampleInfo; } CSeisSurvey3D& GetSurvey() { return m_survey; } CColorBase& GetColorBar() { return m_colorBar; } /** @brief 设置采样间隔,参数单位与SegY格式中的保持一致,使用时需要乘以0.001 */ void SetSampleInterval(unsigned short si); bool InitSurvey(); //根据建立好的索引初始化测网及读取器 void InitRange(); //初始化线道号范围,必须在建立好后调用 //////////////////////////////////////////////////////////////////////// //SegY文件操作函数 CFileSegy* OpenSegyFile(); void CloseSegyFile(); bool IsOpen(); //定位到指定道 bool SeekToTrace(int row, int col); //从SegY中指定道中读取一个振幅值,使用前需要先定位到指定道开始 // 参数这pTempMem:临时缓存,可外部指定,为了防止每次进行内存申请而设,缺省时内部自动申请内存读取 float ReadOneValueFromSegy(double dTime, bool bLineValue, BYTE* pTempMem = NULL); float ReadOneValueFromSegy(int nIndexSample); ///** @brief 从SegY中指定道中读取一个振幅值 ///** int inl:线号 ///** int crl:道号 ///** int nIndexSample:道索引号(基于0值) ///** double dTime:指定的实际时间值 ///** bool bLineValue:是否插值 float ReadOneValueFromSegy(int inl, int crl, int nIndexSample); //读取指定线道采样点处的振幅值 float ReadOneValueFromSegy(int inl, int crl, double dTime, bool bLineValue); //////////////////////////////////////////////////////////////////////// CString m_strFileName; //与该体数据对应的SegY文件 CSeisSampleInfo m_sampleInfo; //地震剖面的采样点信息 CSeisSurvey3D m_survey; //测网等信息 CColorBase m_colorBar; //颜色条 protected: //得到不规则工区边界 -- wcw void GetIrregularBorder(TTypeSet& tp); //得到下一个方向边边界点,若不存在或已被查找过,返回false -- wcw bool GetDirectIndexPoints(TTypeSet& tp, int& direct); public: TIntervalStep m_inlRange; //仅是保存getInlRange返回的结果 TIntervalStep m_crlRange; //仅是保存getCrlRange返回的结果 protected: CFileSegy m_frSegy; //SegY文件读取 }; }//namespace