You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
7.2 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//////////////////////////////////////////////////////////////////////////////
//文件: 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<int>& 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<int>
{
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<CSegment3D> segments; //道号的集合
};
//管理三维SegY文件中的线道号、坐标及道在文件中的位置
class AFX_EXT_CLASS CSeisIndex3D : public TObjectSet<CSeisIndexLine3D>
{
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<int>& rg) const; //!< Returns whether fully regular.
bool getCrlRange(TIntervalStep<int>& rg) const; //!< Returns whether fully regular.
bool getCubeRange(CCubeRange& cr);
//获得指定剖面的线道号范围
bool getInlRange(int inline_num, OUT TIntervalStep<int>& rg) const;
bool getCrlRange(int crossline_num, OUT TIntervalStep<int>& 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<CSeisIndexPoint>& 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<CSeisIndexPoint>& tp);
//得到下一个方向边边界点若不存在或已被查找过返回false -- wcw
bool GetDirectIndexPoints(TTypeSet<CSeisIndexPoint>& tp, int& direct);
public:
TIntervalStep<int> m_inlRange; //仅是保存getInlRange返回的结果
TIntervalStep<int> m_crlRange; //仅是保存getCrlRange返回的结果
protected:
CFileSegy m_frSegy; //SegY文件读取
};
}//namespace