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.

440 lines
24 KiB
C#

1 month ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Unplugged.Segy;
namespace GeoSigma.PcgDrawSection
{
public partial class FormParseHeader : Form
{
public ISegyFile Segy { get; set; }
public ISegyOptions Options { get; set; }
private bool isChanged = false;
DataTable dtInfor;
int inlineMin = 0, inlineMax = 0, crosslineMin = 0, crosslineMax = 0;
List<HeadRow> HeaderSchemaRows = null;
List<HeadRow> TraceSchemaRows = null;
private void FormParseHeader_Load(object sender, EventArgs e)
{
InitTraceBinding();
ShowFileHeader();
Application.Idle += Application_Idle;
}
private void Application_Idle(object sender, EventArgs e)
{
bool isTraceShow = this.tsbtnShowTraceHeader.Checked;
if(this.tbtnSetInline.Enabled == isTraceShow)
{
return;
}
this.tbtnSetInline.Enabled = isTraceShow;
this.tbtnSetCrossLine.Enabled = isTraceShow;
this.bdNavTrace.Enabled = isTraceShow;
}
public FormParseHeader()
{
InitializeComponent();
CreateFileSchema();
CreateTraceSchema();
InitTable();
}
private void tbtnOK_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
/// <summary>
/// 显示文件头
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tbtnShowFileHeader_Click(object sender, EventArgs e)
{
if (Segy == null)
{
return;
}
ShowFileHeader();
this.tbtnShowFileHeader.Checked = true;
this.tsbtnShowTraceHeader.Checked = false;
}
private void tsbtnShowComment_Click(object sender, EventArgs e)
{
MessageBox.Show(this, Segy.Header.Text, "文件描述");
}
/// <summary>
/// 显示道头信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tsbtnShowTraceHeader_Click(object sender, EventArgs e)
{
if (Segy == null)
{
return;
}
if (Segy == null) { return; }
ParseTraceHeader(Segy.Traces[(int)this.bdSourceTraceHeader.Current].Header, dtInfor);
this.tbtnShowFileHeader.Checked = false;
this.tsbtnShowTraceHeader.Checked = true;
}
private void tbtnSetInline_Click(object sender, EventArgs e)
{
}
private void tbtnSetCrossLine_Click(object sender, EventArgs e)
{
}
private void InitTraceBinding()
{
if(this.Segy == null)
{
return;
}
int nTraceCount = this.Segy.Traces.Count;
int[] lst = new int[nTraceCount];
for(int i = 0; i < nTraceCount; i++)
{
lst[i] = i;
}
bdSourceTraceHeader.DataSource = lst;
bdNavTrace.BindingSource = bdSourceTraceHeader;
this.tlblInlineLocation.Text = $"Inline:{this.Options.TraceHeaderLocationForInlineNumber + 1:000}-{this.Options.TraceHeaderLocationForInlineNumber + 4:000}";
this.tlblCrosslinePosition.Text = $"Crossline:{this.Options.TraceHeaderLocationForCrosslineNumber + 1:000}-{this.Options.TraceHeaderLocationForCrosslineNumber + 4:000}";
}
private void InitTable()
{
dtInfor = new DataTable();
dtInfor.Columns.Add("字节位置", typeof(System.String));
dtInfor.Columns.Add("数据", typeof(System.String));
dtInfor.Columns.Add("描述", typeof(System.String));
this.dgvData.DataSource = this.dtInfor;
for (int i = 0; i < this.dgvData.Columns.Count; i++)
{
this.dgvData.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
}
}
private void ShowFileHeader()
{
if(Segy == null)
{
return;
}
ParseFileHeader(Segy.Header, dtInfor);
// Inline、Crossline范围
int nDelay = 0;
Segy.GetLineRange(ref inlineMin, ref inlineMax, ref crosslineMin, ref crosslineMax,ref nDelay);
this.tlblInline.Text = $"Inline:{inlineMin}-{inlineMax}";
this.tlblCrossline.Text = $"Crossline:{crosslineMin}-{crosslineMax}";
this.dgvData.ContextMenuStrip = null;
}
/// <summary>
/// 导航
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bdSourceTraceHeader_CurrentChanged(object sender, EventArgs e)
{
int nSelect = 0;
if (dgvData.SelectedRows != null && dgvData.SelectedRows.Count > 0)
{
nSelect = dgvData.SelectedRows[0].Index;
}
int nScroll = dgvData.FirstDisplayedScrollingRowIndex;
ParseTraceHeader(Segy.Traces[(int)this.bdSourceTraceHeader.Current].Header, dtInfor);
dgvData.Rows[nSelect].Selected = true;
if (nScroll >= 0)
{
dgvData.FirstDisplayedScrollingRowIndex = nScroll;
}
}
/// <summary>
/// 右键选中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dgvData_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
if (e.RowIndex >= 0)
{
dgvData.ClearSelection();
dgvData.Rows[e.RowIndex].Selected = true;
}
}
}
/// <summary>
/// 设置Inline位置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tsmiSetInline_Click(object sender, EventArgs e)
{
if (dgvData.SelectedRows.Count == 0)
{
return;
}
int nRowIndex = dgvData.SelectedRows[0].Index;
Options.TraceHeaderLocationForInlineNumber = TraceSchemaRows[nRowIndex].Position;
this.tlblInlineLocation.Text = $"Inline位置:{this.Options.TraceHeaderLocationForInlineNumber + 1:000}-{this.Options.TraceHeaderLocationForInlineNumber + 4:000}";
this.tlblCrosslinePosition.Text = $"Crossline位置:{this.Options.TraceHeaderLocationForCrosslineNumber + 1:000}-{this.Options.TraceHeaderLocationForCrosslineNumber + 4:000}";
int nDelay = 0;
Segy.GetLineRange(ref inlineMin, ref inlineMax, ref crosslineMin, ref crosslineMax,ref nDelay, Options);
this.tlblInline.Text = $"Inline:{inlineMin}-{inlineMax}";
this.tlblCrossline.Text = $"Crossline:{crosslineMin}-{crosslineMax}";
this.isChanged = true;
}
/// <summary>
/// 设置Crossline位置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tsmiSetCrossline_Click(object sender, EventArgs e)
{
if (dgvData.SelectedRows.Count == 0)
{
return;
}
int nRowIndex = dgvData.SelectedRows[0].Index;
Options.TraceHeaderLocationForCrosslineNumber = TraceSchemaRows[nRowIndex].Position;
this.tlblInlineLocation.Text = $"Inline位置:{this.Options.TraceHeaderLocationForInlineNumber + 1:000}-{this.Options.TraceHeaderLocationForInlineNumber + 4:000}";
this.tlblCrosslinePosition.Text = $"Crossline位置:{this.Options.TraceHeaderLocationForCrosslineNumber + 1:000}-{this.Options.TraceHeaderLocationForCrosslineNumber + 4:000}";
int nDelay = 0;
Segy.GetLineRange(ref inlineMin, ref inlineMax, ref crosslineMin, ref crosslineMax,ref nDelay, Options);
this.tlblInline.Text = $"Inline:{inlineMin}-{inlineMax}";
this.tlblCrossline.Text = $"Crossline:{crosslineMin}-{crosslineMax}";
this.isChanged = true;
}
private void ParseTraceHeader(ITraceHeader traceHeader, DataTable dt)
{
for (int i = 0; i < TraceSchemaRows.Count; i++)
{
TraceSchemaRows[i].DataValue = traceHeader.GetValue(
TraceSchemaRows[i].Position,
TraceSchemaRows[i].DataLength, Segy.Header.IsLittleEndian);
}
dtInfor.Rows.Clear();
foreach (HeadRow headRow in TraceSchemaRows)
{
DataRow drNew = dtInfor.NewRow();
drNew[0] = $"{headRow.Position + 1:000} - {headRow.Position + headRow.DataLength:000}";
drNew[1] = headRow.DataValue > -1e-10 ? headRow.DataValue : null;
drNew[2] = headRow.Description;
dtInfor.Rows.Add(drNew);
}
this.dgvData.ContextMenuStrip = ctmPositionSet;
}
private void FormParseHeader_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.isChanged)
{
this.DialogResult = DialogResult.OK;
}
}
private void ParseFileHeader(IFileHeader fileHeader, DataTable dt)
{
for(int i=0;i< HeaderSchemaRows.Count; i++)
{
HeaderSchemaRows[i].DataValue = fileHeader.GetValue(
HeaderSchemaRows[i].Position,
HeaderSchemaRows[i].DataLength);
}
dtInfor.Rows.Clear();
foreach (HeadRow headRow in HeaderSchemaRows)
{
DataRow drNew = dtInfor.NewRow();
drNew[0] = $"{headRow.Position+1:000} - {headRow.Position + headRow.DataLength:000}";
drNew[1] = headRow.DataValue>-1e-10? headRow.DataValue: null;
drNew[2] = headRow.Description;
dtInfor.Rows.Add(drNew);
}
}
private void CreateTraceSchema()
{
TraceSchemaRows = new List<HeadRow>();
TraceSchemaRows.Add(new HeadRow(0, 4, "测线中道顺序号", null));
TraceSchemaRows.Add(new HeadRow(4, 4, "文件中道顺序号――每个文件以道顺序1开始", null));
TraceSchemaRows.Add(new HeadRow(8, 4, "野外原始记录号。", null));
TraceSchemaRows.Add(new HeadRow(12, 4, "野外原始记录的道号。", null));
TraceSchemaRows.Add(new HeadRow(16, 4, "震源点号――在相同有效地表位置多于一个记录时使用。", null));
TraceSchemaRows.Add(new HeadRow(20, 4, "道集号即CDPCMPCRP等。", null));
TraceSchemaRows.Add(new HeadRow(24, 4, "道集的道数――每个道集从道号1开始。", null));
TraceSchemaRows.Add(new HeadRow(28, 2, "道识别码。", null));
TraceSchemaRows.Add(new HeadRow(30, 2, "产生该道的垂直叠加道数。", null));
TraceSchemaRows.Add(new HeadRow(32, 2, @"产生该道的水平叠加道数。", null));
TraceSchemaRows.Add(new HeadRow(34, 2, @"数据用途: 1=生产 2=试验。", null));
TraceSchemaRows.Add(new HeadRow(36, 4, @"从震源中心点到检波器组中心的距离(若与炮激发线方向相反取负)。", null));
TraceSchemaRows.Add(new HeadRow(40, 4, @"检波器组高程(所有基准以上高程为正,以下为负)。", null));
TraceSchemaRows.Add(new HeadRow(44, 4, @"震源地表高程。", null));
TraceSchemaRows.Add(new HeadRow(48, 4, @"震源距地表深度(正数)。", null));
TraceSchemaRows.Add(new HeadRow(52, 4, @"检波器组基准高程。", null));
TraceSchemaRows.Add(new HeadRow(56, 4, @"震源基准高程。", null));
TraceSchemaRows.Add(new HeadRow(60, 4, @"震源水深。", null));
TraceSchemaRows.Add(new HeadRow(64, 4, @"检波器组水深。", null));
TraceSchemaRows.Add(new HeadRow(68, 2, @"应用于所有在道头41-68字节给定的真实高程和深度的因子。", null));
TraceSchemaRows.Add(new HeadRow(70, 2, @"应用于所有在道头73-88字节和181-188字节给定的真实坐标值的因子。", null));
TraceSchemaRows.Add(new HeadRow(72, 4, @"震源坐标――X。", null));
TraceSchemaRows.Add(new HeadRow(76, 4, @"震源坐标――Y。", null));
TraceSchemaRows.Add(new HeadRow(80, 4, @"检波器组坐标――X。", null));
TraceSchemaRows.Add(new HeadRow(84, 4, @"检波器组坐标――Y。", null));
TraceSchemaRows.Add(new HeadRow(88, 2, @"坐标单位。", null));
TraceSchemaRows.Add(new HeadRow(90, 2, @"风化层速度。", null));
TraceSchemaRows.Add(new HeadRow(92, 2, @"风化层下速度。", null));
TraceSchemaRows.Add(new HeadRow(94, 2, @"震源处井口时间(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(96, 2, @"检波器组处井口时间(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(98, 2, @"震源的静校正量(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(100, 2, @"检波器组的校正量(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(102, 2, @"应用的总静校正量(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(104, 2, @"延迟时间A。", null));
TraceSchemaRows.Add(new HeadRow(106, 2, @"延迟时间B。", null));
TraceSchemaRows.Add(new HeadRow(108, 2, @"记录延迟时间。", null));
TraceSchemaRows.Add(new HeadRow(110, 2, @"起始切除时间(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(112, 2, @"终止切除时间(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(114, 2, @"该道采样点数。", null));
TraceSchemaRows.Add(new HeadRow(116, 2, @"该道采样间隔(微秒)。", null));
TraceSchemaRows.Add(new HeadRow(118, 2, @"野外仪器增益类型。", null));
TraceSchemaRows.Add(new HeadRow(120, 2, @"仪器增益常数(分贝)。", null));
TraceSchemaRows.Add(new HeadRow(122, 2, @"仪器初始增益(分贝)。", null));
TraceSchemaRows.Add(new HeadRow(124, 2, @"相关1=无 2=有。", null));
TraceSchemaRows.Add(new HeadRow(126, 2, @"起始扫描频率(赫兹)。", null));
TraceSchemaRows.Add(new HeadRow(128, 2, @"终止扫描频率(赫兹)。", null));
TraceSchemaRows.Add(new HeadRow(130, 2, @"扫描长度(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(132, 2, @"扫描类型1=线性 2=抛物线 3=指数 4=其他。", null));
TraceSchemaRows.Add(new HeadRow(134, 2, @"扫描道斜坡起始长度(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(136, 2, @"扫描道斜坡终止长度(毫秒)。", null));
TraceSchemaRows.Add(new HeadRow(138, 2, @"斜坡类型1=线性 2=cos 3=其他。", null));
TraceSchemaRows.Add(new HeadRow(140, 2, @"假频滤波频率(赫兹),若使用。", null));
TraceSchemaRows.Add(new HeadRow(142, 2, @"假频滤波坡度(分贝/倍频程)。", null));
TraceSchemaRows.Add(new HeadRow(144, 2, @"陷波频率(赫兹),若使用。", null));
TraceSchemaRows.Add(new HeadRow(146, 2, @"陷波坡度(分贝/倍频程)。", null));
TraceSchemaRows.Add(new HeadRow(148, 2, @"低截频率(赫兹),若使用。", null));
TraceSchemaRows.Add(new HeadRow(150, 2, @"高截频率(赫兹),若使用。", null));
TraceSchemaRows.Add(new HeadRow(152, 2, @"低截坡度(分贝/倍频程)。", null));
TraceSchemaRows.Add(new HeadRow(154, 2, @"高截坡度(分贝/倍频程)。", null));
TraceSchemaRows.Add(new HeadRow(156, 2, @"数据记录的年。", null));
TraceSchemaRows.Add(new HeadRow(158, 2, @"日(以格林尼治标准时间和通用协调时间为基准的公元日)。", null));
TraceSchemaRows.Add(new HeadRow(160, 2, @"时24小时制。", null));
TraceSchemaRows.Add(new HeadRow(162, 2, @"分。", null));
TraceSchemaRows.Add(new HeadRow(164, 2, @"秒。", null));
TraceSchemaRows.Add(new HeadRow(166, 2, @"时间基准码1=当地
2=
3=
4=", null));
TraceSchemaRows.Add(new HeadRow(168, 2, @"道加权因子――最小有效位数定义为2伏。N=0132767。", null));
TraceSchemaRows.Add(new HeadRow(170, 2, @"滚动开关位置1的检波器组号。", null));
TraceSchemaRows.Add(new HeadRow(172, 2, @"野外原始记录中道号1的检波器组号。", null));
TraceSchemaRows.Add(new HeadRow(174, 2, @"野外原始记录中最后一道的检波器组号。", null));
TraceSchemaRows.Add(new HeadRow(176, 2, @"间隔大小(滚动时甩掉的总检波器组数)。", null));
TraceSchemaRows.Add(new HeadRow(178, 2, @"相对测线斜坡起始或终止点的移动。1=下(或后),2=上(或前)", null));
TraceSchemaRows.Add(new HeadRow(180, 4, @"该道的道集(CDP)位置X坐标(应用道头71-72字节的因子)。", null));
TraceSchemaRows.Add(new HeadRow(184, 4, @"该道的道集(CDP)位置Y坐标。", null));
TraceSchemaRows.Add(new HeadRow(188, 4, @"对于3-D叠后数据本字段用来填纵向线号(In-line)。", null));
TraceSchemaRows.Add(new HeadRow(192, 4, @"对于3-D叠后数据本字段用来填横向线号(Cross-line)。", null));
TraceSchemaRows.Add(new HeadRow(196, 4, @"", null));
TraceSchemaRows.Add(new HeadRow(200, 2, @"应用于道头中197-200字节炮点号的因子以得到实际数值。", null));
TraceSchemaRows.Add(new HeadRow(202, 2, @"道值测量单位。", null));
TraceSchemaRows.Add(new HeadRow(204, 6, @"转换常数――该倍数用于将数据道采样转换成转换单位道头211-212字节指定。", null));
TraceSchemaRows.Add(new HeadRow(210, 2, @"转换单位――经乘以道头205-210字节中的转换常数后的数据道采样测量单位。", null));
TraceSchemaRows.Add(new HeadRow(212, 2, @"设备/道标识――与数据道关联的单位号或设备号。", null));
TraceSchemaRows.Add(new HeadRow(214, 2, @"在道头95-114字节给出的作用于时间的因子以得到真实的毫秒表示的时间值。", null));
TraceSchemaRows.Add(new HeadRow(216, 2, @"道值测量单位。", null));
TraceSchemaRows.Add(new HeadRow(218, 6, @"相对震源方位的震源能量方向――正方位方向在道头217-218字节定义。", null));
TraceSchemaRows.Add(new HeadRow(224, 6, @"震源测量――描述产生道的震源效应。", null));
TraceSchemaRows.Add(new HeadRow(230, 2, @"震源测量单位――用于震源测量、道头225-230字节的单位。", null));
TraceSchemaRows.Add(new HeadRow(232, 8, @"未赋值――为任选信息预留。", null));
}
private void CreateFileSchema()
{
HeaderSchemaRows = new List<HeadRow>();
HeaderSchemaRows.Add(new HeadRow(0, 4, "作业标识号", null));
HeaderSchemaRows.Add(new HeadRow(4, 4, "测线号", null));
HeaderSchemaRows.Add(new HeadRow(8, 4, "卷号", null));
HeaderSchemaRows.Add(new HeadRow(12, 2, "每个道集的数据道数。叠前数据强制要求。", null));
HeaderSchemaRows.Add(new HeadRow(14, 2, "每个道集的辅助道数。叠前数据强制要求。", null));
HeaderSchemaRows.Add(new HeadRow(16, 2, "微秒us形式的采样间隔。叠前数据强制要求。", null));
HeaderSchemaRows.Add(new HeadRow(18, 2, "微秒us形式的原始野外记录采样间隔。", null));
HeaderSchemaRows.Add(new HeadRow(20, 2, "数据道采样点数。叠前数据强制要求。", null));
HeaderSchemaRows.Add(new HeadRow(22, 2, "原始野外记录每道采样点数。", null));
HeaderSchemaRows.Add(new HeadRow(24, 2, @"数据采样格式编码。叠前数据强制要求
1=4IBM
2=4
3=2
4=4使
5=4IEEE
6=使
7=使
8=1", null));
HeaderSchemaRows.Add(new HeadRow(26, 2, @"道集覆盖次数――每个数据集的期望数据道数例如CMP覆盖次数。", null));
HeaderSchemaRows.Add(new HeadRow(28, 2, @"道分选码(即采集类型)。", null));
HeaderSchemaRows.Add(new HeadRow(30, 2, @"垂直求和码。", null));
HeaderSchemaRows.Add(new HeadRow(32, 2, @"起始扫描频率Hz。", null));
HeaderSchemaRows.Add(new HeadRow(34, 2, @"终止扫描频率Hz。", null));
HeaderSchemaRows.Add(new HeadRow(36, 2, @"扫描长度ms。", null));
HeaderSchemaRows.Add(new HeadRow(38, 2, @"扫描类型码。", null));
HeaderSchemaRows.Add(new HeadRow(40, 2, @"扫描信道的道数。", null));
HeaderSchemaRows.Add(new HeadRow(42, 2, @"有斜坡时,以毫秒表示的扫描道起始斜坡长度(斜坡从零时刻开始,对这个长度有效)。", null));
HeaderSchemaRows.Add(new HeadRow(44, 2, @"以毫秒表示的扫描道终止斜坡长度(斜坡终止始于扫描长度减去斜坡结尾处的长度)。", null));
HeaderSchemaRows.Add(new HeadRow(46, 2, @"斜坡类型。", null));
HeaderSchemaRows.Add(new HeadRow(48, 2, @"相关数据道。", null));
HeaderSchemaRows.Add(new HeadRow(50, 2, @"二进制增益恢复1=恢复2=未恢复。", null));
HeaderSchemaRows.Add(new HeadRow(52, 2, @"振幅恢复方法。", null));
HeaderSchemaRows.Add(new HeadRow(54, 2, @"测量系统1=米2=英尺。", null));
HeaderSchemaRows.Add(new HeadRow(56, 2, @"脉冲极化码。", null));
HeaderSchemaRows.Add(new HeadRow(58, 2, @"可控源极化码。", null));
HeaderSchemaRows.Add(new HeadRow(60, 240, @"未赋值。", null));
HeaderSchemaRows.Add(new HeadRow(300, 2, @"SEG Y格式修订版号。", null));
HeaderSchemaRows.Add(new HeadRow(302, 2, @"固定长度道标志。1表示所有道具有相同的采样间隔和采样点数即在文件头中17-18和21-22字节。0表示道长可能变化此时道头中115-116字节的采样点数必须用来确认各道的实际长度。", null));
HeaderSchemaRows.Add(new HeadRow(304, 2, @"扩展文件头。", null));
HeaderSchemaRows.Add(new HeadRow(306, 94, @"未赋值。", null));
}
}
public class HeadRow
{
public int Position { get; set; } = 0;
public int DataLength { get; set; } = 4;
public string Description { get; set; } = string.Empty;
public dynamic DataValue { get; set; } = null;
public HeadRow(int position, int dataLength, string description, dynamic dataValue)
{
this.Position = position;
this.DataLength = dataLength;
this.Description = description;
this.DataValue = dataValue;
}
}
}