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#

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.

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=4字节IBM浮点数
2=4字节两互补整数
3=2字节两互补整数
4=4字节带增益定点数过时不再使用
5=4字节IEEE浮点数
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;
}
}
}